系统托盘在我们使用的程序中很普遍,下面我们来看一个很不错的例子,使用Win32 API实现,对理解系统托盘有些帮助。

  1. #include <windows.h>
  2. #define IDR_PAUSE 12
  3. #define IDR_START 13
  4. /*
  5. #include <shellapi.h>
  6. #pragma   comment(lib,   "shell32.lib")
  7. */
  8. LPCTSTR szAppName = TEXT("服务程序");
  9. LPCTSTR szWndName = TEXT("服务程序");
  10. HMENU hmenu;//菜单句柄
  11. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  12. {
  13. NOTIFYICONDATA nid;
  14. UINT WM_TASKBARCREATED;
  15. POINT pt;//用于接收鼠标坐标
  16. int xx;//用于接收菜单选项返回值
  17. // 不要修改TaskbarCreated,这是系统任务栏自定义的消息
  18. WM_TASKBARCREATED = RegisterWindowMessage(TEXT("TaskbarCreated"));
  19. switch (message)
  20. {
  21. case WM_CREATE://窗口创建时候的消息.
  22. nid.cbSize = sizeof(nid);
  23. nid.hWnd = hwnd;
  24. nid.uID = 0;
  25. nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
  26. nid.uCallbackMessage = WM_USER;
  27. nid.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  28. lstrcpy(nid.szTip, szAppName);
  29. Shell_NotifyIcon(NIM_ADD, &nid);
  30. hmenu=CreatePopupMenu();//生成菜单
  31. AppendMenu(hmenu,MF_STRING,IDR_PAUSE,"暂停服务");//为菜单添加两个选项
  32. AppendMenu(hmenu,MF_STRING,IDR_START,"恢复服务");
  33. break;
  34. case WM_USER://连续使用该程序时候的消息.
  35. if (lParam == WM_LBUTTONDOWN)
  36. MessageBox(hwnd, TEXT("Win32 API 实现系统托盘程序,双击托盘可以退出!"), szAppName, MB_OK);
  37. if (lParam == WM_LBUTTONDBLCLK)//双击托盘的消息,退出.
  38. SendMessage(hwnd, WM_CLOSE, wParam, lParam);
  39. if (lParam == WM_RBUTTONDOWN)
  40. {
  41. GetCursorPos(&pt);//取鼠标坐标
  42. ::SetForegroundWindow(hwnd);//解决在菜单外单击左键菜单不消失的问题
  43. EnableMenuItem(hmenu,IDR_PAUSE,MF_GRAYED);//让菜单中的某一项变灰
  44. xx=TrackPopupMenu(hmenu,TPM_RETURNCMD,pt.x,pt.y,NULL,hwnd,NULL);//显示菜单并获取选项ID
  45. if(xx==IDR_PAUSE) MessageBox(hwnd, TEXT("111"), szAppName, MB_OK);
  46. if(xx==IDR_START) MessageBox(hwnd, TEXT("222"), szAppName, MB_OK);
  47. if(xx==0) PostMessage(hwnd,WM_LBUTTONDOWN,NULL,NULL);
  48. //MessageBox(hwnd, TEXT("右键"), szAppName, MB_OK);
  49. }
  50. break;
  51. case WM_DESTROY://窗口销毁时候的消息.
  52. Shell_NotifyIcon(NIM_DELETE, &nid);
  53. PostQuitMessage(0);
  54. break;
  55. default:
  56. /*
  57. * 防止当Explorer.exe 崩溃以后,程序在系统系统托盘中的图标就消失
  58. *
  59. * 原理:Explorer.exe 重新载入后会重建系统任务栏。当系统任务栏建立的时候会向系统内所有
  60. * 注册接收TaskbarCreated 消息的顶级窗口发送一条消息,我们只需要捕捉这个消息,并重建系
  61. * 统托盘的图标即可。
  62. */
  63. if (message == WM_TASKBARCREATED)
  64. SendMessage(hwnd, WM_CREATE, wParam, lParam);
  65. break;
  66. }
  67. return DefWindowProc(hwnd, message, wParam, lParam);
  68. }
  69. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  70. LPSTR szCmdLine, int iCmdShow)
  71. {
  72. HWND hwnd;
  73. MSG msg;
  74. WNDCLASS wndclass;
  75. HWND handle = FindWindow(NULL, szWndName);
  76. if (handle != NULL)
  77. {
  78. MessageBox(NULL, TEXT("Application is already running"), szAppName, MB_ICONERROR);
  79. return 0;
  80. }
  81. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  82. wndclass.lpfnWndProc = WndProc;
  83. wndclass.cbClsExtra = 0;
  84. wndclass.cbWndExtra = 0;
  85. wndclass.hInstance = hInstance;
  86. wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  87. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  88. wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  89. wndclass.lpszMenuName = NULL;
  90. wndclass.lpszClassName = szAppName;
  91. if (!RegisterClass(&wndclass))
  92. {
  93. MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);
  94. return 0;
  95. }
  96. // 此处使用WS_EX_TOOLWINDOW 属性来隐藏显示在任务栏上的窗口程序按钮
  97. hwnd = CreateWindowEx(WS_EX_TOOLWINDOW,
  98. szAppName, szWndName,
  99. WS_POPUP,
  100. CW_USEDEFAULT,
  101. CW_USEDEFAULT,
  102. CW_USEDEFAULT,
  103. CW_USEDEFAULT,
  104. NULL, NULL, hInstance, NULL);
  105. ShowWindow(hwnd, iCmdShow);
  106. UpdateWindow(hwnd);
  107. while (GetMessage(&msg, NULL, 0, 0))
  108. {
  109. TranslateMessage(&msg);
  110. DispatchMessage(&msg);
  111. }
  112. return msg.wParam;
  113. }

windows API 创建系统托盘图标的更多相关文章

  1. C/C++ Windows API——获取系统指定目录(转)

    原文地址:C/C++ Windows API——获取系统指定目录 经测试,在win10 VS2017中用wprintf()输出正常,SHGetSpecialFolderPath函数也正常运行 但是用M ...

  2. 使用Windows api 获得系统时间并生成文件夹

    // 使用window api 获得系统时间 // 生成 #include "stdafx.h" #include <Windows.h> #include <d ...

  3. windows API 统计系统字体

    最近工作中遇到一个需求,需要统计当前系统中包含的所有字体.在网上逛了一圈后发现了EnumFontFamiliesEx这个API好像就可以实现这个功能.这里将自己对这个API的理解做一个记录,算是对这块 ...

  4. windows API 创建临时文件

    创建完临时文件后,即可用C\C++标准函数写入.读取,也可以用API.MFC方法来操作. TCHAR szPathName[MAX_PATH]; TCHAR szFileName[MAX_PATH]; ...

  5. Windows API获取系统配置文件的配置参数

    在Windows平台下获取系统配置文件(如:System.ini)的配置参数. 系统配置文件System.ini的内容如下: [SYSTEM] ServiceIP = 10.128.11.99:600 ...

  6. 调用windows api 获取系统分辨率

    c++中: int cxScreen,cyScreen; cxScreen=GetSystemMetrics(SM_CXSCREEN); cyScreen=GetSystemMetrics(SM_CY ...

  7. windows API 开发飞机订票系统 图形化界面 (二)

    首先,用到的数据结构的定义.以及全局变量和函数的声明如下: // Flight.c : 定义应用程序的入口点. // #include "stdafx.h" //订单 typede ...

  8. windows API 开发飞机订票系统 图形化界面 (一)

    去年数据结构课程设计的作品,c语言实现,图形化界面使用windows API实现. 首发在我csdn博客:http://blog.csdn.net/u013805360/article/details ...

  9. Windows API 函数列表 附帮助手册

    所有Windows API函数列表,为了方便查询,也为了大家查找,所以整理一下贡献出来了. 帮助手册:700多个Windows API的函数手册 免费下载 API之网络函数 API之消息函数 API之 ...

随机推荐

  1. ecshop整合discuz教程完美教程

    所需软件: ecshop安装包:    ECShop_V2.7.3_UTF8_release1106.rarucenter安装包:   UCenter_1.6.0_SC_UTF8.zipdiscuz! ...

  2. 使用JQuery对页面进行绑值

    使用JQuery对页面进行绑值 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"&g ...

  3. Django框架(二十四)—— Django rest_framework-视图组件

    目录 视图组件 一.基本视图 二.自定义的封装视图 三.利用mixin类和generice类编写视图 1.使用 2.源码 四.利用generics 下的ListCreateAPIView,Retrie ...

  4. jmeter 不同线程组之间传递变量1

    一 采用全局变量在不同线程组之间传递变量的坑 ${__setProperty(newcompanyId,${companyId},)}; 不采用全局变量传递参数,请求报文格式如下: 正确的报文: {& ...

  5. JavaScript去除数组中重复的数字

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  6. Linux常用信号快捷键的使用

    ctrl-c 发送 SIGINT 信号给前台进程组中的所有进程.常用于终止正在运行的程序.ctrl-z 发送 SIGTSTP 信号给前台进程组中的所有进程,常用于挂起一个进程.ctrl-d 不是发送信 ...

  7. LNMP一键安装包+Thinkphp搭建基于pathinfo模式的路由

    LNMP一键安装包是一个用Linux Shell编写的可以为CentOS/RadHat/Fedora.Debian/Ubuntu/Raspbian/Deepin VPS或独立主机安装LNMP(Ngin ...

  8. 18-python基础-字符串(1)

    1.字符串的定义 字符串就是一串字符,是编程语言中表示文本的数据类型. 在python中可以使用一对双引号“”或者一对单引号‘’定义一个字符串. 可以使用索引获取一个字符串中指定位置的字符,索引计数从 ...

  9. 一、最新Kafka单节点部署+测试 完整

    每次学一个东西从基础的开始,循序渐进. 不急不躁,路还很长. 所有教程都是学习汪文君大神的kafka教程的. 一.部署 这里选的kafka版本是 0.10.2.1   下载连接 https://dow ...

  10. Spring学习笔记(5)——IoC再度学习

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...