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

UpDown控件反向工作求助:上箭头减数值下箭头增数值

问题:UpDown控件箭头操作与预期数值变化相反

编写了一个关联Edit控件的UpDown控件小程序,测试后发现点击上箭头数值减少,下箭头数值增加,与预期相反。使用Windows 11 + Visual Studio 2022开发,代码如下:

#include <Windows.h>
#include <CommCtrl.h>
#include "resource.h"

#pragma comment(lib, "comctl32.lib")

static HWND et1, ud1;
static HINSTANCE hinstancia;

LRESULT OnDestroy(HWND hwnd, WPARAM wp, LPARAM lp)
{
    PostQuitMessage(0);
    return 0;
}
/////////////////////////////////////////////////////////////////////
LRESULT OnCreate(HWND hwnd, WPARAM wp, LPARAM lp)
{
    et1 = CreateWindowEx(0, L"edit", L"", WS_CHILD | WS_VISIBLE, 10, 10, 40, 16, hwnd, NULL, hinstancia, NULL);
    if (!et1)
    {
        MessageBox(NULL, L"I was unable to create the input control", L"Error", MB_OK);
        exit(0);
    }
    ud1 = CreateWindowEx(0, L"MSCTLS_UPDOWN32", L"", WS_CHILD | WS_VISIBLE | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY | UDS_SETBUDDYINT, 50, 10, 12, 16, hwnd, NULL, hinstancia, NULL);
    if (!ud1)
    {
        MessageBox(NULL, L"I was unable to create the up down control", L"Error", MB_OK);
        exit(0);
    }
    return 0;
}
/////////////////////////////////////////////////////////////////////
LRESULT CALLBACK wndproc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
    switch (msg)
    {
    case WM_DESTROY: return OnDestroy(hwnd, wp, lp);
    case WM_CREATE: return OnCreate(hwnd, wp, lp);
    default: return DefWindowProc(hwnd, msg, wp, lp);
    }
    
}
////////////////////////////////////////////////////////////////////////////////////////////////
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    INITCOMMONCONTROLSEX ice;
    WNDCLASSEX wc;
    HWND hwnd;
    MSG msg;
    hinstancia = hInstance;
    ice.dwSize = sizeof(INITCOMMONCONTROLSEX);
    ice.dwICC = ICC_UPDOWN_CLASS;
    InitCommonControlsEx(&ice);
    ZeroMemory(&wc, sizeof(WNDCLASSEX));
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.hInstance = hInstance;
    wc.lpszClassName = L"Test1";
    wc.hbrBackground = (HBRUSH) GetStockObject(GRAY_BRUSH);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    wc.lpfnWndProc = wndproc;
    wc.style = CS_HREDRAW | CS_VREDRAW;
    if (!RegisterClassEx(&wc))
    {
        MessageBox(NULL, L"Window class was not registered", L"Error", MB_OK);
        return 0;
    }
    hwnd = CreateWindowEx(WS_EX_APPWINDOW, L"Test1", L"Sample", WS_CAPTION | WS_SYSMENU | WS_VISIBLE,
        CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, NULL, NULL, hInstance, NULL);
    if (!hwnd)
    {
        MessageBox(NULL, L"Window was not createed", L"Error", MB_OK);
        return 0;
    }
    ShowWindow(hwnd, nShowCmd);
    UpdateWindow(hwnd);
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);  
    }
    return (int)msg.wParam;
}

预期行为:点击上箭头数值增加,下箭头数值减少。


解决方案

问题出在未显式设置UpDown控件的数值范围,导致控件的默认范围逻辑因Edit初始为空触发了非预期的行为。

UpDown控件的核心行为规则:

  • 上箭头:将数值向最大值方向调整
  • 下箭头:将数值向最小值方向调整

若控件的最大值小于最小值,就会出现箭头操作与数值变化反向的情况。即使默认范围应为0(最小值)到100(最大值),空Edit的初始状态可能干扰了控件的默认范围初始化。

修复方法是在创建UpDown控件后,显式发送UDM_SETRANGE消息设置范围,同时可设置初始位置:

// 在创建ud1的代码后添加:
// 设置范围:最小值0,最大值100(注意MAKELPARAM参数顺序是(max, min))
SendMessage(ud1, UDM_SETRANGE, 0, MAKELPARAM(100, 0));
// 设置初始数值为0
SendMessage(ud1, UDM_SETPOS, 0, 0);

修改后的OnCreate函数如下:

LRESULT OnCreate(HWND hwnd, WPARAM wp, LPARAM lp)
{
    et1 = CreateWindowEx(0, L"edit", L"", WS_CHILD | WS_VISIBLE, 10, 10, 40, 16, hwnd, NULL, hinstancia, NULL);
    if (!et1)
    {
        MessageBox(NULL, L"I was unable to create the input control", L"Error", MB_OK);
        exit(0);
    }
    ud1 = CreateWindowEx(0, L"MSCTLS_UPDOWN32", L"", WS_CHILD | WS_VISIBLE | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_AUTOBUDDY | UDS_SETBUDDYINT, 50, 10, 12, 16, hwnd, NULL, hinstancia, NULL);
    if (!ud1)
    {
        MessageBox(NULL, L"I was unable to create the up down control", L"Error", MB_OK);
        exit(0);
    }
    // 新增:设置范围和初始位置
    SendMessage(ud1, UDM_SETRANGE, 0, MAKELPARAM(100, 0));
    SendMessage(ud1, UDM_SETPOS, 0, 0);
    return 0;
}

这样设置后,上箭头会向最大值100方向增加数值,下箭头向最小值0方向减少数值,符合预期行为。


内容的提问来源于stack exchange,提问作者José Antonio López Cano

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 11:04:58