📄 ch09.htm
字号:
<P>Now that the ActiveX control that you want to use is registered with the operating
system, you need to register it with Visual C++ and add it to your project. To do
this, follow these steps:</P>
<P>
<DL>
<DT></DT>
<DD><B>1. </B>Select Project|Add To Project|Components and Controls from the Visual
C++ menu.
<P>
<DT></DT>
<DD><B>2. </B>In the Components and Controls Gallery dialog, navigate to the Registered
ActiveX Controls folder, as in Figure 9.3.
<P>
</DL>
<P><A HREF="javascript:popUp('09fig03.gif')"><B>FIGURE 9.3.</B></A><B> </B><I>The
ActiveX controls that can be added to your project.</I></P>
<P><I></I>
<DL>
<DT><I></I></DT>
<DD><B>3. </B>Select the control you want to register, such as the Microsoft FlexGrid
control, and click the Insert button.
<P>
<DT></DT>
<DD><B>4. </B>Click OK on the message box asking whether you want to insert this
component in your project.
<P>
<DT></DT>
<DD><B>5. </B>On the Confirm Classes dialog, click the OK button to add the C++ classes
specified, as in Figure 9.4.
<P>
</DL>
<P><A HREF="javascript:popUp('09fig04.gif')"><B>FIGURE 9.4.</B></A><B> </B><I>Visual
C++ tells you what classes will be added to your project.</I></P>
<P><I></I>
<DL>
<DT><I></I></DT>
<DD><B>6. </B>Click the Close button on the Components and Controls Gallery dialog
to finish adding controls to your project.
<P>
<DT></DT>
<DD><B>7. </B>The FlexGrid control should have been added to the Control Palette
for your dialog window, as in Figure 9.5.
<P>
</DL>
<P><A HREF="javascript:popUp('09fig05.gif')"><B>FIGURE 9.5.</B></A><B> </B><I>The
ActiveX control FlexGrid is added to the Control Palette for use on your dialog windows.</I></P>
<P>If you examine the Class View area of the workspace pane, you see the four classes
that Visual C++ added to your project. Expand the class trees and you see numerous
methods for these classes. Visual C++ created these classes and methods by examining
the ActiveX control that you just added and created class methods to call each of
the methods in the control's IDispatch interface.</P>
<BLOCKQUOTE>
<P>
<HR>
<STRONG>NOTE:</STRONG> If you use older ActiveX controls in your Visual C++ applications,
Visual C++ might not be able to generate the classes and methods to encapsulate the
control's functionality. The information in the control that provided Visual C++
with the information necessary to build these classes and methods is a more recent
addition to the ActiveX specification. As a result, older controls might not provide
this information, making them more difficult to use with Visual C++.
<HR>
</BLOCKQUOTE>
<H3><A NAME="Heading6"></A>Adding the Control to Your Dialog</H3>
<P>Now that you have added the FlexGrid control to your project, you can add it to
your dialog window just as you would any other control. Set the control properties
as in Table 9.1.</P>
<P>
<H4>TABLE 9.1. CONTROL PROPERTY SETTINGS.</H4>
<P>
<TABLE BORDER="1">
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT"><I>Object</I></TD>
<TD ALIGN="LEFT"><I>Property</I></TD>
<TD ALIGN="LEFT"><I>Setting</I></TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT">FlexGrid control </TD>
<TD ALIGN="LEFT">ID </TD>
<TD ALIGN="LEFT">IDC_MSFGRID </TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT"> <P>
</TD>
<TD ALIGN="LEFT">Rows </TD>
<TD ALIGN="LEFT">20 </TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT"> <P>
</TD>
<TD ALIGN="LEFT">Cols </TD>
<TD ALIGN="LEFT">4 </TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT"> <P>
</TD>
<TD ALIGN="LEFT">MergeCells </TD>
<TD ALIGN="LEFT">2 - Restrict Rows </TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT"> <P>
</TD>
<TD ALIGN="LEFT">Format </TD>
<TD ALIGN="LEFT">< Region |< Product </TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD ALIGN="LEFT"> <P>
</TD>
<TD ALIGN="LEFT">(FormatString) </TD>
<TD ALIGN="LEFT">|< Employee |>Sales </TD>
</TR>
</TABLE>
</P>
<P>Once you add the control to your dialog window, you will notice that there is
an additional tab on the properties dialog with all the control properties, as in
Figure 9.6. You can choose to use this tab to set all the properties on the control,
or you can go through the other tabs to set the properties, just as you would with
the standard controls.</P>
<P><A HREF="javascript:popUp('09fig06.gif')"><B>FIGURE 9.6.</B></A><B> </B><I>ActiveX
controls have a property tab that contains all control properties.</I></P>
<P>Once you have finished setting all the properties for the control, you'll need
to add a variable for the control so that you can interact with the control in your
code. To add this variable, open the Member Variables tab on the Class Wizard and
add a variable for the control. Because you are adding a variable for an ActiveX
control, you can only add a control variable, so the only thing available for you
to specify is the variable name. For this example application, name the variable
m_ctlFGrid.</P>
<P>
<H2><A NAME="Heading7"></A>Using an ActiveX Control in Your Application</H2>
<PRE>Once Visual C++ has generated all the classes to encapsulate the ActiveX control, working with the control is a simple matter of calling the various methods and responding to control events just like the standard controls. You'll start with using the control methods to get information about the control and to modify data within the control. Then you'll learn how to respond to control events with Visual C++.
</PRE>
<H3><A NAME="Heading8"></A>Interacting with the Control</H3>
<P>The application that you are building today will generate a number of product
sales over five sales regions with four salespeople. You will be able to scroll through
the data, which will be sorted by region and product, to compare how each salesperson
did for each product.</P>
<P>To make this project, you will build an array of values that will be loaded into
cells in the grid. The grid will then be sorted in ascending order, using the FlexGrid
control's internal sorting capabilities.</P>
<P>
<H4>Loading Data into the Control</H4>
<P>The first thing you will do is create a function to load data into the FlexGrid
control. Add a new function to the CActiveXDlg class by right-clicking the Class
View of the workspace and choosing Add Member Function. Specify the Function Type
as void, the Function Declaration as LoadData, and the access as Private. Click the
OK button and edit the function, adding the code in Listing 9.1.</P>
<P>
<H4>LISTING 9.1. THE LoadData FUNCTION.</H4>
<PRE> 1: void CActiveXDlg::LoadData()
2: {
3: int liCount; // The grid row count
4: CString lsAmount; // The sales amount
5:
6: // Initialize the random number generator
7: srand((unsigned)time(NULL));
8: // Create Array in the control
9: for (liCount = m_ctlFGrid.GetFixedRows();
10: liCount < m_ctlFGrid.GetRows(); liCount++)
11: {
12: // Generate the first column (region) values
13: m_ctlFGrid.SetTextArray(GenID(liCount, 0), RandomStringValue(0));
14: // Generate the second column (product) values
15: m_ctlFGrid.SetTextArray(GenID(liCount, 1), RandomStringValue(1));
16: // Generate the third column (employee) values
17: m_ctlFGrid.SetTextArray(GenID(liCount, 2), RandomStringValue(2));
18: // Generate the sales amount values
19: lsAmount.Format("%5d.00", rand());
20: // Populate the fourth column
21: m_ctlFGrid.SetTextArray(GenID(liCount, 3), lsAmount);
22: }
23:
24: // Merge the common subsequent rows in these columns
25: m_ctlFGrid.SetMergeCol(0, TRUE);
26: m_ctlFGrid.SetMergeCol(1, TRUE);
27: m_ctlFGrid.SetMergeCol(2, TRUE);
28:
29: // Sort the grid
30: DoSort();
</PRE>
<PRE>31: }</PRE>
<P>In this function, the first thing that you do is initialize the random number
generator. Next, you loop through all of the rows in the control, placing data in
each of the cells. You get the total number of rows in the control by calling the
GetRows method and the number of the header row by calling the GetFixedRows method.
You are able to add data to the control cells by calling the SetTextArray method,
which has the cell ID as the first argument and the cell contents as the second argument,
both of which are generated by functions you'll be creating in a few moments.</P>
<P>Once you have data in the grid cells, you call SetMergeCol, which tells the control
that it can merge cells in the first three columns if adjacent rows contain the same
value. Finally, you sort the control, using another function you have yet to create.</P>
<P>
<H4>Calculating the Cell ID</H4>
<P>The cells in the FlexGrid control are numbered sequentially from left to right,
top to bottom. With your control, the first row, which contains the headers (and
is already populated), has cells 0 through 3, the second row cells 4 through 7, and
so on. Therefore, you can calculate the ID of a cell by adding its column number
to the total number of columns in the control, multiplied by the current row number.
For instance, if your control has four columns, and you are in the third column and
fourth row, you can calculate your cell ID as 2 + (4 * 3) = 14. (Remember that the
column and row numbers start with 0, so the third column is 2 and the fourth row
is number 3.)</P>
<P>Now that you understand how you can calculate the cell ID, you need to implement
that formula in a function. Add a new function to the CActiveXDlg class using the
same method as for the LoadData function. The type of this function should be int
and the description should be GenID(int m_iRow, int m_iCol). Once you add the function,
edit it with the code in Listing 9.2.</P>
<P>
<H4>LISTING 9.2. THE GenID FUNCTION.</H4>
<PRE> 1: int CActiveXDlg::GenID(int m_iRow, int m_iCol)
2: {
3: // Get the number of columns
4: int liCols = m_ctlFGrid.GetCols();
5:
6: // Generate an ID based on the number of columns,
7: // the current column, and the current row
8: return (m_iCol + liCols * m_iRow);
</PRE>
<PRE>9: }</PRE>
<P>
<H4>Generating Random Data</H4>
<P>To populate the first three columns in the grid, you want to randomly generate
data. In the first column, you want to put region names. In the second column, you
want to put product names. And in the third column, you want to put salesperson names.
By using a switch statement to determine which column you are generating data for
and then using a modulus division on a randomly generated number in another switch
statement, you can randomly select between a limited set of data strings.</P>
<P>To implement this functionality, add another function to the CActiveXDlg class
with a type of CString and a description of RandomStringValue(int m_iColumn). Edit
the resulting function, adding the code in Listing 9.3.</P>
<P>
<H4>LISTING 9.3. THE RandomStringValue FUNCTION.</H4>
<PRE> 1: CString CActiveXDlg::RandomStringValue(int m_iColumn)
2: {
3: CString lsStr; // The return string
4: int liCase; // A random value ID
5:
6: // Which column are we generating for?
7: switch (m_iColumn)
8: {
9: case 0: // The first column (region)
10: // Generate a random value between 0 and 4
11: liCase = (rand() % 5);
12: // What value was generated?
13: switch (liCase)
14: {
15: case 0:
16: // 0 - Northwest region
17: lsStr = "Northwest";
18: break;
19: case 1:
20: // 1 - Southwest region
21: lsStr = "Southwest";
22: break;
23: case 2:
24: // 2 - Midwest region
25: lsStr = "Midwest";
26: break;
27: case 3:
28: // 3 - Northeast region
29: lsStr = "Northeast";
30: break;
31: default:
32: // 4 - Southeast region
33: lsStr = "Southeast";
34: break;
35: }
36: break;
37: case 1: // The second column (product)
38: // Generate a random value between 0 and 4
39: liCase = (rand() % 5);
40: // What value was generated?
41: switch (liCase)
42: {
43: case 0:
44: // 0 - Dodads
45: lsStr = "Dodads";
46: break;
47: case 1:
48: // 1 - Thingamajigs
49: lsStr = "Thingamajigs";
50: break;
51: case 2:
52: // 2 - Whatchamacallits
53: lsStr = "Whatchamacallits";
54: break;
55: case 3:
56: // 3 - Round Tuits
57: lsStr = "Round Tuits";
58: break;
59: default:
60: // 4 - Widgets
61: lsStr = "Widgets";
62: break;
63: }
64: break;
65: case 2: // The third column (employee)
66: // Generate a random value between 0 and 3
67: liCase = (rand() % 4);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -