码迷,mamicode.com
首页 > 编程语言 > 详细

MFC 静态拆分视图窗口

时间:2021-06-05 17:47:03      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:else   图标   imp   int()   ase   min   use   vat   静态   

今天学习了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);
};


#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()
};

在类外分别加上实现宏

//CSelectView类

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

IMPLEMENT_DYNCREATE(CSelectView,CTreeView)


//窗口类
#include "resource.h"
#include "CMyDialog.h"


// CMyDialog

IMPLEMENT_DYNCREATE(CMyDialog, CFormView)

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

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);  //获取选中项的字符串数据
    //根据选择的项发送自定义消息(NM_A,NM_B)来更改右边的视图窗口类
  //我就随便定义了两个消息NM_A,NM_B,都响应OnMyChange函数
  
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;
}

 

 

效果:

技术图片

 

 

 

技术图片

 

 

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

 

MFC 静态拆分视图窗口

标签:else   图标   imp   int()   ase   min   use   vat   静态   

原文地址:https://www.cnblogs.com/greenleaf1976/p/14851446.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!