标签: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; }
效果:
这样就方便用对话框来拖拽控件来布局界面
标签:else 图标 imp int() ase min use vat 静态
原文地址:https://www.cnblogs.com/greenleaf1976/p/14851446.html