C语言创建windows窗口实例

下面是关于C语言创建Windows窗口实例的完整攻略,分为以下几个步骤:

1. 引入必要的头文件

首先我们需要在程序中引入必要的头文件,包括Windows.h和tchar.h。这些头文件在使用Windows API时必须被包含,以便于调用其中定义的函数和宏。

#include <windows.h>
#include <tchar.h>

2. 定义窗口过程函数

窗口过程函数是Windows程序中最重要的函数之一。它负责处理窗口的消息和事件,比如响应用户的鼠标和键盘操作,处理窗口的绘制,以及定时器等各种功能。

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }

    return 0;
}

3. 注册窗口类

在创建窗口实例之前,我们需要先注册一个窗口类。窗口类是Windows程序中用来描述窗口的一个数据结构,它包含了窗口的各种属性(如背景颜色、边框风格、菜单等)以及窗口过程函数的指针。

WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = nullptr;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));

if (!RegisterClassEx(&wcex))
{
    MessageBox(nullptr,
           _T("Call to RegisterClassEx failed!"),
           _T("Win32 Desktop App"),
           MB_ICONERROR);

    return 1;
}

这里我们定义了一个WNDCLASSEX结构体,设置了窗口类的各种属性,然后通过RegisterClassEx函数将窗口类注册到Windows系统中。

4. 创建窗口实例

窗口类注册成功后,我们就可以开始创建窗口实例了。创建窗口实例需要使用CreateWindowEx函数。这个函数的参数包括窗口类名、窗口标题、窗口样式、窗口位置和大小等信息,其中窗口位置和大小是可选的。

HWND hWnd = CreateWindowEx(
    WS_EX_CLIENTEDGE,
    szWindowClass,
    _T("Hello, World!"),
    WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, CW_USEDEFAULT,
    500, 500,
    nullptr,
    nullptr,
    hInstance,
    nullptr);

if (!hWnd)
{
    MessageBox(nullptr,
           _T("Call to CreateWindowEx failed!"),
           _T("Win32 Desktop App"),
           MB_ICONERROR);

    return 1;
}

这里我们通过CreateWindowEx函数创建了一个基本的窗口实例,并将其赋值给了hWnd变量,用于后续的操作。

5. 显示窗口实例和消息循环

窗口实例创建成功后,为了看到窗口,我们需要将其显示出来。这个可以通过ShowWindow函数实现。然后,我们需要进入消息循环,在程序窗口未关闭之前,程序都会不断地循环接收消息,处理消息,再接收消息,处理消息的过程。

ShowWindow(hWnd,
    nCmdShow);
UpdateWindow(hWnd);

// Main message loop:
MSG msg;
while (GetMessage(&msg, nullptr, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

return (int) msg.wParam;

这里我们首先通过ShowWindow函数将窗口实例显示出来,并使用UpdateWindow函数更新窗口。然后进入一个while循环,不断调用GetMessage函数等待消息,然后将消息转换并分发到对应的窗口过程函数进行处理。

示例1:一个简单的窗口程序

下面是一个简单的窗口程序示例,它创建了一个基本的窗口实例,并在窗口中显示“Hello, World!”这个字符串。

#include <windows.h>
#include <tchar.h>

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    const TCHAR szWindowClass[] = _T("DesktopApp");

    WNDCLASSEX wcex;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
    wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.lpszMenuName = nullptr;
    wcex.lpszClassName = szWindowClass;
    wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));

    if (!RegisterClassEx(&wcex))
    {
        MessageBox(nullptr,
               _T("Call to RegisterClassEx failed!"),
               _T("Win32 Desktop App"),
               MB_ICONERROR);

        return 1;
    }

    HWND hWnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        szWindowClass,
        _T("Hello, World!"),
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        500, 500,
        nullptr,
        nullptr,
        hInstance,
        nullptr);

    if (!hWnd)
    {
        MessageBox(nullptr,
               _T("Call to CreateWindowEx failed!"),
               _T("Win32 Desktop App"),
               MB_ICONERROR);

        return 1;
    }

    ShowWindow(hWnd,
        nCmdShow);
    UpdateWindow(hWnd);

    // Main message loop:
    MSG msg;
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int) msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }

    return 0;
}

示例2:带按钮的窗口程序

下面是一个稍微复杂一点的窗口程序示例,它创建了带有一个按钮的窗口实例,并使用对应的窗口过程函数处理按钮点击事件。

#include <windows.h>
#include <tchar.h>

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void OnCommand(HWND hWnd, int id, HWND hwndCtl, UINT codeNotify);

const TCHAR szWindowClass[] = _T("DesktopApp");
const TCHAR szWindowTitle[] = _T("Hello, World!");

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    WNDCLASSEX wcex;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
    wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.lpszMenuName = nullptr;
    wcex.lpszClassName = szWindowClass;
    wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));

    if (!RegisterClassEx(&wcex))
    {
        MessageBox(nullptr,
            _T("Call to RegisterClassEx failed!"),
            _T("Win32 Desktop App"),
            MB_ICONERROR);

        return 1;
    }

    HWND hWnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        szWindowClass,
        szWindowTitle,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        500, 500,
        nullptr,
        nullptr,
        hInstance,
        nullptr);

    if (!hWnd)
    {
        MessageBox(nullptr,
            _T("Call to CreateWindowEx failed!"),
            _T("Win32 Desktop App"),
            MB_ICONERROR);

        return 1;
    }

    // Create a button
    HWND hWndButton = CreateWindow(
        _T("BUTTON"),
        _T("Click me"),
        WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
        10, 10,
        100, 30,
        hWnd,
        (HMENU) 1,
        (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE),
        nullptr);

    if (!hWndButton)
    {
        MessageBox(nullptr,
            _T("Call to CreateWindow failed!"),
            _T("Win32 Desktop App"),
            MB_ICONERROR);

        return 1;
    }

    ShowWindow(hWnd,
        nCmdShow);
    UpdateWindow(hWnd);

    // Main message loop:
    MSG msg;
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int) msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        OnCommand(hWnd, LOWORD(wParam), (HWND) lParam, HIWORD(wParam));
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }

    return 0;
}

