MFC第二十九天 CView类的分支(以及其派生类的功能)、MFC六大关键技术

文章目录

  • CView类的分支
    • CEditView
    • CHtmlView
      • MainFrm.h CMainFrame 类的接口
      • CMainView .h
    • CListCtrl与CListView的创建原理
  • CTreeView
    • CTreeCtrl类简介
    • CTreeCtrl类的原理以及常用功能
  • MFC六大关键技术
  • 视图和带分割栏的框架开发与消息路由
    • CLeftView.cpp
    • CRightView.h
    • CRightView.cpp
    • CWelcome .h
    • CWelcome.cpp
    • division.h
    • division.cpp
    • MainFrm.h
    • MainFrm.cpp
  • 附录:为什么用户点击一下视图,即可让菜单有效?

CView类的分支

CEditView

对CMainView使用了CEditView类的派生,对其默认字体进行改变。

#include "CMainView.h"BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{CCreateContext cc;cc.m_pNewViewClass = RUNTIME_CLASS(CMainView);CreateView(&cc);return CFrameWnd::OnCreateClient(lpcs, pContext);
}
// CMainView 视图
class CMainView : public CEditView
{DECLARE_DYNCREATE(CMainView)protected:CMainView();           // 动态创建所使用的受保护的构造函数virtual ~CMainView();protected:DECLARE_MESSAGE_MAP()
public:virtual void OnInitialUpdate();afx_msg void OnEnChange();
};
void CMainView::OnInitialUpdate()
{CEditView::OnInitialUpdate();auto hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);SetFont(CFont::FromHandle(hFont), FALSE); //CFont::FromHandle(hFont) 将句柄转为指针 临时外壳}

在这里插入图片描述
在这里插入图片描述

CHtmlView

需要添加#include <afxhtml.h>头文件

MainFrm.h CMainFrame 类的接口

#pragma once
class CMainView;
class CMainFrame : public CFrameWnd
{CMainView* m_pMainView;
}
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{CCreateContext cc;cc.m_pNewViewClass = RUNTIME_CLASS(CMainView);m_pMainView =(CMainView*)CreateView(&cc);return  m_pMainView!=NULL;
}
BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{// 让视图第一次尝试该命令if (m_pMainView && m_pMainView->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))return TRUE;// 否则,执行默认处理return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}

CMainView .h

class CMainView : public CHtmlView
{DECLARE_DYNCREATE(CMainView)
}
#include "pch.h"
#include "Browse.h"
#include "CMainView.h"void CMainView::OnInitialUpdate()
{CHtmlView::OnInitialUpdate();Navigate2(_T("www.baidu.com")); //导航到目标地址上}

在这里插入图片描述

CListCtrl与CListView的创建原理

a)CListCtrl的内部创建原理是通过CWnd::Create(sClassName,…)来实现的。
b)CStatic,CEdit,CButton的内部创建原理无一不是这个原理,即使是拖入对话框的控件底层也是这样实现的。
(通过.rc读取风格和位置等要素,再调用CWnd类的Create函数)
c)CListView和CTreeView整个类都几乎没有代码,其实就是一个变种的CListCtrl或者CTreeCtrl。
d)所以你会看到直接强转:

INLINE CListCtrl& CListView::GetListCtrl() const{ return *(CListCtrl*)this; }

CListView和CTreeView的原理

// CListView
_AFXCVIEW_INLINE CListView::CListView() : CCtrlView(WC_LISTVIEW,AFX_WS_DEFAULT_VIEW){ }_AFXCVIEW_INLINE CListCtrl& CListView::GetListCtrl() const{ return *(CListCtrl*)this; }
_AFXCVIEW_INLINE CTreeView::CTreeView() : CCtrlView(WC_TREEVIEW,AFX_WS_DEFAULT_VIEW){ }_AFXCVIEW_INLINE CTreeCtrl& CTreeView::GetTreeCtrl() const{ return *(CTreeCtrl*)this; }

CTreeView

CTreeCtrl类简介

