使窗口具備拖動到邊界自動最大化/還原的特性

從win7開始,windows的特性中具備了拖動窗口到屏幕邊界時最大化,還原,或者佔據半個工作區的功能,

如果希望自己的窗口具體這種特性,那麼需要在窗口屬性中添加 WS_BORDERG與WS_THICKFRAME,

但是對於DirectUI繪製的一些窗口時,在窗口創建時就添加WS_THICKFRAME會造成窗口的邊框由系統繪製,不符合設計效果



解決方法是創建時使用

WS_BORDER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX 

而後處理WM_NCCALCSIZE消息


  1. LRESULT EditorFrame::OnNcCalcSzie(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  2. {
  3. bHandled = TRUE;
  4. LONG style = GetWindowLong(m_hWnd, GWL_STYLE);
  5. if ((style & WS_THICKFRAME) == 0)
  6. SetWindowLong(m_hWnd, GWL_STYLE, style | WS_THICKFRAME);
  7. return S_OK;
  8. }

此時應該已經具備了拖動邊緣響應最大化/還原的特性,但是可能會有新的問題,就是最大化的邊框並不切合顯示器的邊,


此時需要處理WM_GETMINMAXINFO消息 

  1. LRESULT EditorFrame::OnGetMinMaxInfo(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  2. {
  3. bHandled = TRUE;
  4. MINMAXINFO* lpmmi = (MINMAXINFO*)lParam;
  5. lpmmi->ptMaxPosition.x = 0;
  6. lpmmi->ptMaxPosition.y = 0;
  7. MONITORINFO oMonitor = {};
  8. oMonitor.cbSize = sizeof(oMonitor);
  9. ::GetMonitorInfo(::MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST), &oMonitor);
  10. lpmmi->ptMaxSize.x = oMonitor.rcWork.right - oMonitor.rcWork.left;
  11. lpmmi->ptMaxSize.y = oMonitor.rcWork.bottom - oMonitor.rcWork.top;
  12. SIZE mini_size = { 0 };
  13. mini_size.cx = NO_BORDER_MINI_WIDTH;
  14. mini_size.cy = NO_BORDER_MINI_HEIGHT;
  15. lpmmi->ptMinTrackSize.x = mini_size.cx;
  16. lpmmi->ptMinTrackSize.y = mini_size.cy;
  17. return S_OK;
  18. }



這樣前一個問題差不多解決了,但是在win10系統下貼合左邊框時出來了邊框繪製的問題


經過嘗試,處理WM_NCACTIVATE消息可以避免這種情況出現的可能性

  1. LRESULT EditorFrame::OnNcActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  2. {
  3. bHandled = TRUE;
  4. if (::IsIconic(m_hWnd)) bHandled = FALSE;
  5. return (wParam == 0) ? TRUE : FALSE;
  6. }






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章