DwmGetWindowAttribute does not work on child window, is it true?

Viewed 279

I'm trying DwmGetWindowAttribute to get a window's real, physical, pixel location on screen. It works well for top-level windows. But I find that it does not work for child windows, in which case it returns just E_HANDLE (0x80070006).

However, MSDN does not state anything about such child-window limitation. So I'm in baffle.

Can any one confirm this behavior? Thank you.

This is my C++ test code (DwmBounds.cpp):

#include <stdio.h>
#include <windows.h>
#include <dwmapi.h>

int main()
{
    DWORD winerr = 0;
    HWND hwndTop = FindWindow(L"Notepad", NULL);
    if(!hwndTop)
    {
        wprintf(L"Cannot find a Notepad window.\n");
        return 4;
    }

    RECT rc = {};
    HRESULT hr = DwmGetWindowAttribute(hwndTop, DWMWA_EXTENDED_FRAME_BOUNDS, &rc, sizeof(rc));
    if (hr != S_OK)
    {
        wprintf(L"Fail to call DwmGetWindowAttribute() on Notepad window. HRESULT=0x%08X\r\n",
            (DWORD)hr);
        return 4;
    }

    wprintf(L"Notepad DWMWA_EXTENDED_FRAME_BOUNDS: LT(%d, %d) RB(%d, %d)\r\n", 
        rc.left, rc.top, rc.right, rc.bottom);

    HWND hwndEdit = FindWindowEx(hwndTop, nullptr, L"Edit", nullptr);
    if (!hwndEdit)
        return 4;

    hr = DwmGetWindowAttribute(hwndEdit, DWMWA_EXTENDED_FRAME_BOUNDS, &rc, sizeof(rc));
    if(hr != S_OK)
    {
        // Always get HRESULT=0x80070006 (E_HANDLE), why?
        wprintf(L"Get DWMWA_EXTENDED_FRAME_BOUNDS fails on child window(0x%08X), HRESULT=0x%08X\n", 
            (DWORD)hwndEdit, (DWORD)hr);
        return 4;
    }

    wprintf(L"Editbox DWMWA_EXTENDED_FRAME_BOUNDS: LT(%d, %d) RB(%d, %d)\r\n",
        rc.left, rc.top, rc.right, rc.bottom);

    return 0;
}

This is its output:

enter image description here

The benefit of DwmGetWindowAttribute is: Whatever the setting of DPI_AWARENESS_CONTEXT on the calling thread, DwmGetWindowAttribute always reports physical screen coordinate. On the other hand, GetWindowRect just reports the "virtual" coordinates relating to calling thread's DPI-awareness-context. So, I am wondering whether I can use DwmGetWindowAttribute to get each top-level window and child window's physical coordinates.

0 Answers
Related