在学习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 应用程序与用户进行交互的接口。利用窗口可以接收用户的输入、以及显示输出。

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

MFC学习笔记——07-MFC_18day

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

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

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

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

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

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

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

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

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

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

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 //函数入口

 


消息处理机制

MFC学习笔记——07-MFC_18day

① 操作系统接收到应用程序的窗口消息,将消息投递到该应用程序的消息队列中。
② 应用程序在消息循环中调用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学习笔记——07-MFC_18day

注意:要配置环境(项目鼠标右键,在项目属性页,选择“常规”——》“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的调用之间处理消息。
MFC学习笔记——07-MFC_18day

3)对应消息处理函数分别在类中声明,类外定义:MFC学习笔记——07-MFC_18day

 


帮助文档的使用
1) MSDN的使用
MFC学习笔记——07-MFC_18day

MFC学习笔记——07-MFC_18day

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

MFC学习笔记——07-MFC_18day

MFC学习笔记——07-MFC_18day


 

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 =

相关文章:

  • 2022-12-23
  • 2021-07-20
  • 2021-08-03
  • 2022-02-22
  • 2021-05-12
  • 2021-08-03
  • 2021-11-29
  • 2022-02-02
猜你喜欢
  • 2021-07-19
  • 2021-11-30
  • 2021-12-20
  • 2022-01-20
相关资源
相似解决方案