class CTreeCtrl : public CWnd
{// DECLARE_DYNAMIC virtual OK - CWnd has DECLARE_DYNAMICDECLARE_DYNAMIC(CTreeCtrl)// Constructors
public:CTreeCtrl();// Generic creatorBOOL Create(_In_ DWORD dwStyle, _In_ const RECT& rect, _In_ CWnd* pParentWnd, _In_ UINT nID);// Generic creator allowing extended style bitsBOOL CreateEx(_In_ DWORD dwExStyle, _In_ DWORD dwStyle, _In_ const RECT& rect,_In_ CWnd* pParentWnd, _In_ UINT nID);// Attributes// Retrieves the bounding rectangle for the specified item.BOOL GetItemRect(_In_ HTREEITEM hItem, _Out_ LPRECT lpRect, _In_ BOOL bTextOnly) const;// Gets the count of items in the control.UINT GetCount() const;// Returns the level-to-level indentation (in pixels).UINT GetIndent() const;// Sets the level-to-level indentation (in pixels).void SetIndent(_In_ UINT nIndent);// Retrieves the image list associated with the control.CImageList* GetImageList(_In_ int nImageList) const;// Sets the image list associated with this control.CImageList* SetImageList(_In_opt_ CImageList* pImageList, _In_ int nImageList);// Retrieves the next item having the given relationship with the// specified item. 遍历函数HTREEITEM GetNextItem(_In_ HTREEITEM hItem, _In_ UINT nCode) const;// Retrieves the next child item after the specified item.HTREEITEM GetChildItem(_In_ HTREEITEM hItem) const;
//	获取长子// Retrieves the next sibling item after the specified item.HTREEITEM GetNextSiblingItem(_In_ HTREEITEM hItem) const;// Retrieves the previous sibling item of the specified item.HTREEITEM GetPrevSiblingItem(_In_ HTREEITEM hItem) const;// Retrieves the parent of the specified item.HTREEITEM GetParentItem(_In_ HTREEITEM hItem) const;// Retrieves the topmost visible item in the control.HTREEITEM GetFirstVisibleItem() const;// Retrieves the next visible item after the specified item.HTREEITEM GetNextVisibleItem(_In_ HTREEITEM hItem) const;// Retrieves the previous visible item before the specified item.HTREEITEM GetPrevVisibleItem(_In_ HTREEITEM hItem) const;// Retrieves the last expanded item in the tree. This does not retrieve the last item visible in the tree-view window.HTREEITEM GetLastVisibleItem() const;// Retrieves the higlighted item, NULL if none.HTREEITEM GetSelectedItem() const;获取选中的项// Retrieves the currently drop-highlighted item, NULL if none.HTREEITEM GetDropHilightItem() const;// Retrieves the root item of the control, NULL if none.HTREEITEM GetRootItem() const;// Retrieves information about a particular item in the control.BOOL GetItem(_Out_ TVITEM* pItem) const;// Retrieves the text associated with the given item.CString GetItemText(_In_ HTREEITEM hItem) const;// Retrieves the images associated with the given item.BOOL GetItemImage(_In_ HTREEITEM hItem, _Out_ int& nImage,_Out_ int& nSelectedImage) const;// Retrieves the state of the given item.UINT GetItemState(_In_ HTREEITEM hItem, _In_ UINT nStateMask) const;// Retrieves the user-supplied data associated with the given item.DWORD_PTR GetItemData(_In_ HTREEITEM hItem) const;// Sets the state of the an item.BOOL SetItem(_In_ TVITEM* pItem);BOOL SetItem(_In_ HTREEITEM hItem, _In_ UINT nMask, _In_opt_z_ LPCTSTR lpszItem, _In_ int nImage,_In_ int nSelectedImage, _In_ UINT nState, _In_ UINT nStateMask, _In_ LPARAM lParam);BOOL SetItemEx(_In_ HTREEITEM hItem, _In_ UINT nMask, _In_opt_z_ LPCTSTR lpszItem, _In_ int nImage,_In_ int nSelectedImage, _In_ UINT nState, _In_ UINT nStateMask, _In_ LPARAM lParam,_In_ UINT uStateEx, _In_opt_ HWND hWnd, _In_ int iExpandedImage);// Sets the text of the specified item.BOOL SetItemText(_In_ HTREEITEM hItem, _In_z_ LPCTSTR lpszItem);// Sets the image on the specified item.BOOL SetItemImage(_In_ HTREEITEM hItem, _In_ int nImage, _In_ int nSelectedImage);// Sets the state of the specified item.BOOL SetItemState(_In_ HTREEITEM hItem, _In_ UINT nState, _In_ UINT nStateMask);// Sets the user data on the specified item.BOOL SetItemData(_In_ HTREEITEM hItem, _In_ DWORD_PTR dwData);// Determines if the specified item has children.BOOL ItemHasChildren(_In_ HTREEITEM hItem) const;// Gets the count of items presently visible in the control.UINT GetVisibleCount() const;// Retrieves the tool tip control associated with this control.CToolTipCtrl* GetToolTips() const;// Sets the tool tip control to be used by this control.CToolTipCtrl* SetToolTips(_In_ CToolTipCtrl* pWndTip);// Retrieves the background colour used throughout the control.COLORREF GetBkColor() const;// Sets the background color to be used throughout the control.COLORREF SetBkColor(_In_ COLORREF clr);// Retrieves the height of items in the control.SHORT GetItemHeight() const;// Sets the height of items in the control.SHORT SetItemHeight(_In_ SHORT cyHeight);// Retrieves the text color used for all items in the control.COLORREF GetTextColor() const;// Sets the text color used for all items in the control.COLORREF SetTextColor(_In_ COLORREF clr);// Gets the checked state of the specified item in the control.// (Only useful on a control with the TVS_CHECKBOXES style.)BOOL GetCheck(_In_ HTREEITEM hItem) const;// Sets the checked state of the specified item in the control.// (Only useful on a control with the TVS_CHECKBOXES style.)BOOL SetCheck(_In_ HTREEITEM hItem, _In_ BOOL fCheck = TRUE);COLORREF GetLineColor() const;COLORREF SetLineColor(_In_ COLORREF clrNew = CLR_DEFAULT);// Operations// Inserts a new item to the control.HTREEITEM InsertItem(_In_ LPTVINSERTSTRUCT lpInsertStruct);HTREEITEM InsertItem(_In_ UINT nMask, _In_z_ LPCTSTR lpszItem, _In_ int nImage,_In_ int nSelectedImage, _In_ UINT nState, _In_ UINT nStateMask, _In_ LPARAM lParam,_In_ HTREEITEM hParent, _In_ HTREEITEM hInsertAfter);HTREEITEM InsertItem(_In_z_ LPCTSTR lpszItem, _In_ HTREEITEM hParent = TVI_ROOT,_In_ HTREEITEM hInsertAfter = TVI_LAST);HTREEITEM InsertItem(_In_z_ LPCTSTR lpszItem, _In_ int nImage, _In_ int nSelectedImage,_In_ HTREEITEM hParent = TVI_ROOT, _In_ HTREEITEM hInsertAfter = TVI_LAST);// Removes the specified item from the control.BOOL DeleteItem(_In_ HTREEITEM hItem);// Removes all items from the control.BOOL DeleteAllItems();// Expands the children of the specified item.BOOL Expand(_In_ HTREEITEM hItem, _In_ UINT nCode);// Selects the specified item. 选中BOOL Select(_In_ HTREEITEM hItem, _In_ UINT nCode);// Selects the specified item.BOOL SelectItem(_In_opt_ HTREEITEM hItem);// Selects an item to be the drop target in the control.BOOL SelectDropTarget(_In_opt_ HTREEITEM hItem);// Draws the specified item as the drop target for the control.BOOL SelectSetFirstVisible(_In_ HTREEITEM hItem);// Begins editing the label of the specified item.CEdit* EditLabel(_In_ HTREEITEM hItem);
TVN_ENDEDIT 消息时获取编辑控件,把用户输入的文字取出来// Retrieves the edit control used to perform in-place editing.CEdit* GetEditControl() const;
};

