另类的CDialogBar——可停靠对话框的实现方法

         本文大部分思路来自于《VISUAL C++ 6.0 MFC 类库参考手册》一书!

         CDialogBar在MFC中就是提供控制条形式的非模态对话框。

         其使用过程很简单:

         1.在MainFrame框架中声明变量 

             

        CDialogBar m_dialogbar;

         2.在MainFrame的OnCreate函数中创建

          

        EnableDocking(CBRS_ALIGN_ANY);
	if (!m_dialogbar.Create(this,IDD_PREV,WS_CHILD|WS_VISIBLE|CBRS_TOOLTIPS|CBRS_LEFT|CBRS_SIZE_DYNAMIC|CBRS_FLYBY,IDD_PREV))
	{
		TRACE0("控制栏创建失败!");
		return -1;
	}
	m_dialogbar.EnableDocking(CBRS_ALIGN_LEFT);
	DockControlBar(&m_dialogbar);
          其中IDD_PREV为在资源中加入的对话框ID

        这样确实可以创建一个可以停靠的对话框条,但是同时这个对话框条有很多问题:

        1.在该对话框上添加的按钮都会呈灰色,无论你是否给该按钮添加消息响应函数。

        2.你为该对话框重载了OnInitDialog()后发现仍然无法初始化对话框


       1的原因是因为CDialogBar对话框的消息响应是由MainFrame处理,所以你在当前对话框下给按钮绑定消息响应是不会响应的!

       2的原因是因为CDialogBar是CContorlBar的子类,而非CDialog的子类,无法重载OnInitDialog()。(网上有解决办法可以让其初始化,点击打开链接)

         

       为了让创建的对话框条能够像一般对话框那样响应消息,本文给的思路是采用多级嵌套,将一个可以响应消息的对话框覆盖在对话框条上。

       为此我们需要创建如下几个类

      1.CDialogBarExt             继承于CDialogBar

      2.CDlgContainer            对话框容器类,

      3.CInnerDlg                     要嵌套的对话框类(相应的对话框资源)

      下面分别是这三个类的代码

       DialogBar.h

#pragma once

#include "DlgContainer.h"
// CDialogBarExt

class CDialogBarExt : public CDialogBar
{
	DECLARE_DYNAMIC(CDialogBarExt)

public:
	CDlgContainer m_Container;
	CDialogBarExt();
	virtual ~CDialogBarExt();

protected:
	DECLARE_MESSAGE_MAP()
public:
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
};

     DialogBar.cpp

// DialogBarExt.cpp : 实现文件
//

#include "stdafx.h"
#include "MagicHouse.h"
#include "DialogBarExt.h"


// CDialogBarExt

IMPLEMENT_DYNAMIC(CDialogBarExt, CDialogBar)

CDialogBarExt::CDialogBarExt()
{

}

CDialogBarExt::~CDialogBarExt()
{
}


BEGIN_MESSAGE_MAP(CDialogBarExt, CDialogBar)
	ON_WM_CREATE()
END_MESSAGE_MAP()



// CDialogBarExt 消息处理程序




int CDialogBarExt::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CDialogBar::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  在此添加您专用的创建代码
	m_Container.Create (NULL,(LPCTSTR)"",WS_CHILD|WS_VISIBLE|WS_BORDER,CRect (0,10,203,500),this,0,NULL);
	return 0;
}
   DlgContainer.h
#pragma once

#include "InnerDlg.h"
// CDlgContainer

class CDlgContainer : public CWnd
{
	DECLARE_DYNAMIC(CDlgContainer)

public:
	CDlgContainer();
    CInnerDlg m_InnerDlg;
	virtual ~CDlgContainer();

protected:
	DECLARE_MESSAGE_MAP()
public:
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnPaint();
};

    DlgContainer.cpp

// DlgContainer.cpp : 实现文件
//

#include "stdafx.h"
#include "MagicHouse.h"
#include "DlgContainer.h"


// CDlgContainer

IMPLEMENT_DYNAMIC(CDlgContainer, CWnd)

CDlgContainer::CDlgContainer()
{

}

CDlgContainer::~CDlgContainer()
{
}


BEGIN_MESSAGE_MAP(CDlgContainer, CWnd)
	ON_WM_CREATE()
	ON_WM_PAINT()
END_MESSAGE_MAP()



// CDlgContainer 消息处理程序




int CDlgContainer::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  在此添加您专用的创建代码
	m_InnerDlg.Create(IDD_INNERDLG,this);
	m_InnerDlg.ShowWindow(SW_NORMAL);
	return 0;
}


void CDlgContainer::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	// TODO: 在此处添加消息处理程序代码
	CRect rect;
	CBrush brush;

	brush.CreateSolidBrush (RGB (128,128,128));

	GetClientRect (rect);

	dc.FillRect (rect,&brush);
	// 不为绘图消息调用 CWnd::OnPaint()
}
    InnerDlg.h

#pragma once


// CInnerDlg 对话框

class CInnerDlg : public CDialog
{
	DECLARE_DYNAMIC(CInnerDlg)

public:
	CInnerDlg(CWnd* pParent = NULL);   // 标准构造函数
	virtual ~CInnerDlg();

// 对话框数据
	enum { IDD = IDD_INNERDLG };

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

	DECLARE_MESSAGE_MAP()
public:
	virtual BOOL OnInitDialog();	
	afx_msg void OnPaint();
};
  InnerDlg.cpp

// InnerDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "MagicHouse.h"
#include "InnerDlg.h"
#include "afxdialogex.h"


// CInnerDlg 对话框

IMPLEMENT_DYNAMIC(CInnerDlg, CDialog)

CInnerDlg::CInnerDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CInnerDlg::IDD, pParent)
	, posY(0)
{

}

CInnerDlg::~CInnerDlg()
{
}

void CInnerDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(CInnerDlg, CDialog)
	ON_WM_PAINT()
END_MESSAGE_MAP()


// CInnerDlg 消息处理程序


BOOL CInnerDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// TODO:  在此添加额外的初始化
	CWnd *pParent=GetParent();
	CRect rc_parent;
	pParent->GetClientRect(&rc_parent);

	// SET INITIAL POSITION OF THE DIALOG
	SetWindowPos(NULL, 0, 
		0, 
		rc_parent.right,
		rc_parent.bottom, SWP_SHOWWINDOW);
	return TRUE;  // return TRUE unless you set the focus to a control
	// 异常: OCX 属性页应返回 FALSE
}


void CInnerDlg::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	// TODO: 在此处添加消息处理程序代码
	// 不为绘图消息调用 CDialog::OnPaint()
}

    如此一来,我们在MainFrame中声明如下变量

      

    CDialogBarExt m_dialogbar;

    并在OnCreate中创建该控制条即可!
 



你可能感兴趣的:(c,框架,null,Class,mfc,border)