一旦「1行選択」にしたリストビューを、「複数行選択」に戻すには

解決


三角おむすび  2008-04-13 13:01:18  No: 68008

.NET2008 VISTA MFC です。

リストビューで、デフォルトが複数行選択で、1行選択にするには、

LONG dwStyle = GetWindowLong(m_list1.GetSafeHwnd(), GWL_STYLE);
dwStyle |= LVS_SINGLESEL; 
SetWindowLong(m_list1.GetSafeHwnd(), GWL_STYLE, dwStyle);

でいい、というところまでは分ったのですが、

では、一旦「1行選択」にしたリストビューを、「複数行選択」に戻すにはどうしたらいいのでしょうか。

いろいろなキーワードで「くぐって」みたのですが、見つかりません。

アドバイスをお願いします。


夏みかん  2008-04-13 17:39:41  No: 68009

> いろいろなキーワードで「くぐって」みたのですが、見つかりません。
検索せずに LVS_SINGLESEL ビットをリセットすればいいだけだよ。

// 複数行選択から1行選択にする場合
LONG dwStyle = GetWindowLong( m_list1.GetSafeHwnd(), GWL_STYLE );
dwStyle &= |LVS_SINGLESEL; 
SetWindowLong( m_list1.GetSafeHwnd(), GWL_STYLE, dwStyle );
SetWindowPos( m_list1.GetSafeHwnd(), NULL, 0, 0, 0, 0,
  (SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED) );

あと動的にスタイルを変更するときには
SetWindowPos 関数に SWP_FRAMECHANGED を
指定して呼び出す必要があると思うので記述する。

ちなみに拡張スタイルならマクロ関数を使って変更します。
http://www.kumei.ne.jp/c_lang/sdk2/sdk_198.htm
ListView_GetExtendedListViewStyle(hwndLV)
ListView_SetExtendedListViewStyle(hwndLV, dw)


夏みかん  2008-04-13 17:41:17  No: 68010

訂正。

誤)
dwStyle &= |LVS_SINGLESEL;

正)
dwStyle &= ~LVS_SINGLESEL;

ビットORじゃなかった。
打ち間違っていました。


三角おむすび  2008-04-13 23:55:19  No: 68011

夏みかんさん、ありがとうございます。

LONG dwStyle = GetWindowLong( m_list1.GetSafeHwnd(), GWL_STYLE );
dwStyle &= ~LVS_SINGLESEL;
SetWindowLong( m_list1.GetSafeHwnd(), GWL_STYLE, dwStyle );

で、動的に変更できているように見えます。
(5回1行選択と、複数行選択を繰り返しましたが、エラーにはなりませんでした)

SetWindowPos( m_list1.GetSafeHwnd(), NULL, 0, 0, 0, 0,
  (SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED) );

を追加すると、

CWnd::SetWindowPos' : 関数に 7 個の引数を指定できません。

というエラーになります。

「SetWindowPos 関数に SWP_FRAMECHANGED を指定して呼び出す」
「拡張スタイルならマクロ関数を使って変更」
は、初心者で、まだよく理解できていません。

最初の3行だけでは、後々、何か問題が起こるのでしょうか。

お手数ですが、アドバイスをお願いいたします。


夏みかん  2008-04-14 00:25:45  No: 68012

> SetWindowPos
この関数名にはAPIの関数とMFCの関数と2つあります。
MFC の場合は引数の個数が違うのでエラーになりました。

APIの SetWindowPos を呼び出すには :: とつけないといけませんでした。

LONG dwStyle = ::GetWindowLong( m_list1.GetSafeHwnd(), GWL_STYLE );
dwStyle &= ~LVS_SINGLESEL;
::SetWindowLong( m_list1.GetSafeHwnd(), GWL_STYLE, dwStyle );
::SetWindowPos( m_list1.GetSafeHwnd(), NULL, 0, 0, 0, 0,
  (SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED) );
です。

> 最初の3行だけでは、後々、何か問題が起こるのでしょうか。
APIマニュアルには動的にスタイルを変更するとき SetWindowPos に
SWP_FRAMECHANGED を付けて呼び出せと書かれている。

だから呼び出したほうが良いと思う。
なお MFC なら ModifyStyle 関数がありませんか?
動的にスタイルを変える場合はこの関数と使えば良いと思う。

m_list1.ModifyStyle( LVS_SINGLESEL, 0, (SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER) );

こんな感じかな。


三角おむすび  2008-04-14 11:30:42  No: 68013

夏みかんさん、ありがとうございます。

m_list1.ModifyStyle( LVS_SINGLESEL, 0, (SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER) );

で、いきます。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加