C++ ::MoveWindow的问题-留下空白
我非常渴望解决这个非常烦人的问题:( 我试图在父窗口上显示子窗口。有时需要调整窗口的大小。但由于某些原因,当我使用MoveWindow功能时,它会在父窗口顶部留下空白。我想在此处显示图片,但无法发布图片 下面是代码示例:C++ ::MoveWindow的问题-留下空白,c++,windows,winapi,user-interface,mfc,C++,Windows,Winapi,User Interface,Mfc,我非常渴望解决这个非常烦人的问题:( 我试图在父窗口上显示子窗口。有时需要调整窗口的大小。但由于某些原因,当我使用MoveWindow功能时,它会在父窗口顶部留下空白。我想在此处显示图片,但无法发布图片 下面是代码示例: HWND hwnd // Comes from external function. Was defined as WS_CHILD previously HWND hwndParent = ::GetParent(hwnd); RECT parentRect
HWND hwnd // Comes from external function. Was defined as WS_CHILD previously
HWND hwndParent = ::GetParent(hwnd);
RECT parentRect = {0,0,0,0};
RECT childRect = {0,0,0,0};
::GetClientRect(hwndParent, &parentRect); // Suppose it returns {0,0,600,300}
BOOL ok = ::MoveWindow(hwnd, 0, 0, 600, 300, true);
::GetClientRect(hwnd, &childRect); // Will return {0,0,584,297}
为什么??
我做错了什么?我是否忘记了窗口初始化时的一些标志?!
MoveWindow
更新窗口位置,而GetClientRect
获取窗口的客户端区域部分,该部分不必相同。如果您的窗口具有非客户端区域,则一切正常,并按预期工作
如果您仍然觉得子窗口没有完全覆盖父窗口的客户端区域,那么间距属于子控件/窗口,您需要寻找方法将其删除(控件标志、参数等)。
MoveWindow
对窗口坐标进行操作,包括非客户端区域(边框、标题栏等)
GetClientRect
获取窗口客户端部分的区域,忽略边框、标题栏等
这就是不匹配的地方。如果要将
MoveWindow
移动到所需的客户端大小,只需尝试并预测要传递到MoveWindow
的内容。请注意,这并不总是可能的,也不总是准确的。例如,窗口、菜单(可以换行到多行)的最小/最大大小等。使用GetWindowRect
和MapWindowPoints(NULL,hwndParent,&parentRect,2)
而不是使用GetWindowRect
,将其调整到父窗口坐标。GetWindowRect
将包括MoveWindow
所需的非客户端区域
编辑:如果您想要一个没有非客户端区域的窗口,以便窗口矩形和客户端矩形大小相同,则需要修剪应用于窗口的矩形。避免使用WS_边框、WS_标题、WS_DLGFRAME、WS_重叠、WS_大小框和WS_THICKFRAME样式。问题是父窗口的WS_弹出标志。 很奇怪。据我所知,它不应该有这样的影响
感谢大家!您是否应该使用getwindowrect来解释非客户端区域?@Iron Eagle:当父窗口收到WM_PAINT消息时,您是否正确地重新绘制了父窗口?我对您所说的“//假设它返回…”部分表示怀疑.为什么要假设呢?Alex K:-这到底有什么帮助?Alex-是的,重画正在工作。tenfour-我的意思是,我给::MoveWindow的数字与我从::GetClientRect获得的数字相同。数字本身并不重要。但这正是问题所在。我在窗口顶部除了顶部栏外还看到一个空白字段,这意味着窗口中还有一些被视为已被某个对象占用的区域,因此无法使用。我无法理解它是什么。假设即使AdjustWindowRect也会将rect从{0,0600300}设置为{0,0584287}。这仍然留下了一个问题-为什么?这是因为子窗口有一个非客户端区域。子窗口的窗口样式是什么?屏幕截图也很有用。让我对你的观察感到困惑的是“父窗口顶部的空白区域”。即使rect更小,大小也与窗口的顶部无关,只与窗口的底部/右侧有关。只需指定
(0,0)就很容易了
作为上/左坐标。屏幕截图如下:至于窗口样式-这里是WS|u CLIPCHILDREN | WS|u ClipShildren | WS|u ClipShildren | WS|u CHILD。我试着用它们玩,顺便说一句,没用。至于其余的-这正是我试图解决的问题:)当你设置子窗口的位置时,你的左上角坐标应该是(0,0),你知道吗?MoveWindow top/left是相对于父级的客户端窗口区域的。请注意,我的坐标确实是(0.0)(见原始问题中的代码)。然而,问题是-为什么它不放在(0,0)?是的,但我对客户区感兴趣。它没有帮助。尽管如此,它看起来是这样的:可能有一点误解。父窗口应具有简单的窗口样式(名称、X按钮、最小化按钮等)。它有它。问题是没有使用整个客户端区域。客户区内留有空白。请看这幅画。灰色区域中没有任何内容,GetClientRect会返回特定的大小,但由于某些原因,只使用了该大小的一部分。@Iron Eagle,不使用整个客户端区域的原因是整个子窗口必须包含在其中,包括子窗口具有的任何非客户端边框。我的建议是确保子窗口没有任何会创建非客户端区域的样式;如果操作正确,GetClientRect和GetWindowRect将返回相同的大小。使用Spy++验证窗口样式。以下是Spy信息。如您所见,由于某种原因,客户端区域移动到(3,64)而不是(0,0)。你能告诉我为什么吗?好的。这正是我所想的!似乎还有一个地方可以放其他东西,比如顶部菜单和窗口边框,还有一些标志我需要调整。但是你能告诉我什么标志吗?它可能是WS.*
和WS.*EX.*
窗口样式标志。它有16像素宽,只有3像素高,所以我假设这是一种边界。无论如何,您甚至没有提到这些控件是什么,一些标准或自定义控件,或者第三方控件?这给猜测留下了太多的空间。对不起,我没有完全理解你的意思。你的意思是什么?你有两个窗口,一个家长和一个孩子。它们是什么,它们是什么类型的窗口?以下是子窗口的间谍信息: