2008年11月18日
ALT+Tabチックなプログラムを書く…オナードローCListBox編
以下のエントリの一応続編です
とりあえず、このエントリでALT+Tabチックなプログラムのメモは終了です。
切替タスクの名前とアイコンが取得できたので、表示する必要があります。とりあえず、リストボックス(CListBox)で表示することにしましたが…標準のCListBoxでは、アイコンを併せて表示することができません
そこで、CodeProjectを検索してでてきたのが「Graphic and text ownerdraw listbox」です。サンプル画面を見る限り、今回の用途には十分そうです。使うのも簡単ですね。
リストボックス部品を貼って、COwnerDrawListBoxクラスとしてメンバー変数(例えばm_OwnerListBox)を作ってアイテムを設定したいところで以下のような感じで書くだけです
m_OwnerListBox.Add("アイテム1", ::AfxGetApp()->LoadIcon(ICON_ITEM1)); m_OwnerListBox.Add("アイテム2", ::AfxGetApp()->LoadIcon(ICON_ITEM2));
あとは、アイコンとテキストの位置関係の設定を以下のような感じで。
m_OwnerListBox.SetTextPosition(COwnerDrawListBox::ITEM_LEFT); m_OwnerListBox.SetIconPosition(COwnerDrawListBox::ITEM_RIGHT);
上記の場合だとテキストが左側にアイコンが右側に表示されます。
そして、リストボックスが不要になった時点で以下のコードでメモリを解放すればOKです。
m_OwnerDrawListBox.Destroy();
ところが、COwnerDrawListBoxには2つほど問題がありました
- SetTextPositionとSetIconPositionで両方を同じ側にした場合の動作
- VS2005で動作させると実行時エラーを起こす
1の方は仕様かも知れませんが…アイコンを左側、テキストを右側にしたかったので設定するとテキストが右寄せになってしまいます。わたしは、右寄せは嫌だったので両方左側に指定してみました。すると、テキストとアイコンが左側で重なってしまいました
たぶん、これも仕様なのでしょう。
でも、それ以上の細かな位置制御はなかったので結局…COwnerDrawListBox::DrawItemメソッド中の右寄せをしている以下の部分を変更しました。
// pDC->DrawText(pListDataItem->strItemData, // strlen(pListDataItem->strItemData), // rectText, // DT_RIGHT | DT_SINGLELINE | DT_VCENTER); pDC->DrawText(pListDataItem->strItemData, _tcslen(pListDataItem->strItemData), rectText, DT_SINGLELINE | DT_VCENTER);
ITEM_LEFT, ITEM_RIGHTで面倒な条件を組んでありますね
自分のやりたい位置制御がハッキリしているなら、思い切り書き直した方がよいかも知れません
次に2の方ですが…VS6でデバッグしている時は問題なかった(表面化しなかっただけですが)のですが、透明化の際にVS2005でデバッグ実行するとエラーになり見つかった問題です。同じくCOwnerDrawListBox::DrawItemメソッド中でのCDCクラスの扱いが良くないようです。
CListBox::DrawItem (MFC)の例に合わせて以下のように変更しました。
// CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); CDC dc; dc.Attach(lpDrawItemStruct->hDC); CDC *pDC = &dc; ... // pDC->Detach(); dc.Detach();
何だか最終的にはCOwnerDrawListBox::DrawItemメソッドを書き直しちゃったので、使う意味はなかったかも知れません。DrawItemメソッドがほとんど全てですし
できあがったタスク切替のイメージは以下のような感じです

TrackBack URL :
