这篇指南将从基础到进阶,覆盖以下几个方面:

(图片来源网络,侵删)
- 准备工作:安装编译器和开发环境
- 第一个 Windows 程序:
Hello, World!(控制台版) - 核心概念:Windows 程序的骨架 (WinMain)
- 图形界面入门:创建一个窗口
- 深入窗口过程:处理用户输入
- 常用 Windows API 介绍
- 推荐学习资源和进阶方向
准备工作:安装编译器和开发环境
在 Windows 上写 C 程序,你需要两个东西:
- 编译器:将你写的 C 代码转换成可执行文件 (.exe) 的工具。
- 集成开发环境:一个集成了代码编辑、编译、调试等功能的软件,能让开发更高效。
推荐方案
Visual Studio (最推荐,功能最全)
这是微软官方的旗舰级 IDE,对 Windows 开发支持最好,也是初学者的首选。
- 下载:访问 Visual Studio 官网。
- 安装:下载 "Community" 社区版(免费),在安装程序中,确保勾选 “使用 C++ 的桌面开发” 这个工作负载,它会自动为你安装 C/C++ 编译器、Windows SDK(软件开发工具包)以及强大的 Visual Studio IDE。
- 创建项目:
- 打开 Visual Studio。
- 选择 “创建新项目”。
- 搜索并选择 “Windows 控制台应用” 或 “空项目” (对于更底层的 Win32 开发)。
MinGW-w64 + VS Code (轻量级,跨平台)

