イメージ リストについて

イメージ リストは、同じサイズのイメージのコレクションであり、各イメージはインデックスで参照できます。 イメージ リストは、アイコンまたはビットマップの大規模なセットを効率的に管理するために使用されます。 イメージ リスト内のすべての画像は、画面デバイス形式の 1 つのワイド ビットマップに含まれています。 イメージ リストには、イメージを透過的に描画するために使用されるマスク (アイコン スタイル) を含むモノクロ ビットマップを含めることもできます。

Microsoft Win32 API には、イメージ リストの作成と破棄、イメージの追加と削除、イメージの置換とマージ、イメージの描画、およびイメージのドラッグを可能にするイメージ リスト関数とマクロが用意されています。 イメージ リスト関数を使用するには、ソース コード ファイルに共通コントロール ヘッダー ファイルを含め、共通コントロール エクスポート ライブラリとリンクします。 さらに、イメージ リスト関数を呼び出す前に、InitCommonControls または InitCommonControlsEx 関数を使用して、共通コントロール DLL が読み込まれるようにします。

このセクションでは、次のトピックについて説明します。

種類

イメージ リストには、非マスクとマスクの 2 種類があります。 非マスク イメージ リストは、1 つ以上の画像を含むカラー ビットマップで構成されます。 マスク イメージ リストは、同じサイズの 2 つのビットマップで構成されます。 1 つ目は画像を含むカラー ビットマップです。2 つ目は一連のマスクを含むモノクロ ビットマップで、1 つ目のビットマップ内の画像ごとに 1 つあります。

非マスク画像は描画されるときに、単純にターゲット デバイス コンテキストにコピーされます。つまり、デバイス コンテキストの既存の背景色の上に描画されます。 マスク画像は描画されるときに、画像のビットがマスクのビットと組み合わされます。通常、ターゲット デバイス コンテキストの背景色が表示される透明な領域がビットマップ内に生成されます。 マスクされたイメージを描画するときに指定できる描画スタイルはいくつかあります。 たとえば、選択されたオブジェクトを示すために画像をディザリングするように指定できます。

イメージ リストの作成と破棄

イメージ リストを作成するには、ImageList_Create 関数を呼び出します。 パラメーターには、作成するイメージ リストの種類、各イメージの寸法、リストに追加するイメージの数が含まれます。 マスクされていないイメージ リストの場合、関数は、指定された寸法の指定された数のイメージを保持するのに十分な大きさの単一のビットマップを作成します。 次に、画面と互換性のあるデバイス コンテキストを作成し、その中のビットマップを選択します。 マスクされたイメージ リストの場合、関数は 2 つのビットマップと 2 つの画面互換デバイス コンテキストを作成します。 イメージ ビットマップを 1 つのデバイス コンテキストに選択し、マスク ビットマップをもう一方のデバイス コンテキストに選択します。 共通コントロール DLL には、イメージ リスト関数の実行可能コードが含まれています。

ImageList_Create では、イメージ リストに含まれるイメージの初期数と、リストを拡大できるイメージ数を指定します。 そのため、最初に指定した画像よりも多くの画像を追加しようとすると、新しいイメージに合わせて画像一覧が自動的に拡大されます。

ImageList_Create が正常に処理されると、HIMAGELIST 型へのハンドルが返されます。 他のイメージ リスト関数でこのハンドルを使用して、イメージ リストにアクセスし、イメージを管理します。 イメージの追加と削除、1 つのイメージ リストからのイメージのコピー、2 つの異なるイメージ リストからのイメージのマージを行うことができます。 イメージ リストが不要になったら、ImageList_Destroy 関数の呼び出しでハンドルを指定して破棄できます。

イメージの追加と削除

ビットマップ イメージ、アイコン、またはカーソルをイメージ リストに追加できます。 ビットマップ イメージを追加するには、ImageList_Add 関数の呼び出しで 2 つのビットマップにハンドルを指定します。 最初のビットマップには、イメージ ビットマップに追加する 1 つ以上のイメージが含まれており、2 番目のビットマップにはマスク ビットマップに追加するマスクが含まれています。 マスクされていないイメージ リストの場合、2 番目のビットマップ ハンドルは無視されます。これは NULL に設定できます。

ImageList_AddMasked 関数は、ビットマップ イメージをマスクされたイメージ リストに追加します。 この関数は、マスク ビットマップを 指定しない点を除き、ImageList_Add に似ています。 代わりに、マスクを自動的に生成するために、システムがイメージ ビットマップと組み合わせる色を指定します。 イメージ ビットマップ内の指定された色の各ピクセルが黒に変更され、マスク内の対応するビットが 1 に設定されます。 その結果、指定した色に一致するイメージ内のピクセルは、イメージの描画時に透明になります。

