MFC单文档多视图的多种实现方式

       MFC下实现单文档多视图(非切割模式),虽然现在有了CTabView,主视图从CTabView继承,然后主视图初始化时把自己子视图添加进去,各个视图以Tab页的方式显示。这种方式在某些场景下 可以,多数情况下不符号用户要求。下面介绍两种非Tab页方式的实现:

      第一种,利用CCreateContext,动态创建和切换视图。在CMainFrame中,枚举视图ID,并创建视图切换函数。

// Attributes
public:
 	/***********窗口切换*****/
	enum eView { VIEW = 1, VIEW1 = 2 ,VIEW2 = 3,VIEW3 = 4,VIEW4 = 5,VIEW5 = 6};
    void SwitchToView(eView nView);

在CPP中的实现:

BOOL bFirst = TRUE;
void CMainFrame::SwitchToView(eView nView)
{
    CView* pOldActiveView = GetActiveView();
	if (bFirst)
	{
		m_pView[0] = pOldActiveView;
		bFirst =FALSE;
	}

    CView* pNewActiveView = (CView*) GetDlgItem(nView);
    //如果视图不存在,动态创建
	if(m_pView[nView-1]==NULL)
	{
        switch (nView)
		{
        case VIEW:
            m_pView[0] = (CView*) new CMonitoringSysView;
            break;
        case VIEW1:
            m_pView[1] = (CView*) new EnvironmentParaShow;
            break;
		}
		pNewActiveView = m_pView[nView-1];
        CCreateContext context;
        context.m_pCurrentDoc = pOldActiveView->GetDocument();
        pNewActiveView->Create(NULL, NULL, WS_BORDER|WS_CHILD ,
            rectDefault, this, nView, &context);
        pNewActiveView->OnInitialUpdate();
    }
    //隐藏旧视图,显示新视图
	pNewActiveView = m_pView[nView-1];
    SetActiveView(pNewActiveView);
    pNewActiveView->ShowWindow(SW_SHOW);
    pOldActiveView->ShowWindow(SW_HIDE);
	if (GetRuntimeClass() == RUNTIME_CLASS(CMonitoringSysView))
	{
		pOldActiveView->SetDlgCtrlID(nView);
	}
	else if (GetRuntimeClass() == RUNTIME_CLASS(EnvironmentParaShow))
	{
		pOldActiveView->SetDlgCtrlID(nView);
	}
	pNewActiveView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
    RecalcLayout();
}

//切换视图
void CMainFrame::OnMonitsys() 
{
	SwitchToView(VIEW);
}

OnMonitsys是菜单关联函数。

     第二种,使用多视图模板类CMDIMVDocTemplate,这是一个老外写的模板类,在APP类中屏蔽掉原来的doc、frame和view的常见,使用这个模板类创建。这个模板类每创建一个视图类View,必须同时创建一个ChildFrame.

CMvDocTemplate *pDocTemplate = new CMDIMVDocTemplate(IDR_WATERINFO, RUNTIME_CLASS(CWaterInfoSysDoc));
	
	pDocTemplate->AddFrameTemplate(
		new CFrameTemplate( 
		IDR_WATERINFO, 
		RUNTIME_CLASS( CChildFrame ), 
		RUNTIME_CLASS( CWaterInfoSysView ), 
		ID_REALTIMEMONITOR,//该视图对应的菜单ID, 
		SW_SHOWMAXIMIZED, 
		TRUE ) ); //为TRUE时,激活态,系统开始运行时创建
	pDocTemplate->AddFrameTemplate(
		new CFrameTemplate( 
		IDR_WATERINFO, 
		RUNTIME_CLASS( CChileFrmRpt), 
		RUNTIME_CLASS( CDialyWaterLevelRptView), 
		ID_DAILY_WATERLEVCAPATY, 
		SW_SHOWMAXIMIZED, 
		FALSE ) );

	pDocTemplate->AddFrameTemplate(
		new CFrameTemplate(
		IDR_WATERINFO,
		RUNTIME_CLASS(CChildFrmRainfall),
		RUNTIME_CLASS(CRainfallHistogramView),
		ID_RAINFALLHISTOGRAM,
		SW_SHOWMAXIMIZED,
		FALSE));

    AddDocTemplate(pDocTemplate);
	m_server.ConnectTemplate(clsid, pDocTemplate, FALSE);

	COleTemplateServer::RegisterAll();

	// 创建主 MDI 框架窗口
	CMainFrame* pMainFrame = new CMainFrame;
	if (!pMainFrame || !pMainFrame->LoadFrame(IDR_WATERINFO))//IDR_MAINFRAME))
	{
		delete pMainFrame;
		return FALSE;
	}
	m_pMainWnd = pMainFrame;

ChildFrame需继承自CMDIChildWndEx,头文件:

#pragma once

// CChildFrmRainfall

class CChildFrmRainfall : public CMDIChildWndEx
{
	DECLARE_DYNCREATE(CChildFrmRainfall)

public:
	CChildFrmRainfall();
	virtual ~CChildFrmRainfall();

protected:
	DECLARE_MESSAGE_MAP()
	virtual void OnUpdateFrameTitle(BOOL bAddToTitle);
};