(图片来源网络,侵删)
如果你喜欢轻量级的编辑器,或者想在同一个环境下编写跨平台代码,这是一个很好的选择。
- 安装编译器:下载并安装 MSYS2,MSYS2 是一个强大的软件环境和构建平台,它包含了 MinGW-w64 编译器。
- 安装 MSYS2 后,打开它,按照提示更新系统核心包。
- 然后安装编译器套件:在 MSYS2 终端中运行
pacman -S --needed base-devel mingw-w64-ucrt-x86_64-toolchain。
- 安装 VS Code:从 VS Code 官网 下载并安装。
- 配置 VS Code:
- 安装 C/C++ 扩展 (由 Microsoft 发布)。
- 安装 Code Runner 扩展 (可以一键编译运行代码)。
- 配置编译器路径:在 VS Code 的设置中,找到 "compiler path",并指向你安装的 MinGW-w64 中的
gcc.exe(C:\msys64\ucrt64\bin\gcc.exe)。
第一个 Windows 程序:Hello, World! (控制台版)
在深入学习 Win32 API 之前,我们先写一个最熟悉的控制台程序,这能让你确认环境配置正确。
// hello_console.c
#include <stdio.h> // 标准输入输出库
int main() {
printf("Hello, Windows Console World!\n");
return 0;
}
- 如何编译和运行 (在 Visual Studio 中):
- 创建一个 "Windows 控制台应用" 项目。
- 将上面的代码复制到
main.c文件中。 - 按
Ctrl + F5直接运行,或者点击 "本地 Windows 调试器"。
- 如何编译和运行 (在 MinGW-w64 + VS Code 中):
- 创建一个
.c文件,粘贴代码。 - 按
Ctrl + Alt + N(如果安装了 Code Runner),它会自动编译运行。 - 或者在终端中手动编译:
gcc hello_console.c -o hello_console.exe,然后运行hello_console.exe。
- 创建一个
核心概念:Windows 程序的骨架 (WinMain)
标准的 C 程序从 main 函数开始,但 Windows GUI 程序的入口点是一个叫做 WinMain 的函数。
// skeleton.c
#include <windows.h> // Windows API 的头文件,必须包含!
// 窗口过程函数的声明
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// WinMain 是 Windows GUI 程序的入口点
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
// ... 程序主逻辑 ...
return 0;
}
// 窗口过程函数的定义
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
// ... 处理各种消息 ...
return DefWindowProc(hwnd, uMsg, wParam, lParam); // 默认处理
}
关键参数解释:
HINSTANCE hInstance:当前实例的句柄,可以理解为你的程序在内存中的“身份证”。LPSTR lpCmdLine:命令行参数,类似于main函数中的argv。int nCmdShow:指定窗口如何显示(正常显示、最大化、最小化)。HWND:Handle to a WiNDow,窗口句柄,Windows 中几乎 everything(窗口、按钮、图标、字体等)都是一个对象,程序通过句柄来操作它们。HINSTANCE:Handle to an INSTance,实例句柄。LRESULT:窗口过程函数的返回值类型。CALLBACK:一个宏,表示函数调用约定(__stdcall),这是 Windows API 的要求。WindowProc:这是窗口的“消息处理中心”,操作系统会把用户的各种操作(如点击、按键、移动窗口)封装成消息,发送到这个函数。
图形界面入门:创建一个窗口
创建一个窗口并显示出来,需要调用一系列 Windows API 函数,这个过程是固定的,你需要记住它。
#include <windows.h>
// 窗口过程函数
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
// 1. 注册窗口类
WNDCLASS wc = {0};
wc.lpfnWndProc = WindowProc; // 窗口过程函数地址
wc.hInstance = hInstance;
wc.lpszClassName = "MyMainWindowClass"; // 窗口类名
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 加载标准箭头光标
if (!RegisterClass(&wc)) {
MessageBox(NULL, "Window Registration Failed!", "Error", MB_ICONERROR);
return 0;
}
// 2. 创建窗口
HWND hwnd = CreateWindowEx(
0, // 可选的扩展样式
"MyMainWindowClass", // 窗口类名
"My First Window", // 窗口标题
WS_OVERLAPPEDWINDOW, // 窗口样式
CW_USEDEFAULT, CW_USEDEFAULT, // x, y 位置 (让系统决定)
800, 600, // 宽度, 高度
NULL, // 父窗口句柄
NULL, // 菜单句柄
hInstance, // 实例句柄
NULL // 额外创建参数
);
if (hwnd == NULL) {
MessageBox(NULL, "Window Creation Failed!", "Error", MB_ICONERROR);
return 0;
}
// 3. 显示和更新窗口
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// 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_DESTROY: // 当窗口被销毁时(比如用户点击了 'X' 按钮)
PostQuitMessage(0); // 发送一个 WM_QUIT 消息,使 GetMessage 返回 0
return 0;
// 可以在这里添加对其他消息的处理,如 WM_PAINT, WM_LBUTTONDOWN 等
}
// 如果我们没有处理这个消息,就交给系统默认处理
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
代码步骤解析:
- 注册窗口类 (
RegisterClass):在创建窗口前,必须先“注册”一个窗口类,这个类定义了窗口的“性格”,比如它由哪个函数来处理消息,使用什么图标,光标样式是什么。 - 创建窗口 (
CreateWindowEx):使用已注册的窗口类来创建一个具体的窗口实例,这个函数返回一个窗口句柄HWND,后续所有对窗口的操作都通过它进行。 - 显示和更新窗口 (
ShowWindow,UpdateWindow):窗口创建后默认是不可见的。ShowWindow让它显示出来,UpdateWindow立即重绘窗口内容。 - 消息循环 (
GetMessage,TranslateMessage,DispatchMessage):这是 Windows 程序的核心,程序会在这里循环等待,直到收到WM_QUIT消息(通常由PostQuitMessage发送)才会退出。GetMessage从消息队列中取出消息,DispatchMessage将消息发送给对应的WindowProc函数处理。
深入窗口过程:处理用户输入
让我们让窗口对用户的点击做出反应,我们修改 WindowProc 函数,处理 WM_PAINT 和 WM_LBUTTONDOWN 消息。
// 在 WindowProc 函数的 switch 语句中添加以下 case
case WM_PAINT: // 当窗口需要重绘时(如首次显示、被遮挡后重新显示)
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps); // 获取设备上下文句柄,用于绘图
// 绘制一些文本
TextOut(hdc, 50, 50, "Hello, Graphics World!", 23);
// 绘制一个矩形
Rectangle(hdc, 100, 100, 200, 200);
EndPaint(hwnd, &ps); // 结束绘图
return 0;
}
case WM_LBUTTONDOWN: // 当鼠标左键在窗口内被按下时
{
char buffer[100];
sprintf_s(buffer, "Mouse clicked at: (%d, %d)", LOWORD(lParam), HIWORD(lParam));
MessageBox(hwnd, buffer, "Mouse Click", MB_OK);
return 0;
}
WM_PAINT:这是最重要的消息之一,每当窗口内容需要被刷新时,系统就会发送这个消息,你必须处理它,否则窗口可能会一片空白。BeginPaint和EndPaint是配对使用的,用于获取和释放绘图资源。WM_LBUTTONDOWN:鼠标左键按下事件。lParam参数包含了鼠标点击的坐标信息。LOWORD/HIWORD:宏,用于从 32 位的lParam中提取低 16 位(X坐标)和高 16 位(Y坐标)。
常用 Windows API 介绍
Windows API 庞大无比,但有一些是经常用到的:
| 分类 | 常用函数 | 功能描述 |
|---|---|---|
| 窗口管理 | CreateWindowEx |
创建窗口 |
ShowWindow |
显示/隐藏窗口 | |
MoveWindow |
移动/调整窗口大小 | |
DestroyWindow |
销毁窗口 | |
GetWindowText |
获取窗口标题 | |
| 消息处理 | GetMessage |
从消息队列获取消息 |
PeekMessage |
查看(但不移除)消息队列中的消息 | |
DispatchMessage |
分发消息到窗口过程 | |
PostMessage |
将消息放入消息队列(异步) | |
SendMessage |
直接调用窗口过程(同步) | |
| 绘图 | GetDC / ReleaseDC |
获取/释放设备上下文 |
BeginPaint / EndPaint |
开始/结束绘制(用于 WM_PAINT) |
|
TextOut |
绘制文本 | |
Rectangle |
绘制矩形 | |
Ellipse |
绘制椭圆 | |
BitBlt |
位块传输(用于图像复制) | |
| 控件 | CreateWindow |
创建标准控件(按钮、编辑框等) |
GetDlgItem |
通过 ID 获取控件句柄 | |
SetWindowText |
设置控件文本 | |
GetWindowText |
获取控件文本 | |
| 资源 | LoadIcon |
加载图标 |
LoadCursor |
加载光标 | |
LoadBitmap |
加载位图 | |
LoadImage |
通用图像加载函数 |
推荐学习资源和进阶方向
学习资源
- Charles Petzold 的《Windows 程序设计》:这本书被誉为 Windows 开发的“圣经”,非常经典,讲解细致入微,适合从头学起。
- 微软官方文档:最权威、最及时的参考资料,搜索 "Windows API reference" 即可找到。
- 在线教程:有很多优秀的 YouTube 频道和博客网站提供 Windows API 的视频和图文教程。
进阶方向
- MFC (Microsoft Foundation Classes):微软对 Win32 API 的一层 C++ 封装,使用面向对象的方式简化开发,虽然现在项目变少,但学习它有助于理解框架设计思想。
- .NET WinForms / WPF / UWP:使用 C# 和 .NET 框架进行 Windows 开发,开发效率更高,是现代 Windows 应用开发的主流方向之一。
- DirectX / OpenGL:如果你对游戏开发、图形渲染感兴趣,学习这些图形 API 是必经之路。
- COM (Component Object Model):Windows 的组件对象模型,是许多高级技术(如 ActiveX, DirectShow)的基础,理解它能让你对 Windows 底层有更深的认识。
在 Windows 上用 C 语言编程,就是围绕 句柄 和 消息 这两个核心概念展开的。
- 句柄 是你操作 Windows 对象(窗口、文件、画笔等)的钥匙。
- 消息 是 Windows 通知你发生事件的机制。
从 WinMain 开始,通过注册类、创建窗口、进入消息循环,到在 WindowProc 中响应各种消息,构成了一个标准 Windows GUI 程序的生命周期,虽然这个过程比简单的控制台程序复杂,但它为你打开了构建功能强大、界面丰富的桌面应用的大门,祝你学习顺利!
