mfc 学习的第一天
1 通过底层实现窗口
1.1 sdk api 句柄
1.2 消息处理机制
1.3 头文件 windows.h
1.4 程序入口 winMain
2 具体6个步骤
2.1 1、设计窗口 WNDCLASS wc
2.2 2、注册窗口 RegisterClass
2.3 3、创建窗口 createWindow
2.4 4、显示和更新 showWindhow updateWindow
2.5 5、通过循环取消息 MSG msg
2.5.1 写循环 while(1)
2.5.2 GetMessage==false 跳出循环
2.5.3 翻译消息
2.5.4 分发消息
2.6 6、窗口过程
2.6.1 LRESULT CALLBACK WindowProc
2.6.2 返回默认处理
2.6.3 return DefWindowProc(hwnd, uMsg, wParam, lParam);
2.6.4 点击叉子 WM_CLOSE destroy
2.6.5 WM_DESTROY postQuitMessage(0)
2.6.6 鼠标左键按下
2.6.7 键盘按下
2.6.8 绘图 文字
vs2013创建win32项目
步骤:文件→新建→项目→选择Win32项目,确定→下一步→勾上空项目,完成→源文件右键→添加→新建项→C++文件→名称为:windows.c→添加
小技巧:
安装番茄助手,提高编程效率。
注释/取消注释
1)注释:组合键“Ctrl+K+C”;
2)取消注释:组合键“Ctrl+K+U”
windows.c的源码
#include <Windows.h> //底层实现窗口 的头文件
#include <windowsx.h>
//6、处理窗口过程
//CALLBACK 代表__stdcall参数的传递顺序:从右到左 一次入栈,并且在函数返回前 清空堆栈
LRESULT CALLBACK WindowProc(
HWND hwnd, //消息所属的窗口句柄
UINT uMsg, //具体的消息名称 WM_XXXX 消息名
WPARAM wParam, //键盘附加消息
LPARAM lParam //鼠标附加消息
)
{
POINT pt; //定义坐标
PAINTSTRUCT ps; //定义绘图结构体
HDC hdc; //定义设备上下文句柄
switch (uMsg)
{
case WM_CLOSE:
//所以xxxWindow为结尾的方法,都不会进入到消息队列中,而是直接执行
DestroyWindow(hwnd); //DestroyWindow 发送另一个消息 WM_DESTROY
break;
case WM_DESTROY:
PostQuitMessage(0); //真正的退出窗口 使 GetMessage(&msg,NULL,0,0) == FALSE
case WM_LBUTTONDOWN: //鼠标左键按下
pt.x = GET_X_LPARAM(lParam); //GET_X_LPARAM 方法 需要加windowsx.h 头文件
pt.y = GET_Y_LPARAM(lParam);
wchar_t buf[1024];
wsprintf(buf, TEXT("x = %d,y = %d"), pt.x, pt.y);
MessageBox(hwnd, buf, TEXT("鼠标的左键按下"), MB_OK);
break;
case WM_KEYDOWN: //键盘
MessageBox(hwnd, TEXT("键盘按下"), TEXT("键盘按下"), MB_OK);
break;
case WM_PAINT: //绘图
//绘图结构体
hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 100, 100, TEXT("hello"), strlen("hello"));
EndPaint(hwnd, &ps);
break;
default:
break;
}
//返回值用默认处理方式
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
//程序入口函数
//WINAPI 代表__stdcall参数的传递顺序:从右到左 一次入栈,并且在函数返回前 清空堆栈
int WINAPI WinMain(
HINSTANCE hInstance, //应用程序实例句柄
HINSTANCE hPrevInstance, //上一个应用程序句柄,在win32环境下,参数一般为NULL,不起作用了
LPSTR lpCmdLine, // char * argv[]
int nShowCmd) //显示命令 窗口 最大化、最小化、正常
{
//1、设计窗口
//2、注册窗口
//3、创建窗口
//4、显示和更新
//5、通过循环取消息
//6、处理消息(窗口过程)
//1、设计窗口
WNDCLASS wc;
wc.cbClsExtra = 0; //类的额外的内存
wc.cbWndExtra = 0; //窗口额外的内存
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //设置背景
wc.hCursor = LoadCursorW(NULL, IDC_HAND); //设置光标 如果第一个参数为NULL,代表使用系统提供的光标
wc.hIcon = LoadIconW(NULL, IDI_ERROR); //图标 如果第一个参数为NULL,代表使用系统提供的图标
wc.hInstance = hInstance; //应用程序实例句柄 传入WinMain中的形参即可
wc.lpfnWndProc = WindowProc; //回调函数 窗口过程
wc.lpszClassName = TEXT("WIN"); //指定窗口类名称
wc.lpszMenuName = NULL; //菜单名称
wc.style = 0; //显示风格 0代表默认风格
//2、注册窗口类
RegisterClass(&wc);
//3、创建窗口
/*
lpClassName, 类名
lpWindowName, 标题名
dwStyle, WS_OVERLAPPEDWINDOW 风格
x, 显示坐标 CW_USEDEFAULT 使用默认值
y,
nWidth, 宽高
nHeight,
hWndParent, 父窗口 NULL
hMenu, 菜单 NULL
hInstance, 实例句柄 hInstance
lpParam 附加值 鼠标附加值 NULL
*/
HWND hwnd = CreateWindow(wc.lpszClassName,wc.lpszMenuName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
//4、显示和更新
ShowWindow(hwnd,SW_SHOWNORMAL);
UpdateWindow(hwnd);
//5、通过循环取消息
/*
HWND hwnd; 主窗口句柄
UINT message; 具体的消息名称
WPARAM wParam; 附加消息 键盘消息
LPARAM lParam; 附件消息 鼠标消息 左右键
DWORD time; 消息产生时间
POINT pt; 附加消息 鼠标消息 x y
*/
MSG msg;
while (GetMessage(&msg,NULL,0,0))
{
/*
_Out_ LPMSG lpMsg, 消息
_In_opt_ HWND hWnd, 捕获窗口 NULL代表捕获所有窗口
_In_ UINT wMsgFilterMin, 最小和最大的过滤的消息 一般填入0
_In_ UINT wMsgFilterMax 填0代表捕获所有的消息
*/
//if (GetMessage(&msg,NULL,0,0) == FALSE)
//{
// break;
//}
//翻译消息
TranslateMessage(&msg);
//不为false 则分发消息
DispatchMessage(&msg);
}
//6、处理窗口过程
return 0;
}