浅谈Windows API

尽管SEDF_JKHJKE这种变量定义形式很烂,但死磕一次。

Windows API中的窗口程序API

这篇博客主要是想简单写一写Windows API中关于图形窗口程序的部分。我认为图形窗口部分最核心的就是消息循环机制,虽然不知道内部如何实现,不知道内部是不是需要调度,消息队列可能就是最简单的FIFS(先到先服务的思想来处理消息)。

消息是什么消息

消息是I/O消息或者软件消息,这些消息是有编码的,比如按下键盘VK_XXX或者关闭程序VM_CLOSE这些,实际上这些消息都有一个唯一确定的ID,即它的编码。当消息被触发时,Windows会封装一个MSG对象,这个MSG对象里面至少有一个消息的编码ID,然后把这个MSG对象放入消息队列。当MSG对象排队到队头时,就会对此消息进行处理,进行处理的函数是消息回调函数(代码中的MyWinProc),这是自己定义的,需要你来对某些你所需要的消息进行特殊的处理。

这是不停地从消息队列队头取消息并分发处理

	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

这是处理消息时回调函数,根据不同的消息ID编码值做出不同的处理。

LRESULT CALLBACK MyWinProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
	switch (msg)
	{
	case WM_CLOSE:
		DestroyWindow(hwnd);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		break;
	}
	return DefWindowProc(hwnd, msg, wparam, lparam);
}

创建窗口

创建窗口毫不意外需要以下东西:

  • 窗口属性配置信息,即代码中的WNDCLASS
  • 创建函数,及代码中的CreateWindow

另外还需要以下东西:

  • 创建窗口前需要将窗口属性配置信息注册RegisterClass(&wndclass)
  • 创建完窗口之后需要将窗口显示ShowWindow(hwnd, SW_NORMAL)和开始更新UpdateWindow(hwnd)

代码

#include

LRESULT CALLBACK MyWinProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
	switch (msg)
	{
	case WM_CLOSE:
		DestroyWindow(hwnd);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		break;
	}
	return DefWindowProc(hwnd, msg, wparam, lparam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	WNDCLASS wndclass = {
		CS_HREDRAW | CS_VREDRAW,
		MyWinProc,
		0,
		0,
		hInstance,
		LoadIcon(NULL, IDI_APPLICATION),
		LoadCursor(NULL, IDC_ARROW),
		(HBRUSH)GetStockObject(GRAY_BRUSH),
		NULL,
		"wincls"
	};
	RegisterClass(&wndclass);
	HWND hwnd = CreateWindow("wincls", "我的窗口", WS_OVERLAPPEDWINDOW, 0, 0, 800, 600, NULL, NULL, NULL, NULL);
	ShowWindow(hwnd, SW_NORMAL);
	UpdateWindow(hwnd);
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return 0;
}

你可能感兴趣的:(C语言)