Search code examples
c++winapiscreensaver

c++ WinApi : GetClientRect fails


I am coding a screensaver program running on Windows.

In preview mode, Windows calls the program this way :
Screensaver.exe /p ParentWindowHandle

However, when I make this call in my program :
BOOL res = GetClientRect(parentWindowHandle, rect)
res is FALSE, rect is NULL and I get ERROR_INVALID_WINDOW_HANDLE with GetLastError()

GetWindowRect gives me the same results.

But, if I make a call to BOOL res = IsWindow(parentWindowHandle) instead, I get res == TRUE. Does this not mean I have a valid window handle ?

The code looks like this :

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
    unsigned int handle = GetHandleFromCommandLine(pCmdLine); // Custom function (tested and approved :) )
    HWND parentWindowHandle = (HWND) handle;
    LPRECT rect = NULL;
    BOOL res = GetClientRect(parentWindowHandle, rect);
    // here, rect == NULL, res == FALSE and GetLastError() returns ERROR_INVALID_WINDOW_HANDLE

    // ...
    // ...
}

Solution

  • On 64-bit Windows, a window handle is 64 bits and cannot fit in an unsigned int, so your cast is producing a value that is an invalid window handle. You should modify your GetHandleFromCommandLine function so that it returns a proper HWND, not an unsigned int, and no type cast is necessary.

    Also, GetClientRect returns the rectangle by storing it into the value pointed at by the second parameter. If you pass it NULL, it has nowhere to store that, so it will either crash or fail with an invalid parameter error. To avoid that, pass in the address of a local variable:

    RECT rect;
    GetClientRect(..., &rect);