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

如何用C++控制Inno Setup安装器中的TNewCheckBox控件?

跨进程程序化点击Inno Setup中TNewCheckBox控件失败问题

我需要用C++程序对另一个进程里Inno Setup安装器中的TNewCheckBox控件执行程序化点击,逻辑是检测系统内存,若≤8GB则勾选该复选框。目前已能成功获取该控件句柄,但尝试用SendMessage、PostMessage、SendDlgItemMessage发送BM_CLICK消息均无法勾选控件——代码提示已找到并点击复选框,但安装器界面无变化;用BM_GETCHECK读取状态始终显示未勾选,手动勾选后重新运行代码结果也一样。

C++程序与安装器相互独立,需手动启动安装器后在对应界面运行程序,仅通过句柄获取、消息发送与状态读取交互。


提供的代码

C++程序代码

#include <Windows.h>
#include <iostream>

HWND EnumChildWindowsRecursive(HWND hwndParent)
{
    HWND hwndChild = FindWindowExW(hwndParent, NULL, NULL, NULL);

    if (hwndChild == NULL)
    {
        return NULL;
    }

    wchar_t szClassName[256];
    GetClassNameW(hwndChild, szClassName, sizeof(szClassName) / sizeof(wchar_t));

    wchar_t szWindowText[256];
    GetWindowTextW(hwndChild, szWindowText, sizeof(szWindowText) / sizeof(wchar_t));

    std::wcout << L"Handle: " << hwndChild << L", Class Name: " << szClassName << L", Text: " << szWindowText << std::endl;

    if (_wcsicmp(szClassName, L"TNewCheckBox") == 0 && _wcsicmp(szWindowText, L"Limit installer to 2 GB of RAM usage") == 0)
    {
        return hwndChild;
    }

    HWND hwndSubChild = EnumChildWindowsRecursive(hwndChild);
    if (hwndSubChild != NULL)
        return hwndSubChild;

    return EnumChildWindowsRecursive(FindWindowExW(hwndParent, hwndChild, NULL, NULL));
}

void ClickCheckBox(HWND hwndCheckBox)
{
    SendMessage(hwndCheckBox, BM_CLICK, 0, 0);
}

int GetSystemRAM()
{
    MEMORYSTATUSEX statex;
    statex.dwLength = sizeof(statex);

    if (GlobalMemoryStatusEx(&statex))
    {
        DWORDLONG totalMemoryInBytes = statex.ullTotalPhys;
        int totalMemoryInGB = static_cast<int>(totalMemoryInBytes / (1024 * 1024 * 1024));
        return totalMemoryInGB;
    }

    return -1;
}

int main()
{
    HWND hwnd = FindWindowW(NULL, L"Setup - Test Installer version 1.0");
    if (hwnd == NULL)
    {
        std::cout << L"Window title not found" << std::endl;
        return 0;
    }

    std::cout << L"Found window with title" << std::endl;

    HWND hwndCheckBox = EnumChildWindowsRecursive(hwnd);
    if (hwndCheckBox == NULL)
    {
        std::cout << "Checkbox not found" << std::endl;
        return 0;
    }

    std::cout << "Checkbox found" << std::endl;

    DWORD ramSizeGB = GetSystemRAM();
    if (ramSizeGB <= 8)
    {
        std::cout << "8 GB of RAM or less" << std::endl;
        std::cout << "Checkbox handle: 0x" << std::hex << reinterpret_cast<uintptr_t>(hwndCheckBox) << std::endl;
        ClickCheckBox(hwndCheckBox);
        std::cout << "Checkbox clicked" << std::endl;
    }
    else
    {
        std::cout << "More than 8 GB of RAM" << std::endl;
    }

    return 0;
}

Inno Setup 脚本([Setup]段)

[Setup]
AppName=Test Installer
AppVersion=1.0
DefaultDirName={pf}\TestInstaller
OutputDir=Output
OutputBaseFilename=TestInstallerSetup

[Components]
Name: "CheckBox"; Description: "Include checkbox functionality"; Types: full custom; Flags: fixed

Inno Setup 脚本([Code]段)

[Code]
var
  CheckBox: TNewCheckBox;

procedure InitializeWizard;
begin
  CheckBox := TNewCheckBox.Create(WizardForm);
  CheckBox.Parent := WizardForm;
  CheckBox.Left := 8;
  CheckBox.Top := WizardForm.ClientHeight - 100;
  CheckBox.Caption := 'Enable checkbox functionality';
  CheckBox.Checked := True;
end;

procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep = ssPostInstall then
  begin
    if CheckBox.Checked then
    begin
      MsgBox('Checkbox is checked', mbInformation, MB_OK);
    end
    else
    begin
      MsgBox('Checkbox is unchecked', mbInformation, MB_OK);
    end;
  end;
end;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 00:13:14