如何在Awesomium中实现鼠标点击

本文关键字:鼠标 实现 Awesomium | 更新日期: 2023-09-27 18:26:31

我写这段代码是为了测试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);
        }
    }

我试图通过查看正确的chromium类来让这个代码与chromium句柄一起工作,但它不起的作用

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

如何在Awesomium中实现鼠标点击

如文档中所述(请参阅:WebViewType),窗口化视图本身捕获所有输入,并且您不能使用Awesomium API以编程方式注入输入(您可以在尝试时通过向相应的HWND发送本机Windows消息来实现这一点,但这不是建议的直接过程)。

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

在我的XNA游戏中,我使用了很多Awesomium,这是我在我的Awesominium组件中实现的输入系统,它运行得很好。请注意,这只是我的类的一部分,所以有些方法不在这里,但理解过程并不需要它们基本上在我的线程中。基本上,我挂接到表单中的消息,并将它们转发到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);

我的表面在屏幕外的网络视图中,所以越复杂,这也应该适用于

我发布了一个单独的答案来给出另一个方向:看看这个要点: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();

我将viewtype设置为屏幕外,injectclick运行良好,当设置为window时,它不起作用。我不知道为什么,但我可以解决这个问题。