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

Тема в разделе "WASM.WIN32", создана пользователем maxdiver, 1 апр 2007.

  1. maxdiver

    maxdiver Max

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

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    EnumWindows
     
  3. maxdiver

    maxdiver Max

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

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    там много какие нужно исключать.. со сброшенным WS_VISIBLE, с установленным WS_EX_TOOLWINDOW и еще какие-то, сам точно не знаю..
     
  5. wasm_test

    wasm_test wasm test user

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

    krid24 Member

    Публикаций:
    0
    Регистрация:
    17 авг 2004
    Сообщения:
    88
    Код (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

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    308
    Адрес:
    Саратов
    Спасибо.
    От себя добавлю только, что проверки на окно-родитель не нужны - EnumWindows и так перечисляет только окна верхнего уровня. Таким образом, окончательный код выглядит так:
    Код (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

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

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Просто это уже из разряда трюков - окно скрывалось с панели задач, путём присвоения ему (создания для него) невидимого родителя. (WS_EX_TOOLWINDOW не использовался)
    // а кстати чем отличаются результаты GetParent(hwnd) и GetWindow(hwnd,GW_OWNER)?
     
  10. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    дык можно просто дернуть ITaskBarList::lol: eleteTab
     
  11. asmfan

    asmfan New Member

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

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Так и есть =) Можно по WM_SETFOCUS делать DeleteTab снова.
     
  13. kero

    kero Модератор SOURCES & 2LZ Команда форума

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    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

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    kero, спасибо, познавательная вещь.
     
  15. kero

    kero Модератор SOURCES & 2LZ Команда форума

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    Парочка более наглядных контрпримеров к процедуре 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

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

    kero Модератор SOURCES & 2LZ Команда форума

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    maxdiver
    >Ну и что же делать? :)

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

    maxdiver Max

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    308
    Адрес:
    Саратов
    Вот что удалось найти в 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 Команда форума

    Публикаций:
    0
    Регистрация:
    4 апр 2006
    Сообщения:
    1.074
    Адрес:
    Москва
    maxdiver

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

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

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

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

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

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

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

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

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

    maxdiver Max

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    308
    Адрес:
    Саратов
    Я имел в виду, что я хочу получать список окон при закрытом explorer.exe, а таскбар ведь принадлежит этому процессу, поэтому нужен другой способ получения списка.

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