2011-08-28 165 views
3

我正在寻找一种方法来将鼠标点击发送到Windows上的后台应用程序(即通过句柄),我用来确认我的代码的测试窗口正在接受并处理点击,但我的目标应用程序不虽然Spy ++显示消息)。什么会导致PostMessage发送的鼠标点击被忽略?

这可能是什么原因造成的?有没有解决办法?

这里是我使用的C#代码。

public enum WMessages : int 
{ 
    WM_LBUTTONDOWN = 0x201, 
    WM_LBUTTONUP = 0x202, 

    WM_KEYDOWN = 0x100, 
    WM_KEYUP = 0x101, 

    WH_KEYBOARD_LL = 13, 
    WH_MOUSE_LL = 14, 
} 

[return: MarshalAs(UnmanagedType.Bool)] 
[DllImport("user32.dll", SetLastError = true)] 
private static extern int PostMessage(HandleRef hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); 

public void SendClick(WMessages type, Point pos) 
{ 
    switch(type) 
    { 
     case WMessages.WM_LBUTTONDOWN: 
      PostMessage(new HandleRef(null, this.process.MainWindowHandle), 
       (UInt32)WMessages.WM_LBUTTONDOWN, (IntPtr)0x1, 
       (IntPtr)((pos.Y << 16) | (pos.X & 0xFFFF))); 
      return; 
     case WMessages.WM_LBUTTONUP: 
      PostMessage(new HandleRef(null, this.process.MainWindowHandle), 
       (UInt32)WMessages.WM_LBUTTONDOWN, (IntPtr)0x1, 
       (IntPtr)((pos.Y << 16) | (pos.X & 0xFFFF))); 
      return; 
     default: 
      return; 
    } 
} 

SendClick(WMessages.WM_LBUTTONDOWN, Cursor.Position); 
SendClick(WMessages,WM_LBUTTONUP, Cursor.Position); 

这是可能实现?有没有更好的方法来实现这个目标?

注意:上述代码在应用程序处于活动状态并且鼠标悬停在正确位置时不起作用。我也在专门将输入发送到后台应用程序,所以SendInput和其他人无法解决问题。

谢谢

+0

你怎么知道,如果你看到经历的信息它不工作?可能是因为你的位置是错误的,它得到它但没有做任何事情,因为它是它的区域外的点击 –

+0

要使用HWND将屏幕坐标(即'Cursor.Position')转换为客户端坐标,请使用http://msdn.microsoft .com/en-us/library/dd162952(v = vs.85).aspx –

+0

您的pinvoke声明是错误的。使用pinvoke.net找到正确的。 –

回答

2

您是否试过SendMessage调用而不是PostMessage? SendMessage立即调用窗口的处理程序。 PostMessage将消息放在列表中供以后处理。

+1

SendMessage只是在调用类PostMessage机制来将消息发送到目标进程时冻结调用进程。只有在窗口处于同一进程中时,该调用才立即进行。此外,SendMessage在来自不同进程的SendMessage调用中调用的消息处理程序中失败 - 以防当进程彼此等待时发生死锁。请记住,COM调用另一个pocesses中的COM对象在内部使用SendMessage - 所以不要直接在COM对象方法中调用SendMessage ....天哪,Win32是一团糟...... –

3
 public void SendClick(WMessages type, Point pos) 
{ 
    switch(type) 
    { 
     case WMessages.WM_LBUTTONDOWN: 
      PostMessage(new HandleRef(null, this.process.MainWindowHandle), 
       (UInt32)WMessages.WM_LBUTTONDOWN, (IntPtr)0x1, 
       (IntPtr)((pos.Y << 16) | (pos.X & 0xFFFF))); 
      return; 
     case WMessages.WM_LBUTTONUP: 
      PostMessage(new HandleRef(null, this.process.MainWindowHandle), 
       (UInt32)WMessages.WM_LBUTTONDOWN, (IntPtr)0x1, // <--(2) but you are telling to do WM_LBUTTONDOWN 
       (IntPtr)((pos.Y << 16) | (pos.X & 0xFFFF))); 
      return; 
     default: 
      return; 
    } 
} 

SendClick(WMessages.WM_LBUTTONDOWN, Cursor.Position); 
SendClick(WMessages.WM_LBUTTONUP, Cursor.Position); // <--(1) you are sending WM_LBUTTONUP 

所以刚才读(1)第(2)然后,你的问题就解决了