1

I'm working on a project, a Web Bot, that makes use of a WebBrowser control.

My aim is to programmably open the webBrowsers ContextMenu on a desired element in the loaded WebBrowser, and select an option from the ContextMenu.

Example:

navigate to Google in a WebBrowser control. Open the ContextMenu. Select "Show Picture"

so far this is the closest code i have managed to find Here :

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

This code returns a error on the first line so far, Any solutions here?




The working alternative:

So far i have managed to achieve this though simulating clicks, the problem with this is that when the window is hidden there is an obvious error. Also i would prefer not having the cursor jump across the screen. if there was a way to simulate clicks on a hidden window it could perhaps be a solution here. Here is my current code to simulate clicks: (although i would prefer not make use of simulated clicking, this code works)

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

if there is a way to do this procedure through calling the WebBrowsers ContextMenu...?!

Bump.

Community
  • 1
  • 1
Msegling
  • 365
  • 3
  • 12

1 Answers1

0

It depends on your concrete requirement. If you want to operate particular HTML element, you can access it via DOM. IMO, you can do everything that WebBrowser can do.

If you want to use the context menu (to avoid writing extra code or to pretend an user operation), you can send a mouse click at desired position and then block context menu popup temporary. Here is my sample code in Delphi for your reference.

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 is one method of the interface IDocHostUIHandler. In other words, you have to extend the WebBrowser control by implementing at least IDocHostUIHandler. See also MSDN.

stanleyxu2005
  • 8,081
  • 14
  • 59
  • 94