-
-
Notifications
You must be signed in to change notification settings - Fork 26
/
VC下使用ActiveX控件的问题.html
316 lines (311 loc) · 13.8 KB
/
VC下使用ActiveX控件的问题.html
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
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>VC知识库</title>
</head>
<body>
<div align="justify">
<table class="font" height="57" width="100%" border="0">
<tr>
<td class="bigfont" borderColor="#800080" align="middle" width="27%" bgColor="#b8cfe7" height="6">
<font color="#800080">VC知识库(五)</font> </td>
<td class="bigfont" borderColor="#800080" align="middle" width="73%" bgColor="#b8cfe7" height="6">
<font color="#800080">www.vckbase.com</font> </td>
</tr>
<tr>
<td class="header" vAlign="top" align="middle" width="100%" colSpan="2" height="4">
<hr></td>
</tr>
<tr>
<td class="header" vAlign="top" align="middle" width="100%" colSpan="2" height="17">
<small>
<p align="center"><big>VC++5.0下使用ActiveX控件的问题</big></small></td>
</tr>
<tr>
<td class="info" align="middle" width="100%" colSpan="2" height="17">
<small><big><font face="宋体">刘芳 周顺平</font></big></small> </td>
</tr>
<tr>
<td class="font" width="100%" colSpan="2" height="22"><hr></td>
</tr>
<tr>
<td class="font" width="100%" colSpan="2" height="5"><small>
<table width="80%" align="center" border="0">
<tr>
<td>
自从Microsoft最早在1996年3月的Internet专业开发人员研讨会上提出ActiveX一词以来,到今天已有无数公司的无数产品中涉及了ActiveX技术,而作为ActiveX技术之一的ActiveX控件,更是得到广大开发者的青睐。那么,到底什么是ActiveX控件呢?</td>
</tr>
<tr>
<td>
一方面,它表示将你带向Microsoft、Internet和业界的新技术的小型快速的可重用组件。它与开发语言无关,在任何支持ActiveX控件的软件开发平台(如VB、VC++、Access、VFP、Delphi、PowerBuilder等)上都可以使用ActiveX控件,程序员可以像使用Windows标准控件一样使用不同厂商开发的ActiveX控件。这样就实现了软件开发的工业化,大大地提高了软件的生产效率。</td>
</tr>
<tr>
<td>
另一方面,它代表Internet与应用程序的一种集成策略。用户可以从Internet上下载ActiveX控件,也可以通过网络在本地机上调用远程机上的ActiveX控件,还可以将ActiveX控件加入到Internet主页上。
既然ActiveX控件对程序员是如此地重要,那么如何用好ActiveX控件也就成为软件开发者所关心的问题。本文以VC++5.0为开发工具,以一个项目名为Test的应用程序为例,针对笔者在控件使用中遇到的一些问题加以讨论。</td>
</tr>
<tr>
<td> </td>
</tr>
<tr bgColor="#ffcc66">
<td><font face="楷体_GB2312">一.使应用程序支持ActiveX控件</font></td>
</tr>
<tr>
<td>要想在应用程序中使用ActiveX控件,必须使你的应用程序成为ActiveX控件包容器。ActiveX
控件包容器就是完全支持ActiveX控件,并能把控件组合进自己的窗口或对话框的父应用程序。利用MFC的AppWizard,你可以很方便地创建你的包容器程序。事实上,在用AppWizard创建新的应用程序时,你的应用程序就被缺省设置为控件包容器,即使你在创建过程中没有加入ActiveX控件支持,以后也可以手动地进行更改。</td>
</tr>
<tr>
<td>
1、在项目的应用类的.cpp文件(本例中为test.cpp)的Initinstance函数中加入对函数AfxEnableControlContainer()的调用,如下所示:</td>
</tr>
<tr>
<td>BOOL CTestApp::InitInstance()
<p>{ </p>
<p>AfxEnableControlContainer(); </p>
<p>... </p>
<p>}</td>
</tr>
<tr>
<td>2、在项目中的STDAFX.H头文件中加入如下代码:#include <afxdisp.h><AFXDISP.H>
然后重新链接项目即可。</td>
</tr>
<tr>
<td><AFXDISP.H></td>
</tr>
<tr bgColor="#ffcc66">
<td><font face="楷体_GB2312">二.在非对话框容器中使用ActiveX控件</font></td>
</tr>
<tr>
<td>在使用一个已注册的ActiveX控件之前,必须先用组件廊将该控件添加到应用程序中:</td>
</tr>
<tr>
<td>1、从Project菜单中选择Add To Project下的Components and Controls。</td>
</tr>
<tr>
<td>2、在弹出的对话框中双击并打开Registered ActiveX Control子目录。</td>
</tr>
<tr>
<td>3、选择你需要的控件,点击Insert按钮,弹出Confirm Classes对话框。</td>
</tr>
<tr>
<td>4、在列出的类名中选择需要的类(缺省为全选中,最好接受缺省设置),点击OK,关闭Confirm
Classes对话框。</td>
</tr>
<tr>
<td>5、点击Close关闭组件廊,则该控件的图标即加入到对话框编辑器的控件面板上。</td>
</tr>
<tr>
<td>
这样,我们就可以在对话框中像使用Windows标准控件那样使用该控件了。但在某些应用中,你可能需要在非对话框容器(如应用程序的窗口)中嵌入ActiveX控件。这时没有对话框编辑器,我们应怎样在非对话框容器中使用ActiveX控件呢?</td>
</tr>
<tr>
<td>当组件廊将ActiveX控件添加到你的应用程序后,组件廊会创建一些包裹类(即在Confirm
Classes对话框中列出的那些类)。其中有一个类的基类是CWnd,该类是控件的包裹类,它被用作控件与控件包容器之间的接口,有两个公有的Create成员函数:</td>
</tr>
<tr>
<td>virtual BOOL Create(LPCTSTR lpszClassName,<p>LPCTSTR
lpszWindowName, DWORD dwStyle,</p>
<p>const RECT& rect, CWnd* pParentWnd, UINT nID,</p>
<p>CCreateContext* pContext = NULL)</td>
</tr>
<tr>
<td>和BOOL Create(LPCTSTR lpszWindowName, DWORD dwStyle,<p>
const RECT& rect, CWnd* pParentWnd, UINT nID,</p>
<p>CFile* pPersist = NULL, BOOL bStorage = FALSE,</p>
<p>BSTR bstrLicKey = NULL)</td>
</tr>
<tr>
<td>我们就可以使用该控件的包裹类的Create函数在非对话框容器中动态地创建此控件的实例。</td>
</tr>
<tr>
<td>具体步骤如下:(本例中欲加入的控件名为MSFlexGrid
,CMSFlexGrid是控件的包裹类,msflexgrid.h是包裹类的头文件)</td>
</tr>
<tr>
<td>1、在视类头文件(本例中为TestView.h)中的类定义前加上<p>#include msflexgrid.h</td>
</tr>
<tr>
<td>2、在TestView.h中CTestView类定义的protected部分加上控件包裹类类型的成员变量声明:</td>
</tr>
<tr>
<td>class CTestView : public CView
<p>{ </p>
<p>... </p>
<p>protected: </p>
<p>CMSFlexGrid m_fgrid; </p>
<p>... </p>
<p>};</td>
</tr>
<tr>
<td>3、用ClassWizard为类CTestView 添加消息WM_CREATE的处理函数CTestView::OnCreate,在此函数中,调用控件类CMSFlexGrid的Create函数:</td>
</tr>
<tr>
<td>int CTestView::OnCreate(LPCREATESTRUCT lpCreateStruct)
<p>{ </p>
<p>if (CView::OnCreate(lpCreateStruct) == -1) return -1; </p>
<p>// ****** Add your code below this line ********** //</p>
<p>m_fgrid.Create(NULL, WS_VISIBLE, </p>
<p>CRect(50,50,100,100), this, 0);//用this指针作为指向父窗口的指针//</p>
<p>m_fgrid.SetCols(2); </p>
<p>m_fgrid.SetRows(10); </p>
<p>m_fgrid.SetTextMatrix(0,0,"序号"); </p>
<p>m_fgrid.SetTextMatrix(0,1,"姓名"); // ****** Add your code
above this line ********** // </p>
<p>return 0; </p>
<p>}</td>
</tr>
<tr>
<td>4、重新链接工程,运行。可以看到当应用程序的视窗生成时,控件也动态地生成了。</td>
</tr>
<tr>
<td>5、如果你以后还想改变控件的位置和大小,可以继承CWnd::MoveWindow()函数。例如,若想使控件充满整个窗口,并在父窗口移动和缩放时也随之移动和缩放,可以添加消息WM_SIZE的处理函数OnSize,并加入如下代码:</td>
</tr>
<tr>
<td>void CTestView::OnSize(UINT nType, int cx, int cy)<p>
CView::OnSize(nType, cx, cy); // TODO: Add your message
handler code here// </p>
<p>m_fgrid.MoveWindow(0,0,cx,cy); </td>
</tr>
<tr>
<td> </td>
</tr>
<tr bgColor="#ffcc66">
<td><font face="楷体_GB2312">三、在对话框中使用运行时不可见的ActiveX控件</font></td>
</tr>
<tr>
<td>通常情况下,我们可以用两种方法来存取对话框中的控件:</td>
</tr>
<tr>
<td>1、将控件与对话框的成员变量相关联,通过对话框数据交换DDX来实现控件和对应的成员变量之间的数据交换(详情请参阅VC联机帮助ActiveX
Control Containers: Connecting an ActiveX Control to a
Member Variable)</td>
</tr>
<tr>
<td>2、调用函数CWnd::GetDlgItem来取得指向控件的指针。</td>
</tr>
<tr>
<td>
有些ActiveX控件没有用户界面,在运行时不可见。如果你在对话框中加入了运行时不可见的ActiveX控件,并想用CWnd::GetDlgItem来存取此控件,则此控件将不能正常工作。要得到代表此控件的对象指针,可采取以下两种方法之一:</td>
</tr>
<tr>
<td>1、在ClassWizard的成员变量标签中,选择此控件的ID,点击Add
Variable,然后输入一个成员变量名,在Category中选择Control,在Variable
type中选择控件类。</td>
</tr>
<tr>
<td>
2、声明一个此控件类型的局部变量,并将它作为一个对话框项。加入类似如下所列的代码(其中CmyCtrl是控件类,IDMYCTRL1是控件ID):</td>
</tr>
<tr>
<td>CMyCtrl myCtrl;
<p>myCtrl.SubclassDlgItem(IDC_MYCTRL1, this); // ...
使用控件myCtrl ... //</p>
<p>myCtrl.UnsubclassWindow();</td>
</tr>
<tr bgColor="#ffffff">
<td> </td>
</tr>
<tr bgColor="#ffcc66">
<td><font face="楷体_GB2312">下面举一个例子加以说明</font></td>
</tr>
<tr>
<td>本例将在对话框中加入一个运行时不可见的计时控件Timer Object。该控件在一个的预定的时间间隔过去之后引发
Timer 事件,该时间间隔储存于该控件的Interval
属性中,它以千分之一秒为单位指定时间的长度。本例用一个成员变量m_num来计数,每隔一个Interval时间递增1,当m_num计到10时,重置为0,并将时间间隔m_Interval增加200毫秒,并分别在两个静态框中显示当前的m_num和m_Interval。步骤如下:</td>
</tr>
<tr>
<td>1、用组件廊将Timer控件加入到项目Test中。</td>
</tr>
<tr>
<td>2、在项目中插入一个新的对话框,类名为CTestDlg。</td>
</tr>
<tr>
<td>3、在对话框模板中加入控件Timer
Object(包裹类为CIeTimer),如图2的右下角。打开属性对话框,设置ID为IDC_TIMER1。再切换至All属性页,设置Interval为200。</td>
</tr>
<tr>
<td>4、在对话框模板中添加静态控件,Caption为“The current interval is:”。</td>
</tr>
<tr>
<td>
5、添加一个不带Caption的静态控件,打开属性对话框,设置ID为IDC_STATIC1。再切换至Extended
Styles属性页,选中Static edge复选框。</td>
</tr>
<tr>
<td>6、按下Ctrl键的同时双击静态控件IDC_STATIC1,弹出Add Member
Variable对话框,第一项中填写变量名m_text1,Category项中选择Control,Variable
type项中选择CStatic。</td>
</tr>
<tr>
<td>7、添加静态控件"The current number is:"。</td>
</tr>
<tr>
<td>
8、重复步骤5到步骤6,添加一个不带Caption的静态控件(ID为IDC_STATIC2),变量名为m_text2。</td>
</tr>
<tr>
<td>9、运行ClassWizard并选择Message Map属性页,在Class name
中选择CTestDlg,Object IDs中选择IDC_TIMER1,在Messages中选择Timer,点击Add
Function…按钮,加入OnTimerTimer1()处理函数。
</td>
</tr>
<tr>
<td>
采用第一种方法,则按前面所述步骤用ClassWizard给此控件类添加一个成员变量m_timer,并在OnTimerTimer1函数中添加如下代码:</td>
</tr>
<tr>
<td>void CTestDlg::OnTimerTimer1() // TODO: Add your control
notification handler code here //<p>char buf[10]; </p>
<p>m_num++; </p>
<p>if(m_num>=10) </p>
<p>{ </p>
<p>m_num=0;</p>
<p>m_interval+=200; </p>
<p>m_timer.SetInterval(m_interval); </p>
<p>} </p>
<p>_itoa(m_interval,buf,10); </p>
<p>m_text1.SetWindowText (buf); </p>
<p>_itoa(m_num,buf,10); </p>
<p>m_text2.SetWindowText (buf);</td>
</tr>
<tr>
<td> </td>
</tr>
<tr>
<td>若采用第二种方法,则不需要添加此控件类的成员变量,只需将加灰显示的语句用下列语句代替即可:</td>
</tr>
<tr>
<td>CIeTimer m_timer;
<p>m_timer.SubclassDlgItem(IDC_TIMER1,this); </p>
<p>m_timer.SetInterval(m_interval); </p>
<p>m_timer.UnsubclassWindow();</td>
</tr>
<tr>
<td>运行之后可以看到计数的步调越来越慢了(因为时间间隔越来越大)</td>
</tr>
<tr>
<td> </td>
</tr>
<tr>
<td>
ActiveX控件大大地简化了开发者的工作,灵活地使用控件能使开发者高效地开发出各种软件。以上是笔者在使用控件的过程中总结出的一些实践经验,希望对大家有所帮助。</td>
</tr>
</table>
<p> </small></td>
</tr>
<tr>
<td class="font" width="100%" colSpan="2" height="12"></td>
</tr>
<tr>
<td class="font" width="100%" colSpan="2" height="6"></td>
</tr>
<tr>
<td class="font" width="100%" colSpan="2" height="8"></td>
</tr>
<tr>
<td class="font" width="100%" colSpan="2" height="17"></td>
</tr>
</table>
</div>
</body>
</html>