none
CListCtrlのアイテム選択時のテキスト矩形の取得について RRS feed

  • 質問

  • お世話になります。

     

    CListCtrlのアイテム選択時に

    「アイコン」と「テキスト」が青く反転表示されると思いますが、

    このテキストの部分の矩形を取得することは可能でしょうか?

     ※フォーカスの矩形でもあります

     

    CListCtrlの GetItemRect や GetSubItemRect で試した結果、

    意図する矩形が取得できませんでした。

    自前で計算しようかとも思ったのですが、

    ビューの設定(詳細/アイコン/タイル/リスト)を切替できるようにしているため

    同じアイテムでも計算方法を変更する必要があるのではないかと思いました。

     

    もし標準の方法があれば、計算する必要もありませんので、

    ご存知であれば教えて頂けないでしょうか。

     

    開発環境は、VC2010(評価版) MFCです。

    2010年9月7日 5:33

回答

  • LVIR_BOUNDS、LVIR_ICON、LVIR_LABEL の何れを指定しても、
    意図した矩形にならない場合、自分は、そのどれかで取得した矩形を
    元に、自前で算定してます。  例えば
    LVS_REPORT時に、指定カラムだけを再描画したいが、
    ボーダーを含めたくない場合等にやってます。まぁカットアンドトライですけどね(vv;)。
    • 回答としてマーク target_3to4 2010年9月10日 4:59
    2010年9月7日 7:38
  • >詳細/タイル/リスト

    自分で計算する必要がありますね。

     

    ・LV_VIEW_LIST/LV_VIEW_DETAILS

    Viewの種類やStyle等により、応用や調整が必要かもしれません。

    便宜上、求めるフォーカスの矩形をFocusRect、その幅をFocusWidthとします。

    1.GetItemRect(LVIR_LABEL)でLabelRect取得

    2.GetStringWidth()でStringWidth取得

    3.FocusWidth = StringWidth + GetSystemMetrics(SM_CXFOCUSBORDER) * 2

    4.FocusWidthとLabelRectの幅を比較

    5-1.同等かFocusWidthの幅が大きい場合

      6.FocusRect = LabelRect

    5-2.LabelRectの幅が大きい場合

      7.FocusRect = LabelRect

      8.FocusRectの幅をFocusWidthにする

     

    ・LV_VIEW_TILE

    文字列を囲うようにFocusが表示されるため、CDCを利用して計算する必要がありますね。

    DrawTextやGetSystemMetrics(SM_CX(Y)FOCUSBORDER)で計算することになりそうです。

    Visual Styleが適用されている場合、DrawThemeTextを利用する必要があるか検証が必要です。

     

    >※LVS_ICON と LV_VIEW_ICON が厳密に同じなのかは確認していません。

    同じですよ。

    • 回答としてマーク target_3to4 2010年9月10日 4:59
    2010年9月8日 13:09

