1. 程式人生 > >MFC 控制元件大小隨窗體改變而改變大小-OnSize

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

)- 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);    
//獲取IDi的空間的控制代碼,因為確認”ID1取消”ID2
 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函式那麼簡單了,實現起來有點複雜。等我掌握了這個複雜的方法,一定會拿來分享的。

 

mfc 控制元件大小隨窗體改變而改變

  如果對話方塊或視類的大小調後,控制元件的大小和位置沒有變化,介面看起來會很不爽.

  控制元件是從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);    
//獲取IDi的空間的控制代碼,因為確認”ID1取消”ID2
 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函式那麼簡單了,實現起來有點複雜。等我掌握了這個複雜的方法,一定會拿來分享的。

 

mfc 控制元件大小隨窗體改變而改變

  如果對話方塊或視類的大小調後,控制元件的大小和位置沒有變化,介面看起來會很不爽.

  控制元件是從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);
}

方法也是在網上看到的!