树形控件的属性

#define TVS_HASBUTTONS          0x0001
#define TVS_HASLINES       有虚线     0x0002
#define TVS_LINESATROOT         0x0004			#define TVS_EDITLABELS          0x0008
#define TVS_DISABLEDRAGDROP     0x0010
#define TVS_SHOWSELALWAYS       0x0020
#define TVS_RTLREADING          0x0040
#define TVS_NOTOOLTIPS          0x0080
#define TVS_CHECKBOXES          0x0100
#define TVS_TRACKSELECT         0x0200
#define TVS_SINGLEEXPAND        0x0400
#define TVS_INFOTIP             0x0800
#define TVS_FULLROWSELECT       0x1000
#define TVS_NOSCROLL            0x2000
#define TVS_NONEVENHEIGHT       0x4000
#define TVS_NOHSCROLL           0x8000  // TVS_NOSCROLL overrides this
#if (NTDDI_VERSION >= NTDDI_WINXP)
#define TVS_EX_NOSINGLECOLLAPSE     0x0001
#endif
#if (NTDDI_VERSION >= NTDDI_VISTA)
#define TVS_EX_MULTISELECT          0x0002
#define TVS_EX_DOUBLEBUFFER         0x0004
#define TVS_EX_NOINDENTSTATE        0x0008
#define TVS_EX_RICHTOOLTIP          0x0010
#define TVS_EX_AUTOHSCROLL          0x0020
#define TVS_EX_FADEINOUTEXPANDOS    0x0040
#define TVS_EX_PARTIALCHECKBOXES    0x0080
#define TVS_EX_EXCLUSIONCHECKBOXES  0x0100
#define TVS_EX_DIMMEDCHECKBOXES     0x0200
#define TVS_EX_DRAWIMAGEASYNC       0x0400
#endif

