|
拡張コンボボックス
今回は拡張コンボボックスを使ってみます。拡張コンボボックスは、次のようにアイテムにイメージをつけることができるコンボボックスです。普通のコンボボックスでもアイテムにイメージをつけることはできますが、その場合はオーナードローで作らなければいけません。拡張コンボボックスの場合はもう少し簡単にアイテムにイメージをつけることができます。

ではまず、リソースエディタで拡張コンボボックスを作成します。ツールボックスから「Extended Combo Box」を選んで、ダイアログに追加します。コンボボックスと同様に、拡張コンボボックス自体のサイズと、プルダウンで出てくるリストのサイズの両方を設定します。リストのサイズは、拡張コンボボックスの↓部分を一度クリックしてから下方向にサイズを伸ばすと設定できます。

拡張コンボボックスのプロパティは、リソースIDとTypeを設定します。ここでは「Type」を「ドロップダウンリスト」にします。他はデフォルトのままでOKです。

アイテムにつけるイメージは、CImageListクラスで管理します。このクラスは複数のイメージをインデックスで管理できます。動的配列のイメージ版?のようなものだと考えればいいでしょう。では、このクラスに渡すビットマップをビットマップエディタで作成します。複数のイメージを横に並べて、1枚のビットマップにします。

アイテムの高さはイメージの高さによって自動的に伸縮します。ここでは24x24の大きさのイメージを5枚並べました。真ん中の緑の帽子?は「オーバーレイイメージ」に使います。オーバーレイイメージというのはイメージの上に重ねて表示するイメージです。顔のイメージに帽子のオーバーレイイメージを重ねると、帽子をかぶった顔になります。
1つのアイテムにつけるイメージは、通常状態、選択状態、オーバーレイイメージの3種類を設定できます。もちろん必ずしも全部つける必要はありません。また、アイテムごとに設定するイメージを変えることもできます。使いたいイメージを全部用意して、1枚のビットマップに横並びに並べておきます。イメージはインデックスで指定するので、どのような順番で並べてあっても大丈夫です。
もう一つ、イメージには透過色を設定できます。色は何色にしてもいいですが、ここではピンク色(赤:255、緑:0、青:255)にしています。透過したいところはこの色で塗りつぶしておきます。
では、次に拡張コンボボックス用にDDX変数を追加します。拡張コンボボックスはCComboBoxExクラスで操作します。アクセスはprivate、「コントロール変数」をチェックし、カテゴリにColtrolを選択します。Control型の変数なのでm_xcで始まる名前にするとよいでしょう。

次は、ダイアログクラスにCImageList型のメンバ変数を追加します。

では、コードの方を実装していきましょう。OnInitDialog()で次のように処理します。
BOOL CComboExDlg::OnInitDialog()
{
CDialog::OnInitDialog();
SetIcon(m_hIcon, TRUE); // 大きいアイコンの設定
SetIcon(m_hIcon, FALSE); // 小さいアイコンの設定
// TODO: 初期化をここに追加します。
{
COMBOBOXEXITEM exItem;
CString str;
int err = 0;
// イメージリスト作成
if (!err) if (!m_imageList.Create
(IDB_BITMAP1, 24, 1, RGB(255, 0, 255))) err = 1;
// オーバーレイイメージを設定
if (!err) if (!m_imageList.SetOverlayImage(2, 1)) err = 1;
// 拡張コンボボックスにイメージリストをセット
if (!err) m_xcComboEx.SetImageList(&m_imageList);
// アイテム挿入
if (!err)
{
str = _T("アイテム1");
exItem.mask = CBEIF_IMAGE | CBEIF_SELECTEDIMAGE |
CBEIF_OVERLAY | CBEIF_TEXT;
exItem.iImage = 0;
exItem.iSelectedImage = 1;
exItem.iOverlay = 1;
exItem.iItem = -1;
exItem.pszText = const_cast<LPTSTR>(static_cast<LPCTSTR>(str));
if (m_xcComboEx.InsertItem(&exItem) == -1) err = 1;
}
if (!err)
{
str = _T("アイテム2");
exItem.pszText = const_cast<LPTSTR>(static_cast<LPCTSTR>(str));
if (m_xcComboEx.InsertItem(&exItem) == -1) err = 1;
}
if (!err)
{
str = _T("アイテム3");
exItem.pszText = const_cast<LPTSTR>(static_cast<LPCTSTR>(str));
exItem.iImage = 3;
exItem.iSelectedImage = 4;
exItem.iOverlay = 1;
if (m_xcComboEx.InsertItem(&exItem) == -1) err = 1;
}
if (!err) if (m_xcComboEx.SetCurSel(0) == CB_ERR) err = 1;
}
return TRUE;
}
|
まずは、CImageList::Create()関数でイメージリストを作成します。引数には、ビットマップのリソースID、1つのイメージの横幅、拡張単位、透過色を指定します。イメージリストについてはまた別のところで詳しく取り上げたいと思います。
次はCImageList::SetOverlayImage()関数でオーバーレイイメージを設定します。第一引数は0から始まるイメージのインデックス(ビットマップの左から何番目か)、第二引数は1から始まるオーバーレイイメージのインデックスです。これはイメージのインデックスとは関係のない、自分で決める値です。ここでは1にしました。
次は、CComboBoxEx::SetImageList()関数で拡張コンボボックスにイメージリストをセットします。
拡張コンボボックスにアイテムを挿入するには、CComboBoxEx::InsertItem()関数を使います。この関数には、COMBOBOXEXITEM型の構造体のポインタを渡します。
COMBOBOXEXITEM構造体は、どのメンバを設定するのかを指定するために、まずmaskメンバをセットします。ここでは3種類のイメージとアイテムの文字列をセットするので、maskには、CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_OVERLAY | CBEIF_TEXTを設定します。
アイテムの文字列はpszTextに文字列のポインタをセットします。通常時のイメージはiImageに、選択状態のイメージはiSelectedImageにイメージリストのインデックスをセットします。オーバーレイイメージはiOverlayに先ほど決めたオーバーレイイメージのインデックスをセットします。これはイメージリストのインデックスとは別なので注意が必要です。
ここでは、1番目、2番目のアイテムに赤い顔、3番目のアイテムに青い顔を表示するようにしてみました。アイテムによってイメージリストのインデックスを変えているところに注意してください。
では、ビルドして実行してみましょう。アイテムにイメージがついているのがわかります。通常状態、選択状態でイメージが変わります。また、オーバーレイイメージをつけているので、帽子をかぶった顔になっています。

|