C++ 创建一个窗口采用GDI的方式绘制文字

跟Winform和WPF不太一样的创建方式,是基于Windows 系统API的方式,这也是Windows系统编程的一部分,这种方式很底层了算是。

创建项目

windows 桌面向导

直接创建

创建main.cpp

#include <windows.h>

//定义窗口宽度
int WINDOW_WIDTH = 800;
//定义当前文本绘制的宽度位置
int CurrentWidth = 0;
// 窗口过程函数声明
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

// 程序入口点
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
	// 1. 注册窗口类
	const wchar_t CLASS_NAME[] = L"Sample Window Class";

	WNDCLASS wc = { 0 };
	wc.lpfnWndProc = WindowProc;    // 窗口过程函数
	wc.hInstance = hInstance;     // 实例句柄
	wc.lpszClassName = CLASS_NAME;    // 窗口类名
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); // 背景色

	RegisterClass(&wc);

	// 2. 创建窗口
	HWND hwnd = CreateWindowEx(
		0,                              // 扩展样式
		CLASS_NAME,                     // 窗口类名
		L"我的第一个窗口",               // 窗口标题
		WS_OVERLAPPEDWINDOW,            // 窗口样式(带标题栏、边框、最大化/最小化按钮)

		// 窗口位置和大小
		CW_USEDEFAULT, CW_USEDEFAULT,   // 初始x、y坐标(使用默认值)
		WINDOW_WIDTH, 600,                       // 宽度和高度

		NULL,       // 父窗口句柄
		NULL,       // 菜单句柄
		hInstance,  // 实例句柄
		NULL        // 附加数据
	);

	if (hwnd == NULL)
	{
		return 0; // 创建窗口失败
	}

	// 3. 显示窗口
	ShowWindow(hwnd, nCmdShow);

	// 4. 消息循环
	MSG msg = { 0 };
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);  // 翻译键盘消息
		DispatchMessage(&msg);   // 分发消息到窗口过程
	}

	return 0;
}

// 窗口过程(处理窗口消息)
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
		case WM_CREATE:
			// 设置1秒定时器(ID为1)
			SetTimer(hwnd, 1, 1000, NULL);
			break;
		case WM_TIMER:
			// 定时器触发(wParam 为定时器ID,这里判断是否是我们设置的ID=1)
			if (wParam == 1) {
				CurrentWidth += 10;
				if (CurrentWidth >= (WINDOW_WIDTH -10))//如果宽度超过窗口宽度,重置为0
				{
					CurrentWidth = 0;
				}
				// 每1秒触发一次重绘(标记整个客户区无效)
				InvalidateRect(hwnd, NULL, TRUE);
			}
			break;
		case WM_DESTROY:
			PostQuitMessage(0);  // 窗口关闭时发送退出消息
			return 0;

		case WM_PAINT:// 绘制窗口内容
		{
			PAINTSTRUCT ps;
			HDC hdc = BeginPaint(hwnd, &ps);

			// 绘制背景
			FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 1));

			// 绘制文本
			const wchar_t text[] = L"Hello, Win32!";
			TextOut(hdc, CurrentWidth, 50, text, wcslen(text));

			EndPaint(hwnd, &ps);
			return 0;
		}
	}

	// 处理未定义的消息(使用默认处理)
	return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

运行一下结果如下:

函数分析

其中最主要的就是CreateWindowEx创建窗口这个函数,除了ShowWindow显示窗口,还有SetWindowPos可以更加自定义的显示窗口(比如不能缩小方法等)

消息循环这一块除了阻塞获取消息的GetMessage实际上还可以用另外一个函数 PeekMessage 无阻塞的获取窗口消息

另外使用了一个定时为1秒的定时器 SetTimer(hwnd, 1, 1000, NULL); 它会每一秒触发窗口消息 WM_TIMER 类型

还有就是GDI的绘制函数部分 BeginPaint和 EndPaint.

逻辑分析

整体逻辑简单,创建一个窗口,然后,消息循环(维持消息泵)不让应用退出除非收到退出的窗口消息(比如点击X或者Ctrl+F4),然后,每一秒让窗体显示的文字移动10像素,移动到窗体最右侧就从头开始.

总结

一个最简单的C++窗口示例,细节实际上很多,用来学习基础WINApi还不错.

git仓库

https://github.com/kesshei/direct9Demo
https://gitee.com/kesshei/direct9Demo
posted @ 2025-10-16 18:13  蓝创精英团队  阅读(15)  评论(0)    收藏  举报  来源