c语言 createwindow

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

CreateWindow 并不是 C 语言的标准库函数,它是 Windows API (Win32 API) 中的一个核心函数,专门用于在 Windows 操作系统上创建窗口,这个函数的使用与 C 语言本身无关,而是与 Windows 平台紧密绑定。

c语言 createwindow
(图片来源网络,侵删)

如果你想在 Linux、macOS 或其他操作系统上创建窗口,你需要使用它们各自的 API,X11、GTK、Qt 或 macOS 的 Cocoa API。


CreateWindow 函数简介

CreateWindow (以及更现代的 CreateWindowEx) 函数是 Win32 编程的基石,它的作用是在内存中创建一个窗口对象,然后将其注册到 Windows 系统中,使其在屏幕上可见,调用这个函数后,Windows 操作系统会负责管理这个窗口,包括绘制、处理用户输入(如点击、键盘输入)等。

函数原型

我们通常使用更强大的 CreateWindowEx 函数,它是 CreateWindow 的扩展版本。

HWND CreateWindowEx(
  DWORD     dwExStyle,    // 扩展窗口样式
  LPCSTR    lpClassName,  // 预注册的窗口类名
  LPCSTR    lpWindowName, // 窗口标题
  DWORD     dwStyle,      // 窗口样式
  int       X,            // 窗口左上角 x 坐标
  int       Y,            // 窗口左上角 y 坐标
  int       nWidth,       // 窗口宽度
  int       nHeight,      // 窗口高度
  HWND      hWndParent,   // 父窗口句柄
  HMENU     hMenu,        // 窗口菜单句柄
  HINSTANCE hInstance,    // 应用程序实例句柄
  LPVOID    lpParam       // 创建参数
);

返回值:

c语言 createwindow
(图片来源网络,侵删)
  • 如果函数成功,它会返回一个 HWND 类型的值,这是新创建窗口的句柄,你可以通过这个句柄来操作这个窗口(改变大小、发送消息、销毁它等)。
  • 如果函数失败,它会返回 NULL

参数详解:

  1. dwExStyle (扩展窗口样式):

    • 指定窗口的扩展样式,例如是否带有边框、是否在最顶层等。
    • 常用值:WS_EX_CLIENTEDGE (凹陷的边框), WS_EX_WINDOWEDGE (凸起的边框), WS_EX_TOPMOST (始终在最前)。
    • 如果不需要,通常设为 0
  2. lpClassName (窗口类名):

    • 这是一个字符串,指定了窗口的“模板”,Windows 通过这个名称来查找如何创建这个窗口(包括窗口过程函数、图标、鼠标样式等)。
    • 这个类名必须是预先注册的,通过 RegisterClassEx 函数,你也可以使用系统预定义的类名,如 "BUTTON", "EDIT", "STATIC""EDIT",但创建主窗口时,你必须使用自己注册的类名。
  3. lpWindowName (窗口标题):

    c语言 createwindow
    (图片来源网络,侵删)
    • 栏上显示的文本。
    • "我的第一个窗口"
  4. dwStyle (窗口样式):

    • 定义窗口的基本外观和行为。
    • 常用值:
      • WS_OVERLAPPED: 带有标题栏和边框的顶层窗口。
      • WS_CAPTION: 有标题栏。
      • WS_SYSMENU: 有系统菜单(最大化、最小化、关闭按钮)。
      • WS_MINIMIZEBOX: 有最小化按钮。
      • WS_MAXIMIZEBOX: 有最大化按钮。
      • WS_SIZEBOX: 可调整大小。
      • WS_VISIBLE: 窗口创建后立即可见。
    • 这些样式可以用 (按位或) 组合起来,WS_OVERLAPPEDWINDOW 等于 WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX
  5. X, Y (窗口位置):

    • 窗口左上角在屏幕上的坐标。
    • 使用 CW_USEDEFAULT 可以让 Windows 自动选择一个默认位置。
  6. nWidth, nHeight (窗口大小):

    • 窗口的初始宽度和高度(以像素为单位)。
    • 使用 CW_USEDEFAULT 可以让 Windows 自动选择一个默认大小。
  7. hWndParent (父窗口句柄):

    • 如果创建的是子窗口,这里指定父窗口的句柄,对于主窗口,通常设为 NULL
  8. hMenu (菜单句柄):

    • 窗口的菜单句柄,对于主窗口,通常设为 NULL,或者指定一个资源中定义的菜单句柄。
  9. hInstance (应用程序实例句柄):

    • 当前应用程序的实例句柄,在 WinMain 函数中,这个值由系统传入,它告诉 Windows 这是哪个程序的实例。
  10. lpParam (创建参数):

    • 一个可选的指针,用于向窗口过程传递额外的创建数据,对于主窗口,通常设为 NULL

完整的 C 语言示例:创建一个简单的窗口

下面是一个完整的、可运行的 C 语言程序,它创建一个窗口并显示出来,这是学习 Win32 编程的 "Hello, World!"。

