《MFC最小化到系統(tǒng)托盤》由會員分享,可在線閱讀,更多相關(guān)《MFC最小化到系統(tǒng)托盤(7頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、轉(zhuǎn)MFC最小化到系統(tǒng)托盤
一、托盤簡介
所謂的“托盤”,在Windows系統(tǒng)界面中,指的就是下面任務(wù)條右側(cè),有系統(tǒng)時間等等的標(biāo)志的那一部分。在程序最小化或掛起時,但有不希望占據(jù)任務(wù)欄的時候,就可以把程序放到托盤區(qū)。其實,托盤區(qū)的編程很簡單,下面簡要闡述一下子嘍A_A
二、托盤編程相關(guān)函數(shù)
其實呢,把程序放到托盤上的本質(zhì)就是先在托盤區(qū)繪制一個圖標(biāo),然后把程序隱藏不
見,再對托盤的圖標(biāo)進(jìn)行消息處理,就可以了。
繪制圖標(biāo)以及確定圖標(biāo)所傳送消息的函數(shù)只有一個,那就是——————
WINSHELLAPIBOOLWINAPI
DWORDdwMessage,
PNOTIFYICONDATA
2、pnid);
Shell_NotifyIcon(
這個函數(shù)呢,負(fù)責(zé)向系統(tǒng)傳遞消息,
呢,是個布爾類型的。就是說,如果返回
以添加、修改或刪除托盤區(qū)的圖標(biāo)。
0,那就是成仁啦,非0才成功。
她的返回值
參數(shù)dwMessage是表示這個函數(shù)的應(yīng)用功能是哪一方面,是添加、刪除,還是修改圖標(biāo)。如果是添加,則它的值為NIM_ADD;刪除則是NIM_DELETE;而修改是NIM_MODIFY。參數(shù)pnid就是具體的和程序在托盤區(qū)的圖標(biāo)有關(guān)系的結(jié)構(gòu)了。它的定義如下:
typedefstruct_NOTIFYICONDATA{
DWORDcbSize;
UINT
uID;
UINT
3、uFlags;
UINT
uCallbackMessage;
HICON
hIcon;
HWNDhWnd;
charszTip[64];
}NOTIFYICONDATA,*PNOTIFYICONDATA;
面就對該結(jié)構(gòu)各個參數(shù)進(jìn)行刨析:
cbSize:結(jié)構(gòu)的長度,用“位”來做單位。一般在程序中,我們用(DWORD)sizeof(NOTIFYICONDATA)給它賦值。
HWnd
一個句柄,如果對托盤中的圖標(biāo)進(jìn)行操作,相應(yīng)的消息就傳給這個句柄
4、
所代表的窗口。自然了,大多數(shù)情況下是this->m_hWnd嘍。
uID:在工程中定義的圖標(biāo)ID
uFlags:這個成員標(biāo)志著其他哪些成員的數(shù)據(jù)是有效的,分別為NIF_ICON,NIF_MESSAGE,NIF_TIP,分別代表著數(shù)據(jù)有效的成員是hlcon,uCallbackMessage,szTip。當(dāng)然,三個值可以用"聯(lián)系到一起。下面分別對涉及
到的成員進(jìn)行闡述
hlcon:要增加,刪除或修改的圖標(biāo)句柄。如果只知道個ulD,一般可能會用函數(shù)Loadlcon來得到句
5、柄。例如
Loadlcon(AfxGetlnstanceHandle(),MAKElNTRESOURCE(lDR_MAlNFRAME))。
uCallbackMessage:這在對托盤區(qū)的操作中,是比較重要的數(shù)據(jù)成員。這是個消息標(biāo)志,當(dāng)用鼠標(biāo)對托盤區(qū)相應(yīng)圖標(biāo)進(jìn)行操作的時候,就會傳遞消息給Hwnd所代表的窗
口。所以說,在uFlags中,一般都得標(biāo)志它有效。這里一般都是自定義的消息。
szTip:鼠標(biāo)移動到托盤圖標(biāo)上時的提示文字。
在MFC中怎樣將窗口最小化到托盤
一)原理
1. 最小化的原理:首先要將窗口隱藏,然后在右下角繪制圖標(biāo)。
2. 恢復(fù)的原理:將窗口顯示,再將托盤中的圖
6、片刪除。
3. 消息聲明與消息響應(yīng)函數(shù)的機制原理。
(二)程序描述
1. 先定義自己消息聲明與消息響應(yīng)函數(shù)。消息響應(yīng)函數(shù)處理當(dāng)用戶左鍵雙擊與右鍵點擊托盤
2. 定義處理窗口最小化時候調(diào)用的函數(shù)。調(diào)用的函數(shù)中完成托盤樣式、托盤上顯示的文字、對應(yīng)的消息等等。具體查看NOTlFYlCONDATA結(jié)構(gòu)與代碼。
3. 當(dāng)用戶最小化窗口時候,OnSysCommart捕捉到對應(yīng)消息,并調(diào)用創(chuàng)建托盤函數(shù)
三)程序?qū)崿F(xiàn)
1、自定義消息WM_SHOWT:AS#KdefineWM_SHOWTASK(WM_USER+1)
2、在MFC勺::0nSysCommand(UINTnID,LPARAMIPar
7、am函數(shù)體中增加一個命令響應(yīng)
if(nID==SC_MINIMIZE)ToTray();//最小化到托盤勺函數(shù)
3、在消息映射中添加ON_MESSAGE(WM_SHOWTASK,OnSho,其中k)WM_SHOWTAS消息名,
OnShowTask是自己定義的消息響應(yīng)函數(shù),后面有說明。(四)具體函數(shù)內(nèi)容1、最小化到托盤函數(shù)
voidCClockDlg::OnCreateNotifyIcon()
{
nid.cbSize=(DWORD)sizeof(NOTIFYICONDATA);
nid.hWnd=this->m_hWnd;
nid.uID=IDR_MAINFRAME;
ni
8、d.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP;nid.uCallbackMessage=WM_SHOWTASK;//自定義的消息名稱
nid.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));strcpy(nid.szTip,"程序名稱");//信息提示條Shell_NotifyIcon(NIM_ADD,&nid);//在托盤區(qū)添加圖標(biāo)ShowWindow(SW_HIDE);//隱藏主窗口
}
2、恢復(fù)界面函數(shù)在頭文件中定義消息響應(yīng)函數(shù)
afx_msgLRESULTO
9、nShowTask(WPARAMwParam,LPARAMlParam);//wParam接收的是圖標(biāo)的ID,而IParam接收的是鼠標(biāo)的行為LRESULT
LRESULTCClockDlg::OnShowTask(WPARAMwParam,LPARAMlParam)
{
if(wParam!=nid.uID)
{
MessageBox("heIoo");
return1;
}
switch(IParam)
{
caseWM_RBUTTONUP右鍵起來時彈出快捷菜單,這里只有一個“關(guān)閉”
{
LPPOINTIpoint=newtagPOINT;
::GetCursor
10、Pos(Ipoint);//得到鼠標(biāo)位置
//聲明一個彈出式菜單
CMenumenu;
menu.CreatePopupMenu();
//增加菜單項“關(guān)閉”,點擊則發(fā)送消息WM_DESTF給主窗口(已/隱藏),將程序
結(jié)束。
menuAppendMenu(MF_STRING,WM_DESTRO關(guān)閉");//確定彈出式菜單的位置menu.TrackPopupMenu(TPM_LEFTALIGN,lpoint->x,lpoint->y,this);//資源回收HMENUhmenu=menu.Detach();
menu.DestroyMenu();
deletelpoint;
11、}break;
caseWM_LBUTTONDBLCL/K雙擊左鍵的處理
{
MoveWindow(GetSystemMetrics(SM_CXSCREEN)-dlgrect.Width()-20,0,dlgrect.Width(),dlgrect.Height(),true);
this->ShowWindow(SW_SHOWNORMAL);
DeleteTray();
}
break;
default:break;
}
return0;
}
3、刪除托盤圖標(biāo)函數(shù)
voidCClockDlg::DeleteTray()
{
NOTIFYICONDATAnid;
12、
nid.cbSize=(DWORD)sizeof(NOTIFYICONDATA);
nid.hWnd=this->m_hWnd;
nid.uID=IDR_MAINFRAME;
nid.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP;nid.uCallbackMessage=WM_SHOWTASK//;自定義的消息名稱nid.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));
strcpy(nid.szTip,"程序名稱");//信息提示條為“計劃任務(wù)提醒”Shell_No
13、tifyIcon(NIM_DELETE,&nid);//在托盤區(qū)刪除圖標(biāo)
}
我只想自己實現(xiàn)SC_CLOSE,
而不想覆蓋其他的SysCommand,
voidCMainFrame::OnSysCommand(UINTnID,LPARAMIParam)
{
if(nID==SC_CLOSE)
//自己的實現(xiàn)代碼
Restore
但我發(fā)現(xiàn)框架運行后,其他的SysCommand,如Maximize,Minimize,Move,
等都沒法實現(xiàn)了,難道每個SysCommand都要自己實現(xiàn)一遍嗎?
請問如何解決?
在else里加上
CFrameWnd::OnSysCommand
14、(nID,IParam);
也就是
if(nID==SC_CLOSE)
{
//自己的實現(xiàn)代碼
}
else
CFrameWnd::OnSysCommand(nID,lParam);
到底OnSysCommand可不可以在CFrameWnd中重載可以啊,我一直這么做:
?h文件的消息定義處添加:
afx_msgvoidOnSysCommand(UINTnID,LPARAMIParam);
?cpp文件的消息響應(yīng)處添加:
ON_WM_SYSCOMMAND()
.cpp文件添加處理函數(shù):
voidCYourFrameWnd::OnSysCommand(UINTnID,L
15、PARAMIParam)
{
CFrameWnd::OnSysCommand(nID,IParam);
}
窗口最大化、最小化及關(guān)閉的消息是什么?如何截獲?
VC與bolandC一樣
最大化、最小化將發(fā)送WM_SYSCOMMAND消息。要處理該消息,可以這么做:
1、在Form的頭文件中添加:
void__fastcallRestrictMinimizeMaximize(TMessage&Msg);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_SYSCOMMAND,TMessage,RestrictMinimizeMaximize)
END_
16、MESSAGE_MAP(TForm)
2、在Form的單元文件中添加:
void__fastcallTForm1::RestrictMinimizeMaximize(TMessage&Msg)
{
if(Msg.WParam==SC_MINIMIZE)
{
//catchesminimize...
}
elseif(Msg.WParam==SC_MAXIMIZE)
{
//catchesmaximize...
}
elseif(Msg.WParam==SC_CLOSE)
TForm::Dispatch(&Msg);
//or"elseTForm::Dispatch(
17、&Msg)"totrap
}
關(guān)閉窗口的消息為WM_CLOSE,C++Builder提供了OnClose事件。
voidCClockDlg::OnSysCommand(UINTnID,LPARAMlParam)
{
//TODO:在此添加消息處理程序代碼和/或調(diào)用默認(rèn)值
if(nID==SC_MINIMIZE)
CDialog::OnSysCommand(nID,lParam);
}
消息發(fā)送
SendMessage()
函數(shù)功能:該函數(shù)將指定的消息發(fā)送到一個或多個窗口。此函數(shù)為指定的窗口調(diào)用窗口程序,直到窗口程序處理完消息再返回。而函數(shù)PostMessage不同,將一個
18、消息寄送到一個線程的
消息隊列后立即返回。
函數(shù)原型:LRESULTSendMessage(HWNDhWnd,UINTMsg,WPARAMwParam,LPARAMIParam);
參數(shù):
hWnd:其窗口程序?qū)⒔邮障⒌拇翱诘木浔H绻藚?shù)為HWND_BROADCAST,
則消息將被發(fā)送到系統(tǒng)中所有頂層窗口,包括無效或不可見的非自身擁有的窗口、被覆蓋的窗口和彈出式窗口,但消息不被發(fā)送到子窗口。
Msg:指定被發(fā)送的消息。
wParam:指定附加的消息指定信息。
IParam:指定附加的消息指定信息。返回值:返回值指定消息處理的結(jié)果,依賴于所發(fā)送的消息。
備注:需要用HWND_BROADCAST通信的應(yīng)用程序應(yīng)當(dāng)使用函數(shù)RegisterWindowMessage來為應(yīng)用程序間的通信取得一個唯一的消息。
錯誤一:
errorC2440:“static_cast”:無法從“LRESULT(__thiscallCClockDlg::*)(UINT)”轉(zhuǎn)換為“LRESULT(__thiscallCWnd::*)(WPARAM,LPARAM)”碰到這個錯誤說明聲明的消息響應(yīng)函數(shù)格式不對。
正確的消息響應(yīng)函數(shù)為:
afx_msgLRESULTOnShowTask(WPARAMwParam,LPARAMlPar)a;m紅色的不變。
VC常見問題百問1-25