Гиперссылки в диалоговых окнах на Ассемблере
Создание текстовой гиперссылки в диалоговом окне, казалось бы, простая задача. Но дело в том, что в Windows по умолчанию нет элементов диалоговых окон, которые бы выполняли роль гиперссылки. Готовых решений на FASM тоже не нашлось, значит придется создавать такой элемент самостоятельно. Сперва определимся с задачами, что нам надо сделать. Должен получиться элемент диалогового окна в виде текста определенного цвета, при наведении на который курсор должен менять свою форму, а цвет изменяться на подсвеченный. При клике на такой элемент должна открываться заданная ссылка. Задачи ясны, начнем их решать. Сперва выберем элемент диалоговых окон из списка стандартных, который и будет использоваться в качестве гиперссылки. Сразу же приходит на ум STATIC. По умолчанию элемент класса STATIC полностью оправдывает свое название и не реагирует практически ни на какие сообщения. Чтобы STATIC принимал движение курсора и нажатия клавиш мышки, его надо описать в ресурсах с флагом стилей SS_NOTIFY.А как отследить движение курсора только над нашей гиперссылкой? Тут нам на помощь придет такая полезная вещь, как субклассирование. Суть субклассирования проста. С каждым окном связан указатель на оконную процедуру, которая обрабатывает сообщения Windows. Когда система получает сообщение, предназначенное для некоторого окна, она находит адрес оконной процедуры этого окна и вызывает ее. При субклассировании мы заменяем эту процедуру нашей и сохраняем указатель на старую процедуру, чтобы можно было передать ей сообщения для дальнейшей обработки. Это делается функцией SetWindowLong с индексом GWL_WNDPROC на этапе инициализации главного окна:
Code (Assembler) : Убрать нумерацию
- ...
- ; Получить хэндл нашего STATIC'а
- invoke GetDlgItem,[hwnddlg],ID_LINK
- ; Субклассировать гиперссылку и установить собственный
- ; обработчик для STATIC'а
- invoke SetWindowLong,eax,GWL_WNDPROC,WindowProc
- ; Сохранить адрес предыдущего обработчика
- mov [OldWndProc],eax
- ...
Code (Assembler) : Убрать нумерацию
- ;------------------------------------------------------------
- ; Наша собственная процедура обработки дочернего окна STATIC
- ;------------------------------------------------------------
- proc WindowProc hwnddlg:DWORD,msg:DWORD,wparam:DWORD,lparam:DWORD
- cmp [msg],WM_SETCURSOR ; Курсор над ссылкой
- je .cursor_over_hyperlink
- cmp [msg],WM_LBUTTONDOWN ; Нажатие мышкой на ссылке
- je .open_link
- ; Передать управление предыдущему обработчику
- invoke CallWindowProc,[OldWndProc],[hwnddlg],[msg],[wparam],[lparam]
- ret
- .cursor_over_hyperlink:
- ; Загрузить и установить курсор в виде руки
- invoke LoadCursor,0,IDC_HAND
- invoke SetCursor,eax
- jmp .finish
- .open_link:
- ; Открыть ссылку
- invoke ShellExecute,[hwnddlg],szOpen,szLink,NULL,NULL,SW_SHOW
- .finish:
- xor eax,eax
- ret
- szOpen db 'open',0 ; Команда открытия
- szLink db 'http://www.manhunter.ru',0 ; Ссылка на сайт
- endp
Code (Assembler) : Убрать нумерацию
- section '.data' data readable writeable
- hHyper dd ? ; Хэндл гиперссылки
- hBrushBack dd ? ; Хэндл кисточки
- sscolor dd ? ; Цвет закраски
- clrMain = 0FF0000h ; Обычный цвет ссылки (синий)
- clrActive = 00000FFh ; Цвет активной ссылки (красный)
Code (Assembler) : Убрать нумерацию
- ...
- ; Получить хэндл кисточки основного цвета окна
- invoke GetSysColor,COLOR_BTNFACE
- invoke CreateSolidBrush,eax
- mov [hBrushBack],eax
- ; Установить обычный цвет гиперссылки
- mov [sscolor],clrMain
- ; Получить хэндл нашего EDIT'а
- invoke GetDlgItem,[hwnddlg],ID_LINK
- mov [hHyper],eax
- ...
Code (Assembler) : Убрать нумерацию
- ...
- cmp [msg],WM_CTLCOLOREDIT
- je .set_color_edit
- ...
- .set_color_edit:
- ; Обрабатывается наш EDIT?
- mov eax,[hHyper]
- cmp [lparam],eax
- je @f
- ; Нет, пропустить
- xor eax,eax
- jmp .finish
- @@:
- ; Установить цвет текста ссылки
- invoke SetTextColor,[wparam],[sscolor]
- ; Установить режим заднего фона на прозрачный
- invoke SetBkMode,[wparam],TRANSPARENT
- ; Установить цвет EDIT как основной цвет окна
- mov eax,[hBrushBack]
- jmp .finish
Code (Assembler) : Убрать нумерацию
- ;------------------------------------------------------------
- ; Наша собственная процедура обработки дочернего окна EDIT
- ;------------------------------------------------------------
- proc WindowProc hwnddlg:DWORD,msg:DWORD,wparam:DWORD,lparam:DWORD
- cmp [msg],WM_SETCURSOR ; Курсор над ссылкой
- je .cursor_over_hyperlink
- cmp [msg],WM_LBUTTONDOWN ; Нажатие мышкой на ссылке
- je .open_link
- ; Передать управление предыдущему обработчику
- invoke CallWindowProc,[OldWndProc],[hwnddlg],[msg],[wparam],[lparam]
- ret
- .cursor_over_hyperlink:
- ; Загрузить и установить курсор в виде руки
- invoke LoadCursor,0,IDC_HAND
- invoke SetCursor,eax
- ; Установить цвет текста ссылки
- mov [sscolor],clrActive
- ; Перерисовать EDIT в новом цвете
- invoke InvalidateRect,[hHyper],NULL,TRUE
- jmp .finish
- .open_link:
- ; Открыть ссылку
- invoke ShellExecute,[hwnddlg],szOpen,szLink,NULL,NULL,SW_SHOW
- ; Установить цвет текста ссылки
- mov [sscolor],clrMain
- ; Перерисовать EDIT в новом цвете
- invoke InvalidateRect,[hHyper],NULL,TRUE
- .finish:
- xor eax,eax
- ret
- szOpen db 'open',0 ; Команда открытия
- szLink db 'http://www.manhunter.ru',0 ; Ссылка на сайт
- endp
UPD: Тут камрад Zummenix подсказал как корректно сделать STATIC цветным. Спасибо! Перезалил примеры, статью править пока не буду.
Есть еще варианты создания гиперссылки в диалоговых окнах через RichEdit, внедренный HTML и всякие посторонние компоненты, но они тут рассматриваться не будут. В приложении два примера диалоговых окон с текстовой гиперссылкой, реализованной через элементы классов STATIC и EDIT.
Просмотров: 6850 | Комментариев: 6
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Alex
(08.12.2023 в 11:22):
В ComCtl32.dll версии 6 определен элемент управления SysLink.
ManHunter
(01.10.2022 в 19:02):
Когда люди придумали деньги, количество нерешаемых задач значительно уменьшилось. Пара-тройка сотен баксов упростит решение.
Анна
(01.10.2022 в 16:07):
Добрый день, а можете подсказать, как мне реализовать эту задачу?
Скачать 3 иконки и 2 курсора. Реализовать приложение с использованием TabStip с 3 закладками. При переходе на другую закладку нужно поменять иконку. Каждая закладка должна иметь другое оконное наполнение. При наведении мышкой на текстовое поле устанавливается 1 курсор, на кнопку 2-й. При движении по другому полю окна курсор стандартный.
начали учить ассемблер на парах, но я очень мало понимаю(
Скачать 3 иконки и 2 курсора. Реализовать приложение с использованием TabStip с 3 закладками. При переходе на другую закладку нужно поменять иконку. Каждая закладка должна иметь другое оконное наполнение. При наведении мышкой на текстовое поле устанавливается 1 курсор, на кнопку 2-й. При движении по другому полю окна курсор стандартный.
начали учить ассемблер на парах, но я очень мало понимаю(
ManHunter
(10.07.2009 в 17:25):
Перезалил примеры с цветым статиком. Zummenix, спасибо!
ManHunter
(10.07.2009 в 16:06):
Кинь, интересно посмотреть. У меня что-то так и не получилось.
Zummenix
(10.07.2009 в 16:02):
Делал HyperLink на статике, цвет текста прекрасно меняется через SetTextColor, могу скинуть исходник, если нужно :)
Добавить комментарий
Заполните форму для добавления комментария