C语言创建MFC底层窗口
头文件:#include <windows.h>或者是#include <Windows.h> (单词首字母不区分大小写)
入口函数:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)(在 #include <WinBase.h>的913行)
WINAPI 代表 _stdcall 表示参数的传递顺序是从后往前传递
HINSTANCE hInstanc:应用程序实例句柄(handle :句柄 instance :实例)
HINSTANCE hPrevInstance:上一个应用程序实例句柄
第一步:设计窗口
①用到一个结构体:WNDCLASS 生成实例对象
WNDCLASS wc;//帮助文档查看WNDCLASS的的帮助文档可以获得成员属性的一些值
②设置各种属性
wc.cbClsExtra = 0;//类的额外内存(前缀 cb:count of byte)
wc.cbWndExtra = 0;//窗口的额外内存
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);//背景颜色 记住接口 GetStockObject 强制转换类型
wc.hCursor = LoadCursor(NULL, IDC_WAIT);//加载光标
wc.hIcon = LoadIcon(NULL, IDI_WARNING);//加载图标
wc.hInstance = hInstance;//应用程序的实例句柄
wc.lpfnWndProc = WindowProc;//(函数后面实现)这是一个长函数指针 前缀(lpfn)(long pointer functino process)
wc.lpszClassName = TEXT(“MFC的底层窗口”);//窗口的名字 前缀(lpsz)(long pointer string)
wc.lpszMenuName = NULL;//菜单名 没有菜单
wc.style = 0;//表示系统默认的风格
第二步:注册窗口
函数:RegisterClass(&wc);
直接调用这个函数进行注册
第三步:创建窗口
函数:CreateWindow()
函数的参数解释:
lpClassName,//类名
lpWindowName,//窗口名
dwStyle,//风格WS_OVERLAPPEDWINDOW正常的风格
x,//横坐标CW_USEDEFAULT使用默认值
y,//纵坐标
nWidth,//窗口宽度
nHeight,//窗口高度
hWndParent,//父窗口
hMenu,//菜单
hInstance,//实例句柄
lpParam//附加值 一般是鼠标附加值
第四步:窗口的显示和更新
函数://显示
ShowWindow(hwnd, SW_SHOWNORMAL);//正常显示
//更新
UpdateWindow(hwnd);
直接调用这两个函数
第五步:通过循环获取消息
函数:GetMessage(第二个参数为NULL的时候表示接受所有窗口的消息)
TranslateMessage//翻译消息
DispatchMessage//分发消息
第六步:窗口过程(操作系统回调函数)
调用窗口过程函数
LRESULT CALLBACK WindowProc(
In HWND hwnd, //消息所属窗口的句柄
In UINT uMsg, // 具体的小熊
In WPARAM wParam,//键盘的附加消息
In LPARAM lParam //鼠标的附加消息
)
windows操作系统处理消息的机制
1)操作系统接收到应用程序的窗口消息,将消息投递到该应用程序的消息队列中
2)应用程序在消息循环中调用GetMessage函数从消息队列中取出一条条的消息。取出后,以对消息进行一些预处理,如放弃对某些消息的响应,或者调用TranslateMessage产生新的消息
3)应用程序调用DispatchMessage,将消息回传给操作系统。消息是由MSG结构体对象来表示的,其中就包含了接收消息的窗口的句柄。因此,DispatchMessage函数总能进行正确的传递
4)系统利用WNDCLASS结构体的lpfnWndProc成员保存的窗口过程函数的指针调用窗口过程,对消息进行处理(即“系统给应用程序发送了消息”)。
注意:消息调用的是window结尾的函数是消息不进入应用程序消息队列中,由操作系统直接调用
代码
#include <Windows.h>
#include <Windowsx.h>
LRESULT CALLBACK WindowProc(
_In_ HWND hwnd, //消息所属窗口的句柄
_In_ UINT uMsg, // 具体的小熊
_In_ WPARAM wParam,//键盘的附加消息
_In_ LPARAM lParam //鼠标的附加消息
)
{
switch (uMsg)
{
case WM_CLOSE://关闭窗口
DestroyWindow(hwnd);//发送另一个消息
//以Window结尾的函数由操作系统直接回调
break;
case WM_DESTROY://关闭程序
PostQuitMessage(0);
break;
case WM_LBUTTONDOWN:
{
int xPos = GET_X_LPARAM(lParam);
int yPos = GET_Y_LPARAM(lParam);
char buf[1024];
wsprintf(buf, TEXT("x = %d,y = %d"), xPos, yPos);
MessageBox(hwnd, buf, TEXT("按下左键"), MB_OK);
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
//1、设计窗口
WNDCLASS wc;//帮助文档查看WNDCLASS的的帮助文档可以获得成员属性的一些值
wc.cbClsExtra = 0;//类的额外内存(前缀 cb:count of byte)
wc.cbWndExtra = 0;//窗口的额外内存
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//背景颜色 记住接口 GetStockObject 强制转换类型
wc.hCursor = LoadCursor(NULL, IDC_ARROW);//加载光标
wc.hIcon = LoadIcon(NULL, IDI_WARNING);//加载图标
wc.hInstance = hInstance;//应用程序的实例句柄
wc.lpfnWndProc = WindowProc;//这是一个长函数指针前缀(lpfn)(long pointer functino process)
wc.lpszClassName = TEXT("MFC");//窗口的名字 这是一个长字符串指针 前缀(lpsz)(long pointer string)
wc.lpszMenuName = NULL;//菜单名 没有菜单
wc.style = 0;//表示系统默认的风格
//注册窗口
RegisterClass(&wc);
//创建窗口
HWND hwnd = CreateWindow(wc.lpszClassName, TEXT("MFC底层窗口"), WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
/*
lpClassName,//类名
lpWindowName,//窗口名
dwStyle,//风格WS_OVERLAPPEDWINDOW正常的风格
x,//横坐标CW_USEDEFAULT使用默认值
y,//纵坐标
nWidth,//窗口宽度
nHeight,//窗口高度
hWndParent,//父窗口
hMenu,//菜单
hInstance,//实例句柄
lpParam//附加值 一般是鼠标附加值
*/
//显示和更新窗口
//显示
ShowWindow(hwnd, SW_SHOWNORMAL);//正常显示
//更新
UpdateWindow(hwnd);
//循环获取消息
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))//第二个参数为NULL表示接受所有窗口的消息
{
TranslateMessage(&msg);//翻译消息
DispatchMessage(&msg);//分发消息
}
return 0;
}