返回首页

{A}
简介
这是一个特殊的工具栏辅助模板类,您可以使用WTL框架窗口的基于应用程序实现以下:将文本添加到工具栏按钮添加下拉菜单的工具栏按钮组合框添加到工具栏
这里给出的代码使得它很容易显示专业外观的工具栏的任何WTL CFrameWnd的派生窗口,我希望,解释它是如何的作品也证明有用的。入门
首先,你需要包含头文件,最好是在你为MainFrm.h:

#include "ToolBarHelper.h"

下一步,推导出你的窗口CToolBarHelper类(可能的CMainFrame):{C}
接下来,如果你是想工具栏的下拉菜单/组合框,你需要添加一个CHAIN​​_MSG_MAP进入你的消息映射,以确保正确处理CBN_SELCHANGE和TBN_DROPDOWN消息:
BEGIN_MSG_MAP(CMainFrame)

    ...

    CHAIN_MSG_MAP(CToolBarHelper<CMainFrame>)

END_MSG_MAP()

这可能是一个好主意,反正这样做,如果你想添加drop-downs/comboboxes后。CString的,等等。
请注意,代码使用的CString,CRECT,CSIZE类。这意味着,如果你是在Visual Studio 6编译,您将需要#包括LT; atlmisc.hgt,而Visual Studio 2005的用户可能要使用新的atlstr.h和atltypes.h头。 atlctrls.h文件也是必不可少的,但WTL的类向导默认情况下添加到stdafx.h中。
接下来,添加相关的魔法你的CMainFrame::OnCreate函数来调剂您的工具栏。工具栏按钮添加文本
将文本添加到工具栏按钮,您首先需要使用ATL_SIMPLE_TOOLBAR_​​PANE_STYLE_EX而不是ATL_SIMPLE_TOOLBAR_​​PANE_STYLE,以确保您的工具栏创建。如果你忘了这一步,那么文本将不会出现在工具栏上按钮。只需更换这一行:
HWND hWndToolBar = CreateSimpleToolBarCtrl(m_hWnd, IDR_MAINFRAME, 

                   FALSE, ATL_SIMPLE_TOOLBAR_PANE_STYLE);

与此:
HWND hWndToolBar = CreateSimpleToolBarCtrl(m_hWnd, IDR_MAINFRAME, FALSE, 

                   ATL_SIMPLE_TOOLBAR_PANE_STYLE_EX);

注意,ATL_SIMPLE_TOOLBAR_​​PANE_STYLE_EX是一个简单的组合ATL_SIMPLE_TOOLBAR_​​PANE_STYLE和神奇的工具栏TBSTYLE_LIST风格(确保按钮上的文字会显示)。
现在,所​​有你需要做的的是将文本添加到相关的按钮,使用下列方法之一:AddToolbarButtonText(HWND hWndToolBar,UINT的NID,LPCTSTR lpsz)
使用此方法来设置工具栏按钮的文本直接从一个字符串,例如:
AddToolbarButtonText(hWndToolBar, ID_APP_ABOUT, _T("About"));

只需通过工具栏的窗口句柄(CreateSimpleToolBarCtrl返回一个),你想改变按钮的ID,和您要添加的文字。AddToolbarButtonText(hWndToolBar的HWND,UINT,UINT的NID nStringID)
使用这种方法,从指定的字符串资源添加文本。例如:
这将载入IDS_TOOLBAR_​​TEXT字符串和文本分配到指定的工具栏按钮(在这种情况下,ID_EDIT_PASTE)。
最后,您可以设置工具栏按钮的文本已经被分配到一个按钮的工具提示使用下列方法:AddToolbarButtonText(HWND hWndToolBar,UINT的NID)
此方法将试图加载字符串相同的ID按钮,寻找工具提示文本,并将其分配给按钮。例如:
AddToolbarButtonText(hWndToolBar, ID_FILE_SAVE);

这将负载与编号ID_FILE_SAVE,看起来像这样的字符串:
Save the active document\nSave (Ctrl+S)

