欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
VC++6.0中實(shí)現將應用程式的圖標加入到視窗系統的系統托盤(pán)中
摘要
  本文對怎么將應用程式的圖標加入到視窗系統的系統托盤(pán)中做了較為周詳的介紹,
  然后給出了一個(gè)C++類(lèi)以方便的實(shí)現該功能,并在VC++6.0中給出了一個(gè)應用程式
  實(shí)例來(lái)體現其具體實(shí)現過(guò)程。同時(shí)該應用程式實(shí)例還講解了怎么在托盤(pán)中實(shí)現動(dòng)
  畫(huà)圖標及在程式中關(guān)閉計算機的技術(shù)。

  關(guān)鍵詞:系統托盤(pán) 動(dòng)畫(huà)圖標

  視窗系統98桌面的系統托盤(pán)位于任務(wù)欄的右側,即視窗系統98桌面的右下方。他常
  用來(lái)顯示一些系統的狀態(tài)。如:系統時(shí)間,音量控制及其他的一些圖標(依個(gè)
  人機器安裝的軟件而不定),如下圖為筆者的視窗系統98系統托盤(pán)。(圖略)

  常常能見(jiàn)到一些優(yōu)秀的軟件在運行后會(huì )將其應用程式圖標加入到系統托盤(pán)中,如
  金山詞霸。如果能將自己編寫(xiě)的應用程式的圖標也加入到系統托盤(pán)中,將會(huì )使你
  的程式顯得非常有專(zhuān)業(yè)水準。

  其實(shí)這并不困難,和系統托盤(pán)通信的函數只有一個(gè):

Shell_NotifyIcon (UINT message, NOTIFYICONDATA &m_nid);

  首先看一下該函數的兩個(gè)參數。
  第一個(gè)參數message能取以下值:

NIM_ADD     向托盤(pán)中加入一個(gè)圖標;
NIM_MODIFY   修改托盤(pán)中的圖標
NIM_DELETE   從托盤(pán)中刪除一個(gè)圖標

  第二個(gè)參數m_nid是NOTIFYICONDATA結構的一個(gè)引用。該結構的原型如下:
typedef struct _NOTIFYICONDATA
{
DWORD cbSize;// 結構的大小,必須在程式中給出
HWND hWnd;
//是你程式中將要接收托盤(pán)消息的窗口句柄
UINT uID;
// 應用程式中定義的托盤(pán)圖標ID,此參數用作標識
UINT uFlags;
//設置屬性,低三位有意義,0--7,如下:
//第一位//#define NIF_MESSAGE 0x1
// uCallbackMessage參數有效

//第二位//#define NIF_ICON  0x2 // hIcon參數有效
//第三位//#define NIF_TIP  0x4 // szTip參數有效
          
UINT uCallbackMessage;  
// 自定義的消息ID值,一定不要和以有的消息ID相重。  
HICON hIcon;
//顯示在系統托盤(pán)上的Icon的句柄,能為系統的 IDI_WINLOGO等
CHAR szTip[64]; // 用于圖標顯示的提示字符串
} NOTIFYICONDATA;

  為了接收到來(lái)自托盤(pán)的通知消息你能將uCallbackMessage設定為你所定義的消息
  ID值,同時(shí)設定NIF_MESSAGE標志。這樣當用戶(hù)在你的托盤(pán)圖標上移動(dòng)或按下鼠標
  時(shí),視窗系統將發(fā)出消息:該消息的 messageID是你在uCallbackMessage中定義的
  值;wParam是你定義的uID值;而lParam是鼠標事件(如WM_LBUTTONDOWN),這樣你
  的應用程式就能響應該事件了。
  因此,為了將自己的應用程式加入到系統托盤(pán)中,首先得建立一處理托盤(pán)通知消息
  的窗口對象,然后將窗口對象和你自己的托盤(pán)通知消息聯(lián)系起來(lái)并建立相應的托盤(pán)
  通知消息映射機制,以便你的窗口對象能處理相應的事件。

  能看到結構體NOTIFYICONDATA中,其成員變量hWnd,uID,uFlags均用于在窗口對
  象和你自己的托盤(pán)通知消息之間建立聯(lián)系,而成員變量uCallbackMessage則必須是
  對應于你的窗口對象的托盤(pán)通知消息ID值。

  于是要完成的工作有:

  (1)建立一處理托盤(pán)通知消息的窗口對象;
  (2)建立一結構體NOTIFYICONDATA變量,并給變量的相應域賦值以在托盤(pán)通知消
       息和窗口對象之間建立聯(lián)系;
  (3)建立相應的托盤(pán)通知消息映射機制;
  (4)調用Shell_NotifyIcon函數以在系統托盤(pán)中加入、修改或刪除圖標;
  (5)當然別忘了在你的窗口對象中編寫(xiě)相應的事件響應函數。

  因此,能編寫(xiě)一C++類(lèi)來(lái)實(shí)現以上功能以簡(jiǎn)化編程同時(shí)提高代碼的可重用性。以
  下為該類(lèi)代碼:

class CTrayIcon : public CCmdTarget {
protected:
  DECLARE_DYNAMIC(CTrayIcon)
  NOTIFYICONDATA m_nid;    
// Shell_NotifyIcon 函數中的結構參數

public:
  CTrayIcon(UINT uID);
  ~CTrayIcon();

  // 通過(guò)調用該成員函數來(lái)接收托盤(pán)通知消息
  void SetNotificationWnd(CWnd* pNotifyWnd,
  UINT uCbMsg);

  // SetIcon 函數用來(lái)在系統托盤(pán)中加入、改動(dòng)及刪除圖標。
  //要刪除圖標這樣調用:SetIcon(0)
  BOOL SetIcon(UINT uID);
  BOOL SetIcon(HICON hicon, LPCSTR lpTip);
  BOOL SetIcon(LPCTSTR lpResName, LPCSTR lpTip)
  {
     return SetIcon(lpResName ?
     AfxGetApp()->LoadIcon(lpResName):NULL,lpTip);
  }
  
  BOOL SetStandardIcon(LPCTSTR lpszIconName,LPCSTR lpTip)
  {
     return SetIcon(::LoadIcon(NULL,lpszIconName),lpTip);
  }

  virtual LRESULT OnTrayNotification(WPARAM uID, LPARAM lEvent);
};

CTrayIcon::CTrayIcon(UINT uID)
{
  //初始化NOTIFYICONDATA結構變量
  memset(&m_nid, 0 , sizeof(m_nid));
  m_nid.cbSize = sizeof(m_nid);
  m_nid.uID = uID;
  AfxLoadString(uID, m_nid.szTip, sizeof
  (m_nid.szTip));
}

CTrayIcon::~CTrayIcon()
{
  SetIcon(0); // 從系統托盤(pán)中刪除圖標
}

// 設定通知窗口,該窗口必須已被創(chuàng )建
void CTrayIcon::SetNotificationWnd(CWnd* pNotifyWnd, UINT uCbMsg)
{
    ASSERT(pNotifyWnd==NULL || ::IsWindow(pNotifyWnd->GetSafeHwnd()));

    m_nid.hWnd = pNotifyWnd->GetSafeHwnd();

ASSERT(uCbMsg==0 || uCbMsg>=WM_USER);
m_nid.uCallbackMessage = uCbMsg;
}

BOOL CTrayIcon::SetIcon(UINT uID)
{
  HICON hicon=NULL;
  if (uID) {
   AfxLoadString(uID, m_nid.szTip, sizeof(m_nid.szTip));
   hicon = AfxGetApp()->LoadIcon(uID);
  }
  return SetIcon(hicon, NULL);
}

//////////////////
//
BOOL CTrayIcon::SetIcon(HICON hicon, LPCSTR lpTip)
{
  UINT msg;
  m_nid.uFlags = 0;

  // 設定圖標
  if (hicon) {
   // 判斷是要在系統托盤(pán)中增加還是要刪除圖標
   msg = m_nid.hIcon ? NIM_MODIFY : NIM_ADD;
   m_nid.hIcon = hicon;
   m_nid.uFlags |= NIF_ICON;
  } else { // 刪除圖標
   if (m_nid.hIcon==NULL)
     return TRUE;   //已被刪除
   msg = NIM_DELETE;
  }
  if (lpTip)
   strncpy(m_nid.szTip, lpTip, sizeof(m_nid.szTip));
  if (m_nid.szTip[0])
   m_nid.uFlags |= NIF_TIP;

  if (m_nid.uCallbackMessage && m_nid.hWnd)
   m_nid.uFlags |= NIF_MESSAGE;

  BOOL bRet = Shell_NotifyIcon(msg, &m_nid);
  if (msg==NIM_DELETE || !bRet)
   m_nid.hIcon = NULL;
  return bRet;
}

