如何使SetCursorPos和/或SendInput在VM中工作?

时间:2019-02-12 03:15:50

标签: winapi virtual-machine

我有一个使用SetCursorPos定位光标的程序。该程序在实际硬件上运行时会按预期方式运行,但在VM(VMware工作站10.0.7)中运行时,它将无法正常运行。光标不移动。我试着改用SendInput(它造成的系统调用有所不同,因此我认为它可以工作),结果与SetCursorPos相同,它可以在真实硬件上运行,而在VM中运行时则无法运行。

问题是:是否有人可以使SetCursorPos或SendInput在VM中工作?如果可以,怎么办?也可以采用任何其他方法将光标定位在VM中可以工作的特定位置。

谢谢您的帮助。

对于任何想尝试的人,这是我尝试过的一些代码。

{$APPTYPE CONSOLE}

program ConsoleSetCursorPos;

uses
  Windows
  ;

function GetConsoleWindow : HWND; stdcall; external kernel32;

procedure DoIt;
var
  ConsoleWindow   : HWND;
  ClientRect      : TRECT;

  CursorPosRetVal : BOOL;
  LastError       : dword;

  Desktop         : HDESK;

begin
  // the code below is not normally necessary - for testing only

  Desktop       := OpenInputDesktop(0, false, WINSTA_WRITEATTRIBUTES);
  LastError     := GetLastError;

  writeln;
  writeln('From OpenInputDesktop');
  writeln('Last error (decimal) : ', LastError);

  if Desktop = 0 then
  begin
    writeln('Program terminated due to OpenInputDesktop failure');
    halt(255);
  end;

  if not SetThreadDesktop(Desktop) then
  begin
    writeln('Program terminated due to SetThreadDesktop failure');
    halt(255);
  end;

  writeln;

  // end of normally unnecessary code

  SetLastError(0);
  ConsoleWindow := GetConsoleWindow;

  GetClientRect(ConsoleWindow, ClientRect);

  ClientToScreen(ConsoleWindow, ClientRect.TopLeft);

  CursorPosRetVal := SetCursorPos(ClientRect.Left, ClientRect.Top);
  LastError       := GetLastError;

  if not CursorPosRetVal
  then writeln('SetCursorPos returned false (failed)')
  else writeln('SetCursorPos returned true  (succeeded)');

  writeln('Last error (decimal) : ', LastError);

  if Desktop <> 0 then CloseDesktop(Desktop);
end;

begin
  DoIt;
end.

1 个答案:

答案 0 :(得分:0)

关于SetCursorPos doc的评论:

  

光标是共享资源。窗口应仅移动光标   当光标位于窗口的工作区时。

     

调用过程必须对WINSTA_WRITEATTRIBUTES具有访问权限   窗口站。

     

呼叫时输入桌面必须是当前桌面   SetCursorPos。呼叫OpenInputDesktop以确定当前   桌面是输入桌面。如果不是,请致电SetThreadDesktop   OpenInputDesktop返回的HDESK切换到该桌面。

或者您也可以尝试与this answer一样从VM卸载鼠标驱动程序。