windows c语言编程

99ANYc3cd6
预计阅读时长 29 分钟
位置: 首页 C语言 正文

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

windows c语言编程
(图片来源网络,侵删)
  1. 准备工作:安装编译器和开发环境
  2. 第一个 Windows 程序:Hello, World! (控制台版)
  3. 核心概念:Windows 程序的骨架 (WinMain)
  4. 图形界面入门:创建一个窗口
  5. 深入窗口过程:处理用户输入
  6. 常用 Windows API 介绍
  7. 推荐学习资源和进阶方向

准备工作:安装编译器和开发环境

在 Windows 上写 C 程序,你需要两个东西:

  • 编译器:将你写的 C 代码转换成可执行文件 (.exe) 的工具。
  • 集成开发环境:一个集成了代码编辑、编译、调试等功能的软件,能让开发更高效。

推荐方案

Visual Studio (最推荐,功能最全)

这是微软官方的旗舰级 IDE,对 Windows 开发支持最好,也是初学者的首选。

  1. 下载:访问 Visual Studio 官网
  2. 安装:下载 "Community" 社区版(免费),在安装程序中,确保勾选 “使用 C++ 的桌面开发” 这个工作负载,它会自动为你安装 C/C++ 编译器、Windows SDK(软件开发工具包)以及强大的 Visual Studio IDE。
  3. 创建项目
    • 打开 Visual Studio。
    • 选择 “创建新项目”。
    • 搜索并选择 “Windows 控制台应用” 或 “空项目” (对于更底层的 Win32 开发)。

MinGW-w64 + VS Code (轻量级,跨平台)

windows c语言编程
(图片来源网络,侵删)

如果你喜欢轻量级的编辑器,或者想在同一个环境下编写跨平台代码,这是一个很好的选择。

  1. 安装编译器:下载并安装 MSYS2,MSYS2 是一个强大的软件环境和构建平台,它包含了 MinGW-w64 编译器。
    • 安装 MSYS2 后,打开它,按照提示更新系统核心包。
    • 然后安装编译器套件:在 MSYS2 终端中运行 pacman -S --needed base-devel mingw-w64-ucrt-x86_64-toolchain
  2. 安装 VS Code:从 VS Code 官网 下载并安装。
  3. 配置 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 中)
    1. 创建一个 "Windows 控制台应用" 项目。
    2. 将上面的代码复制到 main.c 文件中。
    3. Ctrl + F5 直接运行,或者点击 "本地 Windows 调试器"。
  • 如何编译和运行 (在 MinGW-w64 + VS Code 中)
    1. 创建一个 .c 文件,粘贴代码。
    2. Ctrl + Alt + N (如果安装了 Code Runner),它会自动编译运行。
    3. 或者在终端中手动编译: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:指定窗口如何显示(正常显示、最大化、最小化)。
  • HWNDHandle to a WiNDow,窗口句柄,Windows 中几乎 everything(窗口、按钮、图标、字体等)都是一个对象,程序通过句柄来操作它们。
  • HINSTANCEHandle 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);
}

代码步骤解析:

  1. 注册窗口类 (RegisterClass):在创建窗口前,必须先“注册”一个窗口类,这个类定义了窗口的“性格”,比如它由哪个函数来处理消息,使用什么图标,光标样式是什么。
  2. 创建窗口 (CreateWindowEx):使用已注册的窗口类来创建一个具体的窗口实例,这个函数返回一个窗口句柄 HWND,后续所有对窗口的操作都通过它进行。
  3. 显示和更新窗口 (ShowWindow, UpdateWindow):窗口创建后默认是不可见的。ShowWindow 让它显示出来,UpdateWindow 立即重绘窗口内容。
  4. 消息循环 (GetMessage, TranslateMessage, DispatchMessage):这是 Windows 程序的核心,程序会在这里循环等待,直到收到 WM_QUIT 消息(通常由 PostQuitMessage 发送)才会退出。GetMessage 从消息队列中取出消息,DispatchMessage 将消息发送给对应的 WindowProc 函数处理。

深入窗口过程:处理用户输入

让我们让窗口对用户的点击做出反应,我们修改 WindowProc 函数,处理 WM_PAINTWM_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:这是最重要的消息之一,每当窗口内容需要被刷新时,系统就会发送这个消息,你必须处理它,否则窗口可能会一片空白。BeginPaintEndPaint 是配对使用的,用于获取和释放绘图资源。
  • 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 通用图像加载函数

推荐学习资源和进阶方向

学习资源

  1. Charles Petzold 的《Windows 程序设计》:这本书被誉为 Windows 开发的“圣经”,非常经典,讲解细致入微,适合从头学起。
  2. 微软官方文档:最权威、最及时的参考资料,搜索 "Windows API reference" 即可找到。
  3. 在线教程:有很多优秀的 YouTube 频道和博客网站提供 Windows API 的视频和图文教程。

进阶方向

  1. MFC (Microsoft Foundation Classes):微软对 Win32 API 的一层 C++ 封装,使用面向对象的方式简化开发,虽然现在项目变少,但学习它有助于理解框架设计思想。
  2. .NET WinForms / WPF / UWP:使用 C# 和 .NET 框架进行 Windows 开发,开发效率更高,是现代 Windows 应用开发的主流方向之一。
  3. DirectX / OpenGL:如果你对游戏开发、图形渲染感兴趣,学习这些图形 API 是必经之路。
  4. COM (Component Object Model):Windows 的组件对象模型,是许多高级技术(如 ActiveX, DirectShow)的基础,理解它能让你对 Windows 底层有更深的认识。

在 Windows 上用 C 语言编程,就是围绕 句柄消息 这两个核心概念展开的。

  • 句柄 是你操作 Windows 对象(窗口、文件、画笔等)的钥匙。
  • 消息 是 Windows 通知你发生事件的机制。

WinMain 开始,通过注册类、创建窗口、进入消息循环,到在 WindowProc 中响应各种消息,构成了一个标准 Windows GUI 程序的生命周期,虽然这个过程比简单的控制台程序复杂,但它为你打开了构建功能强大、界面丰富的桌面应用的大门,祝你学习顺利!

-- 展开阅读全文 --
头像
dede 后台添加会员
« 上一篇 03-23
dede 整合 记事狗
下一篇 » 03-23

相关文章

取消
微信二维码
支付宝二维码

目录[+]