转载:MFC初窥(MFC运行机制,孙鑫C++第三讲笔记整理)

转载地址:https://blog.csdn.net/u012377333/article/details/40789893
孙鑫视频02是介绍C++,这部分不说了,03是介绍MFC,真是深入浅出,所以第一章要好好理解,第三章可以一步步查找创建窗口的4个过程。

转载内容: —–

有了一定的Windows32编程知识,就能学习MFC了。

在学习MFC之前,一定要弄明白Windows32编程中的消息循环是怎么回事。MFC实际上就是对Windows API函数的封装。

 

在Windows程序设计编程中,创建一个窗口要经历下面四个过程 (如有不懂,请看博客 win32初窥)

1设计一个窗口类;
2注册窗口类;
3创建窗口;
4显示及更新窗口。
 
同样,MFC中也是一样的。只是封装了而已,很多人认为MFC很难学,看着书本能编程序,但是却编写不了自己的程序,为什么呢?因为还没有理解MFC的原理的机制。
市场上有很多有关VC++的书本,但是很少有将MFC原理讲得比较透彻的,引用孙鑫老师的话。
同样的,WinMain也是入口函数,具体的过程,请看孙鑫视频20讲之第三讲
 
其中,孙鑫老师开始提出的一个问题是:
在全局变量中,定义一个子类对象。。。
[html]  view plain copy


  1. #include<iostream>  

  2. #include<string>  

  3. using namespace std;  

  4.   

  5. class Person  

  6. {  

  7. public:  

  8.     Person *p;  

  9.     Person()  

  10.     {  

  11.         p=this;//保存this指针  

  12.     }  

  13.     virtual void say()  

  14.     {  

  15.         cout<<“Person’s say()”<<endl;  

  16.     }  

  17.   

  18. };  

  19.   

  20. class Student:public Person  

  21. {  

  22. public:  

  23.       

  24.     Student()  

  25.     {  

  26.   

  27.     }  

  28.     void say()  

  29.     {  

  30.         cout<<“Student’s say()”<<endl;  

  31.     }  

  32.   

  33. };  

  34.   

  35. Student s;  

  36.   

  37. int main()  

  38. {  

  39.       

  40.     s.p->say();//这里将调用子类的方法  

  41.     return 0;  

  42. }  

 
什么都不用做,直接用向导生成一个MFC窗口。
下面是结构图,有五个类
是这样命名的,开头的C表示Class ,C+工程名+(App,Doc,View…)

其中CMainFrame表示一个窗口(主窗体,包括标题栏,菜单…),XXApp表示运用程序,XXDOC表示文档类(加载数据,实现数据的存储与操作分离),XXView也表示一个窗口(相当于Windows的客户区)

 

下面看看MFC中类的主要继承关系:

由于继承树太大,这里只罗列了CWnd的继承关系

 

 

API中CreateWindowEx和CreateWindow几乎是一样的,Ex表示扩展,多了一个参数

下面用API模拟CWnd

just模拟

[html]  view plain copy


  1. //下面是模仿封装API函数  

  2.   

  3. class CWnd  

  4. {  

  5. public:  

  6.     BOOL CreateEX(  

  7.         DWORD dwExStyle,      // extended window style  

  8.         LPCTSTR lpClassName,  // registered class name  

  9.         LPCTSTR lpWindowName, // window name  

  10.         DWORD dwStyle,        // window style  

  11.         int x,                // horizontal position of window  

  12.         int y,                // vertical position of window  

  13.         int nWidth,           // window width  

  14.         int nHeight,          // window height  

  15.         HWND hWndParent,      // handle to parent or owner window  

  16.         HMENU hMenu,          // menu handle or child identifier  

  17.         HINSTANCE hInstance,  // handle to application instance  

  18.         LPVOID lpParam        // window-creation data  

  19.         );  

  20.   

  21.     BOOL ShowWindow(int nCmdShow);  

  22.   

  23.     BOOL UpdateWindow();  

  24.   

  25. public:  

  26.     HWND m_hWnd;  

  27. };  

  28.   

  29. BOOL CWnd::CreateEx(  

  30.                DWORD dwExStyle,      // extended window style  

  31.                LPCTSTR lpClassName,  // registered class name  

  32.                LPCTSTR lpWindowName, // window name  

  33.                DWORD dwStyle,        // window style  

  34.                int x,                // horizontal position of window  

  35.                int y,                // vertical position of window  

  36.                int nWidth,           // window width  

  37.                int nHeight,          // window height  

  38.                HWND hWndParent,      // handle to parent or owner window  

  39.                HMENU hMenu,          // menu handle or child identifier  

  40.                HINSTANCE hInstance,  // handle to application instance  

  41.                LPVOID lpParam        // window-creation data  

  42.             );  

  43. {  

  44.     m_hWnd=::CreateWindowEx(dwExstyle,lClassName,lpWindowName,dwStyle,x,y,nWidth,nHeight,hWndParent,  

  45.                             hMenu,hInstance,lParam);  

  46.   

  47.     if(m_hWnd!=NULL)  

  48.   

  49.         return TRUE;  

  50.     else  

  51.         return FALSE;  

  52. }  

  53.   

  54. BOOL CWnd::ShowWindow(int nCmdShow)  

  55. {  

  56.     return ::ShowWindow(m_hWnd,nCmdShow);//调用的是SDK全局函数,加个::说明是全局的  

  57. }  

  58.   

  59. BOOL CWnd::UpdateWindow()  

  60. {  

  61.     return ::UpdateWindow(m_hWnd);  

  62. }  

  63.   

  64. int WINAPI WinMain(    

  65.                    HINSTANCE hInstance,      // handle to current instance     

  66.                    HINSTANCE hPrevInstance,  // handle to previous instance     

  67.                    LPSTR lpCmdLine,          // command line     

  68.                    int nCmdShow              // show state     

  69.                    )    

  70. {    

  71.     WNDCLASS wndclass;    

  72.       

  73.     wndclass.cbClsExtra=0;    

  74.     wndclass.cbWndExtra=0;    

  75.     wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);    

  76.     wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);    

  77.     wndclass.hIcon=LoadIcon(NULL,IDI_ERROR);    

  78.     wndclass.hInstance=hInstance;    

  79.    …  

  80.     

  81.     CWnd cwnd;  

  82.    cwnd.CreateEx(dwExstyle,…,…);  

  83.   

  84.     cwnd.ShowWindow(nCmdShow);    

  85.     cwnd.UpdateWindow();    

  86.       

  87.     while(GetMessage(&msg,NULL,0,0))    

  88.     {    

  89.         TranslateMessage(&msg);    

  90.         DispatchMessage(&msg);    

  91.     }    

  92.       

  93.     …  

  94. }    

 

下面是重头戏(引用了某位仁兄的,太详细了)

