オーナードロー CListBox の作り方

行単位で色を変える必要があったので CListBox の派生クラスを作成した。
久々にやったらハマったので手順をメモして残す事にする。

  1. 派生クラスを作成する。仮にクラス名は CMyListBox とする。
  2. CMyListBox::DrawItem() をオーバーライドする。
  3. ダイアログエディタでリストボックスコントロールを貼り付ける。
  4. ダイアログエディタでリストボックスコントロールのプロパティを変更
    • 「Owner Draw」を「固定」か「変数*1」に設定。「固定」にすると行の高さが固定になり「変数」にすると CListBox::MeasureItem() が呼び出されるようになり行単位で高さが変更できるようになる。
    • 「Has Strings」を「True」に設定。「False」だと AddString() で指定した文字列がリストボックス内部に保持されない(= CListBox::GetText() や lpDrawItemStruct->itemData から文字列が取り出せなくなる)。またソート指定をした場合に CListBox::CompareItem() が呼び出されるようになる。
  5. ダイアログエディタ上でリストボックスコントロールを右クリックしてメニューから「変数の追加」を選択し CListBox 型のコントロール変数を作成する。
  6. ヘッダファイルを編集して上記変数の型を CListBox から CMyListBox に変更する。


「Has Strings」プロパティがデフォルトで「False」だったため、lpDrawItemStruct->itemData にゴミしか入って来ずハマってしまった。ゴミいれるくらいなら NULL 詰めといてくれい。
あと DRAWITEMSTRUCT.itemID にもやられた。詳細は以下で。

*1:原文は「variable」なので値を意味を考えると「可変」が正しいと思われる