托盘程序就是运行在系统托盘区域的程序,显示为桌面右下角显示区域的一个小图标。通常托盘程序带有几种功能:托盘菜单,托盘图标,气泡提示,托盘提示。例如QQ收到消息后,会在系统右下角显示闪动QQ图标。
主程序Tray.cpp
- #include <windows.h>
- #include "resource.h"
- #define WM_TRAY (WM_USER + 100)
- #define WM_TASKBAR_CREATED RegisterWindowMessage(TEXT("TaskbarCreated"))
- #define APP_NAME TEXT("托盘程序")
- #define APP_TIP TEXT("Win32 API 实现系统托盘程序")
- NOTIFYICONDATA nid; //托盘属性
- HMENU hMenu; //托盘菜单
- //实例化托盘
- void InitTray(HINSTANCE hInstance, HWND hWnd)
- {
- nid.cbSize = sizeof(NOTIFYICONDATA);
- nid.hWnd = hWnd;
- nid.uID = IDI_TRAY;
- nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO;
- nid.uCallbackMessage = WM_TRAY;
- nid.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TRAY));
- lstrcpy(nid.szTip, APP_NAME);
- hMenu = CreatePopupMenu();//生成托盘菜单
- //为托盘菜单添加两个选项
- AppendMenu(hMenu, MF_STRING, ID_SHOW, TEXT("提示"));
- AppendMenu(hMenu, MF_STRING, ID_EXIT, TEXT("退出"));
- Shell_NotifyIcon(NIM_ADD, &nid);
- }
- //演示托盘气泡提醒
- void ShowTrayMsg()
- {
- lstrcpy(nid.szInfoTitle, APP_NAME);
- lstrcpy(nid.szInfo, TEXT("收到一条消息!"));
- nid.uTimeout = 1000;
- Shell_NotifyIcon(NIM_MODIFY, &nid);
- }
- LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- switch (uMsg)
- {
- case WM_TRAY:
- switch(lParam)
- {
- case WM_RBUTTONDOWN:
- {
- //获取鼠标坐标
- POINT pt; GetCursorPos(&pt);
- //解决在菜单外单击左键菜单不消失的问题
- SetForegroundWindow(hWnd);
- //使菜单某项变灰
- //EnableMenuItem(hMenu, ID_SHOW, MF_GRAYED);
- //显示并获取选中的菜单
- int cmd = TrackPopupMenu(hMenu, TPM_RETURNCMD, pt.x, pt.y, NULL, hWnd,
- NULL);
- if(cmd == ID_SHOW)
- MessageBox(hWnd, APP_TIP, APP_NAME, MB_OK);
- if(cmd == ID_EXIT)
- PostMessage(hWnd, WM_DESTROY, NULL, NULL);
- }
- break;
- case WM_LBUTTONDOWN:
- MessageBox(hWnd, APP_TIP, APP_NAME, MB_OK);
- break;
- case WM_LBUTTONDBLCLK:
- break;
- }
- break;
- case WM_DESTROY:
- //窗口销毁时删除托盘
- Shell_NotifyIcon(NIM_DELETE, &nid);
- PostQuitMessage(0);
- break;
- case WM_TIMER:
- ShowTrayMsg();
- KillTimer(hWnd, wParam);
- break;
- }
- if (uMsg == WM_TASKBAR_CREATED)
- {
- //系统Explorer崩溃重启时,重新加载托盘
- Shell_NotifyIcon(NIM_ADD, &nid);
- }
- return DefWindowProc(hWnd, uMsg, wParam, lParam);
- }
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/,
- LPSTR /*lpCmdLine*/, int iCmdShow)
- {
- HWND hWnd;
- MSG msg;
- WNDCLASS wc = { 0 };
- wc.style = NULL;
- wc.hIcon = NULL;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hInstance;
- wc.lpfnWndProc = WndProc;
- wc.hbrBackground = NULL;
- wc.lpszMenuName = NULL;
- wc.lpszClassName = APP_NAME;
- wc.hCursor = NULL;
- if (!RegisterClass(&wc)) return 0;
- hWnd = CreateWindowEx(WS_EX_TOOLWINDOW, APP_NAME, APP_NAME, WS_POPUP, CW_USEDEFAULT,
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
- ShowWindow(hWnd, iCmdShow);
- UpdateWindow(hWnd);
- InitTray(hInstance, hWnd); //实例化托盘
- SetTimer(hWnd, 3, 1000, NULL); //定时发消息,演示气泡提示功能
- while (GetMessage(&msg, NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return msg.wParam;
- }
资源头文件 resource.h
- #define IDI_TRAY 101
- #define ID_SHOW 40001
- #define ID_EXIT 40002
资源文件 resource.rc
- #include "resource.h"
- IDI_TRAY ICON DISCARDABLE "ico.ico"
编译很简单,使用 Visual Studio建立一个空项目,建好以上3个文件,再找一个ico图标,保存为ico.ico,即可编译。
本文介绍如何使用 Win32 API 开发具备托盘菜单、图标、气泡提示等功能的系统托盘程序。文章详细展示了创建托盘程序的过程,包括初始化托盘、处理消息、显示托盘提示等步骤。

2383

被折叠的 条评论
为什么被折叠?



