Полезное для программистов:

Фриланс
Новости
Статьи
   
Рубрики:


Управление чужими контролами или делаем цвет фона иконок на рабочем столе прозрачным.

Поиск:
Предыстория: на форуме JusTalionis-ом была поднята тема про прозрачность фона иконок и настолько она получилась интересная, что cardinal попросил написать небольшую статейку для ФАК-а. Чем собственно я и занялся. Но просто описывать как сменить цвет мне не захотелось, поэтому статью можно рассматривать как простенький пример по механизму управления контролами при помощи SendMessage.


И так, здесь мы рассмотрим не большой пример по управлению объектами не принадлежащих нашему приложению. Делать мы это будем естественно при помощи АПИ функций.
Для большей наглядности мы выбрали простую задачу – сделать цвет подписи иконок на рабочем столе прозрачным.
Теория:
Поверх картинки (фона) рабочего стола лежит прозрачный элемент управления класса ListView под названием SysListView32, вот на нем то и держаться все иконочки. Следовательно первое что нам нужно сделать – это найти сей важный контрол. Как только мы найдем его мы можем делать с ним практически все что захотим, ну или по крайней мере то что позволяет нам класс ListView и его предки. 
Практика:
И так приступим к реализации первой части нашего проекта. Для начала добавим в проект новый модуль, где будем описывать все наши функции. Дальше, как уже писалось первое что мы должны сделать это найти наш SysListView32 для этого нам понадобится две функции:  FindWindow и FindWindowEx. Первая ищет базовое окно, вторая соответственно в найденном окне ищет «потомков». Вот их описания:
Код

Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _        
(ByVal lpClassName As String, _ ‘имя базового класса        
ByVal lpWindowName As String) As Long ‘имя искомого окна

Public Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" _        
(ByVal hwndParent As Long, _  ‘хэндл предка
ByVal hwndChildAfter As Long, _   ‘хэндл наследника (нам не понадобиться)
ByVal lpszClass As Any, _   ‘имя класса
ByVal lpszWindow As Any) As Long ‘имя окна

Каждая из них возвращает нам хэндл (тип long) найденного объекта если все прошло удачно, и в противном случае она вернет нам 0. Так поступает любая АПИ функция.
Вот так мы будем искать наш лист. Для хранения хэндла нашего листа заведем переменную типа Long и в нее будем складывать результаты работы наших функций поиска:
Код

Dim SLV As Long ' тут будем хранить хэндл найденного SysListView32
SLV = FindWindow("Progman", "Program Manager") 'ищем окно класса Progman
SLV = FindWindowEx(SLV, nil, "SHELLDLL_DefView", "") 'внутри него ищем SHELLDLL_DefView
SLV = FindWindowEx(SLV, nil, "SysListView32", "") 'И наконец получаем хэндл нашего SysListView32


Метод управления чужими объектами очень прост – зная хэндл объекта и его класс мы можем передавать ему служебные сообщения, которые может обрабатывать данный класс или данный экземпляр объекта. Для того чтобы передавать эти сообщения нам потребуется еще одна функция SendMessage:
Код

Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" _       
(ByVal hwnd As Long, _     ‘хэндл объекта которому передаем сообщение
ByVal wMsg As Long, _     ‘сообщение     
ByVal wParam As Long, _   ‘правый параметр сообщения       
ByVal lParam As Long) As Long ‘левый параметр сообщения

Все сообщения обозначаются номерами типа Long, в других языках (например Делфи), они уже описанный в соответствующих модулях, а нам придется делать это руками. Не бойтесь ничего страшного в этом нету. Сообщения для ListView всегда начинаются с прифекса LVM_ (List View Message)
Код

Const LVM_SETTEXTBKCOLOR As Long  = 4134 'устанавливаем цвет фона иконок
Const LVM_GETITEMCOUNT As Long = 4100 ' получаем количество иконок *
Const LVM_REDRAWITEMS As Long = 4117 ' перерисовываем иконки *
Const LVM_UPDATE As Long  = 4138 ' обновляем наш лист
Const CLR_NONE = &HFFFFFFFF 'прозрачный цвет фона иконок, люблю хранить подобные вещи в константах

Комментарии:
* Эти два сообщения нам понадобятся для того чтобы перерисовать иконочки на рабочем столе. 
Все эти числа легко найти в МСДН-е
Кроме всего нам понадобятся еще несколько переменных для хранения возвращенных нашими сообщениями результатов работы
Код

Dim col As Long 'сюда будем складывать результат при смене цвета и при редраве
Dim IconCount As Integer ‘тут будет храниться количство иконок


