从win7开始,windows的特性中具备了拖动窗口到屏幕边界时最大化,还原,或者占据半个工作区的功能,
如果希望自己的窗口具体这种特性,那么需要在窗口属性中添加 WS_BORDERG与WS_THICKFRAME,
但是对于DirectUI绘制的一些窗口时,在窗口创建时就添加WS_THICKFRAME会造成窗口的边框由系统绘制,不符合设计效果
解决方法是创建时使用
WS_BORDER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX
而后处理WM_NCCALCSIZE消息
-
LRESULT EditorFrame::OnNcCalcSzie(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
-
{
-
bHandled = TRUE;
-
LONG style = GetWindowLong(m_hWnd, GWL_STYLE);
-
if ((style & WS_THICKFRAME) ==
0)
-
SetWindowLong(m_hWnd, GWL_STYLE, style | WS_THICKFRAME);
-
return S_OK;
-
}
此时应该已经具备了拖动边缘响应最大化/还原的特性,但是可能会有新的问题,就是最大化的边框并不切合显示器的边,
此时需要处理WM_GETMINMAXINFO消息
-
LRESULT EditorFrame::OnGetMinMaxInfo(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
-
{
-
bHandled = TRUE;
-
MINMAXINFO* lpmmi = (MINMAXINFO*)lParam;
-
lpmmi->ptMaxPosition.x =
0;
-
lpmmi->ptMaxPosition.y =
0;
-
-
MONITORINFO oMonitor = {};
-
oMonitor.cbSize =
sizeof(oMonitor);
-
::GetMonitorInfo(::MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST), &oMonitor);
-
lpmmi->ptMaxSize.x = oMonitor.rcWork.right - oMonitor.rcWork.left;
-
lpmmi->ptMaxSize.y = oMonitor.rcWork.bottom - oMonitor.rcWork.top;
-
-
SIZE mini_size = {
0 };
-
mini_size.cx = NO_BORDER_MINI_WIDTH;
-
mini_size.cy = NO_BORDER_MINI_HEIGHT;
-
lpmmi->ptMinTrackSize.x = mini_size.cx;
-
lpmmi->ptMinTrackSize.y = mini_size.cy;
-
return S_OK;
-
}
这样前一个问题差不多解决了,但是在win10系统下贴合左边框时出来了边框绘制的问题
经过尝试,处理WM_NCACTIVATE消息可以避免这种情况出现的可能性
-
LRESULT EditorFrame::OnNcActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
-
{
-
bHandled = TRUE;
-
if (::IsIconic(m_hWnd)) bHandled = FALSE;
-
return (wParam ==
0) ? TRUE : FALSE;
-
}