工具提示文本,可以发现后,立即\ N。现在,你可以看到,快捷键已硬连线成工具提示文本,以便AddToolbarButtonText将寻找首个开放式支架下面的\ n只使用之间的文本。因此,在这个例子中,ID_FILE_SAVE编号的工具栏按钮将设置为文本保存。
够简单。引擎盖下
将文本添加到工具栏按钮,需要以下步骤:确保工具栏TBSTYLE_EX_MIXEDBUTTONS样式位。调用CToolBarCtrl::AddStrings方法添加按钮上的文字工具栏的内部列表。更改按钮的信息,以确保TBSTYLE_AUTOSIZE BTNS_SHOWTEXT位被设置。删除,然后重新插入工具栏按钮。添加下拉菜单的工具栏按钮
为了增加一个下拉菜单,工具栏按钮,你首先需要使用Visual Studio资源编辑器创建菜单。然后,只需添加一个调用下面的方法的CMainFrame::OnCreate中:AddToolBarDropDownMenu(hWndToolBar的HWND,nButtonID UINT,UINT nMenuID)
指定工具栏的窗口句柄(再次,一个由CreateSimpleToolBarCtrl返回),将被分配的下拉按钮,按钮的ID,你要显示的按钮被点击时的菜单的ID。很简单。菜单命令,将被路由到主框架窗口是正常的,如果您有分配按钮图像时,就会出现(见本演示示例程序)。
如果你想立即修改菜单显示之前(例如,添加新项目),然后重写以下虚函数:
virtual void PrepareToolBarMenu(UINT nMenuID, HMENU hMenu);

此功能称为CToolBarHelper之前显示一个菜单,并通过大约是要显示的菜单的ID,和菜单句柄,这将允许你修改菜单内容。
例如,示例程序演示如何加入一个分隔符和两个新的菜单项是附加到文件的IDR_NEW菜单|新的工具栏按钮:
void CMainFrame::PrepareToolBarMenu(UINT nMenuID, HMENU hMenu)

{

 if (nMenuID == IDR_NEW)

 {

  CMenuHandle menu(hMenu);

  menu.AppendMenu(MF_SEPARATOR);

  menu.AppendMenu(MF_STRING, ID_NEW_DOCUMENT, _T("Document..."));

  menu.AppendMenu(MF_STRING, ID_NEW_TEMPLATE, _T("Template..."));

 }

}

很简单的东西。引擎盖下
添加到工具栏按钮的下拉菜单中包括以下步骤:确保按钮本身分配的TBSTYLE_EX_DRAWDDARROWS风格。处理TBN_DROPDOWN通知消息。显示菜单使用的CMainFrame::m_CmdBar.TrackPopupMenu,以确保菜单显示凉爽每个项目旁边的小按钮,如果分配。
请注意,一个CSimpleMap是用来与菜单ID映射工具栏按钮的ID。已经很多年这个非常简单的地图类的ATL的一部分,不应该给你的任何问题。我的STL的大用户,所以通常会使用std::地图,但CSimpleMap这个非常简单的目的,是完全足够的。将组合框添加到工具栏
要到工具栏上添加一个ComboBox,首先你需要添加一个按钮到工具栏,作为一个占位符的行为。只需添加一个新的按钮,使用Visual Studio工具栏编辑器,并确保它有一个ID - 没有图像。接下来,创建组合框,调用下面的方法:从CMainFrame中:OnCreate中:CreateToolbarComboBox(HWND hWndToolBar,UINT NID,UINT nWidth,UINT nHeight,DWORD dwComboStyle)
您需要提供的最低参数的是工具栏的窗口句柄(再次,一个由CreateSimpleToolBarCtrl返回)和特殊的占位符"按钮添加到您的工具栏的ID。组合框的宽度,高度和样式将默认为16,16和CBS_DROPDOWNLIST,(注意宽度/高度指定的字符,而不是像素,并且只应该用来为指导,为不同口味的Windows /视觉样式,可能会导致组合框,确定自己的身高)。
CreateToolbarComboBox返回新创建的组合框,然后你就可以使用添加项目的HWND。例如,要添加一个ComboBox包含三个项目:
CComboBox combo = CreateToolbarComboBox(hWndToolBar, ID_COMBO_PLACEHOLDER);

combo.AddString(_T("Item 1"));

combo.AddString(_T("Item 2"));

combo.AddString(_T("Item 3"));

CToolBarHelper,当一个ComboBox项目被选中,将调用下面的函数,你必须添加到您的CMainFrame类:
void OnToolBarCombo(HWND hWndCombo, UINT nID, int nSel, 

                    LPCTSTR lpszText, DWORD dwItemData);

