How to use 'Back' & 'Forward' navi

2019-02-13 06:50发布

问题:

The WebBrowser control in WPF is inherited from theUIElement, 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 buttonsmean 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,
    }

回答1:

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



回答2:

Much simpler way....

This works for me in WPF and .net 4.5

private void Window_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton.Equals(MouseButton.XButton1)) MessageBox.Show(@"back");
if (e.ChangedButton.Equals(MouseButton.XButton2)) MessageBox.Show(@"forward");
}


回答3:

The WebBrowser controll is really just thin wrapper around the Trident COM object. It's not 'pure WPF' like other built-in controls... so lots of normal things don't work with it. To answer your question, the closest you can get is hooking into the Navigating event. This won't tell you whether the user is trying to go forwards or back or elsewhere but it will give you the URL and the opportunity to set e.Cancel = true to stop the navigation (usually followed by calling Navigate(url) to take the user somewhere else).