すべての返信

  • LVIR_BOUNDS、LVIR_ICON、LVIR_LABEL の何れを指定しても、
    意図した矩形にならない場合、自分は、そのどれかで取得した矩形を
    元に、自前で算定してます。  例えば
    LVS_REPORT時に、指定カラムだけを再描画したいが、
    ボーダーを含めたくない場合等にやってます。まぁカットアンドトライですけどね(vv;)。
    • 回答としてマーク target_3to4 2010年9月10日 4:59
    2010年9月7日 7:38
  • 仲澤@失業者 様

    前回に続き、ご回答ありがとうございます。

     

    やはり自前で計算するしかないようですね。

    ただ、リストで表示されているテキストは、

    文字列が長い場合、自動で折り返しや省略文字が使用されますので

    結構苦労しそうです。

    一度、CDCクラスで描画時のテキストのサイズなどを取得して、

    同じ矩形が取得できるか試してみたいと思います。

     

     

     

     

    2010年9月7日 9:02
  • LVS_ICONで試してみましたが、LVIR_LABELで取れますね。

    フォーカスあり

      Rect : left = 2, top = 53 , right = 127, bottom = 127 , Width = 125 , Height = 74

    フォーカスなし

      Rect : left = 2, top = 53 , right = 127, bottom = 79 , Width = 125 , Height = 26

     

    Itemの文字列が長いため、Height に差が出ていますね。

    これは意図する矩形とは異なるのでしょうか。

    それとも、特定の状況で意図する矩形にならないのでしょうか。

     

    PrintScreenで画面をCaptureして、画像アプリに貼り付けし、

    Rectの位置が正しいか確認しましたが、ぴったりの位置でしたよ。

    • 編集済み kozz 2010年9月7日 11:39 追記
    2010年9月7日 11:25
  • kozz 様

    ご回答ありがとうございます。

     

    私の場合は、ビューの種類をCListCtrl::SetViewで指定していますが、

    アイコン(LV_VIEW_ICON)の場合は、確かにぴったりの位置が取得できました。

     ※LVS_ICON と LV_VIEW_ICON が厳密に同じなのかは確認していません。

     

    ただし、ビューの設定(詳細/アイコン/タイル/リスト)を切替することできるようにしていますので、

    「LV_VIEW_DETAILS/LV_VIEW_LIST/LV_VIEW_TILE」を指定した場合、

    意図した位置(矩形)が、GetItemRectなどでは取得できませんでした。

     ※NM_CUSTOMDRAW 内で、矩形を取得し描画して確かめています。

     

    現在の状況としては、

    「選択で反転されるテキストの矩形」を取得するには

    ・アイコン        GetItemRect でLVIR_LABELを指定

    ・詳細/タイル/リスト  自前で計算??

    となっています。

     

     

     

    2010年9月8日 0:45
  • >詳細/タイル/リスト

    自分で計算する必要がありますね。

     

    ・LV_VIEW_LIST/LV_VIEW_DETAILS

    Viewの種類やStyle等により、応用や調整が必要かもしれません。

    便宜上、求めるフォーカスの矩形をFocusRect、その幅をFocusWidthとします。

    1.GetItemRect(LVIR_LABEL)でLabelRect取得

    2.GetStringWidth()でStringWidth取得

    3.FocusWidth = StringWidth + GetSystemMetrics(SM_CXFOCUSBORDER) * 2

    4.FocusWidthとLabelRectの幅を比較

    5-1.同等かFocusWidthの幅が大きい場合

      6.FocusRect = LabelRect

    5-2.LabelRectの幅が大きい場合

      7.FocusRect = LabelRect

      8.FocusRectの幅をFocusWidthにする

     

    ・LV_VIEW_TILE

    文字列を囲うようにFocusが表示されるため、CDCを利用して計算する必要がありますね。

    DrawTextやGetSystemMetrics(SM_CX(Y)FOCUSBORDER)で計算することになりそうです。

    Visual Styleが適用されている場合、DrawThemeTextを利用する必要があるか検証が必要です。

     

    >※LVS_ICON と LV_VIEW_ICON が厳密に同じなのかは確認していません。

    同じですよ。

    • 回答としてマーク target_3to4 2010年9月10日 4:59
    2010年9月8日 13:09
  • kozz 様

    詳しい解説ありがとうございます。

    参考にさせて頂きます。

     

    ただ、こちらの都合で申し訳ないのですが、

    試行錯誤が必要そうですので

    纏まった時間が取れるときに試してみたいと思います。

     

    試した結果はまたご報告させて頂きますので

    よろしくお願いします。

     

    2010年9月9日 4:02
  • LV_VIEW_LIST/LV_VIEW_DETAILS で、

    kozz 様に提示して頂いた方法を試しました。

     

    ほぼ同一の矩形が取得できましたが、

    少し小さく、取得したRectのright に「6」足すことで

    同一の矩形になりました。

    ただし、XPだとそのまま使えそう(??)なのですが、

    Vistaの場合、アイテムの名称に小文字の「r」が入っていると

    矩形がずれてしまいます。 (7は未確認)

     ※確認できたのが「r」だけで、他にもあるかもしれません。

     

    最初に、仲澤@失業者様がおっしゃった様に、

    試行錯誤が必要で時間が掛かりそうなので、

    意図した矩形はまだ取れていませんが、

    一旦、解決とさせて頂きます。

     

    ※自前の計算で簡単な方法が見つかれば、

     こちらにまた書き込みさせて頂きますが、

     全く別の方法を検討するかもしれません。

     

    仲澤@失業者 様

    kozz 様

    ありがとうございました。

    2010年9月10日 5:00