5

カスタム描画を使用して、透明なツリー ビューを作成しようとしています (今のところ、Visual Styles が有効になっている場合をテストしています)。

私のCDDS_PREPAINTハンドラーは正常に動作し、ツリーには親の背景ビットマップが適切に描画されています。

を使用して返すCDDS_ITEMPREPAINTところにハンドラーを追加しようとしましたが、失敗しました。ノードはデフォルトの白い背景で描画されます。SetBkColor( ((LPNMCUSTOMDRAW)lParam)->hdc, TRANSPARENT );CDRF_NEWFONT

アイテムのテキストの背景を透明にするにはどうすればよいですか?

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

よろしくお願いします。

以下は、例示的なコード スニペットです。

switch( ((LPNMCUSTOMDRAW)lParam)->dwDrawStage  )
{
case CDDS_PREPAINT:
    {
        DrawThemeParentBackground(
            ((LPNMCUSTOMDRAW)lParam)->hdr.hwndFrom,
            ((LPNMCUSTOMDRAW)lParam)->hdc,
            &((LPNMCUSTOMDRAW)lParam)->rc );

        // since tree is in dialog box we need below statement
        SetWindowLongPtr( hDlg, DWLP_MSGRESULT, (LONG_PTR)CDRF_NOTIFYITEMDRAW );
        return TRUE;

    }
    break;
case CDDS_ITEMPREPAINT :  // how to properly handle this ???
    {   
        SetBkMode( ((LPNMCUSTOMDRAW)lParam)->hdc, TRANSPARENT );

        SetWindowLongPtr( hDlg, DWLP_MSGRESULT, (LONG_PTR)CDRF_NEWFONT );
        return TRUE;
    }
    break;
}
4

1 に答える 1

5

残念ながら、これは自分でアイテムを描かないと簡単にはできません。

ツリー ビュー コントロールは、伝統的ExtTextOut()に項目のタイトルを描画するために関数を内部的に使用していたことがわかりました。この関数は、明示的な flags パラメーターを受け取ります。値ETO_OPAQUEは、「現在の背景色を使用して四角形を塗りつぶす必要がある」ことを示します。

SetBkMode()このオプションは追加のフラグとして渡され、現在の GDI バックグラウンド モードを調べても決定されないため、これを回避するためにカスタム描画ハンドラーで使用することはできません。DC の背景色プロパティもアルファ チャネルをサポートしていないため、透明に設定することはできません。

Common Controls バージョン 6.0 およびテーマ ウィンドウの装飾以降、これは少し異なりますが、この場合はまだ役に立ちません。コントロールはパーツを呼び出すだけDrawThemeBackground()TVP_TREEITEM、残りは使用されているテーマに従って処理されます。たとえば、Windows 8.1 のデフォルトの Aero テーマには、次のエントリがあることがわかります。

ClassID  | PartID       | StateID      | Property        | Value
---------+--------------+--------------+-----------------+--------------
TreeView | TVP_TREEITEM | TREIS_NORMAL | FILLCOLOR:COLOR | 255, 255, 255

それで、代替案は何ですか?

イベントに戻ってすべての表示操作を自分で行うCDRF_SKIPDEFAULTオプションが常にあります。CDDS_ITEMPREPAINTただし、線、[+] ボックス、選択およびフォーカスの四角形、その他すべてを描画する必要があります。

もう 1 つのオプションは、コントロールに保存されているタイトル テキストを空のままにし、それを追加することです。CDDS_ITEMPOSTPAINTつまり、 with を使用TVM_GETITEMRECTwParam=TRUEてテキスト四角形を取得し、コントロールによって他のすべてが既に描画された後に実際のテキストをそこに描画します。しかし、空のテキストに対しても小さな不透明な長方形が描画されるように見えるため、このメソッドも失敗します。最初にそのアーティファクトを消去してから、自分でテキストを描画する必要があります。アイテムの状態のすべての組み合わせで機能するコードを考え出すのは難しいように思えました。

于 2014-05-02T00:44:46.110 に答える