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++之string类对象的容量操作详解

    下面我将详细讲解一下“C++之string类对象的容量操作详解”的攻略。 容量操作详解 理解容量 在C++中,string类是一种非常实用的字符串处理类。string类中的容量操作可以帮助我们了解和控制该类的内存分配和管理。 容量通常包括字符串对象的大小、长度、容量等。在使用string类时,我们通常需要考虑它将占用的内存,并需要对内存进行优化管理。因此,理…

    C 2023年5月22日
    00
  • C4D怎么建模三维立体的摩天轮?

    当我们要建模三维立体的摩天轮时,通常需要经过以下步骤: 步骤一:创建摩天轮主体的外形 这个步骤可以用多边形建模实现。我们可以先创建轮廓线,然后再为其赋予一个融合体(Extrude)属性来进行外形建模。这里我们用一个圆形作为轮廓线的基础。具体步骤如下: 打开C4D,再打开新建一个工程。 将“多边形建模”界面的开关打开。(然后,将视图模式切换至左视图模式) 将圆…

    C 2023年5月22日
    00
  • win10系统升级提示错误代码0x80070006-0x2000c该怎么解决

    win10系统升级提示错误代码0x80070006-0x2000c的解决方法 出现win10系统升级提示错误代码0x80070006-0x2000c的原因很多,包括错误的系统配置,损坏的文件或注册表项,软件冲突等等。下面是一些常用的解决方法: 方法一:运行Windows更新故障排除工具 Windows更新故障排除工具是解决Win10升级问题的有力工具。以下是…

    C 2023年5月23日
    00
  • jQuery深拷贝Json对象简单示例

    当我们需要复制一个json对象时,直接使用=赋值是不行的,因为这会导致两个变量指向同一个内存地址,修改其中一个对象的值会同时修改另一个对象的值。这时候我们需要使用深拷贝来复制json对象,这样两个对象就指向不同的内存地址,不会相互影响。 以下是深拷贝Json对象的示例代码: // 定义json对象 var obj1 = {"name":&…

    C 2023年5月23日
    00
  • C语言实现歌手大奖赛计分程序

    C语言实现歌手大奖赛计分程序 程序实现功能 本程序主要实现歌手大奖赛计分功能,包括对选手的评分以及最终的排名输出。 实现思路 程序主要分为以下几个步骤进行实现: 获取选手总数 获取评委人数 获取选手分数 对选手的得分进行排序 最终输出选手排名 具体实现步骤 获取选手总数以及评委人数 可以使用scanf函数来获取用户输入的选手总数以及评委人数。 int sin…

    C 2023年5月23日
    00
  • ASP 精华源码收集(五年总结)

    ASP 精华源码收集(五年总结)攻略 简介 ASP(Active Server Pages)作为一种面向WEB的动态脚本语言,发展至今已经拥有了很多的经典精华源码。本攻略将针对ASP精华源码的收集整理过程及部分示例说明进行介绍。 收集整理过程 1. 明确收集目标 在收集ASP精华源码之前,我们需要先明确收集目标,将收集到的代码分类整理,以便后期使用。在明确收…

    C 2023年5月23日
    00
  • C++11各种锁的具体使用

    C++11各种锁的具体使用 在多线程编程时,锁是常用的线程同步机制之一。C++11中提供了多种不同的锁类型,用于处理不同的并发情况,本文将详细介绍这些锁的用法。 1、互斥锁(std::mutex) 使用互斥锁可以实现对共享资源的互斥访问。 #include <iostream> #include <mutex> #include &l…

    C 2023年5月22日
    00
  • VC实现Windows多显示器编程的方法

    下面是详细的讲解“VC实现Windows多显示器编程的方法”的完整攻略。 1. 概述 在现代计算机上使用多个显示器已经很常见了,其中在Windows操作系统下实现多显示器编程对于一些需要展示多个窗口或图形界面的应用非常有用处。本文将介绍在VC环境下如何实现Windows多显示器编程。 2. 实现 2.1 函数EnumDisplayDevices 在Windo…

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