從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;
- }