How to use 'Back' & 'Forward' navigation button events in WPF WebBrowser?
c#, webbrowser-control, wpf
Solution
You can use low level hook of mouse and check if the xbutton1 or xbutton2 clicked look here
for the value of `WM_XBUTTONDOWN` look http://msdn.microsoft.com/en-us/library/ms646245(VS.85).aspx
Problem
The `WebBrowser` control in WPF is inherited from the`UIElement`, but we cannot register event handlers in `UIElement` events. Why is it? At WPF WebBrowser Mouse Events not working as expected, it is answered but I still cannot understand. Anyway, hooking up handlers to the events provided by the document of the `WebBrowser` can catch most mouse events but cannot use 'Back' & 'Forward' navigation button events. Since the internet explorer can do this, I think it is possible. Is there any way to solve this issue? UPDATE: In this question, `'Back' & 'Forward' navigation buttons`mean XButton1 and XButton2 in 5-button mouse system. UPDATE2: I fixed this question with the Navid Rahmani's answer. I'd think someone will need this answer, so I attach main part. If finding any problem or more reasonable solution, please let me know. ``` //This code assumes the `WebBrowser` field named _webBrowser is already initiated. //For the detail out of this code, please refer to the Navid Rahmani's answer. private bool _isMouseOver; private HTMLDocumentEvents2_Event _docEvent; public ctor() { _webBrowser.LoadCompleted += _webBrowser_LoadCompleted; } private void _webBrowser_LoadCompleted(object sender, NavigationEventArgs e) { if (_docEvent != null) { _docEvent.onmouseover -= _docEvent_onmouseover; _docEvent.onmouseout -= _docEvent_onmouseout; } if (_webBrowser.Document != null) { _docEvent = (HTMLDocumentEvents2_Event)_webBrowser.Document; _docEvent.onmouseover += _docEvent_onmouseover; _docEvent.onmouseout += _docEvent_onmouseout; } } void _docEvent_onmouseout(IHTMLEventObj pEvtObj) { _isMouseOver = false; } void _docEvent_onmouseover(IHTMLEventObj pEvtObj) { _isMouseOver = true; } private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) { if (_isMouseOver) { if (nCode >= 0 && (MouseMessages)wParam == MouseMessages.XBUTTON) { var hookStruct = (Msllhookstruct)Marshal.PtrToStructure(lParam, typeof(Msllhookstruct)); if (hookStruct.mouseData == 0x10000) { //do something when XButto1 clicked } else if (hookStruct.mouseData == 0x20000) { //do something when XButto2 clicked } } } return CallNextHookEx(_hookID, nCode, wParam, lParam); } private enum MouseMessages { //WM_LBUTTONDOWN = 0x00A1, //WM_LBUTTONUP = 0x0202, //WM_MOUSEMOVE = 0x0200, //WM_MOUSEWHEEL = 0x020A, //WM_RBUTTONDOWN = 0x0204, //WM_RBUTTONUP = 0x0205, XBUTTON = 0x020B, } ```