リストビューをクリック・選択できないようにしたい – プログラミング – Home

リストビューをクリック・選択できないよ...
 
通知
すべてクリア

[解決済] リストビューをクリック・選択できないようにしたい


ボノ
 ボノ
(@ボノ)
ゲスト
結合: 13年前
投稿: 7
Topic starter  

環境:VS2008、MFC

リストビューを見せるだけにし、
クリックや選択を一切出来ないようにしたいのですが上手くできません。

TVN_ITEMCHANGINGと、NM_DBCLKをオーバーライドして
*pResult = TRUE;

としたのですが、
クリック後選択はされなくなったのですがクリックした瞬間に
一瞬青くなったのが見えてしまいます。

また、何度かクリックしてると点線の枠が見え
フォーカスが当たった状態になってしまいます。

クリックした際は、一切何も動作しないようにしたいです。

ネットも探してみたのですが思うような回答が見つからず困っています。
(探し方が悪いだけかもしれませんが)

どうかご助力、よろしくお願いします。


引用未解決
トピックタグ
瀬戸っぷ
 瀬戸っぷ
(@瀬戸っぷ)
ゲスト
結合: 18年前
投稿: 178
 

>TVN_ITEMCHANGINGと、NM_DBCLKをオーバーライドして
>*pResult = TRUE;

LVN_~ですよね?
無効にする…ってのは違いますかねぇ。
スクロールするような状態だと動かせなくなるし。


返信引用
ボノ
 ボノ
(@ボノ)
ゲスト
結合: 13年前
投稿: 7
Topic starter  

すいません、ツリービューの間違いでした


返信引用
ロマ
 ロマ
(@ロマ)
ゲスト
結合: 18年前
投稿: 170
 

TVN_ITEMCHANGINGはTVN_SELCHANGINGではないですか。

SDKだと
CreateWindowでTVS_DISABLEDRAGDROPをつければ
なんとかなりそうです。


返信引用
ボノ
 ボノ
(@ボノ)
ゲスト
結合: 13年前
投稿: 7
Topic starter  

TVS_DISABLEDRAGDROPをつけることで、
比較的要望通りの動作になりました。

ただ、左クリックのみで、右クリックは無効になっていません。
NM_RCLKやNM_RDBLCLKをオーバーライドして無効化してもだめでした。

右クリックの無効化はどうすればよいのでしょうか?


返信引用
ロマ
 ロマ
(@ロマ)
ゲスト
結合: 18年前
投稿: 170
 

派生クラスをつくって、OnRButtonDownを上書きするのはいかがでしょう。
まぁ、ここまでやるなら、TVS_DISABLEDRAGDROPは無視して、
OnLButtonDown,OnKeyDownなども上書きして、
ユーザー入力を全てつぶす方がよいかも知れません。

それとも、展開/折りたたみは残したいのでしょうか。
そうなると、キーボードで展開/折りたたみもできたほうが良いでしょうし、
選択はしないけれど、フォーカス枠は描かねばなりません。
そのためには、TVN_SELCHANGINGは扱わない、
NM_CUSTOMDRAWのCDDS_PREPAINTでCDRF_NOTIFYITEMDRAWを返し、
NM_CUSTOMDRAWのCDDS_ITEMPREPAINTで
NMTVCUTOMDRAWのclrText=GetSysColor(COLOR_WINDOWTEXT),
clrTextBk=GetSysColor(COLOR_WINDOW)にして、
CDRF_DODEFAULTを返すとうまくいくようです。


返信引用
ボノ
 ボノ
(@ボノ)
ゲスト
結合: 13年前
投稿: 7
Topic starter  

展開・折りたたみも必要ありません
マウス・キーボードともに一切動作しないようにしたいんです

やはり派生クラスを作ってみるしかないんでしょうか
やり方が良くわからないので、調べて勉強してみます

派生クラスについて、
MFCでの良い解説サイトとかあったら教えていただけると助かります!


返信引用
AR2
 AR2
