分享

Win32 API 实现系统托盘程序

 217小月月坑 2015-03-25

托盘程序就是运行在系统托盘区域的程序,显示为桌面右下角显示区域的一个小图标。通常托盘程序带有几种功能:托盘菜单,托盘图标,气泡提示,托盘提示。例如QQ收到消息后,会在系统右下角显示闪动QQ图标。

主程序Tray.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#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
1
2
3
#define IDI_TRAY    101 
#define ID_SHOW     40001 
#define ID_EXIT     40002

资源文件 resource.rc
 
1
2
3
#include "resource.h" 
   
IDI_TRAY ICON DISCARDABLE "ico.ico"

编译很简单,使用 Visual Studio建立一个空项目,建好以上3个文件,再找一个ico图标,保存为ico.ico,即可编译。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多