.dataRemarquez le 'window style': TIS_ALWAYSTIP. Ce style indique que l'on affichera le tooltip lorsque le pointeur de la souris est placée au-dessus du secteur désigné, indépendamment du statut de la fenêtre qui contient ce secteur. Mis seul, si vous employez ce Flag, quand le pointeur de la souris plane sur le secteur, vous faites référence au tooltip control, et la bulle tooltip apparaîtra même si la fenêtre (ou l'objet) sous le pointeur de la souris est inactive.
TooltipClassName db "Tooltips_class32",0
.code
.....
invoke InitCommonControls
invoke CreateWindowEx, NULL, addr TooltipClassName, NULL, TIS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL
TOOLINFO STRUCT
cbSize DWORD ?
uFlags DWORD ?
hWnd DWORD ?
uId DWORD ?
rect RECT <>
hInst DWORD ?
lpszText DWORD ?
lParam LPARAM ?
TOOLINFO ENDS
Noms | Explications |
cbSize | est la taille de la structure TOOLINFO. Vous DEVEZ remplir ce membre. Windows vous renverra un flag pour dire qu'il y a une erreur si ce champ n'est pas rempli correctement et vous obtiendrez des résultats étranges, imprévisibles. |
uFlags | est un flag (de la taille d'un bit) qui défini les caractéristiques du tool. Cette valeur peut être une combinaison de plusieurs flags que voici :
|
hWnd | est l'handle de la fenêtre qui contient le tool. Si vous mettez le flag TTF_IDISHWND, ce champ sera ignoré puisque Windows utilisera la valeur du membre uId
en tant qu' handle de la fenêtre. Vous avez besoin de remplir ce champ si :
|
uId | La valeur a mettre dans ce champ peut avoir deux significations. ça dépend si le membre uFlags (vu plus haut)
contient le Flag TTF_IDISHWND.
|
rect | La structure RECT définie les dimensions du tool. Cette structure définit un rectangle positionné par rapport au coin supérieur gauche du secteur client de la fenêtre (qui peut aussi être un simple objet) choisi par le membre hWnd. Bref, vous devez remplir cette structure si vous voulez avoir un tool qui ne recouvre qu'une partie du secteur client. Le tooltip control ignorera ce champ si vous avez déjà mis le Flag TTF_IDISHWND (Car dans ce cas, c'est que souhaitiez utiliser un tool qui recouvre la totalité de secteur client. Enfin Normalement ! ! ! ) |
hInst | est l'handle de l'instance (du groupe de données) qui contient la chaîne de caractères en ressource lequel sera employé en tant que 'tooltip texte' uniquement si la valeur dans le membre lpszText pointe sur cette chaîne de caractères. Ça peut paraître confus. Lisez d'abord l'explication sur le membre lpszText et vous comprendrez à quoi sert réellement ce champ. Le tooltip control ignora ce champ si le champ lpszText ne contient pas l'identificateur de la chaîne de caractères en ressource. |
lpszText | Ce champ peut avoir plusieurs valeurs :
|
Pour récapituler, vous avez besoin de remplir la structure TOOLINFO avant de la soumettre au tooltip control. Cette structure définit les caractéristiques du tool que vous désirez obtenir.
.data?SendMessage: Ce message renverra la valeur TRUE si le tool est enregistré avec succès au près du tooltip control, FALSE dans le cas contraire.
ti TOOLINFO <>
.......
.code
.......
<fill the TOOLINFO structure>
.......
invoke SendMessage, hwndTooltip, TTM_ADDTOOL, NULL, addr ti
WndProc proc hWnd:DWORD,
uMsg:DWORD, wParam:DWORD, lParam:DWORD
.......
if uMsg==WM_CREATE
.............
elseif
uMsg==WM_LBUTTONDOWN || uMsg==WM_MOUSEMOVE
|| uMsg==WM_LBUTTONUP || uMsg==WM_RBUTTONDOWN || uMsg==WM_MBUTTONDOWN ||
uMsg==WM_RBUTTONUP || uMsg==WM_MBUTTONUP
invoke SendMessage, hwndTooltip, TTM_RELAYEVENT, NULL, addr msg
..........
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\comctl32.inc
includelib \masm32\lib\comctl32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
DlgProc proto :DWORD,:DWORD,:DWORD,:DWORD
EnumChild proto :DWORD,:DWORD
SetDlgToolArea proto :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
.const
IDD_MAINDIALOG equ 101
.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
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,IDD_MAINDIALOG,NULL,addr DlgProc,NULL
invoke ExitProcess,eaxDlgProc proc hDlg:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
LOCAL ti:TOOLINFO
LOCAL id:DWORD
LOCAL rect:RECT
.if uMsg==WM_INITDIALOG
invoke InitCommonControls
invoke CreateWindowEx,NULL,ADDR ToolTipsClassName,NULL,\
TTS_ALWAYSTIP,CW_USEDEFAULT,\
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
hInstance,NULL
mov hwndTool,eax
mov id,0
mov ti.cbSize,sizeof TOOLINFO
mov ti.uFlags,TTF_SUBCLASS
push hDlg
pop ti.hWnd
invoke GetWindowRect,hDlg,addr rect
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
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 endpEnumChild proc uses edi hwndChild:DWORD,lParam:DWORD
LOCAL buffer[256]:BYTE
mov edi,lParam
assume edi:ptr TOOLINFO
push hwndChild
pop [edi].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 endpSetDlgToolArea 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
.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
mov eax,[esi].right
sub eax,[esi].left
shr eax,1
inc eax
mov [edi].rect.left,eax
mov [edi].rect.top,0
mov eax,[esi].right
sub eax,[esi].left
mov [edi].rect.right,eax
mov eax,[esi].bottom
sub eax,[esi].top
mov [edi].rect.bottom,eax
.elseif id==2
mov [edi].rect.left,0
mov eax,[esi].bottom
sub eax,[esi].top
shr eax,1
inc eax
mov [edi].rect.top,eax
mov eax,[esi].right
sub eax,[esi].left
shr eax,1
mov [edi].rect.right,eax
mov eax,[esi].bottom
sub eax,[esi].top
mov [edi].rect.bottom,eax
.else
mov eax,[esi].right
sub eax,[esi].left
shr eax,1
inc eax
mov [edi].rect.left,eax
mov eax,[esi].bottom
sub eax,[esi].top
shr eax,1
inc eax
mov [edi].rect.top,eax
mov eax,[esi].right
sub eax,[esi].left
mov [edi].rect.right,eax
mov eax,[esi].bottom
sub eax,[esi].top
mov [edi].rect.bottom,eax
.endif
push lpText
pop [edi].lpszText
invoke SendMessage,hwndTool,TTM_ADDTOOL,NULL,lpti
assume edi:nothing
assume esi:nothing
ret
SetDlgToolArea endp
end start
invoke InitCommonControlsAprès ça, on définit quatre Tools pour chaque coin de la boîte de dialogue.
invoke CreateWindowEx,NULL,ADDR ToolTipsClassName,NULL,\
TTS_ALWAYSTIP,CW_USEDEFAULT,\
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
hInstance,NULL
mov hwndTool,eax
mov id,0
; Employé en tant qu' ID du tool.
mov ti.cbSize,sizeof TOOLINFO
mov ti.uFlags,TTF_SUBCLASS
; Impose au tooltip control de sous-classer la fenêtre de dialogue.
push hDlg
pop ti.hWnd ;
handle de la fenêtre qui contient le tool.
invoke GetWindowRect,hDlg,addr rect
; Obtient les dimensions du secteur client.
invoke SetDlgToolArea,hDlg,addr ti,addr MainDialogText1,id,addr
rect
Nous initialisons les membres de la structure TOOLINFO. Remarquez que nous voulons diviser le secteur client en 4 Tools donc nous avons besoin de connaitre les dimensions du secteur client. C'est pourquoi nous appelons GetWindowRect. Nous ne souhaitons pas transmettre les messages souris au tooltip control nous-mêmes donc nous mettons le Flag TIF_SUBCLASS.
SetDlgToolArea
est une fonction qui construit le rectangle de limitation de chaque tool et enregistre ce tool vis à vis du tooltip control. Je n'entrerai pas dans les détails complexes du calcul, il suffirai pour dire qu'elle divise le secteur client en 4 secteurs de mêmes tailles. Donc on envoie le message TTM_ADDTOOL au tooltip control, en passant l'adresse de la structure TOOLINFO dans le paramètre lParam.
invoke SendMessage,hwndTool,TTM_ADDTOOL,NULL,lpti
Après que ces 4 tools soient enregistrés, nous pouvons nous intéresser aux boutons de la boîte de dialogue. Nous pouvons mamipuler chaque bouton par son ID mais ce n'est pas pratique. A la place, nous emploierons l'appel API EnumChildWindows pour dénombrer tous les 'Controls' sur la boîte de dialogue et nous les enregistrons ensuite au près de notre tooltip control.
EnumChildWindows proto hWnd:DWORD, lpEnumFunc:DWORD, lParam:DWORDhWnd est l'handle de la fenêtre parente. LpEnumFunc est l'adresse de la fonction EnumChildProc laquelle sera appelée pour chaque contrôle ayant été dénombré. lParam est la valeur que l'on passera à la fonction EnumChildProc. La fonction EnumChildProc a la définition suivante :
EnumChildProc proto hwndChild:DWORD, lParam:DWORDhwndChild est l'handle d'un contrôle ayant été dénombré par EnumChildWindows. lParam est la même valeur lParam que celle que nous avons passé à EnumChildWindows.
invoke EnumChildWindows,hDlg,addr EnumChild,addr tiNous passons l'adresse de la structure TOOLINFO dans le paramètre lParam parce que nous enregistrerons chaque Child Control de tooltip control dans la fonction EnumChild. Si nous n'utilisons pas cette méthode, nous devons déclarer ti en tant que variable globale, ce qui peut faire apparaître des bogues(défauts).
EnumChild proc uses edi hwndChild:DWORD,lParam:DWORDNotez que dans ce cas, nous employons un type de tool différent: celui-ci recouvre le secteur client de la fenêtre en entier. Nous avons donc besoin de remplir l'élément uID avec l'handle de la fenêtre qui contient ce tool. C'est pourquoi nous devons mettre le Flag TTF_IDISHWND dans le membre uFlags.
LOCAL buffer[256]:BYTE
mov edi,lParam
assume edi:ptr TOOLINFO
push hwndChild
pop [edi].uId ; Nous utilisons la totalité du secteur client du 'Control' en tant que 'tool'.
or [edi].uFlags,TTF_IDISHWND
invoke GetWindowText,hwndChild,addr buffer,255
lea eax,buffer ; Ceci utilise le texte de la fenêtre comme tooltip texte.
mov [edi].lpszText,eax
invoke SendMessage,hwndTool,TTM_ADDTOOL,NULL,edi
assume edi:nothing
ret
EnumChild endp