+ -
当前位置:首页 → 问答吧 → 如何在CPropertyPage里建一个多文档的窗口?

如何在CPropertyPage里建一个多文档的窗口?

时间:2011-12-14

来源:互联网

本人要做一个石油软件,支持读入多口的数据,每一口井数据处理有很多步骤,其中每一步可能有产生多条曲线,我采用类似saphir软件的思路处理:
如图:
相当于,视图CFormView来表示一口井的数据,而计算步骤用CPropertyPage对应,那么一个计算步骤里可能产生的多条曲线分别要放到不同的Dialog中(要求要用对话框,如果还用CPropertyPage就不会发帖了),我采用了如下两条思路实验过,思路及出现的问题分别如下:
思路1、用无模式的WS_CHILD风格的对话框实现,但是很不理想,原因是:如果主窗口(或者CFormView)的大小及位置改变,但是该窗口不会变化。也许你会想到重载该Dialog的OnWindowPosChanging()或者OnMoving()之类的来使得该Dialog跟随CFormView的大小及位置而动态改变,但是我要告诉你的是,你做不到像MDI中子窗口的那种效果,就是子窗口一旦超出CMainFrame的范围后只显示部分,而我要的就是这种效果。
思路2:在CPropertyPage中新建一个CMDIFrame,将图画到CMDIFrameWnd上,这个思路也无法实现,程序会崩溃,因为CMDIFrame生成时需要菜单等资源,而我的程序不需要这些东西,只需要这个架子。
  如何解决?我倾向于用第2种思路来做,感觉第二种思路清晰,处理也比较简单,第一种要处理很多消息,肯定到时会出现很多麻烦问题。

作者: shenniu818   发布时间: 2011-12-14

方法2中的程序崩溃肯定还是你代码有一些地方没有处理好,自己调试分析一下

作者: oyljerry   发布时间: 2011-12-14

MDI多文档实现,打开一个View表示一口井。。。

作者: shen_wei   发布时间: 2011-12-14

我的做法如下:
1、继承几个类
  CCanDockDialogPropertyPage继承自CPropertyPage,用来生成属性页;
  CPageChildFrame继承自CMDIFrameWndEx,用来管理子窗口,相当于app中的Mainfram一样的作用。
  CPageChildWnd继承自CMDIChildWndEx,就是显示那个曲线的窗口。
  CChildDialogView继承自CView,用来贴到CPageChildWnd上显示曲线的,为了保持曲线,所以需要用到View类。

2、在CCanDockDialogPropertyPage添加成员变量:

3、在CCanDockDialogPropertyPage的构造函数中:
  CPageChildWnd* m_pPageChildWnd;
CPageChildFrame* m_pPageChildFrm;
  析构函数中:
  if(NULL!=m_pPageChildWnd)
delete m_pPageChildWnd;

if(NULL!=m_pPageChildFrm)
delete m_pPageChildFrm;

4、CCanDockDialogPropertyPage::OnCreate()中创建Frame,代码如下:
  CString strMyClass = AfxRegisterWndClass( CS_VREDRAW |
  CS_HREDRAW,
  ::LoadCursor( NULL, IDC_ARROW ),
  ( HBRUSH )::GetStockObject( WHITE_BRUSH ),
  ::LoadIcon( NULL, IDI_APPLICATION ) );

   
  m_pPageChildFrm = new CPageChildFrame();  
  m_pPageChildFrm->Create(strMyClass, _T( "View" ), WS_CHILD | WS_VISIBLE, m_rectClient, this);//m_rectClient为CCanDockDialogPropertyPage窗口的大小
  m_pPageChildFrm->MoveWindow( 0, 0, 50, 50);

5、在CFame中生成一个窗口CWnd的代码如下:
  5.1、类声明:CChildDialogView* m_pChildDlgView;
  5.2、类构造:m_pChildDlgView=NULL;
  5.3、类析构:
  if(NULL!=m_pChildDlgView)
delete m_pChildDlgView;
  5.4、CPageChildFrame::OnCreate中创建,代码如下:
  if (CMDIFrameWndEx::OnCreate(lpCreateStruct) == -1)
return -1;

//if (CMDIFrameWndEx::Create(_T("CMDIFrameWndEx"), _T( "CMDIFrameWndEx" ), WS_CHILD | WS_VISIBLE, m_rectClient, this) == -1)
// return -1;
 
   
CCreateContext structContext;
  structContext.m_pNewViewClass = RUNTIME_CLASS(CChildDialogView);
  structContext.m_pCurrentDoc = NULL;
  structContext.m_pNewDocTemplate = NULL;
  structContext.m_pLastView = NULL;
  structContext.m_pCurrentFrame = this;

  // Because the CFRameWnd needs a window class, we will create
  // a new one. I just copied the sample from MSDN Help.
  // When using it in your project, you may keep CS_VREDRAW and
  // CS_HREDRAW and then throw the other three parameters.
  //CString strMyClass = AfxRegisterWndClass( CS_VREDRAW |
  // CS_HREDRAW,
  // ::LoadCursor( NULL, IDC_ARROW ),
  // ( HBRUSH )::GetStockObject( WHITE_BRUSH ),
  // ::LoadIcon( NULL, IDI_APPLICATION ) );

  m_pChildDlgView = ( CChildDialogView* )( this->CreateView( &structContext ) );
  ::SendMessage( m_pChildDlgView->GetSafeHwnd(), WM_INITIALUPDATE, 0, 0 );

  this->SetActiveView( (CView*)m_pChildDlgView );


程序会在CMDIFrameWndEx::OnCreate(lpCreateStruct)这里中断,跟踪进入后到CMDIFrameWnd::OnCreateClient()的
ASSERT(pMenu != NULL);这行中断,原因是我创建的CFrame没有菜单这个资源,当然就是NULL啦。怎么才能不出现断言错误呢?
首先说明的是,我的确不需要菜单这些资源。

作者: shenniu818   发布时间: 2011-12-14

上面的帖子有点乱,我重新整理了一下,希望高人给予指点啊,感激不禁:
我的做法如下:
1、继承几个类
  CCanDockDialogPropertyPage继承自CPropertyPage,用来生成属性页;
  CPageChildFrame继承自CMDIFrameWndEx,用来管理子窗口,相当于app中的Mainfram一样的作用。
  CPageChildWnd继承自CMDIChildWndEx,就是显示那个曲线的窗口。
  CChildDialogView继承自CView,用来贴到CPageChildWnd上显示曲线的,为了保持曲线,所以需要用到View类。

2、在CCanDockDialogPropertyPage添加成员变量并创建Frame框架,按如下方式进行:
  2.1、类声明中:
  CPageChildWnd* m_pPageChildWnd; ///存放曲线的每个窗口,每个窗口的曲线数据来自不同地方
  CPageChildFrame* m_pPageChildFrm;//一个防止多窗口的框架
  2.2、类构造中:
  m_pPageChildWnd=NULL;
m_pPageChildFrm=NULL;
  2.2、析构函数中:
  if(NULL!=m_pPageChildWnd)
  delete m_pPageChildWnd;
  if(NULL!=m_pPageChildFrm)
  delete m_pPageChildFrm;
  2.3、CCanDockDialogPropertyPage::OnCreate()中具体开始创建Frame,代码如下:
   
  CString strMyClass = AfxRegisterWndClass( CS_VREDRAW | CS_HREDRAW,::LoadCursor( NULL, IDC_ARROW ),( HBRUSH )::GetStockObject( WHITE_BRUSH ),::LoadIcon( NULL, IDI_APPLICATION ) );
  m_pPageChildFrm = new CPageChildFrame();  
  m_pPageChildFrm->Create(strMyClass, _T( "View" ), WS_CHILD | WS_VISIBLE, m_rectClient, this);//m_rectClient为CCanDockDialogPropertyPage窗口的大小
  m_pPageChildFrm->MoveWindow( 0, 0, 50, 50);

3、在CFame中生成一个窗口CWnd的代码如下:
  3.1、类声明:
  CChildDialogView* m_pChildDlgView;
  3.2、类构造:
  m_pChildDlgView=NULL;
  3.3、类析构: 
  if(NULL!=m_pChildDlgView)
  delete m_pChildDlgView;
  5.4、CPageChildFrame::OnCreate中创建,代码如下:

  if (CMDIFrameWndEx::OnCreate(lpCreateStruct) == -1)
  return -1; 
 
  CCreateContext structContext;
  structContext.m_pNewViewClass = RUNTIME_CLASS(CChildDialogView);
  structContext.m_pCurrentDoc = NULL;
  structContext.m_pNewDocTemplate = NULL;
  structContext.m_pLastView = NULL;
  structContext.m_pCurrentFrame = this;
  m_pChildDlgView = ( CChildDialogView* )( this->CreateView( &structContext ) );
  ::SendMessage( m_pChildDlgView->GetSafeHwnd(), WM_INITIALUPDATE, 0, 0 );
  this->SetActiveView( (CView*)m_pChildDlgView );


程序会在CMDIFrameWndEx::OnCreate(lpCreateStruct)这里中断,跟踪进入后,查看到CMDIFrameWnd::OnCreateClient()的
ASSERT(pMenu != NULL);这行中断,原因是我创建的CFrame没有菜单这个资源,当然就是NULL啦。怎么才能不出现断言错误呢?
首先说明的是,我的确不需要菜单这些资源。

作者: shenniu818   发布时间: 2011-12-14

热门下载

更多