重点:MFC运行机制
  
  提示:对于不想理解内部运行过程的,可以不看这一章,可以看了后面的界面设计再回头来看这一章,可能感觉更深刻。
  这一次课和上一次的课的重点就是MFC的窗口类创建过程,而要反复说明的就是:MFC的程序和C语言的程序,从执行原理上说,是完全一致的。
  抓住这一点,那么对于理解MFC程序的运行机制也就相对于简单了。
  C中的main函数就相当于MFC中的WinMain函数。
  感兴趣的可以利用VC的断点设置自己跟踪下面讲述的各个函数,就明白它的执行顺序了。
  
  一、C语言程序执行步骤
  在C语言中,大约的步骤如下:
  1, 全局变量内存分配
  2, 进入main函数
  
  二、MFC程序的运行步骤(主要是初始化)
  
  打开一个MFC APPWizard(exe)工程,跟踪其执行步骤,可以发现,是以下顺序:
  1) CXXApp中的全局变量定义
  CXXApp theApp;
  2) 调用CXXApp构造函数
  CXXApp ::CXXApp(){}
  3) 进入Winmain函数(_tWinMain为宏,值为WinMain)
  _tWinMain(){}
  
  4) 完成初始化工作:包括窗口类注册、窗口产生、显示和更新
  pThread->InitInstance()
  
  对于MFC程序,MainFrame,View,ToolBar,Controlbar等都是窗口,所以下面的窗口注册与创建、显示等要反复调用多次,一次对应一个窗口
  
  (1) 注册窗口类
  
  AfxEndDeferRegisterClass
  
  (2) 创建窗口
  
  CMainFrame::PreCreateWindow()//反复调用一次是给我们修改窗口属性的机会
  
  CFrameWnd::Create()
  
  (3) 消息循环
  
  PumpMessage()
  
  补充1:
  
  在MFC中,由于涉及到(窗口)类定义,所以定义全局变量的时候,需要进行更多的步骤。
  
  全局变量涉及到类定义(类似于C中的类型定义)的话,那么需要遵循以下步骤(以MFC的窗口类为例)
  
  1) 设计一个窗口类
  
  2) 注册窗口类
  
  3) 创建窗口
  
  4) 显示及更新窗口
  
  5) 消息循环
  
   
  
  补充2:其他需要注意的几点
  
  1, 每一个MFC程序,有且只有一个从WinApp类派生的类(应用程序类),也只有一个从应用程序类所事例化的对象,表示应用程序本身。在WIN32程序当中,表示应用程序是通过WINMAIN入口函数来表示的(通过一个应用程序的一个事例号这一个标识来表示的)。在基于MFC应用程序中,是通过产生一个应用程序对象,用它来唯一的表示了应用程序。
  
  2, _tWinMain函数中通过调用AfxWinMain()函数来完成它要完成的功能。(Afx*前缀代表这是应用程序框架函数,是一些全局函数,应用程序框架是一套辅助生成应用程序的框架模型,把一些类做一些有机的集成,我们可根据这些类函数来设计自己的应用程序)。
  
  3, 设计窗口类:在MFC中事先设计好了几种缺省的窗口类,根据不同的应用程序的选择,调用AfxEndDeferRegisterClass()函数注册所选择的窗口类。
  
  4, PreCreateWindow()是个虚函数,如果子类有则调用子类的。
  
  5, CreateWindowEx()函数参数与CREATESTRUCT结构体成员完全一致,CreateWindowEx()函数与CREATESTRUCT结构体参数的对应关系,使我们在创建窗口之前通过可PreCreateWindow(cs)修改cs结构体成员来修改所要的窗口外观。
  
  6,注意两个函数。
  
  ::TranslateMessage(&m_msgCur)函数进行消息(如键盘消息)转换
  
  ::DispatchMessage(&m_msgCur)函数分派消息到窗口的回调函数处理(实际上分派的消息经过消息映射,交由消息响应函数进行处理。)
  
  7,可以认为View类窗口是CMainFram类窗口的子窗口。DOCument类是文档类。DOC-VIEW结构将数据本身与它的显示分离开。
  
  文档类用于数据的存储,加载;视类用于数据的显示,修改
  
  8,CTEApp::InitInstance()函数中通过文档模板将文档类,视类,框架类的有机组织一起。语句如下:
  
  CSingleDocTemplate* pDocTemplate;
  pDocTemplate = new CSingleDocTemplate(
   IDR_MAINFRAME,
   RUNTIME_CLASS(CTEDoc),
   RUNTIME_CLASS(CMainFrame), // main SDI frame window
   RUNTIME_CLASS(CTEView));
  AddDocTemplate(pDocTemplate);//增加到模板
  
  补充3:本课涉及到MFC函数的源文件位置
  
  根目录
  
  找到您安装VC98下MFC的位置,比如我的机子上为:D:\Program Files\Microsoft Visual Studio\VC98\MFC。下面提供的就是相对路径了。
  
   
  
  CWinApp构造函数: MFC=>SRC=>APPCORE.CPP
  AfxWinMain:MFC=>SRC=>WINMAIN.CPP
  AfxEndDeferRegisterClass: MFC=>SRC=>APPCORE.CPP
  CFrameWnd::PreCreateWindow()函数所在文件:MFC=>SRC=>WINFRM.CPP
  CFrameWnd::Create()函数路径:MFC=>SRC=>WINFRM.CPP
  CWnd::CreateEx()函数路径:MFC=>SRC=>WINCORE.CPP
  CWinThread::Run()方法路径:MFC=>SRC=>THRDCORE.CPP

 创建按钮

1在CMainFrame创建

双击CMainFrame,添加数据成员,CButton m_btn

在OnCreate方法添加如下代码:

[html]  view plain copy


  1. m_btn.Create(TEXT(“first Button”),BS_PUSHBUTTON|WS_CHILD,CRect(0,0,100,100),this,123);  

  2. m_btn.ShowWindow(SW_NORMAL);  

 

2在CXXView创建

双击CXXView,添加数据成员,CButton m_btn

在CXXView右键Add windows Message Handler 添加WM_CREATE消息处理,然后生成OnCreate函数

在OnCreate函数添加如下代码

[html]  view plain copy


  1. m_btn.Create(TEXT(“Button2”),BS_PUSHBUTTON|WS_CHILD|WS_VISIBLE,CRect(0,0,100,100),this,123);  


两个代码效果是等价的:

        </div>
            </div>
        </article>

有了一定的Windows32编程知识,就能学习MFC了。

在学习MFC之前,一定要弄明白Windows32编程中的消息循环是怎么回事。MFC实际上就是对Windows API函数的封装。

 

在Windows程序设计编程中,创建一个窗口要经历下面四个过程 (如有不懂,请看博客 win32初窥)

1设计一个窗口类;
2注册窗口类;
3创建窗口;
4显示及更新窗口。
 
同样,MFC中也是一样的。只是封装了而已,很多人认为MFC很难学,看着书本能编程序,但是却编写不了自己的程序,为什么呢?因为还没有理解MFC的原理的机制。
市场上有很多有关VC++的书本,但是很少有将MFC原理讲得比较透彻的,引用孙鑫老师的话。
同样的,WinMain也是入口函数,具体的过程,请看孙鑫视频20讲之第三讲
 
其中,孙鑫老师开始提出的一个问题是:
在全局变量中,定义一个子类对象。。。
[html]  view plain copy


  1. #include<iostream>  

  2. #include<string>  

  3. using namespace std;  

  4.   

  5. class Person  

  6. {  

  7. public:  

  8.     Person *p;  

  9.     Person()  

  10.     {  

  11.         p=this;//保存this指针  

  12.     }  

  13.     virtual void say()  

  14.     {  

  15.         cout<<“Person’s say()”<<endl;  

  16.     }  

  17.   

  18. };  

  19.   

  20. class Student:public Person  

  21. {  

  22. public:  

  23.       

  24.     Student()  

  25.     {  

  26.   

  27.     }  

  28.     void say()  

  29.     {  

  30.         cout<<“Student’s say()”<<endl;  

  31.     }  

  32.   

  33. };  

  34.   

  35. Student s;  

  36.   

  37. int main()  

  38. {  

  39.       

  40.     s.p->say();//这里将调用子类的方法  

  41.     return 0;  

  42. }  

 
什么都不用做,直接用向导生成一个MFC窗口。
下面是结构图,有五个类
是这样命名的,开头的C表示Class ,C+工程名+(App,Doc,View…)

其中CMainFrame表示一个窗口(主窗体,包括标题栏,菜单…),XXApp表示运用程序,XXDOC表示文档类(加载数据,实现数据的存储与操作分离),XXView也表示一个窗口(相当于Windows的客户区)

 

下面看看MFC中类的主要继承关系:

由于继承树太大,这里只罗列了CWnd的继承关系

 

 

API中CreateWindowEx和CreateWindow几乎是一样的,Ex表示扩展,多了一个参数

下面用API模拟CWnd

just模拟

