mfc控件自适应窗口大小,随窗口大小变化而变化

作为一个mfc的初学者,难免会遇到这样的问题,窗口可以改变大小,而其中的控件大小也随之改变,那怎么样去做呢。

1.对应窗口的属性Maximize Box和Minimize Box设置为true,从而能够使窗口最大化和最小化,Border属性设置为Resizing从而可以改变窗口的大小。

2.在消息有个WM_SIZE,添加函数OnSize,这样可以在函数内调整控件的大小,特别说明很多代码中利用当前控件比值与窗口大小比值再乘上当前窗口大小来改变控件大小,但是由于精度的问题,调整多次就会出问题,那么这里可以利用一个结构体保存每个控件与原窗口的比值。

先创建结构体:

typedef struct Rect
{
public:
    int Id;
    double scale[4];


Rect()
{
  Id=-2;
  scale[0]=0;
  scale[1]=0;
  scale[2]=0;
  scale[3]=0;
}


Rect(const Rect& c)
{
   *this=c;
}
}control;

其中Id用来保存控件的Id,但是这里初始化为-2代表着里面没有控件,所以你要注意你的控件中没有宏定义Id为-2的,这里算是一个不完善点。

然后在类的成员变量中添加变量

CRect m_rect;//获取最开始的窗口大小
control m_control[10];//最多10个控件,这里代码可移植性没那么强,但是作者能力比较低,直接用数字代表,也没有用宏定义

然后就可以在OnSize中添加方法了

//控制控件大小,使得随窗口大小变化而变化
void CChangeDBToolDlg::OnSize(UINT nType, int cx, int cy)
{

CDialog::OnSize(nType, cx, cy);
//获取控件得到大小以及原大小,方便进行比例调整
CWnd *pWnd;             
int woc;
//列出所有控件
    HWND  hwndChild=::GetWindow(m_hWnd,GW_CHILD);  
//判定是否为最小状态,是的话就不进行重绘
if(!cx||!cy)              
{
   return;      
}
else
{
while(hwndChild)
{
                      woc=::GetDlgCtrlID(hwndChild);//获得控件的ID
     pWnd= GetDlgItem(woc); //获取ID为woc的空间的句柄
     int i=0;
     if(pWnd)
     {
          CRect rect;   //获取当前窗口的大小
      pWnd->GetWindowRect(&rect);
      ScreenToClient(&rect);//将控件大小转换为在对话框中的区域坐标
  for( i=0;i<10;i++)
  {
  if(m_control[i].Id==woc)//如果保存的有该控件与窗口比值,直接乘上当前窗口大小
  {
  rect.left = m_control[i].scale[0] * cx;
  rect.right = m_control[i].scale[1] * cx;
  rect.top = m_control[i].scale[2] * cy;
  rect.bottom = m_control[i].scale[3] * cy;
  break;
  }
  }
  if(i==10)
  {
      for(i=0;i<10;i++)
  {
  if(m_control[i].Id==-2)//没有找到控件的比值,则选择一个没有数据的空间进行保存
  {
  m_control[i].Id=woc;
  m_control[i].scale[0] = (double)rect.left/m_rect.Width();//注意类型转换,不然保存成long型就直接为0了
  m_control[i].scale[1] = (double)rect.right/m_rect.Width();
  m_control[i].scale[2] = (double)rect.top/m_rect.Height();
  m_control[i].scale[3] = (double)rect.bottom/m_rect.Height();
  /////调整控件大小
  rect.left = m_control[i].scale[0] * cx;
  rect.right = m_control[i].scale[1] * cx;
  rect.top = m_control[i].scale[2] * cy;
  rect.bottom = m_control[i].scale[3] * cy;
  break;
  }
  }
  }
     pWnd->MoveWindow(rect);//设置控件大小
      }
 hwndChild=::GetWindow(hwndChild, GW_HWNDNEXT); 
}
GetClientRect(&m_rect);//将变化后的对话框大小设为旧大小


}


// TODO: 在此处添加消息处理程序代码
}

其实网上有很多这种代码,但是很多都没有保存比值,导致多次变化后其位置会改变,但是代码还有不足之处是一些字体控件等不能改变大小,我还在调一些东西,学会了后面发。

你可能感兴趣的:(mfc控件自适应窗口大小,随窗口大小变化而变化)