初识Win32

一、Windows窗口的创建过程

1.定义WinMain函数

int CALLBACK WinMain(
    _In_  HINSTANCE hInstance,
    _In_  HINSTANCE hPrevInstance,
    _In_  LPSTR lpCmdLine,
    _In_  int nCmdShow
  )

WinMain函数是窗口程序的入口函数(类似于main函数),WinMain的第一个参数是当前应用程序的实例句柄,第二个参数是前一个实例,第三个参数是命令行参数,最后一个参数是主窗口显示方式。

2.设计并注册窗口类

typedef struct _WNDCLASS {
UINT style;// 窗口类的风格
WNDPROC lpfnWndProc;//窗口处理函数
int cbClsExtra;//窗口扩展
int cbWndExtra;//窗口实例扩展
HINSTANCE hInstance;//实例句柄
HICON hIcon;//窗口的最小化图标
HCURSOR hCursor;//窗口鼠标光标
HBRUSH hbrBackground;//窗口背景色
LPCTSTR lpszMenuName;//窗口菜单
LPCTSTR lpszClassName;// 窗口类名
} WNDCLASS, *LPWNDCLASS;

以上是窗口类的定义,用法如下

int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns, LPSTR lpCmd, int nCmdShow)
{   
    WNDCLASS wc = { 0 };
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wc.hCursor = NULL;
	wc.hIcon = NULL;
	wc.hInstance = hIns;
	wc.lpfnWndProc = WndProc;//窗口处理函数
	wc.lpszClassName = "Main";//窗口类名
	wc.lpszMenuName = NULL;//菜单
    wc.style = CS_HREDRAW | CS_VREDRAW;//窗口类的风格
}

示例中,将创建的窗口的hInstance = hIns,意思是将当前程序的实例句柄赋值给该窗口,窗口处理函数WndProc是个回调函数,稍后会讲解,wc.style = CS_HREDRAW | CS_VREDRAW,从名字就看出来了,就是同时具备水平重画和垂直重画。因为当我们的窗口显示的时候,被其他窗口挡住后重新显示,或者大小调整后,窗口都要发生绘制,就像我们在纸上涂鸦一样,每次窗口的变化都会“粉刷”一遍,并发送WM_PAINT消息。

窗口类设计完成后,不要忘了向系统注册,这样系统才能知道有这个窗口类的存在。向操作系统注册窗口类,使用RegisterClass函数,它的参数就是一个指向WNDCLASS结构体的指针,所以我们传递的时候,要加上&符号。

RegisterClass(&wc);//将以上所有赋值全部写入操作系统

3.创建并显示窗口

	// 创建窗口
	HWND hwnd = CreateWindow(
		cls_Name,			//类名,要和刚才注册的一致
		L"我的应用程序",			//窗口标题文字
		WS_OVERLAPPEDWINDOW, 		//窗口外观样式
		100,				//窗口相对于父级的X坐标
		100,				//窗口相对于父级的Y坐标
		500,				//窗口的宽度
		500,				//窗口的高度
		NULL,				//没有父窗口,为NULL
		NULL,				//没有菜单,为NULL
		hInstance,			//当前应用程序的实例句柄
		NULL);				//没有附加数据,为NULL
	if(hwnd == NULL) 				//检查窗口是否创建成功
		return 0;

WS_OVERLAPPEDWINDOW,msdn中解释为Creates an overlapped window with the WS_OVERLAPPEDWS_CAPTIONWS_SYSMENUWS_THICKFRAMEWS_MINIMIZEBOX, and WS_MAXIMIZEBOX styles.也就是说WS_OVERLAPPEDWINDOW可以创建一个拥有各种窗口风格的窗体,包括标题,系统菜单,边框,最小化和最大化按钮等。

窗口创建后,就要显示它,用ShowWindow函数

ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);//可选,更新窗口

SW_SHOW表示以当前大小激活运行后的程序窗口并显示它。 

4.消息循环

当程序运行的时候,会不断产生新的信号,例如,按下鼠标左键会产生WM_LBUTTONDOWN的信号,我们需要对产生的信号不断用GetMessage获取到然后处理

  BOOL WINAPI GetMessage(
    _Out_     LPMSG lpMsg,
    _In_opt_  HWND hWnd,
    _In_      UINT wMsgFilterMin,
    _In_      UINT wMsgFilterMax
  );

 第一个参数是一个指向MSG结构的指针。第二个参数是句柄,通常我们用NULL,因为我们会捕捉整个应用程序的消息。后面两个参数是用来过滤消息的,指定哪个范围内的消息我接收,在此范围之外的消息我拒收,如果不过滤就全设为0.。用法如下:

//消息循环
	MSG nMsg = { 0 };
	while (GetMessage(&nMsg, NULL, 0, 0)) {
		TranslateMessage(&nMsg);
		DispatchMessage(&nMsg);//将消息交给窗口处理函数来处理
	}

死循环不断获取消息,用DispatchMessage函数将消息发给消息处理函数去处理,在这之前,当获取到消息时,对于键盘的大小写区分,还需要翻译一下,所以要 TranslateMessage。

5.消息响应

LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
{
	switch (msgID)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	}
	return DefWindowProc(hWnd, msgID, wParam, lParam);
}

当按下退出键,程序会退出,其余情况按默认处理。

完整代码如下:(编码方式采用多字节字符集)

#define _CRT_SECURE_NO_WARNINGS 1
#include<windows.h>

//窗口处理函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
{
	switch (msgID)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	}
	return DefWindowProc(hWnd, msgID, wParam, lParam);
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns, LPSTR lpCmd, int nCmdShow)
{
	hInstance = hIns;
	//注册窗口类
	WNDCLASS wc = { 0 };
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wc.hCursor = NULL;
	wc.hIcon = NULL;
	wc.hInstance = hIns;
	wc.lpfnWndProc = WndProc;//窗口处理函数
	wc.lpszClassName = "Main";//窗口类名
	wc.lpszMenuName = NULL;//菜单
	wc.style = CS_HREDRAW | CS_VREDRAW;//窗口类的风格
	RegisterClass(&wc);//将以上所有赋值全部写入操作系统
	//在内存创建窗口
	HWND hWnd = CreateWindow("Main", "window", WS_OVERLAPPEDWINDOW, 100, 100, 500, 500, NULL, NULL, hIns, NULL);

	//显示窗口
	ShowWindow(hWnd, SW_SHOW);
	UpdateWindow(hWnd);//可选

	//消息循环
	MSG nMsg = { 0 };
	while (GetMessage(&nMsg, NULL, 0, 0)) {
		TranslateMessage(&nMsg);
		DispatchMessage(&nMsg);//将消息交给窗口处理函数来处理
	}
	return 0;

}

二、字符串

在开发过程中,由于字符串的编码方式不同(ANSI,UNICODE),会导致每隔字符所占的大小不同,对应的字符串处理函数也不同。下面是一些常用字符串处理函数:

字符串长度:
● Ansi:strlen(char *str);
● Unicode:wcslen(wchar_t *str);
● 通用函数:_tcslen(TCHAR *str);

字符串转成数字

● Ansi:int atoi(const char *str);
● Unicode:int _wtoi(const wchar_t *str);
● 通用函数:_tstoi(const TCHAR *str);

字符串拷贝:
● Ansi:strcpy(char *strDestination, const char *strSource);
● Unicode:wcscpy(wchar_t *strDestination, const wchar_t *strSource);
● 通用函数:_tcscpy(TCHAR *strDestination, const TCHAR *strSource);


目录

文章目录

一、Windows窗口的创建过程

1.定义WinMain函数

2.设计并注册窗口类

3.创建并显示窗口

4.消息循环

5.消息响应

二、字符串


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值