MFC改变控件位置和大小

本文介绍了如何在MFC应用程序中根据对话框的大小变化自动调整控件的大小和位置,详细展示了使用MoveWindow和SetWindowPos方法的具体步骤,并提供了一个解决控件随对话框一起缩放问题的完整示例。
摘要由CSDN通过智能技术生成

转自 http://blog.csdn.net/yuanjilai/article/details/7522985

 

  1. void CmyqeDlg::OnSize(UINT nType, int cx, int cy)  
  2. {  
  3.     CDialog::OnSize(nType, cx, cy);  
  4.     if(nType!=SIZE_MINIMIZED)  
  5.     {  
  6.          if (me) // 判断是否为空,因为对话框创建时会调用此函数,而当时控件还未创建    
  7.     {  
  8.             CRect rt;  
  9.             me.GetWindowRect(&rt);  
  10.          ScreenToClient(&rt);  
  11.             me.MoveWindow(rt.left,rt.top,cx-rt.left*2,cy-rt.top-rt.left);  
  12.     }  
  13. }  
  14.   
  15. CWnd *pWnd;  
  16. pWnd = GetDlgItem( IDC_BUTTON1 );    //获取控件指针,IDC_BUTTON1为控件ID号  
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()可以改变控件的大小和位置。

 

 

  1. void MoveWindow(int x,int y,int nWidth,int nHeight);  
  2. void MoveWindow(LPCRECT lpRect);  
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,维持大小不变;
例:

 

 

  1. CWnd *pWnd;  
  2. pWnd = GetDlgItem( IDC_BUTTON1 );    //获取控件指针,IDC_BUTTON1为控件ID号   
  3. pWnd->SetWindowPos( NULL,50,80,0,0,SWP_NOZORDER | SWP_NOSIZE );    //把按钮移到窗口的(50,80)处   
  4. pWnd = GetDlgItem( IDC_EDIT1 );  
  5. pWnd->SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER | SWP_NOMOVE );    //把编辑控件的大小设为(100,80),位置不变   
  6. pWnd = GetDlgItem( IDC_EDIT1 );  
  7. pWnd->SetWindowPos( NULL,0,0,100,80,SWP_NOZORDER );    //编辑控件的大小和位置都改变  
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()中加入以下代码:

 

 

  1. CWnd * pWnd;  
  2. pWnd = GetDlgItem(IDC_LIST);      // 获取控件句柄    
  3. if (pWnd) // 判断是否为空,因为对话框创建时会调用此函数,而当时控件还未创建    
  4. {  
  5.           CRect rect;    // 获取控件变化前大小    
  6.           pWnd -> GetWindowRect( & rect);  
  7.           ScreenToClient( & rect); // 将控件大小转换为在对话框中的区域坐标   
  8.           //  cx/m_rect.Width()为对话框在横向的变化比例    
  9.           rect.left = rect.left * cx / m_rect.Width(); /**/ /// //调整控件大小    
  10.          rect.right = rect.right * cx / m_rect.Width();  
  11.          rect.top = rect.top * cy / m_rect.Height();  
  12.          rect.bottom = rect.bottom * cy / m_rect.Height();  
  13.          pWnd -> MoveWindow(rect); // 设置控件大小    
  14. }   
  15. GetClientRect( & m_rect); // 将变化后的对话框大小设为旧大小  
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).

 

 

贴一下对我自己实际问题的代码:

首先在头文件中定义几个变量:

 

  1. CRect rectPointList,rectCmdResponse;  
  2. CWnd *pWnd;  
	CRect rectPointList,rectCmdResponse;
	CWnd *pWnd;


然后在对话框初始化函数中保存好需要获取的控件的大小和位置

 

系统首先获取的屏幕坐标,获取后要将屏幕坐标转换成用户坐标系:

 

  1.        pWnd = (CWnd *)GetDlgItem(IDC_STATIC_GROUPBOX_POINT_LIST);  
  2. pWnd->GetWindowRect(rectPointList);  
  3. ScreenToClient(rectPointList);  
  4.   
  5. pWnd = (CWnd *)GetDlgItem(IDC_EDIT_RESPONSE);  
  6. pWnd->GetWindowRect(rectCmdResponse);  
  7. ScreenToClient(rectCmdResponse);  
        pWnd = (CWnd *)GetDlgItem(IDC_STATIC_GROUPBOX_POINT_LIST);
	pWnd->GetWindowRect(rectPointList);
	ScreenToClient(rectPointList);

	pWnd = (CWnd *)GetDlgItem(IDC_EDIT_RESPONSE);
	pWnd->GetWindowRect(rectCmdResponse);
	ScreenToClient(rectCmdResponse);


在响应改变大小的函数中调整控件大小:

 

 

  1. pWnd = GetDlgItem(IDC_EDIT_RESPONSE);  
  2. pWnd->MoveWindow(rectCmdResponse.left,rectCmdResponse.top,rectCmdResponse.right-rectCmdResponse.left,rectCmdResponse.bottom-rectCmdResponse.top);  
  3. //pWnd->SetWindowPos(NULL,rectCmdResponse.left,rectCmdResponse.top,rectCmdResponse.right-rectCmdResponse.left,rectCmdResponse.bottom-rectCmdResponse.top,SWP_NOZORDER);  
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 !!!!

转载于:https://www.cnblogs.com/sitemaker/articles/2686588.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值