最近做了一个windows项目需要用到如下api:
BOOL MoveWindow( HWND hWnd, int X, int Y, int nWidth, int nHeight, BOOL bRepaint );
该api的主要功能是改变指定窗口的位置和大小。
在使用过程中发现在传入1024,576的高度和宽度的后,WM_SIZE消息返回的实际高度和宽度分别为1008,560,对此非常不解,遂求助google,发现了如下文章。
http://suite101.com/article/client-area-size-with-movewindow-a17846
阅读后可谓茅塞顿开。
首先要文章解释了如下两个窗口概念
The Client Rectangle(客户区)
这个窗口部分是程序可以使用BeginPaint直接绘画的区域,比窗口实际大小要小。
通过函数GetClientRect(HWND hWnd, RECT * rcClient);获取大小。
The Window Rectangle(窗口区)
包括窗口上的所有控件和菜单项。
通过函数GetWindowRect(HWND hWnd, RECT * rcWindow);获取大小。
恰巧MoveWindow这个函数改变的是The Window Rectangle(窗口区)大小,所以如果你想通过该函数改变客户去大小的话就需要传入高度和宽度的时候把非客户区的高度宽度计算在内。
以下是参考实现代码
void ClientResize(HWND hWnd, int nWidth, int nHeight)
{
RECT rcClient, rcWindow;
POINT ptDiff;
GetClientRect(hWnd, &rcClient);
GetWindowRect(hWnd, &rcWindow);
ptDiff.x = (rcWindow.right - rcWindow.left) - rcClient.right;
ptDiff.y = (rcWindow.bottom - rcWindow.top) - rcClient.bottom;
MoveWindow(hWnd,rcWindow.left, rcWindow.top, nWidth + ptDiff.x, nHeight + ptDiff.y, TRUE);
}