动态连接控件和控件对象

要在程序中创建新设计的控件,显然不能用自动创建的办法,因为对话框模板对新控件的特性一无所知.程序可以用手工方法创建控件,在调用派生类的Create函数时,派生类会调用基类的Create函数创建控件.用Create函数创建控件是一件比较麻烦的工作,程序需要为函数指定一大堆的控件风格以及控件的坐标和ID.特别是控件的坐标,没有经验的程序员很难确切地安排控件的位置和大小,往往需要反复调整.利用MFC的CWnd::SubclassDlgItem和DDX_Control提供的动态连接功能,可以避免Create函数的许多麻烦,该函数大大简化了在对话框中创建派生控件的过程.   在用手工方法创建控件时,先要构建一个控件对象,然后再用Create函数在屏幕上创建控件窗口,也就是说,控件的创建工作是由控件对象完成的.动态连接的思路则不同,SubclassDlgItem可以把对话框中已有的控件与某个窗口对象动态连接起来,该窗口对象将接管控件的消息处理,从而使控件具有新的特性.SubclassDlgItem函数的声明为 BOOL SubclassDlgItem( UINT nID, CWnd* pParent );     参数nID是控件的ID,pParent是指向父窗口的指针.若连接成功则函数返回TRUE,否则返回FALSE.   综上所述,要在程序中使用派生控件,应该按下面两步进行: 在对话框模板中放置好基类控件. 在对话框类中嵌入派生控件类的对象. 在OnInitDialog中调用SubclassDlgItem将派生类的控件对象与对话框中的基类控件相连接,则这个基类控件变成了派生控件.     

例如,如果要在对话框中使用新设计的按钮控件,应先在对话框模板中的合适位置放置一个普通的按钮,然后,在OnInitDialog函数中按下面的方式调用SubclassDlgItem即可:

BOOL CMyDialog::OnInitDialog() 

         CDialog::OnInitDialog(); 
         m_MyButton.SubclassDlgItem(IDC_MYBUTTON, 
this); 
         
return TRUE; 
}
 

 

 

 

实际上DDX_Control会调用SubClassDlgItem

  1. void   AFXAPI   DDX_Control(CDataExchange*   pDX,   int   nIDC,   CWnd&   rControl)   
  2.   {   
  3.   if   ((rControl.m_hWnd   ==   NULL)   &&   (rControl.GetControlUnknown()   ==   NULL))         //   not   subclassed   yet   
  4.   {   
  5.   ASSERT(!pDX->m_bSaveAndValidate);   
  6.     
  7.   pDX->PrepareCtrl(nIDC);   
  8.       HWND   hWndCtrl;   
  9.       pDX->m_pDlgWnd->GetDlgItem(nIDC,   &hWndCtrl);   
  10.   if   ((hWndCtrl   !=   NULL)   &&   !rControl.SubclassWindow(hWndCtrl))   
  11.   {   
  12.   ASSERT(FALSE);             //   possibly   trying   to   subclass   twice?   
  13.   AfxThrowNotSupportedException();   
  14.   }   
  15.   #ifndef   _AFX_NO_OCC_SUPPORT   
  16.   else   
  17.   {   
  18.     if   (hWndCtrl   ==   NULL)   
  19.     {   
  20.   if   (pDX->m_pDlgWnd->GetOleControlSite(nIDC)   !=   NULL)   
  21.   {   
  22.         rControl.AttachControlSite(pDX->m_pDlgWnd,   nIDC);   
  23.   }   
  24.     }   
  25.     else   
  26.     {   
  27.         //   If   the   control   has   reparented   itself   (e.g.,   invisible   control),   
  28.         //   make   sure   that   the   CWnd   gets   properly   wired   to   its   control   site.   
  29.         if   (pDX->m_pDlgWnd->m_hWnd   !=   ::GetParent(rControl.m_hWnd))   
  30.         rControl.AttachControlSite(pDX->m_pDlgWnd);   
  31.     }   
  32.   }   
  33.   #endif   //!_AFX_NO_OCC_SUPPORT   
  34.     
  35.   }   
  36.   }   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值