MFC 静态拆分视图窗口

MFC 静态拆分视图窗口

今天学习了MFC中拆分窗口,现将方法记录下.

想要在窗口视图中拆分成左右两个视图窗口,首先要注意的是拆分后要加载到左右的视图要符合动态创建的类,

也就是要在自己创建的视图类中添加动态创建机制宏.

类内声明宏:

DECLARE_DYNCREATE(CSelectView)     //CSelectView为自己创建的视图类

类外实现宏:

IMPLEMENT_DYNCREATE(CSelectView,CTreeView)  //CTreeView为父类

**

1.创建两个自己的视图类,

**

CSelectView继承于CTreeView

CMyDialg继承于CFromView

CSelectView用于树形控件显示,没啥可说的.着重说下,对话框的视图类,要注意是子窗口,无边框.所以在窗口属性中要把.Border设置为None,Style设置为Child

下面是两个类的声明:

#pragma once
#include <afxcview.h>	//树形视图类头文件
class CSelectView :
	public CTreeView
{
	DECLARE_DYNCREATE(CSelectView)
	CSelectView();
protected:
	//virtual void OnDraw(CDC* pDC) override;
private:
	CTreeCtrl *m_pTreeCtrl;
public:
	virtual void OnInitialUpdate();
	DECLARE_MESSAGE_MAP()
	afx_msg void OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult);
};

#pragma once
#include <afxext.h>	//对话框视图类头文件

// CMyDialog 窗体视图

class CMyDialog : public CFormView
{
	DECLARE_DYNCREATE(CMyDialog)

protected:
	CMyDialog();           // 动态创建所使用的受保护的构造函数
	virtual ~CMyDialog();


	virtual void OnDraw(CDC* pDC) override;

public:
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_DIALOG1 };
#endif
#ifdef _DEBUG
	virtual void AssertValid() const;
#ifndef _WIN32_WCE
	virtual void Dump(CDumpContext& dc) const;
#endif
#endif


	virtual void OnDragLeave() override;

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

	DECLARE_MESSAGE_MAP()
};

在类外分别加上实现宏

#include "CSelectView.h"
#include "MyApp.h"

IMPLEMENT_DYNCREATE(CSelectView,CTreeView)

CSelectView::CSelectView()
{

}
#include "resource.h"
#include "CMyDialog.h"


// CMyDialog

IMPLEMENT_DYNCREATE(CMyDialog, CFormView)

CMyDialog::CMyDialog()
	: CFormView(IDD_DIALOG1)
{

}

注意,如果父类中有纯虚函数要在自己创建的类中实现,不然无法动态创建类对象

2.在主框架类中重写OnCreateClient()函数

//m_splitter:为类的成员变量:

CSplitterWnd m_splitter;

BOOL MyWnd::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
	//拆分窗口(一行两列)
	m_splitter.CreateStatic(this, 1, 2);
	//创建视图类对象
	m_splitter.CreateView(0, 0, RUNTIME_CLASS(CSelectView),
		CSize(200, 200), pContext);
	m_splitter.CreateView(0, 1, RUNTIME_CLASS(CMyDialog),
		CSize(200, 200), pContext);

	return TRUE;
}

这样就把主窗口拆分成左右两个视图窗口了,中间的分隔栏可以用鼠标左右拖动

在这里插入图片描述

在这里插入图片描述

3.加载数据到树形视图中

树形视图类要加载数据就要在初始化函数OnInitialUpdate()中

首先要定义一个CTreeCtrl类型的控件,用来操作数据

在树形视图类中添加

CTreeCtrl*  m_treeCtrl;

在OnInitialUpdate()中添加数据加载


void CSelectView::OnInitialUpdate()
{
	CTreeView::OnInitialUpdate();

	// TODO: 在此添加专用代码和/或调用基类
	m_pTreeCtrl = &GetTreeCtrl();

	m_pTreeCtrl->ModifyStyle(0, TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS| TVS_SHOWSELALWAYS);

	m_pTreeCtrl->InsertItem(TEXT("显示数据"), 0,0,TVI_ROOT);
	m_pTreeCtrl->InsertItem(TEXT("添加数据"), 0, 0, TVI_ROOT);
	m_pTreeCtrl->InsertItem(TEXT("修改数据"), 0, 0, TVI_ROOT);
	m_pTreeCtrl->InsertItem(TEXT("删除数据"), 0, 0, TVI_ROOT);

}

