
Листинг . (компиляторFasmw 1.68)
format PE GUI 4.0
entry start
include 'win32a.inc'
ID_EDIT1 = 100
ID_EDIT2 = 101
ID_STATIC = 102
; Сегмент данных
section '.data' data readable writeable
hwndTip dd ? ; Хэндл окна подсказки
TTipFlag dd ? ; Флаг активности подсказки
; Структура TRACKMOUSEEVENT не определена, сделаем это сами
struct TRACKMOUSEEVENT
cbSize dd ?
dwFlags dd ?
hwndTrack dd ?
dwHoverTime dd ?
ends
; Определяем нужные структуры
tme TRACKMOUSEEVENT
pt POINT
ttip TOOLINFO
trect RECT
oldX dd ? ; Сохраненные координаты мыши
oldY dd ?
; Определяем нужные константы
TTM_TRACKACTIVATE = WM_USER + 17
TTM_TRACKPOSITION = WM_USER + 18
TTM_SETMAXTIPWIDTH = WM_USER + 24
; Сообщения окну подсказки
TTF_SUBCLASS = 0x0010
TTF_TRACK = 0x0020
TTF_ABSOLUTE = 0x0080
TTF_TRANSPARENT = 0x0100
; Сообщение обработчика мыши
TME_LEAVE = 0x00000002
; Максимальная ширина всплывающей подсказки
TOOLTIP_WIDTH = 200
; Предустановленное количество элементов в массиве подсказок
TOOLTIPS_COUNT = 5
; Массив данных для всплывающих подсказок
; Формат массива:
; 1 DWORD - сохраненный адрес обработчика
; 2 DWORD - адрес подсказки
tt_data rd (TOOLTIPS_COUNT*2)
;----------------------------------------------------------------------
section '.code' code readable executable
start:
invoke GetModuleHandle,0
invoke DialogBoxParam,eax,37,HWND_DESKTOP,DialogProc,0
invoke ExitProcess,0
;----------------------------------------------------------------------
proc DialogProc hwnddlg,msg,wparam,lparam
push ebx esi edi
cmp [msg],WM_INITDIALOG
je .wminitdialog
cmp [msg],WM_COMMAND
je .wmcommand
cmp [msg],WM_CLOSE
je .wmclose
xor eax,eax
jmp .finish
.wminitdialog:
; Установить подсказки для всех элементов
invoke GetDlgItem,[hwnddlg],ID_EDIT1
stdcall AddTooltip,eax,szTip1,tt_data+(0*8)
invoke GetDlgItem,[hwnddlg],ID_EDIT2
stdcall AddTooltip,eax,szTip2,tt_data+(1*8)
invoke GetDlgItem,[hwnddlg],IDCANCEL
stdcall AddTooltip,eax,szTip3,tt_data+(2*8)
; Установить подсказку для главного окна
stdcall AddTooltip,[hwnddlg],szText,tt_data+(3*8)
invoke GetDlgItem,[hwnddlg],ID_STATIC
stdcall AddTooltip,eax,szTip4,tt_data+(4*8)
jmp .processed
.wmcommand:
cmp [wparam],BN_CLICKED shl 16 + IDCANCEL
je .wmclose
cmp [wparam],BN_CLICKED shl 16 + IDOK
jne .processed
.wmclose:
invoke EndDialog,[hwnddlg],0
.processed:
mov eax,1
.finish:
pop edi esi ebx
ret
endp
szTip1 db 'Enter your login',0
szTip2 db 'Enter your password',0
szTip3 db 'Hello! Click me and your Universe will be annihilated ;)',0
szTip4 db 'STATIC is not so static',0
szText db 'Window',0
;----------------------------------------------------------------------
; Процедура добавления подсказки к окну
; Входные параметры:
; hwnd - хэндл окна, к которому добавляется подсказка
; lpText - указатель на строку подсказки
; lpData - указатель на данные (2 DWORD)
;----------------------------------------------------------------------
proc AddTooltip hwnd:DWORD, lpText:DWORD, lpData:DWORD
pusha
; Оно подсказки уже инициализировано?
cmp [hwndTip],0
jne @f
invoke GetModuleHandle,0
; Создать окно подсказки
invoke CreateWindowEx,NULL, ttclass, NULL,\
TTS_ALWAYSTIP,\
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,\
NULL, NULL, eax, NULL
; Сохранить хэндл окна подсказки
mov [hwndTip],eax
; Определить константу CS_DROPSHADOW
CS_DROPSHADOW = 00020000h
; Получить текущее значение стиля окна
invoke GetWindowLong,[hwndTip],GCL_STYLE
; Добавить к нему атрибут тень
or eax,CS_DROPSHADOW
; Установить новый стиль окна
invoke SetClassLong,[hwndTip],GCL_STYLE,eax
; Заполнение структуры для подсказки
mov [ttip.cbSize],sizeof.TOOLINFO
mov [ttip.hwnd],NULL
mov [ttip.uFlags],TTF_IDISHWND+TTF_TRACK+TTF_ABSOLUTE+TTF_SUBCLASS
mov [ttip.uId],NULL
mov [ttip.lpszText],szNull
; Создать подсказку
invoke SendMessage,[hwndTip],TTM_ADDTOOL,0,ttip
; Установить максимальную ширину. При этом длинный текст будет
; переноситься на следующую строку
invoke SendMessage,[hwndTip],TTM_SETMAXTIPWIDTH,0,TOOLTIP_WIDTH
; Установить подсказку поверх всех окон
invoke SetWindowPos,[hwndTip],HWND_TOPMOST,0,0,0,0,SWP_NOMOVE+SWP_NOSIZE+SWP_NOACTIVATE
@@:
; Субклассировать окно для вывода подсказки
invoke SetWindowLong,[hwnd],GWL_WNDPROC,ToolTipProc
mov edi,[lpData]
stosd
mov eax,[lpText]
stosd
; Сохранить в пользовательских данных окна указатель на массив
invoke SetWindowLong,[hwnd],GWL_USERDATA,[lpData]
popa
ret
ttclass db 'tooltips_class32',0
szNull db ' ',0
endp
;----------------------------------------------------------------------
; Субклассированная процедура обработки всплывающей подсказки
;----------------------------------------------------------------------
proc ToolTipProc hwnddlg:DWORD,msg:DWORD,wparam:DWORD,lparam:DWORD
cmp [msg],WM_MOUSELEAVE
je .wmleave
cmp [msg],WM_MOUSEMOVE
je .wmmouse
; Получить адрес предыдущего обработчика
invoke GetWindowLong,[hwnddlg],GWL_USERDATA
mov eax,[eax]
; Передать управление предыдущему обработчику
invoke CallWindowProc,eax,[hwnddlg],[msg],[wparam],[lparam]
ret
.wmleave:
; Скрыть подсказку
invoke SendMessage,[hwndTip], TTM_TRACKACTIVATE, FALSE, ttip
mov [TTipFlag],FALSE
jmp .finish
.wmmouse:
; Подсказка уже показывается?
cmp [TTipFlag],TRUE
je @f
; Установить перехватчик мыши на событие
mov [tme.cbSize],sizeof.TRACKMOUSEEVENT
mov eax,[hwnddlg]
mov [tme.hwndTrack],eax
mov [tme.dwFlags],TME_LEAVE
invoke TrackMouseEvent,tme
; Получить адрес строки подсказки
invoke GetWindowLong,[hwnddlg],GWL_USERDATA
mov eax,[eax+4]
; Установить новый текст подсказки
mov [ttip.lpszText],eax
; Обновить подсказку
invoke SendMessage,[hwndTip], TTM_SETTOOLINFO, TRUE, ttip
; Включить отображение подсказки
invoke SendMessage,[hwndTip], TTM_TRACKACTIVATE, TRUE, ttip
; Установить флаг, что подсказка уже отображается
mov [TTipFlag],TRUE
@@:
; Получить координаты мыши
mov eax,[lparam]
and eax,0FFFFh
mov esi,eax ; X
mov eax,[lparam]
shr eax,16
mov edi,eax ; Y
; Фактическое движение мыши было?
mov eax,[oldX]
cmp eax,esi
jne @f
mov eax,[oldY]
cmp eax,edi
je .finish
@@:
; Сохранить новые координаты
mov eax,esi
mov [pt.x],eax
mov [oldX],eax
mov eax,edi
mov [pt.y],eax
mov [oldY],eax
; Вычислить абсолютные координаты на экране
invoke ClientToScreen,[hwnddlg],pt
mov ebx,[pt.y]
; Получить высоту окна подсказки
invoke GetWindowRect,[hwndTip],trect
mov eax,[trect.top]
sub eax,[trect.bottom]
add ebx,eax
shl ebx,16
add ebx,[pt.x]
add ebx,5
; Установить подсказку на новые координаты
invoke SendMessage,[hwndTip], TTM_TRACKPOSITION, 0, ebx
.finish:
xor eax,eax
ret
endp
;----------------------------------------------------------------------
section '.idata' import data readable writeable
library kernel32,'KERNEL32.DLL',\
user32,'USER32.DLL'
include 'api\kernel32.inc'
include 'api\user32.inc'
;----------------------------------------------------------------------
section '.rsrc' resource data readable
directory RT_DIALOG,dialogs
resource dialogs,\
37,LANG_ENGLISH+SUBLANG_DEFAULT,demonstration
dialog demonstration,'Tooltips Demo',0,0,190,58,WS_CAPTION+WS_SYSMENU+DS_CENTER
dialogitem 'BUTTON','',-1, 2, -1, 185, 37,WS_VISIBLE+BS_GROUPBOX
dialogitem 'STATIC','EDIT1:',ID_STATIC,5,8,45,12,WS_VISIBLE+SS_RIGHT+SS_NOTIFY
dialogitem 'EDIT','',ID_EDIT1,55,6,110,12,WS_VISIBLE+ES_CENTER+WS_BORDER+ES_NUMBER
dialogitem 'STATIC','EDIT2:',-1,5,22,45,12,WS_VISIBLE+SS_RIGHT
dialogitem 'EDIT','',ID_EDIT2,55,20,110,12,WS_VISIBLE+ES_CENTER+WS_BORDER
dialogitem 'BUTTON','Exit',IDCANCEL,135,40,50,15,WS_VISIBLE+WS_TABSTOP+BS_PUSHBUTTON
enddialog
Результат
Вывод
В ходе курсовой работы была написана программа позволяющая выводить подсказки при наведении на объекты курсора мыши. Всплывающие подсказки позволяют облегчить пользователь общение с приложением, что позволяет избежать множества разнообразных ошибок. Всплывающие подсказки являются неотъемлемой частью большинства приложений.
Использование готовых API функций позволяет существенно ускорить разработку программ, уменьшает количество кода и возможных ошибок, и делает программы более удобными для понимания.
Используемая литература.
http://msdn.microsoft.com/library/ms123401(дата обращения 25.05.2013)
http://www.codenet.ru/progr/delphi/WinAPI/(дата обращения 27.05.2013)
http://vsokovikov.narod.ru/index.htm(дата обращения 16.05.2013)
В.Ю. Пирогов: Ассемблер для Windows, изд. Молгачева С. В., 2002г., 552 с.