Список окон приложений

Discussion in 'WASM.WIN32' started by maxdiver, Apr 1, 2007.

  1. maxdiver

    maxdiver Max

    Blog Posts:
    0
    Подскажите пожалуйста: Как получить список окон приложений, т.е. список тех окон, которые отображаются на Панели Задач?
    Попытался найти что-нибудь в MSDN, но что-то ничего подходящего не нашел.
     
  2. wasm_test

    wasm_test wasm test user

    Blog Posts:
    0
    EnumWindows
     
  3. maxdiver

    maxdiver Max

    Blog Posts:
    0
    Да она возвращает окна, которые не являются дочерними. Однако сколько окон она возвращает! Там явно не те окна, которые на Панели задач. Даже если наложить условие, чтобы стиль был WS_VISIBLE, все равно окон слишком много. Например, у WinAmp'а там несколько окон, каждое из которых не зависит от остальных
     
  4. Nouzui

    Nouzui New Member

    Blog Posts:
    0
    там много какие нужно исключать.. со сброшенным WS_VISIBLE, с установленным WS_EX_TOOLWINDOW и еще какие-то, сам точно не знаю..
     
  5. wasm_test

    wasm_test wasm test user

    Blog Posts:
    0
    Еще есть занятный интерфейс ITaskBarList, но там можно только добавить или убрать окно... а как получить список - хз .
    Вот тут (http://forum.antichat.ru/thread30055.html) была проблема определения HWND окна по кнопке на таскбаре.. и кажется ее решили. Советую прочитать:
    отсюда алгоритм - перечисляем кнопки таскбара и лдя каждой получаем HWND
     
  6. krid24

    krid24 Member

    Blog Posts:
    0
    Code (Text):
    1. BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
    2. {
    3.  if (IsWindowVisible(hwnd) && !GetParent(hwnd) && !GetWindow(hwnd,GW_OWNER) &&
    4.  !(GetWindowLong(hwnd,GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
    5.  {
    6.     // кнопка на таскбаре
    7.  }
    8.  return TRUE;
    9. }
    10.  
    11. ...
    12.  
    13. EnumWindows(EnumWindowsProc,0);
     
  7. maxdiver

    maxdiver Max

    Blog Posts:
    0
    Спасибо.
    От себя добавлю только, что проверки на окно-родитель не нужны - EnumWindows и так перечисляет только окна верхнего уровня. Таким образом, окончательный код выглядит так:
    Code (Text):
    1. BOOL STDCALL EnumWindowsProc (HWND hwnd, LPARAM lp)
    2. {
    3.     if (IsWindowVisible (hwnd) && !(GetWindowLong (hwnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
    4.         // найдено окно
    5.     return TRUE;
    6. }
     
  8. krid24

    krid24 Member

    Blog Posts:
    0
    Проверки нужны, т.к. EnumWindows перечисляет некоторые окна (многие апплеты панели управления, системные диалоги, etc.), имеющие и родителя и владельца (OWNER). Кнопки на панели задач у них нет, но без проверки на Parent и Owner в твой список они все равно попадут (хоть у них и установлен WS_VISIBLE и сброшен WS_EX_TOOLWINDOW).
     
  9. asmfan

    asmfan New Member

    Blog Posts:
    0
    Просто это уже из разряда трюков - окно скрывалось с панели задач, путём присвоения ему (создания для него) невидимого родителя. (WS_EX_TOOLWINDOW не использовался)
    // а кстати чем отличаются результаты GetParent(hwnd) и GetWindow(hwnd,GW_OWNER)?
     
  10. wasm_test

    wasm_test wasm test user

    Blog Posts:
    0
    дык можно просто дернуть ITaskBarList::lol: eleteTab
     
  11. asmfan

    asmfan New Member

    Blog Posts:
    0
    Там всё хитрее - при альттабинге, если не ошибаюсь (давно с этим работал), опять на таскбаре появляется кнопа.
    В общем так - если окно теряет фокус а потом снова его приобретает - кнопа появляется. Так по-моему было. Поэтому этот вариант работы с кнопой на таскбаре я отмёл для себя.
     
  12. wasm_test

    wasm_test wasm test user

    Blog Posts:
    0
    Так и есть =) Можно по WM_SETFOCUS делать DeleteTab снова.
     
  13. kero

    kero Модератор SOURCES & 2LZ Staff Member

    Blog Posts:
    0
    krid24

    >BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
    >{
    > if (IsWindowVisible(hwnd) && !GetParent(hwnd) && !GetWindow(hwnd,GW_OWNER) &&
    > !(GetWindowLong(hwnd,GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
    > {
    > // кнопка на таскбаре
    > }
    > return TRUE;
    >}
    >...
    >EnumWindows(EnumWindowsProc,0);


    Не учтен случай, когда окно - дщерь десктопа:
    hWndParent = GetDesktopWindow, а dwStyle, например, = WS_CHILD OR WS_CAPTION, -
    и кнопка есть, и парент !=0.


    asmfan

    >окно скрывалось с панели задач, путём присвоения ему (создания для него) невидимого родителя.
    >// а кстати чем отличаются результаты GetParent(hwnd) и GetWindow(hwnd,GW_OWNER)?

    О Parent и Owner см. http://www.wasm.ru/forum/viewtopic.php?id=15560 .
    Для начала: родитель - это Parent, а "присвоенный невидимый" - это Owner (владелец).
     
  14. asmfan

    asmfan New Member

    Blog Posts:
    0
    kero, спасибо, познавательная вещь.
     
  15. kero

    kero Модератор SOURCES & 2LZ Staff Member

    Blog Posts:
    0
    Парочка более наглядных контрпримеров к процедуре krid24 (см. аттач).

    TaskbarCase1 показывает, что приложение может иметь "кнопку" на таскбаре даже тогда, когда
    и WS_EX_TOOLWINDOW есть, и Owner!=0, и Parent!=0, и даже при IsWindowVisible=0.

    В TaskbarCase2 добавлен WS_EX_APPWINDOW, в результате TaskbarCase2 попадает в список Alt+Tab,
    и при этом только 1 из 4 условий - IsWindowVisible!=0 - обязано соблюдаться.

    (Проверено на XP pro sp2).

    Так что уточнить бы процедурку-то :)
     
  16. maxdiver

    maxdiver Max

    Blog Posts:
    0
    Ну и что же делать? :)
    Вариант с отправкой сообщений таскбару не катит. Вообще-то я хочу написать некую облегчённую оболочку вместе тяжелого и тормозного explorer.exe. Да и вообще, получить список окон - довольно распространенная задача (например, в примитивном удаленном шелле).
     
  17. kero

    kero Модератор SOURCES & 2LZ Staff Member

    Blog Posts:
    0
    maxdiver
    >Ну и что же делать? :)

    Например - http://groups.google.ru -> поиск -> "taskbar applications list"
     
  18. maxdiver

    maxdiver Max

    Blog Posts:
    0
    Вот что удалось найти в MSDN:
    1. The Shell creates a button on the taskbar whenever an application creates a window that isn't owned.
    2. To prevent the window button from being placed on the taskbar, create the unowned window with the WS_EX_TOOLWINDOW extended style.
    3. As an alternative, you can create a hidden window and make this hidden window the owner of your visible window.
    4. If you want to dynamically change a window's style to one that doesn't support visible taskbar buttons, you must hide the window first (by calling ShowWindow with SW_HIDE), change the window style, and then show the window.

    Если я правильно понял, то получается, если даже окну присвоили стиль WS_EX_TOOLWINDOW, то оно всё равно останется на таскбаре, пока оно не будет скрыто хотя бы раз. Получается, что невозможно получить точный список окон?

    P.S. В гугле я тоже не смог ничего найти. В лучшем случае там проверяют IsWindowVisible.
     
  19. kero

    kero Модератор SOURCES & 2LZ Staff Member

    Blog Posts:
    0
    maxdiver

    >Если я правильно понял, то получается, если даже окну присвоили стиль WS_EX_TOOLWINDOW, то оно всё равно останется на таскбаре, пока оно не будет скрыто хотя бы раз.

    Да нет же, понять следовало так: чтобы убрать окно с таскбара, окну надо установить WS_EX_TOOLWINDOW в момент, когда оно невидимо.
    Просто всмотритесь в приведенные выше контрпримеры.

    >Получается, что невозможно получить точный список окон?

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

    Если список окон, отвечающих условиям MSDN, в общем случае беднее списка окон, представленных "кнопками" на таскбаре, -
    ну, так и составить список "кнопок" таскбара, без оглядки на свойства соответствующих окон.

    >>Вариант с отправкой сообщений таскбару не катит.

    ?? Да в нашем распоряжении - туча сообщений! Ведь "кнопки" лежат не на таскбаре, а на дочернем стандартном тулбаре (окно класса ToolbarWindow32).

    Короче, берите "Сканер toolbar'ов" из Inqsoft Window Scanner by CyberManiac, сканируйте таскбаровский тулбар - и увидите искомый список.
    Обратите внимание, там два варианта сканирования: без внедрения в чужой процесс и с оным, делайте выводы.

    (Кстати, "Quick Launch" - тоже тулбар, да и трей не без тулбара).
     
  20. maxdiver

    maxdiver Max

    Blog Posts:
    0
    Я имел в виду, что я хочу получать список окон при закрытом explorer.exe, а таскбар ведь принадлежит этому процессу, поэтому нужен другой способ получения списка.

    Вот и я про то же: получается, что само по себе наличие стиля WS_EX_TOOLWINDOW ещё не говорит о том, что кнопка должна быть убрана.