zoukankan      html  css  js  c++  java
  • 在MFC中使dialog自适应缩放

    起因

    最近用mfc做了不少小软件,界面上都是基于CDialog或者CFormView,界面不能缩放一直是问题。一个办法是在OnSize()里面调用所有控件的MoveWindow()函数,根据比例调整控件大小。但是在界面上控件比较多的时候,这个发放就显得很繁琐了。于是我写了一个CAutoResize类,去实现控件的统一缩放。

    工作原理

    原理上很简单,对于MFC中的CDilalog,它的信息都存在程序文件夹下的XXX.rc中,XXX是项目名称。如下图所示,

    CAutoResize类首先就读取XXX.rc,先获取控件长宽信息,dlgWidth和dlgHeight。然后获取相应控件上的ID,x和y坐标,控件宽度和高度,用这些值去除以dlgWidth和dlgHeight得到相应的比例,然后把信息存在Vector数组中。

    Init函数

      1 bool CAutoResize::Init(char *resourceName, char *dlgID)
      2 {
      3     CString strRcName;
      4     CString strDlgID;
      5     strDlgID.Format("%s", dlgID);
      6     strRcName.Format("./%s", resourceName);
      7 
      8     if(!rcFile.Open(strRcName, CFile::modeRead))
      9     {
     10         AfxMessageBox("can't open the resource file");
     11     }
     12     CString strRead;
     13 
     14 //找到dlgID所在的行
     15 
     16     while(rcFile.ReadString(strRead))
     17     {
     18         TRACE("strRead:%s
    ", strRead);
     19 
     20         if(!Match(strRead, strDlgID))
     21         {
     22             continue;
     23         }
     24         else 
     25         {   
     26             int commaIndex = strRead.Find(",");
     27             strRead = strRead.Mid(commaIndex + 1);
     28             commaIndex = strRead.Find(",");
     29             strRead = strRead.Mid(commaIndex + 1);
     30             commaIndex = strRead.Find(",");
     31             dlgWidth = atoi((const char*)strRead.Left(commaIndex));
     32             strRead = strRead.Mid(commaIndex + 1);
     33             dlgHeight = atoi((const char*)strRead);
     34             TRACE("dlgWidth:%d
    dlgHeight:%d
    ", dlgWidth, dlgHeight);
     35 
     36 
     37             for(int i=0;i<3;i++)
     38             {
     39                 rcFile.ReadString(strRead);
     40 
     41             }
     42             break;
     43         }
     44     }
     45 
     46 
     47     // 开始读取各个控件的信息
     48     while(rcFile.ReadString(strRead))
     49     {
     50         Item item;  
     51 
     52 
     53         TRACE("strRead:%s
    ", strRead);
     54         if(strRead == "END")
     55         {
     56             break;
     57         }
     58         CString str = strRead.Left(20);
     59         str.TrimLeft(" ");
     60         str.TrimRight(" ");
     61         TRACE("begin to store items
    ");
     62         strRead = strRead.Mid(20);
     63         strRead.TrimLeft(" ");
     64 
     65 
     66         CString tempRead, strTemp;
     67         tempRead.Empty();
     68         strTemp.Empty();
     69         long pos;
     70 
     71         do 
     72         {
     73         tempRead.TrimLeft(" ");
     74         strRead = strRead + tempRead;
     75          pos = rcFile.GetPosition();
     76 
     77         rcFile.ReadString(tempRead);
     78         TRACE("tempRead:%s
    ", tempRead);
     79         strTemp = tempRead.Left(20);
     80         strTemp.TrimLeft(" ");
     81         strTemp.TrimRight(" ");
     82 
     83         TRACE("strTemp:%s
    ", strTemp);
     84 
     85         }while(strTemp.IsEmpty());
     86 
     87 
     88         rcFile.Seek(pos, CFile::begin);
     89 
     90         TRACE("strRead:%s
    ", strRead);     
     91 
     92         TRACE("str:%s
    ", str);
     93 
     94 //不同的控件类型格式不同,分情况讨论
     95 //  format: ID, x, y, width, height, style
     96         if(str == _T("EDITTEXT") || str == _T("COMBOBOX"))   
     97         {
     98             int commaIndex = strRead.Find(",");
     99  //存储控件id 类型CString, 过会还要读取resource.h去获取对应的Int类型id
    100             item.itemID = strRead.Left(commaIndex);              
    101             TRACE("itemID:%s
    ", strRead.Left(commaIndex));
    102             strRead = strRead.Mid(commaIndex + 1);
    103             commaIndex = strRead.Find(",");
    104  // 坐标x比例
    105 
    106             item.xPercentage = (float)atoi((const char *)strRead.Left(commaIndex)) / (float)dlgWidth;  
    107             strRead = strRead.Mid(commaIndex + 1);
    108             commaIndex = strRead.Find(",");
    109 // 坐标y比例
    110             item.yPercentage = (float)atoi((const char *)strRead.Left(commaIndex)) / (float)dlgHeight; 
    111             strRead = strRead.Mid(commaIndex + 1);
    112             commaIndex = strRead.Find(",");
    113 // 宽比例
    114             item.widthPercentage = (float)atoi((const char *)strRead.Left(commaIndex)) / (float)dlgWidth;  
    115             strRead = strRead.Mid(commaIndex + 1);
    116 //高比例
    117             item.heightPercentage = (float)atoi((const char *)strRead) / (float)dlgHeight;          
    118 
    119 
    120         }      
    121  // format: text, id, class, style, x, y, width, height
    122         else if(str == _T("CONTROL"))                     
    123         {
    124             int commaIndex = strRead.Find(",");
    125             strRead = strRead.Mid(commaIndex + 1);          
    126             commaIndex = strRead.Find(",");
    127             item.itemID = strRead.Left(commaIndex);
    128             TRACE("itemID:%s
    ", strRead.Left(commaIndex));
    129             strRead = strRead.Mid(commaIndex + 1);
    130             commaIndex = strRead.Find(",");
    131             strRead = strRead.Mid(commaIndex + 1);
    132             commaIndex = strRead.Find(",");
    133             strRead = strRead.Mid(commaIndex + 1);
    134             commaIndex = strRead.Find(",");
    135             item.xPercentage = (float)atoi((const char *)strRead.Left(commaIndex)) / (float)dlgWidth;
    136 
    137             strRead = strRead.Mid(commaIndex + 1);
    138             commaIndex = strRead.Find(",");
    139             item.yPercentage = (float)atoi((const char *)strRead.Left(commaIndex)) / (float)dlgHeight;
    140             strRead = strRead.Mid(commaIndex + 1);
    141             commaIndex = strRead.Find(",");
    142             item.widthPercentage = (float)atoi((const char *)strRead.Left(commaIndex)) / (float)dlgWidth;
    143             strRead = strRead.Mid(commaIndex + 1);
    144 
    145             item.heightPercentage = (float)atoi((const char *)strRead) / (float)dlgHeight;
    146 
    147 
    148 
    149         }       
    150 // format :text, id, x, y, width, height
    151         else                                                           
    152         {
    153             TRACE("others
    ");
    154             int commaIndex = strRead.Find(",");
    155             strRead = strRead.Mid(commaIndex + 1);      
    156             commaIndex = strRead.Find(",");
    157             item.itemID = strRead.Left(commaIndex);
    158             TRACE("itemID:%s
    ", strRead.Left(commaIndex));
    159             strRead = strRead.Mid(commaIndex + 1);
    160             commaIndex = strRead.Find(",");
    161             item.xPercentage = (float)atoi((const char *)strRead.Left(commaIndex)) / (float)dlgWidth;
    162 
    163             strRead = strRead.Mid(commaIndex + 1);
    164             commaIndex = strRead.Find(",");
    165             item.yPercentage = (float)atoi((const char *)strRead.Left(commaIndex)) / (float)dlgHeight;
    166             strRead = strRead.Mid(commaIndex + 1);
    167             commaIndex = strRead.Find(",");
    168             item.widthPercentage = (float)atoi((const char *)strRead.Left(commaIndex)) / (float)dlgWidth;
    169             strRead = strRead.Mid(commaIndex + 1);
    170 
    171             item.heightPercentage = (float)atoi((const char *)strRead) / (float)dlgHeight;
    172 
    173 
    174 
    175 
    176         }   
    177 
    178         TRACE("%s %f %f %f %f
    ", item.itemID, item.xPercentage, item.yPercentage, item.widthPercentage, item.heightPercentage);
    179         itemVec.push_back(item);
    180         TRACE("num of cotrol object is :%d", itemVec.size());
    181 
    182     }
    183 
    184     return true;
    185 }

    GetIdFromString函数,读取resource.h获取对应Int类型id。

     1 int CAutoResize::GetIdFromString(CString &str)   // Convert the type of control's ID from string to int.
     2 {
     3 
     4     CStdioFile file;
     5     int len = str.GetLength();
     6     if(!file.Open(_T("./resource.h"), CFile::modeRead)) // read the resource file
     7     {
     8         AfxMessageBox(_T("resource file open failed"));
     9         return 0;
    10     }
    11     CString strRead;
    12     while(file.ReadString(strRead))
    13     {
    14         if(!strRead.IsEmpty())
    15         {
    16             if(strRead.Left(2) == "#d")
    17             {   
    18                 strRead = strRead.Mid(8);
    19                 int commaIndex = strRead.Find(" ");
    20 
    21                 if(strRead.Left(commaIndex) == str)                     
    22                 {
    23                     strRead = strRead.Mid(commaIndex+1);
    24                     strRead.TrimLeft(" ");
    25                     TRACE("%s
    ", strRead);
    26                     return atoi((const char*)strRead);   // get  item id;
    27                 }
    28             }
    29         }
    30     }
    31     return 0;
    32 }

    Resize函数 改变控件大小

     1 void CAutoResize::Resize(CView *pView, int cx, int cy)
     2 {
     3 
     4     //从vector中取出每个控件信息
     5     std::vector<Item>::iterator iter;
     6     for(iter = itemVec.begin(); iter != itemVec.end();++iter)  
     7     {   
     8         Item *item = static_cast<Item*>(iter);
     9         int x = item->xPercentage*cx;
    10         int y = item->yPercentage*cy;
    11         int width = item->widthPercentage*cx;
    12         int height = item->heightPercentage*cy;
    13         CRect rc;
    14         rc.SetRect(x, y, x+width, y+height);
    15         TRACE("cotrol name:%s
    ", item->itemID);
    16         TRACE("	 x:%d, y:%d,  %d, height:%d
    ", x, y, width, height);
    17         int id = GetIdFromString(item->itemID);
    18 
    19         // MoveWindow
    20 
    21         if(id)
    22         {       
    23         (pView->GetDlgItem(id))->MoveWindow(&rc);
    24         }
    25     }
    26 }

    使用方法

    1.在CDialog类中加入CAutoSize类的成员变量

    2.在对话框的初始化函数中调用Init函数,传入资源文件名和对话框id

    3.在OnSize()中调用Resize函数。

    注:对话框中必须给每个CStatic控件不同的id,不然就不能改变大小。

    不足之处

    1.一些控件类型格式不同,目前init函数里所测试过的格式不多,不排除有一些格式读不出来。所以这个类只是提供一种方法,并不通用。

    2.由于运行时需要读取XXX.rc和resource.h文件,所以在生成的exe运行文件文件夹下也必须要有这两个文件。

     

  • 相关阅读:
    MVC 4 异步编程简化了
    Plextor 浦科特M7VC性能
    epson Robot 指令集合
    在MFC下面实际演示CCriticalSection 的使用
    如何看MFC程序
    SCADA 必备函数之 :关于消息的函数
    SCADA必备函数 实际测试。
    (转)extern关键字两种场景的使用
    (转)全局变量、extern/static/const区别与联系
    (转 )C++ static、const和static const 以及它们的初始化
  • 原文地址:https://www.cnblogs.com/wangke1020/p/3527958.html
Copyright © 2011-2022 走看看