// 缺省事件處理程式,該程式處理鼠標右擊及雙擊事件。
LRESULT CTrayIcon::OnTrayNotification(WPARAM wID,
LPARAM lEvent)
{
  if (wID!=m_nid.uID ||
   (lEvent!=WM_RBUTTONUP && lEvent!=WM_LBUTTONDBLCLK))
   return 0;

  // 使用和托盤(pán)圖標擁有同樣ID號的菜單作為右鍵彈出菜單
  // 并將菜單上的第一項作為缺省命令使用,
  // 缺省命令在WM_LBUTTONDBLCLK事件發(fā)生時(shí)被擊發(fā)
  //
  CMenu menu;
  if (!menu.LoadMenu(m_nid.uID))
   return 0;
  CMenu* pSubMenu = menu.GetSubMenu(0);
  if (!pSubMenu)
   return 0;

  if (lEvent==WM_RBUTTONUP) {

   //使菜單第一項為缺省項 (表現為粗體)
   ::SetMenuDefaultItem(pSubMenu->m_hMenu, 0, TRUE);

   // 在鼠標的當前位置彈出菜單。
   CPoint mouse;
   GetCursorPos(&mouse);
   ::SetForegroundWindow(m_nid.hWnd);
   ::TrackPopupMenu(pSubMenu->m_hMenu,
     0,
     mouse.x,
     mouse.y,
     0,
     m_nid.hWnd,
     NULL);

  } else // 雙擊事件: 執行菜單第一項
   ::SendMessage(m_nid.hWnd, WM_COMMAND, pSubMenu->
   GetMenuItemID(0), 0);

  return 1; // 表示事件已被處理
}

  以下以在VC++6.0中具體實(shí)現的程式為例。該程式將擁有以下功能:程式被執行
  后,首先顯示一對話(huà)框表示程式開(kāi)始執行,然后該對話(huà)框消失。接著(zhù)程式圖標
  被加入到系統托盤(pán)中,能看到,該圖標將是一動(dòng)畫(huà)圖標。當鼠標在該系統托
  盤(pán)上右擊時(shí),將彈出一菜單。如圖所示(略)。其第一項為缺省項命令,單擊
  將顯示應用程式。為簡(jiǎn)化編程,該應用程式只是顯示一應用程式主窗口。而單擊
  菜單第二項將關(guān)閉機器,單擊菜單第三項將結束本程式。當并且當用戶(hù)雙擊時(shí),
  CTrayIcon將執行菜單上的第一項:顯示服務(wù)程式,這將擊活(顯示)TrayDemo
  (正常情況下,他是隱藏的)。而要終止TrayDemo,你得選擇結束本程式。當你
  執行File Exit或關(guān)掉TrayDemo主窗口時(shí),TrayDemo并沒(méi)有真正的關(guān)掉,他只不過(guò)
  隱藏起來(lái)了而已。TrayDemo 重載了Cmainframe::OnClose函數以執行該項功能。
  首先在VC++6.0中生成用應用程式向導生成一單文件工程TrayDemo,然后在工程中
  加入以上的CTrayIcon類(lèi)。

  要使用CTrayIcon類(lèi),你首先得實(shí)例化一個(gè)CTrayIcon類(lèi)對象,TrayDemo在視圖中
  完成此項工作。以下是對應代碼:

class CTrayDemoView : public CView {
protected: CTrayIcon m_trayIcon;
          // my tray icon
           .
           .
           .
};

  當你實(shí)例化一個(gè)CTrayIcon類(lèi)對象之后,你必須分配給其一個(gè)ID號。該ID號是此圖
  標在其生命周期內使用的唯一一個(gè)ID號,即使在以后你改動(dòng)了實(shí)際顯示的圖標。此
  ID號是當鼠標事件發(fā)生時(shí)你獲得的ID。他能不必是圖標的資源ID;在TrayDemo
  中,其值是IDR_TRAYICON,由CTrayDemoView構造函數所初始化。
CTrayDemoView::CTrayDemoView() :
m_trayIcon(IDR_TRAYICON){
           .
           .
           .
}

