MFC 控制元件大小隨窗體改變而改變大小-OnSize
轉載:https://blog.csdn.net/zhoxier/article/details/7776128
一個基於對話方塊的MFC介面,怎麼樣才能讓對話方塊裡的控制元件能和對話方塊同比例變小變大?今天我一直想解決這個問題,這是師姐留給我的任務。經過在網上的大量搜素,終於找到了解決方法,其實比較簡單。
一般情況下,我們新建的對話方塊,裡面的“確定”和:取消”按鈕,在對話方塊最大化得時候,不會一起變大的,而是保持原來的大小。
最簡單的情況:
我們可以採取下面的措施:對話方塊也是視窗,最大化是對視窗大小的改變,而在windows messagehandle中有個WM_SIZE的訊息,該訊息在視窗大小發生變化的時候會產生。那麼我們可以根據這個訊息,在視窗大小發生變化的時候,利用MoveWindow()函式來重新設定各個控制元件的大小。
還是以上面最簡單的情況為例子:
1
在對話方塊類中新增成員變數 CRect m_rect 他是用來記錄當前對話方塊的大小。我們在OnInitDialog()函式中獲取對話方塊建立時的大小:GetClientRect(&m_rect);
2 增加訊息WM_SIZE的訊息響應函式 OnSize():只要對話方塊大小發生變化,就會呼叫該函式。
3 在OnSize()函式中增加如下程式碼:(最簡單的為例子,就一個確定按鈕和取消按鈕)
來源:(http://blog.sina.com.cn/s/blog_4b5039210100dzkd.html
voidCTestDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
for (int i=1;i<=2;i++) //因為是兩個控制元件,所以這裡用了迴圈
{
CWnd*pWnd;
pWnd = GetDlgItem(i); //獲取ID為i的空間的控制代碼,因為“確認”ID為1,“取消”ID為2
if(pWnd) //判斷是否為空,因為對話方塊建立時會呼叫此函式,而當時控制元件還未建立
{
CRect rect; //獲取控制元件變化前的大小
pWnd->GetWindowRect(&rect);
ScreenToClient(&rect//將控制元件大小轉換為在對話方塊中的區域座標
//cx/m_rect.Width()為對話方塊在橫向的變化比例
rect.left=rect.left*cx/m_rect.Width();//調整控制元件大小
rect.right=rect.right*cx/m_rect.Width();
rect.top=rect.top*cy/m_rect.Height();
rect.bottom=rect.bottom*cy/m_rect.Height();
pWnd->MoveWindow(rect);//設定控制元件大小
}
}
GetClientRect(&m_rect);// 將變化後的對話方塊大小設為舊大小
}
然後執行,當對話方塊最大化的時候,兩個按鈕也變大了。
(因為全屏圖太大,我只截取了右上角的部分)
PS:其實這種方法實現起來簡單,但是是存在問題的,如果介面有很多控制元件,那個當你拖拽視窗的角的時候,經過幾次變大變小,你會發現其實裡面的控制元件已經失真了,就不是原來的長寬比例了。那麼要實現不管視窗怎麼變,裡面的控制元件不但大小跟著變,而且大小比例也跟著變,那就不是這個OnSize函式那麼簡單了,實現起來有點複雜。等我掌握了這個複雜的方法,一定會拿來分享的。
二
如果對話方塊或視類的大小調後,控制元件的大小和位置沒有變化,介面看起來會很不爽.
控制元件是從CWnd派生的,但不能使用SetWindowPos()或OnSize()或OnSizing()來改變其大小,應在父視窗的WM_SIZE訊息中使用MoveWindow()來進行調整。
VC++之根據對話方塊大小調整控制元件大小
1、在對話方塊類中加入成員變數CRect m_rect;用於儲存對話方塊大小變化前的大小;
2、在對話方塊的OnInitDialog()函式中獲取對話方塊建立時的大小:
GetClientRect(&m_rect);
3、在WM_SIZE的響應函式OnSize()中加入以下程式碼:
CWnd *pWnd;
pWnd = GetDlgItem(IDC_LIST); //獲取控制元件控制代碼
if(pWnd)//判斷是否為空,因為對話方塊建立時會呼叫此函式,而當時控制元件還未建立
{
CRect rect; //獲取控制元件變化前大小
pWnd->GetWindowRect(&rect);
ScreenToClient(&rect);//將控制元件大小轉換為在對話方塊中的區域座標
// cx/m_rect.Width()為對話方塊在橫向的變化比例
rect.left=rect.left*cx/m_rect.Width();/////調整控制元件大小
rect.right=rect.right*cx/m_rect.Width();
rect.top=rect.top*cy/m_rect.Height();
rect.bottom=rect.bottom*cy/m_rect.Height();
pWnd->MoveWindow(rect);//設定控制元件大小
}
GetClientRect(&m_rect);//將變化後的對話方塊大小設為舊大小
三
如果是裡面只有一兩個控制元件倒好辦,但控制元件太多的話這樣做是不是重複勞動太多了?
有沒有更好的辦法啊?
視類中加成員函式和成員變數:
void SetControlInfo(WORD CtrlId);
protected:
int m_old_cx,m_old_cy;
CDWordArray m_control_info;
建構函式中初始化:
m_old_cx = m_old_cy = 0;
加控制元件資訊的函式定義:
void CTestFormView::SetControlInfo(WORD CtrlId)
{
m_control_info.Add(CtrlId);
}
修改OnSize函式:
void CTestFormView::OnSize(UINT nType, int cx, int cy)
{
if(cx==0 || cy==0)
{
cx=800;
cy=600;
}
CFormView::OnSize(nType, cx, cy);
float dx_percent = (m_old_cx ==0)? 1 : (float)((float)cx/(float)m_old_cx);
float dy_percent = (m_old_cy ==0)? 1 : (float)((float)cy/(float)m_old_cy);
if(m_old_cx)
{
CRect WndRect;
CWnd *pWnd;
for(int i = 0; i < m_control_info.GetSize(); i++)
{
pWnd = GetDlgItem(m_control_info[i]);
if(!pWnd)
{
TRACE( “Control ID - %d NOT FOUND!!\n “,m_control_info[i]);
continue;
}
pWnd-> GetWindowRect(&WndRect);
ScreenToClient(&WndRect);
WndRect.left = (int)(WndRect.left*dx_percent);
WndRect.right = (int)(WndRect.right* dx_percent);
WndRect.bottom = (int)(WndRect.bottom*dy_percent);
WndRect.top = (int)(WndRect.top*dy_percent);
pWnd-> MoveWindow(&WndRect);
}
}
m_old_cx = cx;
m_old_cy = cy;
}
在OnInitialUpdate函式中加入控制元件ID:
SetControlInfo(IDC_BUTTON1);
。。。。。。。。。。。。。。。。
執行,搞定!
Dialog也一樣!
上面是轉載的內容,補充一些,就是,當在執行上面的程式後,當dlg為僅剩下標題欄時,再放大,就不會顯示內部的控制元件,那麼自己設定了窗體的最小值:
void CDataBaseConfigDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
{
// TODO: 在此新增訊息處理程式程式碼和/或呼叫預設值
if(lpMMI->ptMinTrackSize.x <= 800)
lpMMI->ptMinTrackSize.x = 800;
if(lpMMI->ptMinTrackSize.y <= 500)
lpMMI->ptMinTrackSize.y = 500;
CDialogEx::OnGetMinMaxInfo(lpMMI);
}
方法也是在網上看到的!
一個基於對話方塊的MFC介面,怎麼樣才能讓對話方塊裡的控制元件能和對話方塊同比例變小變大?今天我一直想解決這個問題,這是師姐留給我的任務。經過在網上的大量搜素,終於找到了解決方法,其實比較簡單。
一般情況下,我們新建的對話方塊,裡面的“確定”和:取消”按鈕,在對話方塊最大化得時候,不會一起變大的,而是保持原來的大小。
最簡單的情況:
當我們點選最大化按鈕的時候,對話方塊會最大化,但是控制元件“確定”和“取消”不會跟著變大。如果我們在對話方塊上面有多少控制元件,那麼會很醜,而且很不實用,最大化本來就是想看的更清楚嘛。
我們可以採取下面的措施:對話方塊也是視窗,最大化是對視窗大小的改變,而在windows messagehandle中有個WM_SIZE的訊息,該訊息在視窗大小發生變化的時候會產生。那麼我們可以根據這個訊息,在視窗大小發生變化的時候,利用MoveWindow()函式來重新設定各個控制元件的大小。
還是以上面最簡單的情況為例子:
1 首先要知道對話方塊大小是否改變,改變了多少,我們應該記錄當前對話方塊的大小。
在對話方塊類中新增成員變數 CRect m_rect 他是用來記錄當前對話方塊的大小。我們在OnInitDialog()函式中獲取對話方塊建立時的大小:GetClientRect(&m_rect);
2 增加訊息WM_SIZE的訊息響應函式 OnSize():只要對話方塊大小發生變化,就會呼叫該函式。
3 在OnSize()函式中增加如下程式碼:(最簡單的為例子,就一個確定按鈕和取消按鈕)
來源:(http://blog.sina.com.cn/s/blog_4b5039210100dzkd.html)- MFC:如何讓對話方塊中的控制元件和對話方塊一起變小變大_蕭蕭_新浪部落格
voidCTestDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
for (int i=1;i<=2;i++) //因為是兩個控制元件,所以這裡用了迴圈
{
CWnd*pWnd;
pWnd = GetDlgItem(i); //獲取ID為i的空間的控制代碼,因為“確認”ID為1,“取消”ID為2
if(pWnd) //判斷是否為空,因為對話方塊建立時會呼叫此函式,而當時控制元件還未建立
{
CRect rect; //獲取控制元件變化前的大小
pWnd->GetWindowRect(&rect);
ScreenToClient(&rect//將控制元件大小轉換為在對話方塊中的區域座標
//cx/m_rect.Width()為對話方塊在橫向的變化比例
rect.left=rect.left*cx/m_rect.Width();//調整控制元件大小
rect.right=rect.right*cx/m_rect.Width();
rect.top=rect.top*cy/m_rect.Height();
rect.bottom=rect.bottom*cy/m_rect.Height();
pWnd->MoveWindow(rect);//設定控制元件大小
}
}
GetClientRect(&m_rect);// 將變化後的對話方塊大小設為舊大小
}
然後執行,當對話方塊最大化的時候,兩個按鈕也變大了。
(因為全屏圖太大,我只截取了右上角的部分)
PS:其實這種方法實現起來簡單,但是是存在問題的,如果介面有很多控制元件,那個當你拖拽視窗的角的時候,經過幾次變大變小,你會發現其實裡面的控制元件已經失真了,就不是原來的長寬比例了。那麼要實現不管視窗怎麼變,裡面的控制元件不但大小跟著變,而且大小比例也跟著變,那就不是這個OnSize函式那麼簡單了,實現起來有點複雜。等我掌握了這個複雜的方法,一定會拿來分享的。
二
如果對話方塊或視類的大小調後,控制元件的大小和位置沒有變化,介面看起來會很不爽.
控制元件是從CWnd派生的,但不能使用SetWindowPos()或OnSize()或OnSizing()來改變其大小,應在父視窗的WM_SIZE訊息中使用MoveWindow()來進行調整。
VC++之根據對話方塊大小調整控制元件大小
1、在對話方塊類中加入成員變數CRect m_rect;用於儲存對話方塊大小變化前的大小;
2、在對話方塊的OnInitDialog()函式中獲取對話方塊建立時的大小:
GetClientRect(&m_rect);
3、在WM_SIZE的響應函式OnSize()中加入以下程式碼:
CWnd *pWnd;
pWnd = GetDlgItem(IDC_LIST); //獲取控制元件控制代碼
if(pWnd)//判斷是否為空,因為對話方塊建立時會呼叫此函式,而當時控制元件還未建立
{
CRect rect; //獲取控制元件變化前大小
pWnd->GetWindowRect(&rect);
ScreenToClient(&rect);//將控制元件大小轉換為在對話方塊中的區域座標
// cx/m_rect.Width()為對話方塊在橫向的變化比例
rect.left=rect.left*cx/m_rect.Width();/////調整控制元件大小
rect.right=rect.right*cx/m_rect.Width();
rect.top=rect.top*cy/m_rect.Height();
rect.bottom=rect.bottom*cy/m_rect.Height();
pWnd->MoveWindow(rect);//設定控制元件大小
}
GetClientRect(&m_rect);//將變化後的對話方塊大小設為舊大小
三
如果是裡面只有一兩個控制元件倒好辦,但控制元件太多的話這樣做是不是重複勞動太多了?
有沒有更好的辦法啊?
視類中加成員函式和成員變數:
void SetControlInfo(WORD CtrlId);
protected:
int m_old_cx,m_old_cy;
CDWordArray m_control_info;
建構函式中初始化:
m_old_cx = m_old_cy = 0;
加控制元件資訊的函式定義:
void CTestFormView::SetControlInfo(WORD CtrlId)
{
m_control_info.Add(CtrlId);
}
修改OnSize函式:
void CTestFormView::OnSize(UINT nType, int cx, int cy)
{
if(cx==0 || cy==0)
{
cx=800;
cy=600;
}
CFormView::OnSize(nType, cx, cy);
float dx_percent = (m_old_cx ==0)? 1 : (float)((float)cx/(float)m_old_cx);
float dy_percent = (m_old_cy ==0)? 1 : (float)((float)cy/(float)m_old_cy);
if(m_old_cx)
{
CRect WndRect;
CWnd *pWnd;
for(int i = 0; i < m_control_info.GetSize(); i++)
{
pWnd = GetDlgItem(m_control_info[i]);
if(!pWnd)
{
TRACE( “Control ID - %d NOT FOUND!!\n “,m_control_info[i]);
continue;
}
pWnd-> GetWindowRect(&WndRect);
ScreenToClient(&WndRect);
WndRect.left = (int)(WndRect.left*dx_percent);
WndRect.right = (int)(WndRect.right* dx_percent);
WndRect.bottom = (int)(WndRect.bottom*dy_percent);
WndRect.top = (int)(WndRect.top*dy_percent);
pWnd-> MoveWindow(&WndRect);
}
}
m_old_cx = cx;
m_old_cy = cy;
}
在OnInitialUpdate函式中加入控制元件ID:
SetControlInfo(IDC_BUTTON1);
。。。。。。。。。。。。。。。。
執行,搞定!
Dialog也一樣!
上面是轉載的內容,補充一些,就是,當在執行上面的程式後,當dlg為僅剩下標題欄時,再放大,就不會顯示內部的控制元件,那麼自己設定了窗體的最小值:
void CDataBaseConfigDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
{
// TODO: 在此新增訊息處理程式程式碼和/或呼叫預設值
if(lpMMI->ptMinTrackSize.x <= 800)
lpMMI->ptMinTrackSize.x = 800;
if(lpMMI->ptMinTrackSize.y <= 500)
lpMMI->ptMinTrackSize.y = 500;
CDialogEx::OnGetMinMaxInfo(lpMMI);
}
方法也是在網上看到的!