要想在任务栏注册一个图标,须要用到一个API,
BOOL Shell_NotifyIcon(
DWORD dwMessage, //指几个宏,如果是增加就是:NIM_ADD,删除图标就是:NIM_DELETE
PNOTIFYICONDATA lpdata //一个指向NOTIFYICONDATA结构的指针
);
在这里我们主要是关注结构typedef struct _NOTIFYICONDATA {
DWORD cbSize; //本结构的大小,就是sizeof(NOTIFYICONDATA);
HWND hWnd; //关联的窗口名柄.this->m_hWnd
UINT uID; //就是你指定操作的ICON ID,DEFAULT就是IDR_MAINFRAME
UINT uFlags; //NIF_ICON|NIF_MESSAGE|NIF_TIP
UINT uCallbackMessage; //这里是一个自定义消息的CALL BACK MESSAGE如;WM_MYMSG
HICON hIcon; //图标句柄.系统图标就是:AfxGetApp()->LoadIconA(IDR_MAINFRAME);
TCHAR szTip[64]; //显示的TIPS,
DWORD dwState;
DWORD dwStateMask;
TCHAR szInfo[256];
union {
UINT uTimeout;
UINT uVersion;
};
TCHAR szInfoTitle[64];
DWORD dwInfoFlags;
GUID guidItem;
} NOTIFYICONDATA, *PNOTIFYICONDATA;
根据这个结构要求,我们要定义一个自定义消息.可以在文件头中加入#define WM_MYMSG (WM_USER+1)
只要是定义了这个结构,就可以用Shell_NotifyIcon函数注册一个ICON了可以将以下代码加入到窗口的OnInitDialog()中.
NOTIFYICONDATA m_Notify;
m_Notify.cbSize=sizeof(NOTIFYICONDATA);
m_Notify.hWnd=this->m_hWnd;
m_Notify.hIcon=AfxGetApp()->LoadIconA(IDR_MAINFRAME);
m_Notify.uID=IDR_MAINFRAME;
m_Notify.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP;
m_Notify.uCallbackMessage=WM_MYMSG; //这就是自订义的消息.
strcpy_s(m_Notify.szTip,_T("LiJun Mail Sniffer"));
Shell_NotifyIcon(NIM_ADD,&m_Notify);
但是,现在还不能对自订消息进行处理,在类中加一个自定义消息处理函数声明:
afx_msg LRESULT OnDeng(WPARAM wParam,LPARAM lParam);
再加入映射:
BEGIN_MESSAGE_MAP()
....
ON_MESSAGE(WM_MYMSG,OnDeng)
...
END_MESSAGE_MAP()
函数实现:下面的示例是右健弹出一个MENU.
LRESULT 类名::OnDeng(WPARAM wParam, LPARAM lParam){
POINT pt;
GetCursorPos(&pt);
if(wParam==IDR_MAINFRAME){
if(lParam==WM_RBUTTONDOWN)
{
m_Menu.GetSubMenu(0)->TrackPopupMenuEx(0,pt.x,pt.y,this,NULL);
}else if(lParam==WM_LBUTTONDOWN)
{
ShowWindow(SW_SHOW);
UpdateWindow();
}
}
最后,我们要在程序退出后删除掉这个注册ICON:
可以在OnDestroy()中加入:
::Shell_NotifyIcon(NIM_DELETE,&m_Notify);
如果要拦截WM_CLOSE消息,不让关闭程序,其实很简单,对于单文档应用程序,
只要在On_Close()中重新写入代码即可.如下:
void 类名::OnClose(){
if(不想关闭)
{
ShowWindow(SW_HIDE); //HIDE WINDOW
return;
}
CWnd::OnClose();
}