有时我会收到客户的错误报告,但我无法解释。在 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
-------------------------------------------------------------------
and
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 says:
调用GetCursorPos时输入的桌面必须是当前桌面。调用OpenInputDesktop判断当前桌面是否为输入桌面。如果不是,请使用 OpenInputDesktop 返回的 HDESK 调用 SetThreadDesktop 以切换到该桌面。
您可能会遇到这种情况,最常见的是在解锁工作站时。在我的代码中我替换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);
with RedirectProcedure
如此处所述:delphi 中的补丁例程调用
事实证明,对于我的特定场景,GetCursorPos
会失败,但是GetCursorInfo
不会失败。但正如评论中指出的,有些情况下GetCursorInfo
也会失败。在这种情况下,您可能会发现安排修补后的函数不返回是很方便的False
.
As for GetKeyState
,我对此不太确定。很可能很相似,但是GetKeyState
是一个我个人并不熟悉的API。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)