none
MFC リストコントロール オーナードローのやり方 RRS feed

  • 質問

  • お世話になります。

    今回、イメージリストへのソート機能を実装しようと考えています。

    ソート前のリストの選択状態を、ソート後のリストへ反映させるのが狙いです。

    別サイトで情報を集めた結果、オーナードローを行えば、今回の実装しようとしている事が出来そうだという事が分かりました。

    ただ、オーナードロー(OnDrawItem)のイベントに処理が入って来ません・・・。

    そこで、どうやればいいのか、ご教授頂きたく質問をさせて頂きました。

    今回自分でやった事は、下記2点です。

    PreCreateWindow()の追加

    OnDrawItemの追加

    ただ、この方法だと、OnInitDialogで呼び出す場合には、PreCreateWindow()には入ってこないという事です。

    自分が調べた情報では、オーナードローのやり方が違うのだと思いますが、調べる情報はどれも同様のやり方です。

    よろしくお願いいたします。

    2015年11月20日 12:27

回答

  • 質問の内容に一部不明な点があるので、
    まずは、基本的な内容だけを説明してみます。

    1.リストコントロールの「カスタムドロー」とは、リストから送られるWM_NOTIFYメッセージの
     NM_CUSTOMDRAWに応答して描画する処理を言います。
     レポート(LVS_REPORT)でも、アイコン(LVS_ICON)でも可能なようです。

    2.リストコントロールの「オーナードロー」とはLVS_OWNERDRAWFIXEDスタイルを指定した
     リストコントロールで、かつレポート(LVS_REPORT)形式でしか動作しません。
     WM_DRAWITEM メッセージに応答して描画します。MFCの場合virtual void DrawItem( LPDRAWITEMSTRUCT lpDIS)
     をオーバーライドします。

    次にリストコントロールの構築方法ですが、親がDLGの場合一般に2つの方法が考えられます。

    3.ダイアログリソースに記述して自動的に構築した場合には、
      WM_INITDIALOGで当該のリストコントロールをGetDlgItem()して取得します。
     リソースには先に説明したスタイルをあらかじめ指定しておく必要があります。
     MFCの場合はDoDataExchange()内でCListCtrl型のメンバーに取得します。

    4.ダイアログリソースに記述しない場合は、構築する必要があります。
     CreateWindowEx()で構築する場合、先に説明したウインドウスタイルを指定する必要があります。
     MFCの場合にはCListCtrl::CreateEx()を使用する必要があります。
     スタイルの指定に関しては同じです。

    以上の説明にあるキーワードなどを使って調べてみてはどうでしょう。


    2015年11月24日 5:15

すべての返信

  • たぶんMFCのダイアログベースアプリのことだと思いますが、質問するときは開発環境やターゲット環境のバージョンなどをきちんと詳しく書きましょう。フォーラムの回答者はエスパーではありません。

    オーナードローを有効にするためには、Visual C++リソースビューで当該リストコントロールの[Owner Draw Fixed]設定をTrueに変更してやる必要があります(コントロールの作成時にLVS_OWNERDRAWFIXEDスタイルを指定することに相当します)。おそらく「調べた情報」というのは、ダイアログ上のCListCtrlに関する方法ではなく、SDI/MDI上のCListViewに関する方法だと思われます。MFCは決してWin32初心者用のGUIフレームワークではなく、Win32をある程度知り尽くしている人が効率的に開発するための中級者・上級者向けライブラリなので、Win32 APIの内情を知らない人にはかなり厳しいと思います。

    ただ、「リストの選択状態をソート前後で保持する」といった単純な目的であれば、オーナードローのような大仰なことをする必要があるとは思えません。オーナードローではなく、リストの仮想化(LVS_OWNERDATA)だけで十分対応できると思います。仮想化に関しては自分で調べてみてください。

    2015年11月21日 16:38
  • 質問の内容に一部不明な点があるので、
    まずは、基本的な内容だけを説明してみます。

    1.リストコントロールの「カスタムドロー」とは、リストから送られるWM_NOTIFYメッセージの
     NM_CUSTOMDRAWに応答して描画する処理を言います。
     レポート(LVS_REPORT)でも、アイコン(LVS_ICON)でも可能なようです。

    2.リストコントロールの「オーナードロー」とはLVS_OWNERDRAWFIXEDスタイルを指定した
     リストコントロールで、かつレポート(LVS_REPORT)形式でしか動作しません。
     WM_DRAWITEM メッセージに応答して描画します。MFCの場合virtual void DrawItem( LPDRAWITEMSTRUCT lpDIS)
     をオーバーライドします。

    次にリストコントロールの構築方法ですが、親がDLGの場合一般に2つの方法が考えられます。

    3.ダイアログリソースに記述して自動的に構築した場合には、
      WM_INITDIALOGで当該のリストコントロールをGetDlgItem()して取得します。
     リソースには先に説明したスタイルをあらかじめ指定しておく必要があります。
     MFCの場合はDoDataExchange()内でCListCtrl型のメンバーに取得します。

    4.ダイアログリソースに記述しない場合は、構築する必要があります。
     CreateWindowEx()で構築する場合、先に説明したウインドウスタイルを指定する必要があります。
     MFCの場合にはCListCtrl::CreateEx()を使用する必要があります。
     スタイルの指定に関しては同じです。

    以上の説明にあるキーワードなどを使って調べてみてはどうでしょう。


    2015年11月24日 5:15
  • sygh 様

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

    開発環境やターゲット環境について、今後記載するようにします。

    又、リストの仮想化の件、調べてみようと思います。ありがとうございました。

    2015年11月24日 6:45
  • 基本的な部分、ご説明ありがとうございます。

    自分自身、理解していなかった部分が多々ありました。

    オーナードロー・カスタムドローと、区別が分かりました。

    キーワード検索を行った所、オーナードローよりもカスタムドローの方が、今回は適していると思い実装してみました。

    その所、やはりオーナードローで実装が可能そうです。

    大変助かりました。ありがとうございます。

    2015年11月24日 6:52