Sent to you by Leon via Google Reader:
根據VC5聯機幫助中有關圖標的資料翻譯而成
● 圖標
圖標是一張圖片,它是由一張位圖和一個掩碼圖像產生的透明圖像區域。以下內容描述了怎樣創建、顯示、銷毀和復制圖標。
● 關于圖標(About Icons)
在Windows系統中圖標隨處可見,它一般用來描述一個對象,比如文件、文件夾、快捷方式、應用程序、以及各種文檔。在Win32 API中的圖標函數可以允許應用程序來創建、讀取、排列和銷毀圖標。
有關用特定圖標來代表某一種文件類型的資料,請參見Icon Handlers一節。
● 圖標的熱點(Icon Hot Spot)
圖標中的某一個像素被指定為熱點,操作系統將根據這個點來跟蹤和定位圖標。一般情況下,圖標的熱點都是定位在圖標的中心點上。如果你用CreateIconIndirect()函數來創建一個圖標,那么你可以指定圖標的任何一點作為它的熱點。(譯者注:其實圖標并不使用熱點,這可能是微軟的文檔沒有寫清楚。使用熱點的是光標。)
● 圖標的類型(Icon Types)
操作系統提供了一組標准圖標供應用程序隨時使用,在Windows頭文件(windows.h)中有這些圖標的資源ID值(以IDI_為前綴的定義)。每一個標准圖標都有一個缺省的圖像與之對應,用戶可以隨時用標准光標(?)來替換這些缺省圖像。定制圖標(Custom icons)可以用于特殊程序或隨便什么目的(譯者注:微軟很有意思,我們不可能只用標准圖標而不用自己的圖標:-),下面是几個定制圖標:
● 圖標的尺寸(Icon Sizes)
Windows使用四種圖標尺寸:系統小型、系統大型、殼小型、殼大型。
系統小型圖標用于顯示在窗口的標題條中。如果你想改變這種圖標的尺寸,可啟動顯示控制面板程序,單擊"外觀"卡片,從"項"(Item)列表中選擇"標題按鈕"(Caption Buttons),然后修改"尺寸"值。如果你想在應用程序中獲取系統小型圖標的尺寸,可調用GetSystemMetrics()函數(使用SM_CXSMICON和SM_CYSMICON作為參數)。
系統大型圖標主要是被應用程序自身使用(比如在"關于"對話框中),但它也顯示在Alt+Tab對話框中。CreateIconFromResource()、DrawIcon()、ExtractIcon()、和LoadIcon()函數都是使用系統大型圖標。因為系統大型圖標的尺寸是被視頻設備定義的,所以不能修改。如果你想獲取這種圖標的尺寸,可調用GetSystemMetrics()函數(使用SM_CXICON和SM_CYICON作為參數)。CreateIcon()、CreateIconFromResourceEx()和CreateIconIndirect()這三個函數可以創建與系統大型圖標尺寸不同的圖標。
殼小型圖標是被用于Windows Exploer程序和一些公共對話框,通常情況下,這種圖標的尺寸是與系統小型圖標的尺寸相等的。你可以使用SHGetFileInfo()函數來獲取該類型圖標的圖標列表句柄(使用SHGFI_SHELLICONSIZE|SHGFI_SMALLICON作為參數),然后使用ImageList_GetIconSize()函數來獲得圖標的尺寸。
殼大型圖標將被用于桌面。如果你想修改這種圖標的尺寸,可啟動顯示控制面板程序,單擊"外觀"卡片,從"項"列表中選擇"圖標",然后設置它的值。(注:這個值將被保存在系統注冊表中,地址是:HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics\Shell Icon Size),你同時也需要單擊"Plus!"卡片,并選擇"使用大圖標"復選框。要想獲取這種圖標的尺寸,可先用SHGetFileInfo()函數(使用SHGFI_SHELLICONSIZE作為參數)來取得系統圖像的列表,然后用ImageList_GetIconSize()函數來取得圖標的尺寸。
系統"開始"菜單中將使用殼大型圖標或者殼小型圖標,具體使用哪一種將取決于"使用大圖標"復選框是否被設置。
你的應用程序圖標應該提供以下几種格式:
* 48×48, 256色
* 32×32, 16色
* 16×16, 16色
當你的應用程序在注冊窗口類時,WNDCLASSEX結構中的hIcon成員應對應于32×32的圖標,hIconSm成員則對應于16×16圖標。有關類圖標的更多信息,請參見Class Icons一節。
● 圖標的創建(Icon Creation)
標准圖標是預定義的,所以他們不需要創建。要想使用標准圖標,應用程序可以用LoadImage()函數來獲得這種圖標的句柄(圖標句柄是一個HICON類型的系統唯一值,可用于代表一個標准圖標或定制圖標)。
如果應用程序想使用自己的圖標(稱為定制圖標),那么開發者一般都是先用圖像軟件來制作圖標的圖像,然后將該圖像作為ICON資源包含到程序中。在程序運行的時候,調用LoadIcon()或LoadImage()函數來獲取圖標的句柄。圖標資源一般將包含几種不同顯示設備所需要的數據,LoadIcon()和LoadImage()函數在讀取圖標時,會自動調入與當前顯示設備最匹配的數據。
應用程序也可以在運行的時候創建一個定制圖標,方法是先填寫一個ICONINFO結構,再使用CreateIconIndirect()函數創建即可。你也可以用GetIconInfo()函數來獲取指定圖標的熱點、掩碼位圖和彩色位圖。但應用程序應該盡量避免在運行時創建圖標,最好的方法是將定制圖標做成資源,然后用LoadIcon()或LoadImage()函數在運行時調用。這樣作的好處是可以消除圖標對設備的依賴、軟件本地化更容易,并可以使應用程序間共享圖標。
CreateIconFromResourceEx()函數可以讓應用程序瀏覽從系統資源、被創建的圖標、到基于資源數據的光標等數種圖像,CreateIconFromResourceEx()函數也可以根據其他EXE文件或DLL文件中的二進制資源數據來創建圖標。有關資源函數的更多信息,請參見Resource Functions一節。
● 圖標的顯示(Icon Display)
應用程序可以調用GetIconInfo()函數來獲取指定圖標的圖像(譯者注:即位圖的句柄),也可以調用DrawIconEx()函數來顯示圖標。如果想顯示一個圖標的默認圖像,在調用DrawIconEx()函數時請指定DI_COMPAT標志,如果不指定這個標志,該函數將使用用戶指定的圖像。
● 銷毀圖標(Icon Destruction)
當應用程序不再需要一個在運行時(使用CreateIconIndirect()函數創建的)創建的圖標的時候,它應該銷毀這個圖標。可以使用DestroyIcon()函數來達到該目的,DestroyIcon()函數將銷毀圖標句柄,并釋放指定圖標所占用的內存資源。(注:DestroyIcon()函數只能用于銷毀由CreateIconIndirect()函數創建的圖標,而其它類型的圖標是不需要銷毀的)。
● 圖標的復制(Icon Duplication)
CopyIcon()函數可以復制圖標的句柄,這使得應用程序或DLL可以取得其他程序的圖標(復制),當那些程序被釋放的時候,這些復制的圖標將繼續有效。
CopyImage()函數可以創建一個基于指定圖標的新的圖標。這個新圖標可以大于或小于原來的圖標。有關在EXE文件中加、減、替換圖標的信息,請參見Resources一節。
● 創建一個圖標(Create an Icon)
要想使用圖標,應用程序必需先獲得圖標的句柄。下面的范例將展示怎樣創建兩種不同類型的圖標句柄:一種是標准圖標(一個感嘆號),另一種是定制圖標(作為程序的資源)。
HICON hIcon1; // icon handle
HICON hIcon2; // icon handle
// Create a standard question icon.
hIcon1 = LoadIcon(NULL, IDI_QUESTION);
// Create a custom icon based on a resource.
hIcon2 = LoadIcon(hinst, MAKEINTRESOURCE(460));
// Create a custom icon at run time.
雖然應用程序最好不要在運行時創建圖標,但此處還是放置了一個用CreateIcon()函數創建運行時圖標的例子,其目的主要是講解系統對掩碼位圖的解釋原理。
HICON hIcon3; // icon handle
// Yang icon AND bitmask
BYTE ANDmaskIcon[] = {
0xFF, 0xFF, 0xFF, 0xFF, // line 1
0xFF, 0xFF, 0xC3, 0xFF, // line 2
0xFF, 0xFF, 0x00, 0xFF, // line 3
0xFF, 0xFE, 0x00, 0x7F, // line 4
0xFF, 0xFC, 0x00, 0x1F, // line 5
0xFF, 0xF8, 0x00, 0x0F, // line 6
0xFF, 0xF8, 0x00, 0x0F, // line 7
0xFF, 0xF0, 0x00, 0x07, // line 8
0xFF, 0xF0, 0x00, 0x03, // line 9
0xFF, 0xE0, 0x00, 0x03, // line 10
0xFF, 0xE0, 0x00, 0x01, // line 11
0xFF, 0xE0, 0x00, 0x01, // line 12
0xFF, 0xF0, 0x00, 0x01, // line 13
0xFF, 0xF0, 0x00, 0x00, // line 14
0xFF, 0xF8, 0x00, 0x00, // line 15
0xFF, 0xFC, 0x00, 0x00, // line 16
0xFF, 0xFF, 0x00, 0x00, // line 17
0xFF, 0xFF, 0x80, 0x00, // line 18
0xFF, 0xFF, 0xE0, 0x00, // line 19
0xFF, 0xFF, 0xE0, 0x01, // line 20
0xFF, 0xFF, 0xF0, 0x01, // line 21
0xFF, 0xFF, 0xF0, 0x01, // line 22
0xFF, 0xFF, 0xF0, 0x03, // line 23
0xFF, 0xFF, 0xE0, 0x03, // line 24
0xFF, 0xFF, 0xE0, 0x07, // line 25
0xFF, 0xFF, 0xC0, 0x0F, // line 26
0xFF, 0xFF, 0xC0, 0x0F, // line 27
0xFF, 0xFF, 0x80, 0x1F, // line 28
0xFF, 0xFF, 0x00, 0x7F, // line 29
0xFF, 0xFC, 0x00, 0xFF, // line 30
0xFF, 0xF8, 0x03, 0xFF, // line 31
0xFF, 0xFC, 0x3F, 0xFF}; // line 32
// Yang icon XOR bitmask
BYTE XORmaskIcon[] = {
0x00, 0x00, 0x00, 0x00, // line 1
0x00, 0x00, 0x00, 0x00, // line 2
0x00, 0x00, 0x00, 0x00, // line 3
0x00, 0x00, 0x00, 0x00, // line 4
0x00, 0x00, 0x00, 0x00, // line 5
0x00, 0x00, 0x00, 0x00, // line 6
0x00, 0x00, 0x00, 0x00, // line 7
0x00, 0x00, 0x38, 0x00, // line 8
0x00, 0x00, 0x7C, 0x00, // line 9
0x00, 0x00, 0x7C, 0x00, // line 10
0x00, 0x00, 0x7C, 0x00, // line 11
0x00, 0x00, 0x38, 0x00, // line 12
0x00, 0x00, 0x00, 0x00, // line 13
0x00, 0x00, 0x00, 0x00, // line 14
0x00, 0x00, 0x00, 0x00, // line 15
0x00, 0x00, 0x00, 0x00, // line 16
0x00, 0x00, 0x00, 0x00, // line 17
0x00, 0x00, 0x00, 0x00, // line 18
0x00, 0x00, 0x00, 0x00, // line 19
0x00, 0x00, 0x00, 0x00, // line 20
0x00, 0x00, 0x00, 0x00, // line 21
0x00, 0x00, 0x00, 0x00, // line 22
0x00, 0x00, 0x00, 0x00, // line 23
0x00, 0x00, 0x00, 0x00, // line 24
0x00, 0x00, 0x00, 0x00, // line 25
0x00, 0x00, 0x00, 0x00, // line 26
0x00, 0x00, 0x00, 0x00, // line 27
0x00, 0x00, 0x00, 0x00, // line 28
0x00, 0x00, 0x00, 0x00, // line 29
0x00, 0x00, 0x00, 0x00, // line 30
0x00, 0x00, 0x00, 0x00, // line 31
0x00, 0x00, 0x00, 0x00}; // line 32
hIcon3 = CreateIcon(
hinst, // application instance
32, // icon width
32, // icon height
1, // number of XOR planes
1, // number of bits per pixel
ANDmaskIcon, // AND bitmask
XORmaskIcon); // XOR bitmask
在創建圖標時,CreateIcon()函數使用下列的原理表來AND和XOR位掩碼:
AND位掩碼 XOR位掩碼 顯示
-------------------------------------------
0 0 黑色
0 1 白色
1 0 屏幕
1 1 屏幕的反色
在關閉之前,應用程序必需用DestroyIcon()函數來銷毀任何用CreateIconIndirect()函數創建的圖標(譯者注:這也可以看出用資源圖標的好處)。
● 顯示圖標(Displaying an Icon)
你的應用程序可以將讀入或創建的圖標顯示在程序的客戶區或子窗口中,下面的范例顯示了怎樣在一個窗口中顯示圖標(HDC代表窗口):
HICON hIcon1; // icon handle
HDC hdc; // handle of display context
DrawIcon(hdc, 10, 20, hIcon1);
Windows系統會自動的顯示窗口的類圖標,你的應用程序可以在注冊窗口類時指定這個圖標。也可以在程序運行時調用SetClassLong()函數來替換類圖標(該函數會修改所有該類的窗口設置),下面的范例演示了用一個圖標資源來替換類圖標的方法:
HINSTANCE hinst; // handle of current instance
HWND hwnd; // main window handle
// Change the icon for hwnd's window class.
SetClassLong(hwnd, // window handle
GCL_HICON, // changes icon
(LONG) LoadIcon(hinst, MAKEINTRESOURCE(480))
);
有關窗口類的更多信息,請參見Window Classes一節。
● 共享圖標資源(Sharing Icon Resources)
下面的范例演示了怎樣從另一個應用程序中提取圖標,并在自己的程序中顯示出來。代碼中調用了CreateIconFromResourceEx()、DrawIcon()、LookupIconIdFromDirectoryEx()、和其它的几個資源函數。
HICON hIcon1; // icon handle
HINSTANCE hExe; // handle to loaded .EXE file
HRSRC hResource; // handle for FindResource
HRSRC hMem; // handle for LoadResource
BYTE *lpResource; // address of resource data
int nID; // ID of resource that best fits current screen
HDC hdc; // handle of display context
// Load the file from which to copy the icon.
hExe = LoadLibrary("myapp.exe");
// Find the icon directory whose identifier is 440.
hResource = FindResource(hExe,
MAKEINTRESOURCE(440),
RT_GROUP_ICON);
// Load and lock the icon directory.
hMem = LoadResource(hExe, hResource);
lpResource = LockResource(hMem);
// Get the identifier of the icon that is most appropriate for the video display.
nID = LookupIconIdFromDirectoryEx((PBYTE) lpResource, TRUE,
CXICON, CYICON, LR_DEFAULTCOLOR);
// Find the bits for the nID icon.
hResource = FindResource(hExe,
MAKEINTRESOURCE(nID),
MAKEINTRESOURCE(RT_ICON));
// Load and lock the icon.
hMem = LoadResource(hExe, hResource);
lpResource = LockResource(hMem);
// Create a handle to the icon.
hIcon1 = CreateIconFromResourceEx((PBYTE) lpResource,
SizeofResource(hExe, hResource), TRUE, 0x00030000,
CXICON, CYICON, LR_DEFAULTCOLOR);
// Draw the icon in the client area.
DrawIcon(hdc, 10, 20, hIcon1);
● 關于圖標的函數:(Icon Fuctions)
CopyIcon
CreateIcon
CreateIconFromResource
CreateIconFromResourceEx
CreateIconIndirect
DestroyIcon
DrawIcon
DrawIconEx
GetIconInfo
LoadIcon
LookupIconIdFromDirectoryEx
● 關于圖標的結構:(Icon Structures)
ICONINFO
ICONMETRICS
● 關于圖標的消息:(Icon Messages)
WM_ERASEBKGND
WM_ICONERASEBKGND
WM_PAINTICON
Things you can do from here:
- Subscribe to 学海无涯 回头是岸 using Google Reader
- Get started using Google Reader to easily keep up with all your favorite sites