?? 04165-3.txt
字號:
}
6. 使應用程序顯示為任務條通知區中的圖標
在Windows 95任務條的右邊有一個區域被稱為通知區域,在其中可以顯示一些應用程序的圖標,用鼠標單擊其中的圖標一般能彈出應用程序的菜單,雙擊則能顯示應用程序的完整窗口界面。時鐘和音量控制是任務條通知區最常見的圖標。
任務條通知區編程可以通過Windows 95外殼編程接口函數Shell_NotifyIcon來實現,該函數在shellapi.h頭文件中聲明,其原型如下:
WINSHELLAPI BOOL WINAPI Shell_NotifyIcon( DWORD dwMessage,
PNOTIFYICONDATA pnid);
dwMessage是對通知區圖標進行操作的消息,主要有三中,如下表所示。
Shell_NotifyIcon使用的消息
消息
說明
NIM_ADD
在任務條通知區插入一個圖標
NIM_ DELETE
在任務條通知區刪除一個圖標
NIM_ MODIFY
對任務條通知區的圖標進行修改
pnid傳入一個NOTIFYICONDATA結構的指針。NOTIFYICONDATA結構聲明及各域的意義表示如下:
typedef struct _NOTIFYICONDATA { // nid
DWORD cbSize; // NOTIFYICONDATA結構的字節數
HWND hWnd; // 處理通知區圖標消息的窗口句柄
UINT uID; // 通知區圖標的ID
UINT uFlags; // 表示下述三項是否有意義的標志
UINT uCallbackMessage; // 鼠標點擊圖標所發出消息的ID
HICON hIcon; // 圖標句柄
char szTip[64]; // 當鼠標移到圖標上時顯示的提示信息
} NOTIFYICONDATA, *PNOTIFYICONDATA;
當用Shell_NotifyIcon在任務條通知區中放置一個圖標時,同時也定義了一條回調消息,當用戶用鼠標單擊或雙擊圖標時,NOTIFYICONDATA結構中指定的窗口句柄將接受到該消息。該消息的lParam參數將說明鼠標操作的方式。當應用程序退出時,應刪除任務條中的圖標。
下面的示例將說明如何使前述的橢圓窗口程序作為圖標顯示在任務條通知區中,當鼠標單擊圖標時,將彈出一個菜單,當雙擊時,橢圓窗口將完整顯示。
1. 用資源編輯器在EllipseWnd項目的IDR_MENU_CONTEXT菜單中增加一個菜單項“在任務條中插入圖標”(ID為IDM_INSERTICON)。
2. 用資源編輯器在EllipseWnd項目中增加一個菜單資源IDR_MENU_ICON ,在其中設定三個菜單項:
“激活橢圓窗口”(ID為IDM_ACTIVEWINDOW)
“關于...”(ID為IDM_ABOUTBOX)
“退出 Alt+F4”(ID為IDM_EXIT)
3. 在CEllipseWndDlg.h源文件中定義一個消息UM_ICONNOTIFY用以響應圖標操作,并在CEllipseWndDlg類定義中增加響應該消息的處理函數OnIconNotify。用ClassWizard增加響應菜單命令IDM_INSERTICON和IDM_ACTIVEWINDOW的函數定義和模板。CEllipseWndDlg.h中的修改如下:
// 定義響應圖標操作的消息
#define UM_ICONNOTIFY WM_USER+100
class CEllipseWndDlg : public CDialog
{
// Construction
public:
CEllipseWndDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CEllipseWndDlg)
enum { IDD = IDD_ELLIPSEWND_DIALOG };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CEllipseWndDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
CRgn m_rgnWnd;
// 處理圖標的功能函數說明
BOOL AddIcon();
BOOL DeleteIcon();
// Generated message map functions
//{{AFX_MSG(CEllipseWndDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
afx_msg void OnAboutbox();
afx_msg void OnExit();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnDestroy();
afx_msg void OnInserticon();
afx_msg void OnActivewindow();
//}}AFX_MSG
// 圖標消息的處理函數說明
afx_msg void OnIconNotify(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
};
4. 在CEllipseWndDlg.cpp中增加消息影射條目如下:
BEGIN_MESSAGE_MAP(CEllipseWndDlg, CDialog)
//{{AFX_MSG_MAP(CEllipseWndDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_LBUTTONDOWN()
ON_WM_CONTEXTMENU()
ON_COMMAND(IDM_ABOUTBOX, OnAboutbox)
ON_COMMAND(IDM_EXIT, OnExit)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_COMMAND(IDM_INSERTICON, OnInserticon)
ON_COMMAND(IDM_ACTIVEWINDOW, OnActivewindow)
//}}AFX_MSG_MAP
ON_MESSAGE(UM_ICONNOTIFY, OnIconNotify)
END_MESSAGE_MAP()
5. 在CEllipseWndDlg.cpp中增加如下的函數或代碼:
void CEllipseWndDlg::OnDestroy()
{
CDialog::OnDestroy();
// remove main window tag
::RemoveProp(m_hWnd, AfxGetApp()->m_pszExeName);
// 應用程序退出時,刪除任務條中圖標
DeleteIcon();
}
BOOL CEllipseWndDlg::AddIcon()
{
// 在任務條中增加圖標
NOTIFYICONDATA nid;
nid.cbSize = sizeof(nid);
nid.hWnd = m_hWnd;
nid.uID = IDR_MAINFRAME;
nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
nid.uCallbackMessage = UM_ICONNOTIFY;
nid.hIcon = m_hIcon;
CString str = "橢圓窗口";
lstrcpyn(nid.szTip, (LPCSTR)str,
sizeof(nid.szTip) / sizeof(nid.szTip[0]));
return Shell_NotifyIcon(NIM_ADD, &nid);
}
BOOL CEllipseWndDlg::DeleteIcon()
{
// 刪除任務條中的圖標
NOTIFYICONDATA nid;
nid.cbSize = sizeof(nid);
nid.hWnd = m_hWnd;
nid.uID = IDR_MAINFRAME;
return Shell_NotifyIcon(NIM_DELETE, &nid);
}
// 響應圖標消息處理函數
void CEllipseWndDlg::OnIconNotify(WPARAM wParam,
LPARAM lParam)
{
switch ((UINT)lParam)
{
// 鼠標單擊操作
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
{
// 裝入圖標操作菜單
CMenu menu;
menu.LoadMenu(IDR_MENU_ICON);
// 鼠標單擊位置
CPoint point;
GetCursorPos(&point);
// 將背景窗口激活
SetForegroundWindow();
// 顯示圖標菜單
menu.GetSubMenu(0)->TrackPopupMenu(
TPM_LEFTBUTTON|TPM_RIGHTBUTTON,
point.x, point.y, this, NULL);
// 增加一個額外消息,使菜單操作正確
PostMessage(WM_USER, 0, 0);
break;
}
// 鼠標雙擊操作
case WM_LBUTTONDBLCLK:
// 激活應用程序
OnActivewindow();
break;
}
}
// 插入圖標到任務條通知區
void CEllipseWndDlg::OnInserticon()
{
// 先隱藏主窗
ShowWindow(SW_HIDE);
// 插入圖標
AddIcon();
}
// 激活主窗
void CEllipseWndDlg::OnActivewindow()
{
// 先刪除圖標
DeleteIcon();
// 顯示主窗
ShowWindow(SW_SHOW);
UpdateWindow();
}
7. 顯示旋轉文本
在有的應用中,為了達到特殊的效果,經常需要顯示旋轉的文本。文本的顯示方式,包括旋轉,都是由字體來設置的。
字體的屬性主要由創建字體時使用的LOGFONT結構規定,該結構中的lfEscapement域指定了文本行與X軸(水平軸)的角度,其角度單位是十分之一度。為了是所有的字體向相同的方向旋轉,還應同時將LOGFONT結構的lfClipPrecision域設為 CLIP_LH_ANGLES。
下面的代碼將在對話框中顯示在同一起點每隔15度顯示一行文本:
void CRotateTextDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting
if (IsIconic())
{
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CRect rc;
GetClientRect(rc);
CString str(_T("............旋轉文本!"));
dc.SetBkMode(TRANSPARENT);
dc.SetTextColor(RGB(0,0,255));
CFont font;
LOGFONT lf;
memset(&lf,0,sizeof(LOGFONT));
lf.lfHeight = -14;
lf.lfWeight = FW_NORMAL;
lf.lfClipPrecision = CLIP_LH_ANGLES;
strcpy(lf.lfFaceName, "宋體");
for (int i=0;i<3600;i+=150)
{
lf.lfEscapement = i;
font.CreateFontIndirect(&lf);
CFont *pOldFont = dc.SelectObject(&font);
dc.TextOut(rc.right/2, rc.bottom/2,str);
dc.SelectObject(pOldFont);
font.DeleteObject();
}
CDialog::OnPaint();
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -