最近更新于 2023-02-24 10:38

环境

Windows SDK 10.0(Windows 11)
平台工具集:Visual Studio 2022 v143
C 语言标准:C17
字符集:Unicode

控件库

STATIC 静态文本 – 标签

我一般喜欢把它称为标签

#include <Windows.h>

#define ID_STATIC       100 // 标签 ID

LRESULT CALLBACK wndProc(HWND wnd, UINT msg, WPARAM wp, LPARAM lp)
{
    switch (msg)
    {
        case WM_CREATE:
        {
            HWND stc = CreateWindowEx(0, L"STATIC", L"这是一个标签", WS_CHILD | WS_VISIBLE, 200, 150, 100, 20, wnd, (HMENU)ID_STATIC, (HINSTANCE)GetWindowLongPtr(wnd, GWLP_HINSTANCE), NULL);
            if (!stc)
            {
                exit(13);
            }
            break;
        }
        case WM_CLOSE:
        {
            DestroyWindow(wnd);
            break;
        }
        case WM_DESTROY:
        {
            PostQuitMessage(0);
            break;
        }
        default:
        {
            return DefWindowProc(wnd, msg, wp, lp);
        }
    }
    return 0;
}

int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPreInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
    PCWSTR className = L"desktopAPP";
    WNDCLASSEX wc = {0};
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.lpszClassName = className;
    wc.lpfnWndProc = wndProc;
    if (!RegisterClassEx(&wc))
    {
        return 11;
    }

    HWND wnd = CreateWindowEx(0, className, L"标签使用", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 600, 400, NULL, NULL, hInstance, NULL);
    if (!wnd)
    {
        return 12;
    }

    ShowWindow(wnd, nCmdShow);
    UpdateWindow(wnd);

    MSG msg = {0};
    while (GetMessage(&msg, NULL, 0, 0))
    {
        DispatchMessage(&msg);
    }

    return (int)msg.wParam;
}

file

EDIT 编辑框

这个例子创建了一个编辑框,编辑框中显示一段文字,编辑框的大小跟随窗口大小改变

#include <Windows.h>

#define ID_EDIT     100 // 自定义编辑框 ID

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    static HWND edit;

    PCWSTR lpszLatin =  L"中国,以华夏文明为源泉、中华文化为基础,是世界上历史最悠久的国家之一。"
                        L"中国各族人民共同创造了光辉灿烂的文化,具有光荣的革命传统。 " 
                        L"中国是以汉族为主体民族的多民族国家,通用汉语、汉字,汉族与少数民族统称为“中华民族”,又自称“炎黄子孙”、“龙的传人”" 
                        L"中国是世界四大文明古国之一。" 
                        L"距今5800年前后,黄河、长江中下游以及西辽河等区域出现了文明起源迹象;" 
                        L"距今5300年前后,中华大地各地区陆续进入了文明阶段;" 
                        L"距今3800年前后,中原地区形成了更为成熟的文明形态,并向四方辐射文化影响力;" 
                        L"后历经多次民族交融和朝代更迭,直至形成多民族国家的大一统局面" 
                        L"中国疆域辽阔、民族众多,先秦时期的华夏族在中原地区繁衍生息,到了汉代通过文化交融使汉族正式成型,奠定了中国主体民族的基础。" 
                        L"中国文化渊远流长、博大精深、绚烂多彩,是东亚文化圈的文化宗主国,在世界文化体系内占有重要地位,由于各地的地理位置、自然条件的差异,人文、经济方面也各有特点。" ;

    switch (msg)
    {
        case WM_CREATE:
        {
            edit = CreateWindowEx(0, L"EDIT", // 编辑框
                                       NULL,
                                       WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_LEFT | ES_MULTILINE | ES_WANTRETURN, // 子窗口;可见;滚动条;左侧对其;多行显示;接收回车键
                                       0, 0, 0, 0,
                                       hWnd,
                                       (HMENU)ID_EDIT, // 编辑框 ID
                                       (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE), // 获取当前实例句柄
                                       NULL);
            SendMessage(edit,
                        WM_SETTEXT,
                        0,
                        (LPARAM)lpszLatin);
            break;
        }
        case WM_SIZE: // 编辑框大小跟随主窗口大小变化
        {
            MoveWindow(edit,
                       0, 0,
                       LOWORD(lParam),
                       HIWORD(lParam),
                       TRUE);
            break;
        }
        case WM_CLOSE:
        {
            DestroyWindow(hWnd);
            break;
        }
        case WM_DESTROY:
        {
            PostQuitMessage(0);
            break;
        }
        default:
        {
            return DefWindowProc(hWnd, msg, wParam, lParam);
        }
    }
    return 0;
}