CTreeCtrl类的原理以及常用功能

CTreeCtrl类的选中消息分析:
a)结构体:

typedef struct tagTVITEMCHANGE {NMHDR hdr;UINT uChanged;HTREEITEM hItem;UINT uStateNew;UINT uStateOld;LPARAM lParam;
} NMTVITEMCHANGE;

b)State状态分析:

TVIS_SELECTED(0x0002):项被选中。
TVIS_CUT(0x0008):项被剪切。
TVIS_DROPHILITED(0x0004):项高亮显示,用于拖放操作。
TVIS_EXPANDED(0x0020):项展开。
TVIS_BOLD(0x0001):项以粗体显示。
TVIS_DISABLED(0x0040):项禁用(灰色显示)。
TVIS_EXPANDEDONCE(0x0200):项已经展开过一次。
TVIS_EXPANDPARTIAL(0x0400):项部分展开。
TVIS_OVERLAYMASK(0x0F00):覆盖层蒙版。

MFC六大关键技术

1、MFC Initialization —— MFC程序的初始化过程
参见:CWinApp::InitInstance的虚函数,MFC内部接管WinMain平台启动初始化之后再调用InitInstance。
开发者需要创建CWinApp的派生类,并且在全局区定义派生类的全局对象,最后在派生类礼重写InitInstance虚函数。

2、Message Mapping —— 消息映射
参见:任何窗口派生类的头文件中 :DECLARE_MESSAGE_MAP
源文件中:
BEGIN_MESSAGE_MAP(CMainDlg, CDialogEx)
消息映射的数组{数组的每个元素都是一个结构体(消息-ID-函数地址)}
END_MESSAGE_MAP()

3、Message Routing —— 消息传递(路由)
主要在框架与视图架构里,把框架收到的菜单和工具栏消息分发到各个视图类。

BOOL CMainFrame::OnCmdMsg(UINT nID...)if (m_pView && m_pView->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))return TRUE;

4、RTTI(Runtime Type Identification)—— 运行时类型识别
核心的作用是任何MFC的类(CObject派生)都能够获取到类型信息。
而且能知道你的派生类是谁,甚至获取到整个派生树分枝的名字。

auto pInfo = obj.GetRuntimeClass();
while (pInfo)
{AfxMessageBox(CString(_T("你是:")) + pInfo->m_lpszClassName);pInfo = pInfo->m_pBaseClass;//pNext;
}

参见:RUNTIME_CLASS宏以及每个MFC类的信息管理:
DECLARE_DYNAMIC(CMainFrame)
IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)
RTTI运行时识别类型,靠的就是

BOOL CObject::IsKindOf(const CRuntimeClass* pClass) const;
CRuntimeClass* pClassThis = GetRuntimeClass();

5、Dynamic Creation —— 动态创建
比动态类型识别多了一个函数:
原理参见:DECLARE_DYNCREATE(CApp)

IMPLEMENT_DYNCREATE(CApp, CWinApp)
class CApp::public CWinApp
{
public:
static CObject* WINAPI CApp::CreateObject() 	{ return new CApp; } 
}

6、Persistence ——永久保存(串行化、序列化)
利用CArchive类将对象数据保存到磁盘上,把数据按照顺序连续(operator<<)存入到磁盘,加载时按照存入的顺序连续提取数据(operator>>);
优点是比结构体在存储文字时节省存储空间,存储文字时先存编码和长度,加载时再根据长度读取文字,并根据来源编码格式转换到目标格式。
MFC这种连续存储的机制称之为序列化存储(Serialize)。

视图和带分割栏的框架开发与消息路由

CLeftView.h

class CLeftView : public CTreeView{DECLARE_DYNCREATE(CLeftView) //动态创建CTreeCtrl& m_tree {	GetTreeCtrl() };CImageList m_iList;int GetDepth(HTREEITEM hItem) const;
protected:CLeftView();           // 动态创建所使用的受保护的构造函数virtual ~CLeftView();void InitCtrl();
protected:DECLARE_MESSAGE_MAP()
};

CLeftView.cpp

#include "pch.h"
#include "division.h"
#include "CLeftView.h"
#include "CRightView.h"
#include "CWelcome.h"
IMPLEMENT_DYNCREATE(CLeftView, CTreeView)
CLeftView::CLeftView()
{theApp.m_pLeftView = this;
}
CLeftView::~CLeftView()
{}
BEGIN_MESSAGE_MAP(CLeftView, CTreeView)ON_NOTIFY_REFLECT(TVN_SELCHANGED, &CLeftView::OnTvnSelchanged)ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED, &CLeftView::OnTvnItemexpanded)ON_NOTIFY_REFLECT(TVN_ITEMCHANGED, &CLeftView::OnTvnItemChanged)ON_COMMAND(ID_COMP_ADD, &CLeftView::OnCompAdd)ON_COMMAND(ID_COMP_DEL, &CLeftView::OnCompDel)
END_MESSAGE_MAP()
// CLeftView 诊断
#ifdef _DEBUG
void CLeftView::AssertValid() const{CTreeView::AssertValid();
}
// CLeftView 消息处理程序
void CLeftView::OnInitialUpdate()
{CTreeView::OnInitialUpdate();if (m_iList.GetSafeHandle())return;InitCtrl();ModifyStyle(0, TVS_HASLINES| TVS_HASBUTTONS | TVS_LINESATROOT | TVS_SHOWSELALWAYS);auto hItem = m_tree.InsertItem(_T("异人之下"),0,1);auto h = m_tree.InsertItem(_T("那都通"),2,3, hItem);m_tree.InsertItem(_T("张楚岚"),5,4,h);m_tree.InsertItem(_T("冯宝宝"),5,4,h);m_tree.InsertItem(_T("徐三"),  5,4,h);m_tree.InsertItem(_T("徐四"),  5,4,h);m_tree.Expand(h, TVE_EXPAND);auto h2 = m_tree.InsertItem(_T("武当山"),2,3 ,hItem);m_tree.InsertItem(_T("王也"),  5,4, h2);m_tree.InsertItem(_T("老天师"),5,4, h2);m_tree.InsertItem(_T("诸葛青"),5,4, h2);m_tree.InsertItem(_T("诸葛玄"),5,4, h2);m_tree.Expand(h2, TVE_EXPAND);m_tree.Expand(hItem, TVE_EXPAND); //要先插入再展开//m_tree.Select(h2, TVGN_CARET); //设置当前选择 并且带有样式m_tree.SelectItem(h); //设置当前选择 没有样式
}
void CLeftView::InitCtrl(){m_iList.Create(16, 16, ILC_COLOR32, 8, 8);int i = -1;while (++i < 6){m_iList.Add(theApp.LoadIcon(IDI_ICON1 + i));}m_tree.SetImageList(&m_iList, TVSIL_NORMAL);
}
int CLeftView::GetDepth(HTREEITEM hItem) const  //用于获取当前选中的行在 多深
{if (!hItem)return -1;int i = 0;while (hItem = m_tree.GetParentItem(hItem)){++i;}return i;
}
void CLeftView::OnTvnSelchanged(NMHDR* pNMHDR, LRESULT* pResult)
{LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);// TODO: 在此添加控件通知处理程序代码*pResult = 0;
}
void CLeftView::OnTvnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult) //展开或者折叠
{LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);*pResult = 0;
}
void CLeftView::OnTvnItemChanged(NMHDR* pNMHDR, LRESULT* pResult)
{NMTVITEMCHANGE* p  = reinterpret_cast<NMTVITEMCHANGE*>(pNMHDR);auto hItem = p->hItem;if (TVIS_SELECTED & p->uStateNew){auto& split = theApp.m_split;auto pRightView = theApp.m_split.GetPane(0, 1);	 if (pRightView)split.DeleteView(0,1);switch (GetDepth(hItem)){case 0:case 1:split.CreateView(0, 1, RUNTIME_CLASS(CWelcome), { 0,0 }, NULL); break;case 2:{split.CreateView(0, 1, RUNTIME_CLASS(CRightView), { 0,0 }, NULL); CRightView* pRightView =(CRightView*) split.GetPane(0, 1);pRightView->Refresh();}}split.RecalcLayout();}*pResult = 0;
}

CRightView.h

class CRightView : public CListView{DECLARE_DYNCREATE(CRightView)//动态创建CListCtrl& m_list = GetListCtrl(); //说白了任何一个控件的创建都是由CWnd::Create(sCLassName)
protected:CRightView();           // 动态创建所使用的受保护的构造函数virtual ~CRightView();
public:void Refresh();
protected:DECLARE_MESSAGE_MAP()
public:afx_msg void OnStaffAdd();afx_msg void OnStaffDel();virtual void OnInitialUpdate();virtual BOOL PreCreateWindow(CREATESTRUCT& cs);	};

CRightView.cpp

#include "pch.h"
#include "division.h"
#include "CRightView.h"
IMPLEMENT_DYNCREATE(CRightView, CListView)
CRightView::CRightView(){theApp.m_pRightView = this;
}
CRightView::~CRightView()
{theApp.m_pRightView = nullptr;
}
BEGIN_MESSAGE_MAP(CRightView, CListView)ON_COMMAND(ID_STAFF_ADD, &CRightView::OnStaffAdd)ON_COMMAND(ID_STAFF_DEL, &CRightView::OnStaffDel)
END_MESSAGE_MAP()
void CRightView::Refresh()
{
}
void CRightView::AssertValid() const
{CListView::AssertValid();
}
void CRightView::OnStaffAdd()
{}
void CRightView::OnStaffDel()
{}
void CRightView::OnInitialUpdate(){CListView::OnInitialUpdate();if (m_list.GetHeaderCtrl()->GetItemCount() > 0) //防止标题插入两边return;m_list.InsertColumn(0, _T("工号"), 0, 150);m_list.InsertColumn(1, _T("姓名"), 0, 150);m_list.InsertColumn(2, _T("性别"), 0, 150);m_list.InsertColumn(3, _T("入职日期"), 0, 150);m_list.InsertColumn(4, _T("外语"), 0, 150);m_list.InsertColumn(5, _T("工资"), 0, 150);
}
BOOL CRightView::PreCreateWindow(CREATESTRUCT& cs)
{  cs.style |= LVS_REPORT;return CListView::PreCreateWindow(cs);
}

CWelcome .h

class CWelcome : public CFormView{DECLARE_DYNCREATE(CWelcome)
protected:CWelcome();           // 动态创建所使用的受保护的构造函数virtual ~CWelcome();protected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持DECLARE_MESSAGE_MAP()
};

CWelcome.cpp

#include "pch.h"
#include "division.h"
#include "CWelcome.h"
IMPLEMENT_DYNCREATE(CWelcome, CFormView)CWelcome::CWelcome(): CFormView(IDD_FORMVIEW)
{theApp.m_pRightView = this;
}
CWelcome::~CWelcome()
{theApp.m_pRightView = NULL;
}
BEGIN_MESSAGE_MAP(CWelcome, CFormView)
END_MESSAGE_MAP()

division.h

#include "resource.h"       // 主符号
#include "CLeftView.h"
// CApp:有关此类的实现,请参阅 division.cpp
class CLeftView;
class CRightView;
class CApp : public CWinApp
{
public:CApp() noexcept;CLeftView* m_pLeftView{};CView* m_pRightView{};CSplitterWnd m_split;
};
extern CApp theApp;

division.cpp

#include "pch.h"
#include "framework.h"
#include "afxwinappex.h"
#include "afxdialogex.h"
#include "division.h"
#include "MainFrm.h"#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CApp
BEGIN_MESSAGE_MAP(CApp, CWinApp)ON_COMMAND(ID_APP_ABOUT, &CApp::OnAppAbout)
END_MESSAGE_MAP()
BOOL CApp::InitInstance(){			// CApp 初始化CFrameWnd* pFrame = new CMainFrame;if (!pFrame)	return FALSE;m_pMainWnd = pFrame; 	// 创建并加载框架及其资源pFrame->LoadFrame(IDR_MAINFRAME,WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, nullptr,nullptr);if (m_pRightView->IsKindOf(RUNTIME_CLASS(CCtrlView)))AfxMessageBox(_T("m_pRightView对象是CCtrlView派生的"));elseAfxMessageBox(_T("m_pRightView对象不是CCtrlView派生的"));if (m_pRightView->IsKindOf(RUNTIME_CLASS(CFormView)))AfxMessageBox(_T("m_pRightView对象是CFormView派生的"));elseAfxMessageBox(_T("m_pRightView对象不是CFormView派生的"));pFrame->ShowWindow(SW_SHOW);	// 唯一的一个窗口已初始化,因此显示它并对其进行更新pFrame->UpdateWindow();				return TRUE;				}
// 唯一的 CApp 对象
CApp theApp;// 用于运行对话框的应用程序命令
void CApp::OnAppAbout()
{CAboutDlg aboutDlg;aboutDlg.DoModal();
}

MainFrm.h

class CMainFrame : public CFrameWnd{	 
public:CMainFrame() noexcept;
protected: DECLARE_DYNAMIC(CMainFrame)  //动态识别
public:				// 重写virtual BOOL PreCreateWindow(CREATESTRUCT& cs);virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
public:  // 实现virtual ~CMainFrame();
protected:afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);afx_msg void OnSetFocus(CWnd *pOldWnd);DECLARE_MESSAGE_MAP()virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);		};