这是通过组合框的窗口句柄,按钮(例如,ID_COMBO_PLACEHOLDER),新选定的ComboBox项,项目文本和项目数据的索引编号。示例程序显示了这一行动。ComboBox控件的UI更新
如果你想要一个工具栏组合框,可能需要在项目的选择要更新的基础上一些程序的状态,然后你应该做以下内容:您的CMainFrame类中添加一个CComboBox成员。分配一个CreateToolbarComboBox调用返回的HWND的CComboBox。在您的CMainFrame::ONIDLE方法,改变ComboBox中选择相应的。
例如,在您为MainFrm.h:
CComboBox m_wndCombo;

然后,在CMainFrame::OnCreate中:
m_wndCombo = CreateToolbarComboBox(hWndToolBar, ID_COMBO_PLACEHOLDER);

m_wndCombo.AddString(...);

在CMainFrame::的OnIdle:
if (GetFocus() != m_wndCombo)

{

 // Check combo selection is accurate



}

注意ONIDLE代码更新ComboBox的第一检查ComboBox中没有重点,这就避免了一些潜在的闪烁。
示例程序演示了这一行动。引擎盖下
将控件添加到工具栏已被一些人想办以来的第一个共同的工具栏控件,WIN95发布,此标准的工程实践像这样:更改占位按钮是一个分离器,由于设计怪癖,分离器的宽度是可以改变的。更改分离器的宽度相匹配,您要建立的控制。创建控件的工具栏控件的父,使用分隔按钮RECT的大小。
这工作得很好各种风味多年的框架应用程序,方法是我在写这篇文章时选择。不过,我第一次尝试看起来像这样:

问题是,如果你是使用Windows XP视觉样式,工具栏分隔符不再是一个空的空间,因为它是在经典模式下运行时Win9x/Win2000 - 相反,绘制一条垂直线。正如你可以看到从上面的图片,这看起来有点奇怪。起初,我认为这是要解决一个讨厌的和复杂的NM_CUSTOMDRAW劈,一场噩梦。人们改变占位符"按钮是一个分隔符的原因是因为他们可以任意的宽度,而普通按钮的宽度是固定的... ...是什么呢?当然不是 - 文字的按钮,可以明显改变宽度相匹配的文本,我提供以下解决方案:更改的占位符按钮,BTNS_SHOWTEXT的样式。确保被禁用按钮的状态。如果不是,然后徘徊在鼠标下面的ComboBox中会导致要绘制一个幽灵"按钮。
另一个小问题是,ComboBox的高度可能比工具栏本身(特别是如果像我这样的,你运行启用大字体)小了不少,所以我也加入了一些代码中心的IT。
最后一点是为组合框使用的字体。起初,我只是用系统GUI股票字体,但略有不同,这是用来显示工具栏按钮上的文字字体。一些周围挖掘后,会出现菜单字体,所以我使用SystemParametersInfo和SPI_GETNONCLIENTMETRICS组合得到的LOGFONT,所以我可以创建一个使用与组合框的副本。ToolBarHelper.h
下面是在充分CToolBarHelper:
#pragma once



// Define various toolbar button styles in case they are missing



#ifndef TBSTYLE_EX_MIXEDBUTTONS

#define TBSTYLE_EX_MIXEDBUTTONS   0x00000008

#endif



#ifndef BTNS_SHOWTEXT

#define BTNS_SHOWTEXT    0x0040

#endif



#define ATL_SIMPLE_TOOLBAR_PANE_STYLE_EX 

       (ATL_SIMPLE_TOOLBAR_PANE_STYLE|TBSTYLE_LIST)



/// Class used to expost useful toolbar

/// functionality to a WTL CFrameWnd-derived class



template <class T>

class CToolBarHelper

{

private:

 /// Wrapper class for the Win32 TBBUTTONINFO structure.



 class CTBButtonInfo : public TBBUTTONINFO

 {

 public:

  /// Constructor



  CTBButtonInfo(DWORD dwInitialMask = 0)

  {

   memset(this, 0, sizeof(TBBUTTONINFO));

   cbSize = sizeof(TBBUTTONINFO);

   dwMask = dwInitialMask;

  }

 };



 /// Wrapper class for the Win32 TBBUTTON structure.



 class CTBButton : public TBBUTTON

 {

 public:

  /// Constructor



  CTBButton()

  {

   memset(this, 0, sizeof(TBBUTTON));

  }

 };

private:

 CFont m_fontCombo;   ///< Font to use for comboboxes

 CSimpleMap<UINT, UINT> m_mapMenu; ///< Map of command IDs -> menu IDs



public:

 /// Message map



 BEGIN_MSG_MAP(CToolbarHelper<T>)

  COMMAND_CODE_HANDLER(CBN_SELCHANGE, OnSelChangeToolBarCombo)

