首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

MFC 對話框全螢幕切換實作:WINDOWPLACEMENT 與 OnGetMinMaxInfo

     編輯:關於C語言

播放器類應用常需「全螢幕」模式:隱藏標題列、選單、工作列,佔滿整個螢幕工作區。本文提供基於 `WINDOWPLACEMENT` 保存/恢復狀態、配合 `OnGetMinMaxInfo` 限制最大化尺寸的完整 MFC 實作,僅需少量程式碼即可整合至現有 `CDialog`/`CDialogEx` 專案。

核心資料成員

class CFullScreenDlg : public CDialog {
    // ...
protected:
    WINDOWPLACEMENT m_wpPrev;      // 保存進入全螢幕前的視窗狀態
    CRect m_rcFullScreenRect;      // 全螢幕目標矩形 (經 AdjustWindowRectEx 修正)
    bool m_bFullScreen = false;    // 目前狀態旗標
};

全螢幕切換核心函數

void CFullScreenDlg::FullScreenView() {
    if (!m_bFullScreen) {
        // 1. 保存當前視窗完整狀態 (位置、尺寸、最大化/最小化狀態)
        GetWindowPlacement(&m_wpPrev);

        // 2. 取得桌面工作區矩形 (排除工作列)
        CRect rcDesk;
        ::GetWindowRect(::GetDesktopWindow(), &rcDesk);
        // 3. 依視窗風格修正為客戶區對應的視窗矩形
        ::AdjustWindowRectEx(&rcDesk, GetStyle(), FALSE, GetExStyle());
        m_rcFullScreenRect = rcDesk;

        // 4. 準備新視窗配置
        WINDOWPLACEMENT wpNew = m_wpPrev;
        wpNew.showCmd = SW_SHOWNORMAL;      // 正常顯示 (非最大化/最小化)
        wpNew.rcNormalPosition = m_rcFullScreenRect;
        m_bFullScreen = true;

        // 5. 套用
        SetWindowPlacement(&wpNew);
    } else {
        // 退出全螢幕:直接恢復原狀態
        m_bFullScreen = false;
        SetWindowPlacement(&m_wpPrev);
    }
}

配合 OnGetMinMaxInfo 防止使用者拖曳破壞全螢幕

void CFullScreenDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI) {
    if (m_bFullScreen) {
        // 強制最大/最小追蹤尺寸皆等於全螢幕矩形
        lpMMI->ptMaxSize = m_rcFullScreenRect.Size();
        lpMMI->ptMaxTrackSize = lpMMI->ptMaxSize;
        lpMMI->ptMinTrackSize = lpMMI->ptMaxSize; // 可選:也禁止縮小
    }
    CDialog::OnGetMinMaxInfo(lpMMI);
}

快捷鍵觸發範例 (雙擊標題列或 Alt+Enter)

// 在 OnLButtonDblClk 或 PreTranslateMessage 中
void CFullScreenDlg::OnLButtonDblClk(UINT nFlags, CPoint point) {
    // 僅在標題列區域雙擊觸發
    if (SendMessage(WM_NCHITTEST, 0, MAKELPARAM(point.x, point.y)) == HTCAPTION)
        FullScreenView();
    CDialog::OnLButtonDblClk(nFlags, point);
}

// 或覆寫 PreTranslateMessage 攔截 Alt+Enter
BOOL CFullScreenDlg::PreTranslateMessage(MSG* pMsg) {
    if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN && GetKeyState(VK_MENU) & 0x8000) {
        FullScreenView();
        return TRUE;
    }
    return CDialog::PreTranslateMessage(pMsg);
}

關鍵細節說明

  • GetWindowPlacement/SetWindowPlacement 完整保存/恢復 **最大化/最小化/正常狀態、位置、尺寸**,比單純 `GetWindowRect`/`MoveWindow` 魯棒。
  • AdjustWindowRectEx 依視窗風格 (標題列、邊框、選單) 將「客戶區期望尺寸」反推為「視窗外部矩形」,確保全螢幕時客戶區精確貼合螢幕邊緣。
  • OnGetMinMaxInfo 在使用者拖曳邊框、雙擊標題列最大化時被系統呼叫,設定 `ptMaxTrackSize` 可強制限制拖曳上限。
  • 多螢幕環境下,`GetDesktopWindow()` 返回虛擬螢幕聯集矩形,若需單一監視器全螢幕,應改用 `MonitorFromWindow` + `GetMonitorInfo` 取得工作區。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved