?? ch20.htm
字號(hào):
<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 variablesto 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, justafter the <TT>// Implementation</TT> comment.<H4><FONT COLOR="#000077">TYPE: Listing 20.1. Modifications to the CCustomCtrlDlgclass 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 dialogbox's <TT>OnInitDialog</TT> member function. Add the source code from Listing 20.2to 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 controlin 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 initializesthe new member variables added in Listing 20.1. The remaining code initializes thegrid control.</P><P>The first <TT>for</TT> loop in Listing 20.2 sets the column headings to the firstfour months of the year. The next <TT>for</TT> loop sets the text used as row titlesin the grid control. This short snippet of code shows how a grid control is typicallyused: 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 toits 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 shownin Table 20.3.<H4><FONT COLOR="#000077">Table 20.3. ActiveX event messages handled by the CCustomCtrlDlgclass.</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 providedin List- ing 20.3.<H4><FONT COLOR="#000077">TYPE: Listing 20.3. Handling a mouse click event from theActiveX 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 currentrow and column are collected from the grid control. This information is used laterwhen the editing job is finished. The text stored in the current grid cell is retrievedand displayed in the edit control. Finally, the edit control text is selected, whichmakes 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 inthe grid. However, it must be stored in the cell that was originally clicked to openthe edit control. This cell position was stored when the edit control was openedand is now used to reset the current row and column. The edit control text is reformattedinto 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. Fora complete list of exposed methods, open the project workspace view and click theClassView tab. Open the <TT>CGridCtrl</TT> class icon, and you see a list of theavailable 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 handlesmessages 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> memberfunction.<H4><FONT COLOR="#000077">TYPE: Listing 20.4. Recalculating the contents of the ActiveXgrid 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 isinitially empty. Clicking on a cell displays the edit control, which enables youto enter or change the cell's contents. If you click on the cell again, the valuefrom the edit control is moved into the cell, and the edit control is hidden. Clickingthe 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 filledin.</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 toolsthat are used with them. As part of the discussion, you created an example that usedan 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 whatyou'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"><IMGSRC="../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. Allrights reserved.</CENTER></BODY></HTML>
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -