返回首页

下载演示项目 - 26.7 KB
{S0}简介
本文详细介绍如何可以使用我的CMultiSplitterView类,允许 实施一个拆分窗格内的多个切换意见。在图像 上面的灰色地带,是第一种观点。通过菜单栏,然后​​点击"查看 GT显示第二查看"程序动态变化的第一个视图的第二&# 160; 的看法。
这个类允许你切换到任何视图中创建一个函数调用, 没有做任何事情!添加视图是一个函数调用,只要简单 以及。现在,细节... ...代码的详细信息
一切的核心是位于MultiSplitterView.cpp和MultiSplitterView.h。
拆分窗格添加视图都是在这里完成:

 bool CMultiSplitterView::AddSwitchableView(UINT id, 

                 CRuntimeClass * pView,

                 CCreateContext* pContext,

                 CRect & size, bool isFirstView, UINT altId)

{

   CWnd* pWin;

   DWORD style;



   pWin  = (CWnd*) pView->CreateObject();

   style = WS_CHILD ;

   

   if (isFirstView) 

   {

     style |=  WS_VISIBLE ;

   }



   pWin->Create(NULL, NULL, style, size , this, id, pContext);



   if (isFirstView) // id provided is usally diff. so use alternate

   {

     views[pWin] =altId ;

   }

   else 

   {

     views[pWin] = id;

   }



   return true;

}


第一个参数是视图的ID,您的观点联系在一起的,因此您 & #160;可以看看轻松。第二个参数是调用的RUNTIME_CLASS(SomeViewClass) 返回一个指针到的CRuntimeClass类。第三个参数是CCreateContext 在CMainFrame类的OnCreateClient funtion给你。第四 参数是窗口的尺寸。最后两个是可选的,并会 仅可用于AddSwitchableView()在第一次调用。由于为ID 第一个参数是窗格的ID将被设置为第一种观点,我需要 通过在这个类的用户与视图关联的真实ID, 因此,最后一个参数,称为陆运。
好了,我们通过在所有这些PARAMS,然后我们创建一个对象的 是通过它转换为它的基类的运行时类的类型CWnd的 创建和存储。请注意,在调用CWnd对象创建我  ; 始终使用该ID通过这个指针联营公司的观点与 分离器。我然后存储指针的CWnd的"关键"在maplt; GT; 和使用的ID为以后查找的值或替代ID。
 60;
接下来,我们需要切换视图动态之一,是看到另一 是隐藏的。
下面的代码处理任何的若干意见交换:{C}
OK,所以现在的用户或GUI所谓的SwitchView()与一些 ID和行的拆分视图所属的山坳。首先,我们得到 当前视图的使用由用户提供的Row和Col的指针。下一页 我们得到了新的观点(我们的观点与 ID通过)。我们确认,他们不为NULL,然后 从主窗口CFrameWnd的指针。然后,我们比较 & #160;活动视图的旧观点,看看他们是相同的(他们应该) 并设置新的要求的观点。当我们隐藏和显示旧的, 60; 新的观点,是必不可少的,我们设置的新视图的ID& #160; 该视图关联的,因为这是孩子从Row和Col的ID 窗口的窗格。我们下一步查找在maplt旧观点的ID; GT; 60; 因为它的控件的ID依然是从IdFromRowCol()的ID。我们   ;然后重置控件的ID在maplt的存储; GT;使视图 指针可以检索
如何使用:
,在您的CMainFrame,你必须首先包括MultiViewSplitter.h 头文件。接下来,声明一个成员VAR类型CMultiViewSplitter。 下一步在CMainFrame的OnCreateClient(内):

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)

{



CRect r;

GetWindowRect(r);



m_SplitterFirst.CreateStatic(this,1,2); 



m_SplitterFirst.CreateView(0,0, RUNTIME_CLASS( CSomeView) ,

               CSize(r.Width() *0.14, r.Height()), pContext); 





m_SplitterSeconde.CreateStatic(&m_SplitterFirst, 2, 1, WS_CHILD | WS_VISIBLE |

                 WS_BORDER, m_SplitterFirst.IdFromRowCol(0, 1));



/******************* Add switchable views **************************/



   m_SplitterSeconde.AddSwitchableView(m_SplitterSeconde.IdFromRowCol(0, 0),

            RUNTIME_CLASS(CFirstView) ,pContext, CRect(0,0,r.Width(), r.Height()) ,

      true , FIRST_VIEW);



   m_SplitterSeconde.AddSwitchableView(SECOND_VIEW, 

      RUNTIME_CLASS( CSecondView), pContext,

      CRect(0,0,r.Width(), r.Height()*0.60) );



/******************************************************************/



  ...



}


