Конференция "Прочее" » Как определить что приложение загрузило GUI
 
  • Штырлиц (28.09.10 19:33) [0]
    Как можно определить что приложение загрузило визуальную оболочку или что визуальной оболочки нет.

    Есть ряд приложений с визуальной оболочкой, например загружаю фильм проигрывателем, он подвисает и сразу не показывает визуальную оболочку, но она у него есть. Как можно определить есть ли у приложения визуальная оболочка при загрузке или в противном случае её нет. Оболочка может загружаться через WinApi.
  • Хук (29.09.10 11:02) [1]
    Хук на создание окна?
    См. в MSDN: SetWindowsHookEx, WH_CBT, HCBT_CREATEWND.
  • 12 © (29.09.10 11:27) [2]
    перебрать окна, проверить процесс, родивший
  • DiamondShark © (29.09.10 13:16) [3]
    1. В грамотном вопросе содержится значительная часть ответа.

    Щито есть "визуальная оболочка"?
    Возможно, что решение будет тупо следовать из определения.

    2. Основной вопрос системотехники.

    А нафига?
  • Сергей М. © (29.09.10 13:27) [4]

    > Штырлиц


    Вопрос тебе на засыпку: загружает ли нижеследующее приложение "визуальную оболочку" ?

    program Foo;
    ..
    begin
     Application.Run;
    end.
  • DiamondShark © (29.09.10 13:33) [5]

    > Вопрос тебе на засыпку:

    Это вопрос из разряда: "Кузявы ли бутявки?"
    От определения зависит.
  • han_malign (29.09.10 14:04) [6]
    WaitForInputIdle
  • George © (29.09.10 14:16) [7]

    > Сергей М. ©   (29.09.10 13:27) [4]

    Ну там же не видать окошка, значит невизуально. :)
  • Сергей М. © (29.09.10 14:24) [8]

    > George ©   (29.09.10 14:16) [7]


    > там же не видать окошка, значит невизуально


    Ну если следовать такому определению "визуальности", то решение простое как проще некуда:

    CapturedScreenImage := CaptureCurrentScreenImage;
    if RecognizeWindowImage(CapturedScreenImage) then визуальное;

    )
  • George © (29.09.10 14:49) [9]

    > Сергей М. ©   (29.09.10 14:24) [8]

    С тем допущением, что если окошку свернули, она стала невизуальной и детектиться не будет. А так нормалек. :)
  • Сергей М. © (29.09.10 14:56) [10]

    > если окошку свернули


    У объекта Application окошко как раз и не свернуто после создания. Нормалек ?)
  • George © (29.09.10 15:38) [11]

    > Сергей М. ©   (29.09.10 14:56) [10]

    Не, я про

    CapturedScreenImage := CaptureCurrentScreenImage;
    if RecognizeWindowImage(CapturedScreenImage) then визуальное;

    Т.е. если окошко будет свернуто, то RecognizeWindowImage вернет false, ну и будем считать, что если его свернули, то приложение стало невизуальным. :)
  • Штырлиц (30.09.10 04:34) [12]
    Допустим, я загружаю фильм. Практика показала, что если хватать после запуска приложения его хэндлы и смотреть наличие форм, то не всегда это срабатывает.

    Это все из-за того, что при запуске может происходить какая-то обработка в приложении, после чего загружается визуалка. Эта обработка может длиться от 0 до N секунд\минут или приложение просто подвисает. Т.С. Ставить задержку бессмысленно, нужна скорая обработка, а не задержка в пару минуты.

    А теперь вопрос, зацепит ли это при таком раскладе.
    Хук
    Хук на создание окна?
    См. в MSDN: SetWindowsHookEx, WH_CBT, HCBT_CREATEWND.



    Второй вариант. han_malign
     DWORD dwWaitResult;
     for (;;)
     {
       do
       {
         // Ждем пока процесс не проинициализируеться
         //
         dwWaitResult = WaitForInputIdle (prcHandle, 1000);
       }

       while (dwWaitResult == WAIT_TIMEOUT);

       if (dwWaitResult == 0)
       {
         // прикладуха что-то сделала
         //
         if (NULL != FindWindow ("ClassName","Text"))
           break; // for (;;)
       }

       else // if (dwWaitResult == WAIT_FAILED)
       {
         // что-то сдохло
         //
         break;
       }


     } // for (;;)



    Это грамотный вариант с задержкой?
  • Юрий Зотов © (30.09.10 13:14) [13]

    > Штырлиц   (30.09.10 04:34) [12]

    Если нужно дождаться создания окна, то WaitForInputIdle, только проще:

    do while (WaitForInputIdle (prcHandle, 1000) == WAIT_TIMEOUT);
  • 0x00FF00 © (30.09.10 18:40) [14]

    > Юрий Зотов ©   (30.09.10 13:14) [13]

    Отвечаете на delphimasters сишным кодом?
    Оригинально =)
  • tesseract © (01.10.10 00:11) [15]
    Сразу вспоминается предложение директора отдела тестирования MS  бить за такие  извращенные алгоритмы по рукам линейкой.
  • Юрий Зотов © (01.10.10 00:22) [16]

    > 0x00FF00 ©   (30.09.10 18:40) [14]

    Увы. Кажется, я уже всё пишу на псевдокоде, а конкретный код - пофиг. Причем практическую программму под конкретный компилятор - тоже пишу на псевдокоде.

    Самое странное, что компилируется. И даже работает. Внешне, по крайне мере.
    :o)
  • Сергей М. © (01.10.10 00:50) [17]

    > Штырлиц   (30.09.10 04:34) [12]


    WaitForInputIdle() ждет всего-навсего факт существования окна, не более того.
    А имеет ли это окно какое-то отношение к какой-то там "визуалке" или не имеет - то функции WaitForInputIdle ниже колена.
  • Штырлиц (01.10.10 07:25) [18]
    А вообще возможно без этих телодвижений узнать есть ли окно при загрузке процесса. Ждать не могу, может есть какие-то удобные отладочные примеры.

    Прогнал через отладчик процесс - узнал есть ли код создания окна..
  • Штырлиц (01.10.10 08:03) [19]
    Есть вариант хватать subsystem из PE информации о заголовке. Но тут одно но, возможно гуй грузится через API или из отдельной dll.
  • Юрий Зотов © (01.10.10 13:22) [20]

    > Штырлиц   (01.10.10 07:25) [18]

    Посмотреть, есть ли CreateWindow(Ex) в секции импорта?
  • Штырлиц (01.10.10 16:08) [21]
    Первый раз слышу о 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 хотя хендлов и формы нет у приложения.
  • Lamer@fools.ua © (01.10.10 16:25) [22]
    >>tesseract ©   (01.10.10 00:11) [15]

    >Сразу вспоминается предложение директора отдела тестирования MS  бить за такие  извращенные алгоритмы по рукам линейкой.
    Я бы после слова "предложение" поставил двоеточие :)
  • coder123 (01.10.10 16:40) [23]

    > 01.10.10 00:11

    вау!
  • Штырлиц (02.10.10 09:24) [24]
    Вопрос открыт.
    > Сразу вспоминается предложение директора отдела тестирования
    > MS  бить за такие  извращенные алгоритмы по рукам линейкой.
    >
  • Cobalt © (14.10.10 15:00) [25]
    В абстрактном случае - установить тайм-аут, после которого проверять на существование видимых окон, принадлежащих созданному процессу, поскольку именно это означает для пользователя "визуальной оболочки".

    К сожалению, программистские термины далеко не всегда совпадают с разумением юзера :-(
  • Cobalt © (14.10.10 15:00) [26]
    P.S.
    Если тебе это надо для написания своей оболочки виндов, то для окон верхнего уровня есть специальный флаг, который и надо проверять в хуке на создание окон.
  • han_malign (14.10.10 17:21) [27]

    > do while (WaitForInputIdle (prcHandle, 1000) == WAIT_TIMEOUT);

    WaitForInputIdle(prcHandle, INFINITE);
    if(WaitForSingleObject(prcHandle, 0) = WAIT_OBJECT_0)then
       ...//у приложения таки не было GUI


    MSDN: The WaitForInputIdle method only works with processes that have a user interface.

    - правда надо проверить что WaitForInputIdle(..., INFINITE) отобьется при завершении процесса...


    > есть ли CreateWindow(Ex) в секции импорта?

    - окно консоли создается системой или наследуется от родительского приложения...

    есть еще GetGuiResources(), но толку от него в данном контексте мало...
  • _VirEx_ (17.10.10 22:26) [28]
    Form1.Loaded
    if Form1.ComponentState=csLoading
 
Конференция "Прочее" » Как определить что приложение загрузило GUI
Есть новые Нет новых   [134431   +13][b:0][p:0.002]