リストビューの標準/拡張スタイルの併用について

[戻る]
ふぁいと! 2002/09/17(火) 09:59:02
いつもお世話になっております。
質問なのですがリストビューの標準スタイルと拡張スタイルの設定の併用ができない
ことで悩んでいます。
以下のソースのようにOnInitialUpdate()内でリストにアイテムを挿入した後
標準スタイルでラベルの編集を有効にし(ModifyStyle)、拡張スタイルであらかじめ
ダブルクリック等の処理を有効にしています(SetExtendedStyle)。
ですが、ラベル編集が有効になりません。SetExtendedStyleをコメント化
するとラベル編集が有効になるのですが・・・
どなたかよい方法をご存知の方ご教授お願いします。


環境 Win2000(SP3)
     VC++6.0(SPなし)
     MFC

void CXXXXXX::OnInitialUpdate() 
{
 //リストビューを作成する処理
 ・・・・

 // 以下のLVS_EDITLABELSがきかない!SetExtendedStyleをコメントすると使える
 // 標準のリストビュースタイル(LVS_系)は ModifyStyle で設定
 m_cListctrl1.ModifyStyle(0,LVS_EDITLABELS);

 // リストビュー拡張スタイル(LVS_EX系)は SetExtendedStyle で設定
 m_cListctrl1.SetExtendedStyle(LVS_EX_FULLROWSELECT |        
        LVS_EX_TWOCLICKACTIVATE |
        LVS_EX_INFOTIP              
        );

 long state;

 // 指定されたウィンドウに関する情報を取得
 state = ::GetWindowLong(m_cListctrl1.GetSafeHwnd(),GWL_STYLE);
 // 指定されたウィンドウの属性を変更
 ::SetWindowLong(m_cListctrl1.GetSafeHwnd(),GWL_STYLE, (state & ~LVS_TYPEMASK)
               | LVS_REPORT);    
}

dairygoods 2002/09/17(火) 15:46:33
確かに、編集できなくなりますね。

だたし、CListCtrl::EditLabel()は機能するようです。
自分でNM_CLICKを処理するなどして、
EditLabelを呼んでやればよいでしょう。面倒ですが。


ちなみに、こんな風にできます。
m_cListctrl1.ModifyStyle(LVS_TYPEMASK,LVS_EDITLABELS|LVS_REPORT);

ふぁいと! 2002/09/17(火) 19:14:34
[[解決]]
dairygoodsさんどうもありがとうございます。
早速試してみましたがうまくいきませんでした。
理由はOnInitialUpdate() でリストビュー拡張スタイルの設定を
しているSetExtendedStyleの中のLVS_EX_TWOCLICKACTIVATEでした。
これをコメントすると教えていただいた処理でうまくいきました。
でもなぜなんだろう?

    // リストビュー拡張スタイル(LVS_EX系)は SetExtendedStyle で設定
    m_cListctrl1.SetExtendedStyle(
        LVS_EX_FULLROWSELECT |    // 列全体強調表示
// コメント    LVS_EX_TWOCLICKACTIVATE |    // 予めダブルクリックに対応
        LVS_EX_INFOTIP          // ツールチップ
        );


しかしこれではアイテムをクリックしたとき等にアイテムのインデックスを取得できなく
なるので(常に-1が返る)、GetFirstSelectedItemPosition()で取得する。

void CXXXX::OnDblclkList1(NMHDR* pNMHDR, LRESULT* pResult) 
{
 // 現在のホットアイテムのインデックスを返す
 int nIndex = m_cListctrl1.GetHotItem();                
        
 if (nIndex == -1)
 {
  // リストビューコントロールで最初に選択されたアイテムの位置をPOSITION値で取得
  POSITION pos = m_cListctrl1.GetFirstSelectedItemPosition();
  if (pos != NULL)
  {
    // 16進→10進に変換。インデックスは0から始まるため-1
    nIndex = (int)pos - 1;
  }
 }
 // アイテムのテキストを返す
 CString strItemText = m_cListctrl1.GetItemText(nIndex, 0);        

 *pResult = 0;
}


もっとうまいやり方があるのかもしれませんが、とりあえずソースを
書いておきました。
dairygoodsさんどうもありがとうございました。
今後ともよろしくお願いします。

dairygoods 2002/09/18(水) 10:31:47
void CXXXX::OnDblclkList1(NMHDR* pNMHDR, LRESULT* pResult) 
{
   int idx = m_cListctrl1.GetNextItem(-1, LVNI_SELECTED);
   m_cListctrl1.EditLabel(idx);
}

たとえば、こんな風にすれば LVS_EX_TWOCLICKACTIVATE を指定しても
編集モードになりませんか?
(もうちょっと凝った処理をしないと不自然な動きですけど)

ふぁいと! 2002/09/18(水) 12:44:01
dairygoodsさんありがとうございます。
なるほどこんな方法もあるのですね。しかしダブルクリック時には別の処理を
考えているので、そこでのEditLabelはまた次回つかわさせていただきます。
m_cListctrl1.GetNextItem(-1, LVNI_SELECTED);の処理は早速いただきました!

ところでまた質問なのですが・・・([解決]してしまったのでスレッド変えたほうが
よいのでしょうか?)
リストビューのラベル編集後の処理でアイテム名の同名が存在する時など再編集するように
しているのですが、EditLabelの戻り値がNULL(CEdit hWnd=???)になりBeginlabeleditに
飛んでくれません。(同じ処理でツリービューはうまくいくのですが)
なにかご存知でしたらお教えください。

void CFORM_ENVFILE::OnEndlabeleditList1(NMHDR* pNMHDR, LRESULT* pResult) 
{

 if (・・・・){
   // アイテム名の変更に失敗した場合
   // もう一度編集状態にする
   m_cListctrl1.EditLabel(nIndex);    
   return;
  }
}

古いスレッドには追加発言できません。