View和Control的区别(如何在对话框上使用CView类)

CView继承类,和其他窗口类的区别,很重要的就是对CDocument类和CFrameWnd类的操作,而其中,涉及CDocument类的操作,都进行了有效性判断(m_pDocument != NULL),CView类初始化的时候,m_pDocument = NULL,因此并不影响CView类作为控件的使用。涉及CFrame类的操作,有这么几个地方:   
第一个地方:CView::OnDestroy()。
  1. void CView::OnDestroy()  
  2. {   
  3.   CFrameWnd* pFrame = GetParentFrame();   
  4.   if (pFrame != NULL && pFrame->GetActiveView() == this)   
  5.       pFrame->SetActiveView(NULL);    // deactivate during death    
  6.   CWnd::OnDestroy();   
  7. }     
 
   第二个地方:CView::OnActivateFrame()。
  1. void CView::OnActivateFrame(UINT /*nState*/, CFrameWnd* /*pFrameWnd*/) { }  
 

这里,其实是空的,在CView继承类中,只有CFormView类继承了这个虚函数
  1. void CFormView::OnActivateFrame(UINT nState, CFrameWnd* /*pFrameWnd*/)  
  2. {  
  3.   if (nState == WA_INACTIVE)   SaveFocusControl();     // save focus when frame loses activation   
  4. }   
  
实际上都不需要真的CFrame指针,对CView类作为控件使用没有障碍。
  
第三个地方:CView::OnMouseActivate()。
  1. int CView::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)  
  2. int nResult = CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message); if (nResult == MA_NOACTIVATE || nResult == MA_NOACTIVATEANDEAT)   return nResult;   // frame does not want to activate CFrameWnd* pParentFrame = GetParentFrame(); if (pParentFrame != NULL) {   // eat it if this will cause activation   ASSERT(pParentFrame == pDesktopWnd || pDesktopWnd->IsChild(pParentFrame));   // either re-activate the current view, or set this view to be active   CView* pView = pParentFrame->GetActiveView();   HWND hWndFocus = ::GetFocus();   if (pView == this &&    m_hWnd != hWndFocus && !::IsChild(m_hWnd, hWndFocus))   {    // re-activate this view    OnActivateView(TRUE, this, this);   }   else   {    // activate this view    pParentFrame->SetActiveView(this);   } } return nResult; }     
 
另外,在CView::PostNcDestroy(),实现了CView类的自我销毁,这是因为CView类是可以动态生成的(DECLARE_DYNCREATE/IMPLEMENT_DYNCREATE)。
// self destruction
void CView::PostNcDestroy()
{ // default for views is to allocate them on the heap
  //  the default post-cleanup is to 'delete this'.
  //  never explicitly call 'delete' on a view delete this;   
}
  基本上,修改了CView继承类的这几个地方,直接返回不要调用基类相应的成员函数,就可以在对话框上使用。   
  下面举例,用向导生成对话框应用程序,对话框类为CMyDigalog。   
  从CHTMLView类继承一个CHTMLCtrl类,建立相应的消息处理函数并修改以下几个地方:

  1. // CHTMLCtrl 消息处理程序   
  2. int CHTMLCtrl::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)  
  3. {  
  4.  return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message);   
  5. //return CHtmlView::OnMouseActivate(pDesktopWnd, nHitTest, message);    
  6. }   
  7. void CHTMLCtrl::OnDestroy()   
  8. //CHtmlView::OnDestroy();    
  9.  CWnd::OnDestroy();   
  10. }   
  11. void CHTMLCtrl::PostNcDestroy()   
  12. // TODO: 在此添加专用代码和/或调用基类    
  13.   //CHtmlView::PostNcDestroy();    
  14. }   
  15. void CHTMLCtrl::OnActivateFrame(UINT nState, CFrameWnd* pDeactivateFrame)   
  16. // TODO: 在此添加专用代码和/或调用基类    
  17. //CHtmlView::OnActivateFrame(nState, pDeactivateFrame);    
  18. }   
  

增加一个成员函数CreateFromCtrl: 
public: BOOL CreateFromCtrl(UINT nID, CWnd* pParent);   
这个函数通过对话框上的控件创建一个CHTMLCtrl控件,目的是在对话框设计的时候便于布局: 
  1. BOOL CHTMLCtrl::CreateFromCtrl(UINT nID, CWnd* pParent)   
  2. {   
  3.   if (!pParent || !pParent->GetSafeHwnd())  
  4.    return FALSE;  
  5.   CWnd *pCtrl = pParent->GetDlgItem(nID);  
  6.   if (!pCtrl)  
  7.    return FALSE;  
  8.   CRect rcCtrl;  
  9.   pCtrl->GetWindowRect(rcCtrl);  
  10.   pParent->ScreenToClient(rcCtrl);  
  11.   UINT style = ::GetWindowLong(pCtrl->GetSafeHwnd(), GWL_STYLE);  
  12.   pCtrl->DestroyWindow();  
  13.   return Create(NULL, NULL, style | WS_CHILD | WS_VISIBLE, rcCtrl, pParent, nID, NULL);  
  14. }  
 
  还应注意,默认的从CView继承的类,其构造函数和析构函数是protected的,需要修改成public。 
public: CHTMLCtrl(); // 动态创建所使用的受保护的构造函数 
virtual ~CHTMLCtrl();   
然后,在对话框模板中(使用资源编辑器),插入一个Static Text控件,ID为IDC_HTML。
 在对话框头文件中,插入包含文件: #include "htmlctrl.h" 
 增加CHTMLCtrl类型的成员变量: CHTMLCtrl m_ctlHTML;  
 在对话框初始化的时候,创建这个CHTMLCtrl控件:
  1. BOOL CMyDialog::OnInitDialog()   
  2. {  
  3.  CDialog::OnInitDialog();  
  4.  ...  
  5.  m_ctlHTML.CreateFromCtrl(IDC_HTML, this);  
  6.  return TRUE;   
  7. }  
 
 下面,再添加一个按钮,在按钮的消息响应函数中打开HTML文件: 
  1. void CMyDialog::OnSysCommand(UINT nID, LPARAM lParam)   
  2. {   
  3. if ((nID & 0xFFF0) == IDM_ABOUTBOX)  
  4.  {  
  5.    CAboutDlg dlgAbout;  
  6.    dlgAbout.DoModal();  
  7.  } else {  
  8.    CDialog::OnSysCommand(nID, lParam);  
  9.  }   
  10. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值