How to handle chevron button using CToolBarCtrl object?

Most of the developers work with CToolBarCtrl but they get stuck when it comes to display chevron button. This article is all about how to get chevron button displayed on CToolBarCtrl control while resizing its content window.

 

There is a good MSDN article on handling chevrons but no good sample implementation on it. I wrote a small sample using CDialog, CToolBarCtrl and CReBarCtrl classes to illustrate the same.

 

Since the main focus would be on handling chevron button, I am not going to cover tool bar control implementation details. Following are the steps to achieve chevron button on CToolBarCtrl.

 

1.       Using class wizard, create a new class CCustReBarCtrl deriving it from CReBarCtrl MFC class. Add m_wndReBar  and m_wndToolBar  of type CCustReBarCtrl and CToolBarCtrl respectively in dialog class. Create rebar and tool bar controls in OnInitDialog() dialog method as shown below.

 

m_wndReBar.CreateEx(WS_EX_TOOLWINDOW, WS_CHILD | WS_BORDER | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CCS_NOPARENTALIGN | CCS_NODIVIDER | RBS_VARHEIGHT | RBS_BANDBORDERS, CRect(0, 0, 0, 0),this, 10);

 

m_wndToolBar.Create(WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CCS_NOPARENTALIGN | CCS_NODIVIDER | CCS_NORESIZE | TBSTYLE_TRANSPARENT | TBSTYLE_FLAT, CRect(0,0,0,0), &m_wndReBar, IDR_MAINFRAME);  //Note that rebar control is parent for tool bar control.

 

/*Make sure that tool bar resource is loaded here*/

 

m_wndToolBar.AutoSize();

 

Rebar control provides chevron control when RBBS_USECHEVRON flag in the fStyle member of the band's REBARBANDINFOstructure is set. Before defining the band info, define the following macro in stdafx.h file.

#define REBARBANDINFO_SIZE CCSIZEOF_STRUCT(REBARBANDINFO, cxHeader)

 

SIZE sizeButtons;

m_wndToolBar.GetMaxSize(&sizeButtons);

 

REBARBANDINFO rbi;

ZeroMemory((void*)&rbi, sizeof(rbi));

rbi.cbSize = REBARBANDINFO_SIZE; // V5 structure size. Insert fails if the struct is too big

rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE | RBBIM_STYLE;

rbi.fStyle = RBBS_GRIPPERALWAYS | RBBS_USECHEVRON;

rbi.cyMaxChild = rbi.cyMinChild = rbi.cyChild = sizeButtons.cy;

rbi.cxIdeal = rbi.cx = sizeButtons.cx;

rbi.hwndChild = (HWND)m_wndToolBar;

m_wndReBar.InsertBand(-1, &rbi);

 

RECT rcWindow;

GetClientRect(&rcWindow);

 

m_wndReBar.MoveWindow(0, 0, rcWindow.right - rcWindow.left, sizeButtons.cy);

 

2.       It’s very important to size the rebar control accordingly when dialog is resized otherwise chevron button will not be displayed. So handle WM_SIZE message (OnSize() method) in the dialog class and add the following code as shown below.

if (m_wndReBar.GetSafeHwnd())

{

RECT rcRebar;

 

      m_wndReBar.GetWindowRect(&rcRebar);

      m_wndReBar.MoveWindow(0, 0, cx, rcRebar.bottom - rcRebar.top);

                }

 

3.       Now if you run the code and resize the dialog, chevron will be displayed for tools that have been covered. When a user clicks a chevron, the rebar control sends RBN_CHEVRONPUSHED notification. The NMREBARCHEVRON structure that is passed with the notification contains the band's identifier and a RECT structure with the rectangle occupied by the chevron. Your handler must determine which buttons are hidden and display the associated commands on a pop-up menu.

 

Add RBN_CHEVRONPUSHED notification in CCustReBarCtrl, after adding the message map should look like as shown below

 

BEGIN_MESSAGE_MAP(CCustRebarCtrl, CReBarCtrl)

                                ON_NOTIFY_REFLECT(RBN_CHEVRONPUSHED, & CCustRebarCtrl::OnRbnChevronPushed)

