zoukankan      html  css  js  c++  java
  • MFC学习笔记——07-MFC_18day

    在学习MFC总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。

    07-MFC_18day

    目录:
    一、课程安排
    二、编程总结
    三、Win消息机制、SDK编程基础
    1、Windows 编程模型
    2、底层实现窗口的6步骤
    3、利用MFC创建窗口
    4、MFC消息映射机制
    5、Windows字符集介绍
    6、利用向导创建MFC
    四、总结

    一、课程安排

    第一天(Win消息机制、SDK编程基础):
        1、基本概念介绍(SDK、API、句柄、消息队列、WinMain函数)
        2、第一个Windows界面程序(WinAPI)
        3、消息循环和窗口过程函数
        4、第一个MFC程序(CWinApp、CFrameWnd)
        5、消息映射
        6、unicode字符集介绍
        7、根据向导创建MFC应用程序
        8、MFC应用程序几个重要函数的介绍
        9、事件的添加和删除
        
    第二天(对话框、常用控件、文档和视图):
        1、对话框(模态和非模态)
        2、常用控件的使用
            a)按钮CButton
            b)编辑框CEdit
            c)组合框(下拉框)CComboBox
            d)列表视图控件 CListCtrl
            e)树视图控件 CTreeCtrl
            f)标签控件 CTabCtrl
        
    第三天(综合案例:销售信息管理系统)
        
       

    二、编程总结

    编程环境:VS2015

    1、代码自动对齐:Ctrl + a—》Ctrl + k—》Ctrl + f;


    visual assist x是一款非常好用的Microsoft Visual Studio插件,它可以完全集成到您的Microsoft开发环境中,升级了您的IDE,在不改变编程习惯的同时就可以感受到Visual Assist X为您带来的好处。软件支持Microsoft Visual Studio 2003-2017,C/C++,C#,ASP,VisualBasic,Java和HTML等语言,能自动识别各种关键字、系统函数、成员变量、自动给出输入提示、自动更正大小写错误、自动标示错误等。使用Visual Assist X能够非常有助于提高用户开发过程的自动化和开发效率。

    visual assist x破解版:网盘链接:https://pan.baidu.com/s/1FtpBsVgAjbRmgPhABY47xQ 密码:3qov

    破解教程:
    软件下载解压完成后,点击VA_X_Setup2223打开软件安装包,软件会自动识别你电脑中的Microsoft Visual Studio版本,点击Install开始安装软件。


    2、VS中报错:error C2143:语法错误:缺少“:”(在“类型”的前面)

    原因:VS C语言编程Issue,在switch的case的条件判断后 执行语句过多,会发生这个问题,所以需要把这些执行语句整体加个{}或编程一个函数整体。

    三、Win消息机制、SDK编程基础


    为什么学习MFC?
    如果你是在Windows平台上做GUI开发,MFC(微软基础类库)是一个很好的选择,毕竟Windows累积用户群庞大,市场接受程度高。


    基本概念解释
    我们在编写标准C程序的时候,经常会调用各种库函数来辅助完成某些功能:初学者使用得最多的C库函数就是printf了,这些库函数是由你所使用的编译器厂商提供的。在Windows平台下,也有类似的函数可供调用:不同的是,这些函数是由Windows操作系统本身提供的。

    1) SDK和API
    SDK: 软件开发工具包(Software Development Kit),一般都是一些被软件工程师用于为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件的开发工具的集合。

    API函数: Windows操作系统提供给应用程序编程的接口(Application Programming Interface)。
    Windows应用程序API函数是通过C语言实现的,所有主要的 Windows 函数都在 Windows.h 头文件中进行了声明。Windows 操作系统提供了 1000 多种 API函数。

    2) 窗口和句柄
    窗口是 Windows 应用程序中一个非常重要的元素,一个 Windows 应用程序至少要有一个窗口,称为主窗口。

    窗口是屏幕上的一块矩形区域,是 Windows 应用程序与用户进行交互的接口。利用窗口可以接收用户的输入、以及显示输出。

    一个应用程序窗口通常都包含标题栏、菜单栏、系统菜单、最小化框、最大化框、 可调边框,有的还有滚动条。

    窗口可以分为客户区和非客户区, 如上图。 客户区是窗口的一部分, 应用程序通常在客户区中显示文字或者绘制图形。

    标题栏、 菜单栏、 系统菜单、 最小化框和最大化框、 可调边框统称为窗口的非客户区, 它们由 Windows 系统来管理, 而应用程序则主要管理客户区的外观及操作。

    窗口可以有一个父窗口, 有父窗口的窗口称为子窗口。除了上图所示类型的窗口外, 对话框和消息框也是一种窗口。 在对话框上通常还包含许多子窗口, 这些子窗口的形式有按钮、 单选按钮、 复选框、 组框、 文本编辑框等。

    在 Windows 应用程序中, 窗口是通过窗口句柄( HWND) 来标识的。 我们要对某个窗口进行操作, 首先就要得到这个窗口的句柄。

    句柄( HANDLE) 是 Windows 程序中一个重要的概念, 使用也非常频繁。 在 Windows 程序中, 有各种各样的资源( 窗口、 图标、光标,画刷等), 系统在创建这些资源时会为它们分配内存, 并返回标识这些资源的标识号, 即句柄。 在后面的内容中我们还会看到图标句柄( HICON)、 光标句柄( HCURSOR) 和画刷句柄( HBRUSH)。

    3) 消息与消息队列
    Windows 程序设计是一种完全不同于传统的 DOS 方式的程序设计方法。它是一种事件驱动方式的程序设计模式,主要是基于消息的。

    每一个 Windows 应用程序开始执行后, 系统都会为该程序创建一个消息队列, 这个消息队列用来存放该程序创建的窗口的消息。

    例如,当用户在窗口中画图的时候,按下鼠标左键,此时,操作系统会感知到这一事件,于是将这个事件包装成一个消息,投递到应用程序的消息队列中,等待应用程序的处理。

    然后应用程序通过一个消息循环不断地从消息队列中取出消息,并进行响应。

    在这个处理过程中,操作系统也会给应用程序“ 发送消息”。所谓“ 发送消息”,实际上是操作系统调用程序中一个专门负责处理消息的函数,这个函数称为窗口过程。

    4) WinMain函数
    当Windows操作系统启动一个程序时,它调用的就是该程序的WinMain函数( 实际是由插入到可执行文件中的启动代码调用的)。 WinMain是Windows程序的入口点函数,与DOS程序的入口点函数main的作用相同,当WinMain 函数结束或返回时,Windows应用程序结束。


    1、Windows 编程模型
    一个完整的Win32程序(#include <windows.h>),该程序实现的功能是创建一个窗口,并在该窗口中响应键盘及鼠标消息,程序的实现步骤为:
    1)WinMain函数的定义
    2)创建一个窗口
    3)进行消息循环
    4)编写窗口过程函数

    2、底层实现窗口的6步骤

      1 #include <windows.h> //底层实现窗口头文件
      2 
      3 // 6、处理消息(窗口过程)
      4 // CALLBACK 代表 __stdcall 参数传递顺序 从右往左 依次入栈 ,并且在函数返回前自动清空 堆栈内容
      5 // WindowProc的名字要和(1、设计窗口)wc.lpfnWndProc = WindowProc的名字相同
      6 LRESULT CALLBACK WindowProc(
      7     HWND hwnd,  //消息所属窗口句柄
      8     UINT uMsg,  // 具体消息名称 WM_XXX
      9     WPARAM wParam,  // 键盘附加消息
     10     LPARAM lParam   //鼠标附加消息
     11     )
     12 {
     13     
     14     switch (uMsg)
     15     {
     16     case WM_CLOSE:
     17         DestroyWindow(hwnd); //触发 WM_DESTROY  约定俗成一个事情: 函数名 xxxWindow消息,不会放到消息队列中,而是直接执行
     18         break;
     19     case WM_DESTROY:
     20         PostQuitMessage(0); //发送退出消息
     21         break;
     22     case WM_LBUTTONDOWN: //鼠标左键按下消息
     23     {
     24         int xPos;
     25         int yPos;
     26         xPos = LOWORD(lParam);
     27         yPos = HIWORD(lParam);
     28 
     29         //打印操作 通常同MessageBox
     30 
     31         TCHAR buf[1024];
     32         wsprintf(buf, TEXT(" x = %d,y = %d"), xPos, yPos);
     33         // 所属窗口  显示内容   标题内容  关联按键类型
     34         MessageBox(hwnd, buf, TEXT("鼠标按下"), MB_OK);
     35     }
     36         break;
     37     case WM_KEYDOWN: //键盘消息
     38 
     39         MessageBox(hwnd, TEXT("键盘按下"), TEXT("键盘消息"), MB_OK);
     40         break;
     41 
     42     case  WM_PAINT: //绘图消息
     43     {
     44         PAINTSTRUCT ps; //绘图结构体
     45         HDC hdc = BeginPaint(hwnd, &ps);
     46         //绘制文字
     47         TextOut(hdc, 100, 100, TEXT("helloworld"), strlen("helloworld"));
     48         EndPaint(hwnd, &ps);
     49     }
     50         break;
     51     default:
     52         break;
     53     }
     54 
     55 
     56     //默认方式处理
     57     return DefWindowProc(hwnd, uMsg, wParam, lParam);
     58 }
     59 
     60 
     61 
     62 // WINAPI 代表 __stdcall 参数传递顺序 从右往左 依次入栈 ,并且在函数返回前自动清空 堆栈内容
     63 // WinMain函数入口
     64 int WINAPI WinMain(
     65     HINSTANCE hInstance, // 应用程序实例句柄
     66     HINSTANCE hPrevInstance,  // 前一个应用程序实例句柄,在win32环境下,基本值NULL,不起作用
     67     LPSTR lpCmdLine,  // char * argv[] 命令行参数数组
     68     int nShowCmd)   // 窗口显示命令  最大化最小化..
     69 {
     70     //实现底层窗口  6步骤
     71 
     72     // 1、设计窗口类
     73     // 2、注册窗口类
     74     // 3、创建窗口类
     75     // 4、显示和更新窗口
     76     // 5、通过循环取消息
     77     // 6、处理消息(窗口过程)
     78 
     79 
     80     //1、 设计窗口
     81     WNDCLASS wc;
     82     wc.cbClsExtra = 0; //类额外的内存 通常为0
     83     wc.cbWndExtra = 0; //窗口额外的内存,通常为0
     84     wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);  //设置背景
     85     wc.hCursor = LoadCursor(NULL, IDC_HAND);//设置光标 如果第一个参数为NULL,代表使用系统提供的默认光标
     86     wc.hIcon = LoadIcon(NULL, IDI_WARNING);  //设置图标 如果第一个参数为NULL,代表使用系统提供的默认图标
     87     wc.hInstance = hInstance;//当前实例句柄,WinMain函数中形参即可
     88     wc.lpfnWndProc = WindowProc; //窗口过程函数  回调函数 名称可以随机起
     89     wc.lpszClassName = TEXT("WINDOW");//指定窗口类名
     90     wc.lpszMenuName = NULL;//菜单名  没有填NULL
     91     wc.style = 0; // 0代表默认风格
     92 
     93     //2、 注册窗口类
     94     RegisterClass(&wc);
     95 
     96     //3、创建窗口
     97     /*
     98     lpClassName,  类名
     99     lpWindowName, 窗口名
    100     dwStyle,   显示风格 WS_OVERLAPPEDWINDOW
    101     x, y,     创建窗口起始坐标   CW_USEDEFAULT
    102     nWidth, nHeight,  创建窗口默认宽高  CW_USEDEFAULT
    103     hWndParent,  父窗口  NULL
    104     hMenu,     菜单   NULL
    105     hInstance,   实例句柄   hInstance
    106     lpParam 其他参数 NULL
    107     */
    108     HWND hwnd = CreateWindow(wc.lpszClassName, TEXT("TEXT WINDOW"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
    109 
    110     //4、 显示和更新
    111     ShowWindow(hwnd, SW_SHOWNORMAL);
    112     UpdateWindow(hwnd);
    113 
    114 
    115     //5、通过循环取消息
    116     /*
    117     HWND        hwnd;  //主窗口
    118     UINT        message; //消息名称 WM_XXXX (WINDOW MESSAGE)
    119     WPARAM      wParam; // 附加消息 键盘
    120     LPARAM      lParam; // 附加消息 鼠标 左右键
    121     DWORD       time;   // 消息产生时间
    122     POINT       pt;     // 附加消息  鼠标  x y坐标
    123     */
    124     MSG  msg;
    125 
    126     while (GetMessage(&msg, NULL, 0, 0))//代码优化
    127     {
    128         /*
    129         参数
    130         _Out_ LPMSG lpMsg,  消息结构体
    131         _In_opt_ HWND hWnd, NULL 捕获所有窗口消息
    132         _In_ UINT wMsgFilterMin,  过滤最小消息数量
    133         _In_ UINT wMsgFilterMax); 过滤最大消息数量   0 都写0 代表捕获所有消息
    134         */
    135         //if (GetMessage(&msg, NULL, 0, 0) == FALSE)
    136         //{
    137         //    break;
    138         //}
    139 
    140         //翻译消息
    141         TranslateMessage(&msg);
    142 
    143         //分发消息
    144         DispatchMessage(&msg);
    145 
    146     }
    147 
    148 
    149     return 0;
    150 }
    151 
    152 
    153 //函数入口

    消息处理机制

    ① 操作系统接收到应用程序的窗口消息,将消息投递到该应用程序的消息队列中。
    ② 应用程序在消息循环中调用GetMessage函数从消息队列中取出一条一条的消息。取出消息后,应用程序可以对消息进行一些预处理,例如,放弃对某些消息的响应,或者调用TranslateMessage产生新的消息。
    ③ 应用程序调用DispatchMessage,将消息回传给操作系统。消息是由 MSG结构体对象来表示的,其中就包含了接收消息的窗口的句柄。因此, DispatchMessage函数总能进行正确的传递。
    ④ 系统利用WNDCLASS结构体的lpfnWndProc成员保存的窗口过程函数的指针调用窗口过程,对消息进行处理。


    3、利用MFC创建窗口


    MFC是什么?
    微软基础类库(英语:Microsoft Foundation Classes,简称MFC)是一个微软公司提供的类库(class libraries),以C++类的形式封装了Windows API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量。其中包含的类包含大量Windows句柄封装类和很多Windows的内建控件和组件的封装类。
    MFC把Windows SDK API函数包装成了几百个类,MFC给Windows操作系统提供了面向对象的接口,支持可重用性、自包含性以及其他OPP原则。MFC通过编写类来封装窗口、对话框以及其他对象,引入某些关键的虚函数(覆盖这些虚函数可以改变派生类的功能)来完成,并且MFC设计者使类库带来的总开销降到了最低。


    项目的创建和之前一样,只是此次的源文件后缀为.cpp,因为MFC是由C++编写的,编写MFC程序需要包含#include <afxwin.h>头文件。

    注意:要配置环境(项目鼠标右键,在项目属性页,选择“常规”——》“MFC的使用”后选择“在共享DLL中使用MFC”)

    程序执行流程
    ① 程序开始时,先实例化应用程序对象(有且只有一个)
    ② 执行程序的入口函数InitInstance()
    ③ 给框架类MyFrame对象动态分配空间(自动调用它的构造函数),在其构造函数内部,通过CWnd::Create创建窗口
    ④ 框架类对象显示窗口CWnd::ShowWindow
    ⑤ 框架类对象更新窗口CWnd::UpdateWindow
    ⑥ 保存框架类对象指针CWinThread::m_pMainWnd

    4、MFC消息映射机制

    消息映射是一个将消息和成员函数相互关联的表。比如,框架窗口接收到一个鼠标左击消息,MFC将搜索该窗口的消息映射,如果存在一个处理WM_LBUTTONDOWN消息的处理程序,然后就调用OnLButtonDown。

    下面是是将消息映射添加到一个类中所做的全部工作:
    1)所操作类中,声明消息映射宏。
    2)通过放置标识消息的宏来执行消息映射,相应的类将在对BEGIN_MESSAGE_MAP和END_MESSAGE_MAP的调用之间处理消息。

    3)对应消息处理函数分别在类中声明,类外定义:


    帮助文档的使用
    1) MSDN的使用


    2) VC++之MFC类库中文手册
    通过此手册查找,必须加上成员所属的类作用域(类名::),否则,无法查找到匹配的关键字。


    5、Windows字符集介绍


    Widnows字符集
    1) 多字节字符集(8位的ANSI字符集)
    在Windows98以及以前的版本使用8位ANSI字符集,它类似于我们程序员熟悉的ASCII字符集。
    char sz[] = "ABCDEFG";
    char *psz = "ABCDEFG";
    int len = strlen(sz);

    2) 宽字符集(16位的Unicode字符集)
    在WindowsNT和Windows2000后开始使用16位的Unicode字符集,它是ANSI字符集的一个超集。Unicode适用于国际市场销售的应用程序,因为它包含各种各样来自非U.S.字母表的字符,比如中文,日文,韩文,西欧语言等。
    //在字符串前加字母L表示将ANSI字符集转换成Unicode字符集。
    wchar_t wsz[] = L"ABCDEFG";
    wchar_t *pwsz = L"ABCDEFG";
    int len = wcslen(wsz); //测试宽字节字符串的长度

    3) TEXT(_T)宏
    MFC中的TEXT宏可以自动适应字符类型,如果定义了预处理器程序符号_UNICODE,那么编译器将使用Unicode字符,如果没用定义该预处理器程序符号,那么编译器将使用ANSI字符。
    MessageBox(TEXT("鼠标左键"));
    MessageBox(_T("鼠标左键"));

    4) TCHAR类型
    如果定义了_UNICODE符号TCHAR将变为wchar_t类型。如果没用定义_UNICODE符号,TCHAR将变为普通古老的char类型。


    练习:

    mfc.h

     1 #include <afxwin.h> //MFC需要包含的头文件
     2 
     3 class MyApp :public CWinApp  //CWinApp 应用程序类
     4 {
     5 public:
     6 
     7     //MFC 程序入口
     8     virtual BOOL InitInstance();
     9 
    10 };
    11 
    12 //窗口框架类
    13 class MyFrame :public CFrameWnd
    14 {
    15 public:
    16     MyFrame(); //窗口构造函数
    17 
    18     //使用消息映射机制 必须引用声明宏
    19 
    20     DECLARE_MESSAGE_MAP()
    21 
    22     afx_msg void OnLButtonDown(UINT, CPoint); //鼠标左键按下声明
    23 
    24     afx_msg void OnChar(UINT, UINT, UINT); // 键盘函数声明
    25 
    26     afx_msg void OnPaint(); //绘图声明
    27 
    28 };

    mfc.cpp

      1 #include "mfc.h"
      2 
      3 MyApp app; //应用程序对象 ,有且仅有一个
      4 
      5 BOOL MyApp::InitInstance()
      6 {
      7     //创建窗口
      8     m_pMainWnd = new MyFrame;
      9     
     10 
     11     //显示 和 更新
     12     m_pMainWnd->ShowWindow(SW_SHOWNORMAL);
     13     m_pMainWnd->UpdateWindow();
     14 
     15     //m_pMainWnd = frame;//保存指向应用程序的主窗口的指针
     16 
     17     return TRUE; //返回正常初始化
     18 }
     19 
     20 
     21 //消息映射的 分界宏
     22 BEGIN_MESSAGE_MAP(MyFrame,CFrameWnd)
     23 
     24     ON_WM_LBUTTONDOWN() //鼠标左键按下 宏
     25 
     26     ON_WM_CHAR() //键盘宏
     27 
     28     ON_WM_PAINT() //绘图宏
     29 
     30 END_MESSAGE_MAP()
     31 
     32 
     33 
     34 //窗口框架的默认构造函数
     35 MyFrame::MyFrame()
     36 {
     37     Create(NULL, TEXT("MFC WINDOW"));
     38 }
     39 
     40 //鼠标左键按下 实现
     41 void MyFrame::OnLButtonDown(UINT, CPoint point)
     42 {
     43 
     44     //TCHAR buf[1024];
     45     //wsprintf(buf, TEXT("x = %d, y = %d"), point.x, point.y);
     46     //MessageBox(buf);
     47 
     48     CString str; //MFC使用的字符串
     49     //格式化字符串
     50     str.Format(TEXT(" :::::x = %d, y = %d"), point.x, point.y);
     51 
     52     MessageBox(str);
     53 
     54 }
     55 
     56 //键盘实现
     57 void MyFrame::OnChar(UINT key, UINT, UINT)
     58 {
     59     //TCHAR buf[1024];
     60     //wsprintf(buf, TEXT("按下了%c"), key);
     61     //MessageBox(buf);
     62 
     63 
     64     CString str;
     65     str.Format(TEXT("按下了%c 键"),key);
     66     MessageBox(str);
     67 
     68 }
     69 
     70 void MyFrame::OnPaint()
     71 {
     72     CPaintDC dc(this); //画家 画到当前的窗口中
     73 
     74     //画文字
     75     dc.TextOutW(100, 100, TEXT("为了部落"));
     76     
     77     dc.Ellipse(10, 10, 100, 100);
     78 
     79     // 多字节 转 宽字节
     80     //MessageBox(L"aaa");
     81     MessageBox(TEXT("aaa"));
     82 
     83     //TEXT  TCHAR 自动编码转换
     84 
     85     //统计宽字节字符串长度
     86     char * p = "aaaa";
     87     int n = 0;
     88     n = strlen(p);
     89 
     90     wchar_t * p2 = L"bbbb";
     91     n = wcslen(p2);
     92 
     93 
     94     //string 互相转换 char *  -> .c_str();<- 构造
     95     //CString 和char * 互相转换
     96     //char *  -> CString
     97     char * p3 = "aa";
     98     CString str = CString(p3);//构造
     99 
    100     //CString -> char* 
    101     CString str2 = TEXT("abc");
    102     CStringA tmp;
    103     tmp = str2;
    104     char * pp = tmp.GetBuffer();
    105     MessageBox(CString(pp));
    106 
    107 
    108 }
    109 
    110 // Window字符集
    111 // ANSI  1个字符 对应 1个字节  多字节
    112 // 中文 韩文...  宽字节  1个字符对应多个字节  UniCode   utf8  3个字节  gbk  2个字节


    6、利用向导创建MFC

    在VS中选择“文件” -- “新建” -- “项目”;选择 MFC – MFC应用程序,接下来我们创建一个单文档MFC标准类型应用程序。MFC自动为我们生成了四个类,它们的继承关系如下:

    类视图

    文档/视图结构体系
    MFC应用程序框架结构的基石是文档/视图体系结构,它定义了一种程序结构,这种结构依靠文档对象保存应用程序的数据,并依靠视图对象控制视图中显示的数据,把数据本身与它的显示分离开。

    数据的存储和加载由文档类来完成,数据的显示和修改则由视类来完成。 MFC在类CDocument和CView中为稳定视图提供了基础结构。CWinApp、CFrameWnd和其他类与CDocument和CView合作,把所有的片段连在了一起。

    CView类也派生于CWnd类,框架窗口是视图窗口的一个父窗口。主框架窗口(CFrameWnd)是整个应用程序外框所包括的部分,即图中粗框以内的内容,而视类窗口只是主框架中空白的地方。

    消息处理的添加
    在主框架类中添加WM_LBUTTONDOWN消息的响应函数,具体操作如下:

    从类视图中找到CMainFrame(继承自CFrameWnd),选择此类然后从属性面板中找到消息按钮,在消息列表中找到WM_LBUTTONDOWN消息,添加。

    工程文件增加几处改变:

    第一处:在框架类头文件中添加了鼠标左键消息函数的函数声明


    第二处:在框架类cpp文件中添加了消息映射宏


    第三处:在框架列cpp文件中添加了处理鼠标左键消息的函数定义


    我们再此OnLButtonDown函数中添加一个MessageBox消息,鼠标左键按下弹出一个提示框,然后执行程序。我们会惊奇的发现程序并未如我们所愿弹出消息框。

    因为,框架窗口是视窗口的父窗口,那么视类窗口就应该始终覆盖在框架类窗口之上。就好比框架窗口是一面墙,视类窗口就是墙纸,它始终挡在这面墙前边。也就是说,所有操作,包括鼠标单击、鼠标移动等操作都只能有视类窗口捕获。

    MFC框架中一些重要的函数
    1) InitInstance函数


    应用程序类的一个虚函数,MFC应用程序的入口。
    2) PreCreateWindow函数


    当框架调用CreateEx函数创建窗口时,会首先调用PreCreateWindow函数。

    通过修改传递给PreCreateWindow的结构体类型参数CREATESTRUCT,应用程序可以更改用于创建窗口的属性。在产生窗口之前让程序员有机会修改窗口的外观。

    最后再调用CreateWindowEx函数完成窗口的创建。

    3) OnCreate函数


    OnCreate是一个消息响应函数,是响应WM_CREATE消息的一个函数,而WM_CREATE消息是由Create函数调用的。一个窗口创建(Create)之后,会向操作系统发送WM_CREATE消息,OnCreate()函数主要是用来响应此消息的。

    OnCreate与Create的区别:
    》Create()负责注册并产生窗口,像动态创建控件中的Create()一样,窗口创建之后会向操作系统发送WM_CREATE消息。
    》OnCreate()不产生窗口,只是在窗口显示前设置窗口的属性如风格、位置等。
    》OnCreate()是消息WM_CREATE的消息响应函数。

    4) OnDraw和OnPaint


    OnPaint是WM_PAINT消息的消息处理函数,在OnPaint中调用OnDraw,一般来说,用户自己的绘图代码应放在OnDraw中。
    》OnPaint()是CWnd的类成员,负责响应WM_PAINT消息。
    》OnDraw()是CView的成员函数,没有响应消息的功能。

    当视图变得无效时(包括大小的改变,移动,被遮盖等等),Windows发送WM_PAINT消息。该视图的OnPaint 处理函数通过创建CPaintDC类的DC对象来响应该消息并调用视图的OnDraw成员函数。OnPaint最后也要调用OnDraw,因此一般在OnDraw函数中进行绘制。

    通常我们不必编写OnPaint处理函数。当在View类里添加了消息处理OnPaint()时,OnPaint()就会覆盖掉OnDraw()。

    拓展知识点
    》MFC中后缀名为Ex的函数都是扩展函数。
    》在MFC中,以Afx为前缀的函数都是全局函数,可以在程序的任何地方调用它们。

    四、总结

    1    名词解析 SDK  句柄
    2    底层窗口实现
    2.1    头文件 windows .h
    2.2     int WINAPI  WinMain()
    2.3    6个步骤
    2.3.1    1 设计窗口  : WNDCLASS wc
    2.3.2    2 注册窗口类
    2.3.3    3 创建窗口
    2.3.4    4 显示和更新
    2.3.5    5 通过循环取消息
    2.3.6    6 处理窗口过程
    2.3.6.1    处理关闭消息 WM_CLOSE  destroyWindow
    2.3.6.2    WM_DESTROY  postquitMessage
    2.3.6.3    鼠标左键
    2.3.6.4    键盘按下
    2.3.6.5    绘图
    3    MFC实现一个空窗口
    3.1    头文件  #include<afxwin.h>
    3.2    应用程序类 MyApp:public CWinApp
    3.3    有且仅有一个应用程序对象  MyApp app
    3.4    入口函数  BOOL  InitInstance
    3.5    创建窗口
    3.6    窗口框架类  MyFrame:public CFrameWnd
    3.7    构造函数 Create(NULL,标题名)
    3.8    InitInstance 创建窗口
    3.8.1    MyFrame * frame = new MyFrame
    3.8.2    显示
    3.8.3    更新
    3.8.4    保存主窗口指针
    3.8.5    m_pMainWnd = frame
    3.8.6    return TRUE
    3.9    修改项目配置  DLL
    4    消息映射机制
    4.1    在.h中声明 声明宏
    4.2    .cpp中 分界宏
    4.2.1    Begin  ( theClass ,BaseClass)
    4.2.2    End
    4.3    鼠标左键、键盘消息、绘图消息
    4.4    CString  str   format() 格式化字符串
    4.5    CPaintDC  查看其它画的图案  用CDC查找
    5    Windows字符集介绍
    5.1    TEXT TCHAR 做自动编码转换
    5.2    多字节 转 宽字节 L
    5.3    统计宽字节长度  wcslen()
    5.4    CString 和char * 转换
    5.4.1     char * -》CString  调用CString有参构造
    5.4.2     CString  - > char *    
    5.4.2.1    CString s ;
    5.4.2.2     CSringA tmp ; tmp = s
    5.4.2.3    tmp.getBuffer();
    6    利用向导创建MFC    
    6.1    单个文档   MFC标准
    6.2    生成4个类,用类视图看
    6.3    App InitInstance
    6.4    CMainFrame  框架类
    6.5    C…View  视类
    6.6    C…DOC  处理数据存储
    6.7    Create  WM_CREATE  OnCreate 之间联系
    6.7.1    Create  创建窗口  给系统发生 WM_CREATE消息
    6.7.2    OnCreate 响应WM_CREAT消息
    6.8    OnDraw 和OnPaint 关系  
    6.8.1    如果同时存在   OnPaint会覆盖 OnDraw
    6.9    EX为结尾 都是扩展函数  Afx开头 全局函数

    在学习MFC总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。

  • 相关阅读:
    MySQL第五天
    phprpc
    最近数据库不怎么太平
    dumpfile参数,linux和windows下稍有不同
    impdp 时无反应
    修改IP后,重新config EM
    ORA00054: resource busy and acquire with NOWAIT specified
    测试修改DBID手记
    如何关闭任务计划
    文件夹打开变成寻找框如何解决
  • 原文地址:https://www.cnblogs.com/Alliswell-WP/p/CPlusPlus_MFC_01.html
Copyright © 2011-2022 走看看