Приступаем к непосредственному засылу месагов:
Код

……………
col = SendMessage(SLV, LVM_SETTEXTBKCOLOR, 0, CLR_NONE) ' шлем месагу на замену цвета
IconCount = SendMessage(SLV, LVM_GETITEMCOUNT, 0, 0) ' получаем количество итемов..
col = SendMessage(SLV, LVM_REDRAWITEMS, 0, IconCount - 1) 'перерисовали
col = SendMessage(SLV, LVM_UPDATE, 1, 0) 'шлем сообщение на апдейт
……………

Вот что у нас получается в итого:
Код модуля:
Код

Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _        
(ByVal lpClassName As String, _         
ByVal lpWindowName As String) As Long

Public Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" _        
(ByVal hwndParent As Long, _        
ByVal hwndChildAfter As Long, _        
ByVal lpszClass As Any, _        
ByVal lpszWindow As Any) As Long

Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" _        
(ByVal hwnd As Long, _         
ByVal wMsg As Long, _        
ByVal wParam As Long, _        
ByVal lParam As Long) As Long

Код кнопки на форме:
Код

Dim SLV As Long ' хэндл SysListView32
Dim col As Long 
Dim IconCount As Integer
Const CLR_NONE = &HFFFFFFFF 'прозрачный цвет фона иконок
Const LVM_SETTEXTBKCOLOR = 4134 'магическое число
Const LVM_UPDATE = 4138 'еще одно магическое число (взяты мз МСДН-а)
Const LVM_GETITEMCOUNT As Long = 4100 ' получаем количество иконнок
Const LVM_REDRAWITEMS As Long = 4117 ' перерисовываем иконки

SLV = FindWindow("Progman", "Program Manager") 'ищем окно класса Progman
SLV = FindWindowEx(SLV, nil, "SHELLDLL_DefView", "") 'внутри него ищем SHELLDLL_DefView
SLV = FindWindowEx(SLV, nil, "SysListView32", "") 'И наконец получаем хэндл нашего SysListView32
col = SendMessage(SLV, LVM_SETTEXTBKCOLOR, 0, CLR_NONE) ' шлем месагу на замену цвета
IconCount = SendMessage(SLV, LVM_GETITEMCOUNT, 0, 0) ' получаем количество итемов...
col = SendMessage(SLV, LVM_REDRAWITEMS, 0, IconCount - 1) 'перерисовали
col = SendMessage(SLV, LVM_UPDATE, 1, 0) ‘ апдейт
 


Подобным образом можно управлять любыми объектами, как принадлежащими вашему приложению так и располагающихся в самых отдаленных участках системы, будь то игра сапер, кнопка на панели вашего эксплорера или абзац в документе открытого ворда.

Статья не претендует на полноту и не является руководством к действию, она просто иллюстрирует один из способов управления чужими объектами. 
Этот пример проверен и работоспособен только при условии выключенного Active Desktop
За помощь в создании, предоставлении информации и вообще за начинание этой темы огромное спасибо JusTalionis.
Автор: ~FoX~






Просмотров: 6531

 

 

Новые статьи:


Популярные:
  1. Как сделать цикличным проигрывание MIDI-файла?
  2. Создание AVI файла из рисунков
  3. Как устройство "отключить в данной конфигурации"?
  4. Kто в данный момент присоединен через Сеть?
  5. Как узнать количество доступной памяти?
  6. Как реализовать в RichEdit разноцветный текст?
  7. Как скрыть свое приложение от ProcessViewer
  8. Как программно нажать/скрыть/показ кнопку "Start"?
  9. Модуль работы с ресурсами в PE файлах
10. Функции вызова диалоговых окон выбора
11. Проверка граматики средствами Word'а из Delphi.
12. Модуль для упрощенного вызова сообщений
13. Функции для записи и чтение своих данных в, ЕХЕ- файле
14. Рекурсивный просмотр директорий
15. Network Traffic Monitor
16. Разные модули
17. Универсальная функция для обращения к любым экспортируем функциям DLL
18. Библиотека от VladS
19. Протектор для UPX'а
20. Еще об ICQ, сообщения по контакт листу?
21. Использование открытых интерфейсов
22. Теория и практика использования RTTI
23. Работа с TApplication
24. Примеры использования Drag and Drop для различных визуальных компонентов
25. Что такое порт? Правила для работы с портами
26. Симфония на клавиатуре
27. Загрузка DLL
28. Исправление автоинкремента
29. Взаимодействие с чужими окнами
30. Проверить дубляжи в столбце


 

 

 
 
На главную