在我生命中度过了 5 天之后,我即将放弃这个,但在此之前我咨询过一次专家。
我有一个加载网页的 WebBrowser 控件,我以编程方式抓取其内容。在 IE(或任何其他浏览器)中单击页面中的特定菜单项会弹出文件打开对话框。但是使用 InvokeMember()
在 WebBrowser 控件中单击相同的按钮显然无论如何都不做任何事情。我已经经历了几个 SO 问题,例如 Setting Browser Features以确保我的控件的行为与 IE 完全一样,但这并没有成功。
我甚至检查了按钮在后台执行的实际 javascript 函数,并使用 HtmlDocument.InvokeScript()
手动调用它但不能这样做,因为底层函数采用 MouseEvent
的参数类型(实际上是点击事件),我不确定如何在 C# 中创建该对象。
另一种方法是将焦点设置到该特定按钮,然后尝试 SendKeys
,但这将不起作用,因为 WebBrowser 控件不可见。它只是一个内存中的实例。更具体地说,WebBrowser
编辑
应读者的要求,这是我用来查找元素的简单代码:
var MyButton = WB.Document.GetElementById("processfilelink");
processfilelink
是一个 anchor 标记(<a href='#' ... >
),我已经确认这个元素确实存在于文档的正文中。该网页使用 jQuery 的 delegate
绑定(bind)此 anchor 的 click
的功能事件到目标函数。找到按钮后,我只需调用 InvokeMember()
像这样:
MyButton.InvokeMember("click");
注意:我还在页面代码中看到了 mousedown、mouseup 和 focus 事件的绑定(bind)。我希望所有这些事件在调用 click
时自动触发,但为了确保我添加了 InvokeMember
也呼吁这些事件。结果也好不到哪里去。
最佳答案
来自评论:
... load this page in full IE browser, use F12 Tools to debug it and execute button.click() in JavaScript console. Does it work as expected this way?
那么,您已经尝试过了,结果是:
... now that's interesting. It doesn't work! But clicking on the item by hand does work flawlessly. What's going on here?
我怀疑 as MyButton.InvokeMember("click")
不起作用。显然,该页面通过 onclick
事件以外的其他方式处理此点击。它很可能使用 onmousedown
或 onmouseup
事件。研究页面的脚本逻辑以验证是否属于这种情况,使用 F12 调试器并放置一些断点。
已更新,如果发现该页面确实使用了 onmousedown
/onmouseup
,您需要将 WebBrowser
可见并通过发布 WM_LBUTTONDOWN
使其自动化:
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace WindowsFormsApplication_22979038
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void MainForm_Load(object sender, EventArgs e)
{
this.webBrowser.DocumentText = "<a id='goLink' href='javascript:alert(\"Hello!\"),undefined'>Go</a><script></script>";
this.webBrowser.DocumentCompleted += webBrowser_DocumentCompleted;
}
void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
var element = this.webBrowser.Document.GetElementById("goLink");
element.Focus();
var hwnd = GetFocus();
if (!IsChild(this.webBrowser.Handle, hwnd))
throw new ApplicationException("Unexpected focused window.");
var rect = GetElementRect(element);
IntPtr wParam = (IntPtr)MK_LBUTTON;
IntPtr lParam = (IntPtr)(rect.Left | rect.Top << 16);
PostMessage(hwnd, WM_LBUTTONDOWN, wParam, lParam);
PostMessage(hwnd, WM_LBUTTONUP, wParam, lParam);
}
// get the element rect in window client area coordinates
static Rectangle GetElementRect(HtmlElement element)
{
var rect = element.OffsetRectangle;
int left = 0, top = 0;
var parent = element;
while (true)
{
parent = parent.OffsetParent;
if (parent == null)
return new Rectangle(rect.X + left, rect.Y + top, rect.Width, rect.Height);
var parentRect = parent.OffsetRectangle;
left += parentRect.Left;
top += parentRect.Top;
}
}
// interop
const int MK_LBUTTON = 0x0001;
const int WM_LBUTTONDOWN = 0x0201;
const int WM_LBUTTONUP = 0x0202;
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int x;
public int y;
}
[DllImport("User32.dll", CharSet = CharSet.Auto)]
static extern int PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);
[DllImport("User32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
static extern IntPtr GetFocus();
[DllImport("User32.dll", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto)]
static extern bool IsChild(IntPtr hWndParent, IntPtr hWnd);
}
}
关于c# - WebBrowser 控件未响应 InvokeMember ("click"),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22979038/