MFC 将 CMFCToolBar 按钮更改为切换而不是 press/release?

MFC Change CMFCToolBar button to Toggle instead of press/release?

我在网上找到一篇文章说要将工具栏按钮设置为保持按下的类型你只需在按钮上设置样式 TBBS_CHECKBOX 但它对我不起作用(它仍然像一个普通按钮)。我确认样式已设置,就在创建 SetWindowText() MFC 向导设置 CMainFrame::OnCreate() 之后。我做错了什么?

 for (int i=0; ; i++) {
    int id=m_wndToolBar.GetItemID(i);
    if (id==0) {
      break;
    }
    if (id == ID_THE_ID) {
      m_wndToolBar.SetButtonStyle(i, TBBS_CHECKBOX);
    }
  }

使用 Command Handlers is the recommended implementation here. A command ID may be used in multiple UI items, eg a menu item and a toolbar button. A handler affects all items with the same ID, so you don't need a separate one for each item. The CCmdUI Class 提供的方法可以使 UI 项目(例如菜单或工具栏按钮)作为按钮、复选框或单选按钮,此外 enabling/disabling .

在您的示例中,假设是否过滤的选项是在每个文档的基础上实例化的,即文档的所有视图将被同时过滤或不过滤。您应该在文档中定义一个布尔变量 class:

BOOL m_bFilterData = FALSE;

然后是 ON_COMMANDON_UPDATE_COMMAND_UI 工具栏按钮的处理程序和过滤器图片(可能还有菜单项):

BEGIN_MESSAGE_MAP(CMyDoc, CDocument)
  .
  .
    ON_COMMAND(ID_VIEW_FILTERDATA, OnViewFilterData)
    ON_UPDATE_COMMAND_UI(ID_VIEW_FILTERDATA, OnUpdateViewFilterData)
  .
  .
END_MESSAGE_MAP()

void CMyDoc::OnViewFilterData()
{
    // Toggle filtered state
    m_bFilterData = !m_bFilterData;
    // Tell all views to refresh - You can limit this using the lHint/pHint params 
    UpdateAllViews(NULL, 0L, NULL);
}

void CMyDoc::OnUpdateViewFilterData(CCmdUI* pCmdUI)
{
    // Enable/Disable as needed
    pCmdUI->Enable(m_nTotalItems>0);
    // Show pressed/checked if data filtered
    pCmdUI->SetCheck(m_bFilterData);
}

现在,如果过滤器选项是按视图实例化的,即每个视图都可以独立过滤或不过滤,则以上内容必须转到您的视图 class(-es):

void CMyView::OnViewFilterData()
{
    // Toggle filtered state
    m_bFilterData = !m_bFilterData;
    // Refresh this view only
    .
    .
}

void CMyView::OnUpdateViewFilterData(CCmdUI* pCmdUI)
{
    // Enable/Disable as needed
    pCmdUI->Enable(GetDocument()->m_nTotalItems > 0);
    // Show pressed/checked if data filtered
    pCmdUI->SetCheck(m_bFilterData);
}