-
Как можно определить что приложение загрузило визуальную оболочку или что визуальной оболочки нет.
Есть ряд приложений с визуальной оболочкой, например загружаю фильм проигрывателем, он подвисает и сразу не показывает визуальную оболочку, но она у него есть. Как можно определить есть ли у приложения визуальная оболочка при загрузке или в противном случае её нет. Оболочка может загружаться через WinApi.
-
Хук на создание окна?
См. в MSDN: SetWindowsHookEx, WH_CBT, HCBT_CREATEWND.
-
перебрать окна, проверить процесс, родивший
-
1. В грамотном вопросе содержится значительная часть ответа.
Щито есть "визуальная оболочка"?
Возможно, что решение будет тупо следовать из определения.
2. Основной вопрос системотехники.
А нафига?
-
> Штырлиц
Вопрос тебе на засыпку: загружает ли нижеследующее приложение "визуальную оболочку" ?
program Foo;
..
begin
Application.Run;
end.
-
> Вопрос тебе на засыпку:
Это вопрос из разряда: "Кузявы ли бутявки?"
От определения зависит.
-
WaitForInputIdle
-
> Сергей М. © (29.09.10 13:27) [4]
Ну там же не видать окошка, значит невизуально. :)
-
> George © (29.09.10 14:16) [7]
> там же не видать окошка, значит невизуально
Ну если следовать такому определению "визуальности", то решение простое как проще некуда:
CapturedScreenImage := CaptureCurrentScreenImage;
if RecognizeWindowImage(CapturedScreenImage) then визуальное;
)
-
> Сергей М. © (29.09.10 14:24) [8]
С тем допущением, что если окошку свернули, она стала невизуальной и детектиться не будет. А так нормалек. :)
-
> если окошку свернули
У объекта Application окошко как раз и не свернуто после создания. Нормалек ?)
-
> Сергей М. © (29.09.10 14:56) [10]
Не, я про
CapturedScreenImage := CaptureCurrentScreenImage;
if RecognizeWindowImage(CapturedScreenImage) then визуальное;
Т.е. если окошко будет свернуто, то RecognizeWindowImage вернет false, ну и будем считать, что если его свернули, то приложение стало невизуальным. :)
-
Допустим, я загружаю фильм. Практика показала, что если хватать после запуска приложения его хэндлы и смотреть наличие форм, то не всегда это срабатывает.
Это все из-за того, что при запуске может происходить какая-то обработка в приложении, после чего загружается визуалка. Эта обработка может длиться от 0 до N секунд\минут или приложение просто подвисает. Т.С. Ставить задержку бессмысленно, нужна скорая обработка, а не задержка в пару минуты.
А теперь вопрос, зацепит ли это при таком раскладе.
Хук
Хук на создание окна?
См. в MSDN: SetWindowsHookEx, WH_CBT, HCBT_CREATEWND.
Второй вариант.
han_malign DWORD dwWaitResult;
for (;;)
while (dwWaitResult == WAIT_TIMEOUT);
if (dwWaitResult == 0)
else
}
Это грамотный вариант с задержкой?
-
> Штырлиц (30.09.10 04:34) [12]
Если нужно дождаться создания окна, то WaitForInputIdle, только проще:
do while (WaitForInputIdle (prcHandle, 1000) == WAIT_TIMEOUT);
-
> Юрий Зотов © (30.09.10 13:14) [13]
Отвечаете на delphimasters сишным кодом?
Оригинально =)
-
Сразу вспоминается предложение директора отдела тестирования MS бить за такие извращенные алгоритмы по рукам линейкой.
-
> 0x00FF00 © (30.09.10 18:40) [14]
Увы. Кажется, я уже всё пишу на псевдокоде, а конкретный код - пофиг. Причем практическую программму под конкретный компилятор - тоже пишу на псевдокоде.
Самое странное, что компилируется. И даже работает. Внешне, по крайне мере.
:o)
-
> Штырлиц (30.09.10 04:34) [12]
WaitForInputIdle() ждет всего-навсего факт существования окна, не более того.
А имеет ли это окно какое-то отношение к какой-то там "визуалке" или не имеет - то функции WaitForInputIdle ниже колена.
-
А вообще возможно без этих телодвижений узнать есть ли окно при загрузке процесса. Ждать не могу, может есть какие-то удобные отладочные примеры.
Прогнал через отладчик процесс - узнал есть ли код создания окна..
-
Есть вариант хватать subsystem из PE информации о заголовке. Но тут одно но, возможно гуй грузится через API или из отдельной dll.
-
> Штырлиц (01.10.10 07:25) [18]
Посмотреть, есть ли CreateWindow(Ex) в секции импорта?
-
Первый раз слышу о CreateWindow(Ex) в импорте.
В импорте можно зацепиться за
; Imports from USER32.dll
;
extrn ScreenToClient
extrn GetWindowRect
extrn SetClassLongA
extrn IsWindowEnabled
extrn SetWindowPos
Но если взять вызов Api GUI то тут может быть импорт только
; Imports from kernel32.dll
;
extrn LoadLibraryA
extrn GetProcAddress
extrn VirtualAlloc
extrn VirtualFree
Зато subsystem может показать Win32 GUI. Но это не панацея, если взять в пример, что взяв консольный проект на дельфи и убрав консольный вывод -- PЕ заголовок показывает Win32 GUI хотя хендлов и формы нет у приложения.
-
>>tesseract © (01.10.10 00:11) [15]
>Сразу вспоминается предложение директора отдела тестирования MS бить за такие извращенные алгоритмы по рукам линейкой.
Я бы после слова "предложение" поставил двоеточие :)
-
> 01.10.10 00:11
вау!
-
Вопрос открыт.
> Сразу вспоминается предложение директора отдела тестирования
> MS бить за такие извращенные алгоритмы по рукам линейкой.
>
-
В абстрактном случае - установить тайм-аут, после которого проверять на существование видимых окон, принадлежащих созданному процессу, поскольку именно это означает для пользователя "визуальной оболочки".
К сожалению, программистские термины далеко не всегда совпадают с разумением юзера :-(
-
P.S.
Если тебе это надо для написания своей оболочки виндов, то для окон верхнего уровня есть специальный флаг, который и надо проверять в хуке на создание окон.
-
> do while (WaitForInputIdle (prcHandle, 1000) == WAIT_TIMEOUT);
WaitForInputIdle(prcHandle, INFINITE);
if(WaitForSingleObject(prcHandle, 0) = WAIT_OBJECT_0)then
...
MSDN: The WaitForInputIdle method only works with processes
that have a user interface.
- правда надо проверить что WaitForInputIdle(..., INFINITE) отобьется при завершении процесса...
> есть ли CreateWindow(Ex) в секции импорта?
- окно консоли создается системой или наследуется от родительского приложения...
есть еще GetGuiResources(), но толку от него в данном контексте мало...
-
Form1.Loaded
if Form1.ComponentState=csLoading