c ++ WinApi:GetClientRect失败

Jac*_*ack 3 c++ winapi screensaver

我正在编写在Windows上运行的屏幕保护程序.

在预览模式下,Windows以这种方式调用程序:
Screensaver.exe /p ParentWindowHandle

但是,当我在我的程序中进行此调用时:
BOOL res = GetClientRect(parentWindowHandle, rect)
res为FALSE,rect为NULL,我得到ERROR_INVALID_WINDOW_HANDLEGetLastError()

GetWindowRect 给了我相同的结果.

但是,如果我拨打电话BOOL res = IsWindow(parentWindowHandle),我会得到res == TRUE.这不是说我有一个有效的窗口句柄吗?

代码如下所示:

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

    // ...
    // ...
}
Run Code Online (Sandbox Code Playgroud)

Ada*_*eld 7

在64位Windows上,窗口句柄是64位,并且不能适合unsigned int,因此您的强制转换生成一个无效窗口句柄的值.你应该修改你的GetHandleFromCommandLine函数,使它返回一个正确的HWND,而不是一个unsigned int,并且不需要类型转换.

此外,GetClientRect通过将矩形存储到第二个参数指向的值中来返回矩形.如果你通过它NULL,它无处存储它,因此它将崩溃或失败并出现无效的参数错误.为避免这种情况,请传入局部变量的地址:

RECT rect;
GetClientRect(..., &rect);
Run Code Online (Sandbox Code Playgroud)

  • 虽然在Win64上HWND类型确实是64位,但实际值适合32位数据类型:实际上这是必需的,因此32位和64位应用程序可以通过Windows消息进行通信.如果你想亲眼看看这个,启动64位版本的Spy ++,你会发现它只显示了32位的HWND数据.另外,在Win64上,int和long的大小相同:32位; 将转换从int更改为long应该没有区别.(如果您确实需要与指针大小匹配的数据类型,请使用INT_PTR或其他_PTR后缀类型之一.)这里的真正问题可能是RECT. (3认同)