1

我正在尝试根据我的需要自定义CToolbar类(MFC 库)(启用对具有抗锯齿功能的 32 位图标的支持)。
为此,我使用CToolbar 提供的自定义绘制方法,在其中绘制我自己的图标。
图标渲染良好,一切正常,直到用户打开自定义对话框- 他可以在其中选择所需的图标并按照他的喜好排列它们(这是 MFC 工具栏的标准自定义对话框)。

问题:在自定义对话框中,为所有按钮绘制了相同的图像。

以下是我项目中的代码片段:

void CCustomToolBar::OnCustomDraw (NMHDR *pNMHDR, LRESULT *pResult)
{
  LPNMTBCUSTOMDRAW lpNMCustomDraw = (LPNMTBCUSTOMDRAW)pNMHDR;

  switch (lpNMCustomDraw->nmcd.dwDrawStage)
  {
    // the Painting loop starts
  case CDDS_PREPAINT:
    {
      *pResult = CDRF_NOTIFYITEMDRAW; // register for items drawing events
      //if (m_bAdjusting)SetWindowLong (lpNMCustomDraw->nmcd.hdr.hwndFrom, DWL_MSGRESULT, CDRF_NOTIFYITEMDRAW);
    }
    break;
    // Item (button) is going to be painted, do own drawing
  case CDDS_ITEMPREPAINT:
    {
      CDC DrawDC;
      DrawDC.Attach(lpNMCustomDraw->nmcd.hdc);

      CToolBarCtrl& ControlBar = GetToolBarCtrl();

      CRect btnRect = lpNMCustomDraw->nmcd.rc; 
      int State = lpNMCustomDraw->nmcd.uItemState; // CDIS_GRAYED | CDIS_CHECKED | CDIS_DEFAULT | CDIS_DISABLED | CDIS_FOCUS | CDIS_GRAYED | CDIS_HOT | CDIS_SELECTED

      hugeSizedImages_.SetTransparentColor(afxGlobalData.clrBtnFace);

      DrawDC.DrawFrameControl(&btnRect, DFC_BUTTON , DFCS_BUTTONPUSH );

      DWORD dwItem = (DWORD)lpNMCustomDraw->nmcd.dwItemSpec;
      int btnIndex = 0;
      GUARD_IF(m_BitmapIndex.find(dwItem) != m_BitmapIndex.end())
      {
        btnIndex = m_BitmapIndex[dwItem];
      }

      CAfxDrawState ds;
      hugeSizedImages_.PrepareDrawImage(ds, CSize(48,48));
      hugeSizedImages_.Draw(&DrawDC, btnRect.left, btnRect.top, btnIndex);
      hugeSizedImages_.EndDrawImage(ds);
      DrawDC.Detach();

      *pResult = CDRF_SKIPDEFAULT;  // No further drawing
      //if (m_bAdjusting) SetWindowLong (lpNMCustomDraw->nmcd.hdr.hwndFrom, DWL_MSGRESULT, CDRF_SKIPDEFAULT);
    }
    break;
  default:
    *pResult = 0;
  }

留言图:

 BEGIN_MESSAGE_MAP ( CCustomToolBar, CToolBarWithHideableButtons )
      //{{AFX_MSG_MAP ( CCustomToolBar )
      ON_WM_CONTEXTMENU ()
      ON_COMMAND        ( CM_TOOLBAR_CUSTOMIZE, OnPopupCustomize )
      ON_NOTIFY_REFLECT ( TBN_QUERYDELETE,      OnQueryDelete )
      ON_NOTIFY_REFLECT ( TBN_QUERYINSERT,      OnQueryInsert )
      ON_NOTIFY_REFLECT ( TBN_GETBUTTONINFO,    OnGetButtonInfo )
      ON_NOTIFY_REFLECT ( TBN_BEGINADJUST,      OnBeginAdjust )
      ON_NOTIFY_REFLECT ( TBN_ENDADJUST,        OnEndAdjust )
      ON_NOTIFY_REFLECT ( TBN_RESET,            OnReset )
      ON_NOTIFY_REFLECT ( TBN_TOOLBARCHANGE,    OnToolBarChange )
      ON_NOTIFY_REFLECT ( TBN_INITCUSTOMIZE,    OnInitCustomize ) //only with IE 5.0 and 
      ON_NOTIFY_REFLECT ( NM_CUSTOMDRAW,        OnCustomDraw)
      ON_WM_CREATE ()
      //}}AFX_MSG_MAP
    END_MESSAGE_MAP ()

我已经进行了很多调试,并且在自定义窗口出现时设法得到了这一点 - 发送到 CustomDraw 的与要绘制的项目(按钮)相关的信息被遗漏,总是发送零索引。

如果我注释掉 *pResult = CDRF_SKIPDEFAULT; 当系统能够根据它们的索引在自定义对话框中绘制图标时(但只有 4 位深度) - 因此我认为我在自定义绘制中省略了重要的东西。

我已经阅读了 MSDN 中所有可能的文章以及与自定义绘制相关的其他来源,但没有提到自定义窗口中的图标问题。

所以如果有人遇到过类似的问题,请给我一个提示吗?提前致谢!

4

1 回答 1

2

使用新的 CMFCToolBar... 它更简单,并且提供了一个简单的可重写 DrawItem 方法。

于 2014-02-26T10:27:21.187 回答