大家知道,很多Windows程序都要使用MessageBox,只要在這個API函數的一個參數中使用MB_ICONQUESTION標志,便可以在MessageBox的對話框中顯示問號圖標。這樣用不同的標志便可以顯示不同的圖標。與Windows以前的老版本相比,Windows 2000以及Windows XP中的圖標越來越好看,種類也越來越多。為了更廣泛地使用這些漂亮的圖標,本文將介紹如何把它們運用到自己的對話框或窗體中去。為此,首先要解決的問題是:在哪裡以及如何獲取這些圖標?
這個問題屬於Windows中最基本的問題,同時也是最容易搞忘的問題。現在我們來看看一般情況下,我們是如何做的,通過使用預定義的形式為IDI_XXX的資源IDs作為參數調用::LoadIcon函數,我們可以獲取任何所謂的系統圖標。例如:
HICON hIconQuestion = ::LoadIcon(NULL, IDI_QUESTION);
圖一是本文例子程序的運行畫面,圖中顯示了所有的系統圖標。
圖一 例子程序運行畫面
上圖是例子程序在Windows 2000+SP3中運行結果。實現的細節都在mainfrm,cpp文件中。SysIcons[]是一個結構數組,其元素定義了圖標資源的ID和名稱:
const struct {
LPCTSTR nResID;
LPCTSTR name;
} SysIcons[] = {
{ IDI_APPLICATION, _T("IDI_APPLICATION") },
{ IDI_HAND, _T("IDI_HAND") },
{ IDI_QUESTION, _T("IDI_QUESTION") },
{ IDI_EXCLAMATION, _T("IDI_EXCLAMATION") },
{ IDI_ASTERISK, _T("IDI_ASTERISK") },
#if(WINVER >= 0x0400)
{ IDI_WINLOGO, _T("IDI_WINLOGO") },
{ IDI_WARNING, _T("IDI_WARNING") },
{ IDI_ERROR, _T("IDI_ERROR") },
{ IDI_INFORMATION, _T("IDI_INFORMATION") },
#endif
{ NULL, NULL }
};
加載圖標是在CMainFrame::OnPaint()中進行的:
......
for (UINT i=0; SysIcons[i].nResID; i++) {
HICON hicon = ::LoadIcon(NULL, SysIcons[i].nResID);
ASSERT(hicon);
CString name = SysIcons[i].name;
......
{
如果你想在自己的對話框或其它窗體中使用這些系統圖標,方法是這樣的:首先按通常方式創建一個靜態控制,然後用下面的方法加載並顯示圖標:
HICON hicon = ::LoadIcon(NULL, IDI_HAND);
m_wndStatic.SetIcon(hicon);
這裡假設m_wndStatic是你在對話框或窗體中創建的一個CStatic控制。在例子程序的“關於”對話框中,你可以看到一個問號圖標,並且這個圖標也有一個URL鏈接,這是因為使用了CStaticLink超鏈接類的緣故,它是由CStatic派生而來的。
雖然對系統圖標的處理沒有什麼深奧的東西,但Windows把這些簡單的東西弄得有點復雜化了,從圖一中不難看出,IDI_HAND已不再是手的形狀,至少在Windows2000和Window XP中是如此。從稱呼上看也變味了,IDI_ASTERISK成了一個含有字母“i”的球形形狀。微軟對這種詞匯上出現的困惑所做的解釋是:老版本的Windows顯示手形和星號;新版本則是用新的圖標。在winuser.h文件中可以窺見這些變化:
#if(WINVER >= 0x0400)
#define IDI_WARNING IDI_EXCLAMATION
#define IDI_ERROR IDI_HAND
#define IDI_INFORMATION IDI_ASTERISK
#endif /* WINVER >= 0x0400 */
如果你想跟上微軟的這些變化,那麼就使用新符號好了。這樣你的代碼也會更可讀一些,因為現在的警告、錯誤和信息符號更能傳達圖標所要表達的本意。
另外一個令人困惑的東西是:雖然winuser.h中新增了一個新的符號IDI_WINLOGO。在基於Windows XP的應用程序裡使用這個圖標產生的效果並不是我們所熟悉的那個家喻戶曉飛揚的窗口標志,而是圖一裡IDI_APPLICATION所表示的一般窗口標志。仔細閱讀有關文檔後,你會發現微軟對此的解釋是“設計行為”。為什麼這個具有某種代表意義的東西在不同的Windows OS中表現得如此模稜兩可呢?此中緣由鮮為人知。
本文配套源碼