ToolTip 是當滑鼠游標在特定區域停留時,自動彈出的小矩形視窗,顯示開發者預設的提示文字。它與狀態列功能相似,但 ToolTip 會在點擊或移出區域時自動消失。若需在工具列以外的任意視窗/控件顯示提示,必須自行建立與管理 ToolTip 控件。
Tooltips_class32)。TTM_RELAYEVENT 或自動 TTF_SUBCLASS 子類化)。TOOLINFO STRUCT
cbSize DWORD ? ; 結構大小 (必填,否則行為不可預期)
uFlags DWORD ? ; 行為旗標組合
hWnd DWORD ? ; 擁有工具的視窗代碼
uId DWORD ? ; 工具 ID 或視窗代碼 (視 uFlags)
rect RECT <> ; 工具矩形區域 (相對 hWnd 客戶區)
hInst DWORD ? ; 字串資源所在模組代碼
lpszText DWORD ? ; 提示文字指標 / 資源 ID / LPSTR_TEXTCALLBACK
lParam LPARAM ? ; 應用程式自訂資料
TOOLINFO ENDS
TTF_IDISHWND:uId 存放視窗代碼,工具覆蓋整個客戶區 (適用按鈕、編輯框)。TTF_SUBCLASS:強烈建議開啟。ToolTip 會自動子類化目標視窗攔截滑鼠訊息,免除手動轉發麻煩。TTF_CENTERTIP:提示顯示於工具區域正下方,而非滑鼠右下角。TTF_RTLREADING:右到左閱讀順序 (阿拉伯/希伯來語環境)。hInst。TTN_NEEDTEXT 通知至 hWnd 取得文字,適合即時變動內容。此範例建立一個對話框,客戶區劃分為左上、右上、左下、右下四個「工具」,並自動列舉對話框上的按鈕控件註冊為工具 (使用 TTF_IDISHWND 覆蓋整個按鈕區域)。
.data
ToolTipsClassName db "Tooltips_class32",0
MainDialogText1 db "This is the upper left area of the dialog",0
MainDialogText2 db "This is the upper right area of the dialog",0
MainDialogText3 db "This is the lower left area of the dialog",0
MainDialogText4 db "This is the lower right area of the dialog",0
.data?
hwndTool dd ?
hInstance dd ?
.code
DlgProc proc hDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
LOCAL ti:TOOLINFO
LOCAL id:DWORD
LOCAL rect:RECT
.if uMsg == WM_INITDIALOG
invoke InitCommonControls
; 1. 建立 ToolTip 控件
invoke CreateWindowEx, NULL, ADDR ToolTipsClassName, NULL, \
TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, \
NULL, NULL, hInstance, NULL
mov hwndTool, eax
; 2. 初始化通用 TOOLINFO
mov id, 0
mov ti.cbSize, sizeof TOOLINFO
mov ti.uFlags, TTF_SUBCLASS ; 關鍵:自動子類化攔截訊息
push hDlg
pop ti.hWnd
invoke GetWindowRect, hDlg, addr rect
; 3. 註冊四個象限工具
invoke SetDlgToolArea, hDlg, addr ti, addr MainDialogText1, id, addr rect
inc id
invoke SetDlgToolArea, hDlg, addr ti, addr MainDialogText2, id, addr rect
inc id
invoke SetDlgToolArea, hDlg, addr ti, addr MainDialogText3, id, addr rect
inc id
invoke SetDlgToolArea, hDlg, addr ti, addr MainDialogText4, id, addr rect
; 4. 列舉子控件 (按鈕等) 並自動註冊
invoke EnumChildWindows, hDlg, addr EnumChild, addr ti
.elseif uMsg == WM_CLOSE
invoke EndDialog, hDlg, NULL
.else
mov eax, FALSE
ret
.endif
mov eax, TRUE
ret
DlgProc endp
;--------------------------------------------------
; 計算象限矩形並註冊工具
;--------------------------------------------------
SetDlgToolArea proc uses edi esi hDlg:DWORD, lpti:DWORD, lpText:DWORD, id:DWORD, lprect:DWORD
mov edi, lpti
mov esi, lprect
assume esi:ptr RECT
assume edi:ptr TOOLINFO
; 根據 id (0-3) 計算四個象限矩形 (左、上、右、下)
.if id == 0 ; 左上
mov [edi].rect.left, 0
mov [edi].rect.top, 0
mov eax, [esi].right
sub eax, [esi].left
shr eax, 1
mov [edi].rect.right, eax
mov eax, [esi].bottom
sub eax, [esi].top
shr eax, 1
mov [edi].rect.bottom, eax
.elseif id == 1 ; 右上
; ... (略) 計算右半部 ...
.elseif id == 2 ; 左下
; ... (略) 計算下半部左側 ...
.else ; 右下
; ... (略) 計算右下 ...
.endif
push lpText
pop [edi].lpszText
invoke SendMessage, hwndTool, TTM_ADDTOOL, NULL, lpti
assume edi:nothing
assume esi:nothing
ret
SetDlgToolArea endp
;--------------------------------------------------
; EnumChild 回呼:為每個子控件註冊工具 (使用 TTF_IDISHWND)
;--------------------------------------------------
EnumChild proc uses edi hwndChild:DWORD, lParam:DWORD
LOCAL buffer[256]:BYTE
mov edi, lParam
assume edi:ptr TOOLINFO
push hwndChild
pop [edi].uId ; uId = 子控件代碼
or [edi].uFlags, TTF_IDISHWND ; 標記:工具 = 整個子控件客戶區
invoke GetWindowText, hwndChild, addr buffer, 255
lea eax, buffer
mov [edi].lpszText, eax ; 使用控件標題文字作為提示
invoke SendMessage, hwndTool, TTM_ADDTOOL, NULL, edi
assume edi:nothing
ret
EnumChild endp
| 訊息 | 用途 |
|---|---|
| TTM_ACTIVATE | 啟用/停用 ToolTip (wParam=TRUE/FALSE) |
| TTM_DELTOOL | 移除已註冊工具 |
| TTM_GETTOOLINFO / TTM_SETTOOLINFO | 查詢/修改工具屬性 |
| TTM_NEWTOOLRECT | 僅更新工具矩形區域 |
| TTM_UPDATETIPTEXT | 僅更新提示文字 |
| TTM_SETDELAYTIME | 設定顯示延遲、重新顯示延遲、自動關閉時間 |
comctl32.dll,CreateWindowEx 會失敗。TTF_SUBCLASS,必須在目標視窗處理 WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_RBUTTONDOWN, WM_RBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP 並轉發 TTM_RELAYEVENT。lpszText 指向區域變數緩衝區,確保 ToolTip 顯示期間緩衝區有效。