MFC 界面控件自动大小伸缩
MFC 界面控件自动大小伸缩
C++ Builder 开发WINDOWS界面非常省时,不仅仅是提供的界面控件元素多,而且界面元素控件有一项自动伸缩和固定控件边界在某个位置上的属性。MFC提供的界面元素控件时没有该属性的,如果需要,必须得手动加上一堆代码才可以实现,非常繁琐。对入门的开发人员来说这一点很头疼,其实本人也很头疼这一点,所以花了点小时间封装了一些代码来解决该问题,主要还是节省开发时间。
![]()
Code
1
#ifndef CTEST_AUTO_DLG_H
2
#define CTEST_AUTO_DLG_H
3![]()
4
#include "stdafx.h"
5
#include <map>
6![]()
7
using namespace std;
8![]()
9
namespace EFixedType
10![]()
![]()
{
11
enum EFixedType
12![]()
{
13
NONE = 0,
14
TOP = 1,
15
BOOTOM = 2,
16
LEFT = 4,
17
RIGHT = 8
18
};
19
}
20![]()
21
template<class T>
22
class CAutoSizeWnd : public T
23![]()
![]()
{
24
public:
25![]()
26
struct TFixed;
27![]()
28
CAutoSizeWnd(UINT nIDTemplate, CWnd *pCWnd) : T(nIDTemplate, pCWnd)
29![]()
{
30
m_fInitDlg = FALSE;
31
}
32![]()
33
virtual ~CAutoSizeWnd()
34![]()
{
35
36
}
37![]()
38
//功能:该函数必须在 OnCreate 中调用
39
//参数:
40
// CWnd *pCWnd IN 窗口指针,不允许为NULL
41
// DWORD dwType IN 固定的边框,内容为 EFixedType::NONE
42
// EFixedType::TOP
43
// EFixedType::BOOTOM
44
// EFixedType::LEFT
45
// EFixedType::RIGHT
46
// 中的一个或多个,多个用 '|' 号连接
47
//返回值:添加是否成功
48
BOOL AddChildControl(CWnd *pCWnd, DWORD dwType)
49![]()
{
50
if (!pCWnd)
51![]()
{
52
return FALSE;
53
}
54![]()
55
TFixed *pTFixed = new TFixed();
56![]()
57
if (!pTFixed)
58![]()
{
59
return FALSE;
60
}
61![]()
62
if (dwType != EFixedType::NONE)
63![]()
{
64
if (dwType & EFixedType::TOP)
65![]()
{
66
pTFixed->fTop = TRUE;
67
}
68![]()
69
if (dwType & EFixedType::BOOTOM)
70![]()
{
71
pTFixed->fBottom = TRUE;
72
}
73![]()
74
if (dwType & EFixedType::LEFT)
75![]()
{
76
pTFixed->fLeft = TRUE;
77
}
78![]()
79
if (dwType & EFixedType::RIGHT)
80![]()
{
81
pTFixed->fRight = TRUE;
82
}
83
}
84![]()
85
m_CWndCollections.insert( CWndCollections::value_type(pCWnd, pTFixed));
86![]()
87
return TRUE;
88
}
89![]()
90
protected:
91![]()
92
BOOL OnInitDialog()
93![]()
{
94
T::OnInitDialog();
95![]()
96
CWndCollections::iterator entity = m_CWndCollections.begin();
97
CWndCollections::iterator endEntity = m_CWndCollections.end();
98![]()
99
RECT rect;
100![]()
101
TFixed *pTFixed = NULL;
102![]()
103
CRect dlgRect;
104![]()
105
this->GetClientRect(&dlgRect);
106![]()
107
for (; entity != endEntity; ++entity)
108![]()
{
109
pTFixed = entity->second;
110![]()
111
entity->first->GetWindowRect(&rect);
112![]()
113
this->ScreenToClient(&rect);
114![]()
115
pTFixed->iTop = rect.top;
116![]()
117
pTFixed->iBottom = dlgRect.Height() - rect.bottom;
118![]()
119
pTFixed->iLeft = rect.left;
120![]()
121
pTFixed->iRight = dlgRect.Width() - rect.right;
122
}
123![]()
124
return TRUE;
125
}
126![]()
127
virtual void OnSize(UINT nType, int cx, int cy)
128![]()
{
129
T::OnSize(nType, cx, cy);
130![]()
131
if (m_fInitDlg == FALSE)
132![]()
{
133
m_fInitDlg = TRUE;
134![]()
135
return;
136
}
137![]()
138
//处理所有控件的显示大小
139![]()
140
CWndCollections::iterator entity = m_CWndCollections.begin();
141
CWndCollections::iterator endEntity = m_CWndCollections.end();
142![]()
143
for (; entity != endEntity; ++entity)
144![]()
{
145
AutoSize(entity->first, entity->second);
146
}
147
}
148![]()
149
void AutoSize(CWnd *pCWnd, TFixed *pTFixed)
150![]()
{
151
if (!pCWnd || !pTFixed)
152![]()
{
153
return;
154
}
155![]()
156
CRect dlgRect;
157![]()
158
this->GetClientRect(&dlgRect);
159![]()
160
RECT rect;
161![]()
162
pCWnd->GetWindowRect(&rect);
163![]()
164
this->ScreenToClient(&rect);
165![]()
166
int width = rect.right - rect.left;
167![]()
168
int heght = rect.bottom - rect.top;
169![]()
170
if (pTFixed->fTop && pTFixed->fBottom)
171![]()
{
172
rect.top = pTFixed->iTop;
173![]()
174
rect.bottom = dlgRect.Height() - pTFixed->iBottom;
175
}
176
else if (pTFixed->fTop)
177![]()
{
178![]()
179
}
180
else if (pTFixed->fBottom)
181![]()
{
182
rect.top = dlgRect.Height() - heght - pTFixed->iBottom;
183![]()
184
rect.bottom = dlgRect.Height() - pTFixed->iBottom;
185
}
186![]()
187
if (pTFixed->fLeft && pTFixed->fRight)
188![]()
{
189
rect.left = pTFixed->iLeft;
190
rect.right = dlgRect.Width() - pTFixed->iRight;
191
}
192
else if (pTFixed->fLeft)
193![]()
{
194![]()
195
}
196
else if (pTFixed->fRight)
197![]()
{
198
rect.left = dlgRect.Width() - width - pTFixed->iRight;
199![]()
200
rect.right = dlgRect.Width() - pTFixed->iRight;
201
}
202![]()
203
pCWnd->MoveWindow(&rect);
204
}
205![]()
206![]()
207
private:
208![]()
209
struct TFixed
210![]()
{
211
TFixed()
212![]()
{
213
fTop = FALSE;
214
fBottom = FALSE;
215
fLeft = FALSE;
216
fRight = FALSE;
217
iTop = 0;
218
iBottom = 0;
219
iLeft = 0;
220
iRight = 0;
221
}
222![]()
223
BOOL fTop;//是否固定与父窗口上边界的距离
224
BOOL fBottom;//是否固定与父窗口下边界的距离
225
BOOL fLeft;//是否固定与父窗口左边界的距离
226
BOOL fRight;//是否固定与父窗口右边界的距离
227
int iTop;//与父窗口上边界的距离
228
int iBottom;//与父窗口下边界的距离
229
int iLeft;//与父窗口左边界的距离
230
int iRight;//与父窗口右边界的距离
231
};
232![]()
233
typedef map<CWnd *, TFixed *> CWndCollections;
234![]()
235
CWndCollections m_CWndCollections;
236![]()
237
BOOL m_fInitDlg;
238
};
239![]()
240
#endif
该类的使用起来比较简单,最需要在生成一个对话框类的时候把继承的类CDialog 修改为 CAutoSizeWnd<CDialog>,当然还有其他一些相应的CDialog名称的部分修改一下即可。之后再在OnCreate成员函数(响应WM_CREATE事件)内添加代码: AddChildControl(控件指针, 固定的边界枚举),每一个控件加一条语句即可。这样就已经可以实现上述的功能了。
该模板类最主要的函数是:
![]()
Code
1
//功能:该函数必须在 OnCreate 中调用
2
//参数:
3
// CWnd *pCWnd IN 窗口指针,不允许为NULL
4
// DWORD dwType IN 固定的边框,内容为 EFixedType::NONE
5
// EFixedType::TOP
6
// EFixedType::BOOTOM
7
// EFixedType::LEFT
8
// EFixedType::RIGHT
9
// 中的一个或多个,多个用 '|' 号连接
10
//返回值:添加是否成功
11
BOOL AddChildControl(CWnd *pCWnd, DWORD dwType);
另外该类也只是一个初始品,所以现在只能支持CDialog,需要修改后才能支持CView等其他作为窗体的界面元素。
接下是完整代码:例子代码
1
#ifndef CTEST_AUTO_DLG_H2
#define CTEST_AUTO_DLG_H3