int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPreInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
    PCWSTR className = L"Desktop";
    WNDCLASSEX wc = {0};
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.lpszClassName = className;
    wc.lpfnWndProc = WndProc;

    if (!RegisterClassEx(&wc))
    {
        MessageBox(NULL, L"注册窗口失败!", L"错误", MB_OK);
        return 1;
    }

    HWND hWnd = CreateWindowEx(0, className, L"编辑框使用", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 600, 300, NULL, NULL, hInstance, NULL);
    if (!hWnd)
    {
        MessageBox(NULL, L"创建窗口失败!", L"错误", MB_OK);
        return 2;
    }

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

    MSG msg = {0};
    while (GetMessage(&msg, NULL, 0, 0))
    {
        DispatchMessage(&msg);
        TranslateMessage(&msg);
    }

    return (int)msg.wParam;
}

file
file

EDIT 编辑框 & BUTTON 按钮

例子中点击设置将会向文本框写入一段文字,点击获取将弹出消息框并显示编辑框中的内容

#include <Windows.h>

#define ID_EDIT     100 // 编辑框 ID
#define ID_BUTTON1  101 // 设置按钮 ID
#define ID_BUTTON2  102 // 获取按钮 ID

#define BUF_SIZE    128 // 缓冲区大小

LRESULT CALLBACK wndProc(HWND wnd, UINT msg, WPARAM wp, LPARAM lp)
{
    static WCHAR buf[BUF_SIZE]; // 缓冲区,用于存储从编辑框获取的文本

    switch (msg)
    {
        case WM_CREATE:
        {
            HWND edit = CreateWindowEx(0, L"EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_LEFT | ES_MULTILINE, 0, 0, 300, 400, wnd, (HMENU)ID_EDIT, (HINSTANCE)GetWindowLongPtr(wnd, GWLP_HINSTANCE), NULL);
            if (!edit)
            {
                exit(3);
            }
            HWND button1 = CreateWindowEx(0, L"BUTTON", L"设置", WS_CHILD | WS_VISIBLE, 400, 150, 100, 50, wnd, (HMENU)ID_BUTTON1, (HINSTANCE)GetWindowLongPtr(wnd, GWLP_HINSTANCE), NULL);
            if (!button1)
            {
                exit(4);
            }
            HWND button2 = CreateWindowEx(0, L"BUTTON", L"获取", WS_CHILD | WS_VISIBLE, 400, 210, 100, 50, wnd, (HMENU)ID_BUTTON2, (HINSTANCE)GetWindowLongPtr(wnd, GWLP_HINSTANCE), NULL);
            if (!button2)
            {
                exit(5);
            }
            break;
        }
        case WM_COMMAND: // 控件消息
        {
            switch (LOWORD(wp)) // 控件 ID 匹配
            {
                case ID_BUTTON1: // 设置按钮
                {
                    if (HIWORD(wp) == BN_CLICKED) // 单击事件
                    {
                        SetDlgItemText(wnd, ID_EDIT, L"中国,以华夏文明为源泉、中华文化为基础,是世界上历史最悠久的国家之一。"); // 向编辑框设置文本
                    }
                    break;
                }
                case ID_BUTTON2: // 获取按钮
                {
                    if (HIWORD(wp) == BN_CLICKED)
                    {
                        memset(buf, 0, sizeof(buf));
                        GetDlgItemText(wnd, ID_EDIT, buf, BUF_SIZE); // 从编辑框获取文本
                        MessageBox(wnd, buf, L"信息", MB_OK);
                    }
                    break;
                }
                default:
                {
                    break;
                }
            }
            break;
        }
        case WM_CLOSE:
        {
            DestroyWindow(wnd);
            break;
        }
        case  WM_DESTROY:
        {
            PostQuitMessage(0);
            break;
        }
        default:
        {
            return DefWindowProc(wnd, msg, wp, lp);
        }
    }
    return 0;
}

int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPreInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
    PCWSTR className = L"desktopAPP";
    WNDCLASSEX wc = {0};
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.lpszClassName = className;
    wc.lpfnWndProc = wndProc;
    if (!RegisterClassEx(&wc))
    {
        return 1;
    }

    HWND wnd = CreateWindowEx(0, className, L"编辑框使用", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 600, 400, NULL, NULL, hInstance, NULL);
    if (!wnd)
    {
        return 2;
    }

    ShowWindow(wnd, nCmdShow);
    UpdateWindow(wnd);

    MSG msg = {0};
    while (GetMessage(&msg, NULL, 0, 0))
    {
        DispatchMessage(&msg);
        TranslateMessage(&msg);
    }

    return (int)msg.wParam;
}