void OnCommand(HWND hWnd, int id, HWND hwndCtl, UINT codeNotify)
{
    switch (id)
    {
    case 1:
        MessageBox(hWnd,
            _T("Hello, World!"),
            _T("Greetings"),
            MB_OK);
        break;
    default:
        break;
    }
}

在上面的例子中,我们首先创建了一个标题为“Hello, World!”的窗口实例,然后通过CreateWindow函数创建了一个按钮,并设置其位置和大小和按钮上的文本,接着我们注册了窗口过程函数,在过程函数中对按钮事件进行处理,最后在消息循环中调用GetMessage函数,等待用户输入和系统事件的触发。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言创建windows窗口实例 - Python技术站

(1)
上一篇 2023年5月24日
下一篇 2023年5月24日

相关文章

  • C C++ LeetCode题解在二叉树中增加一行示例详解

    C C++ LeetCode题解在二叉树中增加一行示例详解 在二叉树中增加一行的题目通常会让很多人头疼,本文将为大家提供一个详细而完整的攻略,同时提供两条示例说明。 题目描述 给定一个二叉树,根节点为第1层,现在要在第d层插入一个值为v的节点,使得原来的树变成新的树。插入完之后,新节点应该在原来第d层节点的左子树的位置上。 解题思路 一般情况下,我们可以采用…

    C 2023年5月23日
    00
  • JSON在Java中的使用方法实例

    下面是JSON在Java中的使用方法实例的详细攻略: 什么是JSON JSON是一种轻量级的数据交换格式,全称为JavaScript Object Notation。它是一种易于读写的文本格式,可与几乎所有编程语言一起使用,包括Java。 Java中的JSON库 Java中有多个库可以用于处理JSON,其中最流行的库是GSON和Jackson。这里我们以GS…

    C 2023年5月23日
    00
  • C++中临时对象的常见产生情况及其解决的方案

    C++中的临时对象,通常表示一些临时生成的对象,这些对象没有名字,在表达式的计算中会被创建和销毁。临时对象经常出现在以下情况中: 函数返回局部对象 函数参数以值传递方式传递 使用运算符等生成的新对象 下面分别对这三种情况进行详细介绍: 函数返回局部对象 如果在函数中定义了一个对象并将其作为返回值返回,则该对象就是一个局部对象。由于该对象是由函数定义的,因此它…

    C 2023年5月22日
    00
  • C语言实现航班管理系统

    C语言实现航班管理系统 简介 航班管理系统是一个能够记录航班信息并对其进行管理的软件程序。它可以记录航班的基本信息,如航班号、起飞地、目的地、起飞时间、到达时间、机型等,并提供相应的查询、修改、删除等功能。在本篇文章中,我们将使用C语言创建一个简单的航班管理系统。 步骤 步骤1: 创建一个结构体来保存航班信息 首先,我们需要创建一个结构体来存储航班信息。每一…

    C 2023年5月22日
    00
  • C语言学好递归看这一篇就够了

    C语言学好递归看这一篇就够了 什么是递归 递归(Recursion)是指在函数定义中使用函数自身的方法,是一种常用的解决问题的方法,通过不断调用自身,将大问题分解为小问题解决,最终达到解决整个问题的目的。 递归的三要素 递归包含三个要素:- 递归出口- 递归调用- 递归返回 递归示例一:求斐波那契数列第n项 斐波那契数列是指每一项都等于它前面两项的和,第一项…

    C 2023年5月22日
    00
  • 简单了解C语言中主线程退出对子线程的影响

    了解 C 语言中主线程退出对子线程的影响,需要掌握以下知识点:多线程,同步和互斥机制,线程的生命周期等。 首先,我们需要了解一个线程的生命周期。一个线程的生命周期通常包含如下阶段:创建、就绪、运行、阻塞、终止。 在 C 语言中,我们通常使用 pthread_create() 函数来创建线程,使用 pthread_join() 函数来等待线程的终止,使用 pt…

    C 2023年5月22日
    00
  • C 语言基础教程(我的C之旅开始了)[二]

    C 语言基础教程(我的C之旅开始了)[二]攻略 1. 基本数据类型 文章中提到了 C 语言的基本数据类型,包括了整型、浮点型、字符型和指针型。其中整型可以分为有符号和无符号两种,我们可以通过给数据类型指定修饰符来定义它是有符号还是无符号的。 此外,C 语言还有一个关键字 typedef,它可以为现有的数据类型创建一个新的别名。比如我们可以给 unsigned…

    C 2023年5月23日
    00
  • C语言中的函数指针学习笔记

    现在为大家介绍一下“C语言中的函数指针学习笔记”的完整攻略。 什么是函数指针? 函数指针(Function Pointer)是指向函数的指针变量,也就是说,函数指针指向函数的入口地址。 函数指针的定义 函数指针的定义格式如下: typedef int (*func_ptr)(int, int); // func_ptr是一个函数指针类型 上面代码定义了一个名…

    C 2023年5月24日
    00
合作推广
合作推广
分享本页
返回顶部