文章目录
MFC
1 基本概念
WinAPI:Windows平台下的系统调用,Windows.h 调用系统提供的特殊接口,得到系统的资源
窗口:父窗口和子窗口,客户区和非客户区
句柄:结构体变量,窗口句柄HWND,图标句柄HICO
消息队列 -> 消息 -> 窗口过程函数
WinMain() WINAPI 入口地址
2 WinAPI窗口程序
1. WinAPI创建窗口流程
- 定义入口函数WinMain()
- 创建一个窗口
a) 设计窗口类WNDCLASS (给成员变量赋值)
b) 注册窗口类
c) 显示和更新窗口 - 消息循环
- 窗口过程函数
2. WinAPI定义
WinMain()
WinAPI 入口地址
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, // 应用程序实例
HINSTANCE hPrevInstance, // 上一个应用程序实例,不用
LPSTR lpCmdLine, // 命令行参数 long pointer string -> char *
int nCmdShow // 窗口显示的样式 最大化,最小化
)
{
}
3. 创建窗口
#include <windows.h>
LRESULT CALLBACK DealMessage(HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
/*
1. 定义入口函数WinMain()
2. 创建一个窗口
a) 设计窗口类WNDCLASS (给成员变量赋值)
b) 注册窗口类
c) 创建窗口类
d) 显示和更新窗口
3. 消息循环
4. 窗口过程函数
*/
// WINAPI: 修饰函数;规定函数参数入栈从右往左,函数调用完毕,自动清理堆栈
// CALLBACK
int WINAPI WinMain(HINSTANCE hInstance, // 应用程序实例
HINSTANCE hPrevInstance, // 上一个应用程序实例,不用
LPSTR lpCmdLine, // 命令行参数 long pointer string -> char *
int nCmdShow // 窗口显示的样式 最大化,最小化
)
{
// 设计窗口类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 = NULL;
wc.hIcon = LoadIcon(NULL, IDI_WARNING); // 加载系统默认图标
wc.hInstance = hInstance; // 应用程序实列
wc.lpfnWndProc = DealMessage; // 窗口过程函数名字, 消息处理函数
wc.lpszClassName = TEXT("abc"); // 类的名字
wc.lpszMenuName = NULL; // 菜单名字
wc.style = nCmdShow; // 显示风格
// b) 注册窗口类 告诉系统窗口过程函数的入口地址
RegisterClass(&wc);
// c) 创建窗口类
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);
UpdateWindow(hWnd);
}
4. 消息循环
// 消息循环
MSG msg; // 定义一个消息
// 如果接受到WM_QUIT,返回0,退出
// 如果出错,返回-1,不退出
while (GetMessage(&msg, NULL, 0, 0)) {
// 翻译工作
// 虚拟按键转为标准字符WM_CHAR
TranslateMessage(&msg);
// 给操作系统分发消息
DispatchMessage(&msg);
}
return msg.wParam;
5. 窗口过程函数
操作系统调用程序中一个专门负责处理消息的函数,这个函数称为窗口过程
// 窗口过程函数
LRESULT CALLBACK DealMessage(HWND hWnd, // 窗口句柄,消息所属的窗口
UINT uMsg, // 消息标志
WPARAM wParam, // 附加信息
LPARAM lParam
)
{
switch (uMsg)
{
case WM_LBUTTONDOWN: // 鼠标左键按下
MessageBox(hWnd, TEXT("ABC"), TEXT("鼠标左键按下"), MB_OK);
break;
case WM_PAINT:
{
PAINTSTRUCT ps; // 绘图结构体
HDC dc = BeginPaint(hWnd, &ps); // 开始
TCHAR* p = L"AAAAAAAA"; // 转为宽字节
TextOut(dc, 30, 30, p, wcslen(p));
EndPaint(hWnd, &ps);
break;
}
case WM_DESTROY:
PostQuitMessage(2); // WM_QUIT, 给主函数 return msg.wParam
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
6. WinAPI窗口程序源代码
#include <windows.h>
// 窗口过程函数
LRESULT CALLBACK DealMessage(HWND hWnd, // 窗口句柄,消息所属的窗口
UINT uMsg, // 消息标志
WPARAM wParam, // 附加信息
LPARAM lParam
)
{
switch (uMsg)
{
case WM_LBUTTONDOWN: // 鼠标左键按下
MessageBox(hWnd, TEXT("ABC"), TEXT("鼠标左键按下"), MB_OK);
break;
case WM_PAINT:
{
PAINTSTRUCT ps; // 绘图结构体
HDC dc = BeginPaint(hWnd, &ps); // 开始
TCHAR* p = L"AAAAAAAA"; // 转为宽字节
TextOut(dc, 30, 30, p, wcslen(p));
EndPaint(hWnd, &ps);
break;
}
case WM_DESTROY:
PostQuitMessage(2); // WM_QUIT, 给主函数 return msg.wParam
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
/*
1. 定义入口函数WinMain()
2. 创建一个窗口
a) 设计窗口类WNDCLASS (给成员变量赋值)
b) 注册窗口类
c) 创建窗口类
d) 显示和更新窗口
3. 消息循环
4. 窗口过程函数
*/
// WINAPI: 修饰函数;规定函数参数入栈从右往左,函数调用完毕,自动清理堆栈
// CALLBACK
int WINAPI WinMain(HINSTANCE hInstance, // 应用程序实例
HINSTANCE hPrevInstance, // 上一个应用程序实例,不用
LPSTR lpCmdLine, // 命令行参数 long pointer string -> char *
int nCmdShow // 窗口显示的样式 最大化,最小化
)
{
// 设计窗口类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 = NULL;
wc.hIcon = LoadIcon(NULL, IDI_WARNING); // 加载系统默认图标
wc.hInstance = hInstance; // 应用程序实列
wc.lpfnWndProc = DealMessage; // 窗口过程函数名字, 消息处理函数
wc.lpszClassName = TEXT("abc"); // 类的名字
wc.lpszMenuName = NULL; // 菜单名字
wc.style = nCmdShow; // 显示风格
// b) 注册窗口类 告诉系统窗口过程函数的入口地址
RegisterClass(&wc);
// c) 创建窗口类
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);
UpdateWindow(hWnd);
// 消息循环
MSG msg; // 定义一个消息
// 如果接受到WM_QUIT,返回0,退出
// 如果出错,返回-1,不退出
while (GetMessage(&msg, NULL, 0, 0)) {
// 翻译工作
// 虚拟按键转为标准字符WM_CHAR
TranslateMessage(&msg);
// 给操作系统分发消息
DispatchMessage(&msg);
}
return msg.wParam;
}
3 MFC程序
1. MFC创建窗口流程
- 应用程序类
CWinApp
- 框架类
CFrameWnd
创建 mfc.h
和mfc.cpp
文件
在mfc.h
文件中
#pragma once
#include <afxwin.h>
// 1) 应用程序类 CWinApp
class MyApp : public CWinApp
{
public:
// 基类的虚函数
// 派生类只是重写
// MFC程序的入口地址
virtual BOOL InitInstance();
};
// 2) 框架类 CFrameWnd
class MyFrame : public CFrameWnd
{
public:
MyFrame();
private:
};
在mfc.cpp
文件中
#include "mfc.h"
// 有且只有一个全局的应用程序类对象
MyApp myApp;
// 程序入口的地址
BOOL MyApp::InitInstance()
{
/*
* 1.创建框架类对象
* 2.显示窗口
* 3.更新窗口
* 4.保存框架类对象指针
*/
// 1.创建框架类对象
MyFrame* frame = new MyFrame; // 构造函数
// 2.显示窗口
frame->ShowWindow(SW_SHOWNORMAL);
// 3.更新窗口
frame->UpdateWindow();
// 4.保存框架类对象指针
m_pMainWnd = frame;
return TRUE;
}
MyFrame::MyFrame()
{
// CWnd类的成员函数 CWnd::Create
// CFrameWnd 继承于 CWnd
Create(NULL, TEXT("MFC"));
}
2. MFC流程
- 有且只有一个全局的应用程序对象
- 在程序入口函数实现功能 InitInstance()
- 给框架类MyFrame对象动态分配空间(自动调用它的构造函数)
- 框架类MyFrame对象构造函数函数里创建窗口 CWnd::Create
- 框架类对象显示窗口 CWnd::ShowWindow
- 框架类对象更新窗口 CWnd::UpdateWindow
- 保存框架类对象指针 CWinThread::m_PMainWnd
- 给框架类MyFrame对象动态分配空间(自动调用它的构造函数)
3. 消息映射
事件处理:
消息映射
- 所操作类中,声明消息映射宏
DECLARE_MESSAGE_MAP()
- 对应的.cpp 定义宏
BEGIN_MESSAGE_MAP(MyFrame, CFrameWnd) // 派生类名 基类名
ON_WM_LBUTTONDOWN() // 消息映射入口标志
END_MESSAGE_MAP()
- 对应类中,消息处理函数的声明
- 对应.cpp 消息处理函数的定义