4.更改右边的视图类

根据左边树形视图中的选择,右边更改相应的窗口视图类

在树视图的OnTvnSelchanged函数中处理选择项改变的事件

在主框架类中定义自定义消息用

//自定义消息
#define NM_A   (WM_USER+100)
#define NM_B   (WM_USER+101)
#define NM_C   (WM_USER+102)

在这里插入代码片
void CSelectView::OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;
	HTREEITEM hSel = pNMTreeView->itemNew.hItem;
	CString str = m_pTreeCtrl->GetItemText(hSel);
	//MessageBox(str);
	if (str == TEXT("添加数据"))
	{
		::PostMessage(AfxGetMainWnd()->GetSafeHwnd(),NM_A, (WPARAM)NM_A, 0);
	}
	else if (str == TEXT("修改数据"))
	{
		::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), NM_B, (WPARAM)NM_B, 0);
	}

}

在主框架中捕获消息


BEGIN_MESSAGE_MAP(MyWnd,CFrameWnd)
	ON_WM_CREATE()
	ON_COMMAND(ID_BTN_NEW,&MyWnd::OnBtnNew)
	ON_COMMAND(ID_BTN_EDIT,&MyWnd::OnBtnEdit)
	ON_COMMAND(ID_BTN_DELETE,&MyWnd::OnBtnDelete)
	ON_COMMAND(ID_BTN_QUIT,&MyWnd::OnBtnQuit)
	ON_COMMAND(ID_BTN_MIN,&MyWnd::OnBtnMin)
	ON_COMMAND(ID_BTN_FIND,&MyWnd::OnBtnFind)
	ON_WM_PAINT()
	ON_MESSAGE(NM_A,&MyWnd::OnMyChange)	//添加自定义消息函数
	ON_MESSAGE(NM_B,&MyWnd::OnMyChange)	//添加自定义消息函数
	ON_WM_SIZE()
END_MESSAGE_MAP()

在OnMyChange中实现窗口视图类的切换

LRESULT MyWnd::OnMyChange(WPARAM wParam, LPARAM lParam)
{
    CCreateContext context;//动态创建机制结构体
    switch (wParam)
    {
    case NM_A://创建IDD_DIALOG1对话框视图类CMyDialog 
    {
        context.m_pNewViewClass = RUNTIME_CLASS(CMyDialog);//要创建的视图类
        context.m_pCurrentFrame = this;    //当前窗口类
        context.m_pLastView = (CFormView*)m_splitter.GetPane(0, 1); //要在哪列创建新的视图类,(我这是要在右边,也就是第0行1列)
        m_splitter.DeleteView(0, 1);  //删除原来的视图类
        m_splitter.CreateView(0, 1, RUNTIME_CLASS(CMyDialog), CSize(200, 200), &context);  //动态创建新的视图类(大小无所谓,最后都是平铺分隔的左右窗口)
        CMyDialog *pNewView = (CMyDialog*)m_splitter.GetPane(0, 1); //获取新创建的视图类对象
        m_splitter.RecalcLayout();  
        pNewView->OnInitialUpdate();  //初始化新视图类
        m_splitter.SetActivePane(0, 1);  //激活新的视图类

    }
        break;
    case NM_B: //创建IDD_DIALGO2对话框视图类MyAddDlg
    {
        context.m_pNewViewClass = RUNTIME_CLASS(MyAddDlg);
        context.m_pCurrentFrame = this;
        context.m_pLastView = (CFormView*)m_splitter.GetPane(0, 1);
        m_splitter.DeleteView(0, 1);
        m_splitter.CreateView(0, 1, RUNTIME_CLASS(MyAddDlg), CSize(200, 200), &context);
        MyAddDlg *pNewView = (MyAddDlg*)m_splitter.GetPane(0, 1);
        m_splitter.RecalcLayout();
        pNewView->OnInitialUpdate();
        m_splitter.SetActivePane(0, 1);

    }
        break;
    case NM_C:
        break;
    }
    /*if (wParam == NM_A)
    {
        MessageBox(TEXT("添加数据"));
    }
    else if(wParam==NM_B){
        MessageBox(TEXT("修改数据"));
    }*/

    return 0;
}

效果:

在这里插入图片描述

在这里插入图片描述

这样就方便用对话框来拖拽控件来布局界面

签名:GreenLeaf1976

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值