| ||
This chapter was a compromise for me. There are lots of problems in Windows programming, and my natural desire was to coyer them all. However, if I dedicated an entire chapter to every question, the book would soon be too large. Therefore, I decided to devote one chapter to problem-solving aspects and to cover in detail as many interesting problems as I could. This chapter is built on questions that you might ask and answers that I would provide.
Q. How can I ensure that the icon of the minimized application fits on the system toolbar?
This problem can be solved using the shell_NotifyIcon system function. This solution is so simple that I have to wonder why most programmers employ various libraries for this purpose. The shell_NotifyIcon function accepts the following parameters:
First parameterThe action that needs to be carried out
NIM_ADD equ 0h Add an icon to the system toolbar
NIM_MODIFY equ 1h Delete the icon from the system toolbar
NIM_DELETE equ 2h Modify the icon
Second parameterThe pointer to the structure that contains information required for carrying out the specified action
NOTI_ICON STRUC cbSize DWORD ? hWnd DWORD ? uID DWORD ? uFlags DWORD ? uCallbackMessage DWORD ? hIcon DWORD ? szTip DB 64 DUP (?) NOTI_ICON ENDS
The elements of the preceding structure are as follows :
cbSize Structure size .
hWnd Descriptor of the window, to which the message will be sent (described later).
uID Icon identifier.
uFlags Combination of the following flags:
NIF_MESSAGE equ 1h Use the hIcon field
NIF_ICON equ 2h Use the uCallbackMessage field
NIF_TIP equ 4h Use the szTip field
uCallbackMessage Message that arrives to the window identified by the hWnd descriptor if some event occurs near the system toolbar icon. The message value must be more than 1024. When this message arrives, WPARAM contains the icon identifier and LPARAM defines the event that occurred to the icon.
hIcon Icon handle.
SzTip Popup help text.
Consider how the entire mechanism operates. If the window is minimized, the WM_SIZE message arrives at the window function. In this message, wParam must contain the SIZE_MINIMIZED value. In this case, it is necessary to use the shell_NotifyIcon function that will place the icon to the system toolbar. Any event related to the mouse when its cursor is located over the icon would cause the uCallbackMessage to arrive at the window function. You have defined this message yourself. In this case, the most significant wParam word will contain the icon identifier, and the least significant lParam word will allow you to define the event type. Listing 18.1 demonstrates how this mechanism operates.
// The TRAY.RC file // Constant definitions #define WS_SYSMENU 0x00080000L #define WS_MINIMIZEBOX 0x00020000L #define WS_MAXIMIZEBOX Ox000l0000L #define DS_3DLOOK 0x0004L // Identifiers #define IDI_ICON1 1 // Define the icon IDI_ICON1 ICON "ico1.ico" // Dialog box definition DIAL1 DIALOG 0, 0, 250, 110 STYLE WS_SYSMENU WS_MINIMIZEBOX WS_MAXIMIZEBOX DS_3DLOOK CAPTION "Place the icon on the system toolbar" FONT 8, "Arial" { } ; The TRAY.INC file ; Constants NIM_ADD equ Oh ; Add the icon to the system toolbar NIM_MODIFY equ 1h ; Remove the icon NIM_DELETE equ 2h ; Modify the icon NIF_MESSAGE equ 1h ; Use the hIcon field NIF_ICON equ 2h ; Use the uCallbackMessage field NIF_TIP equ 4h ; Use the szTip field FLAG equ NIF_MESSAGE or NIF_ICON or NIF_TIP SIZE_MINIMIZED equ 1h SW_HIDE equ 0 SW_SHOWNORMAL equ 1 ; This message arrives when the window is closed WM_CLOSE equ 10h WM_INITDIALOG equ 110h WM_SIZE equ 5h WM_LBUTTONDBLCLK equ 203h WM_LBUTTONDOWN equ 201h ; Prototypes of external procedures IFDEF MASM EXTERN ShowWindow@8:NEAR EXTERN LoadIconA@8:NEAR EXTERN lstrcpyA@8:NEAR EXTERN Shell_NotifyIconA@8:NEAR EXTERN ExitProcess@4:NEAR EXTERN GetModuleHandleA@4:NEAR EXTERN DialogBoxParamA@20:NEAR EXTERN EndDialog@8:NEAR EXTERN SendDlgItemMessageA@20:NEAR ELSE EXTERN ShowWindow:NEAR EXTERN LoadIconA:NEAR EXTERN lstrcpyA:NEAR EXTERN Shell_NotifyIconA:NEAR EXTERN ExitProcess:NEAR EXTERN GetModuleHandleA:NEAR EXTERN DialogBoxParamA:NEAR EXTERN EndDialog:NEAR EXTERN SendDlgItemMessageA:NEAR ShowWindow@8 = ShowWindow LoadIconA@8 = LoadIconA lstrcpyA@8 = lstrcpyA Shell_NotifyIconA@8 = Shell_NotifyIconA ExitProcess@4 = ExitProcess GetModuleHandleA@4 = GetModuleHandleA DialogBoxParamA@20 = DialogBoxParamA EndDialog@8 = EndDialog SendDlgItemMessageA@20 = SendDlgItemMessageA ENDIF ; Structures ; Message structure MSGSTRUCT STRUC MSHWND DD ? MSMESSAGE DD ? MSWPARAM DD ? MSLPARAM DD ? MSTIME DD ? MSPT DD ? MSGSTRUCT ENDS ; Structure for the Shell_NotifyIcon function NOTI_ICON STRUC cbSize DWORD ? hWnd DWORD ? uID DWORD ? uFlags DWORD ? uCallbackMessage DWORD ? hIcon DWORD ? szTip DB 64 DUP (?) NOTI_ICON ENDS ; The TRAY.ASM file .586P ; Flat memory model .MODEL FLAT, stdcall include tray.inc ; INCLUDELIB directives for the linker IFDEF MASM includelib c:\masm32\lib\user32.lib includelib c:\masm32\lib\kernel32.lib includelib c:\masm32\lib\shell32.lib ELSE includelib c:\tasm32\lib\import32.lib ENDIF ;------------------------------------------------ ; Data segment _DATA SEGMENT MSG MSGSTRUCT <?> HINST DD 0 ; Application descriptor PA DB "DIAL1", 0 NOTI NOTI_ICON <0> TIP DB "Example of using the function" DB "Shell_NotifyIcon", 0 _DATA ENDS ; Code segment _TEXT SEGMENT START: ; Get the application handle PUSH 0 CALL GetModuleHandleA@4 MOV [HINST], EAX ;-------------------------------- PUSH 0 PUSH OFFSET WNDPROC PUSH 0 PUSH OFFSET PA PUSH [HINST] CALL DialogBoxParamA@20 CMP EAX, -1 JNE KOL ; Error message KOL: ;-------------------------------- PUSH 0 CALL ExitProcess@4 ;-------------------------------- ; Window procedure ; Position of parameters in the stack ; [EBP+014H] ; LPARAM ; [EBP+10H] ; WAPARAM ; [EBP+0CH] ; MES ; [EBP+8] ; HWND WNDPROC PROC PUSH EBP MOV EBP, ESP PUSH EBX PUSH ESI PUSH EDI ;-------------- CMP DWORD PTR [EBP+0CH], WM_CLOSE JNE L1 PUSH 0 PUSH DWORD PTR [EBP+08H] CALL EndDialog@8 JMP FINISH L1: CMP DWORD..PTR [EBP+0CH],. WM_INITDIALOG JNE L2 JMP FINISH L2: CMP DWORD PTR [EBP+0CH], WM_SIZE JNE L3 CMP DWORD PTR [EBP+10H], SIZE_MINIMIZED JNE . L3 ; Here, all work related to setting the icon ; on the system toolbar is carried out MOV NOTI.cbSize, 88 MOV EAX, DWORD PTR [EBP+8H] MOV NOTI.hWnd, EAX MOV NOTI.uFlags, FLAG MOV NOTI.uID, 12 ; Icon identifier MOV NOTI.uCallbackMessage, 2000 ; Message ; Load an icon from the resources PUSH 1 PUSH [HINST] CALL LoadIconA@8 ; Copy the popup help message MOV NOTI.hIcon, EAX PUSH OFFSET TIP PUSH OFFSET NOTI.SzTip CALL lstrcpyA@8 ; Place the icon PUSH OFFSET NOTI PUSH NIM_ADD CALL Shell_NotifyIconA@8 ; Hide the minimized window PUSH SW_HIDE PUSH DWORD PTR [EBP+08H] CALL ShowWindow@8 JMP FINISH L3: ; Message from the toolbar icon? CMP DWORD PTR [EBP+0CH], 2000 JNE FINISH ; Identifier of the icon? CMP WORD PTR [EBP+10H], 12 JNE FINISH ; What happened? Was it a double click? CMP WORD PTR [EBP+14H], WM_LBUTTONDBLCLK JNE FINISH ; Fill the structure MOV NOTI.cbSize, 88 MOV EAX, DWORD PTR [EBP+8H] MOV NOTI.hWnd, EAX MOV NOTI.uFlags, NIF_ICON MOV NOTI.uID, 12 ; Icon identifier MOV NOTI.uCallbackMessage, 1000 ; Message ; Delete the icon PUSH OFFSET NOTI PUSH NIM_DELETE CALL Shell_NotifyIconA@8 ; Restore the window PUSH SW_SHOWNORMAL PUSH DWORD PTR [EBP+08H] CALL,ShowWindow@8 FINISH: MOV EAX, 0 POP EDI POP ESI POP EBX POP EBP RET 16 WNDPROC ENDP _TEXT ENDS END START
To translate the program from Listing 18.1, issue the following commands for MASM32:
ml /c /coff /DMASM tray.asm rc tray.rc link /subsystem:windows tray.obj tray.res
Issue the following commands for TASM32:
tasm32 /ml tray.asm brcc32 tray.rc tlink32 -aa tray.obj,,,,,tray.res
In relation to the program from Listing 18.1, I'd like to draw your attention to the WM_SIZE message. It's very useful. Assume that you have placed some information in your window. If this window can be resized, you'll have to solve the problem of positioning the information in the window every time it is resized. This message can be used if you carefully redraw and rescale the window output. It is necessary to point out that when the message is sent, the window size has already changed, WPARAM contains the flag specifying what has happened to the window, and LPARAM gives the new window size (the least significant word is for the width, and the most significant word is for the height).
| ||