如果一个按钮控件关联了一个CButton类变量,就很容易理解,因为源文件中有一个类似CButton m_myButton这样的声明,生成了一个CButton类对象,可以通过m_myButton对象对按钮进行操作.但是如果一个按钮控件没有关联任何变量,它的行为就有点费解了,与这个控件有关只是.rc文件中的添加控件的一个宏PUSHBUTTON,其他就找不到了.但是运行的时候,它可以向父窗口发送通知消息(当然父窗口处不处理这个消息则是另一回事).
1.这个没有关联任何变量的按钮控件有没有一个相应的CButton对象与之对应?如果有,这部分代码在什么地方?
2.如果没有这样的对象,为什么它可以向父窗口发送通知消息(BN_CLICKED和BN_DOUBLECLICKED)?
3.关联变量与不关联变量,有什么不同?
大家有没有明白我想表达的意思?

解决方案 »

  1.   

    1.Windows 的标准控件,都有默认的“窗口处理函数”,这种控件在Dialog上是通过资源进行描述的,在根据对话框资源创建的过程当中,也同样注册了窗口类(这个窗口类里面 就包含默认的处理函数),本质上他和一个自己创建的窗口没有任何区别,你也可以自己创建一个Button.
    2.MFC在创建资源对话框的过程当中最开始都是使用默认的控件处理函数,在Dx.... (函数记不清了,就是哪个添加控件与Cbutton关联的哪个函数)里面MFC做了一些手脚 他通过SubclassWnd(好象是这个 也记不清了),将原来的默认处理函数替换了
    3.关联不关本质没有任何区别
      

  2.   

    看样子,楼主想知道原理性的知识,那就需要看看这本书:『Windows程序设计』下载地址:http://blog.csdn.net/zaodt/archive/2007/11/25/1901332.aspx
      

  3.   

    同意hwsts2楼主怕是没用过SDK直接做开发吧?如果用SDK开发,会发现所有的控件都没有绑定对象.但所有行为依然正常.
    以下为个人愚见:
    问题1:没有CButton对应与之对应.
    问题2:Button向父窗口发消息的机制不依赖于MFC,这是Windows图形系统内定的行为(Button属于Common Control,并不是在MFC里实现的,是一个很基本的DLL里实现的,但微软没开放此DLL的代码).所以这种行为与MFC对象无关,是MFC的下层做的.SDK GUI相关的API也就是在这层基础上实现的.
    问题3:区别在于关联变量后,你可以用这个对象变量来操控这个控件,否则你只能用很原始的SendMessge方式来操控他.其实MFC的对象变量的各个方法就是对各种SendMessage的一个封装,让我调起来更方便.  可以去看一下设定按钮文本的SetWindowText这个方法,它继承自CWnd,你去查看它的实现,就是SendMessage(m_hwnd, WM_SET_TEXT,...).封装了一下,我们调用方便.
    对于绑定值变量的控件,我们可以在UpdateData时候改变对象相关的值,否则也只有用一大堆SendMessage来实现,一样是个封装.除楼上的那本书之外,再推荐本<<深入浅出MFC>>
      

  4.   

    chengchenz 的解释非常深刻,令人受益匪浅.我也一直觉得消息不是控件自己发出的,而是windows发出的.消息发给谁不是由控件决定,而是windows决定.
    现在我有这样的一个理解,不知道对不对.所有的控件,以按钮控件为例,都是一个窗口,每个窗口都有自身的窗口过程.事实上真正创建按钮的不是CButton类,而是一个结构体WNDCLASS.窗口的样式取决于WNDCLASS各成员的值.按钮,单选框,编辑框等等的区别只在于WNDCLASS各成员值的不同.WNDCLASS的一个参数指定了窗口的窗口过程函数地址,当按钮接收到消息时,windows本来应该调用这个窗口过程,但是消息在传递的过程中,mfc做了偷天换日的手脚,用一个统一的过程函数AfxProc把窗口自身的窗口过程函数替换掉了,windows真正调用的是AfxProc,而不再是原来的窗口过程.正是AfxProc的存在,保证了消息按照mfc设计的路径传递.CButton对象的存在与按钮控件的存在无关,CButton只是封装了对控件操作的方法.如果真的是这样的话,就可以很好理解为什么用SDK编程时没有用到CButton类,但仍然可以创建按钮了.
    我的理解不知道对不对,请指正.
      

  5.   

    照楼主这样说,除了MFC之外,其它的开发工具都是不能用按钮的了,因为CButton是MFC的类,其它工具没有这个类,所以就不能用按钮了,哈哈.其实CButton是对标准控件的一种封装,主窗口与按钮之间的通信是通过WM_COMMAND消息来完成的.
      

  6.   

    wltg2001所说与我的意思刚好相反.
    再进来几个人我就结帖.在这里学到不少东西.
      

  7.   

    你所问的三个问题很不好回答,因为有些基本的东西你没有了解,按钮是Windows的标准控件,它并不是借助CButton类来和主窗口通信的,它和主窗口通信是通过发送WM_COMMAND消息,你上面所说的BN_CLICKED和BN_DOUBLECLICKED并不是真正的windows消息,它们仅仅是WM_COMMAND消息的通知码.对于任何一个控件,都是一个窗口,它都有自已的窗口类(不是C++中的类),都有自己的窗口处理程序,按钮也有它自己的窗口处理程序,不过这个程序是系统内置的,当点击按钮时,它向父窗口发送WM_COMMAND消息,消息的wParam中含有通知码也就是上面的BN_CLICKED和按扭ID,lParam中含有按钮的窗口句柄,父窗口通过处理WM_COMMAND消息来响应它.
    上面所说的是SDK中的情况,MFC用CButton类对上述行为作了封装,但是它还是借用WM_COMMAND来和父窗口通信的.至于加不加关联变量,其实这是MFC的一种处理技巧,老实说,是一种很复杂也很精巧的技巧,它内部用类似DDX_Control(pDX, IDC_BUTTON1, m_ddd)这样的宏将按钮和成员变量关联在一起了.