Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > обозреватель окошек


Автор: stab 10.9.2003, 12:50
Делаю обозреватель окошек, что-то вроде Spy++ из поставки VS. Появилась идея для каждого окошка в дереве рисовать иконку. Получаю иконку при помощи WM_GETICON, для большинства окон все ОК. Проблема с апплетами панели управления (к примеру, Свойства: Экран) для них иконку получить не удается, но в списке задач, который появляется по Alt+Tab иконка показывается. Какие идеи?

з.ы. В случае если WM_GETICON не помогает использую GetClassLong, но для апплетов это тоже результатов не дает.

Автор: Baa 10.9.2003, 23:15
В мсдн нашел следующее:
Цитата

An application sends the WM_SETICON message to associate a new large or small icon with a window. The system displays the large icon in the ALT+TAB dialog box, and the small icon in the window caption.

Соотв. мне кажется, что тот же alt+tab посылает WM_GETICON
А если поставить глобальный хук на WM_GETICON и нажать аль+таб, то он вывалится? Не пробовал?

Автор: stab 11.9.2003, 01:44
Оказалось, что у окна просто нет иконки smile.gif т.е. она равна NULL, нет иконки и у класса. Не ясно откуда тогда Alt+Tab берет иконку :/

Автор: p0s0l 11.9.2003, 05:52
Иконка содержится в ресурсах *.cpl
Т.е. тебе придется узнать имя модуля и там смотреть ресурсы...

Автор: stab 11.9.2003, 16:35
Имя модуля по окну я узнать могу, но:

1. Имя модуля всегда rundll32.exe. Но это еще можно как-то обойти, т.е. посмотреть загружены ли в контексте rundll32 модуль чье имя имеет расширение cpl. Но опять же вопрос: а если показывается несколько апплетов одновременно.
2. В одном *.cpl файле может быть несколько апплетов и у каждого своя иконка. Не ясно как по окну узнать, какой из апплетов загружен.

з.ы. есть наверно очень простой путь..., известный только MS smile.gif Весь msdn перерыл ни че не нашел похожего sad.gif инет тоже по возможности весь просмотрел smile.gif

Автор: p0s0l 11.9.2003, 20:19
Порывшись в хелпе WinAPI, вот что придумал, правда, не знаю, что из этого получится...
Короче, если проблема стоит в том, что в одном cpl несколько апплетов, то можно попробовать так:
1)Подключаешь *.cpl как обычную dll. (LoadLibrary или GetModuleHandle)
2)Получаешь адрес процедуры "CplApplet" (GetProcAddress)
3)Вызываешь int n = CplApplet(0, CPL_GETCOUNT, 0, 0), которая возвращает кол-во диалогов в cpl
4)for (int i=0; i<n; i++)
{
NEWCPLINFO info;
info.dwSize = sizeof(info);
CplApplet(0, CPL_NEWINQUIRE, i, &info);
// тут проверка
}
5)В проверке ^^^ сверяй info.szName с именем окна, для которого ты пытаешься узнать иконку.
Если строки совпадают, то в info.hIcon сидит HICON иконки...

PS: Только насчет первого параметра в CplApplet не уверен:
Цитата
hwndCPl

Identifies the main window of the controlling application.

Может быть надо будет писать хэндл родительского окна...

Автор: p0s0l 11.9.2003, 20:22
Цитата
.ы. есть наверно очень простой путь..., известный только MS  Весь msdn перерыл ни че не нашел похожего  инет тоже по возможности весь просмотрел 

Как раз через CplApplet(CPL_NEWINQUIRE) система и узнает иконку, когда запускает нужный апплет... Я так думаю...


Автор: stab 11.9.2003, 20:25
буду пробовать...

p0s0l, ты думаешь, что info.szName всегда равно заголовку окна?

Автор: stab 11.9.2003, 22:19
млин, приплыли, делал-делал и вдруг читаю:

Цитата
szName
Null-terminated string that contains the dialog box name. The name is intended to be displayed below the icon.


Т.е. szName это подпись под иконкой в панели управления, совсем не заголовок окна sad.gif sad.gif sad.gif


проблема начинает становиться интересной smile.gif решение явно не на виду.

Автор: stab 11.9.2003, 23:10
Цитата
А если поставить глобальный хук на WM_GETICON и нажать аль+таб, то он вывалится?


Хук не ставил, но судя по Spy++, который мониторит сообщения к окнам по Alt+Tab ни чего не приходит. Spy++ использует хуки, так что можно считать, что хук ставил smile.gif

что же делатьconfused.gif

Автор: p0s0l 12.9.2003, 00:28
Да уж...
Если рубить, дак рубить...
Можно запустить апплет (CPlApplet(hwnd, CPL_DBLCLK,...), а через долю секунды его закрыть, но перед этим посмотрев, какое дочернее окно появилось у окна hwnd.
Чтобы это каждый раз не перезапускалось - запускай каждый апплет только 1 раз и запоминай заголовок диалога...

Правда, геморрно все это... Но другого способа пока не вижу.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)