直播中
首先,要使程序的主窗口不可見(jiàn),并且不在任務(wù)欄上出現(xiàn)任務(wù)按鈕,要做到這兩點(diǎn),需分別設(shè)置主邊框窗口的風(fēng)格和擴(kuò)展風(fēng)格:
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style =WS_POPUP;//使主窗口不可見(jiàn)
cs.dwExStyle |=WS_EX_TOOLWINDOW;//不顯示任務(wù)按鈕return CFrameWnd::PreCreateWindow(cs);
}
其次,利用系統(tǒng)函數(shù)Shell_NotifyIcon將一個(gè)圖標(biāo)顯示在任務(wù)欄的通告區(qū)中。該函數(shù)的原型為:WINSHELLAPI BOOL WINAPI Shell_NotifyIcon(
DWORD dwMessage,
PNOTIFYICONDATA pnid
);
下例中被顯示的是主邊框窗口的圖標(biāo),實(shí)際上可以顯示任何圖標(biāo):
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
… NOTIFYICONDATA tnd;tnd.cbSize=sizeof(NOTIFYICONDATA);
tnd.hWnd=this->m_hWnd;
tnd.uID=IDR_MAINFRAME;
tnd.uFlags=NIF_MESSAGE|NIF_ICON|NIF_TIP;
tnd.uCallbackMessage=WM_LIBEN;
tnd.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));
strcpy(tnd.szTip,"提示信息");
Shell_NotifyIcon(NIM_ADD,&tnd);
…}
在調(diào)用該函數(shù)之前,需要確定其參數(shù)的取值,其中之一為一個(gè)具有NOTIFYICONDATA類(lèi)型的結(jié)構(gòu)。其原型為:typedef struct _NOTIFYICONDATA { // nid
DWORD cbSize;
HWND hWnd;
UINT uID;
UINT uFlags;
UINT uCallbackMessage;
HICON hIcon;
charszTip[64]; }
NOTIFYICONDATA, *PNOTIFYICONDATA;
在該結(jié)構(gòu)的成員中,cbSize為該結(jié)構(gòu)所占的字節(jié)數(shù),hWnd為接受該圖標(biāo)所發(fā)出的消息的窗口的句柄,uID為被顯示圖標(biāo)的ID,uFlags指明其余的幾個(gè)成員(hIcon、uCallBackMessage和szTip)的值是否有效,uCallbackMessage為一個(gè)自定義的消息,當(dāng)用戶(hù)在該圖標(biāo)上作用一些鼠標(biāo)動(dòng)作時(shí),將向hWnd成員中指定的窗口發(fā)出該消息,可以定義該消息為WM_USER+100。hIcon為被顯示圖標(biāo)的句柄,szTip為一字符數(shù)組,當(dāng)鼠標(biāo)停留在該圖標(biāo)上時(shí),將其內(nèi)容顯示在浮動(dòng)的提示信息框中。Shell_NotifyIcon函數(shù)的另一個(gè)參數(shù)是一個(gè)預(yù)定義的消息,可以取如下值之一:NIM_ADD、NIM_DELETE或NIM_MODIFY,分別表示添加圖標(biāo)、刪除圖標(biāo)或修改圖標(biāo)。最后,要與用戶(hù)進(jìn)行交互,也就是當(dāng)用戶(hù)在該圖標(biāo)上單擊或雙擊鼠標(biāo)左鍵或右鍵時(shí)要執(zhí)行相應(yīng)的操作,至少也要響應(yīng)用戶(hù)終止該程序的意愿。上面已經(jīng)提到,當(dāng)用戶(hù)在圖標(biāo)上進(jìn)行鼠標(biāo)動(dòng)作時(shí),將向
hWnd成員中指定的窗口發(fā)出自定義的消息,該消息由uCallbackMessage成員指定(在上例中為WM_LIBEN,取值為WM_USER+100)。因此,我們的任務(wù)就是在hWnd窗口中響應(yīng)該自定義消息:void CMainFrame::OnLiben(WPARAM wParam,LPARAM lParam)
{
UINT uID;//發(fā)出該消息的圖標(biāo)的ID
UINT uMouseMsg;//鼠標(biāo)動(dòng)作 POINT pt;uID=(UINT) wParam;
uMouseMsg=(UINT) lParam;
if(uMouseMsg==WM_RBUTTONDOWN)//如果是單擊右鍵
{
switch(uID){
case IDR_MAINFRAME://如果是我們的圖標(biāo)
GetCursorPos(&pt);//取得鼠標(biāo)位置
…//執(zhí)行相應(yīng)操作
break;
… default:…
}
}
return;}
需要注意的是,首先要在該窗口類(lèi)的頭文件中給出該消息映射函數(shù)的原型說(shuō)明:afx_msg void OnLiben(WPARAM wParam,LPARAM lParam);
并且要在CPP文件中的消息映射中加入相應(yīng)的條目,注意一定要加在//{{AFX_MSG_MAP(CMainFrame)和//}}AFX_MSG_MAP之外:BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_COMMAND(ID_APP_EXIT, OnAppExit)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_LIBEN,OnLiben)
END_MESSAGE_MAP()
當(dāng)程序結(jié)束時(shí),需要?jiǎng)h去通告區(qū)中的圖標(biāo),這時(shí)同樣應(yīng)該調(diào)用Shell_NotifyIcon函數(shù),只不過(guò)第一個(gè)參數(shù)是表示刪除圖標(biāo)的NIM_DELETE了:void CMainFrame::OnAppExit()
{
// TODO: Add your command handler code here
NOTIFYICONDATA tnid;
tnid.cbSize=sizeof(NOTIFYICONDATA);
tnid.hWnd=this->m_hWnd;
tnid.uID=IDR_MAINFRAME;//保證刪除的是我們的圖標(biāo)
Shell_NotifyIcon(NIM_DELETE,&tnid);AfxPostQuitMessage(0);
}
通過(guò)類(lèi)似的步驟,讀者可以響應(yīng)其他的消息,完成更加高級(jí)的交互功能,這里不再贅述。上文所述是筆者經(jīng)驗(yàn)所得,肯定有不到之處,歡迎指正。