MainFrm.cpp

#include "pch.h"
#include "framework.h"
#include "division.h"
#include "CLeftView.h"
#include "CRightView.h"
#include "MainFrm.h"// CMainFrame 构造/析构
CMainFrame::CMainFrame() noexcept
{// TODO: 在此添加成员初始化代码
}
CMainFrame::~CMainFrame()
{
}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct){if (CFrameWnd::OnCreate(lpCreateStruct) == -1)return -1;if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))	{TRACE0("未能创建工具栏\n");return -1;      // 未能创建	}if (!m_wndStatusBar.Create(this))	{TRACE0("未能创建状态栏\n");return -1;      // 未能创建	}m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);// TODO: 如果不需要可停靠工具栏,则删除这三行EnableDocking(CBRS_ALIGN_ANY);DockControlBar(&m_wndToolBar);		return 0;	}
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{if( !CFrameWnd::PreCreateWindow(cs) )return FALSE;// TODO: 在此处通过修改//  CREATESTRUCT cs 来修改窗口类或样式cs.dwExStyle &= ~WS_EX_CLIENTEDGE;cs.lpszClass = AfxRegisterWndClass(0);return TRUE;
}
// CMainFrame 消息处理程序void CMainFrame::OnSetFocus(CWnd* /*pOldWnd*/)
{// 将焦点前移到视图窗口if (theApp.m_pLeftView)theApp.m_pLeftView->SetFocus();
}
BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{// 让视图第一次尝试该命令if (theApp.m_pLeftView &&theApp.m_pLeftView->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))return TRUE;if (theApp.m_pRightView &&theApp.m_pRightView->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))return TRUE;// 否则,执行默认处理return CWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext){auto& split = theApp.m_split;split.CreateStatic(this, 1, 2);split.CreateView(0, 1, RUNTIME_CLASS(CRightView), { 0,0 }, NULL); //righrview 要在leftview之前  因为在leftview中调用rightview读取数据时,rightview还没有创建,拿不到数据 报它为空split.CreateView(0, 0, RUNTIME_CLASS(CLeftView), { 150,0 }, NULL);//theApp.m_pLeftView = (CLeftView*)split.GetPane(0, 0);  //做这个的目的为了是 点击左边的时候找右边方便 点击右边的时候找左边方便
//theApp.m_pRightView = (CRightView*)split.GetPane(0, 1);//给这个指针赋值也可通过构造函数赋值//CCreateContext cc;//cc.m_pNewViewClass = RUNTIME_CLASS(CLeftView);//theApp.m_pLeftView =(CLeftView*) CreateView(&cc);return TRUE;
}

在这里插入图片描述

附录:为什么用户点击一下视图,即可让菜单有效?

CView* pView = GetActiveView();

BOOL CFrameWnd::OnCmdMsg(UINT nID, int nCode, void* pExtra,AFX_CMDHANDLERINFO* pHandlerInfo){CPushRoutingFrame push(this);// pump through current view FIRSTCView* pView = GetActiveView();if (pView != NULL && pView->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))return TRUE;// then pump through frameif (CWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))return TRUE;// last but not least, pump through appCWinApp* pApp = AfxGetApp();if (pApp != NULL && pApp->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))return TRUE;return FALSE;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/61510.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分布式链路追踪概述

分布式链路追踪概述 文章目录 分布式链路追踪概述1.分布式链路追踪概述1.1.什么是 Tracing1.2.为什么需要Distributed Tracing 2.Google Dapper2.1.Dapper的分布式跟踪2.1.1.跟踪树和span2.1.2.Annotation2.1.3.采样率 3.OpenTracing3.1.发展历史3.2.数据模型 4.java探针技术-j…

现代C++中的从头开始深度学习【2/8】:张量编程

一、说明 初学者文本&#xff1a;此文本需要入门级编程背景和对机器学习的基本了解。张量是在深度学习算法中表示数据的主要方式。它们广泛用于在算法执行期间实现输入、输出、参数和内部状态。 在这个故事中&#xff0c;我们将学习如何使用特征张量 API 来开发我们的C算法。具…

Linux6.33 Kubernetes kubectl详解

文章目录 计算机系统5G云计算第三章 LINUX Kubernetes kubectl详解一、陈述式资源管理方法1.基本信息查看2.项目的生命周期&#xff1a;创建-->发布-->更新-->回滚-->删除 二、声明式管理方法 计算机系统 5G云计算 第三章 LINUX Kubernetes kubectl详解 一、陈述…

Ubuntu系统重置 root 用户密码

文章目录 前言Ubuntu 系统重置 root 用户密码编辑 grub 菜单修改 grub 配置重设 root 用户密码前言 虚拟机用的时间久了登录系统的时候发现 root 密码忘记了, 所以在这里写一篇文章记录一下Ubuntu 系统下 root 密码忘记的解决方案,经过测试, 理论上来说这个方法适用于 Ubuntu …

『PostgreSQL』在 PostgreSQL中创建只读权限和读写权限的账号

&#x1f4e3;读完这篇文章里你能收获到 理解在 PostgreSQL 数据库中创建账号的重要性以及如何进行账号管理掌握在 PostgreSQL 中创建具有只读权限和读写权限的账号的步骤和方法学会使用 SQL 命令来创建账号、为账号分配适当的权限以及控制账号对数据库的访问级别了解如何确保…

【C语言】初阶指针详解

目录 一、什么是指针&#xff1f; 1.指针变量 2.指针大小 二、指针类型 三、野指针 四、指针运算 1.指针-整数 2.指针-指针 3.指针的关系运算 五、指针和数组 六、二级指针 七、指针数组 一、什么是指针&#xff1f; 指针是内存中一个最小单元的编号&#xff0c;…

关于APP备案、小程序备案的问题,如何备案?

近日&#xff0c;工信部发布了关于开展移动互联网应用程序备案工作的通知。为落实相关法律法规要求&#xff0c;促进互联网行业规范健康发展&#xff0c;进一步做好移动互联网信息服务管理&#xff0c;现组织开展移动互联网应用程序&#xff08;以下简称 APP&#xff09;备案工…

【Echart地图】jQuery+html5基于echarts.js中国地图点击弹出下级城市地图(附完整源码下载)

文章目录 写在前面涉及知识点实现效果1、实现中国地图板块1.1创建dom元素1.2实现地图渲染1.3点击地图进入城市及返回 2、源码分享2.1 百度网盘2.2 123云盘2.3 邮箱留言 总结 写在前面 这篇文章其实我主要是之前留下的一个心结&#xff0c;依稀记得之前做了一个大屏项目的时候&…

搞定libstdc++.so.6 version GLIBCXX_3.4.21 not found

一、问题&#xff1a; 今天在安装whisper的时候&#xff0c;突然间报了这样一个错误&#xff1a; OSError: Could not load shared object file: libllvmlite.so Errors were: [OSError("/lib64/libstdc.so.6: version GLIBCXX_3.4.21 not found (required by /opt/con…

前端技术Vue学习笔记--003

前端技术Vue学习笔记 文章目录 前端技术Vue学习笔记1、Vue生命周期和生命周期的四个阶段1.1、Vue生命周期1.2、生命周期的四个阶段1.3、Vue生命周期函数<font colorred>&#xff08;钩子函数&#xff09; 2、小黑记账本&#xff08;案例&#xff09;3、工程化开发和脚手架…

风丘科技将亮相 EVM ASIA 2023

风丘科技将首次亮相 EVM ASIA 2023 WINDHILL will debut EVM ASIA 2023 ——可持续移动的未来 —The Future of SUSTAINABLE Mobility EVM ASIA 2023是亚太地区电气化的国际性展会&#xff0c;专注于新能源汽车、充电技术及汽车零件制造等。展会致力于促进包括充电站、交通…

【MySQL】表中的一条数据在磁盘上是如何存放的?

文章目录 1 InnoDB行格式2 COMPACT行格式2.1 记录的额外信息2.2 记录的真实数据 3 Dynamic & Compressed4 VarChar(n)中n的最大取值&#xff1f; 1 InnoDB行格式 不同的存储引擎一般是为实现不同的特性来开发的&#xff0c;真实数据在不同存储引擎中的存放格式一般是不同的…