(@ar2)
Estimable Member
結合: 5年前
投稿: 110
 

 単にフォーカスや選択状態の表示のみであれば、オーナードローで「フォーカス時」
「選択時」「通常時」と分岐させて描き分けているのを、全部「通常時」で描画するよ
うにすれば問題は解決しそうです。
 以前、私はこれで実現させたことがあります。

 マウスやキーボードの制御を全部無効にするのであればロマさんのおっしゃっている
通りのイベントプロシージャを記述すべきだと思います。
 具体的には
WM_KEYDOWN
WM_KEYUP
WM_LBUTTONUP
WM_LBUTTONDOWN
WM_LBUTTONDBLCLK
WM_RBUTTONUP
WM_RBUTTONDOWN
WM_RBUTTONDBLCLK
WM_MBUTTONUP
WM_MBUTTONDOWN
WM_RBUTTONDBLCLK
 のイベントを拾って潰してやれば良いと思います。

もしかすると
WM_XBUTTONシリーズ、WM_SYSKEYシリーズ、WM_CHARシリーズも容疑者になると思います
ので、このあたりは実験してみてください。

 あと派生クラスにした方がいろいろできますが、イベントを潰すだけなら派生クラス
にしなくても大抵は可能です。
 ただCTreeViewかCTreeCtrlや、Create等で生成したとか、ダイアログリソースに貼り
付けたとかで話が変わってくるので、どういう使い方をしている「ツリービュー」なの
かを明確にした方が的確なアドバイスがもらえると思います。


返信引用
ボノ
 ボノ
(@ボノ)
ゲスト
結合: 13年前
投稿: 7
Topic starter  

やろうとしているのは、ダイアログにCTreeCtrlを貼り付ける方法です。
キーやマウスを効かないようにしたい理由は、
ツリービューを参考図のように表したいからです。

派生クラスを少し調べてみたところ、
希望通りの動作が実装できました。

WM_KEYDOWN
WM_KEYUP
WM_LBUTTONUP
WM_LBUTTONDOWN
WM_LBUTTONDBLCLK
WM_RBUTTONUP
WM_RBUTTONDOWN
WM_RBUTTONDBLCLK
WM_MBUTTONUP
WM_MBUTTONDOWN
WM_RBUTTONDBLCLK

まさに、このイベントを使いました。
ちなみに、UP系のイベントは入れてないのですがこれも入れたほうが良いのでしょう
か?
入れなくても、現在のところ上手く動いているので大丈夫かな、と。
DOWNを殺してるからUPも反応しないのでしょうか?

>イベントを潰すだけなら派生クラスにしなくても大抵は可能です。
今回使ったイベントは、派生クラスにしなくても可能なのでしょうか?
ダイアログに張ったCTreeCtrlのイベントを見ても、このイベントは見当たらなかったの
で・・・
今回は派生クラスを使いますが、今後の勉強のために教えてください。


返信引用
AR2
 AR2
(@ar2)
Estimable Member
結合: 5年前
投稿: 110
 

 VS2008はクラスウィザードが使いにくかった気がするので、サンプルを書いておきま
す。
 分かりにくいですが重要なのは、メッセージマップに登録するマクロの記述でして、
いろんな種類があるので調べてみてください。

ヘッダファイル
public:
afx_msg void OnClickKill(NMHDR *pNMHDR, LRESULT *pResult);

メッセージマップ登録
BEGIN_MESSAGE_MAP(CdlgtestDlg, CDialogEx)
ON_NOTIFY(NM_CLICK, IDC_TREE1, OnClickKill)←全部同じ関数を呼んでる
ON_NOTIFY(NM_DBLCLK, IDC_TREE1, OnClickKill)
ON_NOTIFY(NM_RCLICK, IDC_TREE1, OnClickKill)



END_MESSAGE_MAP()

関数本体
void CdlgtestDlg::OnClickKill(NMHDR *pNMHDR, LRESULT *pResult){
・・・
}

 あと今回のように同じような処理の冗長な記述を嫌うなら、仮想関数の
