⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lion-tutorial23.htm

📁 内有一些代码
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<html>

<head>
<link rel="stylesheet" href="../../asm.css">

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>Iczelion's win32 asm tutorial</title>
</head>

<body bgcolor="#FFFFFF" background="../../images/back01.jpg">
<p align="center">Tutorial 23: Tray Icon</p>
<hr size="1">
In this tutorial, we will learn how to put icons into system tray and how to create/use 
a popup menu. <br>
Download the example <a href="files/tut23.zip">here</a>. 
<h3> Theory:</h3>
System tray is the rectangular region in the taskbar where several icons reside. 
Normally, you'll see at least a digital clock in it. You can also put icons in 
the system tray too. Below are the steps you have to perform to put an icon into 
the system tray: 
<ol>
  <li> Fill a NOTIFYICONDATA structure which has the following members:</li>
  <ul>
    <li> cbSize&nbsp;&nbsp; The size of this structure.</li>
    <li> hwnd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Handle of the window that will receive 
      notification when a mouse event occurs over the tray icon.</li>
    <li> uID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A constant that is 
      used as the icon's identifier. You are the one who decides on this value. 
      In case you have more than one tray icons, you will be able to check from 
      what tray icon the mouse notification is from.</li>
    <li> uFlags&nbsp;&nbsp;&nbsp; Specify which members of this structure are 
      valid</li>
    <ul>
      <li> <b>NIF_ICON</b> The hIcon member is valid.</li>
      <li> <b>NIF_MESSAGE</b> The uCallbackMessage member is valid.</li>
      <li> <b>NIF_TIP</b> The szTip member is valid.</li>
    </ul>
    <li> uCallbackMessage&nbsp; The custom message that Windows will send to the 
      window specified by the hwnd member when mouse events occur over the tray 
      icon. You create this message yourself.</li>
    <li> hIcon&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The handle of the icon you want to 
      put into the system tray</li>
    <li> szTip&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A 64-byte array that contains 
      the string that will be used as the tooltip text when the mouse hovers over 
      the tray icon.</li>
  </ul>
  <li> Call Shell_NotifyIcon which is defined in shell32.inc. This function has 
    the following prototype:</li>
  <p><br>
    <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Shell_NotifyIcon 
    PROTO dwMessage:DWORD ,pnid:DWORD</b> 
  <p>&nbsp;&nbsp;&nbsp; dwMessage&nbsp; is the type of message to send to the 
    shell. <br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>NIM_ADD</b> 
    Adds an icon to the status area. <br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>NIM_DELETE</b> Deletes 
    an icon from the status area. <br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>NIM_MODIFY</b> Modifies 
    an icon in the status area. <br>
    &nbsp;&nbsp;&nbsp; pnid&nbsp; is the pointer to a NOTIFYICONDATA structure 
    filled with proper values <br>
    If you want to add an icon to the tray, use NIM_ADD message, if you want to 
    remove the icon, use NIM_DELETE.
</ol>
That's all there is to it. But most of the time, you're not content in just putting 
an icon there. You need to be able to respond to the mouse events over the tray 
icon. You can do this by processing the message you specified in uCallbackMessage 
member of NOTIFYICONDATA structure. This message has the following values in wParam 
and lParam (special thanks to s__d for the info): 
<ul>
  <li> wParam contains the ID of the icon. This is the same value you put into 
    uID member of NOTIFYICONDATA structure.</li>
  <li> lParam&nbsp; The low word contains the mouse message. For example, if the 
    user right-clicked at the icon, lParam will contain WM_RBUTTONDOWN.</li>
</ul>
Most tray icon, however, displays a popup menu when the user right-click on it. 
We can implement this feature by creating a popup menu and then call TrackPopupMenu 
to display it. The steps are described below: 
<ol>
  <li> Create a popup menu by calling CreatePopupMenu. This function creates an 
    empty menu. It returns the menu handle in eax if successful.</li>
  <li> Add menu items to it with AppendMenu, InsertMenu or InsertMenuItem.</li>
  <li> When you want to display the popup menu where the mouse cursor is, call 
    GetCursorPos to obtain the screen coordinate of the cursor and then call TrackPopupMenu 
    to display the menu. When the user selects a menu item from the popup menu, 
    Windows sends WM_COMMAND message to your window procedure just like normal 
    menu selection.</li>
</ol>
Note: Beware of two annoying behaviors when you use a popup menu with a tray icon: 
<ol>
  <li> When the popup menu is displayed, if you click anywhere outside the menu, 
    the popup menu will not disappear immediately as it should be. This behavior 
    occurs because the window that will receive the notifications from the popup 
    menu MUST be the foreground window. Just call SetForegroundWindow will correct 
    it.</li>
  <li> After calling SetForegroundWindow, you will find that the first time the 
    popup menu is displayed, it works ok but on the subsequent times, the popup 
    menu will show up and close immediately. This behavior is "intentional", to 
    quote from MSDN. The task switch to the program that is the owner of the tray 
    icon in the near future is necessary. You can force this task switch by posting 
    any message to the window of the program. Just use PostMessage, not SendMessage!</li>
