Как заставить SetCursorPos и ​​/ или SendInput работать в виртуальной машине? - PullRequest
0 голосов
/ 12 февраля 2019

У меня есть программа, которая использует SetCursorPos для позиционирования курсора.Программа работает так, как предполагается при работе на реальном оборудовании, но при работе на ВМ (рабочая станция VMware 10.0.7) не работает.Курсор не двигается.Вместо этого я попытался использовать SendInput (системный вызов, который он делает, отличается, поэтому я подумал, что он может работать), результат такой же, как с SetCursorPos, он работает на реальном оборудовании, не работает при работе в виртуальной машине.

Вопрос в том, знает ли кто-нибудь, можно ли заставить SetCursorPos или SendInput работать на ВМ, и если да, то как?Любой другой способ позиционирования курсора в определенном месте, которое работает в ВМ, также приветствуется.

Спасибо за вашу помощь.

Для тех, кто хочет попробовать, вот некоторыекода, который я пробовал.

{$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 голосов
/ 13 февраля 2019

Как примечания по SetCursorPos doc :

Курсор является общим ресурсом.Окно должно перемещать курсор только тогда, когда курсор находится в клиентской области окна.

Вызывающий процесс должен иметь доступ WINSTA_WRITEATTRIBUTES к оконной станции.

Рабочий стол ввода должен быть текущим рабочим столом, когдаВы звоните SetCursorPos.Вызовите OpenInputDesktop , чтобы определить, является ли текущий рабочий стол входным рабочим столом.Если это не так, вызовите SetThreadDesktop с HDESK, возвращаемым OpenInputDesktop, чтобы переключиться на этот рабочий стол.

Или вы можете сделать такую ​​же попытку, чтобы удалить драйвер мыши изВМ как этот ответ .

...