;运行效果
;win32汇编环境,对话框程序中创建托盘示例二
;像QQ来新消息时一样,让托盘图标交替显示,需要加个定时器,准备2个不同的图标,然后在需要的时机,启动定时器,让图标交替显示。
;直接抄进RadAsm可编译运行。重要部分加备注。
;下面为asm文件
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
include windows.inc
include user32.inc
include kernel32.inc
include shell32.inc ;添加必需的头文件
includelib user32.lib
includelib kernel32.lib
includelib shell32.lib ;添加必需的库文件
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 自定义函数声明
DlgProc proto :DWORD,:DWORD,:DWORD,:DWORD ;对话框窗口函数
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;Equ 等值定义
MAINDIALOG equ 1
ICO_MAIN01 equ 1001 ;图标
ICO_MAIN02 equ 1002
WM_SHELLNOTIFY equ WM_USER + 9 ;自定义私人消息,用来处理托盘图标方面的反应
IDI_TRAY equ 2
IDM_RESTORE equ 100
IDM_EXIT equ 101
IDB equ 10
ID_TIMER1 equ 201
; 数据段
.data
szAppName db "我在这里",0 ;当鼠标在其上面时,显示的提示
szRestoreString db "恢复窗口",0
szExitString db "退出程序",0
.data?
hInstance HINSTANCE ?
Snote NOTIFYICONDATA <> ;定义包含系统需要在通知区域中显示通知的信息的结构
hPopupMenu dd ?
hIco01 dd ?
hIco02 dd ?
.const
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke DialogBoxParam, hInstance,MAINDIALOG,NULL, addr DlgProc, NULL
invoke ExitProcess,eax
DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL pt:POINT
.if uMsg == WM_INITDIALOG
invoke LoadIcon,hInstance,ICO_MAIN01
invoke SendMessage,hWnd,WM_SETICON,ICON_BIG,eax
invoke CreatePopupMenu ;创建弹出式菜单
mov hPopupMenu,eax
invoke AppendMenu,hPopupMenu,MF_STRING,IDM_RESTORE,addr szRestoreString ;给创建的弹出式菜单增加项目
invoke AppendMenu,hPopupMenu,MF_STRING,IDM_EXIT,addr szExitString
invoke LoadIcon,hInstance,ICO_MAIN01 ;加载图标
mov hIco01,eax
invoke LoadIcon,hInstance,ICO_MAIN02
mov hIco02,eax
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 这个私人消息处理
push hIco01
pop Snote.hIcon ;把图标给这个NOTIFYICONDATA结构
invoke lstrcpy,addr Snote.szTip,addr szAppName ;当鼠标停留在托盘图标上面时,显示的字符串
invoke Shell_NotifyIcon,NIM_ADD,addr Snote ;调用Shell_NotifyIcon函数,把前面塞满内容的NOTIFYICONDATA结构当作参数给它.并告诉电脑,将图标添加消息发送到右下角的任务栏的状态区域
.elseif uMsg == WM_SIZE ;WM_SIZE消息是当窗口大小或位置发生变化时捕获的消息
.if wParam == SIZE_MINIMIZED ;当窗口最小化时,则
invoke ShowWindow,hWnd,SW_HIDE ;把主窗口隐藏
.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
mov eax,wParam
.if ax == IDM_RESTORE ;如果是恢复主窗口,则恢复
invoke ShowWindow,hWnd,SW_RESTORE
invoke SetForegroundWindow ,hWnd ;激活并让窗口显示在所在窗口前面
.elseif ax == IDM_EXIT
invoke Shell_NotifyIcon,NIM_DELETE,addr Snote ;删除图标
invoke DestroyWindow,hWnd
.elseif ax == IDB ;这是偷懒写法,如果控件多,则需分清各自的wParam与lParam值,不清楚的可以看入门教程里面相关的解释
invoke SetTimer,hWnd,ID_TIMER1,1000,NULL ;设置定时器,1000即1秒
.endif
.elseif uMsg == WM_TIMER ;处理定时器消息
mov eax,wParam
.if eax == ID_TIMER1
mov ebx,Snote.hIcon
.if ebx == hIco01
push hIco02
pop Snote.hIcon
invoke Shell_NotifyIcon,NIM_MODIFY,addr Snote ;修改托盘图标
.else
push hIco01
pop Snote.hIcon
invoke Shell_NotifyIcon,NIM_MODIFY,addr Snote ;修改托盘图标
.endif
.endif
.elseif uMsg == WM_CLOSE
invoke KillTimer,hWnd,ID_TIMER1 ;离开时记得清除定时器
invoke Shell_NotifyIcon,NIM_DELETE,addr Snote ;删除托盘图标
invoke DestroyMenu,hPopupMenu ;退出时清除创建的菜单
invoke EndDialog, hWnd,NULL
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DlgProc endp
end start
;下面为rc文件内容
#include "resource.h" //提示缺少该文件,可以在资源里下载
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define MAINDIALOG 1
#define ICO_MAIN01 1001 //图标
#define ICO_MAIN02 1002
#define IDB 10
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN01 ICON "Main01.ico"
ICO_MAIN02 ICON "Main02.ico"
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//定义对话框
MAINDIALOG DIALOG 10, 10, 200, 90
STYLE DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK
CAPTION "对话框程序模版"
FONT 12, "方正姚体"
BEGIN
CONTROL "点击最化小按钮则会缩为右下角的托盘", -1, "Static", WS_CHILD | WS_VISIBLE, 30, 20, 200, 10
PUSHBUTTON "让托盘图标交替显示", IDB, 50,50,100,12
END
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>