代码之家  ›  专栏  ›  技术社区  ›  SLaks

WebBrowser键盘快捷键

  •  9
  • SLaks  · 技术社区  · 15 年前

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

    我已经设定了 IsWebBrowserContextMenuEnabled WebBrowserShortcutsEnabled 属性到 false 我想处理 KeyUp 并在用户按下ctrl+c时运行一些代码。

    我该怎么做?
    WebBrowser控件不支持键盘事件。
    我试过用表格 松开键 事件与 KeyPreview 但它根本就没有开火。

    编辑 :这是我的解决方案,灵感来自杰布的回答。

    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);
        }
    }
    
    4 回复  |  直到 9 年前
        1
  •  10
  •   Jerb    15 年前

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

    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;
    
        2
  •  4
  •   hurst    11 年前

    It is a bug in Windows Forms . 它的 IDocHostUIHandler.TranslateAccelerator 在检查WebbrowserShortcutsEnabled并将键数据与预定义的快捷方式进行比较后,实现实际上尝试通过返回S ou OK将击键发送到ActiveX主机。不幸的是,在Windows窗体的键盘处理过程中,会在processCmdkey期间检查shortcutkey属性,这意味着idochostuihandler.translateAccelerator返回得有点晚。这导致了 Shortcut 当WebBrowserShortcutsEnabled设置为false时,枚举(例如control+c、del、control+n等)停止工作。

    您可以创建或查找WebBrowser ActiveX包装类(例如 csexwb2 )这提供了不同的idochostuihandler.translateAccelerator实现来再次检查快捷键。Windows窗体WebBrowser控件不允许自定义其IDochostuihandler实现。

        3
  •  0
  •   serge_gubenko    15 年前

    您可以设置一个连接到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());
                //....
            }
    ...
    

    希望这有帮助,问候

        4
  •  0
  •   Siva Sankar Gorantla    9 年前

    经过大量调查,我们发现这是浏览器兼容性问题。

    我们在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. 重写“preprocessCmdKey”方法并处理快捷方式。

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

    如果不想在HTML代码中设置元标记,可以在导航URL之前将元标记分配给WebBrowser控件的文档文本属性。下面是样品。

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