2013-03-18 4 views
9

Я использую этот Delphi 7 кода, чтобы обнаружить, если Internet Explorer работает:Почему FindWindow() не надежно на 100%?

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

Это работает на 99% систем с IE 8,9 и 10.

Но есть некоторые системы (к сожалению, ни один из моих, но у меня есть два бета-тестера, у которых есть такие системы, как Win7 x64 SP1), где FindWindow() возвращает 0 для IEFrame, даже если 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() не является надежным в некоторых системах?

+1

Есть несколько замечаний по [FindWindow] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms633499 (v = vs.85) .aspx) и [GetWindowText] (http : //msdn.microsoft.com/en-us/library/windows/desktop/ms633520 (v = vs.85) .aspx) в MSDN, которые могут предоставить некоторые подсказки. –

+9

Вместо того, чтобы переходить через окна вручную, вы должны использовать ['EnumWindows()'] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms633497.aspx). –

+1

Remy, EnumWindows() требуется функция обратного вызова, поэтому ее нельзя использовать во встроенном коде. В этом случае требуется обработка событий. И мне нужно будет зацикливаться после того, как EnumWindows() будет вызван ANYWAY. Я использую EnumWindows() в других приложениях, и это довольно медленно. Но с другой стороны, он все еще не объясняет, почему FindWindow() работает на 99% системах, но не на 1%. – Casady

ответ

1

Я предполагаю, что FindWindow объявлен для возврата WinHandle, который является THandle, который является Integer, который подписан. (По крайней мере, я думаю, что это было так много лет назад, когда я запрограммировал в Delphi.)

Если IE имеет дескриптор окна с верхним битом, то он будет отрицательным, так что ваш тест будет возвращать значение False:

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

Ручки окна обычно не имеют верхнего набора бит, но я не знаю, что это невозможно.

+0

Я уверен, что дескрипторы WinControl определены Microsoft как typedef void * HANDLE; - таким образом, они не могут быть отрицательными. Мне что-то не хватает? Но вы можете быть здесь. Придется проверить это. – Casady

+0

arx, я проверил определение HWND в Delphi 7: HWND = тип LongWord; поэтому он не может быть отрицательным. – Casady

+0

@casady Если это так, то> то же, что и <>, но что заставило вас выбрать>? Это то, что я вижу на удивление часто. Если окно не найдено, функция возвращает 0. Таким образом, отрицание = 0 равно <> 0. Я не могу представить, какая логика приводит к> 0. –

Смежные вопросы