Windows窗口样式的一些猫腻
2018-03-07 本文已影响0人
赵海洋
机器环境:Windows 10 1709 (16299.192)
在我们的ui库中使用最小窗口属性来创建一个20px宽度的窗口时,发现有它显示出来一直是120px宽度,而我们的ui库中处理了WM_GETMINMAXINFO,返回了20px的最小宽度,不知道为什么没有生效。
然后尝试在WM_CREATE消息处使用MoveWindows来设置一下大小,依然还是120px。
经过一番研究,发现CreateWindows时如果Style的组合不同,会限制第一次MoveWindows的大小,如果连续两次调用MoveWindow(m_hWnd, 0, 0, 20, 720, true); 则窗口大小能变成20px。
经测试,窗口风格测试用例组合如下:
- WS_POPUP | WS_MINIMIZEBOX 无默认最小大小
- WS_POPUP | WS_SYSMENU 无默认最小大小
- WS_OVERLAPPED 默认最小32
- WS_OVERLAPPED | WS_SYSMENU 默认最小54
- WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX 默认最小120
由上可见,关键点在于WS_OVERLAPPED,有它后窗口默认最小会受到限制。并且,这个限制仅对MoveWindow有效,如果是使用SetWindowPos则限制无效。
比如:使用WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX 风格的窗口,在WM_CREATE处,使用以下两种方式设置大小(后续不再调用其它大小调整函数)。
MoveWindow(m_hWnd, 0, 0, 20, 720, true); // 无效,窗口大小是120px
::SetWindowPos(m_hWnd, NULL, 0, 0, 20, 720, SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOSENDCHANGING);
// 有效