CTreeCtrlの非選択状態 – プログラミング – Home

通知
すべてクリア

[解決済] CTreeCtrlの非選択状態


DIO
 DIO
(@DIO)
ゲスト
結合: 18年前
投稿: 62
Topic starter  

VS2005 MFC_SDI WinXP

いつもお世話になります。

チェックボックスとアイコンつきの
CTreeCtrl(正確にはCTreeView)があります。
質問は2点

1.TreeCtrlのアイテムを、操作できなくしたい。

つまり特定のアイテムをチェックボックスを含めて、
CEdit ed;
ed.EnableWindow(false)
のようなことがしたいです。

具体的には、任意のフォルダとその中にあるファイルが
ツリーに読み込まれていて、
親のフォルダのチェックをはずすと、そのサブアイテム全部を
非選択状態?(操作できない)ようにしたいのです。

2.チェックを含めた保存

チェックの状態を含めて、ファイルにツリーを保存し、
読み込んで復元したいのですが、いい方法が浮かびません。
皆さんならどういう方法で実装しますか?

以上、よろしくお願いします。

# http://oshiete1.goo.ne.jp/qa3043530.html
#教えてgooではレスが付かず、こっちに来ました。
#無効は閉じますのでよろしくお願いします。


引用未解決
トピックタグ
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

前者だけ。

1. CTreeViewクラスのNM_CLICKイベントをハンドリングし、
以下のコードを記述。

void CXXXXX::OnClick(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
NMTREEVIEW *pNMTree = (NMTREEVIEW*)pNMHDR;
CTreeCtrl& tree = this->GetTreeCtrl();
TVHITTESTINFO ht = {0};
DWORD pos = ::GetMessagePos();

ht.pt.x = LOWORD(pos);
ht.pt.y = HIWORD(pos);
::MapWindowPoints(HWND_DESKTOP, pNMHDR->hwndFrom, &ht.pt, 1);
tree.HitTest(&ht);

if (ht.hItem)
{
HTREEITEM hParent = tree.GetParentItem(ht.hItem);
if (hParent && !tree.GetCheck(hParent))
{
*pResult = TRUE; // TRUE(!=0)にすると選択状態にならない
return;
}
}

// チェックボックスクリックイベント
if (TVHT_ONITEMSTATEICON & ht.flags)
tree.Invalidate();

*pResult = 0;
}

2. (選択できないぽく見せるため、ノードのテキストをグレイにするため)
CTreeViewクラスの NM_CUSTOMDRAWイベントをハンドリングし、
以下のコードを記述。
※カスタムドローではチェックボックスの表示まで変更できない。

void CXXXXX::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMTVCUSTOMDRAW lpCustomDraw = (LPNMTVCUSTOMDRAW)pNMHDR;
CTreeCtrl& tree = this->GetTreeCtrl();
HTREEITEM hParent;

switch (lpCustomDraw->nmcd.dwDrawStage)
{
case CDDS_PREPAINT:
*pResult = CDRF_NOTIFYITEMDRAW;
return;
case CDDS_ITEMPREPAINT:
case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
hParent = tree.GetParentItem((HTREEITEM)lpCustomDraw->nmcd.dwItemSpec);
// 親にチェックが入っていないか
if (hParent && !tree.GetCheck(hParent))
lpCustomDraw->clrText = ::GetSysColor(COLOR_GRAYTEXT);
return;
}
*pResult = 0;
}

親のチェックボックスのチェックをはずしたとき、このチェックをはずす場合は
http://hpcgi1.nifty.com/MADIA/Vcbbs/wwwlng.cgi?print+200610/06100043.txt
を参考にOnClickを変更してください。(条件は逆になる)


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

後者は
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200607/06070041.txt
を参考にしてみてください。

ただ、PreCreateWindowでスタイル変更しOnInitialUpdateで表示させようとすると
初回だけ、SetCheckが成功しないようです。(原因はわからないです)


返信引用
DIO
 DIO
(@DIO)
ゲスト
結合: 18年前
投稿: 62
Topic starter  

Blueさん

返信ありがとうございます。

なるほど~
マウスのヒットテストでアイテムを持ってきて
制御するのですね。

ひとつわからないのですが
case CDDS_PREPAINT:
*pResult = CDRF_NOTIFYITEMDRAW;
return;

はどうして必要なのでしょうか?
コメントアウトすると動かなくなるので、
必要だということぐらいしか・・・

多分、
*pResult

が何をしているかわかってないからだと思いますが。

それに関連して、
*pResult = TRUE; // TRUE(!=0)にすると選択状態にならない

といった情報はどういう方法で手に入れるのでしょうか?

質問ばかりですが、
よろしくおねがいします。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

NM_CUSTOMDRAW Message
http://msdn2.microsoft.com/en-us/library/ms672574.aspx
をよんでみてください。

> *pResult = TRUE; // TRUE(!=0)にすると選択状態にならない
は、ちょっと試してみたら※できただけで、確証はなかったです。
(らしいをつけておいたほうが良かったですね。)

※リストビューのときに選択させないという処理は、LVN_CHANGINGで*pResultに
TRUEを入れるから、TRUEを入れればできるかなと。
関連スレ)CListCtrlで選択行だけを選択不可にするには?
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200607/06070085.txt


返信引用
DIO
 DIO
(@DIO)
ゲスト
結合: 18年前
投稿: 62
Topic starter  

>Blueさん

返信ありがとうございます。

えーっと、
CDDS_PREPAINTはTreeViewの書き換えの前に送られてきて、
もし、0をかえすと、サブアイテムに描写前にメッセージが飛んでこない。

今回はサブアイテムの描画を変更したいので、
CDRF_NOTIFYITEMDRAW をかえして、

メッセージを飛ばしてもらってる。
であってますか?

おかげさまで、少し理解がすすみました。
ありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました