天天看点

Win32 窗口创建

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;
}
           

继续阅读