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);
}
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);
}
CStatic 默認不處理 WM_SIZE,其內容(文字/圖片/位圖)由系統繪製,不隨父窗口縮放自動縮放。SS_OWNERDRAW 樣式,在父窗口 OnDrawItem 中自繪,按縮放比例縮放文字/圖片。CStatic 重寫 OnPaint,內部按客戶區大小縮放渲染。CStatic 設置 SS_BITMAP + SS_REALSIZECONTROL,加載位圖後在 OnSize 中 StretchBlt 到目標矩形。參考完整項目示例:MFC 自動縮放類下載(含錨點佈局、最小/最大尺寸限制、多種控件支持)。
OnInitDialog 中記錄初始窗口尺寸(m_originalWidth, m_originalHeight)及各控件初始位置。OnSize 會觸發,需判斷 nType == SIZE_MINIMIZED 直接返回。SetProcessDPIAware 或 Manifest 設置。掌握 OnSize + MoveWindow/SetWindowPos 或 OnDraw + 映射模式 兩大核心模式,即可實現 MFC 界面的完美自適應縮放。