2012-05-18 72 views
1

我有一个多线程应用程序,需要能够同时执行多个鼠标单击操作。虚拟鼠标单击c#

我有一个IntPtr intptr我需要发送鼠标点击的过程。 我试图在网上找到这些信息,并且有一些我尝试过的例子。但我没有得到任何工作。

据我了解,以SOLV我的问题,正确的方法是使用功能 SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

的hWnd是的IntPtr的过程。 消息是想要的行动,我想要一个左键单击,int WM_LBUTTONDBLCLK = 0x0203; IntPtr wParam是没有intrest这个问题(据我所知) 而点击的坐标是在lParam中。 我构建lParam的喜欢,

Int32 word = MakeLParam(x, y); 

private int MakeLParam(int LoWord, int HiWord) 
    { 
     return ((HiWord << 16) | (LoWord & 0xffff)); 
    } 

但是,正如你可能知道,我不能得到这个工作。 我的第一个问题是,坐标是否在这个过程的窗口内,或者是绝对坐标? 而我的第二个问题,我做错了什么?

+0

更多的信息在这里:http://msdn.microsoft.com/en-us/library/windows/desktop/ms645606(v=vs.85).aspx – mellamokb

+2

这听起来像是一个问题,有一个更好解决方案比你开始的解决方案...你为什么要这样做? –

回答

0

我不是100%确定我明白你要完成的。但如果你想模拟鼠标输入,那么我建议使用SendInput API。

您可以提供一个要插入输入流的输入数组。

参见:PInvoke reference

0

我不明白为什么有人会想同时发送多个鼠标点击。如果是测试你的GUI,那是错误的测试。没有人可以在同一时间空间中多次点击物体。

但回到你的问题,使用SendMessage不会帮助你,因为它基本上是一个阻塞呼叫。即使您尝试使用PostMessage,您也无法完成同时点击,因为消息队列正在从UI线程中获取并弹出消息并按顺序处理。

+0

Okey。我觉得我必须澄清一点。我想要的不是多个鼠标点击相同的IntPtr intptr。我想要的是有多个点击事件不同的IntPtr intptr。不互相干扰。我的第一次尝试是移动鼠标指针并进行点击。当你只有一个进程执行此操作时,这很有效。当多个线程尝试点击不同的位置时,它会失败。 – VbN

0

我用这个代码,如果你没有设定手柄打电话来点击handle

public static void MouseLeftClick(Point p, int handle = 0) 
{ 
    //build coordinates 
    int coordinates = p.X | (p.Y << 16); 
    //send left button down 
    SendMessage(handle, 0x201, 0x1, coordinates); 
    //send left button up 
    SendMessage(handle, 0x202, 0x1, coordinates); 
} 

左键 - 然后将其发送点击桌面,所以坐标应该是整个屏幕,如果你设置手柄,那么消息将被发送到句柄的窗口,并且您应该为窗口设置坐标。

3

我试图模拟在C#中的鼠标点击就在最近,我写了这个小助手类的伎俩:

public static class SimInput 
{ 
    [DllImport("user32.dll")] 
    static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, UIntPtr dwExtraInfo); 

    [Flags] 
    public enum MouseEventFlags : uint 
    { 
     Move = 0x0001, 
     LeftDown = 0x0002, 
     LeftUp = 0x0004, 
     RightDown = 0x0008, 
     RightUp = 0x0010, 
     MiddleDown = 0x0020, 
     MiddleUp = 0x0040, 
     Absolute = 0x8000 
    } 

    public static void MouseEvent(MouseEventFlags e, uint x, uint y) 
    { 
     mouse_event((uint)e, x, y, 0, UIntPtr.Zero); 
    } 

    public static void LeftClick(Point p) 
    { 
     LeftClick((double)p.X, (double)p.Y); 
    } 

    public static void LeftClick(double x, double y) 
    { 
     var scr = Screen.PrimaryScreen.Bounds; 
     MouseEvent(MouseEventFlags.LeftDown | MouseEventFlags.LeftUp | MouseEventFlags.Move | MouseEventFlags.Absolute, 
      (uint)Math.Round(x/scr.Width * 65535), 
      (uint)Math.Round(y/scr.Height * 65535)); 
    } 

    public static void LeftClick(int x, int y) 
    { 
     LeftClick((double)x, (double)y); 
    } 
} 

的坐标是65535分,这是一个有点古怪,但这种班级会为你处理。

+0

如果您是在“最近”这样做的,为什么使用过时的['mouse_event'函数](http://msdn.microsoft.com/zh-cn/library/windows/desktop/ms646260.aspx)而不是推荐['SendInput'函数](http://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx)? –

+1

@CodyGray:我无法让SendInput工作。这OTOH完美运作。如果您有一个使用SendInput的C#示例,以像素为单位在屏幕坐标中发送鼠标点击...我希望看到它。 – mpen