Почему FindWindowEx не находит окно IP-адреса? - PullRequest
1 голос
/ 13 октября 2019

Создает окно IP-адреса следующим образом, затем пытается найти его с помощью функции FindWindowEx:

    INITCOMMONCONTROLSEX icex;
    icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
    icex.dwICC = ICC_INTERNET_CLASSES;
    InitCommonControlsEx(&icex);

    // hwnd is the parent of the IP address window
    HWND eIpAddress = CreateWindowW(WC_IPADDRESS,
        L"ServerIpAddress",
        WS_CHILD | WS_OVERLAPPED | WS_VISIBLE,
        MulDiv(LOWORD(units), 40, 4), 50,
        MulDiv(LOWORD(units), 70, 4),
        MulDiv(HIWORD(units), 11, 8),
        hwnd, NULL, NULL, NULL);

    // try to retrieve the control; does not work, returns null
    HWND wnd_server_ipaddress = FindWindowEx(hwnd, NULL, NULL, L"ServerIpAddress");

    DWORD err = GetLastError(); // --> returns 0

Но wnd_server_ipaddress имеет значение NULL. Я делаю то же самое с двумя другими стандартными окнами редактирования, которые имеют разные имена, и это работает. Посмотрел в Spy ++, чтобы убедиться в правильности иерархии. Добавлен GetLastError() после вызова и возвращается 0.

        // works
        HWND wnd_server_name = FindWindowEx(hwnd, NULL, NULL, L"ServerName");

        // does not work
        HWND wnd_server_ipaddress = FindWindowEx(hwnd, NULL, WC_IPADDRESS, L"ServerIpAddress");
        HWND wnd_server_ipaddress2 = FindWindow(WC_IPADDRESS, L"ServerIpAddress");

        // works
        wchar_t server_name[512] = { 0 };
        GetWindowText(wnd_server_name, server_name, 512);

        // does not work because wnd_server_ipaddress is null
        wchar_t server_ipaddress[16] = { 0 };
        DWORD dwAddr = 0x0;
        int iCount = (int)SendMessage(wnd_server_ipaddress, IPM_GETADDRESS, 0, (LPARAM)&dwAddr);
        _snwprintf_s(server_ipaddress, sizeof(server_ipaddress) / sizeof(*server_ipaddress), 16,
            L"%ld.%ld.%ld.%ld",
            (dwAddr >> 24) & 0xff,
            (dwAddr >> 16) & 0xff,
            (dwAddr >> 8)  & 0xff,
            (dwAddr)       & 0xff);

Вопрос: Есть ли что-то специфическое для WC_IPADDRESS, которое заставляет FindWindowEx не найти элемент управления?


Редактировать Добавлен код, который работает для стандартного управления.

    // creation with ServerName as lpWindowName
    HWND eName = CreateWindowW(L"Edit", L"ServerName",
        WS_CHILD | WS_VISIBLE | WS_BORDER,
        MulDiv(LOWORD(units), 40, 4), 10,
        MulDiv(LOWORD(units), 150, 4),
        MulDiv(HIWORD(units), 11, 8),
        hwnd, NULL, NULL, NULL);

    // reset text
    SetWindowText(eName, L"");

    // retrieve control - works
    HWND wnd_server_name = FindWindowEx(hwnd, NULL, NULL, L"ServerName");

    // retrieve value - works, gets whatever the text in the control is
    wchar_t server_name[512] = { 0 };
    GetWindowText(wnd_server_name, server_name, 512);

1 Ответ

1 голос
/ 13 октября 2019

Элемент управления IP-адресом является не стандартным элементом управления . Присвоение текста окна, например "ServerIpAddress", элементу управления IP-адресом не имеет смысла, и, скорее всего, он будет отброшен при создании окна. Чтобы назначить IP-адрес элементу управления IP-адресом, необходимо использовать оконное сообщение IPM_SETADDRESS.

Кроме того, согласно документации FindWindowEx():

Если параметр lpszWindow не равен NULL, FindWindowEx вызывает функцию GetWindowText для получения имени окна для сравнения.

GetWindowText() не работает сэлемент управления IP-адресом, как для стандартного элемента редактирования. Чтобы получить IP-адрес из элемента управления IP-адресом, вы должны использовать сообщение окна IPM_GETADDRESS.

Таким образом, при использовании FindWindow/Ex() элемент управления IP-адресом не может быть найденего текстовое содержание, как стандартное управление редактирования может быть. Его можно найти только по имени WC_IPADDRESS класса.

Чтобы сделать то, что вы пытаетесь, вам нужно:

  1. сохранить HWND изЭлемент управления IP-адресом, который возвращает CreateWindow() (это предпочтительное решение):

    HWND gIpAddress; // stored somewhere that you can reach it
    
    ...
    
    // hwnd is the parent of the IP address window
    gIpAddress = CreateWindowW(WC_IPADDRESS,
        L"",
        WS_CHILD | WS_OVERLAPPED | WS_VISIBLE,
        MulDiv(LOWORD(units), 40, 4), 50,
        MulDiv(LOWORD(units), 70, 4),
        MulDiv(HIWORD(units), 11, 8),
        hwnd, NULL, NULL, NULL);
    
    ...
    
    DWORD dwAddr = 0x0;
    SendMessage(gIpAddress, IPM_GETADDRESS, 0, (LPARAM)&dwAddr);
    ...
    
  2. укажите ID элемента управления для элемента управления IP-адресом (в hMenu параметр CreateWindow()), а затем используйте GetDlgItem(), чтобы получить HWND элемента управления IP-адресом при необходимости:

    // hwnd is the parent of the IP address window
    HWND eIPAddress = CreateWindowW(WC_IPADDRESS,
        L"",
        WS_CHILD | WS_OVERLAPPED | WS_VISIBLE,
        MulDiv(LOWORD(units), 40, 4), 50,
        MulDiv(LOWORD(units), 70, 4),
        MulDiv(HIWORD(units), 11, 8),
        hwnd, (HMENU)12345, NULL, NULL);
    
    ...
    
    // hwnd is the parent of the IP address window
    HWND wnd_server_ipaddress = GetDlgItem(hwnd, 12345);
    DWORD dwAddr = 0x0;
    SendMessage(wnd_server_ipaddress, IPM_GETADDRESS, 0, (LPARAM)&dwAddr);
    ...
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...