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

MFC 界面自動縮放實現:OnSize 中繪圖縮放與 Static 控件處理

     編輯:程式設計疑難解答

核心思路

MFC 實現界面自動縮放,核心在於 重寫 OnSize 消息處理函數,根據新窗口尺寸計算縮放比例,調整子控件位置/大小或重新繪製客戶區內容。

兩種主要實現模式

模式一:控件位置/大小動態調整(適用於對話框/表單視圖)

void CMyDialog::OnSize(UINT nType, int cx, int cy) {
    CDialogEx::OnSize(nType, cx, cy);
    
    if (!m_bInitialized) return; // OnInitDialog 後才處理
    
    // 計算縮放比例
    double ratioX = (double)cx / m_originalWidth;
    double ratioY = (double)cy / m_originalHeight;
    
    // 遍歷需縮放的控件,調整位置與大小
    RepositionControl(IDC_EDIT1, ratioX, ratioY);
    RepositionControl(IDC_BUTTON_OK, ratioX, ratioY);
    // ...
}

void CMyDialog::RepositionControl(int nID, double ratioX, double ratioY) {
    CWnd* pWnd = GetDlgItem(nID);
    if (!pWnd) return;
    
    CRect rect;
    pWnd->GetWindowRect(&rect);
    ScreenToClient(&rect);
    
    // 根據錨點策略計算新位置(此處簡示:等比例縮放)
    rect.left = (int)(rect.left * ratioX);
    rect.top = (int)(rect.top * ratioY);
    rect.right = (int)(rect.right * ratioX);
    rect.bottom = (int)(rect.bottom * ratioY);
    
    pWnd->MoveWindow(&rect);
}

模式二:OnDraw 中按比例繪圖(適用於視圖類/自繪控件)

void CMyView::OnDraw(CDC* pDC) {
    CMyDoc* pDoc = GetDocument();
    CRect rect;
    GetClientRect(&rect);
    
    // 根據當前客戶區大小計算縮放比例
    double scaleX = (double)rect.Width() / m_baseWidth;
    double scaleY = (double)rect.Height() / m_baseHeight;
    
    // 設置映射模式或手動縮放繪圖座標
    pDC->SetMapMode(MM_ANISOTROPIC);
    pDC->SetWindowExt(m_baseWidth, m_baseHeight);
    pDC->SetViewportExt(rect.Width(), rect.Height());
    
    // 繪製邏輯使用基準座標系,自動映射到當前視口
    DrawContent(pDC); 
}

Static 控件內容不縮放的原因與對策

  • 原因:CStatic 默認不處理 WM_SIZE,其內容(文字/圖片/位圖)由系統繪製,不隨父窗口縮放自動縮放。
  • 對策 1:Owner Draw:設置 SS_OWNERDRAW 樣式,在父窗口 OnDrawItem 中自繪,按縮放比例縮放文字/圖片。
  • 對策 2:替換為自繪控件:繼承 CStatic 重寫 OnPaint,內部按客戶區大小縮放渲染。
  • 對策 3:使用圖片控件 + StretchBlt:CStatic 設置 SS_BITMAP + SS_REALSIZECONTROL,加載位圖後在 OnSize 中 StretchBlt 到目標矩形。

推薦資源

參考完整項目示例:MFC 自動縮放類下載(含錨點佈局、最小/最大尺寸限制、多種控件支持)。

關鍵提示

  1. 在 OnInitDialog 中記錄初始窗口尺寸(m_originalWidth, m_originalHeight)及各控件初始位置。
  2. 最小化/最大化時 OnSize 會觸發,需判斷 nType == SIZE_MINIMIZED 直接返回。
  3. 考慮 DPI 感知:高 DPI 屏幕下需配合 SetProcessDPIAware 或 Manifest 設置。

掌握 OnSize + MoveWindow/SetWindowPos 或 OnDraw + 映射模式 兩大核心模式,即可實現 MFC 界面的完美自適應縮放。

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