1

I am trying to customize CToolbar class(MFC library) for my needs (enabling support of 32 bit icons with anti-aliasing).
For that purpose I am using custom draw method provided by CToolbar, where I paint my own Icons.
Icons are rendered fine and everything is OK, until user opens customization dialog - where he can pick needed icons and arrange them as he likes (this is standard customization dialog for MFC toolbar).

Problem: in customization dialog the same image is drawn for all buttons.

Here are code snippets from my project:

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;
  }

Message map:

 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 ()

I have done debugging a lot, and managed to get that when customizing window appear - information that is sent to CustomDraw related to the item(button) to be drawn is missed, always zero index is sent.

If I comment out *pResult = CDRF_SKIPDEFAULT; when system is able to draw icons in customization dialog according to their indexes(but with 4 bit depth only) - hence I think that I have ommited smth important in the custom draw.

I have read all possible articles in MSDN and other sources related to the custom draw, but no problem of icons in customization window is mentioned there.

So if anybody has faced with similar problem, could you please give me a hint? thanks in advance!

spin_eight
  • 3,925
  • 10
  • 39
  • 61

1 Answers1

2

Use the new CMFCToolBar... it is much simpler and it provides an easy overridable DrawItem method.

xMRi
  • 14,982
  • 3
  • 26
  • 59
  • Thank you for suggestion. I am aware of CMFCToolBar, I even use CMFCToolBarImages for drawing Icons, but I can't use a newer one due to I work in the legacy project where a lot of changes should be done to switch from the old version to a new one. – spin_eight Feb 26 '14 at 10:41
  • No. It isn't complicated really. It should be possible just to exchange the baseclass from CToolBar to CMFCToolBar as long as you don't have much customizations. I tranfered a lot of legacy code in former times to the BCG-Library and later some to the MFC-Next version. It isn't complicated! – xMRi Feb 26 '14 at 11:14
  • I got 4 levels above CToolBar - this is really mean a lot of work to be done. And to finish my task I need only to solve issue with icons in customization window, but it is very hard for me to estimate time needed for the solution. So I shall spare 2-3 days, if I fail I will use CMFCToolBar. – spin_eight Feb 26 '14 at 11:28
  • You get all customization for free... with CMFcToolBar.... but I understand what you mean! – xMRi Feb 26 '14 at 11:46