要增加圖標,可調用SetIcon重載函數之一
m_trayIcon.SetIcon(IDI_MYICON); //參數為資源ID
m_trayIcon.SetIcon("myicon");  //參數為資源名
m_trayIcon.SetIcon(hicon); //參數為HICON句柄
m_trayIcon.SetStandardIcon(IDI_WINLOGO);
//加入系統圖標

  除了SetIcon(UINT uID)函數需要一個(gè)同樣擁有uID號的字符串資源作為提示字符串
  以外,所有這些函數都有一個(gè)可選的指向提示字符串的LPCSTR參數。例如,在
  TRAYTEST中有以下行:
// (In TrayDemoView.cpp)
m_trayIcon.SetIcon(IDI_RED);

  該語(yǔ)句在增加圖標的同時(shí)同樣設定了提示字符串,因為T(mén)rayDemo有一個(gè)同樣ID的字
  符串:如果你想改動(dòng)圖標,只需再次調用其中的一個(gè)SetIcon函數,只不過(guò)需要不
  同的ID或HICON。CTrayIcon類(lèi)知道響應NIM_MODIFY消息而不是NIM_ADD消息。同樣
  的函數甚至能去掉圖標:
m_trayIcon.SetIcon(0);//removeicon

  CtrayIcon類(lèi)會(huì )將其解釋為NIM_DELETE事件。這么多的代碼和標志只用一個(gè)簡(jiǎn)單的
  重載函數就予以完成,這是C++的偉大之處。
  如果要顯示動(dòng)畫(huà)圖標,只需設置一定時(shí)器,然后在定時(shí)器的響應事件中調用
  SetIcon成員函數就能了。如:

int CTrayDemoView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
m_timerID = this->SetTimer(99,200,NULL);

}

void CTrayDemoView::OnTimer(UINT nIDEvent)
{
uChangeIcon++;
if(uChangeIcon-IDI_RED>2)
  uChangeIcon=IDI_RED;
m_trayIcon.SetIcon(uChangeIcon);
CView::OnTimer(nIDEvent);
}

  在示例程式中,有3個(gè)圖標,其ID為IDI_RED,IDI_YELLO,IDI_GREEN,且其ID值是相
  連的,因而UINT型變量uChangeIcon用來(lái)依次輪換三個(gè)圖標。這樣程式執行以后,你
  將會(huì )看到紅、黃、綠三個(gè)交通指示燈依次閃爍。
  那么怎樣處理托盤(pán)通知呢?

  要處理托盤(pán)通知,需要在你設定圖標之前調用CTrayIcon::SetNotificationWnd函
  數,當然你必須已創(chuàng )建了窗口。最適當的地方是在OnCreate函數中,在TrayDemo
  中也是這樣做的。用ClassWizard在CtrayDemoView類(lèi)中加入WM_CREATE消息響應函
  數OnCreate(),并加入以下代碼:

// Private message used for tray notifications
#define WM_MY_TRAY_NOTIFICATION WM_USER+0
int CTrayDemoView::OnCreate(LPCREATESTRUCT lpCreateStruct)
            .
            .
            .
m_trayIcon.SetNotificationWnd(this,WM_MY_TRAY_NOTIFICATION);
m_trayIcon.SetIcon(IDI_RED);
return 0;
}

  然后進(jìn)行消息注冊(REGISTER),一旦注冊以后,你就能用正常的消息映射方式
  處理托盤(pán)通知。
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_MESSAGE(WM_MY_TRAY_NOTIFICATION,OnTrayNotification)
// (or ON_REGISTERED_MESSAGE)
END_MESSAGE_MAP()

當然不要忘了在TrayDemoView.h中加入以下語(yǔ)句:
afx_msg LRESULT OnTrayNotification(WPARAM wp, LPARAM lp);

  當你的處理程式得到在托盤(pán)圖標上的鼠標事件的控制以后,WPARAM參數是你在創(chuàng )建
  CTrayIcon類(lèi)時(shí)定義的ID;LPARAM是鼠標事件(如,WM_LBUTTONDOWN)。當捕捉到
  通知后你能做所有你想做的事情;記得最后要調用
  CTrayIcon::OnTrayNotification函數以完成一些缺省的處理。該虛函數完成前面
  所提到的一些缸省的UI行為。特別的,他處理WM_LBUTTONDBLCLK和WM-RBUTTONUP事
  件。CTrayIcon類(lèi)尋找和圖標擁有同樣ID的菜單(如,IDR_TRAYICON)。如果擁有
  該ID的菜單存在,CTrayIcon類(lèi)將在用戶(hù)右擊圖標的時(shí)候顯示此菜單;而當用戶(hù)雙
  擊時(shí),CTrayIcon將執行菜單上的第一個(gè)命令。

