關於影像清單
影像清單是相同大小的影像集合,每個影像都可以由其索引參考。 影像清單可用來有效率地管理大型圖示集或點陣圖。 影像清單中的所有影像都包含在單一寬點陣圖中,以螢幕裝置格式表示。 影像清單也可以包含單色位圖,其中包含用來以透明方式繪製影像的遮罩(圖示樣式)。
Microsoft Win32 API 提供影像清單函式和巨集,可讓您建立和終結影像清單、新增和移除影像、取代和合併影像、繪製影像,以及拖曳影像。 若要使用影像清單函式,請在原始程式碼檔案中包含通用控件頭檔,並與通用控件匯出連結庫連結。 此外,在呼叫任何映射清單函式之前,請使用 InitCommonControls 或 InitCommonControlsEx 函式,以確保載入通用控件 DLL。
本節將討論下列主題:
類型
影像列表有兩種類型:無遮罩和有遮罩。 非遮罩影像清單是由包含一或多個影像的色彩點陣圖所組成。 遮罩影像清單包含兩個大小相等的點陣圖。 第一個是包含影像的色彩點陣圖,第二個是單色位圖,其中包含一系列遮罩,第一個點陣圖中的每個影像各一個。
當繪製不帶遮罩的影像時,它僅會被複製到目標設備環境中;也就是說,它會覆蓋設備環境的現有背景顏色進行繪製。 繪製遮罩影像時,影像的位元會與遮罩的位元結合,通常會在目標設備的背景色顯示出來的位圖中產生透明區域。 在繪製遮罩影像時,您可以指定數種繪圖樣式。 例如,您可以指定將影像進行抖動處理,以指示選取的物件。
建立和銷毀圖像列表
您可以呼叫 ImageList_Create 函式來建立映像清單。 參數包括要建立的影像清單類型、每個影像的維度,以及您想要新增至清單的影像數目。 針對非遮罩影像清單,函式會建立足以容納指定維度之指定影像數目的單一位圖。 然後,它會建立與螢幕相容的裝置內容,並將點圖選取到其中。 針對遮罩影像清單,函式會建立兩個位圖和兩個螢幕相容的裝置上下文。 它會將影像位圖選取為一個裝置內容,並將遮罩位圖選取到另一個裝置內容中。 通用控制項 DLL 包含影像清單函式的可執行程式代碼。
在 ImageList_Create中,您可以指定影像清單中的影像初始數目,以及列表可以成長的影像數目。 因此,如果您嘗試新增的影像數目超過您最初指定的影像,影像清單會自動成長以容納新的影像。
如果 ImageList_Create 成功,它會傳回 HIMAGELIST 類型的控制代碼。 您可以在其他影像清單函式中使用這個句柄來存取影像清單和管理影像。 您可以新增和移除影像、將影像從一個影像清單複製到另一個映射清單,以及合併來自兩個不同的影像清單的影像。 當您不再需要影像清單時,可以在呼叫 ImageList_Destroy 函式時指定其句柄來終結它。
新增和移除影像
您可以將點陣圖影像、圖示或游標新增至影像清單。 您可以在呼叫 ImageList_Add 函式時,將句柄指定為兩個點陣圖,以新增位圖影像。 第一個位圖包含要新增至影像位圖的一或多個影像,而第二個位圖則包含要新增至遮罩位圖的遮罩。 對於未遮罩的影像清單,第二個位圖句柄會被忽略,可以設定為 NULL。
ImageList_AddMasked 函式也會將點陣圖影像新增至遮罩影像清單。 此函式類似於 ImageList_Add,但您未指定遮罩位圖。 相反地,您可以指定系統與影像位圖結合的色彩,以自動產生遮罩。 影像點陣圖中指定色彩的每個像素都會變更為黑色,且遮罩中的對應位設為1。 因此,在繪製影像時,符合指定色彩之影像中的任何圖元都是透明的。
ImageList_AddIcon 巨集會將圖示或游標新增至影像清單。 如果影像清單已遮罩,ImageList_AddIcon 會將圖示或游標提供的遮罩新增至遮罩位圖。 如果影像清單未遮罩,則繪製影像時不會使用圖示或游標的遮罩。
您可以使用 ImageList_GetIcon 函式,從影像清單中的影像及其遮罩中建立圖示。 函式會返回新圖示的句柄。
ImageList_Add、ImageList_AddMasked和 ImageList_AddIcon 將索引指派給每個影像,因為它會新增至影像清單。 索引是以零為起始;也就是說,清單中的第一個影像具有零的索引、下一個影像的索引為 1,依故。 新增單一影像之後,函式會傳回影像的索引。 一次新增多個影像時,函式會傳回第一個影像的索引。
ImageList_Remove 函式會從影像清單中移除影像。
取代和合併影像
ImageList_Replace 和 ImageList_ReplaceIcon 函式會將影像清單中的影像取代為新的影像。 ImageList_Replace 以點陣圖影像和遮罩取代影像,ImageList_ReplaceIcon 以圖示或游標取代影像。
ImageList_Merge 函式會合併兩個影像,並將新映像儲存在新的映射清單中。 新的映像是透過在第一個影像上以透明方式繪製第二個影像來建立。 新圖像的遮罩是將兩個現有圖像的遮罩位進行 OR 邏輯運算後的結果。
繪製圖像
若要繪製影像,您可以使用 ImageList_Draw 或 ImageList_DrawEx 函式。 您可以指定影像清單的控制碼、要繪製之影像的索引、目的地裝置內容的控制碼、裝置內容中的位置,以及一或多個繪圖樣式。
當您指定 ILD_TRANSPARENT 樣式時,ImageList_Draw 或 ImageList_DrawEx 會使用雙步驟程式來繪製遮罩影像。 首先,它會在影像位元和遮罩位元上執行邏輯 AND 作業。 然後,它會對第一個作業的結果和目的地裝置內容的背景位執行邏輯 XOR 作業。 此程式會在產生的影像中建立透明區域;也就是說,遮罩中的每個白色位都會使產生的影像中對應的位成為透明。
在純色背景上繪製遮罩影像之前,您應該使用 ImageList_SetBkColor 函式,將影像清單的背景色彩設定為與目的地相同的色彩。 設定色彩不需要在影像中建立透明區域,並讓 ImageList_Draw 或 ImageList_DrawEx 將影像直接複製到目的地裝置內容,進而大幅提升效能。 若要繪製影像,請在呼叫 ImageList_Draw 或 ImageList_DrawEx中指定 ILD_NORMAL 樣式。
您可以隨時設定遮罩影像清單的背景色彩,使其在任何純色背景上正確繪製。 將背景色彩設定為CLR_NONE預設會以透明方式繪製影像。 若要擷取影像清單的背景色彩,請使用 ImageList_GetBkColor 函式。
ILD_BLEND25 和 ILD_BLEND50 樣式會使用系統醒目提示色彩對影像進行抖動處理。 如果您使用遮罩影像來代表使用者可以選取的對象,這些樣式會很有用。 例如,您可以使用 ILD_BLEND50 樣式,在用戶選取影像時繪製影像。
使用SRCCOPY點陣作業,將非遮罩影像複製到目的地裝置內容。 不論裝置內容的背景色彩為何,影像中的色彩都會顯示相同。 ImageList_Draw 或 ImageList_DrawEx 中指定的繪圖樣式也不會影響非遮罩影像的外觀。
拖曳影像
Win32 API 包含在畫面上拖曳影像的函式。 拖曳函式會以色彩順暢地移動影像,而不會閃爍游標。 可以拖動被遮罩和未被遮罩的影像。
ImageList_BeginDrag 函式會開始拖曳作業。 參數包括影像清單的控制代碼、要拖曳的影像索引,以及影像中熱點的位置。 熱點是拖曳功能辨識為影像在螢幕上精確位置的單一像素。 一般而言,應用程式會設定作用點,使其與滑鼠游標的熱點重合。 ImageList_DragMove 函式會將影像移至新位置。
ImageList_DragEnter 函式會設定拖曳影像在視窗中的初始位置,並將影像繪製在該位置。 參數包括用於繪製影像的視窗句柄,及視窗內初始位置的座標。 座標相對於視窗的左上角,而不是用戶區域。 所有採用座標做為參數的影像拖曳函式也是如此。 這表示您必須在指定座標時補償視窗元素的寬度,例如框線、標題列和功能表列。 如果您在呼叫 ImageList_DragEnter時指定 NULL 視窗句柄,則拖曳函式會在與桌面視窗相關聯的裝置內容中繪製影像,且座標是相對於螢幕左上角。
ImageList_SetDragCursorImage 函式會結合指定的影像(通常是滑鼠游標影像)與目前的拖曳影像,來建立新的拖曳影像。 由於拖曳函式在拖曳作業期間使用新影像,因此您應該使用 ShowCursor 函式,在呼叫 ImageList_SetDragCursorImage之後隱藏實際的滑鼠游標。 否則,系統可能會在拖曳作業期間出現兩個滑鼠游標。
當應用程式呼叫 ImageList_BeginDrag時,系統會建立暫時的內部映像清單,然後將指定的拖曳映射複製到內部清單。 您可以使用 ImageList_GetDragImage 函式,取得暫存拖曳影像清單的句柄。 函式也會擷取目前的拖曳位置,以及拖曳影像相對於拖曳位置的位移。
影像資訊
有數個函式可從影像清單中擷取資訊。 ImageList_GetImageInfo 函式會填入 IMAGEINFO 結構,其中包含單一影像的相關信息,包括影像和遮罩位圖的控點、每圖元的色彩平面和位數,以及影像位圖內的影像周框。 您可以使用此資訊直接操控影像的點陣圖。 ImageList_GetImageCount 函式會擷取影像清單中的影像數目。
影像重疊
每個影像清單都包含要作為重疊使用的索引清單。 重疊是透過另一個影像以透明方式繪製的影像。 影像清單中目前的任何影像都可以當做重疊使用。 您可以為每個影像清單指定最多四個重疊。 此限制已擴充至 4.71 版中的 15 個。
您可以使用 ImageList_SetOverlayImage 函式,將影像的索引新增至重疊清單、指定影像清單的句柄、現有影像的索引,以及所需的重疊索引。 實際上,這告訴影像列表:「索引 x 的影像可以作為重疊使用,而我想將其作為重疊索引 y。」重疊索引是從1開始的,而不是從0開始,因為重疊索引為0表示不使用任何重疊。
使用 ImageList_Draw 或 ImageList_DrawEx 函式繪製影像時,您可以指定重疊。 重疊是通過將所需的繪圖旗標與 INDEXTOOVERLAYMASK 巨集結果進行邏輯 OR 運算來指定的。 INDEXTOOVERLAYMASK 巨集會接收重疊索引,並將其格式化以便與這些函式的旗標一起使用。 這會使用指定的重疊繪製影像。 下列範例示範如何在繪製影像時新增和指定重疊。
ImageList_SetOverlayImage(himl, 0, 3);
ImageList_Draw(himl, 1, hdc, 0, 0, ILD_MASK | INDEXTOOVERLAYMASK(3));
這會繪製影像 1,然後使用影像 0 重疊該影像。 因為 3 是您在 ImageList_SetOverlayImage 呼叫中指定的重疊索引,因此 3 會放在 INDEXTOOVERLAYMASK 巨集中。
32 位反鋸齒圖示
抗鋸齒是軟化或模糊尖銳邊緣的技術。 這讓影像的外觀更加自然。 Windows Vista 和 Windows 7 中的影像列表支援使用 32 位反鋸齒圖示和位陣圖。 色彩值使用 24 位,而 8 位會作為圖示上的 Alpha 通道使用。 若要建立可以處理每圖元 32 位 (bpp) 影像的影像清單,請呼叫 ImageList_Create 函式,傳入ILC_COLOR32旗標。
若要正確撰寫 32 位圖示,您必須為每個圖示建立多個影像,如下圖所示。
- 前三個影像處於 16 色模式,以用於安全模式。
- 接下來的三個圖示會在 256 色彩模式中使用。
- 最後三個圖示具有 α 通道,而且只能在執行 24 位元色彩或更高的作業系統中使用。
- 圖示格式影像的順序確實很重要。 如果順序錯誤,在擷取圖示時,舊版 Windows 功能會不佳。 不正確地擷取圖示可能會導致記憶體損毀和轉譯不正確。
- 舊版 Windows 有 10 個圖標的資源限制。
注意
您可以使用第三方工具來產生包含 Alpha 色板的圖示檔案和點陣圖。 如果您使用 LoadImage 來載入包含 alpha 的 32 bpp 位圖,則必須指定LR_CREATEDIBSECTION旗標。