END_MESSAGE_MAP()

 

            Following is the code that goes into the chevron handler 'void CCustRebar::OnRbnChevronPushed(NMHDR *pNMHDR, LRESULT *pResult)' method

 

            LPNMREBARCHEVRON pnmrc = reinterpret_cast<LPNMREBARCHEVRON>(pNMHDR);

 

      RECT rcBand;

      RECT rcButton;

      RECT rcIntersect;

      REBARBANDINFO rbi;

      TBBUTTON tbb;

      UINT cButtons;

      UINT iButton;

      UINT iMenu;

      HMENU hmenuPopup;

      MENUITEMINFO mii;

      TCHAR szText[200];

      HRESULT hr;

      CImageList* pimlToolbar;

 

      //

      //  Get the child window for this band.

      ZeroMemory((void*)&rbi, sizeof(rbi));

      rbi.cbSize = REBARBANDINFO_SIZE;

      rbi.fMask = RBBIM_CHILD;

 

      GetBandInfo(pnmrc->uBand, &rbi);

     

      CToolBarCtrl *pTBarCtrl = (CToolBarCtrl *)CToolBarCtrl::FromHandle ( rbi.hwndChild );

      ASSERT(pTBarCtrl);

      ASSERT(pTBarCtrl->IsKindOf(RUNTIME_CLASS(CToolBarCtrl)));

 

    //

    //  Get the client rectangle of the child window

      pTBarCtrl->GetClientRect(&rcBand);

       

    //

    //  Get the number of buttons in the toolbar. This should fail when the

    //  child window is not a toolbar.

 

      if ((cButtons = pTBarCtrl->GetButtonCount()) == 0)

        return;

 

    //

    //  Starting from the leftmost button, retrieve each button's bounding

    //  rectangle until we find a button that is at least partially hidden

    for (iButton = 1; iButton < cButtons; iButton++)

    {

        //

        //  Get the button's rectangle

        ZeroMemory((void*)&rcButton, sizeof(rcButton));

     

        pTBarCtrl->GetItemRect(iButton, &rcButton);

     

        CRect rtTabButton(rcButton);

        CRect rtToolBarCtr(rcBand);

           

        CPoint ptCenter = rtTabButton.CenterPoint();

           

           

         if(!rtToolBarCtr.PtInRect(ptCenter))

            break;

    }

 

      //

    //  Nothing to do if we didn't find a hidden button

    if (iButton == cButtons)

        return;

 

    //

    //  Allocate an array of bitmaps to hold the images used in menu items. An

    //  alternate approach is to ownerdraw the menu

    UINT cImages = cButtons - iButton;

    size_t cb = sizeof(HBITMAP) * cImages;

    HBITMAP* ahbmpImages = (HBITMAP*)malloc(cb);

    if (!ahbmpImages)

        return;

    ZeroMemory((void*)ahbmpImages, cb);

 

    //

    //  Create a memory DC that we use to render the toolbar images

    HDC hdcMem = NULL;

    HDC hdcWindow = ::GetDC(m_hWnd);

    if (hdcWindow)

    {

        hdcMem = CreateCompatibleDC(hdcWindow);

    }

 

    //

    //  Create a popup menu for the hidden toolbar items

    hmenuPopup = CreatePopupMenu();

 

    //

    //  Get the image list for the toolbar

    int cxImage = 0;

    int cyImage = 0;

 

    pimlToolbar = pTBarCtrl->GetImageList();

 

    if (pimlToolbar)

    {

        ImageList_GetIconSize(*pimlToolbar, &cxImage, &cyImage);

    }

       

    //

    //  Create a menu item for each hidden toolbar item

    iMenu = 0;

    for ( ; iButton < cButtons; iButton++)

    {

        ZeroMemory((void*)szText, sizeof(szText));

        ZeroMemory((void*)&tbb, sizeof(tbb));

 

           

     

        if (pTBarCtrl->GetButton(iButton, &tbb))

        { 

                  if(tbb.idCommand != 0)

                  {

                        LoadString(GetModuleHandle(NULL), tbb.idCommand, szText, sizeof(szText)-1);

                        int cch = strlen(szText);

                        szText[cch+1] = '/0';

                  }

 

            //

            //  Create a bitmap for the toolbar icon and draw the icon into the bitmap

            if (hdcMem && pimlToolbar->GetSafeHandle() && ahbmpImages)

            {

                ahbmpImages[iMenu] = CreateCompatibleBitmap(hdcWindow, cxImage, cyImage);

                if (ahbmpImages[iMenu])

                {

                    HBITMAP hbmpOld = (HBITMAP)SelectObject(hdcMem, ahbmpImages[iMenu]);

                    RECT rcImage = {0, 0, cxImage, cyImage};

 

                    //

                    //  First, fill the background with the menu background

                    FillRect(hdcMem, &rcImage, GetSysColorBrush(COLOR_MENU));

 

                    //

                    //  Then draw the icon

                    ImageList_Draw(pimlToolbar->GetSafeHandle(), tbb.iBitmap, hdcMem, 0, 0, ILD_NORMAL);

 

                    SelectObject(hdcMem, hbmpOld);

                }

            }

 

            //

            //  Add a menu item for this toolbar item

            ZeroMemory((void*)&mii, sizeof(mii));

            mii.cbSize = sizeof(MENUITEMINFO);

            mii.fMask = MIIM_STRING;

            mii.dwTypeData = szText;

            mii.wID = tbb.idCommand;

 

            if (ahbmpImages[iMenu])

            {

                mii.fMask |= MIIM_BITMAP;

                mii.hbmpItem = ahbmpImages[iMenu];

            }

 

            InsertMenuItem(hmenuPopup, iMenu++, TRUE, &mii);

        }

    }

 

    //

    //  Display the popup menu if it has menu items

    if (0 < GetMenuItemCount(hmenuPopup))

    {

            ::MapWindowPoints(pnmrc->hdr.hwndFrom, NULL, (LPPOINT)&pnmrc->rc, 2);

        TrackPopupMenu(hmenuPopup,

                       TPM_LEFTALIGN | TPM_TOPALIGN,

                       pnmrc->rc.left, pnmrc->rc.bottom,

                       0, m_hWnd, NULL);

    }

 

    //

    //  Destroy the popup menu

    DestroyMenu(hmenuPopup);

 

    //

    //  Cleanup the bitmaps

    if (ahbmpImages)

    {

        while (cImages)

        {

            cImages--;

            if (ahbmpImages[cImages])

                DeleteObject(ahbmpImages[cImages]);

        }

        free(ahbmpImages);

    }

 

    //

    //  Release the DCs used to handle the bitmaps

    if (hdcMem)

    {

        DeleteDC(hdcMem);

    }

 

    if (hdcWindow)

    {

            ::ReleaseDC(m_hWnd, hdcWindow);

    }

 

      // TODO: Add your control notification handler code here

      *pResult = 0;

 

 

 

