2009-12-30 384 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");