如何在Awesomium中实现鼠标点击?

时间:2015-12-13 00:50:11

标签: c# awesomium

我编写了这段代码来测试Inject鼠标方法,但它对我不起作用。该测试应该在谷歌文本框搜索区域中单击,但该框永远不会突出显示。知道为什么吗?

谷歌的页面确实加载了。代码运行(通过断点确认),但没有任何反应。

public partial class Form1 : Form
    {
        private IWebView webView;
        public Form1()
        {
            InitializeComponent();
            initiate();

        }

        private void button1_Click(object sender, EventArgs e)
         {
            click(650, 405);
        }

        private async void initiate()
        {

            WebSession session = WebCore.CreateWebSession(
@"C:\SessionDataPath", WebPreferences.Default);
            webView = WebCore.CreateWebView(
      this.ClientSize.Width,
      this.ClientSize.Height, session, WebViewType.Window
     );
            webView.ParentWindow = this.Handle;
            webView.Source = new Uri("http://www.google.com");
            await Task.Delay(30000);
            click(650, 405);

        }

        public void click(int x, int y)
        {
            webView.InjectMouseMove(x, y);
            webView.InjectMouseDown(MouseButton.Left);
            webView.InjectMouseUp(MouseButton.Left);
        }
    }

我尝试通过查看正确的铬类来使用此代码来处理铬手柄,但它不起作用

  private async Task<bool> clickCoorindate(Point point)
        {
            webView.FocusView();
            int x = point.X; // X coordinate of the click
            int y = point.Y; // Y coordinate of the click
            IntPtr handle = webView.ProcessHandle;
            StringBuilder className = new StringBuilder(100);
            while (className.ToString() != "Chrome_RenderWidgetHostHWND") // The class control for the browser
            {
                handle = GetWindow(handle, 5); // Get a handle to the child window
                GetClassName(handle, className, className.Capacity);
                if (className.ToString() == "Chrome_RenderWidgetHostHWND")
                    handle = Handle;

            }

            IntPtr lParam = (IntPtr)((y << 16) | x); // The coordinates
            IntPtr wParam = IntPtr.Zero; // Additional parameters for the click (e.g. Ctrl)
            const uint downCode = 0x201; // Left click down code
            const uint upCode = 0x202; // Left click up code
            const uint moveCode = 0x200;

            SendMessage(handle, downCode, wParam, lParam); // Mouse button down
            SendMessage(handle, upCode, wParam, lParam); // Mouse button up
            Thread.Sleep(20);
            SendMessage(handle, downCode, wParam, lParam); // Mouse button down
            SendMessage(handle, upCode, wParam, lParam); // Mouse button up

            return true;

        }

4 个答案:

答案 0 :(得分:0)