  NOTIFY_CODE_HANDLER(TBN_DROPDOWN, OnToolbarDropDown)

 END_MSG_MAP()



 /// Modify a toolbar button to have a drop-down button



 void AddToolBarDropDownMenu(HWND hWndToolBar, UINT nButtonID, UINT nMenuID)

 {

  ATLASSERT(hWndToolBar != NULL);

  ATLASSERT(nButtonID > 0);

  // Use built-in WTL toolbar wrapper class



  CToolBarCtrl toolbar(hWndToolBar);

  // Add the necessary style bit (TBSTYLE_EX_DRAWDDARROWS) if



  // not already present



  if ((toolbar.GetExtendedStyle() & TBSTYLE_EX_DRAWDDARROWS) 

                                  != TBSTYLE_EX_DRAWDDARROWS)

   toolbar.SetExtendedStyle(toolbar.GetExtendedStyle() | 

                            TBSTYLE_EX_DRAWDDARROWS);

  // Get existing button style



  CTBButtonInfo tbi(TBIF_STYLE);

  if (toolbar.GetButtonInfo(nButtonID, &tbi) != -1)

  {

   // Modify the button



   tbi.fsStyle |= TBSTYLE_DROPDOWN;

   toolbar.SetButtonInfo(nButtonID, &tbi);

   // We need to remember that this menu

   // ID is associated with the button ID

   // so use a basic map for this.



   m_mapMenu.Add(nButtonID, nMenuID);

  }

 }



 LRESULT OnToolbarDropDown(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)

 {

  // Get the toolbar data



  NMTOOLBAR* ptb = reinterpret_cast<NMTOOLBAR*>(pnmh);

  // See if the button ID has an asscociated menu ID



  UINT nMenuID = m_mapMenu.Lookup(ptb->iItem);

  if (nMenuID)

  {

   // Get the toolbar control



   CToolBarCtrl toolbar(pnmh->hwndFrom);

   // Get the button rect



   CRect rect;

   toolbar.GetItemRect(toolbar.CommandToIndex(ptb->iItem), &rect);

   // Create a point



   CPoint pt(rect.left, rect.bottom);

   // Map the points



   toolbar.MapWindowPoints(HWND_DESKTOP, &pt, 1);

   // Load the menu



   CMenu menu;

   if (menu.LoadMenu(nMenuID))

   {

    CMenuHandle menuPopup = menu.GetSubMenu(0);

    ATLASSERT(menuPopup != NULL);

    T* pT = static_cast<T*>(this);

    // Allow the menu items to be initialised (for example,



    // new items could be added here for example)



    pT->PrepareToolBarMenu(nMenuID, menuPopup);

    // Display the menu    



    // Using command bar TrackPopupMenu method means menu icons are displayed



    pT->m_CmdBar.TrackPopupMenu(menuPopup, 

       TPM_RIGHTBUTTON|TPM_VERTICAL, pt.x, pt.y);

   }

  }

  return 0;

 }



 /// Override this Allow the menu items to be enabled/checked/etc.



 virtual void PrepareToolBarMenu(UINT /*nMenuID*/, HMENU /*hMenu*/)

 {

 }



 /// Add text to a toolbar button



 void AddToolbarButtonText(HWND hWndToolBar, UINT nID, LPCTSTR lpsz)

 {

  // Use built-in WTL toolbar wrapper class



  CToolBarCtrl toolbar(hWndToolBar);

  // Set extended style



  if ((toolbar.GetExtendedStyle() & TBSTYLE_EX_MIXEDBUTTONS) 

                                  != TBSTYLE_EX_MIXEDBUTTONS)

   toolbar.SetExtendedStyle(toolbar.GetExtendedStyle() | 

                            TBSTYLE_EX_MIXEDBUTTONS);

  // Get the button index



  int nIndex = toolbar.CommandToIndex(nID);

  CTBButton tb;

  toolbar.GetButton(nIndex, &tb);

  int nStringID = toolbar.AddStrings(lpsz);

  // Alter the button style



  tb.iString = nStringID;

  tb.fsStyle |= TBSTYLE_AUTOSIZE|BTNS_SHOWTEXT;

  // Delete and re-insert the button



  toolbar.DeleteButton(nIndex);

  toolbar.InsertButton(nIndex, &tb);

 }



 /// Add resource string to a toolbar button



 void AddToolbarButtonText(HWND hWndToolBar, UINT nID, UINT nStringID)

