WebBrowser keyboard shortcuts

别等时光非礼了梦想. 提交于 2019-11-30 07:08:18

You could try this method as well. Put it in your main form area and it should catch all of the keyboard commands. I use it to add keyboard shortcuts to dynamically created tabs.

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
    switch (keyData)
    {
        case Keys.Control|Keys.Tab:
            NextTab();
            return true;
        case Keys.Control|Keys.Shift|Keys.Tab:
            PreviousTab();
            return true;
        case Keys.Control|Keys.N:
            CreateConnection(null);
            return true;
    }
    return false;
Sheng Jiang 蒋晟

It is a bug in Windows Forms. Its IDocHostUIHandler.TranslateAccelerator implementation actually tries to send the keystroke to the ActiveX host by returning S_OK after checking WebBrowserShortcutsEnabled and comparing the key data to predefined shortcuts. unfortunately in Windows Forms's keyboard processing, the shortcutkey property is checked during ProcessCmdKey, which means IDocHostUIHandler.TranslateAccelerator returned a little bit too late. That causes anything in the Shortcut enum (e.g. Control+C, Del, Control+N etc) stops working when WebBrowserShortcutsEnabled is set to false.

You can create or find a webbrowser ActiveX wrapper class (e.g. csexwb2) that provides a different IDocHostUIHandler.TranslateAccelerator implementation to check shortcut keys again. The Windows Forms webbrowser control does not allow customizing its IDocHostUIHandler implementation.

you can set a keyboard messages hook to your webbrowser control and filter out keyup keys messages or do some handling for them. Please see if code below would work for you:

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, IntPtr windowTitle);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll")]
public static extern int GetCurrentThreadId();

public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
public const int WH_KEYBOARD = 2;
public static int hHook = 0;

// keyboard messages handling procedure
public static int KeyboardHookProcedure(int nCode, IntPtr wParam, IntPtr lParam)
{
    Keys keyPressed = (Keys)wParam.ToInt32();
    Console.WriteLine(keyPressed);

    if (keyPressed.Equals(Keys.Up) || keyPressed.Equals(Keys.Down))
    {
        Console.WriteLine(String.Format("{0} stop", keyPressed));
        return -1;
    }
    return CallNextHookEx(hHook, nCode, wParam, lParam);
}

// find explorer window
private IntPtr FindExplorerWindow()
{
    IntPtr wnd = FindWindowEx(webBrowser1.Handle, IntPtr.Zero, "Shell Embedding", IntPtr.Zero);
    if (wnd != IntPtr.Zero)
    {
        wnd = FindWindowEx(wnd, IntPtr.Zero, "Shell DocObject View", IntPtr.Zero);
        if (wnd != IntPtr.Zero)
            return FindWindowEx(wnd, IntPtr.Zero, "Internet Explorer_Server", IntPtr.Zero);
    }
    return IntPtr.Zero;
}
...
        // install hook    
        IntPtr wnd = FindExplorerWindow();
        if (wnd != IntPtr.Zero)
        {
            // you can either subclass explorer window or install a hook
            // for hooking you don't really need a window handle but can use it
            // later to filter out messages going to this exact window
            hHook = SetWindowsHookEx(WH_KEYBOARD, new HookProc(KeyboardHookProcedure),
                (IntPtr)0, GetCurrentThreadId());
            //....
        }
...

hope this helps, regards

After investigating a lot, we came to know it is browser compatibility issue.

We have added meta tag into the HTML page,then shortcuts are working fine. Below is the sample code.

 <html>
<body>
<Head>
<meta http-equiv="X-UA-Compatible" content="IE=IE8" />
</head>
<form>
First name:<br>
<input type="text" name="firstname">
<br>
Last name:<br>
<input type="text" name="lastname">
</form></body>
</html>

There are three different solutions for this problem.

  1. Adding meta tag to make the Web site browser compatible.

  2. Override "PreocessCmdKey" method and handle the shortcuts.

  3. Emulate browser by adding the key under FEATURE_BROWSER_EMULATION.

If you don't want to set the meta tag in html code, you can assign meta tag to the Document text property of webbrowser control before navigating the URL. Below is the sample.

    //Setting compatible mode of IE.
                    this.m_oWebBrowser.DocumentText = @"<html>
                      <head><meta http-equiv=""X-UA-Compatible"" content=""IE=IE8"" /> </head>
                      <body></body>
                      </html>";
this.m_oWebBrowser.Navigate("www.google.com");
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!