只有部分真正为这个例子中,最重要的是后评论 说"添加切换的意见"。我第一次分裂分配器称为m_SplitterFirst 到2列。然后,我创建了第二个孩子的第一分路分配器 并分裂成两行。现在,这是所有你无关紧要,因为你 可能决定分割你的窗口,但是你认为合适的。
对于第一次调用AddSwitchableView(),请务必使用分离器的ID 提供调用m_SplitterSeconde.IdFromRowCol(X,X),并提供备用  60;作为倒数第二个参数表明这种观点作为最后一个参数和真实的ID 第一种观点。
内的RUNTIME_CLASS(X)的调用,添加类名 任何类封装您的看法。
哇,这就是它!现在,每当你想动态切换视图,只需调用 &# 160;通过SwitchView(X),其中x是视图的ID。请下载 为说明这是如何工作的例子演示工程。
如果任何票这篇文章作为一个得分较低(小于4或5)你能不能给 我告诉我,为什么你给我的,得分和什么我可以做的更好的礼貌。 0; 建议,荣誉,问题是值得欢迎的。感谢您的时间。其他有用的功能
GetViewPtr(UINT ID,INT paneRow,INT paneCol) - 获取一个基类CWnd的指针 与分离器。

回答

评论会员:rkshdixit 时间:2011/12/01
您好,
好文章。
我试图创建与切换类的ListView,但IM无法添加coloum报告模式。请给我一些建议。

在此先感谢
评论会员:ZBPELZER 时间:2011/12/01
亲爱的丹,
您的CMultiSplitterView类是很大的。
我只有一个小问题。
在您的示例应用程序中,我错过主程序图标

我已经尝试此程序图标添加,但没有功能。你知道吗?
兹比格涅夫


评论会员:佩尔泽 时间:2011/12/01
见下文(FCT CL2PacketMakerApp::InitInstance中()):{ BR}。
/ /创建主窗口,这个代码创建一个
/ /新的框架窗口
/ /对象,然后设置为应用程序的主
/ /窗口对象
的CMainFrame * pFrame =新的CMainFrame;
m_pMainWnd = pFrame;

...

HICON的hIcon = AfxGetApp() - > LoadIcon(IDR_MAINFRAME);
(HICON)
{
pFrame ->操作SetIcon(HICON,FALSE)
pFrame ->操作SetIcon(HICON,TRUE);
}

评论会员:oocode 时间:2011/12/01
我插入代码中发现了一些问题。首先,这里是我如何使用您的代码:

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)

{

	CRect cr;

	GetWindowRect(&cr);

	int nHeight = ::GetSystemMetrics(SM_CYSCREEN);

	// Create the main splitter with 2 rows and 1 columns

	if (!m_mainSplitter.CreateStatic(this, 2, 1))

	{

		AfxMessageBox("Error setting up splitter window", MB_ICONERROR);

		return FALSE;

	}

 

	m_mainSplitter.AddSwitchableView(RUNTIME_CLASS(CGridCtrlView),    pContext, CRect(0, 0, cr.Width(), nHeight), _VIEW_1_);

	m_mainSplitter.AddSwitchableView(RUNTIME_CLASS(CPatientInfoView), pContext, CRect(0, 0, cr.Width(), nHeight), _VIEW_2_);

 

	m_mainSplitter.CreateView(0, 0, RUNTIME_CLASS(CSplitterViewTestView), CSize(cr.Width(), nHeight), pContext);

	m_mainSplitter.CreateView(1, 0, RUNTIME_CLASS(CWaitingView),          CSize(cr.Width(), 0), pContext);

 

	return TRUE;

}


请注意,我开始在AddSwitchableView功能没有添加分配器。这仅仅是一个地方的持有人认为,允许初始化完成。在这里我使用实际调用SwitchViews()函数的代码:

	m_mainSplitter.SwitchView(_VIEW_1_, 0, 0);




	m_mainSplitter.SwitchView(_VIEW_2_, 0, 0);


