刚才给人回复一个问题,引出一连串的问题,然后一边学一边解决了问题。
感觉有必要把这些我理解的东西单独发一发,因为这些很多朋友都跟我一样学的不够深入的人,碰到的一些疑问。
感觉可以加精吧,能加精就赚点分数用用。嘿嘿
如果有错误,请大家指正~欢迎大家讨论~先解释Windows窗口和MFC窗口的区别,这个应该是很多刚学的人不理解的部分。
1.区分窗口句柄和CWnd类对象。
  窗口句柄是Windows里的概念,因为是用C写的,所以Windows里面的窗口都是用C的struct写的(不是
Cpp的 Struct
)。仅仅是一些窗口属性的描述而已。那怎么标识这个窗口呢?通过指针可以标识,但是MS
把指针封装了一下成了句柄,隐藏了实现细节。
  而MFC里面的CWnd概念呢,是C++的类,一个CWnd的对象就对应了一个窗口,CWnd里面封装了一个成员叫
m_hWnd,这个就是他对应的窗口句柄,这个变量相当于一系列描述窗口属性成员变量,此外还封装了一些
针对这个窗口句柄的一些操作。
  Windows SDK通过操作API函数来控制HWND,但是这些操作都是全局函数,没有CPP一样把这些操作封装
到类里面。而MFC 就是把这些API的操作封装到了CWnd类里面。然后看两篇文章,理解一下子类化控件的意思
http://baike.baidu.com/view/3000324.htm?fr=ala0_1
http://blog.csdn.net/livingpark/archive/2009/09/14/4551640.aspx
第二篇文章里面有一句
在VC 中,DoDataExchange函数中的DDX_Control之类的函数会调用SubClassDlgItem完成窗口子类化,这样控件自己就能处理消息了。 
好了,在你的DoDateExchange()里面的DDX_Control()打上断点,跟进去看看代码
我跟进源码里面去看了,DDX_Control不是直接调用的SubClassDlgItem这个函数,但是里面执行的操作跟这个函数是一致的。DDX_Control()里面先声明了一个窗口句柄HWND hWndCtrl,这个句柄是还没初始化的。
然后调用pDX->m_pDlgWnd->GetDlgItem(nIDC, &hWndCtrl);
再跟进去看,你会发现这个函数实际上是做的下面的操作:
取出这个控件窗口的句柄,存入hWndCtrl;  //注意这个窗口的Windows struct(也就是Windows窗口句柄)已经存在了,但是还没有和一个CWnd的对象关联然后DDX_Control()里面下一句
if ((hWndCtrl != NULL) && !rControl.SubclassWindow(hWndCtrl));
其中rControl.SubclassWindow(hWndCtrl)是子类化这个窗口,也就是把hWndCtrl这个窗口句柄和rControl这个CWnd类进行关联,里面用到CWnd.Attach();
也就是相当于CWnd.m_hWnd=hWndCtrl;所以,在DDX_CONTROL里面就是把控件窗口句柄和你设置的控件类对象绑定起来
DDX_Text类似,但是又用的另外一个函数
CDataExchange::PrepareEditCtrl(int nIDC)和CDataExchange::PrepareCtrl(int nIDC)
如果上面的操作理解了,再理解这个也就不难了。再来说明另外一点。如果不用DDX,怎么实现控件对象和控件窗口绑定呢?下面照搬别人的了
综上所述,要在程序中使用派生控件,应该按下面步骤进行: 
1、在对话框模板中放置好基类控件. 
2、在对话框类中嵌入派生控件类的对象. 
3、在 OnInitDialog中调用SubclassDlgItem将派生类的控件对象与对话框中的基类控件相连接,则这个基类控件变成了派生控件. 还有一点,这个控件子类化做的操作并不只是关联窗口这么简单
他主要还是做的替换窗口处理过程的操作。你自己派生的控件类实现了新的消息映射的话,这个操作会帮你把原来的处理过程替换成新的。

解决方案 »

  1.   

    - -##
    写了俩小时呢。。
    不过这是给刚入门的朋友看的。。高手就帮忙指正一下吧。。其实关键在第一段,区分窗口句柄和CWnd类对象。对后面部分不感兴趣的可以忽略了。。长度长点容易加精
      

  2.   

    CWnd类和窗口句柄HWND,CWnd类中有个数据成员m_hWnd,与窗口相关联,CWnd窗口类对象的生命周期和窗口的生命周期并不一样,窗口Destroy了,m_hWnd为NULL了,但是CWnd类并不一定也被销毁了。CWnd类销毁了,与之相关联的窗口应该也是被销毁了,因为两者之间的纽带(m_hWnd)已经断开了,同时回收相关的资源。即CWnd类对象销毁析构时候,也会回收相关的窗口资源,销毁与之相关联的窗口。
      

  3.   

    一个MFC窗口对象是一个C++ CWnd类(或派生类)的实例,是程序直接创建的。在程序执行中它随着窗口类构造函数的调用而生成,随着析构函数的调用而消失。而Windows窗口则是Windows系统的一个内部数据结构的实例,由一个“窗口句柄”标识,Windows系统创建它并给它分配系统资源。Windows窗口在MFC窗口对象创建之后,由CWnd类的Create成员函数创建,“窗口句柄”保存在窗口对象的m_hWnd成员变量中。Windows窗口可以被一个程序销毁,也可以被用户的动作销毁
      

  4.   

    不知楼主能否讲解一下,如何介入API也就是windows窗口中的控件的消息处理
    如果是MFC窗口的话,我可以派生新控件类来处理各种消息,
    问题是Windows窗口的话怎么做呢?
      

  5.   


    我对SDK的理解也不深,我只看了SDK的前几章~能让我看懂MFC程序了之后我就没继续深入了。。
    不过我找了下资料,好像有篇文章符合你的要求
    http://7880.com/info/Article-584ad820.html     SDK的处理方法
    从这里面看来,MFC和SDK的控件处理过程是差不多的。SDK是通过SetWindowLong()来替换了控件窗口的处理过程,MFC中的子类化也是这样做的。下面的文章里面有写MFC的处理方法
    http://www.cnblogs.com/SummerHeart/archive/2008/05/15/1197462.html   
    具体的还是等待高手回答吧。。抛砖引玉了~