【问题标题】:Invoking Webbrowser ContextMenu调用 Webbrowser ContextMenu
【发布时间】:2014-08-12 10:12:31
【问题描述】:

我正在开发一个使用 WebBrowser 控件的项目,即 Web Bot。

我的目标是以编程方式在加载的 WebBrowser 中的所需元素上打开 webBrowsers ContextMenu,然后从 ContextMenu 中选择一个选项。

示例:

在 WebBrowser 控件中导航到 Google。 打开上下文菜单。选择“显示图片”

到目前为止,这是我设法找到的最接近的代码 Here:

foreach (MenuItem vMenuItem in WebBrowser.ContextMenu.MenuItems)
{
    if (vMenuItem.Text.Contains("onwert") && vMenuItem.Text.Contains("PDF"))
    {
        vMenuItem.PerformClick();
    }
}

到目前为止,此代码在第一行返回错误,这里有任何解决方案吗?




可行的替代方案:

到目前为止,我已经设法通过模拟点击来实现这一点,但问题是当窗口隐藏时会出现明显的错误。我也不希望光标在屏幕上跳跃。如果有一种方法可以模拟隐藏窗口上的点击,它可能是这里的解决方案。 这是我当前模拟点击的代码:(虽然我不想使用模拟点击,但此代码有效)

        Point controlLoc = this.PointToScreen(webbrowser1.Location);
        controlLoc.X = controlLoc.X + webbrowser1.Document.GetElementById("sbvdcapimg").OffsetRectangle.Left+65;
        controlLoc.Y = controlLoc.Y + webbrowser1.Document.GetElementById("sbvdcapimg").OffsetRectangle.Top+50;
        Cursor.Position = controlLoc;
        MouseSimulator.ClickRightMouseButton();
        controlLoc.X = controlLoc.X + (webbrowser1.Document.GetElementById("sbvdcapimg").OffsetRectangle.Left + 95);
        controlLoc.Y = controlLoc.Y + (webbrowser1.Document.GetElementById("sbvdcapimg").OffsetRectangle.Top + 45);
        Cursor.Position = controlLoc;
        MouseSimulator.ClickLeftMouseButton();

public class MouseSimulator
{
    [DllImport("user32.dll", SetLastError = true)]
    static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize);

    [StructLayout(LayoutKind.Sequential)]
    struct INPUT
    {
        public SendInputEventType type;
        public MouseKeybdhardwareInputUnion mkhi;
    }
    [StructLayout(LayoutKind.Explicit)]
    struct MouseKeybdhardwareInputUnion
    {
        [FieldOffset(0)]
        public MouseInputData mi;

        [FieldOffset(0)]
        public KEYBDINPUT ki;

        [FieldOffset(0)]
        public HARDWAREINPUT hi;
    }
    [StructLayout(LayoutKind.Sequential)]
    struct KEYBDINPUT
    {
        public ushort wVk;
        public ushort wScan;
        public uint dwFlags;
        public uint time;
        public IntPtr dwExtraInfo;
    }
    [StructLayout(LayoutKind.Sequential)]
    struct HARDWAREINPUT
    {
        public int uMsg;
        public short wParamL;
        public short wParamH;
    }
    struct MouseInputData
    {
        public int dx;
        public int dy;
        public uint mouseData;
        public MouseEventFlags dwFlags;
        public uint time;
        public IntPtr dwExtraInfo;
    }
    [Flags]
    enum MouseEventFlags : uint
    {
        MOUSEEVENTF_MOVE = 0x0001,
        MOUSEEVENTF_LEFTDOWN = 0x0002,
        MOUSEEVENTF_LEFTUP = 0x0004,
        MOUSEEVENTF_RIGHTDOWN = 0x0008,
        MOUSEEVENTF_RIGHTUP = 0x0010,
        MOUSEEVENTF_MIDDLEDOWN = 0x0020,
        MOUSEEVENTF_MIDDLEUP = 0x0040,
        MOUSEEVENTF_XDOWN = 0x0080,
        MOUSEEVENTF_XUP = 0x0100,
        MOUSEEVENTF_WHEEL = 0x0800,
        MOUSEEVENTF_VIRTUALDESK = 0x4000,
        MOUSEEVENTF_ABSOLUTE = 0x8000
    }
    enum SendInputEventType : int
    {
        InputMouse,
        InputKeyboard,
        InputHardware
    }

    public static void ClickRightMouseButton()
    {
        INPUT mouseDownInput = new INPUT();
        mouseDownInput.type = SendInputEventType.InputMouse;
        mouseDownInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_RIGHTDOWN;
        SendInput(1, ref mouseDownInput, Marshal.SizeOf(new INPUT()));

        INPUT mouseUpInput = new INPUT();
        mouseUpInput.type = SendInputEventType.InputMouse;
        mouseUpInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_RIGHTUP;
        SendInput(1, ref mouseUpInput, Marshal.SizeOf(new INPUT()));
    }

    public static void ClickLeftMouseButton()
    {

        INPUT mouseDownInput = new INPUT();
        mouseDownInput.type = SendInputEventType.InputMouse;
        mouseDownInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTDOWN;
        SendInput(1, ref mouseDownInput, Marshal.SizeOf(new INPUT()));

        INPUT mouseUpInput = new INPUT();
        mouseUpInput.type = SendInputEventType.InputMouse;
        mouseUpInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTUP;
        SendInput(1, ref mouseUpInput, Marshal.SizeOf(new INPUT()));
    }

如果有办法通过调用 WebBrowsers ContextMenu 来执行此过程...?!

撞。

【问题讨论】:

    标签: c# webbrowser-control


    【解决方案1】:

    这取决于您的具体要求。如果要操作特定的 HTML 元素,可以通过 DOM 访问它。 IMO,您可以做 WebBrowser 可以做的所有事情。

    如果您想使用上下文菜单(以避免编写额外的代码或假装用户操作),您可以在所需位置发送鼠标单击,然后暂时阻止上下文菜单弹出。这是我在 Delphi 中的示例代码供您参考。

    function TTrident.ShowContextMenu(const dwID: DWORD; const ppt: PPOINT; const pcmdtReserved: IUnknown;
      const pdispReserved: IDispatch): HRESULT;
    begin
      if FDontShowContextMenuThisTime then
      begin
        FDontShowContextMenuThisTime := False;
        Exit(S_OK);
      end
      else
        Exit(S_FALSE);
    end;
    

    ShowContextMenu 是接口IDocHostUIHandler 的一种方法。换句话说,您必须通过至少实现IDocHostUIHandler 来扩展WebBrowser 控件。 See also MSDN.

    【讨论】:

      猜你喜欢
      • 2014-06-09
      • 2011-05-28
      • 1970-01-01
      • 2020-05-18
      • 2013-08-22
      • 1970-01-01
      • 2018-01-11
      • 1970-01-01
      相关资源
      最近更新 更多