mfc 选项卡控制切换选项卡
Posted
技术标签:
【中文标题】mfc 选项卡控制切换选项卡【英文标题】:mfc tab control switch tabs 【发布时间】:2012-07-31 18:32:31 【问题描述】:我创建了一个简单的选项卡控件,它有 2 个选项卡(每个选项卡都是一个不同的对话框)。问题是我不知道如何在选项卡之间切换(当用户按下Titlu Tab1
以显示我为第一个选项卡制作的对话框时,当它按下Titlu Tab2
以显示我的另一个对话框时)。我添加了一个用于更改项目的处理程序,但我不知道我应该如何访问某种索引或子标签。
Tab1.h
和 Tab2.h
是对话框的标题,仅显示带有每个选项卡名称的静态文本。
我的问题可能有一个明显的答案,但我是 C++ 和 MFC 的真正新手。
这是我的标题:
// CTabControlDlg.h : header file
//
#pragma once
#include "afxcmn.h"
#include "Tab1.h"
#include "Tab2.h"
// CCTabControlDlg dialog
class CCTabControlDlg : public CDialog
// Construction
public:
CCTabControlDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
enum IDD = IDD_CTABCONTROL_DIALOG ;
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
CTabCtrl m_tabcontrol1;
CTab1 m_tab1;
CTab2 m_tab2;
afx_msg void OnTcnSelchangeTabcontrol(NMHDR *pNMHDR, LRESULT *pResult);
;
这是.cpp:
// CTabControlDlg.cpp : implementation file
//
#include "stdafx.h"
#include "CTabControl.h"
#include "CTabControlDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
public:
CAboutDlg();
// Dialog Data
enum IDD = IDD_ABOUTBOX ;
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
;
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
CDialog::DoDataExchange(pDX);
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CCTabControlDlg dialog
CCTabControlDlg::CCTabControlDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCTabControlDlg::IDD, pParent)
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
void CCTabControlDlg::DoDataExchange(CDataExchange* pDX)
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_TABCONTROL, m_tabcontrol1);
BEGIN_MESSAGE_MAP(CCTabControlDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//AFX_MSG_MAP
ON_NOTIFY(TCN_SELCHANGE, IDC_TABCONTROL, &CCTabControlDlg::OnTcnSelchangeTabcontrol)
END_MESSAGE_MAP()
// CCTabControlDlg message handlers
BOOL CCTabControlDlg::OnInitDialog()
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
CTabCtrl* pTabCtrl = (CTabCtrl*)GetDlgItem(IDC_TABCONTROL);
m_tab1.Create(IDD_TAB1, pTabCtrl);
TCITEM item1;
item1.mask = TCIF_TEXT | TCIF_PARAM;
item1.lParam = (LPARAM)& m_tab1;
item1.pszText = _T("Titlu Tab1");
pTabCtrl->InsertItem(0, &item1);
//Pozitionarea dialogului
CRect rcItem;
pTabCtrl->GetItemRect(0, &rcItem);
m_tab1.SetWindowPos(NULL, rcItem.left, rcItem.bottom + 1, 0, 0, SWP_NOSIZE | SWP_NOZORDER );
m_tab1.ShowWindow(SW_SHOW);
// al doilea tab
m_tab2.Create(IDD_TAB2, pTabCtrl);
TCITEM item2;
item2.mask = TCIF_TEXT | TCIF_PARAM;
item2.lParam = (LPARAM)& m_tab1;
item2.pszText = _T("Titlu Tab2");
pTabCtrl->InsertItem(0, &item2);
//Pozitionarea dialogului
//CRect rcItem;
pTabCtrl->GetItemRect(0, &rcItem);
m_tab2.SetWindowPos(NULL, rcItem.left, rcItem.bottom + 1, 0, 0, SWP_NOSIZE | SWP_NOZORDER );
m_tab2.ShowWindow(SW_SHOW);
return TRUE; // return TRUE unless you set the focus to a control
void CCTabControlDlg::OnSysCommand(UINT nID, LPARAM lParam)
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
CAboutDlg dlgAbout;
dlgAbout.DoModal();
else
CDialog::OnSysCommand(nID, lParam);
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CCTabControlDlg::OnPaint()
if (IsIconic())
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
else
CDialog::OnPaint();
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CCTabControlDlg::OnQueryDragIcon()
return static_cast<HCURSOR>(m_hIcon);
void CCTabControlDlg::OnTcnSelchangeTabcontrol(NMHDR *pNMHDR, LRESULT *pResult)
// TODO: Add your control notification handler code here
*pResult = 0;
【问题讨论】:
【参考方案1】:您可以在 MFC 中通过将父对话框设置为 CPropertySheet
和包含的对话框 CPropertyPage
来自动执行此操作。
按照您目前的结构方式,您应该为每个对话框执行一个ShowWindow
,其中一个设置为SW_SHOW
,另一个设置为SW_HIDE
,在您的OnTcnSelchangeTabcontrol
函数中。
【讨论】:
【参考方案2】:您应该添加 Tabcontrol 单击事件并执行以下代码。每个对话框/选项卡的对话框指针 pTab1 和 pTab2。
void CYourClass::OnNMClickTab1(NMHDR *pNMHDR, LRESULT *pResult)
pTab1->ShowWindow(SW_HIDE);
pTab2->ShowWindow(SW_HIDE);
for(int i=0;i<2;i++)
m_tbCtrl.HighlightItem(i,FALSE);
switch(m_tbCtrl.GetCurSel())
case 0: pTab1->ShowWindow(SW_SHOW);break;
case 1: pTab2->ShowWindow(SW_SHOW);break;
m_tbCtrl.HighlightItem(m_tbCtrl.GetCurSel(),TRUE);
*pResult = 0;
【讨论】:
以上是关于mfc 选项卡控制切换选项卡的主要内容,如果未能解决你的问题,请参考以下文章
从单独的 UIViewController 切换 UITabBarController 选项卡[重复]
如何从 MFC 选项卡控件 (TabCtrl) 获取额外数据?