在自绘窗口的时候,子类化是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. 使用SVN时出现的文件缺失问题

    使用SVN的童鞋们,可能有三种提交代码的方法: 第一种使用客户端(例如SVNX,CornerStone): 第二种使用Xcode提交(Source Control -> commit): 第三种 ...

  2. jQuery与Ajax的应用——《锋利的jQuery》(第2版)读书笔记3

    第6章 jQuery与Ajax的应用 jQuery对Ajax操作进行了封装,在jQuery中$.ajax()方法属于最底层的方法,第2层是load().$.get()和$.post()方法,第3层是$ ...

  3. winAPI 检查系统设备拔插使用 WM_DEVICECHANGE 消息

    if(message->message == WM_DEVICECHANGE) { /*if (message->wParam == DBT_DEVICEARRIVAL || messag ...

  4. centos 常见软件安装

    centos虚拟机扩展硬盘空间 http://www.cnblogs.com/sixiweb/p/3360008.html http://blog.csdn.net/remote_roamer/art ...

  5. python学习之——selenium元素定位

    web自动化测试按步骤拆分,可以分为四步操作:定位元素,操作元素,获取返回结果,断言(返回结果与期望结果是否一致),最后自动出测试报告. 其中定位元素尤为关键,此篇是使用webdriver通过页面各个 ...

  6. poj -- 1042 Gone Fishing(枚举+贪心)

    题意: John现有h个小时的空闲时间,他打算去钓鱼.钓鱼的地方共有n个湖,所有的湖沿着一条单向路顺序排列(John每在一个湖钓完鱼后,他只能走到下一个湖继续钓),John必须从1号湖开始钓起,但是他 ...

  7. 选择流程—— switch if else结构

    一.switch switch(表达式){ case 常量1: 语句; break; case 常量2: 语句; break; … default; 语句; } 例题:运用switch结构实现购物管理 ...

  8. Javascript.ReactNative-2-javascript-syntax-in-react-native

    JavaScript Syntax in React Native Contents: Arrow Function Let+Const Default + Rest + Spread Destruc ...

  9. Oracle查询某段日期内某个时间段的数据

    示例: 查询最近一周12:30分到13:00这段时间内的订单量: SELECT * FROM T_ORDER O WHERE O.CREATEDATETIME BETWEEN SYSDATE AND ...

  10. Modern C++ CHAPTER 2(读书笔记)

    CHAPTER 2 Recipe 2-1. Initializing Variables Recipe 2-2. Initializing Objects with Initializer Lists ...