 {

  CString str;

  if (str.LoadString(nStringID))

   AddToolbarButtonText(hWndToolBar, nID, str);

 }



 /// Add text to a toolbar button (using tooltip text)



 void AddToolbarButtonText(HWND hWndToolBar, UINT nID)

 {

  TCHAR sz[256];

  if (AtlLoadString(nID, sz, 256) > 0)

  {

   // Add the text following the '\n'



   TCHAR* psz = _tcsrchr(sz, '\n');

   if (psz != NULL)

   {

    // Skip to first character of the tooltip



    psz++;

    // The tooltip text may include the accelerator, i.e.



    // Open (Ctrl+O)



    // So look for an open brace



    TCHAR* pBrace = _tcschr(psz, '(');

    if (pBrace != NULL)

     *(pBrace - 1) = '\0';

    AddToolbarButtonText(hWndToolBar, nID, psz);

   }

  }

 } 



 /// Create a combobox on a toolbar



 HWND CreateToolbarComboBox(HWND hWndToolBar, UINT nID, 

      UINT nWidth = 16, UINT nHeight = 16,

      DWORD dwComboStyle = CBS_DROPDOWNLIST)

 {

  T* pT = static_cast<T*>(this);

  // Use built-in WTL toolbar wrapper class



  CToolBarCtrl toolbar(hWndToolBar);

  // Get the size of the combobox font



  CreateComboFont();

  CSize sizeFont = GetComboFontSize();

  // Compute the width and height



  UINT cx = (nWidth + 8) * sizeFont.cx;

  UINT cy = nHeight * sizeFont.cy;

  // Set the button width



  CTBButtonInfo tbi(TBIF_SIZE|TBIF_STATE|TBIF_STYLE);

  // Make sure the underlying button is disabled



  tbi.fsState = 0;

  // BTNS_SHOWTEXT will allow the button size to be altered



  tbi.fsStyle = BTNS_SHOWTEXT;

  tbi.cx = static_cast<WORD>(cx);

  toolbar.SetButtonInfo(nID, &tbi);

  // Get the index of the toolbar button



  int nIndex = toolbar.CommandToIndex(nID);

  // Get the button rect



  CRect rc;

  toolbar.GetItemRect(nIndex, rc);

  rc.bottom = cy;

  // Create the combobox



  DWORD dwStyle = WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_TABSTOP|dwComboStyle;

  CComboBox combo;

  combo.Create(pT->m_hWnd, rc, NULL, dwStyle, 0, nID);

  combo.SetFont(m_fontCombo);

  combo.SetParent(toolbar);

  // The combobox might not be centred vertically, and we won't know the



  // height until it has been created. Get the size now and see if it



  // needs to be moved.



  CRect rectToolBar;

  CRect rectCombo;

  toolbar.GetClientRect(&rectToolBar);  

  combo.GetWindowRect(rectCombo);

  // Get the different between the heights of the toolbar and



  // the combobox



  int nDiff = rectToolBar.Height() - rectCombo.Height();

  // If there is a difference, then move the combobox



  if (nDiff > 1)

  {

   toolbar.ScreenToClient(&rectCombo);

   combo.MoveWindow(rectCombo.left, rc.top + (nDiff / 2), 

                    rectCombo.Width(), rectCombo.Height());

  }

  return combo;

 }



 /// Create the font to use for comboboxes



 void CreateComboFont()

