如何将数据放入TabControl(MFC)中的控件元素中



MFC中基于对话框的应用程序上有TabControl。

每个选项卡页面都创建为一个对话框。

这是其中一个页面的代码:

class CTabPage1 : public CDialogEx
{
    DECLARE_DYNAMIC(CTabPage1)
public:
    CTabPage1(CWnd* pParent = NULL);   // standard constructor
    virtual ~CTabPage1();
// Dialog Data
    enum { IDD = IDD_TABPAGE1 };
protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    DECLARE_MESSAGE_MAP()
public:
    CComboBox *m_pStyles;
public:
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
};

这就是实现:

#include "stdafx.h"
#include "TestProject.h"
#include "TestProjectDlg.h"
#include "TabPage1.h"
#include "afxdialogex.h"

// CTabPage1 dialog

IMPLEMENT_DYNAMIC(CTabPage1, CDialogEx)
CTabPage1::CTabPage1(CWnd* pParent /*=NULL*/)
    : CDialogEx(CTabPage1::IDD, pParent)
{    
    m_pStyles = new CComboBox;
}

CTabPage1::~CTabPage1()
{
}
void CTabPage1::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_COMBO1, *m_pStyles);
}
BEGIN_MESSAGE_MAP(CTabPage1, CDialogEx)
    ON_WM_CREATE()
END_MESSAGE_MAP()
// CTabPage1 message handlers
int CTabPage1::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    m_pStyles->AddString("aaa");
    UpdateData(0);
    return 0;
}

编译是可以的,但当尝试运行此代码时调试断言失败!

据我所知,断言来自dlgcore.cpp,函数:

    hWnd = ::CreateDialogIndirect(hInst, lpDialogTemplate,
        pParentWnd->GetSafeHwnd(), AfxDlgProc);

请告诉我,错误在哪里?如何将数据放入m_pStyle组合框?也许应该用另一种方法。。。

此外。以下是主对话框的代码:头文件:

#pragma once
#include "afxcmn.h"
#include "TabPage1.h"

// CTestProjectDlg dialog
class CTestProjectDlg : public CDialogEx
{
// Construction
public:
    CTestProjectDlg(CWnd* pParent = NULL);  // standard constructor
// Dialog Data
    enum { IDD = IDD_TESTPROJECT_DIALOG };
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
// Implementation
protected:
    HICON m_hIcon;  
    CTabCtrl m_Tabs;                 
    CTabPage1 *m_pStyles;       
    // Generated message map functions
    virtual BOOL OnInitDialog();
    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    afx_msg BOOL DestroyWindow();
    DECLARE_MESSAGE_MAP();
public:
    afx_msg void OnSelchangeTab1(NMHDR *pNMHDR, LRESULT *pResult);
    afx_msg void OnSelchangingTab1(NMHDR *pNMHDR, LRESULT *pResult);
};

和源文件:

#include "stdafx.h"
#include "TestProject.h"
#include "TestProjectDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CAboutDlg dialog used for App About
class CAboutDlg : public CDialogEx
{
public:
    CAboutDlg();
// Dialog Data
    enum { IDD = IDD_ABOUTBOX };
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
// Implementation
protected:
    DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()

// CTestProjectDlg dialog


CTestProjectDlg::CTestProjectDlg(CWnd* pParent /*=NULL*/)
    : CDialogEx(CTestProjectDlg::IDD, pParent)
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    m_pTabPage1 = new CTabPage1;         
}
void CTestProjectDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_TAB1, m_Tabs);
}
BEGIN_MESSAGE_MAP(CTestProjectDlg, CDialogEx)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, &CTestProjectDlg::OnSelchangeTab1)
    ON_NOTIFY(TCN_SELCHANGING, IDC_TAB1, &CTestProjectDlg::OnSelchangingTab1)
END_MESSAGE_MAP()

// CTestProjectDlg message handlers
BOOL CTestProjectDlg::OnInitDialog()
{
    CDialogEx::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)
    {
        BOOL bNameValid;
        CString strAboutMenu;
        bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
        ASSERT(bNameValid);
        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

    TC_ITEM tci;                
    tci.mask = TCIF_TEXT;
    tci.iImage = -1;
    tci.pszText = "Page1";          
    m_Tabs.InsertItem(0, &tci);     
    tci.pszText = "Page2";        
    m_Tabs.InsertItem(1, &tci);    

    // first TabPage
    tci.mask = TCIF_PARAM;
    tci.lParam = (LPARAM)m_pTabPage1;
    m_Tabs.SetItem(0, &tci);
    m_pTabPage1->Create(CTabPage1::IDD, &m_Tabs);
    m_pTabPage1->SetWindowPos(NULL, 30, 30, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
    m_pTabPage1->ShowWindow(SW_HIDE);   
    // Second TabPage
    tci.mask = TCIF_PARAM;
    tci.lParam = (LPARAM)m_pTabPage2;
    m_Tabs.SetItem(1, &tci);
    m_pTabPage2->Create(CTabPage2::IDD, &m_Tabs);
    m_pTabPage2->SetWindowPos(NULL, 30, 30, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
    m_pTabPage2->ShowWindow(SW_SHOW);
    return TRUE;  // return TRUE  unless you set the focus to a control
}
void CTestProjectDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {
        CAboutDlg dlgAbout;
        dlgAbout.DoModal();
    }
    else
    {
        CDialogEx::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 CTestProjectDlg::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
    {
        CDialogEx::OnPaint();
    }
}
// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CTestProjectDlg::OnQueryDragIcon()
{
    return static_cast<HCURSOR>(m_hIcon);
}

void CTestProjectDlg::OnSelchangeTab1(NMHDR *pNMHDR, LRESULT *pResult)
{
    // TODO: Add your control notification handler code here
    int iTab = m_Tabs.GetCurSel();
    TC_ITEM tci;
    tci.mask = TCIF_PARAM;
    m_Tabs.GetItem(iTab, &tci);
    CWnd* pWnd = (CWnd *)tci.lParam;
    pWnd->ShowWindow(SW_SHOW); 
    *pResult = 0;
}
void CTestProjectDlg::OnSelchangingTab1(NMHDR *pNMHDR, LRESULT *pResult)
{
    // TODO: Add your control notification handler code here
    int iTab = m_Tabs.GetCurSel();
    TC_ITEM tci;
    tci.mask = TCIF_PARAM;
    m_Tabs.GetItem(iTab, &tci);
    CWnd* pWnd = (CWnd *)tci.lParam;
    pWnd->ShowWindow(SW_HIDE); 
    *pResult = 0;
}
BOOL CTestProjectDlg::DestroyWindow() 
{
    delete m_pTabPage1;
    return CDialog::DestroyWindow();
}

当我把组合框放在主对话框窗口上并尝试添加数据时,它就起作用了。但是选项卡页面上的对话框是一个子对话框。在这种情况下,它可能不会为其控件调用一些初始化函数?因为在调试模式下,我可以看到对象m_pStyles,但不能看到它的属性?

也许有一些关于如何使用TabControl的教程?

答案很简单:只需使用另一个处理程序来初始化控件,而不是OnCreate,而是OnShow。(对象没有创建,但我想用它做点什么)。

最新更新