;运行效果:
;win32汇编环境,窗口程序中创建托盘示例一
;托盘,就是电脑桌面右下角那个角落里的图标,这里展示基本的应用方法。
;直接抄进RadAsm可编译运行。重要部分加备注。
;下面为asm文件
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
include shell32.inc ;添加必需的头文件
includelib user32.lib
includelib kernel32.lib
includelib shell32.lib ;添加必需的库文件
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;Equ 等值定义
MAINDIALOG equ 1
ICO_MAIN equ 1000 ;图标
WM_SHELLNOTIFY equ WM_USER + 9 ;自定义私人消息,用来处理托盘图标方面的反应
IDI_TRAY equ 2
IDM_RESTORE equ 100
IDM_EXIT equ 101
.DATA
ClassName db "SimpleWinClass",0
AppName db "窗口程序的模版",0
szSTClassName db "static",0
szSTCaption db "点击最化小按钮则会缩为右下角的托盘",0
szFileIocn db "Main.ico",0 ;图标文件名,在当前文件夹下
szAppName db "我在这里",0 ;当鼠标在其上面时,显示的提示
szRestoreString db "恢复窗口",0
szExitString db "退出程序",0
.DATA?
hInstance HINSTANCE ?
CommandLine LPSTR ?
Snote NOTIFYICONDATA <> ;定义包含系统需要在通知区域中显示通知的信息的结构
hPopupMenu dd ?
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.CODE
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke GetCommandLine
mov CommandLine,eax
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
invoke ExitProcess, eax
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInstance
pop wc.hInstance
mov wc.hbrBackground,COLOR_WINDOW
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke LoadImage,hInstance,addr szFileIocn,IMAGE_ICON,0,0,LR_LOADFROMFILE
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc
invoke CreateWindowEx,NULL, ADDR ClassName,ADDR AppName,WS_OVERLAPPEDWINDOW,100,100,400,200, NULL,NULL,hInst, NULL
mov hwnd,eax
invoke ShowWindow, hwnd,CmdShow
invoke UpdateWindow, hwnd
.while TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.break .if (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.endw
mov eax,msg.wParam
ret
WinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL pt:POINT
.if uMsg == WM_CREATE
invoke CreateWindowEx,NULL,ADDR szSTClassName,ADDR szSTCaption, WS_CHILD + WS_VISIBLE,60, 60, 300, 20,hWnd,NULL,NULL,NULL
invoke CreatePopupMenu ;创建弹出式菜单
mov hPopupMenu,eax
invoke AppendMenu,hPopupMenu,MF_STRING,IDM_RESTORE,addr szRestoreString ;给创建的弹出式菜单增加项目
invoke AppendMenu,hPopupMenu,MF_STRING,IDM_EXIT,addr szExitString
.elseif uMsg == WM_SIZE ;WM_SIZE消息是当窗口大小或位置发生变化时捕获的消息
.if wParam == SIZE_MINIMIZED ;当窗口最小化时,则
mov Snote.cbSize,sizeof NOTIFYICONDATA ;NOTIFYICONDATA此结构的大小
push hWnd
pop Snote.hwnd ;把相关联的主窗口句柄给这个结构变量
mov Snote.uID,IDI_TRAY ;任务栏图标的应用程序定义标识符,就是其ID,这个用来区分你点了哪个不同的托盘图标
mov Snote.uFlags,NIF_ICON+NIF_MESSAGE+NIF_TIP ;指出在这个NOTIFYICONDATA结构中,哪些成员有效。这里指uCallbackMessage成员,hIcon成员,szTip成员有效
mov Snote.uCallbackMessage,WM_SHELLNOTIFY ;告诉NOTIFYICONDATA结构,当有消息在系统图标时,去找 WM_SHELLNOTIFY 这个私人消息处理
invoke LoadImage,hInstance,addr szFileIocn,IMAGE_ICON,0,0,LR_LOADFROMFILE ;加载图标
mov Snote.hIcon,eax ;把图标给这个NOTIFYICONDATA结构
invoke lstrcpy,addr Snote.szTip,addr szAppName ;当鼠标停留在托盘图标上面时,显示的字符串
invoke ShowWindow,hWnd,SW_HIDE ;把主窗口隐藏
invoke Shell_NotifyIcon,NIM_ADD,addr Snote ;调用Shell_NotifyIcon函数,把前面塞满内容的NOTIFYICONDATA结构当作参数给它.并告诉电脑,将图标添加消息发送到右下角的任务栏的状态区域
.endif
.elseif uMsg == WM_SHELLNOTIFY ;处理自定义消息
.if wParam == IDI_TRAY ;如果是这个程序的托盘图标,则
.if lParam == WM_RBUTTONDOWN ;如果鼠标单击右键,则
invoke GetCursorPos,addr pt ;得到当前鼠标的坐标并将X值及Y值给坐标结构 pt
invoke SetForegroundWindow,hWnd ;将创建指定窗口的线程引入前台并激活窗口
invoke TrackPopupMenu,hPopupMenu,TPM_RIGHTALIGN,pt.x,pt.y,NULL,hWnd,NULL ;在鼠标所点的位置显示所创建的菜单,并跟踪菜单上项的选择
invoke PostMessage,hWnd,WM_NULL,0,0 ;发送空消息给主窗口
.elseif lParam == WM_LBUTTONDBLCLK ;如果鼠标左键双击时,则
invoke SendMessage,hWnd,WM_COMMAND,IDM_RESTORE,0 ;发送WM_COMMAND消息,即后面的命令消息给主窗口,其wParam值是IDM_RESTORE,其lParam值是0
.endif
.endif
.elseif uMsg == WM_COMMAND
.if lParam == 0 ;选择菜单时
invoke Shell_NotifyIcon,NIM_DELETE,addr Snote ;删除图标
mov eax,wParam
.if ax == IDM_RESTORE ;如果是恢复主窗口,则恢复
invoke ShowWindow,hWnd,SW_RESTORE ;恢复窗口
invoke SetForegroundWindow ,hWnd ;激活并让窗口显示在所在窗口前面
.else
invoke DestroyWindow,hWnd
.endif
.endif
.elseif uMsg == WM_DESTROY
invoke DestroyMenu,hPopupMenu ;退出时清除创建的菜单
invoke PostQuitMessage,NULL
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
WndProc endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start