【问题标题】:Troubles with ::MoveWindow - leaving blank space::MoveWindow 的问题 - 留下空白
【发布时间】:2011-10-12 10:37:36
【问题描述】:

我非常渴望解决这个非常烦人的问题:( 我正在尝试在父窗口上显示一个子窗口。有时需要调整窗口大小。但是由于某种原因,当我使用 MoveWindow 函数时,它会在父窗口的顶部留下空白。我想在这里展示一张图片,但我不能发布图片。

下面是代码示例:

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}  

为什么?????

我做错了什么?我是否忘记了一些窗口初始化标志?!

【问题讨论】:

  • 您是否应该使用 getwindowrect 来代替客户区?
  • @Iron-Eagle:当父窗口收到WM_PAINT消息时,你是否正确重绘父窗口?
  • 我对你所说的“//假设它返回......”的部分持怀疑态度。为什么要假设什么?
  • Alex K: - 它到底有什么帮助?亚历克斯 - 是的,重绘正在工作。 tenfour - 我的意思是我给 ::MoveWindow 的数字与我从 ::GetClientRect 得到的数字相同。数字本身并不重要。

标签: c++ windows winapi user-interface mfc


【解决方案1】:

不要使用GetClientRect,而是使用GetWindowRectMapWindowPoints(NULL,hwndParent,&parentRect,2)将其调整为父窗口坐标。 GetWindowRect 将包含MoveWindow 需要的非客户区。

编辑:如果您想要一个没有非客户区的窗口,因此窗口矩形和客户端矩形大小相同,您需要修剪您设置的 window styles适用于窗口。避免使用 WS_BORDER、WS_CAPTION、WS_DLGFRAME、WS_OVERLAPPED、WS_SIZEBOX 和 WS_THICKFRAME 样式。

【讨论】:

  • 是的,但我对客户区感兴趣。
  • 它没有帮助。不过,它看起来像这样:i32.fastpic.ru/big/2011/1016/39/…
  • 可能有点误会。父窗口应具有简单的窗口样式(名称、X 按钮、最小化按钮等)。它拥有它。问题是没有使用整个 CLIENT-AREA。 CLIENT 区域内有一个空白区域。请看图片。灰色区域没有任何内容,GetClientRect 返回一定的大小,但由于某种原因,只使用了这个大小的一部分。
  • @Iron-Eagle,不使用整个客户区的原因是整个子窗口必须适合它,包括子窗口的任何非客户边框.我的建议是确保子窗口没有任何会创建非客户区的样式;如果操作正确,GetClientRect 和 GetWindowRect 将返回相同的大小。使用 Spy++ 验证窗口样式。
  • 这里是间谍信息。 i32.fastpic.ru/big/2011/1017/a5/… 如您所见,出于某种原因,客户区移动到 (3, 64) 而不是 (0,0)。你能说出原因吗?
【解决方案2】:

MoveWindow 更新窗口位置,而GetClientRect 获取窗口的客户区部分,不必相同。如果您的窗口有非客户区,那么一切都很好并且按预期工作。

如果您仍然认为子窗口没有完全覆盖父窗口的客户区,那么间距属于子控件/窗口,您需要寻找将其删除的方法(控件标志、参数等)。

【讨论】:

  • 好的。这正是我的想法!似乎还有一个地方可以放置其他东西,比如顶部菜单和窗口边框,还有一些我需要调整的标志。但是你能告诉我什么标志吗?
  • 可能是WS_*WS_EX_* 窗口样式标志。它只有 16 像素宽和 3 像素高,所以我认为这些是某种边界。无论如何,您甚至没有提到这些控件是什么,一些标准或自定义,或第三方控件?这给猜测留下了太多空间。
  • 很抱歉我没有完全理解你。你的意思是什么控制?
  • 你有两个窗口,一个父窗口和一个子窗口。它们是什么,它们是什么样的窗户?
  • 这里是子窗口的spy信息:i32.fastpic.ru/big/2011/1017/a5/…
【解决方案3】:

MoveWindow 作用于窗口坐标——包括非客户区(边框、标题栏等)。

GetClientRect 获取窗口客户部分的区域,忽略边框、标题栏等

这就是不匹配的地方。如果您想将MoveWindow 设置为所需的client 大小,您只需要AdjustWindowRect 来尝试预测要传递给MoveWindow 的内容。请注意,这并不总是可能的,而且并不总是准确的。例如窗口、菜单(可以换行到多行)等的最小/最大尺寸。

【讨论】:

  • 但这正是问题所在。我在顶部栏的添加中看到窗口顶部的空白字段,这意味着窗口中有其他东西被视为已被某物占用的区域,因此无法使用。我无法理解它是什么。假设甚至 AdjustWindowRect 会将矩形从 {0,0,600,300} 设置为 {0,0,584,287}。它仍然留下一个问题 - 为什么?
  • 因为子窗口有非客户区。子窗口的窗口样式有哪些?屏幕截图也很有帮助。让我对您的观察感到困惑的是“父窗口顶部的空白区域”。即使矩形较小,大小也与窗口顶部无关,仅与底部/右侧有关。将(0,0) 指定为上/左坐标非常简单。
  • 好吧,这是屏幕截图:i32.fastpic.ru/big/2011/1016/39/… 至于窗口样式 - 这里是 WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD。我试着和他们一起玩,顺便说一句,它没有帮助。至于其余的 - 这正是我要解决的问题:)
  • 当您设置子窗口的位置时,您的上/左坐标应该只是 (0,0) 您意识到了吗? MoveWindow top/left 是相对于父客户窗口区域的。
  • 嗯,我当然知道。请注意我的坐标确实(0.0)(参见原始问题中的代码)。然而,问题是 - 为什么它没有放在 (0,0) 处?
【解决方案4】:

问题是父窗口的 WS_POPUP 标志。 很奇怪。据我所知,它不应该有这样的效果。

谢谢大家!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 2023-03-03
    • 1970-01-01
    • 2013-06-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多