delphi – 解释GetKeyState / GetCursorPos中的错误

前端之家收集整理的这篇文章主要介绍了delphi – 解释GetKeyState / GetCursorPos中的错误前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
有时我会收到客户的错误报告,我无法解释.在Delphi中的Application.Run()之后,我收到以下错误
EOSError: System error: Code:_5 Access denied

 Call Stack Information:
-------------------------------------------------------------------
|Address |Module     |Unit       |Class |Procedure       |Line    |
-------------------------------------------------------------------
|Running Thread: ID=4352; Priorität=0; Klasse=; [Main Thread]     |
|-----------------------------------------------------------------|
|772B291F|USER32.dll |           |      |GetKeyState     |        |
|772B7B96|USER32.dll |           |      |GetPropA        |        |
|772B7B5A|USER32.dll |           |      |GetPropA        |        |
|772A7BC5|USER32.dll |           |      |DispatchMessageA|        |
|772A7BBB|USER32.dll |           |      |DispatchMessageA|        |
|00A6D804|Program.exe|Program.dpr|      |                |803[369]|  // Application.Run
-------------------------------------------------------------------

EOsError: A call to an OS function Failed

Call Stack Information:
-------------------------------------------------------------------
|Address |Module     |Unit       |Class |Procedure       |Line    |
-------------------------------------------------------------------
|Running Thread: ID=2712; Priorität=0; Klasse=; [Main Thread]     |
|-----------------------------------------------------------------|
|7E379758|USER32.dll |           |      |GetCursorPos    |        |
|7E379ED9|USER32.dll |           |      |GetKeyState     |        |
|7E37B3FC|USER32.dll |           |      |CallNextHookEx  |        |
|7E380078|USER32.dll |           |      |GetPropA        |        |
|7E380042|USER32.dll |           |      |GetPropA        |        |
|7E3696C2|USER32.dll |           |      |DispatchMessageA|        |
|7E3696B8|USER32.dll |           |      |DispatchMessageA|        |
|00A6E823|Program.exe|Program.dpr|      |                |803[369]|  //Application.Run
-------------------------------------------------------------------

在这两种情况下,从Eurekalog提交的屏幕截图都是黑色的.

任何人都可以解释一下,这会导致GetCursorPos或GetKeyState失败的原因是什么?

解决方法

GetCursorPos的文档说:

The input desktop must be the current desktop when you call GetCursorPos. Call OpenInputDesktop to determine whether the current desktop is the input desktop. If it is not,call SetThreadDesktop with the HDESK returned by OpenInputDesktop to switch to that desktop.

在解锁工作站时,最常见的是犯规.在我的代码中,我将GetCursorPos替换为此变体:

function GetCursorPos(var lpPoint: TPoint): BOOL; stdcall;
(* The GetCursorPos API in user32 fails if it is passed a memory address >2GB 
   which breaks LARGEADDRESSAWARE apps.  We counter this by calling GetCursorInfo
   instead which does not suffer from the same problem.

   In addition we have had problems with GetCursorPos failing when called 
   immediately after a password protected screensaver or a locked workstation 
   re-authenticates. This problem initially appeared with XP SP1 and is brought 
   about because TMouse.GetCursorPos checks the return value of the GetCursorPos 
   API call and raises an OS exception if the API has Failed.
*)
var
  CursorInfo: TCursorInfo;
begin
  CursorInfo.cbSize := SizeOf(CursorInfo);
  Result := GetCursorInfo(CursorInfo);
  if Result then begin
    lpPoint := CursorInfo.ptScreenPos;
  end else begin
    lpPoint := Point(0,0);
  end;
end;

您可以使用自己喜欢的代码挂钩机制来替换GetCursorPos.我是这样做的:

RedirectProcedure(@Windows.GetCursorPos,@CodePatcher.GetCursorPos);

使用RedirectProcedure,如下所述:Patch routine call in delphi

事实证明,在我的特定情况下,GetCursorPos会失败,但GetCursorInfo不会失败.但正如评论中指出的那样,有些情况下GetCursorInfo也会失败.在这种情况下,您可能会发现安排补丁函数不返回False是有利的.

至于GetKeyState,我不确定那个.它很可能类似,但GetKeyState是我个人不熟悉的API.

猜你在找的Delphi相关文章