4
#include "stdafx.h"5
#include <map>6

7
using namespace std;8

9
namespace EFixedType10


{11
enum EFixedType12

{13
NONE = 0,14
TOP = 1,15
BOOTOM = 2,16
LEFT = 4,17
RIGHT = 818
};19
}20

21
template<class T>22
class CAutoSizeWnd : public T 23


{24
public:25

26
struct TFixed;27

28
CAutoSizeWnd(UINT nIDTemplate, CWnd *pCWnd) : T(nIDTemplate, pCWnd)29

{30
m_fInitDlg = FALSE;31
}32

33
virtual ~CAutoSizeWnd()34

{35
36
}37

38
//功能:该函数必须在 OnCreate 中调用39
//参数:40
// CWnd *pCWnd IN 窗口指针,不允许为NULL41
// DWORD dwType IN 固定的边框,内容为 EFixedType::NONE42
// EFixedType::TOP43
// EFixedType::BOOTOM 44
// EFixedType::LEFT45
// EFixedType::RIGHT46
// 中的一个或多个,多个用 '|' 号连接47
//返回值:添加是否成功48
BOOL AddChildControl(CWnd *pCWnd, DWORD dwType)49

{50
if (!pCWnd)51

{52
return FALSE;53
}54

55
TFixed *pTFixed = new TFixed();56

57
if (!pTFixed)58

{59
return FALSE;60
}61

62
if (dwType != EFixedType::NONE)63

{64
if (dwType & EFixedType::TOP)65

{66
pTFixed->fTop = TRUE;67
}68

69
if (dwType & EFixedType::BOOTOM)70

{71
pTFixed->fBottom = TRUE;72
}73

74
if (dwType & EFixedType::LEFT)75

{76
pTFixed->fLeft = TRUE;77
}78

79
if (dwType & EFixedType::RIGHT)80

{81
pTFixed->fRight = TRUE;82
}83
}84

85
m_CWndCollections.insert( CWndCollections::value_type(pCWnd, pTFixed));86

87
return TRUE;88
}89

90
protected:91

92
BOOL OnInitDialog()93

{94
T::OnInitDialog();95

96
CWndCollections::iterator entity = m_CWndCollections.begin();97
CWndCollections::iterator endEntity = m_CWndCollections.end();98

99
RECT rect;100

101
TFixed *pTFixed = NULL;102

103
CRect dlgRect;104

105
this->GetClientRect(&dlgRect);106

107
for (; entity != endEntity; ++entity)108

{109
pTFixed = entity->second;110

111
entity->first->GetWindowRect(&rect);112

113
this->ScreenToClient(&rect);114

115
pTFixed->iTop = rect.top;116

117
pTFixed->iBottom = dlgRect.Height() - rect.bottom;118

119
pTFixed->iLeft = rect.left;120

121
pTFixed->iRight = dlgRect.Width() - rect.right;122
}123

124
return TRUE;125
}126

127
virtual void OnSize(UINT nType, int cx, int cy)128

{129
T::OnSize(nType, cx, cy);130

131
if (m_fInitDlg == FALSE)132

{133
m_fInitDlg = TRUE;134

135
return;136
}137

138
//处理所有控件的显示大小139

140
CWndCollections::iterator entity = m_CWndCollections.begin();141
CWndCollections::iterator endEntity = m_CWndCollections.end();142

143
for (; entity != endEntity; ++entity)144

{145
AutoSize(entity->first, entity->second);146
}147
}148

149
void AutoSize(CWnd *pCWnd, TFixed *pTFixed)150

{151
if (!pCWnd || !pTFixed)152

{153
return;154
}155

156
CRect dlgRect;157

158
this->GetClientRect(&dlgRect);159

160
RECT rect;161

162
pCWnd->GetWindowRect(&rect);163

164
this->ScreenToClient(&rect);165

166
int width = rect.right - rect.left;167

168
int heght = rect.bottom - rect.top;169

170
if (pTFixed->fTop && pTFixed->fBottom)171

{172
rect.top = pTFixed->iTop;173

174
rect.bottom = dlgRect.Height() - pTFixed->iBottom;175
}176
else if (pTFixed->fTop)177

{178

179
}180
else if (pTFixed->fBottom)181

{182
rect.top = dlgRect.Height() - heght - pTFixed->iBottom;183

184
rect.bottom = dlgRect.Height() - pTFixed->iBottom;185
}186

187
if (pTFixed->fLeft && pTFixed->fRight)188

{189
rect.left = pTFixed->iLeft;190
rect.right = dlgRect.Width() - pTFixed->iRight;191
}192
else if (pTFixed->fLeft)193

{194

195
}196
else if (pTFixed->fRight)197

{198
rect.left = dlgRect.Width() - width - pTFixed->iRight;199

200
rect.right = dlgRect.Width() - pTFixed->iRight;201
}202

203
pCWnd->MoveWindow(&rect);204
}205

206

207
private:208

209
struct TFixed210

{211
TFixed()212

{213
fTop = FALSE;214
fBottom = FALSE;215
fLeft = FALSE;216
fRight = FALSE;217
iTop = 0;218
iBottom = 0;219
iLeft = 0;220
iRight = 0;221
}222

223
BOOL fTop;//是否固定与父窗口上边界的距离224
BOOL fBottom;//是否固定与父窗口下边界的距离225
BOOL fLeft;//是否固定与父窗口左边界的距离226
BOOL fRight;//是否固定与父窗口右边界的距离227
int iTop;//与父窗口上边界的距离228
int iBottom;//与父窗口下边界的距离229
int iLeft;//与父窗口左边界的距离230
int iRight;//与父窗口右边界的距离231
};232

233
typedef map<CWnd *, TFixed *> CWndCollections;234

235
CWndCollections m_CWndCollections;236

237
BOOL m_fInitDlg;238
};239

240
#endif该类的使用起来比较简单,最需要在生成一个对话框类的时候把继承的类CDialog 修改为 CAutoSizeWnd<CDialog>,当然还有其他一些相应的CDialog名称的部分修改一下即可。之后再在OnCreate成员函数(响应WM_CREATE事件)内添加代码: AddChildControl(控件指针, 固定的边界枚举),每一个控件加一条语句即可。这样就已经可以实现上述的功能了。
该模板类最主要的函数是:
1
//功能:该函数必须在 OnCreate 中调用2
//参数:3
// CWnd *pCWnd IN 窗口指针,不允许为NULL4
// DWORD dwType IN 固定的边框,内容为 EFixedType::NONE5
// EFixedType::TOP6
// EFixedType::BOOTOM 7
// EFixedType::LEFT8
// EFixedType::RIGHT9
// 中的一个或多个,多个用 '|' 号连接10
//返回值:添加是否成功11
BOOL AddChildControl(CWnd *pCWnd, DWORD dwType);另外该类也只是一个初始品,所以现在只能支持CDialog,需要修改后才能支持CView等其他作为窗体的界面元素。
接下是完整代码:例子代码
浙公网安备 33010602011771号