编译器不喜欢 INVALID_HANDLE_VALUE
Compiler does not like INVALID_HANDLE_VALUE
我尝试从其 window 句柄确定进程的名称(包括路径):
function PAGetProcessNameFromWnd(Wnd: HWND): string;
var
ThisList: TStringList;
PID: DWORD;
I: Integer;
begin
Result := '';
if Winapi.Windows.IsWindow(Wnd) then
begin
PID := Winapi.Windows.INVALID_HANDLE_VALUE;
//PID := SysUtils.INVALID_HANDLE_VALUE;
Winapi.Windows.GetWindowThreadProcessId(Wnd, @PID);
ThisList := TStringList.Create;
try
if JclSysInfo.RunningProcessesList(ThisList, True) then
begin
I := ThisList.IndexOfObject(Pointer(PID));
if I > -1 then
Result := ThisList[I];
end;
finally
ThisList.Free;
end;
end;
end;
当我构建应用程序时,我经常在这一行遇到编译器错误:
PID := Winapi.Windows.INVALID_HANDLE_VALUE;
然后我通过注释停用该行并通过取消注释激活后续行:
PID := SysUtils.INVALID_HANDLE_VALUE;
错误是:
[dcc64 Error]: E1012 Constant expression violates subrange bounds
然后过了一会儿(随机)编译器抱怨这一行,游戏通过停用这一行并重新激活前一行来重新启动。如此循环往复。这里有什么问题?
错误发生是因为INVALID_HANDLE_VALUE
被定义为:
INVALID_HANDLE_VALUE = THandle(-1);
哪里
THandle = NativeUInt;
在 64 位平台上,这给出 INVALID_HANDLE_VALUE
八个字节的大小。分配给 DWORD
(四个字节)是有问题的,因为值 (-1) 会溢出,这在编译时是已知的。 INVALID_HANDLE_VALUE
在这里不合适,因为句柄是本机指针的大小,而 PID 始终是 DWORD - 您需要的是 PID,而不是句柄。
GetWindowThreadProcessId
有两个签名:
function GetWindowThreadProcessId(hWnd: HWND; lpdwProcessId: Pointer): DWORD; external minuser name 'GetWindowThreadProcessId';
function GetWindowThreadProcessId(hWnd: HWND; var dwProcessId: DWORD): DWORD; external minuser name 'GetWindowThreadProcessId';
在任何一种情况下,都不需要初始化 PID
变量。来自 documentation :
lpdwProcessId
Type: LPDWORD
A pointer to a variable that receives the process identifier. If this
parameter is not NULL, GetWindowThreadProcessId copies the identifier
of the process to the variable; otherwise, it does not.
因此,如果您想使用此方法检索 PID 值,则只需传入一个变量而不对其进行任何操作。如果没有,就传 0
.
我尝试从其 window 句柄确定进程的名称(包括路径):
function PAGetProcessNameFromWnd(Wnd: HWND): string;
var
ThisList: TStringList;
PID: DWORD;
I: Integer;
begin
Result := '';
if Winapi.Windows.IsWindow(Wnd) then
begin
PID := Winapi.Windows.INVALID_HANDLE_VALUE;
//PID := SysUtils.INVALID_HANDLE_VALUE;
Winapi.Windows.GetWindowThreadProcessId(Wnd, @PID);
ThisList := TStringList.Create;
try
if JclSysInfo.RunningProcessesList(ThisList, True) then
begin
I := ThisList.IndexOfObject(Pointer(PID));
if I > -1 then
Result := ThisList[I];
end;
finally
ThisList.Free;
end;
end;
end;
当我构建应用程序时,我经常在这一行遇到编译器错误:
PID := Winapi.Windows.INVALID_HANDLE_VALUE;
然后我通过注释停用该行并通过取消注释激活后续行:
PID := SysUtils.INVALID_HANDLE_VALUE;
错误是:
[dcc64 Error]: E1012 Constant expression violates subrange bounds
然后过了一会儿(随机)编译器抱怨这一行,游戏通过停用这一行并重新激活前一行来重新启动。如此循环往复。这里有什么问题?
错误发生是因为INVALID_HANDLE_VALUE
被定义为:
INVALID_HANDLE_VALUE = THandle(-1);
哪里
THandle = NativeUInt;
在 64 位平台上,这给出 INVALID_HANDLE_VALUE
八个字节的大小。分配给 DWORD
(四个字节)是有问题的,因为值 (-1) 会溢出,这在编译时是已知的。 INVALID_HANDLE_VALUE
在这里不合适,因为句柄是本机指针的大小,而 PID 始终是 DWORD - 您需要的是 PID,而不是句柄。
GetWindowThreadProcessId
有两个签名:
function GetWindowThreadProcessId(hWnd: HWND; lpdwProcessId: Pointer): DWORD; external minuser name 'GetWindowThreadProcessId';
function GetWindowThreadProcessId(hWnd: HWND; var dwProcessId: DWORD): DWORD; external minuser name 'GetWindowThreadProcessId';
在任何一种情况下,都不需要初始化 PID
变量。来自 documentation :
lpdwProcessId
Type: LPDWORD
A pointer to a variable that receives the process identifier. If this parameter is not NULL, GetWindowThreadProcessId copies the identifier of the process to the variable; otherwise, it does not.
因此,如果您想使用此方法检索 PID 值,则只需传入一个变量而不对其进行任何操作。如果没有,就传 0
.