简体   繁体   中英

WebBrowser keyboard shortcuts

I have a WebBrowser control displaying some HTML.
I want the user to be able to copy the entire document, but not do anything else.

I've set the IsWebBrowserContextMenuEnabled and WebBrowserShortcutsEnabled properties to false , and I want to handle KeyUp and run some code when the user presses Ctrl+C.

How can I do that?
The WebBrowser control doesn't support keyboard events.
I tried using the form's KeyUp event with KeyPreview , but it didn't fire at all.

EDIT : Here's my solution, inspired by Jerb's answer.

class CopyableWebBrowser : WebBrowser {
    public override bool PreProcessMessage(ref Message msg) {
        if (msg.Msg == 0x101    //WM_KEYUP
         && msg.WParam.ToInt32() == (int)Keys.C && ModifierKeys == Keys.Control) {
            DoCopy();
            return true;
        }
        return base.PreProcessMessage(ref msg);
    }
    void DoCopy() {
        Document.ExecCommand("SelectAll", false, null);
        Document.ExecCommand("Copy", false, null);
        Document.ExecCommand("Unselect", false, null);
    }
}

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;

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 (eg Control+C, Del, Control+N etc) stops working when WebBrowserShortcutsEnabled is set to false.

You can create or find a webbrowser ActiveX wrapper class (eg 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");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM