MFC、VS2008
CListCtrlを使って、チェックボックス付きのリストを作成しています。
そこで、アイテムを追加したあと部分的にグレーアウトさせ
チェックボックスを固定させたいと思っています。
※イメージとして、↓のサイトの一番したの画像のような感じです
http://www.g-ishihara.com/mfc_lb_03.htm
このサイトのように、CCheckListBoxを使うとカラム表示が出来ないようなので
CListCtrlを使っています。
CListCtrlでもチェックボックス付きのアイテムを部分的にグレーアウトさせることは
できないのでしょうか?
なかなかレスがつきませんねぇ(vv;)。
当該のサイトのリストボックスはオードローではありますが、その機能ではなく
WM_CTLCOLORLISTBOXに応答して、テキストの色を変更してます。
ですが、ListCtrlには、この方法は使えません。
この場合、リストコントロールにLVS_OWNERDRAWFIXEDを指定して、
CListCltl::DrawItem()をオーバーライドして描画するのが
最短距離だと考えます。
残念ながら、この場合、チェックボックスも自前で描画せざるを得ませんが、
DrawFrameControl()を使うと、誠に粗末なコントロールしか描画されないか
もしれません。
CHECKBOXコントロールをDisableにしたような表示がほしいということでしょうか。
もし、そうならば SDKですがこんな感じはいかがでしょうか。
NM_CUSTONDRAWで
int result = CDRF_DODEFAULT;
switch(nmcd->dwDrawStage)
{
case CDDS_PREPAINT:
result = CDRF_NOTIFYITEMDRAW;
break;
case CDDS_ITEMPREPAINT:
{
NMLVCUSTOMDRAW* nmlvcd = (NMLVCUSTOMDRAW*)lParam;
nmlvcd->clrText = GetSysColor(COLOR_GRAYTEXT);
result = CDRF_NOTIFYPOSTPAINT;
}
break;
case CDDS_ITEMPOSTPAINT:
{
NMCUSTOMDRAW* nmcd = (NMCUSTOMDRAW*)lParam;
RECT rc;
ListView_GetItemRect(hwndListView, nmcd->dwItemSpec,
&rc, LVIR_ICON);
// state iconのrectを計算(ここはいい加減です)
rc.right = rc.left;
rc.left = 0;
// iconの上を灰色で塗る
SetROP2(nmcd->hdc, R2_MERGEPEN);
HGDIOBJ hOld = SelectObject(nmcd->hdc,
GetSysColorBrush(COLOR_GRAYTEXT));
Rectangle(nmcd->hdc, rc.left, rc.top, rc.right, rc.bottom);
SelectObject(nmcd->hdc, hOld);
}
break;
}
return result; // ダイアログなら、DWL_MSGRESULT
}
アイコンを描いた後にグレイにしているので、ゆっくり動かすと
ボロが出ますが、まぁ、実用可と思います。
ご回答ありがとうございます。
SDKはまだあまり理解していないのですが、
これはどのように実装するのでしょう?
LRESULT CALLBACK WinProc とかに実装するのでしょうか?
MFCだと、CListCtrlから派生したクラスCMyListCtrlを作り、
CMyListCtrlのプロパティで=LVN_CUSTONDRAWを追加して、
CMyListCtrl::OnNMCustomDrawの中に入れてください。
私のコードの内、nmcdはpNMCDに、lParamはpNMHDRに置き換え、
return resultは、*pResult = resultに変えてください。
(このまま実行すると、全項目グレイかつマウスクリック可になります)
私の提示したコードは、グレイにするだけなので、
その他
1) 項目のEnable/Disableを項目から取り出す
2) 項目がDisableの時にはクリックを無効にする
のコードが必要になります。
MFCを使っていて既存のコントロールに処理を追加したり、
コントロールの動きをカスタマイズする場合、
元のクラスから派生したクラスを作成してイベントハンドラを
オーバーライドする事になります。
ロマさんが書かれているのが正にそれです。
この時、既存の動きも継承したい場合は親クラスの関数も呼ぶ等
ケースバイケースで考える必要があります。
で、作成した派生クラスのインスタンスを作成して
実際のコントロールと結び付けます。
この辺の手法は動作のカスタマイズを行う時の常套手段なので
詳しく調べて理解しておいた方が良いです。