</ol>
<h3> Example:</h3>
<b>.386</b> <br>
<b>.model flat,stdcall</b> <br>
<b>option casemap:none</b> <br>
<b>include \masm32\include\windows.inc</b> <br>
<b>include \masm32\include\user32.inc</b> <br>
<b>include \masm32\include\kernel32.inc</b> <br>
<b>include \masm32\include\shell32.inc</b> <br>
<b>includelib \masm32\lib\user32.lib</b> <br>
<b>includelib \masm32\lib\kernel32.lib</b> <br>
<b>includelib \masm32\lib\shell32.lib</b> 
<p><b>WM_SHELLNOTIFY equ WM_USER+5</b> <br>
  <b>IDI_TRAY equ 0</b> <br>
  <b>IDM_RESTORE equ 1000</b> <br>
  <b>IDM_EXIT equ 1010</b> <br>
  <b>WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD</b> 
<p><b>.data</b> <br>
  <b>ClassName&nbsp; db "TrayIconWinClass",0</b> <br>
  <b>AppName&nbsp;&nbsp;&nbsp; db "TrayIcon Demo",0</b> <br>
  <b>RestoreString db "&amp;Restore",0</b> <br>
  <b>ExitString&nbsp;&nbsp; db "E&amp;xit Program",0</b> 
<p><b>.data?</b> <br>
  <b>hInstance dd ?</b> <br>
  <b>note NOTIFYICONDATA &lt;></b> <br>
  <b>hPopupMenu dd ?</b> 
<p><b>.code</b> <br>
  <b>start:</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke GetModuleHandle, NULL</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp; hInstance,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke WinMain, hInstance,NULL,NULL, SW_SHOWDEFAULT</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; invoke ExitProcess,eax</b> 
<p><b>WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; LOCAL wc:WNDCLASSEX</b> <br>
  <b>&nbsp;&nbsp;&nbsp; LOCAL msg:MSG</b> <br>
  <b>&nbsp;&nbsp;&nbsp; LOCAL hwnd:HWND</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.cbSize,SIZEOF WNDCLASSEX</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.style, CS_HREDRAW or CS_VREDRAW or 
  CS_DBLCLKS</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.lpfnWndProc, OFFSET WndProc</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.cbClsExtra,NULL</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.cbWndExtra,NULL</b> <br>
  <b>&nbsp;&nbsp;&nbsp; push&nbsp; hInst</b> <br>
  <b>&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp; wc.hInstance</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.hbrBackground,COLOR_APPWORKSPACE</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.lpszMenuName,NULL</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.lpszClassName,OFFSET ClassName</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; invoke LoadIcon,NULL,IDI_APPLICATION</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.hIcon,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.hIconSm,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke LoadCursor,NULL,IDC_ARROW</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; wc.hCursor,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke RegisterClassEx, addr wc</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR 
  AppName,\</b> <br>
  <b>WS_OVERLAPPED+WS_CAPTION+WS_SYSMENU+WS_MINIMIZEBOX+WS_MAXIMIZEBOX+WS_VISIBLE,CW_USEDEFAULT,\</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CW_USEDEFAULT,350,200,NULL,NULL,\</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hInst,NULL</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; hwnd,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp; .while TRUE</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke GetMessage, ADDR msg,NULL,0,0</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .BREAK .IF (!eax)</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke TranslateMessage, ADDR 
  msg</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke DispatchMessage, ADDR msg</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; .endw</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov eax,msg.wParam</b> <br>
  <b>&nbsp;&nbsp;&nbsp; ret</b> <br>
  <b>WinMain endp</b> 
<p><b>WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM</b> <br>
  <b>&nbsp;&nbsp;&nbsp; LOCAL pt:POINT</b> <br>
  <b>&nbsp;&nbsp;&nbsp; .if uMsg==WM_CREATE</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke CreatePopupMenu</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov hPopupMenu,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke AppendMenu,hPopupMenu,MF_STRING,IDM_RESTORE,addr 
  RestoreString</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke AppendMenu,hPopupMenu,MF_STRING,IDM_EXIT,addr 
  ExitString</b> <br>
  <b>&nbsp;&nbsp;&nbsp; .elseif uMsg==WM_DESTROY</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke DestroyMenu,hPopupMenu</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke PostQuitMessage,NULL</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; .elseif uMsg==WM_SIZE</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .if wParam==SIZE_MINIMIZED</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov note.cbSize,sizeof 
  NOTIFYICONDATA</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push hWnd</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop note.hwnd</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov note.uID,IDI_TRAY</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov note.uFlags,NIF_ICON+NIF_MESSAGE+NIF_TIP</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov note.uCallbackMessage,WM_SHELLNOTIFY</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke 
  LoadIcon,NULL,IDI_WINLOGO</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov note.hIcon,eax</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke 
  lstrcpy,addr note.szTip,addr AppName</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke 
  ShowWindow,hWnd,SW_HIDE</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -