📄 tut23.html
字号:
<p><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>When
the main window is created, it creates a popup menu and append two menu
items. AppendMenu has the following syntax:</font></font></font>
<br>
<blockquote><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>AppendMenu
PROTO hMenu:DWORD, uFlags:DWORD, uIDNewItem:DWORD, lpNewItem:DWORD</font></font></font></b>
<br>
<ul>
<li>
<font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>hMenu
is the handle of the menu you want to append the item to</font></font></font></li>
<li>
<font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>uFlags
tells Windows about the menu item to be appended to the menu whether it
is a bitmap or a string or an owner-draw item, enabled, grayed or disable
etc. You can get the complete list from win32 api reference. In our example,
we use MF_STRING which means the menu item is a string.</font></font></font></li>
<li>
<font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>uIDNewItem
is the ID of the menu item. This is a user-defined value that is used to
represent the menu item.</font></font></font></li>
<li>
<font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>lpNewItem
specifies the content of the menu item, depending on what you specify in
uFlags member. Since we specify MF_STRING in uFlags member, lpNewItem must
contain the pointer to the string to be displayed in the popup menu.</font></font></font></li>
</ul>
</blockquote>
<font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>After
the popup menu is created, the main window waits patiently for the user
to press minimize button.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>When
a window is minimized, it receives WM_SIZE message with SIZE_MINIMIZED
value in wParam.</font></font></font>
<p><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
.elseif uMsg==WM_SIZE</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
.if wParam==SIZE_MINIMIZED</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
mov note.cbSize,sizeof NOTIFYICONDATA</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
push hWnd</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
pop note.hwnd</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
mov note.uID,IDI_TRAY</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
mov note.uFlags,NIF_ICON+NIF_MESSAGE+NIF_TIP</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
mov note.uCallbackMessage,WM_SHELLNOTIFY</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
invoke LoadIcon,NULL,IDI_WINLOGO</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
mov note.hIcon,eax</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
invoke lstrcpy,addr note.szTip,addr AppName</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
invoke ShowWindow,hWnd,SW_HIDE</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
invoke Shell_NotifyIcon,NIM_ADD,addr note</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
.endif</font></font></font></b>
<p><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>We
use this opportunity to fill NOTIFYICONDATA structure. IDI_TRAY is just
a constant defined at the beginning of the source code. You can set it
to any value you like. It's not important because you have only one tray
icon. But if you will put several icons into the system tray, you need
unique IDs for each tray icon. We specify all flags in uFlags member because
we specify an icon (NIF_ICON), we specify a custom message (NIF_MESSAGE)
and we specify the tooltip text (NIF_TIP). WM_SHELLNOTIFY is just a custom
message defined as WM_USER+5. The actual value is not important so long
as it's unique. I use the winlogo icon as the tray icon here but you can
use any icon in your program. Just load it from the resource with LoadIcon
and put the returned handle in hIcon member. Lastly, we fill the szTip
with the text we want the shell to display when the mouse is over the icon.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>We
hide the main window to give the illusion of "minimizing-to-tray-icon"
appearance.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>Next
we call Shell_NotifyIcon with NIM_ADD message to add the icon to
the system tray.</font></font></font>
<p><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>Now
our main window is hidden and the icon is in the system tray. If you move
the mouse over it, you will see a tooltip that displays the text we put
into szTip member. Next, if you double-click at the icon, the main window
will reappear and the tray icon is gone.</font></font></font>
<p><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
.elseif uMsg==WM_SHELLNOTIFY</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
.if wParam==IDI_TRAY</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
.if lParam==WM_RBUTTONDOWN</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
invoke GetCursorPos,addr pt</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
invoke SetForegroundWindow,hWnd</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
invoke TrackPopupMenu,hPopupMenu,TPM_RIGHTALIGN,pt.x,pt.y,NULL,hWnd,NULL</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
invoke PostMessage,hWnd,WM_NULL,0,0</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
.elseif lParam==WM_LBUTTONDBLCLK</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
invoke SendMessage,hWnd,WM_COMMAND,IDM_RESTORE,0</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
.endif</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
.endif</font></font></font></b>
<p><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>When
a mouse event occurs over the tray icon, your window receives WM_SHELLNOTIFY
message which is the custom message you specified in uCallbackMessage member.
Recall that on receiving this message, wParam contains the tray icon's
ID and lParam contains the actual mouse message. In the code above, we
check first if this message comes from the tray icon we are interested
in. If it does, we check the actual mouse message. Since we are only interested
in right mouse click and double-left-click, we process only WM_RBUTTONDOWN
and WM_LBUTTONDBLCLK messages.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>If
the mouse message is WM_RBUTTONDOWN, we call GetCursorPos to obtain the
current screen coordinate of the mouse cursor. When the function returns,
the POINT structure is filled with the screen coordinate of the mouse cursor.
By screen coordinate, I mean the coordinate of the entire screen without
regarding to any window boundary. For example, if the screen resolution
is 640*480, the right-lower corner of the screen is x==639 and y==479.
If you want to convert the screen coordinate to window coordinate, use
ScreenToClient function.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>However,
for our purpose, we want to display the popup menu at the current mouse
cursor position with TrackPopupMenu call and it requires screen coordinates,
we can use the coordinates filled by GetCursorPos directly.</font></font></font>
<br><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>TrackPopupMenu
has the following syntax:</font></font></font>
<br>
<ul><b><font face="Arial,Helvetica"><font color="#CC6600"><font size=-1>TrackPopupMenu
PROTO hMenu:DWORD, uFlags:DWORD, x:DWORD, y:DWORD, nReserved:DWORD,
hWnd:DWORD, prcRect:DWORD</font></font></font></b>
<br>
<li>
<font face="Arial,Helvetica"><font size=-1><font color="#FFFF00">hMenu</font><font color="#CCCCCC">
is the handle of the popup menu to be displayed</font></font></font></li>
<li>
<font face="Arial,Helvetica"><font size=-1><font color="#FFFF00">uFlags</font><font color="#CCCCCC">
specifies the options of the function. Like where to position the menu
relative to the coordinates specified later and which mouse button will
be used to track the menu. In our example, we use TPM_RIGHTALIGN to position
the popup menu to the left of the coordinates.</font></font></font></li>
<li>
<font face="Arial,Helvetica"><font size=-1><font color="#FFFF00">x</font><font color="#CCCCCC">
and </font><font color="#FFFF00">y</font><font color="#CCCCCC"> specify
the location of the menu in screen coordinates.</font></font></font></li>
<li>
<font face="Arial,Helvetica"><font size=-1><font color="#FFFF00">nReserved</font><font color="#CCCCCC">
must be NULL</font></font></font></li>
<li>
<font face="Arial,Helvetica"><font size=-1><font color="#FFFF00">hWnd</font><font color="#CCCCCC">
is the handle of the window that will receive the messages from the menu.</font></font></font></li>
<li>
<font face="Arial,Helvetica"><font size=-1><font color="#FFFF00">prcRect</font><font color="#CCCCCC">
is the rectangle in the screen where it is possible to click without dismissing
the menu. Normally we put NULL here so when the user clicks anywhere outside
the popup menu, the menu is dismissed.</font></font></font></li>
</ul>
<font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>When the
user double-clicks at the tray icon, we send WM_COMMAND message to our
own window specifying IDM_RESTORE to emulate the user selects Restore menu
item in the popup menu thereby restoring the main window and removing the
icon from the system tray. In order to be able to receive double click
message, the main window must have CS_DBLCLKS style.</font></font></font>
<p><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
invoke Shell_NotifyIcon,NIM_DELETE,addr note</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
mov eax,wParam</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
.if ax==IDM_RESTORE</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
invoke ShowWindow,hWnd,SW_RESTORE</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
.else</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
invoke DestroyWindow,hWnd</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>
.endif</font></font></font></b>
<p><font face="Arial,Helvetica"><font color="#CCCCCC"><font size=-1>When
the user selects Restore menu item, we remove the tray icon by calling
Shell_NotifyIcon again, this time we specify NIM_DELETE as the message.
Next, we restore the main window to its original state. If the user selects
Exit menu item, we also remove the icon from the tray and destroy the main
window by calling DestroyWindow.</font></font></font>
<br>
<hr WIDTH="100%">
<center><b>[<a href="http://win32asm.cjb.net">Iczelion's Win32 Assembly
Homepage</a>]</b></center>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -