`
hcmfys
  • 浏览: 349494 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

duoview1

 
阅读更多
首先在H文件有如下声明:

class CMultiViewApp : public CWinApp

{

public:

CView* m_pFirstView;

CView* m_pOtherView;

int m_currentView;

CView* m_pView2;

CView* m_pView1;

CMultiViewApp();


// Overrides

// ClassWizard generated virtual function overrides

//{{AFX_VIRTUAL(CMultiViewApp)

public:

virtual BOOL InitInstance();

//}}AFX_VIRTUAL


// Implementation

//{{AFX_MSG(CMultiViewApp)

afx_msg void OnAppAbout();

afx_msg void OnViewOtherview();

afx_msg void OnViewFirstview();

//}}AFX_MSG

afx_msg void OnViewChange(UINT nCmdID);

DECLARE_MESSAGE_MAP()

};


其次,在CPP文件有如下消息MAP:

/////////////////////////////////////////////////////////////////////////////

// CMultiViewApp


BEGIN_MESSAGE_MAP(CMultiViewApp, CWinApp)

//{{AFX_MSG_MAP(CMultiViewApp)

ON_COMMAND(ID_APP_ABOUT, OnAppAbout)

ON_COMMAND(ID_VIEW_OTHERVIEW, OnViewOtherview)

ON_COMMAND(ID_VIEW_FIRSTVIEW, OnViewFirstview)

//}}AFX_MSG_MAP

// Standard file based document commands

ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)

ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)

// Standard print setup command

ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)

ON_COMMAND_RANGE( ID_VIEW_VIEW1, ID_VIEW_VIEW2, OnViewChange)

END_MESSAGE_MAP()


说明:SDI程序在CMyApp::InitInstance()已经通过DocTemplate创建一个关联的视图/文档实例,切显示出来.具体实现如下:

BOOL CMultiViewApp::InitInstance()

{

AfxEnableControlContainer();


// Standard initialization

// If you are not using these features and wish to reduce the size

// of your final executable, you should remove from the following

// the specific initialization routines you do not need.


#ifdef _AFXDLL

Enable3dControls(); // Call this when using MFC in a shared DLL

#else

Enable3dControlsStatic(); // Call this when linking to MFC statically

#endif


// Change the registry key under which our settings are stored.

// TODO: You should modify this string to be something appropriate

// such as the name of your company or organization.

SetRegistryKey(_T("Local AppWizard-Generated Applications"));


LoadStdProfileSettings(); // Load standard INI file options (including MRU)


// Register the application's document templates. Document templates

// serve as the connection between documents, frame windows and views.


CSingleDocTemplate* pDocTemplate;

pDocTemplate = new CSingleDocTemplate(

IDR_MAINFRAME,

RUNTIME_CLASS(CMultiViewDoc),

RUNTIME_CLASS(CMainFrame), // main SDI frame window

RUNTIME_CLASS(CMultiViewView));

AddDocTemplate(pDocTemplate);


// Parse command line for standard shell commands, DDE, file open

CCommandLineInfo cmdInfo;

ParseCommandLine(cmdInfo);


// Dispatch commands specified on the command line

if (!ProcessShellCommand(cmdInfo))

return FALSE;


CView* pActiveView = ((CFrameWnd*) m_pMainWnd)->GetActiveView();

m_pFirstView = pActiveView;

m_pOtherView = (CView*) new COtherView;


CDocument* pDoc = ((CFrameWnd*)m_pMainWnd)->GetActiveDocument();

//通过CCreateContext实现第二视图和文档的关联

CCreateContext context;

context.m_pCurrentDoc = pDoc;


UINT m_ID = AFX_IDW_PANE_FIRST + 1;

CRect rect;

//为了演示第一种多视图是实现方法,把Vew的实例创建放在了这里

m_pOtherView->Create(NULL, NULL, WS_CHILD, rect, m_pMainWnd, m_ID, &context);


// The one and only window has been initialized, so show and update it.

m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);

m_pMainWnd->UpdateWindow();

m_currentView=1;

return TRUE;

}

1. SDI单文档多视图实现方法1
void CMultiViewApp::OnViewOtherview()

{

// TODO: Add your command handler code here

UINT temp = ::GetWindowLong(m_pOtherView->m_hWnd, GWL_ID);

::SetWindowLong(m_pOtherView->m_hWnd, GWL_ID, ::GetWindowLong(m_pFirstView->m_hWnd, GWL_ID));

::SetWindowLong(m_pFirstView->m_hWnd, GWL_ID, temp);


m_pFirstView->ShowWindow(SW_HIDE);

m_pOtherView->ShowWindow(SW_SHOW);


((CFrameWnd*)m_pMainWnd)->SetActiveView(m_pOtherView);

((CFrameWnd*) m_pMainWnd)->RecalcLayout();

m_pOtherView->Invalidate();


}


void CMultiViewApp::OnViewFirstview()

{

// TODO: Add your command handler code here


UINT temp = ::GetWindowLong(m_pOtherView->m_hWnd, GWL_ID); //GetWindowWord()

::SetWindowLong(m_pOtherView->m_hWnd, GWL_ID, ::GetWindowLong(m_pFirstView->m_hWnd, GWL_ID));//SetWindowWord()

::SetWindowLong(m_pFirstView->m_hWnd, GWL_ID, temp);//SetWindowWord()


m_pOtherView->ShowWindow(SW_HIDE);

m_pFirstView->ShowWindow(SW_SHOW);


((CFrameWnd*)m_pMainWnd)->SetActiveView(m_pFirstView);

((CFrameWnd*)m_pMainWnd)->RecalcLayout();

m_pFirstView->Invalidate();

}

2. SDI单文档多视图实现方法2
void CMultiViewApp::OnViewChange(UINT nCmdID)

{

//另外一种方法实现SDI的多视图切换

CView* pViewAdd;

CView* pViewRemove;

CMainFrame* pMainFrame=(CMainFrame*)AfxGetMainWnd();

CDocument* pDoc = pMainFrame->GetActiveDocument();


if((nCmdID == ID_VIEW_VIEW1) && (m_currentView == 1))

return;

if((nCmdID == ID_VIEW_VIEW2) && (m_currentView == 2))

return;


if (nCmdID == ID_VIEW_VIEW2)

{

if (m_pView2 == NULL)

{

m_pView1 = pMainFrame->GetActiveView();

m_pView2 = new COtherView();


//Note that if OnSize has been overridden in CMyView2

//and GetDocument() is used in this override it can

//cause assertions and, if the assertions are ignored,

//cause access violation.

//使用CCreateContext structure实现view和document的关联

CCreateContext context;

context.m_pCurrentDoc=pDoc;//m_pView1->GetDocument();


m_pView2->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,

CFrameWnd::rectDefault, AfxGetMainWnd(), AFX_IDW_PANE_FIRST + 1, &context/*NULL*/);

}

pViewAdd = m_pView2;

pViewRemove = m_pView1;

m_currentView= 2;

}

else

{

pViewAdd = m_pView1;

pViewRemove = m_pView2;

m_currentView= 1;

}


// Set the child i.d. of the active view to AFX_IDW_PANE_FIRST,

// so that CFrameWnd::RecalcLayout will allocate to this

// "first pane" that portion of the frame window's client area

// not allocated to control bars. Set the child i.d. of the

// other view to anything other than AFX_IDW_PANE_FIRST; this

// examples switches the child id's of the two views.


int nSwitchChildID = pViewAdd->GetDlgCtrlID();

pViewAdd->SetDlgCtrlID(AFX_IDW_PANE_FIRST);

pViewRemove->SetDlgCtrlID(nSwitchChildID);


// Show the newly active view and hide the inactive view.


pViewAdd->ShowWindow(SW_SHOW);

pViewRemove->ShowWindow(SW_HIDE);


// Connect the newly active view to the document, and

// disconnect the inactive view.

//通过CCreateContext实现视图View和文档Document的关联

//就没有必要手动AddView(),如果需要可以进行手动RemoveView()

//AddView()会在CView::OnCreate()被MFC调用,RemoveView()会在CView::~CView()被调用

//当然可以根据需要手动调用它们,在本例当中,View都是被创建一次,没有被销毁,所以不会自动

//调用RemoveView()

//pDoc->AddView(pViewAdd);

//pDoc->RemoveView(pViewRemove);


pMainFrame->SetActiveView(pViewAdd);

pMainFrame->RecalcLayout();


return ;

}

The code needed to implement view switching depends on the frame window containing the view. There are three common cases: the view is contained within a CFrameWnd (SDI application), the view is contained within a CMDIChildWnd (MDI application) and the view is a pane of a splitter window, either in SDI or MDI applications. In all cases, what we need is a method in our document class to switch to the desired view. This method should receive the new view as a parameter and return the view that was replaced. This returned view is not contained in the document's list anymore. The advantage of having this method in the document class becomes obvious when there are several document types each of which can have different view types. Let's start with an SDI application that doesn't have splitters:

Collapse Copy Code
CView* CMyDocument::SwitchToView ( CView* pNewView )
{
CFrameWnd* pMainWnd = (CFrameWnd*)AfxGetMainWnd();
CView* pOldActiveView = pMainWnd->GetActiveView();
ASSERT(pOldActiveView != NULL);
ASSERT_VALID(pOldActiveView);
ASSERT(pOldActiveView->GetDocument() == this); // must be attached to us

/* Set the child window ID of the active view to AFX_IDW_PANE_FIRST.
This is necessary so that CFrameWnd::RecalcLayout will allocate
this "first pane" to that portion of the frame window's client
area not allocated to control bars. Set the child ID of
the previously active view to some other ID.
*/

::SetWindowLong(pOldActiveView->m_hWnd, GWL_ID, 0);
::SetWindowLong(pNewView->m_hWnd, GWL_ID, AFX_IDW_PANE_FIRST);

// Show the newly active view and hide the inactive view.
pNewView->ShowWindow(SW_SHOW);
pOldActiveView->ShowWindow(SW_HIDE);

// Connect the newly active view to the document,
// and disconnect the inactive view
AddView(pNewView);
RemoveView(pOldActiveView);
pMainWnd->SetActiveView(pNewView);
pMainWnd->RecalcLayout();

return pOldActiveView;
}In the case of an MDI application (again without splitters):

Collapse Copy Code
CView* CMyDocument::SwitchToView ( CView* pNewView )
{
CMDIFrameWnd* pMainWnd = (CMDIFrameWnd*)AfxGetMainWnd();

// Get the active MDI child window.
CMDIChildWnd* pChild = (CMDIChildWnd*)pMainWnd->MDIGetActive();

// Get the active view attached to the active MDI child window.
CView* pOldActiveView = pChild->GetActiveView();

// Set flag so that document will not be deleted when view is dettached.
BOOL bAutoDelete = m_bAutoDelete;
m_bAutoDelete = FALSE;

// Dettach existing view
RemoveView(pOldActiveView);

// restore flag
m_bAutoDelete = bAutoDelete;

// Show the newly active view and hide the inactive view.
pNewView->ShowWindow(SW_SHOW);
pOldActiveView->ShowWindow(SW_HIDE);

// Attach new view
AddView(pNewView);

pChild->RecalcLayout();
pNewView->UpdateWindow();
pChild->SetActiveView(pNewView);
return pOldActiveView;
}When the view to replace is a pane of a splitter window, there is also a small difference between SDI and MDI applications, related to the retrieval of the current active view. In the method below, you must comment out what you don't need depending on your application type:

Collapse Copy Code
CView* CSDISplitDoc::SwitchToView ( CView* pNewView )
{
/* Uncomment this if this is a SDI application
CFrameWnd* pMainWnd = (CFrameWnd*)AfxGetMainWnd();
CView* pOldActiveView = pMainWnd->GetActiveView();
*/

/* Uncomment this if this is a MDI application
CMDIFrameWnd* pMainWnd = (CMDIFrameWnd*)AfxGetMainWnd();

// Get the active MDI child window.
CMDIChildWnd* pChild = (CMDIChildWnd*)pMainWnd->MDIGetActive();

// Get the active view attached to the active MDI child window.
CView* pOldActiveView = pChild->GetActiveView();
*/

CSplitterWnd* pSplitter = (CSplitterWnd *)pOldActiveView->GetParent();
int row, col;
ASSERT(pSplitter->IsChildPane(pOldActiveView, row, col));

// set flag so that document will not be deleted when view is destroyed
m_bAutoDelete = FALSE;

// Dettach existing view
RemoveView(pOldActiveView);

// set flag back to default
m_bAutoDelete = TRUE;
/* Set the child window ID of the active view to the ID of the corresponding
pane. Set the child ID of the previously active view to some other ID.
*/
::SetWindowLong(pOldActiveView->m_hWnd, GWL_ID, 0);
::SetWindowLong(pNewView->m_hWnd, GWL_ID, pSplitter->IdFromRowCol(row, col));

// Show the newly active view and hide the inactive view.
pNewView->ShowWindow(SW_SHOW);
pOldActiveView->ShowWindow(SW_HIDE);

// Attach new view
AddView(pNewView);

// Set active
pSplitter->GetParentFrame()->SetActiveView(pNewView);
pSplitter->RecalcLayout();
pNewView->SendMessage(WM_PAINT);

return pOldActiveView;
}The SwitchToView functions above receive a pointer to an existing view, so a view must have already been created without attaching it to a document. Note that this imposes restrictions on view creation code, which should not make use of the document in any way (for example, the OnInitialUpdate member function). Otherwise, exceptions might occur. The newly activated view is shown before it is attached to the document, so functions in the view that respond to Windows messages such as WM_SIZE or WM_GETMINMAXINFO should not make use of the document either.

The view must be created with correct parent window and window ID. Both parameters depend on the frame windows containing the view, just the same as the SwithToView function. The non-active views could be created the first time the menu to select one of them was selected or somewhere in the document initialization code. Supposing we have a m_pView1 member in the document class that is a pointer to a view, this is how it should be created in a SDI application:

Collapse Copy Code
if (!m_pView1)
{
// create the new view
m_pView1 = new CView1;
m_pView1->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, CFrameWnd::rectDefault,
AfxGetMainWnd(), AFX_IDW_PANE_FIRST+1, NULL);
}In a MDI application:

Collapse Copy Code
CMDIFrameWnd* pMainWnd = (CMDIFrameWnd*)AfxGetMainWnd();
// Get the active MDI child window.
CMDIChildWnd* pChild = (CMDIChildWnd*)pMainWnd->MDIGetActive();

if (!m_pView1)
{
// create the new view
m_pView1 = new CView1;
m_pView1->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, CRect(0, 0, 0, 0),
pChild, AFX_IDW_PANE_FIRST, NULL);
}And finally, if the view is a pane of a splitter window (read the comments to difference between SDI and MDI applications):

Collapse Copy Code
/* Uncomment this if this is a SDI application
CFrameWnd* pMainWnd = (CFrameWnd*)AfxGetMainWnd();
CView* pActiveView = pMainWnd->GetActiveView();
CSplitterWnd* pSplitter = (CSplitterWnd *)pActiveView->GetParent();
*/

/* Uncomment this if this is a MDI application
CMDIFrameWnd* pMainWnd = (CMDIFrameWnd*)AfxGetMainWnd();
CMDIChildWnd* pChild = (CMDIChildWnd*)pMainWnd->MDIGetActive();
CView* pActiveView = pChild->GetActiveView();
CSplitterWnd* pSplitter = (CSplitterWnd *)pActiveView->GetParent();
*/

if (!m_pView1)
{
// create the new view
m_pView1 = new CView1;
m_pView1->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
CRect(0, 0, 0, 0), pSplitter, 0, NULL);
}When we already have an existing view (m_pView1 in our example), we can make this view active as follows:

Collapse Copy Code
CView* pOldActiveView = SwitchToView(m_pView1);
if (!pOldActiveView)
// there was not an active view
else
// pOldActiveView is a pointer to the now inactive viewNote that inactive views destroy themselves when their parent window is destroyed, so you don't have to worry about destroying them.
分享到:
评论

相关推荐

    威盛电子发布PCI Express芯片组,支持威盛处理器平台

    它是一款高集成的核心逻辑解决方案,支持PCI Express 、 DDR2和一系列丰富的数字多媒体功能,包括威盛UniChrome:trade_mark: Pro集成显卡,支持硬件MPEG-2播放DuoView+:trade_mark:双屏输出。 作为搭载世界首款无碳...

    主板与CPU的搭配

    其最大特点是整合了一款支持DX9的DeltaChrome IGP图形核心,支持DuoView显示技术,具有DVI/TV-out接口。 现在大部分的板子上都集成了声卡、网卡,就算是比较高档的板子也有。声卡,我觉得用集成的就行,现在好一点...

    安全隐患台账(模版).xls

    安全隐患台账(模版).xls

    基于 Java+Mysql 实现的小型仓库管理系统-课程设计(含课设文档+源码)

    【作品名称】:基于 Java+Mysql 实现的小型仓库管理系统-课程设计(含课设文档+源码) 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【项目介绍】:项目说明 1、项目结构:maven+mvc(M模型用的是mybatis技术) 2、项目模式:C/S(客户机/服务器)模式 3、编辑器:IDEA 2019.3.1 4、mysql版本号:5.1.38

    基于VHDL的倒车雷达项目(免费提供全部源码)

    项目简介: 本项目实现了一个基于VHDL(VHSIC硬件描述语言)的倒车雷达系统。倒车雷达用于检测车辆后方障碍物的距离,以辅助驾驶员安全倒车。系统通过超声波传感器检测距离,并使用LED显示或蜂鸣器提示障碍物的接近程度。 项目模块: 传感器接口模块: 处理超声波传感器的信号。 发送触发信号,接收回波信号。 计算回波时间,进而计算距离。 距离计算模块: 根据传感器回波时间计算距离。 处理和转换距离数据,准备用于显示和警报。 警报显示模块: 基于计算出的距离提供视觉和听觉警报。 使用LED显示不同的距离范围。 使用蜂鸣器发出不同频率的警报声。 控制模块: 控制各模块的协调工作。 管理超声波传感器的触发和数据采集周期。

    试验检测仪器设备(参考标准、有证标准物质)一览表.doc

    试验检测仪器设备(参考标准、有证标准物质)一览表.doc

    vuInhub靶场实战系列-Kioptrix Level #1

    vuInhub靶场实战系列-Kioptrix Level #1

    野火的ESP8266配套例程

    本资源是配套作者博客【stm32、ESP8266、华为云 搭建一个简单的物联网系统】

    GPU:计算机图显核心,计算场景应用崛起

    GPU:计算机图显核心,计算场景应用崛起

    Web3.0初探:一个基于区块链技术、用户主导、去中心化的网络生态

    Web3.0:致力打造一个基于区块链技术、用户主导、去中心化的网络生态。在Web3.0中,用户为满足自身需求进行交互操作,并在交互中利用区块链技术,从而实现价值的创造、分配与流通。这样的整个用户交互、价值流通的过程就形成了Web3.0生态。相比Web2.0的平台中心化特征,Web3.0致力于实现用户所有、用户共建的“去中心化”网络生态。

    2024年亲子旅游行业分析报告.pptx

    行业报告

    MQD企业大学建设思路与年度工作重点.pptx

    MQD企业大学建设思路与年度工作重点.pptx

    Java语言基础入门教程 Java实训教程 4.类构造函数-this-静态属性方法-instanceof运算符共55页.pptx

    Java语言基础入门教程 Java实训教程 4.类构造函数-this-静态属性方法-instanceof运算符共55页.pptx

    openssh-9.7p1-1.el6.x86-64.tgz

    centos 6 redhat 6 x86架构的openssh 9.7版本二进制rpm包 安全更新、升级安装新版本openssh 9.7版本,当前最新版本,修复安全漏洞。 2024年6月8日制作,内含ssh-copy-id命令

    风传花信,雨濯春尘-中国人身险产品变迁史与未来展望

    风传花信,雨濯春尘——中国人身险产品变迁史与未来展望 按照不同分类方法,人身险可以分为以下种类: 1)按保障责任划分:人寿保险、健康保险、意外伤害保险、年金保险; 2)按设计类型划分:普通型、分红型、投资连结型、万能型。 40 年间中国人身险产品历经多次变迁,从单一死亡风险保障到多元风险覆盖+兼备理财储蓄功能。

    C08-我的笔记02.md

    C08-我的笔记02.md

    公司项目试验仪器设备台账.docx

    公司项目试验仪器设备台账.docx

    transformer灵魂21问

    transformer灵魂21问

    YOLOv10的改进技术点.pdf

    YOLOv10的改进技术点主要体现在以下几个方面: 1.一致双分配策略(Consistent Dual Assignments): 1.YOLOv10采用了一致双分配策略,通过双重标签分配和匹配指标的一致性,实现了无需NMS(非最大抑制)的后处理训练。这既保证了训练阶段的丰富监督信息,又实现了高效的无NMS预测,提升了性能和速度。 2.在训练过程中,一对一头部与传统的一对多头部合并,两者共享相同的优化目标,但使用不同的匹配策略。一对多头部提供了丰富的监控信号,而一对一头部在推理过程中确保了高效、无NMS的预测。 2.整体效率和精度驱动的模型设计: 1.YOLOv10采用了整体效率和精度驱动的模型设计策略,从效率和精度两个角度对各种YOLO组件进行优化。 2.效率驱动型模型设计:通过使用深度可分离卷积的简化架构来减少计算开销,分离空间减少和信道增加减少计算成本并保留信息。同时,使用内在秩分析来识别和减少模型阶段的冗余,用更有效的结构代替复杂的块。 3.精度驱动的模型设计:通过增加深度阶、引入大型核卷积和部分自注意力模块来增强模型能力,提高性能。 3.性能与效率的提升: 1.YOLOv10

    基于 PHP 开发的线上网校系统 支持线上点播 - 知识付费 - 网校装修 - 数据统计 - 会员模块 - 角色管理等丰富功能

    MeEdu 是一款基于 PHP 开发的线上网校系统。支持线上点播 | 知识付费 | 网校装修 | 数据统计 | 会员模块 | 角色管理等丰富功能。MeEdu 采用前后端分离模式,覆盖 PC | H5 端口。特点:系统稳定 | 功能丰富 | 界面优美 | 持续迭代。截止目前,已超过 1000+ 个人/企业用户选用 MeEdu 搭建了他们的独立网校平台。

Global site tag (gtag.js) - Google Analytics