gpt4 book ai didi

delphi - 解释 GetKeyState/GetCursorPos 的错误

转载 作者:行者123 更新时间:2023-12-03 14:47:35 27 4
gpt4 key购买 nike

有时我会收到客户的错误报告,但我无法解释。在 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;

您可以使用您最喜欢的代码 Hook 机制来替换 GetCursorPos。我这样做是这样的:

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

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

事实证明,对于我的特定场景,GetCursorPos 会失败,但 GetCursorInfo 不会失败。但正如评论中指出的那样,在某些情况下 GetCursorInfo 也会失败。在这种情况下,您可能会发现安排修补后的函数不返回 False 是很方便的。

至于GetKeyState,我不确定。它很可能很相似,但 GetKeyState 是一个我个人并不熟悉的 API。

关于delphi - 解释 GetKeyState/GetCursorPos 的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20142166/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com