none
CListCtrl行を最初に選択したときにCustomDrawで色づけしたセルが白くなってしまう RRS feed

  • 質問

  • CListCtrlのOnCustomDraw()でセルに色を塗っています。

    また、スタイルでLVS_EX_FULLROWSELECTを指定してどのセルをクリックしても行が選択されるようにしています。

    ただし、あるセルだけは、行が選択されたときに反転したくないため、選択された行のそのセルにデフォルトの反転描画が行われない様にしています。

    void CxxxListCtrl::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)

    {

       // 中略

     if (lpLvCustomDraw->nmcd.dwDrawStage == CDDS_ITEMPREPAINT|CDDS_SUBITEM) {

       if (lpLvCustomDraw->iSubItem == 1) {

            int State = ListView_GetItemState(m_hWnd, lpLvCustomDraw->nmcd.dwItemSpec, LVIS_CUT | LVIS_SELECTED | LVIS_FOCUSED);
           if ( State & LVIS_SELECTED ) {
              *pResult = CDRF_SKIPDEFAULT;
               return;
           }

         }

       }

    ところが、CListCtrlを初めて選択したときに、上記で反転を制御しているセルの色が白くなってしまいます。

    次の選択以降はその行の値がきちんと残って表示されています。

    初回の選択で、反転せずにオーナー描画した色を表示するにはどうしたらよいでしょうか。

    ちなみに、VS2005を使っていて、テストしている環境はWindowsXPです。

    ※Vista以降にCDRF_DOERASEという背景のみを描画するというのがありましたが、環境上試せませんでした。

    Vista以降だとこの現象が起こらないとかないですよね、、、

    2012年8月23日 9:08

回答

  • 白くなる理由はわかりませんが、ご提示のコードだとListViewの再描画が必要な場合にも白くなります。

    たとえば、ListViewの上に他のウィンドウが重なった後とか、ListViewの親ウィンドウを画面の外に移動した後に画面の中に戻した場合、ListViewの再描画が生じると白くなります。

    対策としては、CDRF_SKIPDEFAULTでreturnする場合は、自力で描画処理すればよいです。

    別の方法として、nmcd.uItemState &= ~CDIS_SELECTEDをxpで試したところ、何とかなりました。ただし、uItemStateの変更が許されているのかどうかは私には分かりません。

    • 回答としてマーク rieko kume 2012年8月25日 12:35
    • 回答としてマークされていない rieko kume 2012年8月25日 12:35
    • 回答としてマーク rieko kume 2012年8月25日 12:39
    2012年8月25日 3:31

すべての返信

  • 白くなる理由はわかりませんが、ご提示のコードだとListViewの再描画が必要な場合にも白くなります。

    たとえば、ListViewの上に他のウィンドウが重なった後とか、ListViewの親ウィンドウを画面の外に移動した後に画面の中に戻した場合、ListViewの再描画が生じると白くなります。

    対策としては、CDRF_SKIPDEFAULTでreturnする場合は、自力で描画処理すればよいです。

    別の方法として、nmcd.uItemState &= ~CDIS_SELECTEDをxpで試したところ、何とかなりました。ただし、uItemStateの変更が許されているのかどうかは私には分かりません。

    • 回答としてマーク rieko kume 2012年8月25日 12:35
    • 回答としてマークされていない rieko kume 2012年8月25日 12:35
    • 回答としてマーク rieko kume 2012年8月25日 12:39
    2012年8月25日 3:31
  • nmcd.uItemState &= ~CDIS_SELECTED

    を設定したところ、Windows7でも上手く動作しました。

    特定の場所に対して選択を解除するということができるのですね。

    有難うございました。

    2012年8月25日 12:39