01_MFC入门基础知识
一、基础概念
SDK:软件开发工具包,特定的软件包、软件框架、硬件平台、操作系统等建立应用软件时的开发工具的集合;一般而言SDK即开发 Windows 平台下的应用程序所使用的 SDK。
JDK:java开发工具包
IDE:集成开发环境(IDE,Integrated Development Environment )是用于提供程序开发环境的应用程序,一般包括代码编辑器、编译器、调试器和图形用户界面等工具。这里学习MFC,我采用的是vs2013.
API:应用程序接口
WINAPI:windows平台下的系统资源调用,头文件"windows.h",调用系统提供的特殊接口,得到系统的资源。
窗口:父窗口和子窗口,客户区和非客户区。
句柄:结构体变量,窗口句柄HWND,图标句柄:HICO
消息队列
消息
窗口过程函数
一般c/c++或其它编程语言程序都是从main()函数开始执行,而WINAPI的入口地址是WinMain().
二、winAPI窗口程序
1、定义入口函数WinMain()
2、创建一个窗口
a)设计窗口类WNDCLASS(给成员变量赋值)
b)注册窗口类
c)创建窗口类
d)显示和更新窗口
3、消息循环
4、窗口过程函数(回调函数)
下面是一个win32项目:winapi创建窗口(注意vs创建win32空项目,然后再window.cz中添加如下代码)
/* windows.c */
#include "windows.h" //窗口程序的头文件
/*
WINAPI:修饰函数,规定函数参数入栈从右到左,函数调用(CALLBACK)完毕,自动清理堆栈
winAPI窗口程序
1、定义入口函数WinMain()
2、创建一个窗口
a)设计窗口类WNDCLASS(给成员变量赋值)
b)注册窗口类
c)创建窗口类
d)显示和更新窗口
3、消息循环
4、窗口过程函数
*/
/* 4、窗口过程函数 */
LRESULT CALLBACK DealMessage(
HWND hWnd, //窗口句柄,消息所属的窗口
UINT uMsg, //消息标志
WPARAM wParam, //附加消息
LPARAM lParam //附加消息
)
{
switch (uMsg)
{
case WM_LBUTTONDBLCLK://鼠标左键按下
MessageBox(hWnd, TEXT("ABC"), TEXT("鼠标左键按下"), MB_OK);
break;
case WM_PAINT:
{
PAINTSTRUCT ps;//绘图结构体
HDC dc = BeginPaint(hWnd, &ps);//开始
TCHAR* p = L"你好,世界!";//宽字节
TextOutW(dc, 30, 30, p, wcslen(p));
}
case WM_DESTROY:
PostQuitMessage(2);//WM_QUIT,给主函数return msg.wParam
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
/*1、定义入口函数WinMain()*/
int WINAPI WinMain(
HINSTANCE hInstance, //应用程序实例句柄
HINSTANCE hPrevInstance, //上一个应用程序句柄,在win32环境下,参数一般为NULL,不用了
LPSTR lpCmdLine, //char * argv[] 命令行参数
int nShowCmd) //窗口样式:显示命令 最大化、最小化、正常
{
/*
2、创建一个窗口
1.设计窗口
2.注册窗口类
a)设计窗口类WNDCLASS(给成员变量赋值)
b)注册窗口类
c)创建窗口类
d)显示和更新窗口
3.消息循环
4.显示和更新
5.通过循环取消息
6.处理消息(窗口过程)
*/
/* a)设计窗口类WNDCLASS(给成员变量赋值) */
WNDCLASS wc; //窗口类
/*类的附加信息*/
wc.cbClsExtra = 0;//类的额外的内存
wc.cbWndExtra = 0;//窗口的额外内存
//获取系统默认的白色画刷
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//设置 背景,必须写
//wc.hCursor = NULL;//使用系统默认
wc.hCursor = LoadCursor(NULL, IDC_HELP);//加载系统默认光标
wc.hIcon = LoadIcon(NULL, IDI_WARNING);//j加载系统默认图标 图标 如果第一个参数为NULL,代表使用系统提供的光标图标
wc.hInstance = hInstance;//应用程序实例句柄 传入WinMain中的形参即可
wc.lpfnWndProc = DealMessage; //窗口过程函数名字,消息处理函数 回调函数 窗口过程
wc.lpszClassName = TEXT("abc");//指定窗口类名字
wc.lpszMenuName = NULL;//菜单名字
wc.style = nShowCmd;//显示风格 0代表默认风格SW_SHOWNORMAL
/* b)注册窗口类 */
RegisterClass(&wc);
/* c)创建窗口类 */
/*
lpClassName, 类名
lpWindowName, 窗口标题名
dwStyle, WS_OVERLAPPEDWINDOW 风格
x, 显示坐标 CW_USEDEFAULT 默认值
y,
nWidth, 宽高
nHeight,
hWndParent, 父窗口 NULL
hMenu, 菜单 NULL
hInstance, 实例句柄 hInstance
lpParam) 附加值 NULL
*/
HWND hWnd = CreateWindow(TEXT("abc"), TEXT("hello,windows"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
/* d)显示和更新窗口 */
ShowWindow(hWnd, SW_SHOWNORMAL);//SW_SHOWNORMAL表示正常显示 CWnd::ShowWindow
/* 3、消息循环 */
/*
消息结构体
typedef struct tagMSG { // msg
HWND hwnd; 主窗口句柄
UINT message; 具体消息名称
WPARAM wParam; 附加消息 键盘消息
LPARAM lParam; 附加消息 鼠标消息
DWORD time; 消息产生时间
POINT pt; 附加消息 鼠标消息 x y
} MSG;
*/
MSG msg;//创建消息
//如果接受到VM_QUIT,返回0,退出
//如果出错,返回-1,不退出
while (GetMessage(&msg, hWnd, 0, 0))
{
//翻译工作
//虚拟按键转为标准字符WM_CHAR
TranslateMessage(&msg);
//给操作系统分发消息
DispatchMessage(&msg);
}
return 0;
}
三、一个MFC程序(纯代码)
1)应用程序 CWinApp
2)框架类 CFrameWnd
下面是一个MFC程序的总体结构:
#pragma once
#include "afxwin.h"
class MyApp:public CWinApp
{
public:
//MFC程序的入口地址
virtual BOOL InitInstance();
private:
};
class MyFrame:public CFrameWnd
{
public:
MyFrame();
private:
};
1)有且只有一个全局的应用程序类对象
2)在程序入口函数实现功能 InitInstance()
A)给框架类MyFrame对象动态分配空间(自动调用它的构造函数)
a)框架类MyFrame对象构造函数函数里创建窗口 CWnd::Creat
B)框架类对象显示窗口 CWnd::ShowWindow
C)框架类对象更新窗口 CWnd::UpdateWindow
D)保存框架类对象指针 CWinThread::m_pMainWnd
事件处理:
消息映射
1、所操作类中,声明消息映射宏
DECLARE_MESSAGE_MAP()
2、对应的.cpp定义消息宏
BEGIN_MESSAGE_MAP(MyFrame, CFrameWnd) //派生类名,基类名
ON_WM_LBUTTONDOWN() //消息映射入口标志
ON_WM_PAINT()
END_MESSAGE_MAP()
3、对应类中,消息处理函数的声明
4、对应.cpp 消息处理函数的定义
void MyFrame::OnLButtonDown(UINT, CPoint)
{
//CWnd::MessageBox
MessageBox(TEXT("鼠标左键"));
}
void MyFrame::OnPaint()
{
//QPainter p(this);
//p.drawxxx();
CPaintDC cdc(this);
cdc.TextOutW(100, 100,TEXT("你好,mfc") );
}
第一个MFC程序代码示例:
/*
mfc.h
*/
#pragma once
#include "afxwin.h"
//1)应用程序 CWinApp,派生类(子类)
class MyApp :public CWinApp
{
public:
//基类的虚函数
//派生类只是重写
//MFC程序的入口地址
virtual BOOL InitInstance();
private:
};
//2)框架类 CFrameWnd
class MyFrame :public CFrameWnd
{
public:
MyFrame();
/* 消息处理 */
//声明消息映射宏
DECLARE_MESSAGE_MAP()
/* 消息处理_消息处理函数的声明*/
afx_msg void OnLButtonDown(UINT, CPoint);
afx_msg void OnPaint();
private:
};
#include "mfc.h"
/* 1)有且只有一个全局的应用程序类对象 */
MyApp myApp;
/* 2)在程序入口函数实现功能 InitInstance() 程序的入口地址*/
BOOL MyApp::InitInstance()
{
/*
1、创建框架类对象
2、显示窗口
3、更新窗口
4、保存框架类对象指针
*/
//1、创建框架类对象 CWnd::Create
MyFrame *frame = new MyFrame;//构造函数
//2、显示窗口 CWnd::ShowWindow
frame->ShowWindow(SW_SHOWNORMAL);
//3、更新窗口 CWnd::UpdateWindow
frame->UpdateWindow();
//4、保存框架类对象指针 CWinThread::m_pMainWnd
m_pMainWnd = frame;
return TRUE;
}
/* 消息处理_定义消息宏 */
BEGIN_MESSAGE_MAP(MyFrame, CFrameWnd)
ON_WM_LBUTTONDOWN()
ON_WM_PAINT()
END_MESSAGE_MAP()
MyFrame::MyFrame()
{
//CWnd类的成员函数 CWnd::Create
//CFrameWnd 继承于 CWnd
Create(NULL, TEXT("MFC"));
}
void MyFrame::OnLButtonDown(UINT, CPoint)
{
//CWnd::MessageBox
MessageBox(TEXT("鼠标左键"));
}
void MyFrame::OnPaint()
{
//QPainter p(this);
//p.drawxxx();
CPaintDC cdc(this);
cdc.TextOutW(100, 100, TEXT("你好,mfc"));
}
四、根据向导创建工程
1、文档视图结构
文档:它是一个类,这个类专门来存储数据
视图 :它是一个类,这个类专门来显示和修改数据
框架类:一个容器,这个容器装了视图
2、几个比较重要的函数
应用程序类CWinApp:
InitInstance(),程序的入口地址
框架类CFrameWnd:
PreCreateWindow()创建窗口之前调用
OnCreate() 创建窗口后,触发WM_CREATE,它是WM_CREATE消息的处理函数
视图类CView:
OnDraw():绘图
WM_PAINT消息处理函数OnPaint() 内部调用 OnDraw()
OnPaint() 和 OnDraw()同时存在,只有OnPaint()有效
3、事件的添加和删除
a)框架和视图的区别
选择所需类->右击->属性->消息->WM_LBUTTONDOWN->ADD
框架类相当于容器,容器放视图
视图相当于壁纸
五、字符集
ANSI 多字节,单字节
char p[]="acadad";//一个字符一个字节
unicode 宽字节,一个字符2个字节
TCHAR* p=L"ABC";//一个字符2个字节
MFC:
TCHAR:自动适应字节(条件编译)
TEXT()
_T()
六、拓展
afx_xxxx:全局成员函数,不属于某个类特有的
xxxEx:xxxW,拓展
MFC:
类名和函数名字:单词首字母大写
class MyClass
{
};
void SetName()
{
}
//形参
isFlage
isPressTest
//成员变量
m_xxx
m_hWnd