Управление отображением программы на панели задач
При скрытии главного окна программы при помощи функции ShowWindow, программа также убирается с панели задач. Тут ничего сложного. А как сделать так, чтобы окно отображалось на экране, но при этом программа не отображалась на панели задач? В некоторых случаях это можно сделать определенной комбинацией стилей окна, например, добавив в расширенный стиль параметр WS_EX_TOOLWINDOW. Но это не всегда приемлемо, чаще всего стиль окна должен оставаться привычным, то есть с заголовком, иконкой, кнопками сворачивания и т.д. Значит нужны программные способы добавить или убрать программу с панели задач.Наиболее простой в реализации способ, который чаще всего рекомендуют использовать, основан на изменении родительского окна. Если у главного окна приложения нет родительского окна, то оно отображается на панели задач. Если в качестве родительского окна указан рабочий стол, то программа убирается из панели задач. На этапе инициализации окна ему присваивается нулевое значение в качестве хэндла родительского окна.
Code (Assembler) : Убрать нумерацию
- .wminitdialog:
- ; Если окно уже имеет родителя, то сбросить значение
- invoke GetWindowLong,[hwnddlg],GWL_HWNDPARENT
- or eax,eax
- jz @f
- invoke SetWindowLong,[hwnddlg],GWL_HWNDPARENT,0
- @@:
Code (Assembler) : Убрать нумерацию
- .taskbar_show:
- ; Добавить программу на панели задач
- invoke SetWindowLong,[hwnddlg],GWL_HWNDPARENT,0
- ...
- .taskbar_hide:
- ; Убрать программу с панели задач
- invoke GetDesktopWindow
- invoke SetWindowLong,[hwnddlg],GWL_HWNDPARENT,eax
- ...
Важно! Хотя этот способ с технической точки зрения вполне легален, использовать его крайне не рекомендуется. Дело в том, что при назначении окон разных процессов другому процессу, системе очень сложно обрабатывать все внутренние сообщения, связи между потоками и подобные вещи. Некоторые межпроцессовые сообщения могут быть вовсе заблокированы, а попытки манипуляции с окном могут привести к аварийному завершению. Это как раз тот случай, когда кажется, будто что-то работает как вам хочется, но при этом не факт, что оно работает правильно.
Немного более корректный способ - создание невидимого message-only окна. Оно будет использоваться вместо рабочего стола.
Code (Assembler) : Убрать нумерацию
- szClass db '#32770',0
- HWND_MESSAGE = -3
- ...
- ...
- ; Создать невидимое message-only окно
- invoke CreateWindowEx,0,szClass,0,0,0,0,0,0,HWND_MESSAGE,0,0,0
- mov [hWndParent],eax
Code (Assembler) : Убрать нумерацию
- .taskbar_show:
- ; Добавить программу на панели задач
- invoke SetWindowLong,[hwnddlg],GWL_HWNDPARENT,0
- ...
- .taskbar_hide:
- ; Убрать программу с панели задач
- invoke SetWindowLong,[hwnddlg],GWL_HWNDPARENT,[hWndParent]
- ...
Code (Assembler) : Убрать нумерацию
- ; GUID {56FDF344-FD6D-11D0-958A-006097C9A090}
- CLSID_TaskbarList dd 056FDF344h
- dw 0FD6Dh
- dw 011D0h
- db 095h, 08Ah, 000h, 060h, 097h, 0C9h, 0A0h, 090h
- ; GUID {56FDF342-FD6D-11D0-958A-006097C9A090}
- IID_ITaskbarList dd 056FDF342h
- dw 0FD6Dh
- dw 011D0h
- db 095h, 08Ah, 000h, 060h, 097h, 0C9h, 0A0h, 090h
- ; IID_ITaskbarList Interface
- struct ITaskBarList
- QueryInterface dd ?
- AddRef dd ?
- Release dd ?
- HrInit dd ?
- AddTab dd ?
- DeleteTab dd ?
- ActivateTab dd ?
- SetActiveAlt dd ?
- ends
- CLSCTX_INPROC_SERVER = 1
- S_OK = 0
Code (Assembler) : Убрать нумерацию
- .wminitdialog:
- ; Инициализировать COM-объект
- invoke CoInitialize,NULL
- ; Создать объект
- invoke CoCreateInstance,CLSID_TaskbarList,NULL,\
- CLSCTX_INPROC_SERVER,\
- IID_ITaskbarList,pITbDisp
- ; Инициализировать объект панели задач
- mov eax, [pITbDisp]
- mov eax, [eax]
- stdcall dword [eax+ITaskBarList.HrInit],[pITbDisp]
Code (Assembler) : Убрать нумерацию
- .taskbar_show:
- ; Добавить программу на панели задач
- mov eax, [pITbDisp]
- mov eax, [eax]
- stdcall dword [eax+ITaskBarList.AddTab],[pITbDisp],[hwnddlg]
- ; Активировать добавленный элемент панели задач
- mov eax, [pITbDisp]
- mov eax, [eax]
- stdcall dword [eax+ITaskBarList.ActivateTab],[pITbDisp],[hwnddlg]
- ...
- .taskbar_hide:
- ; Убрать программу с панели задач
- mov eax, [pITbDisp]
- mov eax, [eax]
- stdcall dword [eax+ITaskBarList.DeleteTab],[pITbDisp],[hwnddlg]
- ...
В приложении примеры программ с исходными текстами, которые показываются или скрываются на панели задач перечисленными в статье способами.
Просмотров: 1285 | Комментариев: 9
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(11.09.2020 в 14:20):
Добавил в статью, спасибо. Архив тоже обновлен.
Scolgena
(11.09.2020 в 13:20):
можно добавить, что если совсем не нужно отображать на панели задач, можно самому создать себе парента, типа HWND hWndParent = CreateWindowExW(0, L"#32770", 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, 0)
dd1
(08.09.2020 в 20:55):
Тоже подумал об этом, поэтому и стало любопытно.
Спасибо за ответ.
ManHunter
(08.09.2020 в 20:05):
dd1, таким образом в Ассемблере описываются GUID'ы, конкретно в этом случае это GUID {56FDF344-FD6D-11D0-958A-006097C9A090}. Что ж касается формы записи, то честно признаюсь, я не знаю, почему в Ассемблере исторически сложилась именно такая структура. Эту последовательность можно записать хоть отдельными байтами, хоть двордами, хоть еще как, лишь бы получился правильный набор данных. Но, как говорится, так уж тут заведено.
Кто-то выкручивается макросами, чтобы преобразовать GUID из строки в байты. Меня настолько вымораживает каждый раз переводить строку в эту нелогичную конструкцию, что я даже нарисовал себе мелкую софтинку для этой операции. https://www.upload.ee/files/12...uid.zip.html
Кто-то выкручивается макросами, чтобы преобразовать GUID из строки в байты. Меня настолько вымораживает каждый раз переводить строку в эту нелогичную конструкцию, что я даже нарисовал себе мелкую софтинку для этой операции. https://www.upload.ee/files/12...uid.zip.html
dd1
(08.09.2020 в 19:13):
ManHunter, если не трудно, просвятите пожалуйста.
У вас в FASM-коде есть такое место:
section '.data' data readable writeable
IID_ITaskbarList dd 056FDF342h
dw 0FD6Dh
dw 011D0h
db 095h, 08Ah, 000h, 060h, 097h, 0C9h, 0A0h, 090h
Оно вроде, и понятно что это, но в то же время не совсем. Получается что-то среднее между массивом переменного размера и структурой, но у массива все ячейки одного размера и понятно как можно перейти от ячейки к ячейке и скопировать данные. У структуры есть назв. структуры и название ее полей - тоже как бы все понятно. А в такой конструкции как можно оперативно перемещаться и копировать данные разной длины (dd dw db)? И, вообще, это же было придумано для какого-то удобства? Заранее спасибо.
P.S. Кстати, ИДА определяет это как структуру и присваевает даже свои названия полям с разной длиной.
У вас в FASM-коде есть такое место:
section '.data' data readable writeable
IID_ITaskbarList dd 056FDF342h
dw 0FD6Dh
dw 011D0h
db 095h, 08Ah, 000h, 060h, 097h, 0C9h, 0A0h, 090h
Оно вроде, и понятно что это, но в то же время не совсем. Получается что-то среднее между массивом переменного размера и структурой, но у массива все ячейки одного размера и понятно как можно перейти от ячейки к ячейке и скопировать данные. У структуры есть назв. структуры и название ее полей - тоже как бы все понятно. А в такой конструкции как можно оперативно перемещаться и копировать данные разной длины (dd dw db)? И, вообще, это же было придумано для какого-то удобства? Заранее спасибо.
P.S. Кстати, ИДА определяет это как структуру и присваевает даже свои названия полям с разной длиной.
ManHunter
(08.09.2020 в 12:21):
0101, не совсем литературный раздел, но все касаемо Ассемблера я складывал сюда: http://www.manhunter.ru/assemb...er_fasm.html
0101
(08.09.2020 в 05:20):
вообще, имхо, книжка "The Old New Thing" весьма интересна, несмотря на возраст и английский язык (в переводе есть только отдельные главы). Может (сам давно собираюсь) сделать на сайте раздел "must have" литературы? Там будет пару десятков книжек на пару сотен Мб.
ManHunter
(07.09.2020 в 12:54):
Правильное замечание. Добавил в статью предупреждение. Спасибо!
DRON
(07.09.2020 в 12:33):
Объяснение, почему первый способ лучше не использовать:
https://devblogs.microsoft.com...2-00/?p=4683
https://devblogs.microsoft.com...2-00/?p=4683
Добавить комментарий
Заполните форму для добавления комментария