 {

  if (m_fontCombo == NULL)

  {

   NONCLIENTMETRICS ncm;

   ncm.cbSize = sizeof(NONCLIENTMETRICS);

   ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0);

   // Create menu font



   m_fontCombo.CreateFontIndirect(&ncm.lfMenuFont);

   ATLASSERT(m_fontCombo != NULL);

  }

 }



 /// Get the size of the default GUI font



 CSize GetComboFontSize()

 {

  ATLASSERT(m_fontCombo != NULL);

  // We need a temporary DC



  const T* pT = static_cast<const T*>(this);

  CClientDC dc(pT->m_hWnd);

  // Select in the menu font



  CFontHandle fontOld = dc.SelectFont(m_fontCombo);

  // Get the font size



  TEXTMETRIC tm;

  dc.GetTextMetrics(&tm);

  // Done with the font



  dc.SelectFont(fontOld);

  // Return the width and height



  return CSize(tm.tmAveCharWidth, tm.tmHeight + tm.tmExternalLeading);

 }



 LRESULT OnSelChangeToolBarCombo(WORD /*wNotifyCode*/, WORD wID, 

         HWND hWndCtl, BOOL& /*bHandled*/)

 {

  T* pT = static_cast<T*>(this);

  // Get the newly selected item index



  CComboBox combo(hWndCtl);

  int nSel = combo.GetCurSel();

  // Get the item text



  CString strItemText;

  combo.GetLBText(nSel, strItemText);

  // Get the item data



  DWORD dwItemData = combo.GetItemData(nSel);

  // Call special function to handle the selection change



  pT->OnToolBarCombo(combo, wID, nSel, strItemText, dwItemData);

  // Set focus to the main window



  pT->SetFocus();

  return TRUE;

 }

};
示例应用程序
两个示例应用程序提供 - 为Visual Studio 6,和一个用于Visual Studio 2005。我使用WTL的7.5,但与早​​期版本,我认为它应该工作。请注意,代码是Unicode标准,并在Visual Studio 2005示例包含Unicode的发布和调试版本。
示例应用程序演示CToolBarHelper所有可用的方法:点击"新建"按钮,下拉显示一个动态修改菜单。选择视图使用的第一个组合框的颜色。通过颜色,单击颜色按钮周期。单击颜色按钮下拉菜单中显示的颜色,包括按钮图标。注意如何改变颜色,将导致的第一个组合框更新。第二个combobox是简单地加在OnCreate从来没有通过的OnIdle更新。保存,粘贴,关于按钮的文本已被添加使用的各种AddToolbarButtonText方法。改进
如果您有任何意见或建议,我可以就如何改善这种代码,那么请随时发布。我有一个想法是添加支持编辑控件添加到工具栏,这应该不会太困难。

回答

评论会员:modjtaba 时间:2011/12/07

很好和有益的工作。但有一个小虫子在消息映射。当我生成一个命令使用快捷键(如Ctrl保存命令小号),并把它传递给你的消息映射,它错误地成为CBN_SELCHANGE抓获。这是因为加速器生成的命令1等于CBN_SELCHANGE,因为你不测试发件人ID wParam的高字,出现这种情况。
这次调整似乎很容易。我建议添加这块代码OnSelChangeToolBarCombo功能:

	LRESULT OnSelChangeToolBarCombo(WORD wNotifyCode, WORD wID, 

		HWND hWndCtl, BOOL& bHandled)

	{

		// new code starts here

		if(hWndCtl == NULL)

		{

			bHandled=FALSE;

			return FALSE;

		}

		// new code ends here

方面,莫急大

上周五,2009年2月13日,日下午04:36
修改
评论会员:Linux的dotMicrosoft 时间:2011/12/07
我想下面的按钮的图标要显示的文字,反正是有做到这一点?
评论会员:digvesh 时间:2011/12/07
您好,

此代码是一个真正的好帮手。
我试图使用此代码位,但我并不能够得到与标识ID_COMBO_PLACEHOLDER创建的组合框的工具提示

请让我知道如何实现这一。

提前许多感谢。
评论会员:吉姆瑞 时间:2011/12/07
非常感谢非常有帮助的代码

做得更好的两个建议:一个简单的,和一个复杂的

[]的功能,如CreateToolbarComboBox假设应该抱怨(ATLASSERT?),当他们试图找到一个按钮,不存在(因为程序员忘记将它添加到工具栏上的资源)。
[B]当我刚开始看代码,我期待看到您从WTL的CToolBarCtrl派生的类中实现的增强工具栏,而不是为CFrameWindowImpl一个混合类。现在我明白了,这可能是难以实现。 (我还没有尝试自己做。)

但CToolBarHelper的是一个混合至少有两个限制。
(1)代码不能直接用于在Windows中有一个工具栏,但不是框架窗口。
(2)其MSG_MAP拥有的处理程序:
COMMAND_CODE_HANDLER(CBN_SELCHANGE,OnSelChangeToolBarCombo)
这表面上看起来不错,但CBN_SELCHANGE的值为1,因此,这个事件处理程序将捕获任何键盘加速器,达到。 (也有1中的wParam HIWORD,在MDI应用程序,转发未处理的消息,子窗口,它是棘手的达到您的处理程序,以避免加速器。
另一方面,如果你有一个衍生工具栏类,它可以发送一个特殊的通知消息包含窗口,并不会出现冲突。

还是喜欢你做了什么。
评论会员:chengang 时间:2011/12/07
非常有用的帮手,我的五

难道是有用的,如果添加了一些实用工具重新定位控制?

因为我看到一些方案已在他们最右侧的帮助按钮。

感谢

(修改:错字)
 0;