我们知道,CDialogBar兼具对话框和工具条的特征,通过使用对话框编辑器,可以自由地向其对话框模板中添加控件。但是,它不支持OnInitDialog()和DDX机制。本程序从CDialogBar派生一个新类CInitDialogBar,用于解决这个问题,使得对话框条可以像一半对话框那样工作。
事实上,DDX已经在CWnd类中具备,所以,实现派生于CWnd类的CDialogBar就比较容易。
首先,在CInitDialogBar类中重新定义Create函数:
BOOL Create(CWnd * pParentWnd, UINT nIDTemplate, UINT nStyle, UINT nID);
BOOL Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName, UINT nStyle, UINT nID);
下一步,定义一个虚拟函数,用于是OnInitDialog函数的功能。同时,重新声明CWnD的DDX函数 DoDataExchange:
virtual BOOL OnInitDialogBar();
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CInitDialogBar)
protected:
virtual void DoDataExchange(CDataExchange* pDX);
//}}AFX_VIRTUAL
下面是新函数Create的实现代码:
// Let MFC Create the control
// Call the base class Create()
if(!CDialogBar::Create(pParentWnd,
lpszTemplateName, /*(nIDTemplate) for other Create()*/
nStyle, nID))
{
return FALSE;
}
// Since there is no WM_INITDIALOG message we have to call
// our own InitDialog function ourselves after m_hWnd is valid
if(!OnInitDialogBar())
return FALSE;
return TRUE;
下面是调用Create的例子。
首先从CInitDialogBar派生一个新类,并在CMainFrame类的CMainFrame::OnCreate()中编写下面代码:
// CInitDialogBar m_wndDialogBar; in mainframe.h
if (!m_wndDialogBar.Create(this, IDD_DBAR, CBRS_LEFT, 0))
{
TRACE0("Failed to create InitDialogBar\n");
return -1; // fail to create
}
m_wndDialogBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndDialogBar);
下面是使用OnInitDialogBar的一个例子:
BOOL CMainDialogBar::OnInitDialogBar()
{
// Support for DDX mechanism
// If you do not want DDX then
// do not call base class
// All out DDX controls are intialized
// the virtual call to DoDataExchange.
CInitDialogBar::OnInitDialogBar();
// Initialize any controls NOT supported by DDX
// CBitmapButton is one
m_OKButton.AutoLoad(IDOK, this);
return TRUE;
}
void CMainDialogBar:oDataExchange(CDataExchange* pDX)
{
ASSERT(pDX);
CInitDialogBar:oDataExchange(pDX);
// DDX_??? functions to synchronize control with
// data or control object
//{{AFX_DATA_MAP(CAboutDlg)
DDX_Check(pDX, IDC_CHECK1, m_CheckBox);
//}}AFX_DATA_MAP
}
这样,通过调用UpdateData(TRUE),就可以实现变量和控件当前状态之间进行数据交换。下面是CInitDialogBar的全部源码。
实现文件:
//////////////////////////////////////////////////////////////////////
//
// InitDialogBar.h: interface for the CInitDialogBar class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_INITDIALOGBAR_H__46B4D2B3_C982_11D1_8902_0060979C2EFD__INCLUDED_)
#define AFX_INITDIALOGBAR_H__46B4D2B3_C982_11D1_8902_0060979C2EFD__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
////////////////////////////////////////////////////////////////////////////
//
// CInitDialogBar window
//
////////////////////////////////////////////////////////////////////////////
class CInitDialogBar : public CDialogBar
{
DECLARE_DYNAMIC(CInitDialogBar)
// Construction / Destruction
public:
CInitDialogBar();
virtual ~CInitDialogBar();
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CInitDialogBar)
protected:
virtual void DoDataExchange(CDataExchange* pDX);
//}}AFX_VIRTUAL
// Implementation
public:
BOOL Create(CWnd * pParentWnd, UINT nIDTemplate, UINT nStyle, UINT
nID);
BOOL Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName, UINT
nStyle, UINT nID);
protected:
virtual BOOL OnInitDialogBar();
// Generated message map functions
protected:
//{{AFX_MSG(CInitDialogBar)
// NOTE - the ClassWizard will add and remove member functions
here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
////////////////////////////////////////////////////////////////////////////
/
#endif // !defined(AFX_INITDIALOGBAR_H__46B4D2B3_C982_11D1_8902_0060979C2EFD__INCLUDED_)
////////////////////////////////////////////////////////////////////////////
//
// InitDialogBar.cpp: implementation of the CInitDialogBar class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "spectra.h"
#include "InitDialogBar.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CInitDialogBar, CDialogBar)
BEGIN_MESSAGE_MAP(CInitDialogBar, CDialogBar)
//{{AFX_MSG_MAP(CInitDialogBar)
// NOTE - the ClassWizard will add and remove mapping macros
here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
CInitDialogBar::CInitDialogBar()
{
// In derived classes set intial
// state of control(s) here
}
CInitDialogBar::~CInitDialogBar()
{
}
BOOL CInitDialogBar::Create(CWnd * pParentWnd, LPCTSTR lpszTemplateName,
UINT nStyle, UINT nID)
{
// Let MFC Create the control
if(!CDialogBar::Create(pParentWnd, lpszTemplateName, nStyle, nID))
return FALSE;
// Since there is no WM_INITDIALOG message we have to call
// our own InitDialog function ourselves after m_hWnd is valid
if(!OnInitDialogBar())
return FALSE;
return TRUE;
}
BOOL CInitDialogBar::Create(CWnd * pParentWnd, UINT nIDTemplate,
UINT nStyle, UINT nID)
{
if(!Create(pParentWnd, MAKEINTRESOURCE(nIDTemplate), nStyle, nID))
return FALSE;
// Since there is no WM_INITDIALOG message we have to call
// our own InitDialog function ourselves after m_hWnd is valid
if(!OnInitDialogBar())
return FALSE;
return TRUE;
}
BOOL CInitDialogBar::OnInitDialogBar()
{
// Support for the MFC DDX model
// If you do not want this do not call the base class
// from derived classes
UpdateData(FALSE);
return TRUE;
}
void CInitDialogBar:oDataExchange(CDataExchange* pDX)
{
//Derived Classes Overide this function
ASSERT(pDX);
CDialogBar:oDataExchange(pDX);
// In derived class call the DDX_??? functions to set/retrieve values
// of your controls. See example derived class for how to do this.
}
头文件:
//////////////////////////////////////////////////////////////////////
//
// MainDialogBar.h: interface for the CMainDialogBar class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_MAINDIALOGBAR_H__46B4D2B3_C982_11D1_8902_0060979C2EFD__INCLUDED_)
#define AFX_MAINDIALOGBAR_H__46B4D2B3_C982_11D1_8902_0060979C2EFD__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#include "InitDialogBar.h"
// CMainDialogBar window
class CMainDialogBar : public CInitDialogBar
{
DECLARE_DYNAMIC(CMainDialogBar)
// Construction
public:
CMainDialogBar();
virtual ~CMainDialogBar();
// Attributes
public:
protected:
// Control Objects
CBitmapButton m_OKButton;
// Control Variables
BOOL m_CheckBox;
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMainDialogBar)
protected:
virtual void DoDataExchange(CDataExchange* pDX);
//}}AFX_VIRTUAL
protected:
virtual BOOL OnInitDialogBar();
// Implementation
public:
// Generated message map functions
protected:
//{{AFX_MSG(CMainDialogBar)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
////////////////////////////////////////////////////////////////////////////
/
#endif // !defined(AFX_MAINDIALOGBAR_H__46B4D2B3_C982_11D1_8902_0060979C2EFD__INCLUDED_)
////////////////////////////////////////////////////////////////////////////
//
// MainDialogBar.cpp: implementation of the CMainDialogBar class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "spectra.h"
#include "MainDialogBar.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CMainDialogBar, CInitDialogBar)
BEGIN_MESSAGE_MAP(CMainDialogBar, CInitDialogBar)
//{{AFX_MSG_MAP(CMainDialogBar)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
CMainDialogBar::CMainDialogBar()
{
//Set Initial conditions for controls
m_CheckBox = 1;
}
CMainDialogBar::~CMainDialogBar()
{
}
BOOL CMainDialogBar::OnInitDialogBar()
{
// Support for DDX mechanism
// If you do not want DDX then
// do not call base class
CInitDialogBar::OnInitDialogBar();
// Update any controls NOT supported by DDX
// CBitmapButton is one
m_OKButtton.AutoLoad(IDOK, this);
return TRUE;
}
void CMainDialogBar:oDataExchange(CDataExchange* pDX)
{
ASSERT(pDX);
CInitDialogBar:oDataExchange(pDX);
// DDX_??? functions to associate control with
// data or control object
// Call UpdateData(TRUE) to get data at any time
// Call UpdateData(FALSE) to set data at any time
//{{AFX_DATA_MAP(CAboutDlg)
DDX_Check(pDX, IDC_CHECK1, m_CheckBox);
//}}AFX_DATA_MAP
}
|