我第一次调用m_mainSplitter.SwitchViews说,它无法找到的旧观点的指针,函数,因此需要,我选择其他补充意见前,将启动开关。这里是有问题的代码:

	CWnd* pCwnd =(CWnd*)pOldView; // upcast to CWnd ptr

	if (views.find(pCwnd) == views.end()) // search for CWnd ptr

	{

		#ifdef SHOW_MB

			MessageBox("Failed to find old view ptr !!!");

		#endif

		return false;

	}

	UINT oldId = views[pCwnd]; // get id of this view for future lookup

	pOldView->SetDlgCtrlID(oldId); // reset view id, so we can look it up


下面是我所做的修复:

	CWnd* pCwnd =(CWnd*)pOldView; // upcast to CWnd ptr

	if (views.find(pCwnd) != views.end()) // search for CWnd ptr

	{

		UINT oldId = views[pCwnd]; // get id of this view for future lookup

		pOldView->SetDlgCtrlID(oldId); // reset view id, so we can look it up

	}



"为什么你不配合你的脚踝周围煤油浸泡过的抹布,让蚂蚁不会爬上,吃你的糖果屁股... ..." - 山谷Earnhardt,1997年{BR }-----{ BR }"...淫秽惊人层在发言中这么多层次的艺术工作"。贾森 - Jystad,2001年10月26日
评论会员:pank007 时间:2011/12/01
亲爱的丹,

感谢你的好工作,你

我OnInitialUpdate是没有所谓的切换视图的问题。
此功能是非常重要的,因为我想要做一些特殊的初始化CFormViews

它的工作原理,当我添加以下几行
后在AddSwitchableView创建视图:
{ BR}(PVIEW - GT; IsDerivedFrom(RUNTIME_CLASS(CView中)))
{
/ /发送初始通知消息
PWIN - GT; SendMessage函数(WM_INITIALUPDATE);


也许你此行添加到您的解决方案



奥拉夫
评论会员:弥敦道霍尔特CCEI 时间:2011/12/01
我喜欢它,它会是不错的,如果左窗格中查看。或树控件看起来像一个使用Newsbin临
伟大的工作
托尼
评论会员:WREY 时间:2011/12/01
感谢你创建这个类。它应该可以更容易地编写一个资源管理器风格的应用程序。

弥敦道

评论会员:丹克拉克 时间:2011/12/01


威廉

福特斯等opere真正
评论会员:!WREY 时间:2011/12/01
威廉,

样本是VS7的2003年创建。然而,它可以加载在VS6,只需添加头文件和cpp文件。让我知道它是如何。请记住,投票的文章
我通常加载到VS7的(前03)
VS7的03项目删除。sln文件和改变的。vcproj"="7.10"版本"版本="7.00"

- 丹




@{${$丹} {C} {克拉克} [1]
评论会员:Neta777 时间:2011/12/01
感谢的小费(即使我已经知道如何做到这一点)。我的观点是更直接的样本错标为VC6的样品时,它实际上是一个VC7样本。

需要包含"#pragma警告(禁用:4786)"。"为MainFrm.h"和"MultiSplitterView.h"为了抑制众多的STL警告

好!



威廉

等opere真正的特长
评论会员:丹克拉克 时间:2011/12/01
丹,

请原谅我的无能,但我没项目,即使在以前的电子邮件线程的指示,在VC6打开。
你能提供转换为VC6中一步一步的指示,或提供一个VC6的版本吗?

大加赞赏,
NETA
评论会员:Neta777 时间:2011/12/01
嘿内塔,

这里是VS6代码的zip文件,其中包含的URL。我会问在CodeProject偷看文章以及,但在那之前,这个URL将会快很多。
让我知道如果您有任何疑问或问题。

http://www.dancclark.com/code/MultiViewSplitter_VS6.zip

- 丹




@{${$丹} {C} {克拉克} [1]
评论会员:xablackandblue 时间:2011/12/01
感谢丹 - 这就是我一直在寻找有一些文件丢失。DSP文件,但它是很简单的添加它们。
现在,在VC6编译和运行; P

评论会员:Flaviu2 时间:2011/12/01
有大约200警告当我在VC6编译,
就像:
"警告C4786::标识符TR
uncated '255'字,在浏览器信息"
什么是错的?