如何在每个 CMFCTabCtrl 选项卡标题中放置复选框
Posted
技术标签:
【中文标题】如何在每个 CMFCTabCtrl 选项卡标题中放置复选框【英文标题】:How to put checkbox in each CMFCTabCtrl's tab header 【发布时间】:2018-06-20 07:05:01 【问题描述】:我有一个 MFC 应用程序。我在对话框中使用 CMFCTabCtrl。
我的要求是我必须在 CMFCTabCtrl 的每个标签页中添加一个复选框,如下所示。
是否可以在 CMFCTabCtrl 的每个标签页中添加复选框?
【问题讨论】:
【参考方案1】:您无法通过在当前 CMFCTabCtrl
上创建复选框窗口来执行此操作。
我的建议是:
-
实现您自己的
Draw3dFlat
或Draw3dTab
函数。此功能应将复选框绘制到选项卡表面。
您可以覆盖AdjustTabs
以将它们调整为您想要的大小。
实现您自己的 OnLButtonDown
处理程序,用于跟踪用户是否点击了您的复选框...
您拥有所有原始源代码,使用现有代码应该可以实现这一点。
【讨论】:
【参考方案2】:我的问题已在以下链接中得到解答。
https://social.msdn.microsoft.com/Forums/vstudio/en-US/2b86a6df-12bb-4fe2-9f23-d9848de49f84/adding-checkbox-in-cmfctabctrls-tab-header?forum=vcgeneral#000673ca-c995-42d8-85c2-cb4781090653
代码是
BOOL CMyDlg::OnInitDialog()
CDialogEx::OnInitDialog();
// TODO: Add extra initialization here
CRect rectDummy;
rectDummy.SetRectEmpty();
if(!m_tab.Create(CMFCTabCtrl::STYLE_3D_VS2005, rectDummy, this, 1))
TRACE0("Failed to create output tab window\n");
return -1; // fail to create
m_tab.SetResizeMode(CMFCTabCtrl::RESIZE_NO);
m_tab.SetLocation(CMFCTabCtrl::LOCATION_TOP);
CRect rc;
GetClientRect(rc);
m_tab.MoveWindow(0, 200, rc.right, 200);
const DWORD dwStyle = LBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL;
if (!m_wndOutputBuild.Create(dwStyle, rectDummy, &m_tab, 2) ||
!m_wndOutputDebug.Create(dwStyle, rectDummy, &m_tab, 3) ||
!m_wndOutputFind.Create(dwStyle, rectDummy, &m_tab, 4))
TRACE0("Failed to create output windows\n");
return -1; // fail to create
CString strTabName;
BOOL bNameValid;
// Attach list windows to tab:
m_tab.AddTab(&m_wndOutputBuild, L" First", (UINT)0);
m_tab.AddTab(&m_wndOutputDebug, L" Second", (UINT)1);
m_tab.AddTab(&m_wndOutputFind, L" Third", (UINT)2);
m_tab.init();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
myTabCtrl.h
#pragma once
#include "afxtabctrl.h"
class myTabCtrl : public CMFCTabCtrl
public:
myTabCtrl();
~myTabCtrl();
void init();
DECLARE_MESSAGE_MAP()
CButton m_Check1;
CButton m_Check2;
CButton m_Check3;
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
; myTabCtrl.cpp
#include "stdafx.h"
#include "myTabCtrl.h"
myTabCtrl::myTabCtrl()
myTabCtrl::~myTabCtrl()
void myTabCtrl::init()
CRect rc1, rc2, rc3;
GetTabRect(0, rc1);
GetTabRect(1, rc2);
GetTabRect(2, rc3);
m_Check1.Create(_T("Chkbox1"), WS_CHILD | WS_VISIBLE | BS_CHECKBOX, CRect(0, 0, 13, 13), this, 1234);
m_Check2.Create(_T("Chkbox2"), WS_CHILD | WS_VISIBLE | BS_CHECKBOX, CRect(0, 0, 13, 13), this, 1235);
m_Check3.Create(_T("Chkbox3"), WS_CHILD | WS_VISIBLE | BS_CHECKBOX, CRect(0, 0, 13, 13), this, 1236);
m_Check1.MoveWindow(rc1.left + 20, rc1.top + 3, 13, 13);
m_Check2.MoveWindow(rc2.left + 20, rc2.top + 3, 13, 13);
m_Check3.MoveWindow(rc3.left + 20, rc3.top + 3, 13, 13);
BEGIN_MESSAGE_MAP(myTabCtrl, CMFCTabCtrl)
END_MESSAGE_MAP()
LRESULT myTabCtrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
// TODO: Add your specialized code here and/or call the base class
switch (message)
case WM_COMMAND:
if (wParam == 1234)
BOOL checked = m_Check1.GetCheck();
m_Check1.SetCheck(!checked);
else if (wParam == 1235)
BOOL checked = m_Check2.GetCheck();
m_Check2.SetCheck(!checked);
else if (wParam == 1236)
BOOL checked = m_Check3.GetCheck();
m_Check3.SetCheck(!checked);
break;
return CMFCTabCtrl::WindowProc(message, wParam, lParam);
【讨论】:
以上是关于如何在每个 CMFCTabCtrl 选项卡标题中放置复选框的主要内容,如果未能解决你的问题,请参考以下文章
如何更改 CMFCtabCtrl 的 TabbedDocumentsMenu 上的工具提示“活动文件”?