4

WTL コンボボックスをサブクラス化し、コンボボックスのアイテムをオーナー描画しています。コントロールには属性がCBS_DROPDOWNLIST | CBS_HASSTRINGS | CBS_OWNERDRAWVARIABLEあり、ミックスイン クラス COwnerDraw を使用して DrawItem() と MeasureItem() を実装しています。ドロップダウン リストがダウンしている場合、アイテムは正しく描画されます。ただし、ドロップダウン リストが表示されている場合、コンボ ボックス コントロールは空であり、アイテムは描画されません。私は何を間違っていますか?

WTL クラスは次のようになります。

class CMyComboBox :
   public CWindowImpl<CMyComboBox, CComboBox>,
   public COwnerDraw<CMyComboBox>
{
public:
   BEGIN_MSG_MAP_EX(CMyComboBox)
      CHAIN_MSG_MAP(COwnerDraw<CMyComboBox>)
      CHAIN_MSG_MAP_ALT(COwnerDraw<CMyComboBox>, 1)
   END_MSG_MAP()

   void DrawItem(LPDRAWITEMSTRUCT lpDIS)
   {
      CDCHandle dc = lpDIS->hDC;
      dc.FillSolidRect(&lpDIS->rcItem, lpDIS->itemID == 0 ?
         RGB(255,0,0) : RGB(0,255,0));
   }

   void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
   {
      lpMeasureItemStruct->itemWidth = 12;
      lpMeasureItemStruct->itemHeight = 12;
   }
};

このクラスはダイアログで使用され、次のようにサブクラス化されます。

   m_cbMy.SubclassWindow(GetDlgItem(IDC_COMBO1));
   m_cbMy.AddString(_T("Item 1"));
   m_cbMy.AddString(_T("Item 2"));

コントロール属性を にCBS_OWNERDRAWFIXED変更しても何も変わりません。


編集: najmeddine の助けのおかげで、ドロップダウン リストの項目だけでなく、実際のコンボ ボックスを描画するには WM_PAINT を処理する必要があることがわかりました。残念ながら、コンボボックス コントロールもすべて自分で描画する必要があります。コントロールの「内側」のみを描画する必要があるように、GDI に境界線を描画させて矢印をドロップさせる方法はありますか?

4

3 に答える 3

6

コンボボックス コントロールを描画するには、WM_PAINT ハンドラーでテーマ API を使用する必要があります (XP+ では、サポートする必要がある Windows バージョンは指定しません)。具体的には、 を使用して、 iPartIdDrawThemeBackgroundの値の 1 つを渡します。CB_

また、バッファリングされたペイント APIを使用して、Vista で遷移を処理する必要があります。これにより、ペイント ハンドラが複雑になる可能性があります。コンボ ボックス コントロールをカスタム ペイントする場合のこの問題やその他の描画の問題については、ここでかなり詳しく説明します。これを実装するための主なリファレンスとして、そのフォーラム スレッドを使用することをお勧めします。

于 2009-11-13T00:54:52.057 に答える
0

リストではなく、comboBox コントロールを描画するには、WM_PAINTメッセージを処理し、そこで描画を行う必要があります。
イベントはDrawItemドロップ リストとそのアイテムのみを描画します。

于 2009-11-10T11:32:47.210 に答える
0

DrawItem では、四角形を色で塗りつぶします。しかし、DrawText などはどこにあるのでしょうか。

カスタム DrawItem の例

于 2009-11-09T11:52:29.127 に答える