在我的XNA游戏中,我使用了很多Awesomium,这是我在我的awesomium组件中实现的输入系统,它运行得非常好。 请注意,这只是我班级的一部分,所以有些方法不在这里,但不需要他们理解这个过程 基本上在我的线程中。基本上我挂钩我的表单中的消息并将它们转发到WebView。希望这有帮助

  public partial class BasicAwesomiumComponent : DrawableGameComponent {

  private delegate Int32 ProcessMessagesDelegate(Int32 code, Int32 wParam, ref Message lParam);

  private static class User32 {
     [DllImport("user32.dll", SetLastError = true)]
     internal static extern IntPtr SetWindowsHookEx(Int32 windowsHookId, ProcessMessagesDelegate function, IntPtr mod, Int32 threadId);

     [DllImport("user32.dll", SetLastError = true)]
     internal static extern Int32 UnhookWindowsHookEx(IntPtr hook);

     [DllImport("user32.dll", SetLastError = true)]
     internal static extern Int32 CallNextHookEx(IntPtr hook, Int32 code, Int32 wParam, ref Message lParam);

     [DllImport("user32.dll", SetLastError = true)]
     internal static extern Boolean TranslateMessage(ref Message message);

     [DllImport("user32.dll", CharSet = CharSet.Auto)]
     internal static extern IntPtr FindWindow(String className, String windowName);

     [DllImport("user32.dll", CharSet = CharSet.Auto)]
     internal static extern int RegisterWindowMessage(String msg);

     [DllImport("user32.dll", CharSet = CharSet.Auto)]
     internal static extern IntPtr SendMessage(HandleRef hWnd, Int32 msg, Int32 wParam, Int32 lParam);

     [DllImport("user32.dll", CharSet = CharSet.Auto)]
     internal static extern bool SystemParametersInfo(Int32 nAction, Int32 nParam, ref Int32 value, Int32 ignore);

     [DllImport("user32.dll", CharSet = CharSet.Auto)]
     internal static extern int GetSystemMetrics(Int32 nIndex);
  }

  private static class Kernel32 {
     [DllImport("kernel32.dll", SetLastError = true)]
     internal static extern Int32 GetCurrentThreadId();
  }

  private static class SystemMetrics {
     internal static Int32 MouseWheelScrollDelta {
        get {
           return 120;
        }
     }

     internal static Int32 MouseWheelScrollLines {
        get {
           var scrollLines = 0;

           if (User32.GetSystemMetrics(75) == 0) {
              var hwnd = User32.FindWindow("MouseZ", "Magellan MSWHEEL");
              if (hwnd != IntPtr.Zero) {
                 var windowMessage = User32.RegisterWindowMessage("MSH_SCROLL_LINES_MSG");
                 scrollLines = (Int32)User32.SendMessage(new HandleRef(null, hwnd), windowMessage, 0, 0);
                 if (scrollLines != 0) {
                    return scrollLines;
                 }
              }
              return 3;
           }
           User32.SystemParametersInfo(104, 0, ref scrollLines, 0);
           return scrollLines;
        }
     }
  }

  private enum WindowsMessage {
     KeyDown = 0x0100,
     KeyUp = 0x0101,
     Char = 0x0102,

     MouseMove = 0x0200,
     LeftButtonDown = 0x0201,
     LeftButtonUp = 0x0202,
     LeftButtonDoubleClick = 0x0203,

     RightButtonDown = 0x0204,
     RightButtonUp = 0x0205,
     RightButtonDoubleClick = 0x0206,

     MiddleButtonDown = 0x0207,
     MiddleButtonUp = 0x0208,
     MiddleButtonDoubleClick = 0x0209,

     MouseWheel = 0x020A,
  }

  private struct Message {
     internal IntPtr HWnd;
     internal Int32 Msg;
     internal IntPtr WParam;
     internal IntPtr LParam;
     internal IntPtr Result;
  }

  private IntPtr hookHandle;
  private ProcessMessagesDelegate processMessages;

  private Int32 ProcessMessages(Int32 code, Int32 wParam, ref Message lParam) {
     if (this.Enabled && code == 0 && wParam == 1) {

        bool processed = false;

        switch ((WindowsMessage)lParam.Msg) {
           case WindowsMessage.KeyDown:
           case WindowsMessage.KeyUp:
           case WindowsMessage.Char:
              WebKeyboardEvent keyboardEvent = new WebKeyboardEvent((uint)lParam.Msg, lParam.WParam, lParam.LParam, 0);

              awesomiumContext.Post(state => {
                 if (!WebView.IsLive) return;
                 WebView.InjectKeyboardEvent(keyboardEvent);
              }, null);

              processed = true;
              break;

           case WindowsMessage.MouseWheel:
              var delta = (((Int32)lParam.WParam) >> 16);
              awesomiumContext.Post(state => {
                 if (!WebView.IsLive) return;
                 WebView.InjectMouseWheel(delta / SystemMetrics.MouseWheelScrollDelta * 16 * SystemMetrics.MouseWheelScrollLines, 0);
              }, null);

              processed = true;
              break;
        }

        if (!processed) {
           WindowsMessage message = (WindowsMessage)lParam.Msg;
           awesomiumContext.Post(state => {
              if (!WebView.IsLive) return;

              switch (message) {
                 case WindowsMessage.MouseMove:
                    var mouse = Mouse.GetState();
                    WebView.InjectMouseMove(mouse.X - area.X, mouse.Y - area.Y);
                    break;

                 case WindowsMessage.LeftButtonDown:
                    WebView.InjectMouseDown(MouseButton.Left);
                    break;
                 case WindowsMessage.LeftButtonUp:
                    WebView.InjectMouseUp(MouseButton.Left);
                    break;
                 case WindowsMessage.LeftButtonDoubleClick:
                    WebView.InjectMouseDown(MouseButton.Left);
                    break;

                 case WindowsMessage.RightButtonDown:
                    WebView.InjectMouseDown(MouseButton.Right);
                    break;
                 case WindowsMessage.RightButtonUp:
                    WebView.InjectMouseUp(MouseButton.Right);
                    break;
                 case WindowsMessage.RightButtonDoubleClick:
                    WebView.InjectMouseDown(MouseButton.Right);
                    break;

                 case WindowsMessage.MiddleButtonDown:
                    WebView.InjectMouseDown(MouseButton.Middle);
                    break;
                 case WindowsMessage.MiddleButtonUp:
                    WebView.InjectMouseUp(MouseButton.Middle);
                    break;
                 case WindowsMessage.MiddleButtonDoubleClick:
                    WebView.InjectMouseDown(MouseButton.Middle);
                    break;
              }
           }, null);
        }
        User32.TranslateMessage(ref lParam);
     }

     return User32.CallNextHookEx(IntPtr.Zero, code, wParam, ref lParam);
  }
}

更新: 请注意,在我的组件中,要挂钩消息泵,我使用

int currentThread = Kernel32.GetCurrentThreadId();
// Create the message hook.
hookHandle = User32.SetWindowsHookEx(3, ProcessMessages, IntPtr.Zero, currentThread);

我在Offscreen webview中的表面,所以更复杂,这对你也适用

答案 1 :(得分:0)

我发布了一个单独的答案给出了另一个方向: 看看这个要点:https://gist.github.com/robertkhrona/918109

似乎建议做

webView.InjectMouseMove(x,y);
webView.InjectMouseDown(MouseButton.Left);
webView.InjectMouseMove(x,y);
webView.InjectMouseUp(MouseButton.Left);

在两个mousedown / up事件之间移动(到同一位置) 顺便说一下,我认为不应该这样做

你正在运行哪个版本的awesomium?

更新: 请记住在注入输入之前将焦点设置在WebView上

webView.Focus();

答案 2 :(得分:0)

我将viewtype设置为offscreen,并且injectclick工作正常,当设置为window时它不起作用。我不知道为什么,但我可以解决这个问题。

答案 3 :(得分:0)

如文档中所述(请参阅: WebViewType ),窗口视图会捕获所有输入,但您无法注入使用Awesomium API以编程方式输入(您可以通过将本机Windows消息发送到相应的HWND来执行此操作,但不建议使用直接的过程)。

为了能够使用 InjectXXX 方法以编程方式注入输入,请确保您的视图的类型为 {{3} }