#include <windows.h> // 必须包含此头文件来使用 Windows API
// 1. 窗口过程函数的声明
// LRESULT 是一个 32 位或 64 位的整数类型,用于表示消息处理函数的返回值。
// CALLBACK 是一个调用约定,告诉编译器这个函数的参数如何传递。
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// 2. WinMain 函数:程序的入口点
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    // 窗口类名称
    const wchar_t* CLASS_NAME = L"MyMainWindowClass";
    // 3. 注册窗口类
    WNDCLASS wc = { };
    // 设置窗口类的各个属性
    wc.lpfnWndProc = WindowProc; // 指向窗口过程函数的指针
    wc.hInstance = hInstance;    // 应用程序实例句柄
    wc.lpszClassName = CLASS_NAME; // 窗口类名
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 加载标准箭头光标
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); // 设置背景为默认窗口颜色
    // 注册窗口类
    if (!RegisterClass(&wc)) {
        // 如果注册失败,弹出错误对话框并退出
        MessageBox(NULL, L"窗口类注册失败!", L"错误", MB_ICONERROR);
        return 1;
    }
    // 4. 创建窗口
    HWND hwnd = CreateWindowEx(
        0,                      // 扩展样式
        CLASS_NAME,             // 窗口类名
        L"我的第一个窗口",      // 窗口标题
        WS_OVERLAPPEDWINDOW,    // 窗口样式
        CW_USEDEFAULT, CW_USEDEFAULT, // 初始位置 (x, y)
        800, 600,               // 初始大小 (width, height)
        NULL,                   // 父窗口句柄
        NULL,                   // 菜单句柄
        hInstance,              // 应用程序实例句柄
        NULL                    // 创建参数
    );
    if (hwnd == NULL) {
        MessageBox(NULL, L"窗口创建失败!", L"错误", MB_ICONERROR);
        return 1;
    }
    // 5. 显示窗口
    // ShowWindow(hwnd, nCmdShow); // 使用 WinMain 传入的显示方式
    ShowWindow(hwnd, SW_SHOW); // 或者直接显示
    UpdateWindow(hwnd);         // 更新窗口客户区
    // 6. 消息循环
    MSG msg = { };
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg); // 翻译键盘消息
        DispatchMessage(&msg);  // 将消息发送到窗口过程函数
    }
    // 当 GetMessage 返回 0 时,程序退出
    return (int)msg.wParam;
}
// 7. 窗口过程函数:处理所有发送到该窗口的消息
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    switch (uMsg) {
        case WM_DESTROY: // 当窗口被销毁时(例如用户点击了关闭按钮)
            // 发送 WM_QUIT 消息,这将导致 GetMessage 函数返回 0,从而退出消息循环
            PostQuitMessage(0);
            return 0;
        case WM_PAINT: // 当窗口需要重绘时
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);
            // 在这里进行绘制操作
            // 绘制一段文本
            TextOut(hdc, 50, 50, L"你好,Windows 窗口世界!", 22);
            EndPaint(hwnd, &ps);
            return 0;
        }
    }
    // 对于我们没有处理的消息,调用 DefWindowProc 进行默认处理
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

如何编译和运行

  1. 保存代码:将上述代码保存为 main.c
  2. 编译:你需要一个 Windows 下的 C 编译器,Visual Studio 的 cl.exe 或者 MinGW 的 gcc。
    • 使用 MinGW (推荐初学者): 打开命令行(如 cmd 或 PowerShell),进入代码所在的目录,然后运行:
      gcc main.c -o myapp.exe
    • 使用 Visual Studio: 创建一个新的 "Windows 桌面应用程序" 项目,然后将代码粘贴进去,直接按 F5 编译运行。
  3. 运行:编译成功后,会生成 myapp.exe 文件,双击它,你就能看到一个标题为 "我的第一个窗口" 的窗口。
  1. 包含头文件#include <windows.h> 是使用 Win32 API 的前提。
  2. 定义窗口过程WindowProc 函数是窗口的“大脑”,它决定了窗口如何响应各种事件(如点击、关闭、重绘)。
  3. WinMain 入口:程序从这里开始。
  4. 注册窗口类:通过 WNDCLASS 结构体定义窗口的“蓝图”,并用 RegisterClass 将其告诉 Windows。
  5. 创建窗口:调用 CreateWindowEx,根据注册的“蓝图”在内存中创建一个窗口实例。
  6. 显示窗口ShowWindow 让窗口从内存变为可见,UpdateWindow 强制立即重绘一次。
  7. 消息循环:这是 Windows GUI 程序的核心。GetMessage 不断从消息队列中获取消息,TranslateMessageDispatchMessage 将其分发给 WindowProc 处理。
  8. 处理消息:在 WindowProc 中,使用 switch 语句处理不同的消息(如 WM_DESTROY 关闭窗口,WM_PAINT 绘制内容)。
  9. 默认处理:对于未处理的消息,调用 DefWindowProc 让系统执行默认操作。
-- 展开阅读全文 --
头像
dede sitemap绝对路径
« 上一篇 2025-12-23
c语言 shellexecute
下一篇 » 2025-12-23

相关文章

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

目录[+]