编译器不喜欢INVALID_HANDLE_VALUE

时间:2018-09-04 10:44:25

标签: delphi winapi delphi-10.1-berlin

我尝试从其窗口句柄确定进程的名称(包括路径):

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错误]:E1012常量表达式违反了子范围边界

然后,一段时间后(随机),编译器会抱怨此行,并且通过停用此行并重新激活前一行来重新开始游戏。这是无限的。怎么了?

1 个答案:

答案 0 :(得分:0)

发生错误是因为INVALID_HANDLE_VALUE被定义为:

 INVALID_HANDLE_VALUE = THandle(-1);

其中

 THandle = NativeUInt;

在64位平台上,这使INVALID_HANDLE_VALUE的大小为8个字节。分配给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

     

类型:LPDWORD

     

指向接收进程标识符的变量的指针。如果这   参数不为NULL,GetWindowThreadProcessId复制标识符   变量的过程;否则,不会。

因此,如果您想使用此方法检索PID值,则只需传入变量,而不对其执行任何操作即可。如果没有,只需传递0