Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is FindWindow() not 100% reliable?

I'm using this Delphi 7 code to detect if Internet Explorer is running:

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

This works on 99% of the systems with IE 8,9 and 10.

But there are some systems (unfortunately none of mine, but I have two beta testers which have such systems, both Win7 x64 SP1) where FindWindow() returns 0 for IEFrame, even if IE is in memory.

So I've coded an alternate method to find the window:

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;

The alternate method works on 100% of all systems.

My question - why is FindWindow() not reliable on some of the systems?

like image 638
Casady Avatar asked Mar 18 '13 04:03

Casady


2 Answers

I'm guessing that FindWindow is declared to return a WinHandle, which is a THandle, which is an Integer, which is signed. (At least, I think this was the case many years ago when I programmed in Delphi.)

If IE has a window handle with the top bit set then it will be negative so your test will return False:

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

Window handles don't usually have the top bit set, but I don't know that it's impossible.

like image 178
arx Avatar answered Nov 02 '22 23:11

arx


According to Delphi Help, FindWindow(ClassName,WindowName) does not search child windows. This could be the reason for the 1% failures. Maybe in those two beta tester's systems the IEFrame window had WS_CHILD style set.

This would explain why the GetTopWindow/GetNextWindow loop works. GetTopWindow(hWndParent) retrieves the child window at the top of the Z order, and GetNextWindow(hWnd,Direction) retrieves the next child window in the Z order.

This could be tested by calling FindWindowEx(hWndParent,hWndChild,ClassName,WindowName), to see if it works where FindWindow() fails.

like image 2
Guy Gordon Avatar answered Nov 02 '22 22:11

Guy Gordon