如何向WebBrowser发送击键?

时间:2012-01-27 01:55:01

标签: c# wpf winapi keyboard webbrowser-control

我想模拟嵌入式System.Windows.Controls.WebBrowser中的击键。在StackOverflow上已经记录了各种用于模拟击键的技术,但是它们似乎不适用于WebBrowser控件。

知道控件包装了另一个窗口/ hwnd,我本来希望以下工作可行但不是:

[DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hWnd, uint msg, int wParam, int lParam);

...

SendMessage(myWebBrowser.Handle, WM_CHAR, key, 0);

我已经使用SendMessage将模拟击键转发到WPF应用程序的其他部分,并且更喜欢一致的解决方案;但是WebBrowser

失败了

如何将模拟击键转发到WebBrowser

5 个答案:

答案 0 :(得分:3)

我的解决方案是使用SendInput()代替SendMessage()

导入:

[DllImport("user32.dll", SetLastError = true)]
public static extern uint SendInput(uint nInputs, User32.Input[] pInputs, int cbSize);

有关其他类型和常量,请参阅此处:http://pinvoke.net/default.aspx/user32/SendInput.html

对于预期的行为,请参见此处:http://msdn.microsoft.com/en-us/library/windows/desktop/ms646310(v=vs.85).aspx

我的虚拟按键方法:

private void VirtualKeypress(Key keyCode, bool shift, char keyChar)
{
    User32.Input[] inputSequence;
    if (keyChar == '\0' && keyCode == Key.None)
    {
        throw new ArgumentException("Expected a key code or key char, not both.");
    }
    else if (keyChar != '\0')
    {
        inputSequence = KeyboardUtils.ConvertCharToInputArray(keyChar);
    }
    else
    {
        inputSequence = KeyboardUtils.ConvertKeyToInputArray(keyCode, shift);
    }

    User32.SendInput(
        (uint)inputSequence.Length, 
        inputSequence, 
        Marshal.SizeOf(typeof(User32.Input))
    );
}

我有两个辅助方法ConvertCharToInputArray()ConvertKeyToInputArray(),它们返回一个长度为2或4的数组,具体取决于我们是否需要告诉窗口Shift键被按下。例如:

'A' -> [] { shift down, A down, A up, shift up }

'a' -> [] { A down, A up }

答案 1 :(得分:1)

你太近了! WebBrowser.Handle报告的句柄是最常用的句柄,而所有输入都指向最内部的句柄:

var hwnd = _browser.Handle;
hwnd = FindWindowEx(hwnd, IntPtr.Zero, "Shell Embedding", null);
hwnd = FindWindowEx(hwnd, IntPtr.Zero, "Shell DocObject View", null);
hwnd = FindWindowEx(hwnd, IntPtr.Zero, "Internet Explorer_Server", null);

SendMessage(hwnd, WM_CHAR, new IntPtr(0x0D), IntPtr.Zero);

pinvoke.net的FindWindowEx定义:

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

突出显示的是WebBrowser控件: Highlighted is the WebBrowser control

答案 2 :(得分:0)

我只习惯在VB6中使用它,但尝试发送到myWebBrowser.object.Handle或myWebBrowser.object.HWND是我在VB6中看到的,但你的.net版本可能有.Handle。

试试.object,让我知道它是怎么回事!!

答案 3 :(得分:0)

我发现我可以在 C# 程序中通过使用 sendmessage 到进程 # 来移动 HTML 表单(Chrome 浏览器)。

但是,我无法在输入字段中插入文本。尝试了几乎所有的东西(来自纯 C#)。

在进行黑客攻击时,我注意到我可以在光标位于我尝试设置的输入上时弹出上下文编辑菜单,并且菜单上的一项已粘贴! WhatDoYouKnow!我可以与之互动!

这是我使用的代码,一旦我选择了我想要设置的输入:

Clipboard.SetText("52118"); // from C#, put the input value onto the clipboard

chrome.SendKey((char)93); // char 93 opens pop-up menu that includes paste
System.Threading.Thread.Sleep(30);
chrome.SendKey((char)0x28); // down to the first menu item
System.Threading.Thread.Sleep(30);
chrome.SendKey((char)0x28); // down to the second menu item (paste)
System.Threading.Thread.Sleep(100);
chrome.SendKey((char)0x0D); // fire the paste

在此处查看用于 ChromeWrapper 的代码(谢谢!):

Sending keyboard key to browser in C# using sendkey function

答案 4 :(得分:0)

您必须使用 PostMessage 而不是 SendMessage,然后它应该可以工作。

PS:我知道晚了 9 年