现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

VC++控件自适应屏幕的方法

2012-08-07 22:59 工业·编程 ⁄ 共 2368字 ⁄ 字号 评论 6 条

1.首先在初始化函数中,FormView在OnInitialUpdate(),Dialog在OnInitDialog()中初始化控件的大小。

//开始初始化控件大小
m_IsInitialed = false;
CRect m_ClientRect;
this->GetClientRect(&m_ClientRect);
CSize m_Forsize;
m_Forsize = GetTotalSize();//在资源编辑器中定好大小后,程序运行时大小(不管最大化和最小化,该大小均为同一个值),客户区大于或等于显示的大小
double m_x = (double)m_ClientRect.Width() / m_Forsize.cx;//宽度方向发大倍数
double m_y = (double)m_ClientRect.Height() / m_Forsize.cy;//高度方向发大倍数
//调整控件的大小
CWnd *pWnd = NULL;
pWnd = GetWindow(GW_CHILD);
while(pWnd)//判断是否为空,因为对话框创建时会调用此函数,而当时控件还未创建
{
  CRect rect;   //获取控件变化前大小
  pWnd->GetWindowRect(&rect);
  ScreenToClient(&rect);//将控件大小转换为在对话框中的区域坐标
  m_ControlRect.insert(pair<int, CRect>(pWnd->GetDlgCtrlID(), rect));//保存控件的初始大小,以便在OnSize函数中继续使用
  int width = rect.Width();
  int height = rect.Height();
  WCHAR szBuf[256];
  GetClassName(pWnd->m_hWnd,szBuf,256);        
  if( _tcsicmp(szBuf,_T("Edit")) == 0)  
  {
   //Edit只是位置变化,大小没有变
   rect.top = m_y * rect.top;
   rect.left = m_x * rect.left;
   rect.bottom = rect.top + height;
   rect.right = rect.left + width;
  }
  else
  {
   //其它控件位置和大小均变化
   rect.top = m_y * rect.top;
   rect.left = m_x * rect.left;
   rect.bottom = m_y * rect.bottom;
   rect.right = m_x * rect.right;
  }
  pWnd->MoveWindow(&rect);//设置控件大小
  pWnd = pWnd->GetWindow(GW_HWNDNEXT);
}
 
//控件初始化结束
m_IsInitialed = true;
2.如果界面在运行时大小可以改变,则在OnSize函数中加入如下代码

// TODO: 在此处添加消息处理程序代码
    CFormView::ShowScrollBar(SB_BOTH, false);//设置没有滚动条,视情况而定。
         //在界面不是最小化并且已经初始化完毕
    if (!IsIconic() && m_IsInitialed)
    {
        CSize m_Forsize;
        m_Forsize = GetTotalSize();
        double m_x = (double)cx / m_Forsize.cx;
        double m_y = (double)cy / m_Forsize.cy;
                //读取控件的初始大小
        map<int, CRect>::iterator pos = m_ControlRect.begin();
        for (; pos != m_ControlRect.end(); ++pos)
        {
            CRect rect = pos->second;
            int width = rect.Width();
            int height = rect.Height();
            WCHAR szBuf[256];
            GetClassName(GetDlgItem(pos->first)->m_hWnd,szBuf,256);                    
            if( _tcsicmp(szBuf,_T("Edit")) == 0)  
            {
                rect.top = m_y * rect.top;
                rect.left = m_x * rect.left;
                rect.bottom = rect.top + height;
                rect.right = rect.left + width;
            }
            else
            {
                rect.top = m_y * rect.top;
                rect.left = m_x * rect.left;
                rect.bottom = m_y * rect.bottom;
                rect.right = m_x * rect.right;
            }
            GetDlgItem(pos->first)->MoveWindow(rect);
        }
    }

或在OnShowWindow()函数中加入也可以(特别是在对话框作为tabpage时)

目前有 6 条留言    访客:6 条, 博主:0 条

  1. 爱求索 2012年08月10日 6:23 上午  @回复  Δ1楼 回复

    新建一个自适应分辨率的窗体,然后作为基类。。。

  2. 爱求索 2012年08月10日 6:37 上午  @回复  Δ2楼 回复

    得到系统的分辨率可以用getsystemmetrics函数,Win32 API函数ChangeDisplaySettings()可以用来动态改变分辨率

  3. 爱求索 2012年08月10日 6:40 上午  @回复  Δ3楼 回复

    关键是用屏幕大小的百分比来定位控件

  4. 爱求索 2012年08月10日 6:41 上午  @回复  Δ4楼 回复

    int nFullWidth=GetSystemMetrics(SM_CXSCREEN);
    int nFullHeight=GetSystemMetrics(SM_CYSCREEN);
    先得到分辨率 然后各控件位置用在界面上的百分比 而不是具体值

  5. 爱求索 2012年08月10日 6:42 上午  @回复  Δ5楼 回复

    如果dialog不是很多的话
    可以考虑设计多套模版资源,根据不同的分辨率,用不同的模版创建dlg类实例。

    其它灵活的办法:
    1、动态创建控件对象
    2、MoveWindow

    现在的流行分辨率:800*600,1024*768,1280*1024
    程序对这些分辨率提供支持是应该的,不然客户会有意见:浪费了那么多显示器地盘:)

  6. 爱求索 2012年08月10日 6:49 上午  @回复  Δ6楼 回复

    MoveWindow(0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN));

给我留言

留言无头像?