?? lion-tutorial23.htm
字號:
Shell_NotifyIcon,NIM_ADD,addr note</b> <br>
<b> .endif</b> <br>
<b> .elseif uMsg==WM_COMMAND</b> <br>
<b> .if lParam==0</b> <br>
<b> invoke
Shell_NotifyIcon,NIM_DELETE,addr note</b> <br>
<b> mov eax,wParam</b>
<br>
<b> .if ax==IDM_RESTORE</b>
<br>
<b>
invoke ShowWindow,hWnd,SW_RESTORE</b> <br>
<b> .else</b>
<br>
<b>
invoke DestroyWindow,hWnd</b> <br>
<b> .endif</b>
<br>
<b> .endif</b> <br>
<b> .elseif uMsg==WM_SHELLNOTIFY</b> <br>
<b> .if wParam==IDI_TRAY</b> <br>
<b> .if lParam==WM_RBUTTONDOWN</b>
<br>
<b>
invoke GetCursorPos,addr pt</b> <br>
<b>
invoke SetForegroundWindow,hWnd</b> <br>
<b>
invoke TrackPopupMenu,hPopupMenu,TPM_RIGHTALIGN,pt.x,pt.y,NULL,hWnd,NULL</b>
<br>
<b>
invoke PostMessage,hWnd,WM_NULL,0,0</b> <br>
<b> .elseif
lParam==WM_LBUTTONDBLCLK</b> <br>
<b>
invoke SendMessage,hWnd,WM_COMMAND,IDM_RESTORE,0</b> <br>
<b> .endif</b>
<br>
<b> .endif</b> <br>
<b> .else</b> <br>
<b> invoke DefWindowProc,hWnd,uMsg,wParam,lParam</b>
<br>
<b> ret</b> <br>
<b> .endif</b> <br>
<b> xor eax,eax</b> <br>
<b> ret</b> <br>
<b>WndProc endp</b>
<p><b>end start</b> <br>
<h3> Analysis:</h3>
The program will display a simple window. When you press the minimize button,
it will hide itself and put an icon into the system tray. When you double-click
on the icon, the program will restore itself and remove the icon from the system
tray. When you right-click on it, a popup menu is displayed. You can choose to
restore the program or exit it.
<p><b> .if uMsg==WM_CREATE</b> <br>
<b> invoke CreatePopupMenu</b> <br>
<b> mov hPopupMenu,eax</b> <br>
<b> invoke AppendMenu,hPopupMenu,MF_STRING,IDM_RESTORE,addr
RestoreString</b> <br>
<b> invoke AppendMenu,hPopupMenu,MF_STRING,IDM_EXIT,addr
ExitString</b>
<p>When the main window is created, it creates a popup menu and append two menu
items. AppendMenu has the following syntax: <br>
<blockquote><b>AppendMenu PROTO hMenu:DWORD, uFlags:DWORD, uIDNewItem:DWORD, lpNewItem:DWORD</b>
<br>
<ul>
<li> hMenu is the handle of the menu you want to append the item to</li>
<li> 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.</li>
<li> uIDNewItem is the ID of the menu item. This is a user-defined value that
is used to represent the menu item.</li>
<li> 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.</li>
</ul>
</blockquote>
After the popup menu is created, the main window waits patiently for the user
to press minimize button. <br>
When a window is minimized, it receives WM_SIZE message with SIZE_MINIMIZED value
in wParam.
<p><b> .elseif uMsg==WM_SIZE</b> <br>
<b> .if wParam==SIZE_MINIMIZED</b>
<br>
<b> mov note.cbSize,sizeof
NOTIFYICONDATA</b> <br>
<b> push hWnd</b>
<br>
<b> pop note.hwnd</b>
<br>
<b> mov note.uID,IDI_TRAY</b>
<br>
<b> mov note.uFlags,NIF_ICON+NIF_MESSAGE+NIF_TIP</b>
<br>
<b> mov note.uCallbackMessage,WM_SHELLNOTIFY</b>
<br>
<b> invoke
LoadIcon,NULL,IDI_WINLOGO</b> <br>
<b> mov note.hIcon,eax</b>
<br>
<b> invoke
lstrcpy,addr note.szTip,addr AppName</b> <br>
<b> invoke
ShowWindow,hWnd,SW_HIDE</b> <br>
<b> invoke
Shell_NotifyIcon,NIM_ADD,addr note</b> <br>
<b> .endif</b>
<p>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. <br>
We hide the main window to give the illusion of "minimizing-to-tray-icon" appearance.
<br>
Next we call Shell_NotifyIcon with NIM_ADD message to add the icon to
the system tray.
<p>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.
<p><b> .elseif uMsg==WM_SHELLNOTIFY</b> <br>
<b> .if wParam==IDI_TRAY</b> <br>
<b> .if lParam==WM_RBUTTONDOWN</b>
<br>
<b>
invoke GetCursorPos,addr pt</b> <br>
<b>
invoke SetForegroundWindow,hWnd</b> <br>
<b>
invoke TrackPopupMenu,hPopupMenu,TPM_RIGHTALIGN,pt.x,pt.y,NULL,hWnd,NULL</b>
<br>
<b>
invoke PostMessage,hWnd,WM_NULL,0,0</b> <br>
<b> .elseif
lParam==WM_LBUTTONDBLCLK</b> <br>
<b>
invoke SendMessage,hWnd,WM_COMMAND,IDM_RESTORE,0</b> <br>
<b> .endif</b>
<br>
<b> .endif</b>
<p>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. <br>
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. <br>
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. <br>
TrackPopupMenu has the following syntax: <br>
<ul>
<b>TrackPopupMenu PROTO hMenu:DWORD, uFlags:DWORD, x:DWORD, y:DWORD,
nReserved:DWORD, hWnd:DWORD, prcRect:DWORD</b> <br>
<li> hMenu is the handle of the popup menu to be displayed</li>
<li> uFlags 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.</li>
<li> x and y specify the location of the menu in screen coordinates.</li>
<li> nReserved must be NULL</li>
<li> hWnd is the handle of the window that will receive the messages from the
menu.</li>
<li> prcRect 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.</li>
</ul>
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.
<p><b> invoke
Shell_NotifyIcon,NIM_DELETE,addr note</b> <br>
<b> mov eax,wParam</b>
<br>
<b> .if ax==IDM_RESTORE</b>
<br>
<b>
invoke ShowWindow,hWnd,SW_RESTORE</b> <br>
<b> .else</b>
<br>
<b>
invoke DestroyWindow,hWnd</b> <br>
<b> .endif</b>
<p>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. <strong> </strong>
<hr size="1">
<div align="center"> This article come from Iczelion's asm page, Welcom to <a href="http://asm.yeah.net">http://asm.yeah.net</a></div>
</body>
</html>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -