首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

MFC 對話框大小固定與動態邊界適配完整指南

     編輯:程式設計綜合問答

MFC 初學者開發「飛機大戰」類遊戲時,常遇到執行期調整對話框大小導致遊戲元素顯示異常、邊界檢測失效的問題。本文提供從視覺設計到邏輯適配的完整解決方案。

方案一:禁止使用者調整視窗大小(最簡單)

  1. 打開資源視圖,雙擊對話框資源進入編輯器。
  2. 在屬性視窗中找到 Border 屬性,設為 None 或 Thin(去掉可調整邊框)。
  3. 取消 MaximizeBox、MinimizeBox 勾選。
  4. 在 OnInitDialog() 中呼叫 SetWindowPos() 鎖定初始尺寸:
BOOL CGameDlg::OnInitDialog() {
    CDialogEx::OnInitDialog();
    // 固定 800x600,不可調整
    SetWindowPos(NULL, 0, 0, 800, 600, 
                 SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER);
    return TRUE;
}

方案二:允許調整但動態重算遊戲邊界(進階)

若需支援全螢幕或可調整視窗,必須在 OnSize() 訊息處理器中同步更新遊戲邏輯邊界:

void CGameDlg::OnSize(UINT nType, int cx, int cy) {
    CDialogEx::OnSize(nType, cx, cy);
    if (cx <= 0 || cy <= 0) return; // 最小化時略過
    
    // 更新遊戲世界邊界
    m_rcGameBoundary.SetRect(0, 0, cx, cy);
    
    // 通知遊戲物件重新計算位置/速度
    for (auto& obj : m_gameObjects) {
        obj->OnBoundaryChanged(m_rcGameBoundary);
    }
    
    Invalidate(TRUE); // 觸發重繪
}

繪圖效能優化關鍵點

  • 雙重緩衝:在 OnPaint() 使用 CMemDC 避免閃爍。
  • 裁剪區繪製:僅重繪 GetClipBox() 範圍內的物件。
  • 遊戲迴圈分離:使用 SetTimer(1, 16, NULL) (≈60 FPS) 驅動邏輯更新,OnTimer() 呼叫 InvalidateRect() 而非直接繪圖。

常見坑點提醒

  1. OnSize() 在建立視窗時也會觸發一次 (cx=cy=0),需加保護判斷。
  2. 子控制項 (按鈕、編輯框) 若需跟隨縮放,可在 OnSize() 中呼叫 MoveWindow() 或使用 CResizeDialog 輔助類。
  3. 遊戲座標系統建議採用「邏輯座標 → 裝置座標」映射函式,而非硬編碼像素值。

選擇方案一可快速完成教學級專案;方案二則為未來擴展全螢幕、多解析度支援奠定基礎。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved