简体   繁体   English

WebBrowser键盘快捷键

[英]WebBrowser keyboard shortcuts

I have a WebBrowser control displaying some HTML. 我有一个WebBrowser控件显示一些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. 我已将IsWebBrowserContextMenuEnabledWebBrowserShortcutsEnabled属性设置为false ,我想处理KeyUp并在用户按Ctrl + C时运行一些代码。

How can I do that? 我怎样才能做到这一点?
The WebBrowser control doesn't support keyboard events. WebBrowser控件不支持键盘事件。
I tried using the form's KeyUp event with KeyPreview , but it didn't fire at all. 我尝试将表单的KeyUp事件与KeyPreview ,但它根本没有触发。

EDIT : Here's my solution, inspired by Jerb's answer. 编辑 :这是我的解决方案,灵感来自Jerb的回答。

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 . 这是Windows窗体中的一个错误 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. 它的IDocHostUIHandler.TranslateAccelerator实现实际上尝试通过在检查WebBrowserShortcutsEnabled并将密钥数据与预定义的快捷方式进行比较后返回S_OK来将键击发送到ActiveX主机。 unfortunately in Windows Forms's keyboard processing, the shortcutkey property is checked during ProcessCmdKey, which means IDocHostUIHandler.TranslateAccelerator returned a little bit too late. 不幸的是,在Windows Forms的键盘处理中,在ProcessCmdKey期间检查了shortcutkey属性,这意味着IDocHostUIHandler.TranslateAccelerator返回的时间太晚了。 That causes anything in the Shortcut enum (eg Control+C, Del, Control+N etc) stops working when WebBrowserShortcutsEnabled is set to false. 当WebBrowserShortcutsEnabled设置为false时,这会导致快捷方式枚举中的任何内容(例如Control + C,Del,Control + N等)停止工作。

You can create or find a webbrowser ActiveX wrapper class (eg csexwb2 ) that provides a different IDocHostUIHandler.TranslateAccelerator implementation to check shortcut keys again. 您可以创建或查找webbrowser ActiveX包装类(例如csexwb2 ),该类提供不同的IDocHostUIHandler.TranslateAccelerator实现以再次检查快捷键。 The Windows Forms webbrowser control does not allow customizing its IDocHostUIHandler implementation. Windows窗体webbrowser控件不允许自定义其IDocHostUIHandler实现。

you can set a keyboard messages hook to your webbrowser control and filter out keyup keys messages or do some handling for them. 您可以设置键盘消息挂钩到您的webbrowser控件并过滤掉键盘消息或对它们进行一些处理。 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. 我们在HTML页面中添加了元标记,然后快捷方式正常工作。 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. 覆盖“PreocessCmdKey”方法并处理快捷方式。

  3. Emulate browser by adding the key under FEATURE_BROWSER_EMULATION. 通过在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. 如果您不想在html代码中设置元标记,则可以在导航URL之前将元标记分配给webbrowser控件的Document文本属性。 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");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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