CPP文件

#include "stdafx.h"
#include "WaterInfoSys.h"
#include "ChildFrmRainfall.h"

// CChildFrmRainfall

IMPLEMENT_DYNCREATE(CChildFrmRainfall, CMDIChildWndEx)

CChildFrmRainfall::CChildFrmRainfall()
{

}

CChildFrmRainfall::~CChildFrmRainfall()
{
}


BEGIN_MESSAGE_MAP(CChildFrmRainfall, CMDIChildWndEx)
END_MESSAGE_MAP()

// CChildFrmRainfall message handlers
void CChildFrmRainfall::OnUpdateFrameTitle(BOOL bAddToTitle)
{
	CMDIChildWndEx::OnUpdateFrameTitle(bAddToTitle);

	SetWindowText(_T("降雨量柱状图"));
}

每个视图类继承自CFormView即可。

      第三种方式是同MFC自身带的TabView类似,也是Tab页的方式实现,即使用BCGCtrolBar控件,这个控件很早就实现了,比MFC还早。

     安装好BCGContrilBar以后,修改主主视图类继承自CBCGPTabView,在OnCreate内添加你自己的子视图即可。

int CDahangAcqgateStudioView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CBCGPTabView::OnCreate(lpCreateStruct) == -1)
		return -1;

	AddView(RUNTIME_CLASS(CAcqNetgatewayView),_T("采集网关"),0);
	AddView(RUNTIME_CLASS(CSerialPortDevView), _T("串口设备"), 1);
	AddView(RUNTIME_CLASS(CSerialPortIoPtView), _T("串口设备IO点"), 2);
	AddView(RUNTIME_CLASS(CLocalIOPtView),_T("本地IO点"), 3);
	AddView(RUNTIME_CLASS(CUserCustomPtView), _T("用户点"), 4);
	AddView(RUNTIME_CLASS(CModbusTcpProtoPtsView), _T("Modbus协议"), 5);
	AddView(RUNTIME_CLASS(COPCUAProtoPtsView), _T("OPC UA协议"), 6);
	AddView(RUNTIME_CLASS(CMQTTProtoPtsView), _T("MQTT协议"),7);

	OnShowAllChildView(FALSE);

	return 0;
}
//视图切换
void CDahangAcqgateStudioView::OnAcqNetgatewayView()
{
	GetTabControl().SetActiveTab(0);
}

点击   MFC多视图模板类和BCGCtolBarForMFC25   下载资源。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
添加鼠标点击操作步骤可以通过以下步骤实现: 1. 在你的 MFC 文档类中添加一个成员变量,用于保存鼠标点击的位置信息。例如: ``` CPoint m_ptClick; ``` 2. 在你的 MFC 文档类中覆盖 OnLButtonDown 函数,获取当前鼠标点击的位置信息,并保存到 m_ptClick 成员变量中。例如: ``` void CMyDoc::OnLButtonDown(UINT nFlags, CPoint point) { m_ptClick = point; } ``` 3. 在你的 MFC 视图类中覆盖 OnDraw 函数,根据鼠标点击的位置信息绘制一些图形或者文本。例如: ``` void CMyView::OnDraw(CDC* pDC) { CMyDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // 绘制一些图形或者文本 pDC->TextOut(pDoc->m_ptClick.x, pDoc->m_ptClick.y, _T("Hello, world!")); } ``` 4. 在你的 MFC 视图类中添加一个成员变量,用于保存鼠标点击操作是否启用的状态。例如: ``` bool m_bClickEnabled = false; ``` 5. 在你的 MFC 视图类中覆盖 OnUpdate 函数,根据当前文档的状态更新鼠标点击操作是否启用的状态。例如: ``` void CMyView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) { CMyDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // 更新鼠标点击操作是否启用的状态 m_bClickEnabled = (pDoc->GetState() == STATE_CLICK_ENABLED); // 刷新视图 Invalidate(); } ``` 6. 在你的 MFC 视图类中覆盖 OnMouseMove 函数,根据鼠标点击操作是否启用的状态更新视图。例如: ``` void CMyView::OnMouseMove(UINT nFlags, CPoint point) { // 如果鼠标点击操作已启用,则更新视图 if (m_bClickEnabled) { Invalidate(); } } ``` 7. 最后,在你的 MFC 应用程序中添加一个菜项或者工具栏按钮,用于控制鼠标点击操作的启用和禁用。当用户点击该菜项或者工具栏按钮时,修改当前文档的状态,以便在下一次更新视图时启用或者禁用鼠标点击操作。例如: ``` void CMyApp::OnEnableClick() { CMyDoc* pDoc = GetActiveDocument(); ASSERT_VALID(pDoc); // 修改文档状态,以便在下一次更新视图时启用鼠标点击操作 pDoc->SetState(STATE_CLICK_ENABLED); } ``` 以上就是 MFC 文档添加鼠标点击操作的步骤。希望对你有所帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

previewer1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值