为什么FindWindow()不是100%可靠?

时间:2013-03-18 04:16:23

标签: delphi winapi delphi-7

我正在使用此Delphi 7代码来检测Internet Explorer是否正在运行:

function IERunning: Boolean;
begin
  Result := FindWindow('IEFrame', NIL) > 0;
end;

这适用于使用IE 8,9和10的99%的系统。

但是有一些系统(不幸的是我没有,但我有两个beta测试人员都有这样的系统,都是Win7 x64 SP1),其中FindWindow()为IEFrame返回0,即使IE在内存中也是如此。

所以我编写了另一种方法来查找窗口:

function IERunningEx: Boolean;
var WinHandle : HWND;
    Name: array[0..255] of Char;
begin
  Result := False; // assume no IE window is present

  WinHandle := GetTopWindow(GetDesktopWindow);

  while WinHandle <> 0 do // go thru the window list
  begin
      GetClassName(WinHandle, @Name[0], 255);
      if (CompareText(string(Name), 'IEFrame') = 0) then
      begin // IEFrame found
          Result := True;
          Exit;             
      end;
      WinHandle := GetNextWindow(WinHandle, GW_HWNDNEXT);
  end;      
end;

替代方法适用于所有系统的100%。

我的问题 - 为什么FindWindow()在某些系统上不可靠?

2 个答案:

答案 0 :(得分:1)

我猜测FindWindow被声明为返回WinHandle,这是一个THandle,它是一个Integer,它是签名的。 (至少,我认为这是多年前我在Delphi编程的情况。)

如果IE有一个顶部位设置的窗口句柄,则它将为负数,因此您的测试将返回False:

Result := FindWindow('IEFrame', NIL) > 0;

窗口句柄通常不会设置最高位,但我不知道这是不可能的。

答案 1 :(得分:1)

根据Delphi帮助,FindWindow(ClassName,WindowName)不会搜索子窗口。这可能是1%失败的原因。也许在这两个beta测试人员的系统中,IEFrame窗口设置了WS_CHILD样式。

这将解释为什么GetTopWindow / GetNextWindow循环起作用。 GetTopWindow(hWndParent)检索Z顺序顶部的子窗口,而GetNextWindow(hWnd,Direction)检索Z顺序的下一个子窗口。

可以通过调用FindWindowEx(hWndParent,hWndChild,ClassName,WindowName)进行测试, 看看它在FindWindow()失败的地方是否可行。