Подскажите пожалуйста: Как получить список окон приложений, т.е. список тех окон, которые отображаются на Панели Задач? Попытался найти что-нибудь в MSDN, но что-то ничего подходящего не нашел.
Да она возвращает окна, которые не являются дочерними. Однако сколько окон она возвращает! Там явно не те окна, которые на Панели задач. Даже если наложить условие, чтобы стиль был WS_VISIBLE, все равно окон слишком много. Например, у WinAmp'а там несколько окон, каждое из которых не зависит от остальных
там много какие нужно исключать.. со сброшенным WS_VISIBLE, с установленным WS_EX_TOOLWINDOW и еще какие-то, сам точно не знаю..
Еще есть занятный интерфейс ITaskBarList, но там можно только добавить или убрать окно... а как получить список - хз . Вот тут (http://forum.antichat.ru/thread30055.html) была проблема определения HWND окна по кнопке на таскбаре.. и кажется ее решили. Советую прочитать: отсюда алгоритм - перечисляем кнопки таскбара и лдя каждой получаем HWND
Код (Text): 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);
Спасибо. От себя добавлю только, что проверки на окно-родитель не нужны - EnumWindows и так перечисляет только окна верхнего уровня. Таким образом, окончательный код выглядит так: Код (Text): BOOL STDCALL EnumWindowsProc (HWND hwnd, LPARAM lp) { if (IsWindowVisible (hwnd) && !(GetWindowLong (hwnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW)) // найдено окно return TRUE; }
Проверки нужны, т.к. EnumWindows перечисляет некоторые окна (многие апплеты панели управления, системные диалоги, etc.), имеющие и родителя и владельца (OWNER). Кнопки на панели задач у них нет, но без проверки на Parent и Owner в твой список они все равно попадут (хоть у них и установлен WS_VISIBLE и сброшен WS_EX_TOOLWINDOW).
Просто это уже из разряда трюков - окно скрывалось с панели задач, путём присвоения ему (создания для него) невидимого родителя. (WS_EX_TOOLWINDOW не использовался) // а кстати чем отличаются результаты GetParent(hwnd) и GetWindow(hwnd,GW_OWNER)?
Там всё хитрее - при альттабинге, если не ошибаюсь (давно с этим работал), опять на таскбаре появляется кнопа. В общем так - если окно теряет фокус а потом снова его приобретает - кнопа появляется. Так по-моему было. Поэтому этот вариант работы с кнопой на таскбаре я отмёл для себя.
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 (владелец).
Парочка более наглядных контрпримеров к процедуре 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). Так что уточнить бы процедурку-то
Ну и что же делать? Вариант с отправкой сообщений таскбару не катит. Вообще-то я хочу написать некую облегчённую оболочку вместе тяжелого и тормозного explorer.exe. Да и вообще, получить список окон - довольно распространенная задача (например, в примитивном удаленном шелле).
maxdiver >Ну и что же делать? Например - http://groups.google.ru -> поиск -> "taskbar applications list"
Вот что удалось найти в 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.
maxdiver >Если я правильно понял, то получается, если даже окну присвоили стиль WS_EX_TOOLWINDOW, то оно всё равно останется на таскбаре, пока оно не будет скрыто хотя бы раз. Да нет же, понять следовало так: чтобы убрать окно с таскбара, окну надо установить WS_EX_TOOLWINDOW в момент, когда оно невидимо. Просто всмотритесь в приведенные выше контрпримеры. >Получается, что невозможно получить точный список окон? Ох. Было бы невозможно - на таскбаре был бы бардак. Странно, что группогугл не навеял вам мысль о нескольких списках... Если список окон, отвечающих условиям MSDN, в общем случае беднее списка окон, представленных "кнопками" на таскбаре, - ну, так и составить список "кнопок" таскбара, без оглядки на свойства соответствующих окон. >>Вариант с отправкой сообщений таскбару не катит. ?? Да в нашем распоряжении - туча сообщений! Ведь "кнопки" лежат не на таскбаре, а на дочернем стандартном тулбаре (окно класса ToolbarWindow32). Короче, берите "Сканер toolbar'ов" из Inqsoft Window Scanner by CyberManiac, сканируйте таскбаровский тулбар - и увидите искомый список. Обратите внимание, там два варианта сканирования: без внедрения в чужой процесс и с оным, делайте выводы. (Кстати, "Quick Launch" - тоже тулбар, да и трей не без тулбара).
Я имел в виду, что я хочу получать список окон при закрытом explorer.exe, а таскбар ведь принадлежит этому процессу, поэтому нужен другой способ получения списка. Вот и я про то же: получается, что само по себе наличие стиля WS_EX_TOOLWINDOW ещё не говорит о том, что кнопка должна быть убрана.