[html]  view plain copy


  1. //下面是模仿封装API函数  

  2.   

  3. class CWnd  

  4. {  

  5. public:  

  6.     BOOL CreateEX(  

  7.         DWORD dwExStyle,      // extended window style  

  8.         LPCTSTR lpClassName,  // registered class name  

  9.         LPCTSTR lpWindowName, // window name  

  10.         DWORD dwStyle,        // window style  

  11.         int x,                // horizontal position of window  

  12.         int y,                // vertical position of window  

  13.         int nWidth,           // window width  

  14.         int nHeight,          // window height  

  15.         HWND hWndParent,      // handle to parent or owner window  

  16.         HMENU hMenu,          // menu handle or child identifier  

  17.         HINSTANCE hInstance,  // handle to application instance  

  18.         LPVOID lpParam        // window-creation data  

  19.         );  

  20.   

  21.     BOOL ShowWindow(int nCmdShow);  

  22.   

  23.     BOOL UpdateWindow();  

  24.   

  25. public:  

  26.     HWND m_hWnd;  

  27. };  

  28.   

  29. BOOL CWnd::CreateEx(  

  30.                DWORD dwExStyle,      // extended window style  

  31.                LPCTSTR lpClassName,  // registered class name  

  32.                LPCTSTR lpWindowName, // window name  

  33.                DWORD dwStyle,        // window style  

  34.                int x,                // horizontal position of window  

  35.                int y,                // vertical position of window  

  36.                int nWidth,           // window width  

  37.                int nHeight,          // window height  

  38.                HWND hWndParent,      // handle to parent or owner window  

  39.                HMENU hMenu,          // menu handle or child identifier  

  40.                HINSTANCE hInstance,  // handle to application instance  

  41.                LPVOID lpParam        // window-creation data  

  42.             );  

  43. {  

  44.     m_hWnd=::CreateWindowEx(dwExstyle,lClassName,lpWindowName,dwStyle,x,y,nWidth,nHeight,hWndParent,  

  45.                             hMenu,hInstance,lParam);  

  46.   

  47.     if(m_hWnd!=NULL)  

  48.   

  49.         return TRUE;  

  50.     else  

  51.         return FALSE;  

  52. }  

  53.   

  54. BOOL CWnd::ShowWindow(int nCmdShow)  

  55. {  

  56.     return ::ShowWindow(m_hWnd,nCmdShow);//调用的是SDK全局函数,加个::说明是全局的  

  57. }  

  58.   

  59. BOOL CWnd::UpdateWindow()  

  60. {  

  61.     return ::UpdateWindow(m_hWnd);  

  62. }  

  63.   

  64. int WINAPI WinMain(    

  65.                    HINSTANCE hInstance,      // handle to current instance     

  66.                    HINSTANCE hPrevInstance,  // handle to previous instance     

  67.                    LPSTR lpCmdLine,          // command line     

  68.                    int nCmdShow              // show state     

  69.                    )    

  70. {    

  71.     WNDCLASS wndclass;    

  72.       

  73.     wndclass.cbClsExtra=0;    

  74.     wndclass.cbWndExtra=0;    

  75.     wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);    

  76.     wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);    

  77.     wndclass.hIcon=LoadIcon(NULL,IDI_ERROR);    

  78.     wndclass.hInstance=hInstance;    

  79.    …  

  80.     

  81.     CWnd cwnd;  

  82.    cwnd.CreateEx(dwExstyle,…,…);  

  83.   

  84.     cwnd.ShowWindow(nCmdShow);    

  85.     cwnd.UpdateWindow();    

  86.       

  87.     while(GetMessage(&msg,NULL,0,0))    

  88.     {    

  89.         TranslateMessage(&msg);    

  90.         DispatchMessage(&msg);    

  91.     }    

  92.       

  93.     …  

  94. }    

 

下面是重头戏(引用了某位仁兄的,太详细了)

重点:MFC运行机制
  
  提示:对于不想理解内部运行过程的,可以不看这一章,可以看了后面的界面设计再回头来看这一章,可能感觉更深刻。
  这一次课和上一次的课的重点就是MFC的窗口类创建过程,而要反复说明的就是:MFC的程序和C语言的程序,从执行原理上说,是完全一致的。
  抓住这一点,那么对于理解MFC程序的运行机制也就相对于简单了。
  C中的main函数就相当于MFC中的WinMain函数。
  感兴趣的可以利用VC的断点设置自己跟踪下面讲述的各个函数,就明白它的执行顺序了。
  
  一、C语言程序执行步骤
  在C语言中,大约的步骤如下:
  1, 全局变量内存分配
  2, 进入main函数
  
  二、MFC程序的运行步骤(主要是初始化)
  
  打开一个MFC APPWizard(exe)工程,跟踪其执行步骤,可以发现,是以下顺序:
  1) CXXApp中的全局变量定义
  CXXApp theApp;
  2) 调用CXXApp构造函数
  CXXApp ::CXXApp(){}
  3) 进入Winmain函数(_tWinMain为宏,值为WinMain)
  _tWinMain(){}
  
  4) 完成初始化工作:包括窗口类注册、窗口产生、显示和更新
  pThread->InitInstance()
  
  对于MFC程序,MainFrame,View,ToolBar,Controlbar等都是窗口,所以下面的窗口注册与创建、显示等要反复调用多次,一次对应一个窗口
  
  (1) 注册窗口类
  
  AfxEndDeferRegisterClass
  
  (2) 创建窗口
  
  CMainFrame::PreCreateWindow()//反复调用一次是给我们修改窗口属性的机会
  
  CFrameWnd::Create()
  
  (3) 消息循环
  
  PumpMessage()
  
  补充1:
  
  在MFC中,由于涉及到(窗口)类定义,所以定义全局变量的时候,需要进行更多的步骤。
  
  全局变量涉及到类定义(类似于C中的类型定义)的话,那么需要遵循以下步骤(以MFC的窗口类为例)
  
  1) 设计一个窗口类
  
  2) 注册窗口类
  
  3) 创建窗口
  
  4) 显示及更新窗口
  
  5) 消息循环
  
   
  
  补充2:其他需要注意的几点
  
  1, 每一个MFC程序,有且只有一个从WinApp类派生的类(应用程序类),也只有一个从应用程序类所事例化的对象,表示应用程序本身。在WIN32程序当中,表示应用程序是通过WINMAIN入口函数来表示的(通过一个应用程序的一个事例号这一个标识来表示的)。在基于MFC应用程序中,是通过产生一个应用程序对象,用它来唯一的表示了应用程序。
  
  2, _tWinMain函数中通过调用AfxWinMain()函数来完成它要完成的功能。(Afx*前缀代表这是应用程序框架函数,是一些全局函数,应用程序框架是一套辅助生成应用程序的框架模型,把一些类做一些有机的集成,我们可根据这些类函数来设计自己的应用程序)。
  
  3, 设计窗口类:在MFC中事先设计好了几种缺省的窗口类,根据不同的应用程序的选择,调用AfxEndDeferRegisterClass()函数注册所选择的窗口类。
  
  4, PreCreateWindow()是个虚函数,如果子类有则调用子类的。
  
  5, CreateWindowEx()函数参数与CREATESTRUCT结构体成员完全一致,CreateWindowEx()函数与CREATESTRUCT结构体参数的对应关系,使我们在创建窗口之前通过可PreCreateWindow(cs)修改cs结构体成员来修改所要的窗口外观。
  
  6,注意两个函数。
  
  ::TranslateMessage(&m_msgCur)函数进行消息(如键盘消息)转换
  
  ::DispatchMessage(&m_msgCur)函数分派消息到窗口的回调函数处理(实际上分派的消息经过消息映射,交由消息响应函数进行处理。)
  
  7,可以认为View类窗口是CMainFram类窗口的子窗口。DOCument类是文档类。DOC-VIEW结构将数据本身与它的显示分离开。
  
  文档类用于数据的存储,加载;视类用于数据的显示,修改
  
  8,CTEApp::InitInstance()函数中通过文档模板将文档类,视类,框架类的有机组织一起。语句如下:
  
  CSingleDocTemplate* pDocTemplate;
  pDocTemplate = new CSingleDocTemplate(
   IDR_MAINFRAME,
   RUNTIME_CLASS(CTEDoc),
   RUNTIME_CLASS(CMainFrame), // main SDI frame window
   RUNTIME_CLASS(CTEView));
  AddDocTemplate(pDocTemplate);//增加到模板
  
  补充3:本课涉及到MFC函数的源文件位置
  
  根目录
  
  找到您安装VC98下MFC的位置,比如我的机子上为:D:\Program Files\Microsoft Visual Studio\VC98\MFC。下面提供的就是相对路径了。
  
   
  
  CWinApp构造函数: MFC=>SRC=>APPCORE.CPP
  AfxWinMain:MFC=>SRC=>WINMAIN.CPP
  AfxEndDeferRegisterClass: MFC=>SRC=>APPCORE.CPP
  CFrameWnd::PreCreateWindow()函数所在文件:MFC=>SRC=>WINFRM.CPP
  CFrameWnd::Create()函数路径:MFC=>SRC=>WINFRM.CPP
  CWnd::CreateEx()函数路径:MFC=>SRC=>WINCORE.CPP
  CWinThread::Run()方法路径:MFC=>SRC=>THRDCORE.CPP

 创建按钮

1在CMainFrame创建

双击CMainFrame,添加数据成员,CButton m_btn

在OnCreate方法添加如下代码:

[html]  view plain copy


  1. m_btn.Create(TEXT(“first Button”),BS_PUSHBUTTON|WS_CHILD,CRect(0,0,100,100),this,123);  

  2. m_btn.ShowWindow(SW_NORMAL);  

 

2在CXXView创建

双击CXXView,添加数据成员,CButton m_btn

在CXXView右键Add windows Message Handler 添加WM_CREATE消息处理,然后生成OnCreate函数

在OnCreate函数添加如下代码

[html]  view plain copy


  1. m_btn.Create(TEXT(“Button2”),BS_PUSHBUTTON|WS_CHILD|WS_VISIBLE,CRect(0,0,100,100),this,123);  


两个代码效果是等价的:

        </div>
            </div>
        </article>

猜你喜欢

转载自blog.csdn.net/songsong2017/article/details/81747951