鼠标在特定位置(特定窗口内)不移动光标单击/拖动(. net / c++)

本文关键字:单击 光标 拖动 c++ net 移动 定位 位置 鼠标 窗口 | 更新日期: 2023-09-27 18:08:58

我正在开发一个平滑鼠标光标移动的应用程序,这样人们就可以在绘图应用程序(如MS Pain, SAI等)中使用普通鼠标绘制漂亮的曲线。但是,我不希望我的应用程序实际移动鼠标光标,因为它的位置在平滑过程中使用。这意味着我必须让绘图应用程序忽略鼠标光标的实际位置,并为其提供假的,平滑移动的鼠标光标的位置。

你对实现这一目标有什么想法吗?


我的想法是获得目标窗口的处理程序,禁用它(因为它禁用输入,所以当我移动鼠标时,Windows不会向窗口宣布它),发送WM_LBUTTONDOWN,一系列WM_MOUSEMOVEs和WM_LBUTTONUP消息,然后再次启用窗口以获得所需的结果。

我很快把一些代码放在一起,但它不能正常工作。然后我注意到一些奇怪的事情。我拿走了禁用窗口的代码,以及WM_MOUSEMOVE消息。剩下的代码应该在目标窗口内执行简单的单击操作。然而,在大多数情况下,事实并非如此。当我试图用它点击MSPaint的画布时,什么也没发生,但是SendMessage返回0。但当我试图在VS2013或谷歌Chrome窗口内点击时,它工作得很好。(那现在怎么办?)

简化代码如下:

[DllImport("user32.dll", EntryPoint = "FindWindowA", SetLastError = true)]
static extern IntPtr FindWindow(IntPtr lpClassName, string lpWindowName);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern int SendMessage(IntPtr hWnd, int msg, int WParam, int LParam);
void ClickInsideAnotherWindow(string windowTitle, Point clickPos)
{
    IntPtr hWnd = FindWindow(IntPtr.Zero, windowTitle);
    //MSDN said:
    //The low-order word specifies the x-coordinate of the cursor.
    //The high-order word specifies the y-coordinate of the cursor.  
    //
    //The following line of code does the trick by shifting 
    //the Y coordinate by 16 and ORing it with the X coordinate.
    int lParam = ((clickPos.Y << 16) | clickPos.X);
    SendMessage(hWnd, 0x0201, 0, lParam);
    System.Threading.Thread.Sleep(10); //Wait 10ms, just to be sure...
    SendMessage(hWnd, 0x0202, 0, lParam);
    //0x201 is equivalent to WM_LBUTTONDOWN, while
    //0x202 is equivalent to WM_LBUTTONUP
}


所以我想手动发送鼠标事件到一个窗口,而它忽略了真正的光标位置。

我主要用c#编码,但如果在c++中更容易得到这个工作,我会使用它(可能会制作一个dll,如果是这样的话)。如果我的话让你难以理解,我很抱歉,我已经尽力解释了。

请帮我解决这个问题!

鼠标在特定位置(特定窗口内)不移动光标单击/拖动(. net / c++)

当使用Send/PostMessage时,一些窗口必须在前台,一些窗口必须有焦点。

在某些使用DirectX或其他特殊屏幕绘制方法的应用程序中,窗口必须位于鼠标指针下方。

我不知道这到底是为什么。

你可能有一个尝试AttachThreadInput和SetForegroundWindow/SwitchToThisWindow和SetFocus,与一些三个组合,它应该工作。