2009-12-30 264 views
9

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

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

我该怎么做?
WebBrowser控件不支持键盘事件。
我尝试使用表格的KeyUp事件KeyPreview,但它根本没有触发。

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

回答

10

你可以试试这个方法为好。把它放在你的主窗体区域,它应该捕获所有的键盘命令。我用它来将键盘快捷键添加到动态创建的选项卡中。

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; 
+0

这几乎可行,但我无法获得CTRL + C的消息。如果我按C,'keyData'是'C',但是如果我按下Control,有或没有另一个键,'keyData'是'LButton | ShiftKey |控制“,并且没有办法确定哪一个其他键(如果有的话)被按下。 – SLaks 2009-12-30 20:55:23

+0

最后一种情况说明“情况Keys.Control | Keys.N”正在执行您正在尝试执行的操作。 |用于捕获多个键。所以“情况Keys.Control | Keys.C:”应该做的伎俩。 – Jerb 2009-12-31 16:26:12

0

您可以设置一个键盘消息挂钩到您的浏览器控件,并筛选出键盘键消息或为它们做一些处理。请看下面是否将代码为你工作:

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

希望这会有所帮助,至于

4

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

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

0

经过调查了很多,我们才知道它是浏览器兼容性问题。

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

<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> 

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

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

  2. 重写“PreocessCmdKey”方法并处理快捷方式。

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

如果您不想在HTML代码中设置元标记,则可以在导航URL之前将meta标记指定给webbrowser控件的Document文本属性。以下是示例。

//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");