最近經常要用到改變控制項在對話方塊上的位置和大小,一直找不到有效方法,查看了很多資料。這篇博文還算靠譜,轉載到這裡了。
void CmyqeDlg::OnSize(UINT nType, int cx, int cy){CDialog::OnSize(nType, cx, cy);if(nType!=SIZE_MINIMIZED){ if (me) // 判斷是否為空白,因為對話方塊建立時會調用此函數,而當時控制項還未建立 { CRect rt; me.GetWindowRect(&rt); ScreenToClient(&rt); me.MoveWindow(rt.left,rt.top,cx-rt.left*2,cy-rt.top-rt.left); }}CWnd *pWnd;pWnd = GetDlgItem( IDC_BUTTON1 ); //擷取控制項指標,IDC_BUTTON1為控制項ID號
用CWnd類的函數MoveWindow()或SetWindowPos()可以改變控制項的大小和位置。
void MoveWindow(int x,int y,int nWidth,int nHeight);void MoveWindow(LPCRECT lpRect);
SetWindowPos()函數使用更靈活,多用於只修改控制項位置而大小不變或只修改大小而位置不變的情況:
BOOL SetWindowPos(const CWnd* pWndInsertAfter,int x,int y,int cx,int cy,UINT nFlags);
第一個參數我不會用,一般設為NULL;
x、y控制項位置;cx、cy控制項寬度和高度;
nFlags常用取值:
SWP_NOZORDER:忽略第一個參數;
SWP_NOMOVE:忽略x、y,維持位置不變;
SWP_NOSIZE:忽略cx、cy,維持大小不變;
例:
CWnd *pWnd;pWnd = GetDlgItem( IDC_BUTTON1 ); //擷取控制項指標,IDC_BUTTON1為控制項ID號pWnd->SetWindowPos( NULL,50,80,0,0,SWP_NOZORDER | SWP_NOSIZE ); //把按鈕移到視窗的(50,80)處pWnd = GetDlgItem( IDC_EDIT1 );pWnd->SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER | SWP_NOMOVE ); //把編輯控制項的大小設為(100,80),位置不變pWnd = GetDlgItem( IDC_EDIT1 );pWnd->SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER ); //編輯控制項的大小和位置都改變
以上方法也適用於各種視窗。
如果對話方塊或視類的大小調後,控制項的大小和位置沒有變化,介面看起來會很不爽
控制項是從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); // 將變化後的對話方塊大小設為舊大小
解決一個BUG:
加上 if(nType!=1){}
或者 if(nType!=SIZE_MINIMIZED ){}
不然視窗最小化後再恢複就產生BUG(整數除以0).
貼一下對我自己實際問題的代碼:
首先在標頭檔中定義幾個變數:
CRect rectPointList,rectCmdResponse;CWnd *pWnd;
然後在對話方塊初始化函數中儲存好需要擷取的控制項的大小和位置
系統首先擷取的螢幕座標,擷取後要將螢幕座標轉換成使用者座標系:
pWnd = (CWnd *)GetDlgItem(IDC_STATIC_GROUPBOX_POINT_LIST);pWnd->GetWindowRect(rectPointList);ScreenToClient(rectPointList);pWnd = (CWnd *)GetDlgItem(IDC_EDIT_RESPONSE);pWnd->GetWindowRect(rectCmdResponse);ScreenToClient(rectCmdResponse);
在響應改變大小的函數中調整控制項大小:
pWnd = GetDlgItem(IDC_EDIT_RESPONSE);pWnd->MoveWindow(rectCmdResponse.left,rectCmdResponse.top,rectCmdResponse.right-rectCmdResponse.left,rectCmdResponse.bottom-rectCmdResponse.top);//pWnd->SetWindowPos(NULL,rectCmdResponse.left,rectCmdResponse.top,rectCmdResponse.right-rectCmdResponse.left,rectCmdResponse.bottom-rectCmdResponse.top,SWP_NOZORDER);
MoveWindow和SetWindowPos的功能是一樣,參數不一樣。然後四個點的座標,前兩個一個是控制項左邊位置,一個是控制項上邊位置,第三個是控制項的寬度,要用右邊減去左邊,第四個高度,要用下邊減去上邊。
這樣就可以完美實現功能!
注意!!MFC中的Edit Control控制項,如果往控制項中寫入時換行使用的是\n,那麼在改變大小後,框裡面的文字在新的位置不是換行的!而是全部排成一行。
所以在向Edit Control中輸入文字時,最好!最好的換行使用 \r\n !!!!