为什么模拟鼠标单击(使用mouse_event)仅适用于所选组件?

时间:2010-07-14 07:04:10

标签: windows delphi winapi

我有多个游标(实际上是形式),可以通过各自的鼠标进行控制。 (1个用户的1个光标)。

我使用SetCursorPos将默认光标(原始系统光标)定位在不会从我的应用程序中移除焦点的位置,并使用ShowCursor(false)隐藏它。

我有一个获取鼠标和coordinates句柄的类。

当用户点击时,我使用SetCursorPosmouse_event模拟该特定位置的点击次数。

我的模拟鼠标点击仅适用于某些组件的OnClick事件(它应该只是按钮和标签,但我在项目中试验了一些内容,只是为了知道什么会起作用或不起作用):

适用于:

  • 按钮(TButton,TBitBtn,TAdvSmoothButton)
  • TAdvGrid
  • TMenuItem(仅限TMainMenu的直接子女)
  • TRadioButton

它无效:

  • 的TLabel
  • 面板(TPanel,TAdvSmoothPanel)
  • TCoolBar
  • TMenuItem(不是TMainMenu的直接子女)

这是我的代码:

 SetCursorPos(currentX , currentY);
 mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
 mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);

为什么它不适用于某些组件?是否有解决方法(因为我希望能够使用mouse_event单击标签)。

编辑: 我尝试检查点击功能是否真的被调用,所以我把ShowMessage('clicked');放在SetCursorPos和mouse_event之前...但奇怪的是一切(次要编辑:除了MenuItems之外的所有东西)现在工作正常(除了我有一个事实)每次我尝试点击某些内容时弹出消息)。有没有人知道为什么这样做?

3 个答案:

答案 0 :(得分:3)

实际上不推荐使用mouse_event,你应该使用SendInput,看看是否修复了任何东西(我还建议让鼠标移动输入消息,而不是使用SetCursorPos),如果你这样做是为了特定的应用程序,PostMessage可能是一个更好,更简单的替代方案

答案 1 :(得分:2)

似乎在这里工作;

procedure TForm1.Panel1Click(Sender: TObject);
begin
  ShowMessage('Click');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Pt: TPoint;
begin
  Pt := Panel1.ClientToScreen(Point(0, 0));
  SetCursorPos(Pt.x, Pt.y);
//  SetCursorPos(Panel1.ClientOrigin.x, Panel1.ClientOrigin.y);
  mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
  mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
end;

或,没有SetCursorPos;

procedure TForm1.Button1Click(Sender: TObject);
var
  Pt: TPoint;
begin
  Pt := Panel1.ClientToScreen(Point(0, 0));
  Pt.x := Round(((Pt.x + 1) * 65535) / Screen.Width);
  Pt.y := Round(((Pt.y + 1) * 65535) / Screen.Height);
  mouse_event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE or MOUSEEVENTF_LEFTDOWN,
      Pt.x, Pt.y, 0, 0);
  mouse_event(MOUSEEVENTF_ABSOLUTE or MOUSEEVENTF_MOVE or MOUSEEVENTF_LEFTUP,
      Pt.x, Pt.y, 0, 0);
end;

答案 2 :(得分:1)

它现在偶然起作用,那些组件可能已经捕获了鼠标。您需要在第2和第3个参数中传递鼠标指针坐标。因此:

 //SetCursorPos(currentX , currentY);
 mouse_event(MOUSEEVENTF_LEFTDOWN, currentX, currentY, 0, 0);
 mouse_event(MOUSEEVENTF_LEFTUP, currentX, currentY, 0, 0);