WebBrowser键盘快捷键

我有一个WebBrowser控件显示一些HTML。
我希望用户能够复制整个文档,但不能做任何其他事情。

我将IsWebBrowserContextMenuEnabledWebBrowserShortcutsEnabled属性设置为false ,我想处理KeyUp并在用户按Ctrl + C时运行一些代码。

我怎样才能做到这一点?
WebBrowser控件不支持键盘事件。
我尝试使用KeyPreview的表单的KeyUp事件,但它根本没有触发。

编辑 :这是我的解决方案,灵感来自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); } } 

您也可以尝试这种方法。 把它放在你的主表单区域,它应该捕获所有的键盘命令。 我用它来为动态创建的标签添加键盘快捷键。

 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; 

这是Windows窗体中的一个错误 。 它的IDocHostUIHandler.TranslateAccelerator实现实际上尝试通过在检查WebBrowserShortcutsEnabled并将密钥数据与预定义的快捷方式进行比较后返回S_OK来将键击发送到ActiveX主机。 不幸的是,在Windows Forms的键盘处理中,在ProcessCmdKey期间检查了shortcutkey属性,这意味着IDocHostUIHandler.TranslateAccelerator返回的时间太晚了。 当WebBrowserShortcutsEnabled设置为false时,这会导致快捷方式枚举中的任何内容(例如Control + C,Del,Control + N等)停止工作。

您可以创建或查找Webbrowser ActiveX包装类(例如csexwb2 ),该类提供不同的IDocHostUIHandler.TranslateAccelerator实现以再次检查快捷键。 Windows窗体webbrowser控件不允许自定义其IDocHostUIHandler实现。

您可以设置键盘消息挂钩到您的webbrowser控件并过滤掉键盘消息或对它们进行一些处理。 请查看以下代码是否适合您:

 [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()); //.... } ... 

希望这会有所帮助,问候

经过大量调查后,我们才知道它是浏览器兼容性问题。

我们在HTML页面中添加了元标记,然后快捷方式正常工作。 以下是示例代码。

       
First name:

Last name:

这个问题有三种不同的解决方案。

  1. 添加元标记以使网站浏览器兼容。

  2. 覆盖“PreocessCmdKey”方法并处理快捷方式。

  3. 通过在FEATURE_BROWSER_EMULATION下添加密钥来模拟浏览器。

如果您不想在html代码中设置元标记,则可以在导航URL之前将元标记分配给webbrowser控件的Document文本属性。 以下是样本。

  //Setting compatible mode of IE. this.m_oWebBrowser.DocumentText = @"    "; this.m_oWebBrowser.Navigate("www.google.com");