在MFC中使dialog自适应缩放

摘要:
起因最近用mfc做了不少小软件,界面上都是基于CDialog或者CFormView,界面不能缩放一直是问题。一个办法是在OnSize()里面调用所有控件的MoveWindow()函数,根据比例调整控件大小。于是我写了一个CAutoResize类,去实现控件的统一缩放。工作原理原理上很简单,对于MFC中的CDilalog,它的信息都存在程序文件夹下的XXX.rc中,XXX是项目名称。如下图所示,CAutoResize类首先就读取XXX.rc,先获取控件长宽信息,dlgWidth和dlgHeight。

起因

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

工作原理

原理上很简单,对于MFC中的CDilalog,它的信息都存在程序文件夹下的XXX.rc中,XXX是项目名称。如下图所示,在MFC中使dialog自适应缩放第1张

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         longpos;
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, intcy)
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运行文件文件夹下也必须要有这两个文件。

免责声明:文章转载自《在MFC中使dialog自适应缩放》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Centos7网卡配置文件获取进程ID,父进程ID,进程完整路径下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Egg.js 实现向服务器上传图片

1.安装时间处理 及 压缩 模块 yarn add silly-datetime pump 2.文件保存路径 config/config.default.js config.uploadDir = 'app/public/avatar/upload'; 3.创建tools serviceapp/service/tools.js 'use strict';...

vue项目使用自适应布局投屏到物理拼接屏变形的处理

这段时间,一直在做一个大屏项目,它的需求是:物理屏幕(LED拼接屏)的分辨率为:6720*2160,大屏页面需满足:通过屏幕分辨率为1920*1080的PC的浏览器访问IOC大屏,接HDMI线投屏后,物理大屏可被填满,显示分辨率为6720*2160,不会出现图像拉伸或压缩。 有了几个大屏经验的我们,直接就选择了vue+element ui 来做这个项目,另...

干货|自适应大邻域搜索(ALNS)算法求解带时间窗的车辆路径规划问题(附java代码)

转眼距离开学又过去一个多月了,不知道大家在家里学习的怎么样?这段时间小编在家里也没闲着,时隔多日,再次为大家带来干货内容。 邻域搜索类启发式算法有很多种,比如禁忌搜索啦,模拟退火啦,变邻域搜索啦等等。这次带来的自适应大邻域搜索代码,相对上述几种会更复杂,编写相对全面。 小编在编写代码时,主要采用git-hub上一位作者de.markusziller的代码,...

CFileFind类的详解以及应用实例

CFileFind类在afx.h头文件中声明。功能:执行本地文件的查找,支持通配符。类的成员函数:1、查找操作类: 1 //搜索目录下指定的文件,成功返回非0。第二个参数不必理会2 virtual BOOL FindFile(LPCTSTR pstrName = NULL,DWORD dwUnused = 0); 3 virtual BOOL F...

移动端利用rem实现自适应布局

  好久没有写博客了,刚好说说最近遇到的移动端布局问题吧。   本来一直是觉得我的页面布局能力还是不错的,当然,是相对于较基础的来说还是不错的。不过,自己写的案例终归是跟实际开发有区别的,自己写案例的是觉得这个样式有时候并没有那个完美就放弃那个效果了。到后来 ,发现这是一个很不好的习惯,一直想着小毛病不去解决,想着以后总归是会的。结果在实际开发的时候,发现...

弱回调与std::forward

  weak callback template<typename CLASS, typename... ARGS> class WeakCallback { public: WeakCallback(const std::weak_ptr<CLASS>& object, const s...