在自绘窗口的时候,子类化是MFC最常用的窗体技术之一。什么是子类化?窗口子类化就是创建一个新的窗口函数代替原来的窗口函数。

Subclass(子类化)是MFC中最常用的窗体技术之一。子类化完成两个工作:一是把窗体类对象attach到一个windows窗体实体中(即把一个窗体的hwnd赋给该类)。另外就是把该类对象的消息加入到消息路由中,使得该类可以捕获消息。

而通常我们会碰到DDX_Control、SubclassWindow、SubclassDlgItem等,不同的子类化方法。首先先看下面的代码:

void AFXAPI DDX_Control(CDataExchange* pDX, int nIDC, CWnd& rControl)
{
if ((rControl.m_hWnd == NULL) && (rControl.GetControlUnknown() == NULL)) // not subclassed yet
{
ASSERT(!pDX->m_bSaveAndValidate); pDX->PrepareCtrl(nIDC);
HWND hWndCtrl;
pDX->m_pDlgWnd->GetDlgItem(nIDC, &hWndCtrl);
if ((hWndCtrl != NULL) && !rControl.SubclassWindow(hWndCtrl))
{
ASSERT(FALSE); // possibly trying to subclass twice?
AfxThrowNotSupportedException();
}
#ifndef _AFX_NO_OCC_SUPPORT
else
{
if (hWndCtrl == NULL)
{
if (pDX->m_pDlgWnd->GetOleControlSite(nIDC) != NULL)
{
rControl.AttachControlSite(pDX->m_pDlgWnd, nIDC);
}
}
else
{
// If the control has reparented itself (e.g., invisible control),
// make sure that the CWnd gets properly wired to its control site.
if (pDX->m_pDlgWnd->m_hWnd != ::GetParent(rControl.m_hWnd))
rControl.AttachControlSite(pDX->m_pDlgWnd);
}
}
#endif //!_AFX_NO_OCC_SUPPORT }
}

我们发现 DDX_Control()函数中调用了SubclassWindow(),再看SubclassWindow()里写了什么:

// From VS Install PathVC98MFCSRCWINCORE.CPP
BOOL CWnd::SubclassWindow(HWND hWnd)
{
if (!Attach(hWnd))
return FALSE; // allow any other subclassing to occur
PreSubclassWindow(); // now hook into the AFX WndProc
WNDPROC* lplpfn = GetSuperWndProcAddr();
WNDPROC oldWndProc = (WNDPROC)::SetWindowLong(hWnd, GWL_WNDPROC,
(DWORD)AfxGetAfxWndProc());
ASSERT(oldWndProc != (WNDPROC)AfxGetAfxWndProc()); if (*lplpfn == NULL)
*lplpfn = oldWndProc; // the first control of that type created
#ifdef _DEBUG
else if (*lplpfn != oldWndProc)
{ ::SetWindowLong(hWnd, GWL_WNDPROC, (DWORD)oldWndProc);
}
#endif return TRUE;
}
很显然,SubclassWindow()中调用了Attach()函数和reSubclassWindow()函数,由于SubclassWindow()函数是不可重载的,而PreSubclassWindow()函数是可重载的,所以我们经常重载PreSubclassWindow()函数,以致于
窗口被子类化之前进行其它的必要的子类化,看下它原来的声明:
CWnd::PreSubclassWindow
virtual void PreSubclassWindow( );

而SubclassWindow又与SubclassDlgItem有什么区别?前者用于一切具有HWND的窗体,后者只限定于对话框控件

用法:在OnInitDialog中调用SubclassDlgItem将派生类的控件对象与对话框中的基类控件相连接,则这个基类控件对象变成了派生控件对象

总而言之,比较常用的就是DDX_Control。

【C++】DDX_Control、SubclassWindow和SubclassDlgItem的区别的更多相关文章

  1. DDX_Control、SubclassWindow和SubclassDlgItem

    文章参考地址:http://blog.sina.com.cn/s/blog_86fe5b440101au88.html:http://www.cnblogs.com/riskyer/p/3424278 ...

  2. mfc subclasswindow attach setwindowlong使用区别

    1. CWnd::Attach BOOL Attach( HWND hWndNew ); 返回值:如果成功,则返回非零值:否则返回0. 参数: hWndNew 指定了Windows窗口的句柄. 说明: ...

  3. 关于SubclassWindow()和SubclassDlgItem

    msdn上的解析 CWnd::SubclassWindowBOOL SubclassWindow( HWND hWnd ); Return Value Nonzero if the function ...

  4. MFC分类

    屏幕截图(带光标) MFC Button控件自绘 WM_CTLCOLOR消息 MFC窗口创建.销毁消息流程 DDX_Control.SubclassWindow和SubclassDlgItem 隐藏系 ...

  5. 深入理解MFC子类化

    子类化,通俗来讲就是用自己的窗口处理函数来处理特定消息,并将自己其他消息还给标准(默认)窗口处理函数.在SDK中,通过SetWindowLong来指定一个自定义窗口处理函数:SetWindowLong ...

  6. CWnd中PreCreateWindow、PreSubclassWindow、SubclassWindow的区别

    http://blog.csdn.net/swimmer2000/archive/2007/10/30/1856213.aspx MFC(VC6.0)的CWnd及其子类中,有如下三个函数:     / ...

  7. MFC知识点(DDX_Control 与 DDX_Text ,ON_COMMAND和ON_MESSAGE)

    1.DDX_Control 与 DDX_Text 区别 DDX_TEXT()的作用可以理解为把字符串变量和控件的文本(WindowText)关联起来, DDX_Control()的作用可以理解为把变量 ...

  8. CWnd中PreCreateWindow、PreSubclassWindow、SubclassWindow

    原文链接:http://blog.chinaunix.net/uid-14607221-id-2794642.html 1. PreCreateWindow: Called by the framew ...

  9. c#与java的区别

    经常有人问这种问题,用了些时间java之后,发现这俩玩意除了一小部分壳子长的还有能稍微凑合上,基本上没什么相似之处,可以说也就是马甲层面上的相似吧,还是比较短的马甲... 一般C#多用于业务系统的开发 ...

随机推荐

  1. java_js_json_日期格式化

    调用方法: var createBeginTime= createBeginTime.Format("yyyy-MM-dd 00:00:00"); 方法: Date.prototy ...

  2. DataRead 和DataSet区别

    dataset表示一个数据集,是数据在内存中的缓存. 可以包括多个表DatSet 连接数据库时是非面向连接的.把表全部读到Sql中的缓冲池,并断开于数据库的连接 datareader 连接数据库时是面 ...

  3. [题解]vijos 运输计划

    Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球.小 P 掌管一家 ...

  4. js切换不同的div的颜色

    四个div,点击一个变色,其他的不变色,效果如图: 代码如下 : <!DOCTYPE html> <html> <head> <script> wind ...

  5. java中关于正则一些基础使用

    希望能帮到有需要的朋友.-----转载请注明出处. 对于正则处理相关的知识,我一开始是从网上找资料配合使用Java API1.6的一个中文版进行学习,很感谢翻译这个版本的团队(机构)或者个人,很感谢那 ...

  6. 用grunt进行前端工程化之路

    我们的项目wecash4.0的前端构建考虑过用fis和grunt. 目录: 前期调研:fis vs grunt vs gulp? 一.安装grunt和项目. fis是百度fex研发的构建工具,非常方便 ...

  7. Python Decorator分析

    decorator本身是一个函数,这个函数的功能是接受被修饰的函数(decorated)作为参数,返回包装函数(wrapper)替换被修饰函数(decorated). @decorator func ...

  8. flask-admin章节二:wtforms的使用以及在数据库场景中使用QuerySelectField代替SelectField

    概述 flask admin可以支持自定义视图,对于涉及到比较复杂的视图可以选择继承flask_admin.BaseView来定义自己期待的结构. 自定义的视图的每个函数可以使用flask_admin ...

  9. [转]CentOS-6.3安装配置cmake

    CentOS-6.3安装配置cmake   zhoulf 2013-02-03 原创 安装说明 安装环境:CentOS-6.3安装方式:源码编译安装 软件:cmake-2.8.10.2.tar.gz下 ...

  10. LINUX 如何开放端口和关闭端口/jps/sudo命令

    1 在java的根目录下用java的jps查看:============================================================================ ...