使用 C++ 在另一个应用程序中检查 TNewCheckBox

问题描述 投票:0回答:1

如何使用 C++ 以编程方式单击另一个应用程序中的 TNewCheckBox 控件? 我正在尝试与之通信的是 Inno Setup。

这是我已经存在的代码,它允许我获取

TNewCheckBox
和其他一些代码的句柄。 它检查我是否有一定数量的内存,如果有或更少,它会检查复选框。 我设法获取复选框处理程序并使用
SendMessage
发送消息,我还尝试了
PostMessage
SendDlgItemMessage
但无济于事,因为它仍然拒绝检查它。 我在网上搜索过,但没有任何与此相关的内容。 这是我的代码:

#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"TitleOfWindow");
    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;
}

它甚至说找到并单击了该复选框,但在设置中看不到任何内容。

抱歉我的英语不好,感谢您的阅读。

c++ inno-setup ui-automation
1个回答
0
投票

您可能需要考虑使用 PostMessage 函数而不是 SendMessage 来模拟按钮单击。

#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)
{
    // Simulate a BM_CLICK message using PostMessage
    PostMessage(hwndCheckBox, BM_CLICK, 0, 0);

    // Wait for the application to process the message (adjust the delay as needed)
    Sleep(1000);
}

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"TitleOfWindow");
    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;
}
© www.soinside.com 2019 - 2024. All rights reserved.