Модераторы: Akina
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Управление чужими контролами или делаем цвет фона иконок на рабочем столе прозрачным. 
:(
    Опции темы
cardinal
Дата 7.10.2006, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Инженер
****


Профиль
Группа: Экс. модератор
Сообщений: 6003
Регистрация: 26.3.2002
Где: Германия

Репутация: 19
Всего: 99



Предыстория: на форуме 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.


--------------------
Немецкая оппозиция потребовала упростить натурализацию иммигрантов
В моем блоге: Разные истории из жизни в Германии

"Познание бесконечности требует бесконечного времени, а потому работай не работай - все едино".  А. и Б. Стругацкие
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "VB6"
Akina

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по VB обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • Используйте теги [code=vb][/code] для подсветки кода. Используйтe чекбокс "транслит" (возле кнопок кодов) если у Вас нет русских шрифтов.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Akina.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | VB6 | Следующая тема »


 




[ Время генерации скрипта: 0.0439 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.