----------------------------------------------------------------------------------------------------------------------------------------
MFC編寫時,經常需要在運行時動態調整窗口大小,並且使裏面的控件和視圖也隨窗口的尺寸變化而發生變化。
在這之間,您需要在資源視圖中,設置該窗口的“Border屬性”爲Resizing,從而使窗口可以調整大小。
----------------------------------------------------------------------------------------------------------------------------------------
爲了產生OnSIze、OnSizing和OnGetMinMaxInfo三個函數,需要在【類嚮導】中給對應的窗口的WM_SIZE、WM_SIZING、WM_GETMINMAXINFO三個消息添加消息處理函數。
當窗口大小發生動態變化時,響應的順序依次是:WM_GETMINMAXINFO-->WM_SIZING-->WM_SIZE。
OnGetMinMaxInfo()
該函數在窗口初始化時會被調用一次,然後在窗口大小發生改變時也會被調用。利用該函數,可以比較方便的實現窗口最大最小尺寸的控制。
參數lpMMI是一個指向MINMAXINFO 結構體的指針,包含了有關窗口的尺寸信息,其中包括最大化大小和位置、窗口的最大最小跟蹤範圍。
函數使用案例如下:
void CTestDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
{//控制窗口最小尺寸
lpMMI->ptMinTrackSize.x = m_min_width;//x:寬度;m_min_width爲對話框類CTestDLg的私有變量,在OnInitDialog()中已賦值
lpMMI->ptMinTrackSize.y = m_min_height;//y:高度,m_min_height爲對話框類CTestDlg的私有變量,在OnInitDialog()中已賦值
CDialogEx::OnGetMinMaxInfo(lpMMI);
}
OnSizing()
該函數在窗口大小發生變化時被調用。用該函數也可以控制窗口的最大最小尺寸,但是沒有OnGetMinMaxInfo()函數方便。
函數使用案例如下:
void CTestDlg::OnSizing(UINT fwSide, LPRECT pRect)
{
CDialogEx::OnSizing(fwSide, pRect);
//框架調用該成員函數指示用戶調整矩形
//通過處理此消息,應用程序可以監視拖動矩形的大小和位置,因此,如果需要,更改其大小或位置。
int Width = pRect->right - pRect->left;//計算“變化當前”窗口寬度
int Height = pRect->bottom - pRect->top;//計算“變化當前”窗口高度
//若“變化寬度”小於設定的最小寬度,則把真實寬度設置爲最小寬度
if (Width < m_min_width)
pRect->right = pRect->left + m_min_width;
if (Height < m_min_height)
pRect->bottom = pRect->top + m_min_height;
}
注意:用上面的方法,若從窗口右邊調節其大小,可以達到想要的效果;但是從左邊調節窗口大小時,雖然大小可以控制在約定尺寸,但是當達到最小寬度後,再縮小窗口時,會發現整個窗口往右移動了。原因在於代碼中pRect->right = pRect->left + MinWidth;這條語句是相對left來改變right的,而對left沒有約束,所有left移動了,right也跟着移動。看上去就像窗口右移了。所以針對這種情況要另外做相應處理。
OnSizie()
該函數會在窗口大小改變結束後被調用,通常我們會在該函數中重新計算各個空間的位置及大小,並重繪。但用這個函數沒有辦法控制窗口的最大最小尺寸。
函數使用案例如下:
void CTestDlg::OnSize(UINT nType, int cx, int cy)
{
CDialogEx::OnSize(nType, cx, cy);
// TODO: 在此處添加消息處理程序代碼
CRect current_dialog_rect;
GetClientRect(¤t_dialog_rect);//捕獲窗口大小變化後的窗口大小
CWnd * p_wnd;//用於獲取窗口元素
CRect rect;
//重新計算“確認”按鈕的位置,left、top、right、bottom
rect.left = 20;
rect.top = 20;
rect.right = rect.left + 100;
rect.bottom = rect.top + 40;
p_wnd = GetDlgItem(IDC_BUTTON_OK);//通過“確認”按鈕的ID來得到按鈕元素
if (p_wnd)
{
p_wnd->MoveWindow(&rect);//將“確認”按鈕移動到新的位置
}
}