繁体   English   中英

WebBrowser控件无法响应InvokeMember(“click”)

[英]WebBrowser control not responding to InvokeMember(“click”)

在我度过了5天的生活之后,我即将放弃这一点,但在此之前我会咨询专家。

我有一个WebBrowser控件加载网页,我以编程方式抓取其内容。 在IE(或任何其他浏览器)中完成后,单击页面中的特定菜单项将显示“文件打开”对话框。 但是使用InvokeMember()在WebBrowser控件中单击相同的按钮显然无论如何都不会执行任何操作。 我已经经历了几个SO问题,比如设置浏览器功能 ,以确保我的控件行为与IE完全一样,但是没有成功。

我一直在检查按钮在场景后面执行的实际javascript函数,并使用HtmlDocument.InvokeScript()手动调用它,但是由于底层函数采用了MouseEvent类型的参数(实际上是click事件),所以不能这样做而且我不确定如何在C#中创建该对象。

另一种方法是将焦点设置为该特定按钮,然后尝试SendKeys ,但这不起作用,因为WebBrowser控件不可见。 它只是一个内存实例。 更具体地说,WebBrowser

编辑

根据读者的要求,这是我用来查找元素的简单代码:

var MyButton = WB.Document.GetElementById("processfilelink");

processfilelink是一个锚标记( <a href='#' ... > processfilelink ),我已经确认该元素实际存在于文档正文中。 该网页使用jQuery的delegate功能将此锚click事件绑定到目标函数。 找到按钮后,我只需调用这样的InvokeMember()

MyButton.InvokeMember("click");

注意:我还在页面代码中看到mousedown,mouseup和focus事件的绑定。 我希望所有这些事件在调用click时自动触发,但是为了确保我InvokeMember为这些事件添加了InvokeMember调用。 结果并不好。

来自评论:

...在完整的IE浏览器中加载此页面,使用F12工具对其进行调试并在JavaScript控制台中执行button.click()。 它是否按预期工作?

所以,你已经尝试过,结果是:

......现在这很有趣。 它不起作用! 但是手动点击该项目确实可以正常工作。 这里发生了什么?

我怀疑,因为MyButton.InvokeMember("click")不起作用。 显然,页面通过其他方式处理此单击,而不是通过onclick事件。 最有可能的是,它使用onmousedownonmouseup事件。 研究页面的脚本逻辑来验证是否是这种情况,使用F12调试器并设置一些断点。

更新后 ,如果事实证明页面确实使用onmousedown / onmouseup ,则需要通过发布WM_LBUTTONDOWN使WebBrowser可见并自动化它:

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);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM