吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 9035|回复: 10
收起左侧

[其他原创] 一个简单的系统托盘图标的实现

 关闭 [复制链接]
iawen 发表于 2009-2-3 16:39
首发:http://www.iawen.com/read.php/203.htm
很久没有弄这个了,差点了,见朋友的博客有个Delphi版的,于是自己也想弄一个VC的出来!
要实现系统托盘图标,关键在于一个系统函数和一个数据结构。
函数就是Shell_NotifyIcon,原型如下:
BOOL Shell_NotifyIcon(DWORD dwMessage,NOTIFYICONDATA  lpdata);

而数据结构就是NOTIFYICONDATA了,呵呵,具体如下:[separator]
typedef struct _NOTIFYICONDATA {
    DWORD cbSize;
    HWND hWnd;
    UINT uID;
    UINT uFlags;
    UINT uCallbackMessage;
    HICON hIcon;
    TCHAR szTip[64];
    DWORD dwState;
    DWORD dwStateMask;
    TCHAR szInfo[256];
    union {
        UINT uTimeout;
        UINT uVersion;
    };
    TCHAR szInfoTitle[64];
    DWORD dwInfoFlags;
    GUID guidItem;
    HICON hBalloonIcon;
} NOTIFYICONDATA, *PNOTIFYICONDATA;
具体的解释,大家还是查查MSDN吧,这里不多说了!主要用到的几个是:
1、由于Shell_NotifyIcon是定义在shellapi.h里的,所以程序里需要包含上。
2、Shell_NotifyIcon的第一个参数取值:
  A)、NIM_ADD    //这个就是添加一个系统托盘图标了
  B)、NIM_DELETE    //这个是在退出时删除系统托盘图标了

3、对Shell_NotifyIcon的第2个参数,也即NOTIFYICONDATA结构的设置了:
  A)、先定义一个全局的变量:NOTIFYICONDATA nid
  B)、然后在适当的位置对其进行初始化:

对于对话框程序,一般在WM_INITDIALOG里消息初始,不过我这里是用CreateDialog来创建对话框的,所以在主程序WinMain里初始化:
  nid.cbSize=sizeof(NOTIFYICONDATA);  //初始化结构的大小
  nid.hWnd=g_hWnd;      //指定接收托盘消息的句柄
  nid.uID=IDI_TRAY;      //指定托盘图标的ID,呵呵
  nid.uFlags=NIF_ICON | NIF_MESSAGE | NIF_TIP;      //设定结构里有效的位置
      //NIF_ICON:  指定hIcon是有效的,(这里设定自定义系统托盘图标必须的)
      //NIF_MESSAGE:  指定uCallbackMessage是有效的,用于程序接收来自托盘图标的消息,需要自定义一个消息
      //NIF_TIP:  指定szTip是有效的,功能是当鼠标移动到图标上时,显示提示信息
  nid.uCallbackMessage=WM_IAWENTRAY;        //自定义的消息,
      //#define WM_IAWENTRAY  WM_USER+5
  nid.hIcon=LoadIcon(g_hInst,MAKEINTRESOURCE(IDI_TRAY));    //设置图标的句柄
  strcpy(nid.szTip,"测试系统托盘图标,呵呵\r\n点击打开主界面");  //设置提示信息
完成了上面的设置,现在就是开始调用了!
这里示例,是设定系统最小化按钮为隐藏到系统托盘,退出时则删除系统托盘!
如:
    case WM_DESTROY:
      Shell_NotifyIcon(NIM_DELETE,&nid);
      return TRUE;
    case WM_SYSCOMMAND:
      switch(wParam)
      {
        case SC_CLOSE:
          DestroyWindow(hDlg);
          PostQuitMessage(0);
          return TRUE;
        case SC_MINIMIZE:
          ShowWindow(g_hWnd,SW_HIDE);
          Shell_NotifyIcon(NIM_ADD,&nid);
          return TRUE;
      }
这里只所以没有在SC_CLOSE消息里直接删除托盘图标,而是因为在WM_DESTROY里处理会更好!
如果是在SC_CLOSE里直接处理,则会出现程序退出时,图标还在,只有当鼠标移过图标时则会完全不见!
大家可以测试一下,^&^……

而程序要接收来自系统托盘的消息,则是通过我们上面的定义的消息:
    case WM_IAWENTRAY:
      if(wParam==IDI_TRAY){
        if(lParam==WM_LBUTTONDOWN){
          ShowWindow(hDlg,SW_SHOWNORMAL);
          return TRUE;
        }  
      }
      return FALSE;
其中消息的wParam参数为指定的图标ID,lParam参数为事件类型,示例里只接收了WM_LBUTTONDOWN事件,即鼠标左键点击事件!

完整的的代码示例如下:
#include<windows.h>
#include<shellapi.h>
#include"resource.h"

#define WM_IAWENTRAY  WM_USER+5

HINSTANCE g_hInst;
HWND g_hWnd;
NOTIFYICONDATA nid;
INT_PTR CALLBACK MainDlgProc(HWND,UINT,WPARAM,LPARAM);

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR lpCmdLine,int nShowCmd)
{
  g_hInst=hInstance;
  g_hWnd=CreateDialog(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),NULL,MainDlgProc);
  ShowWindow(g_hWnd,nShowCmd);
  
  nid.cbSize=sizeof(NOTIFYICONDATA);
  nid.hWnd=g_hWnd;
  nid.uID=IDI_TRAY;
  nid.uFlags=NIF_ICON | NIF_MESSAGE | NIF_TIP;    
  nid.uCallbackMessage=WM_IAWENTRAY;  
  nid.hIcon=LoadIcon(g_hInst,MAKEINTRESOURCE(IDI_TRAY));
  strcpy(nid.szTip,"测试系统托盘图标,呵呵\r\n点击打开主界面");  //

  MSG uMsg;
  while(GetMessage(&uMsg,NULL,0,0)){
    TranslateMessage(&uMsg);
    DispatchMessage(&uMsg);
  }

  return 0;
}

INT_PTR CALLBACK MainDlgProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
  switch(uMsg){
    case WM_INITDIALOG:
      {
      HICON hIcon=LoadIcon(g_hInst,MAKEINTRESOURCE(IDI_TRAY));
      SendMessage(hDlg,WM_SETICON,ICON_BIG,(LPARAM)hIcon);
      SendMessage(hDlg,WM_SETICON,ICON_SMALL,(LPARAM)hIcon);
      SetDlgItemText(hDlg,IDC_INFO,TEXT("Write By Iawen --2009.02.03"));
      return TRUE;
      }
    case WM_IAWENTRAY:
      if(wParam==IDI_TRAY){
        if(lParam==WM_LBUTTONDOWN){
          ShowWindow(hDlg,SW_SHOWNORMAL);
          return TRUE;
        }  
      }
      return FALSE;
    case WM_DESTROY:
      Shell_NotifyIcon(NIM_DELETE,&nid);
      return TRUE;
    case WM_SYSCOMMAND:
      switch(wParam)
      {
        case SC_CLOSE:
          DestroyWindow(hDlg);
          PostQuitMessage(0);
          return TRUE;
        case SC_MINIMIZE:
          ShowWindow(g_hWnd,SW_HIDE);
          Shell_NotifyIcon(NIM_ADD,&nid);
          return TRUE;
      }
  }
  return FALSE;
}
附件为完整的程序示例工程:
TrayIcon.rar (38.77 KB, 下载次数: 51)

免费评分

参与人数 1威望 +1 收起 理由
zapline + 1 精品文章

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

ximo 发表于 2009-2-3 16:53
终于有1个我看的懂的C++程序了,学习[s:350] [s:350]
zapline 发表于 2009-2-3 20:51
sj3421565 发表于 2009-2-4 17:23
fuma255 发表于 2009-2-5 15:42
多谢楼主分享 谢谢了
XuZhenG 发表于 2009-2-6 16:28

鼓励原创,多练多得

感谢LZ的分享...
诚城 发表于 2009-3-30 21:55
学习了,谢谢
netknight 发表于 2009-4-2 14:54
下载来看看
头像被屏蔽
无心 发表于 2009-4-2 17:33
有些语法都看不懂!
foreverhack 发表于 2010-12-2 21:35
正好学着,学习ing---
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-17 00:23

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表