You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Win32 API计算器Edit控件闪烁故障求助

Win32计算器Edit控件闪烁问题修复

核心问题分析

  • 消息处理未中断:WindowProcedure中WM_COMMAND分支处理完后未添加break,导致每次触发按钮消息时,会继续执行后续的WM_CREATE分支,反复重建控件,这是闪烁的根本原因。
  • 字符集不匹配:使用了CreateWindowW(宽字符版本),但处理文本时用了char类型,应该用wchar_t,否则会引发乱码或内存错误。
  • 按钮创建参数错误:创建数字1按钮时,窗口样式参数BS_RADIOBUTTON|BS_DEFPUSHBUTTON后缺少分隔符|,且位置/尺寸参数顺序错误(正确顺序应为x,y,width,height)。
  • 程序规范缺失:WinMain函数未添加返回值,WindowProcedure中WM_DESTROY分支未添加break,不符合Win32消息处理规范。

修正后的代码

#include <windows.h>
#include <wchar.h>

#define ONE_BUTTON 1

void AddControls(HWND);

HWND hOut;
HWND hOne;

LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int ncmdshow)
{
    WNDCLASSW wc = {0};
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hInstance = hInst;
    wc.lpszClassName = L"mywindowclass";
    wc.lpfnWndProc = WindowProcedure;
    if (!RegisterClassW(&wc))
        return -1;

    CreateWindowW(L"mywindowclass", L"calculatorGUI", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                  100, 100, 500, 350, NULL, NULL, hInst, NULL);

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

LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
    switch (msg)
    {
    case WM_COMMAND:
        switch (wp)
        {
        case ONE_BUTTON:
        {
            wchar_t one[50];
            wchar_t out[15];
            GetWindowTextW(hOne, one, 50);
            wcscpy(out, one);
            SetWindowTextW(hOut, out);
            break;
        }
        }
        break;

    case WM_CREATE:
        AddControls(hWnd);
        break;

    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProcW(hWnd, msg, wp, lp);
    }
    return 0;
}

void AddControls(HWND hWnd)
{
    hOut = CreateWindowW(L"Edit", L"", WS_VISIBLE | WS_CHILD | WS_BORDER,
                         2, 2, 480, 106, hWnd, NULL, NULL, NULL);

    hOne = CreateWindowW(L"Button", L"1", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
                         2, 110, 98, 50, hWnd, (HMENU)ONE_BUTTON, NULL, NULL);
}

关键修正点说明

  • 给WM_COMMAND和按钮消息分支添加break,阻止重复创建控件,彻底解决闪烁问题。
  • 将文本处理改为宽字符类型(wchar_t),搭配GetWindowTextW、wcscpy、SetWindowTextW等宽字符函数,解决字符集不匹配问题。
  • 修正按钮创建的样式参数(移除不需要的BS_RADIOBUTTON样式,补全样式分隔符|),并调整位置尺寸参数顺序为正确的x,y,width,height。
  • 给WinMain添加返回值,给WM_DESTROY分支添加break,规范Win32程序结构。

内容的提问来源于stack exchange,提问作者Ammishaddai Boakye

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 21:40:28