📄 ch19.htm
字号:
<HR>
<STRONG>NOTE:</STRONG> Runtime licenses are a means of making sure that the user
of your control has purchased a license to use the control. Controls developed for
selling to developers often have runtime licenses. The license prevents use of a
control by users who haven't paid for it. When you use the control in an application,
either the runtime license for the control is installed in the user's registry by
the install routine or the runtime license is compiled into the application. These
means prevent someone from using the control to build new applications.
<HR>
</BLOCKQUOTE>
<P>In the second step of the Control Wizard, the questions get a little more involved
but are still fairly easy to answer. In this step, you can click the Edit Names button
to provide the control with descriptive names for the user. At the bottom of the
Control Wizard, you'll find a combo box that lists a number of window classes that
you can subclass in your control. If you want to create a special edit box that performs
some special edits on anything the user types into the box, you choose EDIT from
the list of window classes in the drop-down portion of this combo box. If you choose
to click the Advanced button, the questions about your project require a fairly thorough
understanding of ActiveX controls.</P>
<P>To begin the sample control project today, start a new project, selecting the
MFC ActiveX Control Wizard and giving the project a suitable name, such as Squiggle,
as shown in Figure 19.1.</P>
<P><A HREF="javascript:popUp('19fig01.gif')"><B>FIGURE 19.1.</B></A><B> </B><I>Starting
an ActiveX control project.</I></P>
<P>Leave all the options with their default settings in the first Control Wizard
step because you'll create only a single control today, and you won't need to include
any runtime licensing. On the second Control Wizard step, click the Edit Names button
and make sure that the type name is sufficiently descriptive of the control. Click
OK to approve the names, returning to the second Control Wizard step. If you had
specified in the first step that you were creating multiple controls, then you would
choose each control in the drop-down list beside the Edit Names button, specifying
the names for each individual control in the project. You can leave the rest of the
options in the Control Wizard at their default settings for this sample project.</P>
<P>
<H3><A NAME="Heading7"></A>Modifying the CModArt Class</H3>
<P>Once you create the control shell, copy the Line and ModArt files from the library
module project directory, the project you built on Day 16. Load all four of these
files into the control project, adding the CLine and CModArt classes to the project.</P>
<P>The primary changes that you need to make to the CModArt class for your control
is setting the maximum number of squiggles and length of squiggles variables that
can be exposed as control properties. To be able to implement this, you'll add two
member variables to the CModArt class, one to control the length of the squiggles
and the other to control the number of squiggles. Add these two variables to the
CModArt class as in Table 19.1.</P>
<P>
<H4>TABLE 19.1. MEMBER VARIABLES FOR CModArt CLASS.</H4>
<P>
<TABLE BORDER="1">
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT"><I>Name</I></TD>
<TD ALIGN="LEFT"><I>Type</I></TD>
<TD ALIGN="LEFT"><I>Access</I></TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT">m_iLength</TD>
<TD ALIGN="LEFT">int</TD>
<TD ALIGN="LEFT">Private</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT">m_iSegments</TD>
<TD ALIGN="LEFT">int</TD>
<TD ALIGN="LEFT">Private</TD>
</TR>
</TABLE>
</P>
<P>You need to provide a way for these variables to be retrieved and updated from
the exposed properties. This means that you'll need functions for getting the current
value, and for setting the new value, for each of these variables. To add these functions
for the m_iLength variable, add a member function to the CModArt class, specifying
the type as int, the declaration as GetLength, and the access as public. Edit the
function with the code in Listing 19.1.</P>
<P>
<H4>LISTING 19.1. THE CModArt GetLength FUNCTION.</H4>
<PRE>1: int CModArt::GetLength()
2: {
3: // Return the current value for the m_iLength variable
4: return m_iLength;
5: }</PRE>
<P>Next, add another member function to the CModArt class, specifying the function
type as void, the declaration as SetLength(int iLength), and the access as public.
Edit this function, adding the code in Listing 19.2.</P>
<P>
<H4>LISTING 19.2. THE CModArt SetLength FUNCTION.</H4>
<PRE>1: void CModArt::SetLength(int iLength)
2: {
3: // Set the current value for the m_iLength variable
4: m_iLength = iLength;
5: }</PRE>
<P>Add the same two functions for the m_iSegments variable so that it can also be
exposed as a property of the control.</P>
<P>Now that you have made these two properties available for the control, you'll
make sure that they have been initialized to reasonable values before the control
is used. To initialize these values, modify the CModArt constructor as in Listing
19.3.</P>
<P>
<H4>LISTING 19.3. THE MODIFIED CModArt CONSTRUCTOR.</H4>
<PRE>1: CModArt::CModArt()
2: {
3: // Initialize the random number generator
4: srand((unsigned)time(NULL));
5: // Initialize the property variables
6: m_iLength = 200;
7: m_iSegments = 50;
8: }</PRE>
<P>Finally, you'll modify the two function that create the squiggle drawings so that
they use these variables instead of the hard-coded values that they currently use.
To modify the NewDrawing function, replace the maximum number of squiggles in line
7 with the variable m_iSegments, as in Listing 19.4.</P>
<P>
<H4>LISTING 19.4. THE MODIFIED CModArt NewDrawing FUNCTION.</H4>
<PRE> 1: void CModArt::NewDrawing()
2: {
3: int lNumLines;
4: int lCurLine;
5:
6: // Determine how many lines to create
7: lNumLines = rand() % m_iSegments;
8: // Are there any lines to create?
9: if (lNumLines > 0)
10: {
11: // Loop through the number of lines
12: for (lCurLine = 0; lCurLine < lNumLines; lCurLine++)
13: {
14: // Create the new line
15: NewLine();
16: }
17: }
18: }</PRE>
<P>Finally, replace the maximum length of each squiggle with the m_iLength variable
on line 20 in the NewLine function, as in Listing 19.5.</P>
<P>
<H4>LISTING 19.5. THE MODIFIED CModArt NewLine FUNCTION.</H4>
<PRE> 1: void CModArt::NewLine()
2: {
3: int lNumLines;
.
.
.
18:
19: // Determine the number of parts to this squiggle
20: lNumLines = rand() % m_iLength;
21: // Are there any parts to this squiggle?
.
.
.
67: }</PRE>
<P>You have made all of the necessary modifications to the CModArt and CLine classes
for your ActiveX control. Now you have to add an instance of the CModArt class to
the control class as a member variable. Add a new member variable to the control
class, CSquiggleCtrl, specifying its type as CModArt, its name as m_maDrawing, and
its access as private. You also need to include the header file for the CModArt class
in the control class source code file, so open this file, scroll to the top of the
file, and add an include statement for the ModArt.h file, as in Listing 19.6.</P>
<P>
<H4>LISTING 19.6. THE CSquiggleCtrl INCLUDES.</H4>
<PRE>1: // SquiggleCtl.cpp : Implementation of the CSquiggleCtrl ActiveX Control class.
2:
3: #include "stdafx.h"
4: #include "Squiggle.h"
5: #include "SquiggleCtl.h"
6: #include "SquigglePpg.h"
7: #include "ModArt.h"</PRE>
<P>
<H3><A NAME="Heading8"></A>Adding Properties</H3>
<P>Because the two variables that you added to the CModArt class are not variables
of the control class (CSquiggleCtrl), you will probably want to add Get and Set methods
to set and retrieve the property value. If these two variables were members of the
control class, you could add them through the Class Wizard as member variables. You
would still know when and if the variables had been changed because you would have
a notification method in the control class that would be called when the property
values are changed. However, because they are members of an internal class, you'll
want to exercise a little more control over their values.</P>
<BLOCKQUOTE>
<P>
<HR>
<STRONG>TIP:</STRONG> Even if the variables that you want to expose are member variables
of the control class, you might still want to use the Get and Set methods for accessing
the variables as control properties. Using the Get and Set methods allow you to add
validation on the new value for the properties so that you can make certain that
the container application is setting an appropriate value to the property.
<HR>
</BLOCKQUOTE>
<P>To add these properties to your control, open the Class Wizard and select the
Automation tab, as in Figure 19.2. Click on the Add Property button to add the first
property. In the Add Property dialog, enter the external name that you want your
property to have, such as SquiggleLength, and specify the type as short (the int
type is not available, only short and long). Click the Get/Set methods radio button,
and the dialog enters function names for these two methods, as in Figure 19.3. Click
OK to add this property.</P>
<P><A HREF="javascript:popUp('19fig02.gif')"><B>FIGURE 19.2.</B></A><B> </B><I>The
Class Wizard Automation tab.</I></P>
<P><A HREF="javascript:popUp('19fig03.gif')"><B>FIGURE 19.3.</B></A><B> </B><I>The
Add Property dialog.</I></P>
<P>Click the Edit Code button to add the code for the Get and Set methods. In each
method, you'll call the Get and Set functions that you added to the CModArt class
to control access to the length variable. Edit these two methods as shown in Listing
19.7.</P>
<P>
<H4>LISTING 19.7. THE CSquiggleCtrl Get/SetSquiggleLength FUNCTIONS.</H4>
<PRE>1: short CSquiggleCtrl::GetSquiggleLength()
2: {
3: // TODO: Add your property handler here
4: // Return the result from the GetLength function
5: return m_maDrawing.GetLength();
6: }
7:
8: void CSquiggleCtrl::SetSquiggleLength(short nNewValue)
9: {
10: // TODO: Add your property handler here
11: // Set the new length value
12: m_maDrawing.SetLength(nNewValue);
13: SetModifiedFlag();
14: }</PRE>
<P>Add another property for the number of squiggles in a drawing by following the
same steps, substituting an appropriate property name, such as NumberSquiggles.</P>
<P>One last property you might want to add to your control is a boolean property
that the container application could use to keep the control from creating any new
drawings and to keep the current drawing visible. Add a new property through the
Class Wizard, giving it a suitable name such as KeepCurrentDrawing, and specify the
type as BOOL. Leave this property set as a member variable and click OK. The Class
Wizard automatically adds the variable to the control class, along with all of the
necessary code to maintain the variable.</P>
<P>
<H3><A NAME="Heading9"></A>Designing and Building the Property Page</H3>
<P>You need to provide a property page with your control that developers can use
when they are working with your control. This property page will provide the users
with a means of setting the properties of the control, even if their own development
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -