2009-12-30 20 views
9

Tengo un control WebBrowser que muestra algo de HTML.
Quiero que el usuario pueda copiar el documento completo, pero no hacer nada más.Atajos de teclado de WebBrowser

He configurado las propiedades IsWebBrowserContextMenuEnabled y WebBrowserShortcutsEnabled a false, y quiero manejar KeyUp y ejecutar código cuando el usuario presiona Ctrl + C.

¿Cómo puedo hacer eso?
El control WebBrowser no admite eventos de teclado.
Intenté usar el evento KeyUp del formulario con KeyPreview, pero no se activó en absoluto.

EDIT: Esta es mi solución, inspirada por la respuesta de 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); 
    } 
} 

Respuesta

10

usted podría intentar este método también. Póngalo en el área de su formulario principal y debería capturar todos los comandos del teclado. Lo uso para agregar atajos de teclado a pestañas creadas dinámicamente.

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

Esto casi funciona, pero no puede obtener un mensaje de CTRL + C. Si presiono C, 'keyData' es' C', pero si presiono Control, con o sin otra clave, 'keyData' es' LButton | ShiftKey | Control', y no hay manera de determinar qué otra tecla, si la hubo, se presionó. – SLaks

+0

La última declaración de caso "case Keys.Control | Keys.N" está haciendo exactamente lo que estás tratando de hacer. El | se usa para atrapar varias llaves. por lo que "case Keys.Control | Keys.C:" debería hacer el truco. – Jerb

0

se puede establecer un gancho mensajes de teclado para el control de navegador web y filtrar los mensajes keyup llaves o realizar algún tratamiento para ellos. Por favor, vea si el código de abajo funcionaría para usted:

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

esperanza que esta ayuda, que se refiere a

4

It is a bug in Windows Forms. Su implementación IDocHostUIHandler.TranslateAccelerator realmente intenta enviar la pulsación de tecla al host ActiveX devolviendo S_OK después de comprobar WebBrowserShortcutsEnabled y comparando los datos clave con accesos directos predefinidos. desafortunadamente, en el procesamiento de teclado de Windows Forms, la propiedad del atajo de teclado se comprueba durante ProcessCmdKey, lo que significa que IDocHostUIHandler.TranslateAccelerator regresó un poco tarde. Esto provoca que cualquier cosa en la enumeración Shortcut (por ejemplo, Control + C, Supr, Control + N, etc.) deje de funcionar cuando WebBrowserShortcutsEnabled se establece en falso.

Puede crear o encontrar una clase contenedora ActiveX de webbrowser (por ejemplo, csexwb2) que proporcione una implementación diferente de IDocHostUIHandler.TranslateAccelerator para verificar las teclas de método abreviado de nuevo. El control webbrowser de Windows Forms no permite personalizar su implementación IDocHostUIHandler.

0

Después de investigar mucho, llegamos a saber que es un problema de compatibilidad del navegador.

Hemos agregado la metaetiqueta en la página HTML, luego los accesos directos funcionan bien. A continuación se muestra el código de muestra.

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

Existen tres soluciones diferentes para este problema.

  1. Adición de etiquetas meta para hacer compatible el navegador sitio Web.

  2. Reemplace el método "PreocessCmdKey" y maneje los atajos.

  3. Emule el navegador agregando la clave bajo FEATURE_BROWSER_EMULATION.

Si no desea establecer la etiqueta meta en el código HTML, puede asignar etiqueta meta a la propiedad de texto del documento de control de navegador web antes de navegar la URL. Debajo está la muestra.

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