精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
Seems the mouse buttons do not generate key presses at all, as I've monitored it using a global keyboard hook and got nothing. I was hoping someone might know how these buttons work. They work fine in many other applications, including IE, Firefox, Visual Studio, and even Xiine.
似乎鼠标按键根本不产生按键,因为我已经使用全局键盘钩子监测,毫无所得。我希望有人可能知道这些按钮是如何工作的。它们在许多其他应用工作得很好,包括IE,火狐,Visual Studio中,甚至Xiine。
I found at least part of the answer on Google: the buttons actually correspond to a MouseDown event with the e.Button parameter being either XButton1 or XButton2.since this is a MouseDown event I need to capture, and it should occur while the mouse is over the CsExWB control, where can I trap this event? Looking through the source I cannot find much of anything at all to do with mouse handling.Is it possible to trap events from the underlying COM WB object?
我发现谷歌里至少有一部分的答案对:按钮实际上和一个MouseDown事件对应,事件有e.Button参数,参数要么是XButton1或XButton2。因为这是一个MouseDown事件,它是我要捕捉的目标,当鼠标在CsExWB控件上时,它应该会出现,在那里我可以捕获这个事件?翻翻源代码,我无法找到任何知识点来处理鼠标.可以从底层的COM WB对象捕获事件吗?能否做到这一点?
Three options that I know of:
三个选项,我所知道的:
1. Subscribe to document or documentelement ommousedown and/or onmouseup events. There are two classes within the csEXWB namespace, cHTMLDocumentEvents and cHTMLElementEvents that can be used for this functionality. An example of how to use cHTMLElementEvents can be found in frmHTMLEditor.cs.
1.订阅文档或documentelement ommousedown和/或onmouseup事件。有可用于该功能的csEXWB命名空间,cHTMLDocumentEvents和cHTMLElementEvents内两个类。如何使用cHTMLElementEvents的例子可以在frmHTMLEditor.cs找到。
2. Setup a local mouse hook. Use one of the examples available on the net or take a look at the WndProc method in csEXWB.cs which uses a CBT hook to deal with HTMLDialogs and setup a mouse hook.
2.设置本地鼠标钩子。使用的例子可用一个在网或看看WndProc方法在csEXWB.cs其中使用CBT钩子来处理HTMLDialogs和设置鼠标挂钩。
3. Subclass "Internet Explorer_Server" window. Again, use one of the number of examples available on the net or use the code located in commented region "Subclassing IEServer" within csEXWB.cs.
3.子类“互联网Explorer_Server”窗口。同样,使用实例的数量可用的一个在网络上或使用位于评论区“子类IEServer”内csEXWB.cs的代码。
I've decided to attempt option 3, however I'm having some difficulty obtaining the Internet Explorer_Server handle. In particular, I can't tell when it's created to know when to access it. Is there a point in time when I can know this handle has been created? An event, or even just a point in cEXWB.cs when it will be valid? It doesn't appear to have been created by the end of InternalCreateWB(), though both the ShellEmbeddingHandle and ShellDocObjHandle are.
我决定尝试选项3,但我有一些很难获得互联网Explorer_Server手柄。特别是当它的创建要知道什么时候访问它,我不能告诉。是否有一个时间点该句柄已创建的时候我能知道吗?一个事件,甚至只是在cEXWB.cs一个点时,它会有效吗?它似乎没有已由InternalCreateWB()的端创建的,尽管这两个是ShellEmbeddingHandle和ShellDocObjHandle。
Internet Explorer_Server handle is created the first time when the webbrowser becomes visible (UIActivated).
互联网Explorer_Server句柄创建第一次时,网页浏览器变为可见(UIActivated)。
Here is the final working solution.
First of all, if you followed the previous posts, I decided to opt for "subclassing" (actually just extending) the "Internet Explorer_Server" window by attaching a WndProc and intercepting the WM_XBUTTONDOWN message. I did this rather simply by deriving a new class called IEServerWindow from the .NET framework's NativeWindow class, which is designed explicitly for this purpose.
首先,如果您是在以前的帖子,我决定选择“子类”(实际上只是扩大)通过附加的WndProc和拦截WM_XBUTTONDOWN消息“互联网Explorer_Server”窗口。我通过派生一个新类IEServerWindow从.NET框架的NativeWindow类,它是被设计用于此目的这样做是相当简单的。
[System.Security.Permissions.PermissionSet( System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust" )] internal class IEServerWindow : NativeWindow { cEXWB browser; public IEServerWindow( cEXWB wb ) { this.browser = wb; if ( !wb.IEServerHwnd.Equals( IntPtr.Zero ) ) { AssignHandle( wb.IEServerHwnd ); } } public void Release() { ReleaseHandle(); } [System.Security.Permissions.PermissionSet( System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust" )] protected override void WndProc( ref Message m ) { switch ( m.Msg ) { case WindowsMessages.WM_XBUTTONDOWN: if ( m.WParam.ToInt32() >> 16 == 1 ) // back button browser.GoBack(); else if ( m.WParam.ToInt32() >> 16 == 2 ) // forward button browser.GoForward(); break; } base.WndProc( ref m ); } }
(The security permissions attribute was from the MSDN example of NativeWindow--not entirely sure what it's for but I thought I'd leave it there.)
(安全权限属性是从的NativeWindow MSDN的例子 - 不完全知道是什么感觉了,但我想我会离开它那里)
This will establish the NativeWindow class that we need to instantiate given the handle to the Internet Explorer_Server window (which is the actual window hosting the web browser). The next trick was to figure out where this handle is created. Thanks again to mehrcpp, I added this bit of code:
这将证明,我们需要实例给出的句柄互联网Explorer_Server窗口(这是实际的窗口承载Web浏览器)NativeWindow类。下一个诀窍是,在创建该句柄弄清楚。再次感谢mehrcpp,我加了这段代码:
int IOleInPlaceSite.OnUIActivate() { ieServerWindow = new IEServerWindow( this ); return Hresults.S_OK; }
...where ieServerWindow is just a private instance of IEServerWindow.
...其中ieServerWindow是IEServerWindow只是一个私有的实例。
Now there was one additional problem I had to solve: for some reason, the browser control was not issuing this UIActivate event for instances of cEXWB that had an initial url. Luckily, changing the bottom of InternalCreateWB to this:
现在有一个附加的问题,我不得不解决:由于某种原因,浏览器控制未发出该UIActivate事件有一个初始URL cEXWB的实例。幸运的是,改变内部CreateWEB的底部,这样的:
this.Navigate( "about:blank" ); if ( !string.IsNullOrEmpty( m_sUrl ) ) this.Navigate( m_sUrl );
...solved it.
...解决它。
For completeness, I also altered the definition of WBIEServerHandle() to use FindWindowEx() instead of GetWindow(), which I heard was safer:
为了完整起见,我也改变了WBIEServerHandle()使用的FindWindow(),而不是GetWindow(),这是我听到的是更安全的定义:
private IntPtr WBIEServerHandle() { m_hWBShellEmbeddingHandle = WBShellEmbedingHandle(); m_hWBShellDocObjHandle = FindWindowEx( m_hWBShellEmbeddingHandle, IntPtr.Zero, "Shell DocObject View", IntPtr.Zero ); m_hWBServerHandle = FindWindowEx( m_hWBShellDocObjHandle, IntPtr.Zero, "Internet Explorer_Server", IntPtr.Zero ); return m_hWBServerHandle; }
You will need this import:
您将需要此导入:
[DllImport( "user32.dll", SetLastError = true )] public static extern IntPtr FindWindowEx( IntPtr parentHandle, IntPtr childAfter, string className, IntPtr windowTitle );
...and don't forget to release the NativeWindow handle in OnUIDeactivate:
...不要忘了在ondelete释放NativeWindow手柄:
int IOleInPlaceSite.OnUIDeactivate( bool fUndoable ) { if ( ieServerWindow != null ) { ieServerWindow.Release(); ieServerWindow = null; } return Hresults.E_NOTIMPL; }
I think that's about it. With the above in-place, my cEXWB control now fully supports my mouse's back and forward buttons!
我认为这就是它。有了上面位置正确的代码,我的cEXWB控件现在完全支持鼠标的前进和后退按钮!