LRESULT CTrayDemoView::OnTrayNotification(WPARAM wp, LPARAM lp)
{          
   return m_trayIcon.OnTrayNotification(wp, lp);
}

  只有兩件事需要進(jìn)一步解釋。在顯示菜單之前,CTrayIcon類(lèi)使得第一項為缸省項,
  因此他看起來(lái)是大寫(xiě)的。但怎樣使得一個(gè)菜單項大寫(xiě)呢?使用函數
  GSetMenuDefaultItem。
// Make first menu item the default (bold font)
::SetMenuDefaultItem(pSubMenu->m_hMenu, 0, TRUE);

  這里的0便指定了第一個(gè)菜單項,TRUE表示通過(guò)位置而不是ID來(lái)確定菜單項。
  對CTrayIcon::OnTrayNotification,我們關(guān)心的第二項是為了顯示相關(guān)菜單,他干
  了些什么?

::SetForegroundWindow(m_nid.hWnd);
::TrackPopupMenu(pSubMenu->m_hMenu, ...);

  為了使TrackPopupMenu函數在托盤(pán)環(huán)境中工作正常,你必須首先在擁有該彈出菜單
  的窗口中調用SetForegroundWindow函數。否則,當用戶(hù)按下Esc鍵或在菜單以外單
  擊鼠標時(shí)該菜單將不會(huì )消失。正如你看到的那樣,CTrayIcon類(lèi)使得托盤(pán)圖標的編
  程非常簡(jiǎn)單。為了使托盤(pán)菜單生效,在TrayDemo中所做的只是實(shí)現一個(gè)通知程式,在
  該程式中調用了CTrayIcon::OnTrayNotification,對了別忘了還要提供一個(gè)和
  CTrayIcon類(lèi)擁有同樣ID的菜單。TrayDemo程式中是在菜單編輯器內加入一ID為
  IDR_TRAYICON的如下菜單:
  然后,用ClassWizard在視圖類(lèi)中分別為三個(gè)菜單命令加入如下的響應函數:

void CTrayDemoView::OnDisplayProgram()
{
CWnd* pWnd;
pWnd=AfxGetApp()->m_pMainWnd;
pWnd->ShowWindow(SW_NORMAL);
  pWnd->SetForegroundWindow();
}

void CTrayDemoView::OnCloseProgram()
{
m_bShutdown = TRUE;   // really exit
CWnd* pWnd;
pWnd=AfxGetApp()->m_pMainWnd;
  pWnd->SendMessage(WM_CLOSE);
}

void CTrayDemoView::OnShutoff()
{
Exit視窗系統Ex(EWX_SHUTDOWN,0);
}

  其中,在OnShutoff函數中,Exit視窗系統Ex(EWX_SHUTDOWN,0)用來(lái)關(guān)閉計算機。限
  于篇幅,這里不作周詳介紹,讀者能查看MSDN來(lái)獲得更周詳的資料。
  最后,還要重載Cmainframe::OnClose函數如下:

void CMainFrame::OnClose()
{
CTrayDemoView *pView =
  (CTrayDemoView *)GetActiveView();
if (pView->m_bShutdown)
   CFrameWnd::OnClose();
  else
   ShowWindow(SW_HIDE);
}

  提醒一點(diǎn),為使框架程式識別視圖類(lèi),還要在MainFrm.cpp中加入如下兩句:
#include "TrayDemoDoc.h"
#include "TrayDemoView.h"

  如果有興趣,還能對將本程式繼續擴充,使之能監視系統的狀態(tài):當鼠標和鍵
  盤(pán)在超過(guò)一設定的時(shí)間后,仍沒(méi)有動(dòng)作,則程式將自動(dòng)執行關(guān)機命令。
  以上程式在視窗系統98,VC++6.0中調試通過(guò)。
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
VC知識庫文章 - 系統托盤(pán)編程完全指南(一)
VC窗體設計集錦
VC按鈕添加圖標,位圖:
Delphi托盤(pán)編程實(shí)戰演練
托盤(pán)編程全接觸
vc實(shí)現系統托盤(pán)圖標
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久