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

2

3

4

5

6

7

8

9

10



11

12



13

14

15

16

17

18

19

20

21

22

23



24

25

26

27

28

29



30

31

32

33

34



35

36

37

38

39

40

41

42

43

44

45

46

47

48

49



50

51



52

53

54

55

56

57

58



59

60

61

62

63



64

65



66

67

68

69

70



71

72

73

74

75



76

77

78

79

80



81

82

83

84

85

86

87

88

89

90

91

92

93



94

95

96

97

98

99

100

101

102

103

104

105

106

107

108



109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128



129

130

131

132



133

134

135

136

137

138

139

140

141

142

143

144



145

146

147

148

149

150



151

152



153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171



172

173

174

175

176

177



178

179

180

181



182

183

184

185

186

187

188



189

190

191

192

193



194

195

196

197



198

199

200

201

202

203

204

205

206

207

208

209

210



211

212



213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

该类的使用起来比较简单,最需要在生成一个对话框类的时候把继承的类CDialog 修改为 CAutoSizeWnd<CDialog>,当然还有其他一些相应的CDialog名称的部分修改一下即可。之后再在OnCreate成员函数(响应WM_CREATE事件)内添加代码: AddChildControl(控件指针, 固定的边界枚举),每一个控件加一条语句即可。这样就已经可以实现上述的功能了。
该模板类最主要的函数是:


1

2

3

4

5

6

7

8

9

10

11

另外该类也只是一个初始品,所以现在只能支持CDialog,需要修改后才能支持CView等其他作为窗体的界面元素。
接下是完整代码: 例子代码