http://blogs.msdn.com/dsvc/archive/2009/07/02/how-to-handle-chevron-button-using-ctoolbarctrl-object.aspx

 

http://www.codeproject.com/KB/splitter/zsplitter.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园建设方案旨在通过信息化手段提升教育、管理和服务水平,实现资源数字化、工作流程化、管理高效化和决策智能化。方案包括智慧校园信息化平台和安防平台的建设,涉及教学、科研、管理和服务等多个方面,以满足现代教育和培训需求。 技术服务要求强调了统一支撑平台的建设,包括数据标准、接口标准、代码标准和用户信息标准的统一制定。平台需满足信创和X86交叉适配要求,确保安全自主可控的系统开发环境。此外,方案还涵盖了用户中心系统、统一认证授权中心、统一工作流中心、统一智能报表中心等多个模块,以及数据共享中心、语音识别、移动服务终端等功能,以实现校园内外部信息的互联互通和资源共享。 智慧校园信息化平台的建设还包括了对教学管理、人事管理、公文管理、档案管理、即时通讯、会议管理、督办工作、资产管理等方面的数字化和自动化升级。这些模块的集成旨在提高工作效率,优化资源配置,加强监督管理,并通过移动应用等技术手段,实现随时随地的信息访问和业务处理。 安防平台的建设则侧重于校园安全,包括停车场管理、人脸识别测温、访客自助登记、视频监控等多个系统。这些系统的集成旨在提高校园的安全管理水平,实现对校园内外人员和车辆的有效监控和管理,确保校园环境的安全稳定。 最后,方案还提到了对固定资产的管理,包括购置、使用、归还、报废等全生命周期的管理,以及对网络设备、安防设备、服务器等硬件设施的配置和管理。通过这些措施,智慧校园建设方案旨在为校园提供一个安全、高效、便捷的学习和工作环境。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值