为什么FindWindowEx找不到IP地址窗口?

时间:2019-10-13 15:43:24

标签: c windows winapi

按如下所示创建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 个答案:

答案 0 :(得分:1)

一个IP Address controlnot a standard edit control。将"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. 为IP地址控件(在hMenu的{​​{1}}参数中)指定控件ID ,然后使用GetDlgItem()获取CreateWindow()(在需要时使用IP地址控件):

    HWND