27th Tool Tips Control
We will learn tools to tips control: what it is created and used. Download example
theory:
Tool Tips When a rectangular window displayed when the mouse is resstired on a particular area. The Tool Tip window contains some text that the programmer wants to display. At this point, the tool prompt is the same as the status of the status bar, which is different. It is a tooltip when you click or away from the specified area, you may be familiar with tooltips associated with the toolbar, those "Tips" are the convenience provided by the toolbar control. If you want other windows, controls If you have a tooltip, you have to create them yourself.
Since you have already understood what tool tips, let's take a look at how to create them. The rough steps are as follows:
Create a tooltip control with the CreateWindowEx function. Define a tooltip control to monitor the area where your mouse moves. Pass the area to the Tool Tips Control to transfer the mouse message of the delivery area to the Tool Tool Tips Control. (This is earlier, dependent broadcast message Methods) Let's discuss each step in detail below.
Tool Tips Controls The Tool Tool Tips The control is a general control. Similarly, you want to call somewhere in the source code
INITCOMMONCONTROLS so that MASM can connect your programs and COMCTL32.DLL. Create Tool Tips for CreateWindowEx, typical code as follows:
.DATA
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
Watch the window style:
TiS_ALWAYSTIP specifies how the tooltip is not that the window status containing the specified area, the tooltip is always displayed when the mouse is shifted by the specified area. Simply, even if the window is in an inactive state, the mouse is moved when the tool prompts the specified area. The tool tips will also appear.
You don't have to include in CreateWindowEx
WS_POPUP and
WS_EX_TOOLWINDOW style, because the tooltip processing process will automatically add, you don't have to specify the coordinates and aspects of the tool prompt window, the control will be automatically adjusted according to the text you want to display. Four parameters, all use
CW_USEDEFAULT, the rest of the parameters is not important.
Specified tool
Tool Tips Controls are created but have not been displayed yet, we want to display the tooltip window when the mouse pointer is above a zone. Now you need to specify this area. We call such a "tool", "Tools" is Tool Tips. The control monitors whether the mouse pointer is moving in a square area located in the window client. If the mouse pointer is moving "Tool", the Tool Tip window is displayed. "Tool" can overwrite the entire customer area or just part of it. So we put "Tool" is divided into two types, one is as a window, and the other is part of a window client area. Two kinds of use. Covering the "Tool" of the entire client area is usually used for buttons, editing controls, etc. You don't have to specify the coordinates and size of the focus domain: it is assumed to be the entire customer area of the window. Only the "Tool" part of the window customer area is overwritten in you want to divide the window customer area into several parts but don't want to use the child window. However, it is necessary to specify the coordinates and width of the upper left corner.
Use the following ToolInfo structure to define "Tools":
ToolInfo Struct
CBSIZE DWORD?
UFLAGS DWORD?
HWND DWORD?
Uid DWORD?
Rect RECT <>
Hinst DWORD?
LPSZTEXT DWORD?
LPARAM LPARAM?
ToolInfo Ends
Domain name illustrates the size of the CBSIToolInfo structure. Must be filled, if this area is not filling Windows and does not report error, you will get an unpredictable result .uflags Specifies the properties of the focus domain, which can be the following: ttf_idishWnd "ID IS hWnd ". If you specify this flag, you mean that you want to use" tools "overwritten the entire client area (above the first" tool "). If you use this flag, you must use the window you want to use. The handle fills the UID member. If you don't specify this member, you will use the second "tool", a square area of the client area window. In this case, you must fill the Rect member in the size of the square area. The TTF_CEntertip Usually the tool prompt window is displayed in the lower right of the mouse, if you specify this flag, the tooltip is always displayed in the center of the focus domain regardless of the mouse. TTF_rtlreaming. If your program is not Arab or Hebrew The idiom system is designed, you can completely do it, it makes the prompt text to display from the right to left, is invalid in other systems. TTF_SUBCLASS If you use this flag, Tool Tips Control will subcatenate "Tools" The window is in order to intercept the mouse message sent to it, so that this flag is very useful, otherwise you will have to do more work to forward the message to the tooltip control. HWnd contains the "Tool" window handle, if you specify the TTF_IDishWnd flag Windows will ignore this value and use the value of the UID member as a window handle. You need to fill this domain if:
You don't use the TTF_IDishWnd flag (in other words, you use local "tools") You specify lpstr_textCallback in the LPSZText member. This value tells the Tool Tips When you need to display a prompt window, you must display the window containing "Tool" should be displayed. What is a real-time control text update. If you need to dynamically change the prompt text, you should specify the lpstr_textCallback value in the LPSZText member, and the control sends a TTN_NeedText message to the window specified by the HWND. UID This domain may have two The meaning of the species, whether or not UFLAGS contains TTF_IDishWnd.
If the TTF_IDISHWND flag is not specified as the "Tools" ID defined by the application, since this means you use "tools" only part of the client area, the logic's launch of a client area may exist multiple the same focus domain (there is no existence Renained, the HWND member is not enough, the application defines the ID to distinguish between them, it is necessary, as long as the only ID can be any value. If the TTF_IDISHWND flag is specified, the entire customer area is used as the focus domain. Handle, you may be strange why you don't have the value of the HWnd member mentioned above. The answer is: if lpsztext is specified as lpstr_textCallback, HWnd may have been populated. There is also a window that provides a prompt text and containing "tools". The window may not be the same! (You can design a window program that provides two services, but it is strict, at this point, Microsoft provides us with greater freedom, cheers!) RECT specifies "Tool" Size RECT structure. This structure defines a square size of the base point in the upper left corner of the customer area in HWND, if you want to specify a part of the client as a "tool", you have to fill this structure, if you specify the TTF_IDishWnd flag The control will ignore this value. (You have chosen the entire customer area as "tool") Hinst If the lpsztext specifies the identity of the string resource, it contains an instance handle that will be used as a string resource. The explanation of LPSZText can understand what this domain is used. If lpsztext does not contain string resource ID, the control ignores this domain. LLPSZText can have the following values:
If you are specified as LPSTR_TEXTCALLBACK, the Tool Tip Control will send a TTN_NeedText message to the HWND window to get the string to be displayed. Prompt text Dynamic update method: Each display prompt window changes the prompt text. If you specify a string resource in this domain Identification, when the control is to display the prompt text in the prompt window, search for the string resource list of the instance of the Hinst member ID. Since the string resource list ID is always 16-bit values, the high byte of this domain will always be 0, This approach is very useful when you want to transplant procedures. Since string resources are defined in script, you don't have to modify source code. You only need to modify the string list prompts to change accordingly, but don't worry to introduce BUGS. If this domain The value is not lpstr_textCallback and the high byte is not zero, the control takes this value as a pointer to the prompt text, which is the simplest method but is also the most unstable. By checking the high byte area string resource ID. In general, you need Picking the ToolInfo structure to the tool prompt control before populating, which describes the tool properties you expect.
Register "Tool" to Tool Tips Control Fill
After the ToolInfo structure, it must be passed to the control. A tooltip control can control a lot of "tools", so you don't have to create a lot of controls for a window. To register "Tools", send control to the control
TTM_ADDTOOL message
WPARAM is not used,
LPARAM must contain to register
Toolinfo structure of pointer
.DATA?
Ti ToolInfo <>
.......
.code
.......
.......
Invoke SendMessage, HWNDTooltip, TTM_ADDTOOL, NULL, ADDR TI
Successfully returned
True, otherwise returned
False.
send
TTM_DELTOOL message Unregister.
After forwarding a mouse message, the control knows that the control knows that the control should be monitored and what should be displayed on the prompt window. The only lack is the stimulation mechanism. Think about the customer area of other windows specified by "Tool" Area. How to intercept the message to the window? In practice, you need to intercept the message to learn how long the mouse is stayed. After the specified time passes, the control shows the prompt window. There are two ways: a method to include "tool" The window is collaborated, and the other is not required.
A window containing "Tools" must send TTM_RELAYEVENT to the control to forward messages. LPARAM is a pointer control to forward message MSG only handle the following mouse message:
WM_LBUTTONDOWN WM_MOUSEMOVE WM_LBUTTONUP WM_RBUTTONDOWN WM_MBUTTONDOWN WM_RBUTTONUP WM_MBUTTONUP whole other messages are ignored, so the process include the "Tools" window must contain a selection like this: 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 ......... You can specify a TTF_SUBCLASS flag in the toolinfo structure of UFLAGS. This flag tells the control subcarpse to include the "Tool" window to capture the mouse message without the collaboration of the window. It is easy to use because of the except for the intercepted mouse message and the specified TTF_SUBCLASS flag. Just these, the control has been fully functional until this step. There are several related messages you should know .ttm_activate. If you want to dynamically allow or prohibit the tooltip control, this small news is for you .wparam The value is True, allows the control. If the control is prohibited. If the control is initially created, no send message is activated. TTM_GettoolInfo and TTM_SETTOOLINFO. If you want to pass the ToolInfo structure to the control after the control Change its value, use this message. You need to specify "tool" to change with the correct UID and hwnd value. If you just want to change the value of Rect member, use the TTM_NewToolRect message if you only want to change the prompt text, use the TTM_UPDATETIPTEXT message. TTM_SETDELAYTIME. Use this message to specify the time delay when the control is displayed.
Example: An example is a dialog with two buttons, and the customer distinguish between dialogs is 4 parts: top left, upper right, left, right. Each area is specified as "tool" that you have a message, two buttons are also available. Your own prompt text.
.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, EAX
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 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 Setdlgtolarea, HDLG, Addr Ti, Add, Addr Rect Invoke EnumchildWindows, HDLG, Addr Enumchild, Addr Ti.elseif, INUMCHILD UMSG == WM_Close Invoke EndDialog, HDLG, NULL .ELSE MOV EAX, FALSE RET .Endif Mov Eax, True Ret DLGPROC ENDP
EnumChild 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 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 .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 endpend start
analysis:
After creating the main dialog window, use the CREATEWINDOWEX to create a Tool Tips Control.
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
After that, we continue to define the four corners of the dialog as the focus domain.
MOV ID, 0; focus domain ID MOV TI.CBSIZE, SIZEOF TOOLINFO MOV TI.UFLAGS, TTF_SUBCLAS; Tell the control subclassic window. Push HDLG Pop Ti.hwnd; window handle containing the focus domain Invoke GetWindowRect, HDLG, AddR Rect; Get the size of the customer area Invoke Setdlgtolarea, HDLG, Addr Ti, Addr MageDialogtext1, ID, Addr Rect
We initialize the Toolinfo structure. Note that we must divide the customer zone into four focus domains, so we need to know the size of the client area, so call getWindowRect. Because we don't want to forward messages to the control, specify TiF_subclass flag .Setdlgtoolares is calculated to calculate the focus domain rectangle The range of the range and the function registered to the control. I don't explain the calculation process in detail. It only shows that it divides the dialog into four focus domains. Then send a TTM_ADDTOOL message to the control, and transfer the address of the ToolInfo structure in the lParam parameter.
Invoke SendMessage, HWNDTOOL, TTM_ADDTOOL, NULL, LPTI After four control registration, let's take a look at the button of the dialog, we can use the ID to handle each button, but it is too boring. We use the EnumChildWindows function listing on the dialog box All controls and register them to controls, and the EnumChildWindows prototype is as follows:
ENUMCHILDWINDOWS PROTO HWND: DWORD, LPENUMFUNC: DWORD, LPARAM: DWORD
HWnd is a parent window handle.
LpenumFunc is the EnumChildProc function address that will call each control. LParam is a value that the application is defined to pass to the ENUMCHILDPROC function. The EnumChildProc function is defined as follows:
EnumchildProc Proto Hwndchild: DWORD, LPARAM: DWORD
HWNDCHILD is
ENUMCHILDWINDOWS function enumeration handle. LPARAM is you pass
The same LPARAM of the enumchildWindows function.
In the example. We call so call
EnumChildWindows function:
Invoke EnumchildWindows, HDLG, Addr Enumchild, Addr Ti
We put
The address of the ToolInfo structure is passed in the LParam parameter, because we want
Register each child control in the enumChild function. If we don't use this method, you need to
Ti declaration is a global variable, but this may introduce many bugs.
When we call
When EnumChildWindows, Windows enumerates all the child controls on the dialog and calls each child control.
ENUMCHILD F function. This is if our dialog has two controls,
Enumchild will be called twice.
The enumchild function fills the corresponding member of the ToolInfo structure and registers to the control.
ENUMCHILD Proc Uses Edi HWNDCHILD: DWORD, LPARAM: DWORD
Local buffer [256]: Byte
MOV EDI, LPARAM
Assume EDI: PTR ToolInfo
Push HWNDCHILD
POP [EDI] .uid; We use the whole client is the Tool AS TOOL OF TOOL; WE User CLET
OR [EDI] .uflags, TTF_IDishWnd
Invoke GetWindowText, HWNDCHILD, ADDR BUFFER, 255
Lea Eax, Buffer; Use the window text as the tooltip text
MOV [EDI] .lpsztext, EAX
Invoke SendMessage, Hwndtool, TTM_ADDTOOL, NULL, EDI
Assume EDI: Nothing
RET
ENUMCHILD ENDP
Note In the example, we used a "tool": "Tools" over the entire client area, so we need to populate the handle containing the Tools window.
UID member must also
Designated UFLAGS member
TTF_idishWnd flag.