ImageList_AddIcon マクロは、アイコンまたはカーソルをイメージ リストに追加します。 イメージ リストがマスクされている場合、ImageList_AddIcon はアイコンまたはカーソルと共に提供されるマスクをマスク ビットマップに追加します。 イメージ リストがマスクされていない場合、イメージの描画時にアイコンまたはカーソルのマスクは使用されません。

ImageList_GetIcon 関数を使用すると、イメージ リストのイメージやマスクに基づいてアイコンを作成できます。 この関数は、新しいアイコンへのハンドルを返します。

ImageList_AddImageList_AddMasked および ImageList_AddIcon は、イメージ リストに追加される各イメージにインデックスを割り当てます。 インデックスは 0 から始まります。つまり、リスト内の最初の画像のインデックスは 0 で、次の画像のインデックスは 1 です。 1 つのイメージを追加すると、関数はイメージのインデックスを返します。 一度に複数のイメージが追加されると、関数は最初のイメージのインデックスを返します。

ImageList_Remove 関数は 、イメージ リストからイメージを削除します。

イメージの置換とマージ

ImageList_Replace 関数および ImageList_ReplaceIcon 関数は、イメージ リスト内のイメージを新しいイメージに置き換えます。 ImageList_Replace は、イメージをビットマップ イメージとマスクに置き換え、ImageList_ReplaceIconはイメージをアイコンまたはカーソルに置き換えます。

ImageList_Merge 関数は 2 つのイメージをマージし、新しいイメージを新しいイメージ リストに格納します。 新しいイメージは、2 番目のイメージを 1 つ目のイメージの上に透過的に描画することで作成されます。 新しいイメージのマスクは、2 つの既存のイメージのマスクのビットに対して論理 OR 演算を実行した結果です。

イメージの描画

画像を描画するには、ImageList_Draw または ImageList_DrawEx 関数を使用します。 イメージ リストへのハンドル、描画するイメージのインデックス、宛先デバイス コンテキストへのハンドル、デバイス コンテキスト内の場所、および 1 つ以上の描画スタイルを指定します。

ILD_TRANSPARENT スタイルを指定すると、ImageList_Draw または ImageList_DrawEx は、2 段階のプロセスを使用してマスクされたイメージを描画します。 まず、イメージのビットとマスクのビットに対して論理 AND 演算を実行します。 次に、最初の操作の結果と、宛先デバイス コンテキストのバックグラウンド ビットに対して、論理 XOR 演算を実行します。 このプロセスでは、結果のイメージに透明な領域が作成されます。つまり、マスク内の各白ビットによって、結果のイメージ内の対応するビットが透明になります。

単色の背景にマスクされた画像を描画する前に、ImageList_SetBkColor 関数を使用して画像リストの背景色を宛先と同じ色に設定する必要があります。 色を設定すると、イメージに透明な領域を作成する必要がなくなり、IImageList_Draw または ImageList_DrawEx イメージをコピー先デバイス コンテキストにコピーするだけで済むため、パフォーマンスが大幅に向上します。 イメージを描画するには、ImageList_Draw または ImageList_DrawEx の呼び出しで ILD_NORMAL スタイルを指定します。

マスクされたイメージ リストの背景色は、単色の背景に正しく描画されるようにいつでも設定できます。 背景色を CLR_NONE に設定すると、既定で画像が透過的に描画されます。 イメージ リストの背景色を取得するには、ImageList_GetBkColor 関数を使用します。

ILD_BLEND25ILD_BLEND50 のスタイルによって、システムの強調表示色で画像がディザーされます。 これらのスタイルは、ユーザーが選択できるオブジェクトを表すためにマスクされたイメージを使用する場合に便利です。 たとえば、ILD_BLEND50 スタイルを使用して、ユーザーがイメージを選択するときのイメージを描画できます。

マスクされていないイメージは、SRCCOPY ラスター操作を使用して、コピー先のデバイス コンテキストにコピーされます。 イメージ内の色は、デバイス コンテキストの背景色に関係なく同じように表示されます。 ImageList_Draw または ImageList_DrawEx で指定した描画スタイルも、マスクされていないイメージの外観には影響しません。

イメージをドラッグ

Win32 API には、画面上でイメージをドラッグするための関数が含まれています。 ドラッグ関数により、画像はカラーで滑らかに、カーソルが点滅することなく移動します。 マスクされた画像とマスクされていない画像のどちらでもドラッグできます。

ImageList_BeginDrag 関数は ドラッグ操作を開始します。 パラメーターには、イメージ リストへのハンドル、ドラッグするイメージのインデックス、イメージ内のホット スポットの位置が含まれます。 ホット スポットは、ドラッグ関数が画像の厳密なスクリーン位置として認識する単一のピクセルです。 通常は、マウス カーソルのホット スポットと一致するようにホット スポットを設定します。 ImageList_DragMove 関数は、画像を新しい位置に移動します。

ImageList_DragEnter 関数は、ウィンドウ内のドラッグ イメージの初期位置を設定し、その位置にイメージを描画します。 パラメーターには、イメージを描画するウィンドウへのハンドルと、ウィンドウ内の初期位置の座標が含まれます。 座標は、クライアント領域ではなくウィンドウの左上隅を基準とする相対位置となります。 同じことは、パラメーターとして座標を受け取るすべての画像ドラッグ関数に当てはまります。 つまり座標を指定する際は、境界線やタイトル バー、メニュー バーなど、ウィンドウ要素の幅を差し引く必要があります。 ImageList_DragEnter を呼び出す ときに NULL ウィンドウ ハンドルを指定すると、ドラッグ関数はデスクトップ ウィンドウに関連付けられているデバイス コンテキストにイメージを描画し、座標は画面の左上隅を基準にします。

ImageList_SetDragCursorImage 関数は、指定されたイメージ (通常はマウス カーソル イメージ) と現在のドラッグ イメージを組み合わせて、新しいドラッグ イメージを作成します。 ドラッグ関数はドラッグ操作中に新しいイメージを使用するため、ImageList_SetDragCursorImage を呼び出した後に、ShowCursor 関数を使用して実際のマウス カーソルを非表示にします。 そうしないと、ドラッグ操作中に、マウス カーソルが 2 つあるように見えてしまいます。

アプリケーションが ImageList_BeginDrag を呼び出すと、システムは一時的な内部イメージ リストを作成し、指定されたドラッグ イメージを内部リストにコピーします。 一時的なドラッグ イメージ リストへのハンドルは、ImageList_GetDragImage 関数を使用して取得できます。 また、現在のドラッグ位置と、その位置を基準とするドラッグ画像のオフセットも、この関数で取得されます。

イメージ情報

イメージ リストから情報を取得する関数は多数あります。 ImageList_GetImageInfo 関数は、イメージとマスク ビットマップのハンドル、ピクセルあたりの色平面とビット数、イメージ ビットマップ内のイメージの外接矩形など、1つのイメージに関する情報を IMAGEINFO 構造体に格納します。 この情報を使用して、イメージのビットマップを直接操作することができます。 ImageList_GetImageCount 関数は、イメージ リスト内のイメージの数を取得します。

イメージ オーバーレイ

すべてのイメージ リストには、オーバーレイとして使用するインデックスの一覧が含まれています。 オーバーレイは、別のイメージの上に透過的に描画されるイメージです。 イメージ リスト内の現在のイメージは、オーバーレイとして使用できます。 イメージ リストごとに最大4つのオーバーレイを指定できます。 この制限は、バージョン 4.71 で 15 に拡張されました。

イメージのインデックスをオーバーレイのリストに追加するには、ImageList_SetOverlayImage 関数を使用して、イメージ リストへのハンドル、既存のイメージのインデックス、および目的のオーバーレイ インデックスを指定します。 これ実際には、「インデックスx のイメージをオーバーレイとして使用し、オーバーレイをオーバーレイ インデックス yとして参照したい」ことを伝えます。オーバーレイ インデックスは 0 からではなく、1 から始まります。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 呼び出しで指定したオーバーレイ インデックスであるため、INDEXTOOVERLAYMASK マクロに配置されます。

32 ビット アンチエイリアス化アイコン

アンチエイリアス化は、鋭いエッジを柔らかくしたりぼかしたりするための手法です。 これにより、画像がより自然な外観になります。 Windows Vista および Windows 7 のイメージ リストは、32 ビットのアンチエイリアス化アイコンとビットマップの使用に対応しています。 色の値は 24 ビットを使用し、8 ビットはアイコンのアルファ チャネルとして使用されます。 32 ビット/ピクセル (bpp) イメージを処理できるイメージ リストを作成するには、ImageList_Create 関数を呼び出して、ILC_COLOR32 フラグを渡します。

32 ビット アイコンを正しく作成するには、次の図に示すように、アイコンごとに複数のイメージを作成する必要があります。

illustration showing three sizes of icons for each of three color depths

  • 最初の 3 つのイメージは、セーフ モードで使用するために 16 色モードです。
  • 次の 3 つのアイコンは、256 色モードで使用されます。
  • 最後の 3 つのアイコンにはアルファ チャネルがあり、24 ビットカラー以上を実行しているオペレーティング システムでのみ使用できます。
  • アイコン形式の画像の順序は重要です。 順序が間違っている場合、古いバージョンの Windows はアイコンを抽出するときに機能が低下します。 アイコンを正しく抽出しないと、メモリの破損や不適切なレンダリングが発生する可能性があります。
  • 以前のバージョンの Windows では、10 アイコンのリソース制限がありました。

Note

サード パーティ製のツールを使用すると、アルファ チャネルを含むアイコン ファイルとビットマップを生成できます。 LoadImage を使用してしてアルファを含む 32 bpp ビットマップを読み込む場合は、LR_CREATEDIBStandard Edition CTION フラグを指定する必要があります。