none
リストコントロールでのソートの仕方 RRS feed

  • 質問

  • お世話になっております。

    MFCでダイアログベースで開発をしております。OSはXPです。

    リストで表示されているファイルをソートしたいと考えています。

    フォルダを監視して、そこにファイルが入ってきたらリストにファイル名を表示するといった感じのプログラムです。

    現在は、一番最初に入ってきたものが一番上段で表示されているのですが、一番最後に入ってきたものが一番上段で表示されるようにするためには、どのようにしたらよいのでしょうか?

    SortItemというメソッドは見つけたのですが使い方がいまいちわかりません。

    SortItemをつかってできるのか、はたまた別の方法のほうがよいのか?

    ご教授願えないでしょうか?よろしくお願いします。

    2007年1月26日 16:49

回答

  • まず、C言語の関数ポインタは理解されているでしょうか?これがわかっていないとあの説明はちょっとわかりづらいです。Win32 APIのEnum系の関数などでも多く使用します。

    SortItemは引数に比較用の関数のアドレスを渡します。この渡す関数のアドレスをburuさんが定義します。CListCtrl::SortItemは渡された比較用の関数を呼び出して、その戻り値に応じて、再描画を行います。たとえば、比較用の関数をburuさんがこんな形で作ります。

    int CALLBACK buruCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)

    {

      //中は自分で考える

    }

    この比較用関数はstaticなメンバか、もしくはグローバル(いわゆるCの外部参照可能な関数)でなくてはなりません。

    lParam1,lParam2にはLVITEM構造体のlParamメンバで指定した値が入ります。buruさんがLVITEM.lParamの値をフォルダに追加された順に値を加算しているのであれば、単純にlParam1とlParam2の比較でいいでしょう。

    2007年1月27日 4:24
  • buruさん

    もし、入ってきたときに表示をしているのであれば以下の方法で、常に入ってきたファイル名を一番上に表示することができます。

        LVITEM   mylvItme;
       
        mylvItem.iItem = 0;

    として ".InsertItem(&mylvItem)とすれば一番上に表示することができます。

    2009年6月16日 2:15
  • SortItemと言う関数は何らかの情報を元にアイテムをソートする事が目的になります。
    従って一番最後に入ってきた物と言う条件でソートしたいのであれば、そういう順番になるように
    する為にはどんな情報が必要かと言うところから考える必要があります。

    単純に最後に追加したアイテムを最上段にしたいだけならB_Wolfさんが書かれているように
    InsertItemでアイテムを追加する位置を先頭にすれば良いだけです。
    この場合、リストコントロールのソートはしない設定にしておく必要があります。
    CListCtrl::InsertItemの説明をよく読んで見てください。
    自ずと使い方が見えてくると思います。
    逆にそういう使い方が見えてくるまで関数の仕様をよく理解するようにした方が良いです。

    解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。
    2009年6月16日 9:36

すべての返信

  • まず、C言語の関数ポインタは理解されているでしょうか?これがわかっていないとあの説明はちょっとわかりづらいです。Win32 APIのEnum系の関数などでも多く使用します。

    SortItemは引数に比較用の関数のアドレスを渡します。この渡す関数のアドレスをburuさんが定義します。CListCtrl::SortItemは渡された比較用の関数を呼び出して、その戻り値に応じて、再描画を行います。たとえば、比較用の関数をburuさんがこんな形で作ります。

    int CALLBACK buruCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)

    {

      //中は自分で考える

    }

    この比較用関数はstaticなメンバか、もしくはグローバル(いわゆるCの外部参照可能な関数)でなくてはなりません。

    lParam1,lParam2にはLVITEM構造体のlParamメンバで指定した値が入ります。buruさんがLVITEM.lParamの値をフォルダに追加された順に値を加算しているのであれば、単純にlParam1とlParam2の比較でいいでしょう。

    2007年1月27日 4:24
  • buruさん

    もし、入ってきたときに表示をしているのであれば以下の方法で、常に入ってきたファイル名を一番上に表示することができます。

        LVITEM   mylvItme;
       
        mylvItem.iItem = 0;

    として ".InsertItem(&mylvItem)とすれば一番上に表示することができます。

    2009年6月16日 2:15
  • SortItemと言う関数は何らかの情報を元にアイテムをソートする事が目的になります。
    従って一番最後に入ってきた物と言う条件でソートしたいのであれば、そういう順番になるように
    する為にはどんな情報が必要かと言うところから考える必要があります。

    単純に最後に追加したアイテムを最上段にしたいだけならB_Wolfさんが書かれているように
    InsertItemでアイテムを追加する位置を先頭にすれば良いだけです。
    この場合、リストコントロールのソートはしない設定にしておく必要があります。
    CListCtrl::InsertItemの説明をよく読んで見てください。
    自ずと使い方が見えてくると思います。
    逆にそういう使い方が見えてくるまで関数の仕様をよく理解するようにした方が良いです。

    解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。
    2009年6月16日 9:36
  • こんにちは、フォーラムオペレーターの高橋春樹です。

    KKamedgawaさん、B_Wolfさん、PATIOさん、こんにちは。
    アドバイスありがとうございました。

    buruさん、こんにちは。
    MSDNフォーラムのご利用ありがとうございます。

    質問の投稿から、だいぶ時間が経っているのですが、
    皆様と情報を共有する為に、
    KKamedgawaさん、B_Wolfさん、PATIOさんから頂いたアドバイスに
    回答マークを付けさせてもらいました。

    今後ともMSDNフォーラムをよろしくお願いします。


    マイクロソフト株式会社 フォーラム オペレータ 高橋春樹
    2009年6月25日 7:21