PreTranslateMessage()などを用いて、ツリー宛のメッセージを横取りして、まとめてメ
ッセージを受信/処理しても良いでしょう。


返信引用
AR2
 AR2
(@ar2)
Estimable Member
結合: 5年前
投稿: 110
 

>入れなくても、現在のところ上手く動いているので大丈夫かな、と。
>DOWNを殺してるからUPも反応しないのでしょうか?

 UPとDOWNはセットなので一緒に書きましたが、不要であれば書く必要はないと思いま
す。
 それはボノさんが判断してください。
 (メッセージが届いているかを見るにはspyなどのVSに付属しているツールなどを使う
と良いです)

 個人的には、マウスジェスチャや右クリックメニューなど、UPしか拾ってないケース
を扱うことが多々あるので記述することが多いです。


返信引用
ロマ
 ロマ
(@ロマ)
ゲスト
結合: 18年前
投稿: 170
 

> ちなみに、UP系のイベントは入れてないのですがこれも入れたほうが良いのでしょう
か?

msdnで
MSDN
MSDN Library
Windows Development
Windows Application UI Development
Windows Controls
ControlLibrary
Tree View
Tree-View Controls Overviews
About Tree-View Controls
このページの
Default Tree-View Control Message Processing
の項を参考にしてください。
ただし、時々漏れがあるので、実験が必要です。


返信引用
ボノ
 ボノ
(@ボノ)
ゲスト
結合: 13年前
投稿: 7
Topic starter  

>ARさん
NM_CLICKとかのイベントはCTreeCtrlのイベントで見つかったのですが、
WM_LBUTTONUPとかのイベントは見つからなかったので、これらを
派生クラス化なしでやる方法があるのかな・・・と思ったんですが
やっぱり無理そうなんですかね?

全部同じ関数に出来るのは知らなかったので、今後の参考にさせてもらいます

とりあえず、UPのイベントは今回は必要なさそうなのでなしにすることにしました

>ロマさん
英語を解読する暇がないので、時間のある時に翻訳しながら勉強してみます
こういうのをさらっと紹介してくるってことは、皆さん英語バリバリなんでしょう
か・・・?


返信引用
ボノ
 ボノ
(@ボノ)
ゲスト
結合: 13年前
投稿: 7
Topic starter  

とりあえず、解決としておきます
皆さん、ご助言ありがとうございました


返信引用
ロマ
 ロマ
(@ロマ)
ゲスト
結合: 18年前
投稿: 170
 

解決済みだけど、自己レスです。

> まぁ、ここまでやるなら、TVS_DISABLEDRAGDROPは無視して、
> OnLButtonDown,OnKeyDownなども上書きして、
> ユーザー入力を全てつぶす方がよいかも知れません。

OnNcHitTestを上書きして、HTTRANSPARENTを返すほうが簡単です。

ついでながら、派生クラスを作らない方法だと、以下でうまくいきそうです。

NM_CUSTOMDRAW CDDS_PREPAINTでCDRF_NOTIFYITEMPAINTを返し、
NM_CUSTOMDRAW CDDS_ITEMPREPAINTで
 uItemState = 0; // フォーカス枠を描かない
// TVIS_SELECTED,TVIS_DROPHILITEDで色を変えない
// (ドラッグしたときの青色はTVIS_DROPHILITEDの色です)
NMTVCUSTOMDRAW* nmtvcd = nmtvcd = (NMTVCUSTOMDRAW*)lParam;
nmtvcd->clrText = GetSysColor(COLOR_WINDOWTEXT);
nmtvcd->clrTextBk = GetSysColor(COLOR_WINDOW);
return CDRF_DODEFAULT;
TVN_EXPANDINGでTRUEを返す

ダイアログだと、WS_TABSTOPをはずしてください。
MFCでフレームのクライアントにTreeViewを貼り付けている場合は、
フレームからTreeViewにSetFocusされるかもしれないので、
対策してください。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

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