MFC改變控制項位置和大小

來源:互聯網
上載者:User

最近經常要用到改變控制項在對話方塊上的位置和大小,一直找不到有效方法,查看了很多資料。這篇博文還算靠譜,轉載到這裡了。

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 !!!!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.