📄 ch20.htm
字号:
<P>
<HR>
<B> </B><FONT COLOR="#000077"><B>Just a Minute:</B></FONT><B> </B>Due to the way
in which the Developer Studio tools are integrated, ClassWizard knows all about the
Microsoft FlexGrid control and understands that the <TT>CMSFlexGrid</TT> class is
used to interact with the control.
<HR>
</BLOCKQUOTE>
<P>The main dialog box class, <TT>CCustomCtrlDlg</TT>, uses three new member variables
to interact with the grid control.
<UL>
<LI><TT>m_nRow</TT> is used to store the current cell row when a cell is being edited.<BR>
<BR>
<LI><TT>m_nCol</TT> is used to store the current cell column when a cell is being
edited.<BR>
<BR>
<LI><TT>m_bEditing</TT> is set to <TT>TRUE</TT> when a cell is being edited and <TT>FALSE</TT>
otherwise.
</UL>
<P>Add the declarations for these variables to the <TT>CCustomCtrlDlg</TT> class,
as shown in Listing 20.1. Add the source code to the implementation section, just
after the <TT>// Implementation</TT> comment.
<H4><FONT COLOR="#000077">TYPE: Listing 20.1. Modifications to the CCustomCtrlDlg
class declaration.</FONT></H4>
<PRE><FONT COLOR="#0066FF"><TT>// Implementation</TT>
<TT>protected:</TT>
<TT> BOOL m_bEditing;</TT>
<TT> int m_nRow;</TT>
</FONT></PRE>
<P><TT>int m_nCol;</TT> The grid control must be initialized during the main dialog
box's <TT>OnInitDialog</TT> member function. Add the source code from Listing 20.2
to the <TT>CCustomCtrlDlg::OnInitDialog</TT> member function, just after the <TT>//
TODO</TT> comment.
<H4><FONT COLOR="#000077">TYPE: Listing 20.2. Initializing the ActiveX grid control
in OnInitDialog.</FONT></H4>
<PRE><FONT COLOR="#0066FF"><TT>// TODO: Add extra initialization here</TT>
<TT>m_bEditing = FALSE;</TT>
<TT>m_nRow = 1;</TT>
<TT>m_nCol = 1;</TT>
<TT>char* arCols[4] = { "Jan", "Feb", "Mar", "Apr" };</TT>
<TT>char* arRows[4] = { "Gas", "Phone", "MSN", "Total" };</TT>
<TT>m_grid.SetRow( 0 );</TT>
<TT>for( int nCol = 0; nCol < 4; nCol++ )</TT>
<TT>{</TT>
<TT> m_grid.SetCol( nCol + 1 );</TT>
<TT> m_grid.SetText( arCols[nCol] );</TT>
<TT>}</TT>
<TT>m_grid.SetCol( 0 );</TT>
<TT>for( int nRow = 0; nRow < 4; nRow++ )</TT>
<TT>{</TT>
<TT> m_grid.SetRow( nRow + 1 );</TT>
<TT> m_grid.SetText( arRows[nRow] );</TT>
</FONT></PRE>
<P><TT>}</TT> The source code added to the <TT>OnInitDialog</TT> function first initializes
the new member variables added in Listing 20.1. The remaining code initializes the
grid control.</P>
<P>The first <TT>for</TT> loop in Listing 20.2 sets the column headings to the first
four months of the year. The next <TT>for</TT> loop sets the text used as row titles
in the grid control. This short snippet of code shows how a grid control is typically
used: Select a cell and then set or retrieve the text stored in that cell.
<H3><FONT COLOR="#000077"><B>Detecting Grid Control Events</B></FONT></H3>
<P>When an event occurs in the grid control, the control fires an event message to
its container. The MFC framework translates this event message into a function call.
To define the <TT>Click</TT> event message that is handled by the main dialog box,
you use ClassWizard to add a message-handling function for the message, as shown
in Table 20.3.
<H4><FONT COLOR="#000077">Table 20.3. ActiveX event messages handled by the CCustomCtrlDlg
class.</FONT></H4>
<P>
<TABLE BORDER="1">
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><B>Object ID</B></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><B>Class Name</B></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><B>Message</B></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><B>Function</B></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><TT>IDC_GRID</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><TT>CCustomCtrlDlg</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><TT>Click</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><TT>OnClickGrid</TT></TD>
</TR>
</TABLE>
</P>
<P>Add the source code for the <TT>CCustomCtrlDlg::OnClickGrid</TT> function provided
in List- ing 20.3.
<H4><FONT COLOR="#000077">TYPE: Listing 20.3. Handling a mouse click event from the
ActiveX grid control.</FONT></H4>
<PRE><FONT COLOR="#0066FF"><TT>void CCustomCtrlDlg::OnClickGrid()</TT>
<TT>{</TT>
<TT> CString szText = m_grid.GetText();</TT>
<TT> if( m_bEditing == FALSE )</TT>
<TT> {</TT>
<TT> // Save the current grid position and set the edit flag.</TT>
<TT> m_nRow = m_grid.GetRow();</TT>
<TT> m_nCol = m_grid.GetCol();</TT>
<TT> m_bEditing = TRUE;</TT>
<TT> // Get the current grid text, and display it in the edit</TT>
<TT> // control.</TT>
<TT> szText = m_grid.GetText();</TT>
<TT> m_edit.SetWindowText( szText );</TT>
<TT> m_edit.ShowWindow( SW_SHOW );</TT>
<TT> m_edit.SetFocus();</TT>
<TT> m_edit.SetSel( 0, -1 );</TT>
<TT> }</TT>
<TT> else</TT>
<TT> {</TT>
<TT> // Roll up the edit control, and update the previous</TT>
<TT> // grid position. You must save the current position,</TT>
<TT> // go back to the old position, and then return to the</TT>
<TT> // current position.</TT>
<TT> int nCurrentRow = m_grid.GetRow();</TT>
<TT> int nCurrentCol = m_grid.GetCol();</TT>
<TT> m_grid.SetRow( m_nRow );</TT>
<TT> m_grid.SetCol( m_nCol );</TT>
<TT> m_grid.SetFocus();</TT>
<TT> CString szEntry;</TT>
<TT> m_edit.GetWindowText( szText );</TT>
<TT> szEntry.Format("%01.2f", atof(szText) );</TT>
<TT> m_edit.ShowWindow( SW_HIDE );</TT>
<TT> m_grid.SetText( szEntry );</TT>
<TT> m_bEditing = FALSE;</TT>
<TT> m_grid.SetRow( nCurrentRow );</TT>
<TT> m_grid.SetCol( nCurrentCol );</TT>
<TT> }</TT>
</FONT></PRE>
<P><TT>}</TT> If the program receives a <TT>Click</TT> event, the <TT>m_bEditing</TT>
flag is checked to see whether a cell is currently being edited. If not, the current
row and column are collected from the grid control. This information is used later
when the editing job is finished. The text stored in the current grid cell is retrieved
and displayed in the edit control. Finally, the edit control text is selected, which
makes it easy for a user to overwrite the current contents.</P>
<P>If a cell is being edited, the text contained in the edit control is stored in
the grid. However, it must be stored in the cell that was originally clicked to open
the edit control. This cell position was stored when the edit control was opened
and is now used to reset the current row and column. The edit control text is reformatted
into a standard dollars-and-cents format and stored in the original cell position.</P>
<P>The <TT>GetRow</TT> and <TT>GetCol</TT> functions provided by <TT>CGridCtrl</TT>
are examples of ActiveX control methods that are exposed by the grid control. For
a complete list of exposed methods, open the project workspace view and click the
ClassView tab. Open the <TT>CGridCtrl</TT> class icon, and you see a list of the
available member functions.
<H3><FONT COLOR="#000077"><B>Recalculating the Grid Control Contents</B></FONT></H3>
<P>Each column in the spreadsheet is recalculated when you click the Calculate button.
Add a message-handling function to the <TT>CCustomCtrlDlg</TT> class that handles
messages from the Calculate button, using the values from Table 20.4.
<H4><FONT COLOR="#000077">Table 20.4. Messages handled by the CCustomCtrlDlg class.</FONT></H4>
<P>
<TABLE BORDER="1">
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><B>Object ID</B></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><B>Class Name</B></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><B>Message</B></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><B>Function</B></TD>
</TR>
<TR ALIGN="LEFT" rowspan="1">
<TD ALIGN="LEFT" VALIGN="TOP"><TT>IDC_CALC</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><TT>CCustomCtrlDlg</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><TT>BN_CLICKED</TT></TD>
<TD ALIGN="LEFT" VALIGN="TOP"><TT>OnCalc</TT></TD>
</TR>
</TABLE>
</P>
<P>Add the source code in Listing 20.4 to the <TT>CCustomCtrlDlg::OnCalc</TT> member
function.
<H4><FONT COLOR="#000077">TYPE: Listing 20.4. Recalculating the contents of the ActiveX
grid control.</FONT></H4>
<PRE><FONT COLOR="#0066FF"><TT>void CCustomCtrlDlg::OnCalc()</TT>
<TT>{</TT>
<TT> // Close current editing job, if any.</TT>
<TT> if( m_bEditing != FALSE )</TT>
<TT> {</TT>
<TT> CString szEntry, szText;</TT>
<TT> m_edit.GetWindowText( szText );</TT>
<TT> szEntry.Format("%01.2f", atof(szText) );</TT>
<TT> m_edit.ShowWindow( SW_HIDE );</TT>
<TT> m_grid.SetText( szEntry );</TT>
<TT> m_bEditing = FALSE;</TT>
<TT> }</TT>
<TT> for( int nCol = 1; nCol < 5; nCol++ )</TT>
<TT> {</TT>
<TT> double dTotal = 0.0;</TT>
<TT> m_grid.SetCol( nCol );</TT>
<TT> for( int nRow = 1; nRow < 4; nRow++ )</TT>
<TT> {</TT>
<TT> m_grid.SetRow( nRow );</TT>
<TT> CString szCell = m_grid.GetText();</TT>
<TT> dTotal += atof( szCell );</TT>
<TT> }</TT>
<TT> CString szTotal;</TT>
<TT> szTotal.Format( "%01.2f", dTotal );</TT>
<TT> m_grid.SetRow( 4 );</TT>
<TT> m_grid.SetText( szTotal );</TT>
<TT> }</TT>
</FONT></PRE>
<P><TT>}</TT> Compile and run the <TT>CustomCtrl</TT> example. The grid control is
initially empty. Clicking on a cell displays the edit control, which enables you
to enter or change the cell's contents. If you click on the cell again, the value
from the edit control is moved into the cell, and the edit control is hidden. Clicking
the Calculate button totals each column in the grid control and hides the edit control.
Figure 20.4 shows the CustomCtrl main dialog box with some of the grid cells filled
in.</P>
<P><A NAME="04"></A><A HREF="04.htm"><B>Figure 20.4.</B></A> <BR>
<I>The CustomCtrl project's main dialog box.</I>
<H2><FONT COLOR="#000077"><B>Summary</B></FONT></H2>
<P>In this hour, you learned about ActiveX controls and the Developer Studio tools
that are used with them. As part of the discussion, you created an example that used
an ActiveX grid control as a small spreadsheet.
<H2><FONT COLOR="#000077"><B>Q&A</B></FONT></H2>
<DL>
<DD><B>Q How can I determine which events are provided by an ActiveX control?</B><BR>
<BR>
<B>A</B> After the ActiveX control is added to your project, you can use ClassWizard
to examine the events that are generated by the control.<BR>
<BR>
<B>Q How can I reuse controls installed on my computer by other applications?</B><BR>
<BR>
<B>A</B> Most commercial controls are licensed; they cannot be used to design new
applications without the proper ActiveX licensing file. Some controls can be used
for evaluation purposes, even without a license--to be sure, contact the control
vendor.
</DL>
<H2><FONT COLOR="#000077"><B>Workshop</B></FONT></H2>
<P>The Workshop is designed to help you anticipate possible questions, review what
you've learned, and begin thinking ahead to putting your knowledge into practice.
The answers to the quiz are in Appendix B, "Quiz Answers."
<H3><FONT COLOR="#000077"><B>Quiz</B></FONT></H3>
<DL>
<DD>1. Where are reusable components stored in Developer Studio?<BR>
<BR>
2. What are some other development tools that support creating and using ActiveX
controls?<BR>
<BR>
3. What are some examples of events sent from an ActiveX control?<BR>
<BR>
4. What are some examples of properties exposed by ActiveX controls?<BR>
<BR>
5. What ActiveX control is often used to model a small spreadsheet?<BR>
<BR>
6. True or False: You can edit directly in a grid cell.<BR>
<BR>
7. What AppWizard option must be selected to allow an ActiveX control to work properly?<BR>
<BR>
8. What is an ActiveX method?<BR>
<BR>
9. True or False: ActiveX controls can be developed only for 32-bit systems.
</DL>
<H3><FONT COLOR="#000077"><B>Exercises</B></FONT></H3>
<DL>
<DD>1. Modify the CustomCtrl project so that 12 months are displayed in the grid
and totals are provided for each row as well as for columns.<BR>
<BR>
2. Modify the CustomCtrl project so that the grid is recalculated automatically.<FONT
COLOR="#000077"></FONT>
</DL>
<CENTER>
<P>
<HR>
<A HREF="../ch21/ch21.htm"><IMG SRC="../button/previous.gif" WIDTH="128" HEIGHT="28"
ALIGN="BOTTOM" ALT="Previous chapter" BORDER="0"></A><A HREF="../ch23/ch23.htm"><IMG
SRC="../button/next.gif" WIDTH="128" HEIGHT="28" ALIGN="BOTTOM" ALT="Next chapter"
BORDER="0"></A><A HREF="../index.htm"><IMG SRC="../button/contents.gif" WIDTH="128"
HEIGHT="28" ALIGN="BOTTOM" ALT="Contents" BORDER="0"></A> <BR>
<BR>
<BR>
<IMG SRC="../button/corp.gif" WIDTH="284" HEIGHT="45" ALIGN="BOTTOM" ALT="Macmillan Computer Publishing USA"
BORDER="0"></P>
<P>© <A HREF="../copy.htm">Copyright</A>, Macmillan Computer Publishing. All
rights reserved.
</CENTER>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -