MFC窗口大小變化:OnSIze、OnSizing和OnGetMinMaxInfo區別與關係

----------------------------------------------------------------------------------------------------------------------------------------

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);//將“確認”按鈕移動到新的位置
	}
}







發佈了72 篇原創文章 · 獲贊 269 · 訪問量 76萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章