file
file
file
file

登录界面(标签、编辑框和按钮的综合应用)

#include <Windows.h>

#define ID_STATIC1      100
#define ID_STATIC2      101
#define ID_EDIT1        102
#define ID_EDIT2        103
#define ID_BUTTON1      104

#define STR_SIZE        32

LRESULT CALLBACK wndProc(HWND wnd, UINT msg, WPARAM wp, LPARAM lp)
{
    static WCHAR account[STR_SIZE], password[STR_SIZE];

    switch (msg)
    {
        case WM_CREATE:
        {
            CreateWindowEx(0, L"STATIC", L"账号", WS_CHILD | WS_VISIBLE, 40, 40, 30, 20, wnd, (HMENU)ID_STATIC1, (HINSTANCE)GetWindowLongPtr(wnd, GWLP_HINSTANCE), NULL);
            CreateWindowEx(0, L"STATIC", L"密码", WS_CHILD | WS_VISIBLE, 40, 75, 30, 20, wnd, (HMENU)ID_STATIC2, (HINSTANCE)GetWindowLongPtr(wnd, GWLP_HINSTANCE), NULL);
            CreateWindowEx(0, L"EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER, 90, 40, 200, 20, wnd, (HMENU)ID_EDIT1, (HINSTANCE)GetWindowLongPtr(wnd, GWLP_HINSTANCE), NULL);
            CreateWindowEx(0, L"EDIT", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_PASSWORD, 90, 75, 200, 20, wnd, (HMENU)ID_EDIT2, (HINSTANCE)GetWindowLongPtr(wnd, GWLP_HINSTANCE), NULL);
            CreateWindowEx(0, L"BUTTON", L"登录", WS_CHILD | WS_VISIBLE, 150, 120, 50, 30, wnd, (HMENU)ID_BUTTON1, (HINSTANCE)GetWindowLongPtr(wnd, GWLP_HINSTANCE), NULL);
            break;
        }
        case WM_COMMAND:
        {
            switch (LOWORD(wp))
            {
                case ID_BUTTON1: // 匹配登录按钮
                {
                    if (HIWORD(wp) == BN_CLICKED) // 登录验证操作
                    {
                        memset(account, 0, sizeof(account));
                        memset(password, 0, sizeof(password));
                        GetDlgItemText(wnd, ID_EDIT1, account, STR_SIZE);
                        GetDlgItemText(wnd, ID_EDIT2, password, STR_SIZE);
                        if (!wcscmp(account, L"IYATT-yx") || !wcscmp(password, L"123456")) // 账号密码匹配
                        {
                            MessageBox(wnd, L"登录成功!", L"验证消息", MB_OK);
                        }
                        else
                        {
                            MessageBox(wnd, L"账号或密码错误!", L"验证消息", MB_OK);
                        }
                    }
                    break;
                }
                default:
                {
                    break;
                }
            }
            break;
        }
        case WM_CLOSE:
        {
            DestroyWindow(wnd);
            break;
        }
        case WM_DESTROY:
        {
            PostQuitMessage(0);
            break;
        }
        default:
        {
            return DefWindowProc(wnd, msg, wp, lp);
        }
    }
    return 0;
}

int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPreInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
    PCWSTR className = L"desktopAPP";
    WNDCLASSEX wc = {0};
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.lpszClassName = className;
    wc.lpfnWndProc = wndProc;
    if (!RegisterClassEx(&wc))
    {
        return 11;
    }

    HWND wnd = CreateWindowEx(0, className, L"登录", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 350, 200, NULL, NULL, hInstance, NULL);
    if (!wnd)
    {
        return 12;
    }

    ShowWindow(wnd, nCmdShow);
    UpdateWindow(wnd);

    MSG msg = {0};
    while (GetMessage(&msg, NULL, 0, 0))
    {
        DispatchMessage(&msg);
        TranslateMessage(&msg);
    }

    return (int)msg.wParam;
}

file
file
file