⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch09.htm

📁 VC 21天 学习VC 的好东西
💻 HTM
📖 第 1 页 / 共 3 页
字号:
68:         // What value was generated?
69:         switch (liCase)
70:         {
71:         case 0:
72:             // 0 - Dore
73:             lsStr = "Dore";
74:             break;
75:         case 1:
76:             // 1 - Harvey
77:             lsStr = "Harvey";
78:             break;
79:         case 2:
80:             // 2 - Pogo
81:             lsStr = "Pogo";
82:             break;
83:         default:
84:             // 3 - Nyra
85:             lsStr = "Nyra";
86:             break;
87:         }
88:         break;
89:     }
90:     // Return the generated string
91:     return lsStr;
</PRE>

<PRE>92: }</PRE>
<P>
<H4>Sorting the Control</H4>
<P>To sort the Grid control, you need to select all the columns and then set the
sort to ascending. To implement this functionality, add one more function to the
CActiveXDlg class with a type of void and a definition of DoSort. Edit the function
as in Listing 9.4.</P>
<P>
<H4>LISTING 9.4. THE DoSort FUNCTION.</H4>
<PRE> 1: void CActiveXDlg::DoSort()
 2: {
 3:     // Set the current column to column 0
 4:     m_ctlFGrid.SetCol(0);
 5:     // Set the column selection to all columns
 6:     m_ctlFGrid.SetColSel((m_ctlFGrid.GetCols() - 1));
 7:     // Generic Ascending Sort
 8:     m_ctlFGrid.SetSort(1);
</PRE>

<PRE>9: }</PRE>
<P>In the DoSort function, you set the current column to the first column using the
SetCol method. Next you select from the current column to the last column using the
SetColSel method, effectively selecting all columns in the control. Finally, you
tell the control to sort the columns in ascending order by using the SetSort method,
passing 1 as the flag for the sort order.</P>
<P>Now that you have all the functionality necessary to load the control with data,
you need to call the LoadData function in the OnInitDialog function to load the data
before the control is visible to the user. Edit the OnInitDialog function as in Listing
9.5 to load the data.</P>
<P>
<H4>LISTING 9.5. THE OnInitDialog FUNCTION.</H4>
<PRE> 1: BOOL CActiveXDlg::OnInitDialog()
 2: {
 3:     CDialog::OnInitDialog();
 4: .
 5: .
 6: .
 7:     // TODO: Add extra initialization here
 8: 
 9:     ///////////////////////
10:     // MY CODE STARTS HERE
11:     ///////////////////////
12: 
13:     // Load data into the Grid control
14:     LoadData();
15: 
16:     ///////////////////////
17:     // MY CODE ENDS HERE
18:     ///////////////////////
19: 
20:     return TRUE;  // return TRUE  unless you set the focus to a control
</PRE>

<PRE>21: }</PRE>
<P>If you compile and run your application at this point, you find that it is loading
the data and sorting it, as in Figure 9.7.</P>
<P><A HREF="javascript:popUp('09fig07.gif')"><B>FIGURE 9.7.</B></A><B> </B><I>The
FlexGrid populated with data.</I></P>

<P><I></I>
<H3><A NAME="Heading9"></A>Responding to Control Events</H3>
<P>If you play with your application at this point, you know that the Grid control
does not respond to any input that you might try to give it. If you click one of
the cells and try to change the value, it doesn't respond. What you need to do is
add a control event to handle the input. ActiveX controls make several events available
for use in Visual C++ applications. You can use the Class Wizard to browse through
the available events and determine which events you need to give functionality and
which to ignore. Most ActiveX controls don't have any default functionality attached
to the available events but instead expect you to tell the control what to do on
each event.</P>
<P>You are going to add two control events to capture the mouse clicks and movements.
You will add functionality to allow the user to click a column header and drag it
to another position, thus rearranging the column order. To implement this functionality,
you have to capture two control events, when the mouse button is pressed down and
when it is released. On the first event, you need to check whether the user clicked
a header, and if so, you capture the column selected. On the second event, you need
to move the selected column to the column on which the mouse button was released.</P>
<P>To accomplish this functionality, you need to create a new class variable to maintain
the clicked column number between the two events. Add a new variable to the CActiveXDlg
class, just like you added the functions earlier, specifying the type as int, the
variable name as m_iMouseCol, and the access as Private.</P>
<P>
<H4>Capturing the Column Selected</H4>
<P>To capture the mouse click event for the control, follow these steps:</P>
<P>

<DL>
	<DT></DT>
	<DD><B>1. </B>Using the Class Wizard, add a function for the MouseDown event message
	for the IDC_MSFGRID object.
	<P>
	<DT></DT>
	<DD><B>2. </B>Edit the function using the code in Listing 9.6.
	<P>
</DL>

<H4>LISTING 9.6. THE OnMouseDownMsfgrid FUNCTION.</H4>
<PRE> 1: void CActiveXDlg::OnMouseDownMsfgrid(short Button, short Shift, long      	  &Acirc;x, long y)
 2: {
 3:     // TODO: Add your control notification handler code here
 4: 
 5:     ///////////////////////
 6:     // MY CODE STARTS HERE
 7:     ///////////////////////
 8: 
 9:     // Did the user click on a data row and not the
10:     // header row?
11:     if (m_ctlFGrid.GetMouseRow() != 0)
12:     {
13:         // If so, then zero out the column variable
14:         // and exit
15:         m_iMouseCol = 0;
16:         return;
17:     }
18:     // Save the column clicked on
19:     m_iMouseCol = m_ctlFGrid.GetMouseCol();
20: 
21:     ///////////////////////
22:     // MY CODE ENDS HERE
23:     ///////////////////////
</PRE>

<PRE>24: }</PRE>
<P>In this function, you checked the row clicked by calling the GetMouseRow method.
If the row is not the first row, then zero out the column-holding variable and exit
the function. Otherwise, you need to get the column clicked by calling the GetMouseCol
method. You can store the returned column number in the m_iMouseCol variable that
you just added to the class.</P>
<P>
<H4>Moving the Column Where Released</H4>
<P>Now that you are capturing the selected column number, you need to capture the
column on which the mouse is released. To capture the mouse release event for the
control, follow these steps:</P>
<P>

<DL>
	<DT></DT>
	<DD><B>1. </B>Using the Class Wizard, add a function for the MouseUp event message
	for the IDC_MSFGRID object.
	<P>
	<DT></DT>
	<DD><B>2. </B>Edit the function using the code in Listing 9.7.
	<P>
</DL>

<H4>LISTING 9.7. THE OnMouseUpMsfgrid FUNCTION.</H4>
<PRE> 1: void CActiveXDlg::OnMouseUpMsfgrid(short Button, short Shift, long x, 		  &Acirc;long y)
 2: {
 3:     // TODO: Add your control notification handler code here
 4: 
 5:     ///////////////////////
 6:     // MY CODE STARTS HERE
 7:     ///////////////////////
 8: 
 9:     // If the selected column was the first column,
10:     // there's nothing to do
11:     if (m_iMouseCol == 0)
12:         return;
13:     // Turn the control redraw off
14:     m_ctlFGrid.SetRedraw(FALSE);
15:     // Change the selected column position
16:     m_ctlFGrid.SetColPosition(m_iMouseCol, m_ctlFGrid.GetMouseCol());
17:     // Resort the grid
18:     DoSort();
19:     // Turn redraw back on
20:     m_ctlFGrid.SetRedraw(TRUE);
21: 
22:     ///////////////////////
23:     // MY CODE ENDS HERE
24:     ///////////////////////
</PRE>

<PRE>25: }</PRE>
<P>In this function, you first check to see if there is a selected column to be moved.
If not, you exit the function with nothing to do. If there is a column selected,
you turn off the redraw on the control using the SetRedraw method so that none of
the movement is seen by the user. Next, you move the selected column to the release
column using the SetColPosition method. Once you move the column, you resort the
grid by calling the DoSort function. Finally, you turn the control's redraw back
on so that the control is refreshed to show the user the moved column. If you compile
and link your application, you should now be able to grab column headers and move
the columns about, as in Figure 9.8.</P>
<P><A HREF="javascript:popUp('09fig08.gif')"><B>FIGURE 9.8.</B></A><B> </B><I>The
FlexGrid with reordered columns.</I></P>

<P><I></I>
<H2><A NAME="Heading10"></A>Summary</H2>
<P>Today you learned how you can use ActiveX controls in your Visual C++ applications
to easily extend your application's functionality. You learned the basics of how
ActiveX controls work and how they interact with the containing application. You
also learned how you can add an ActiveX control to your development project so that
you can use it in your application. You saw how Visual C++ creates C++ classes to
encapsulate the ActiveX controls that you add and how you can interact with the control
through the exposed methods of these generated C++ classes. You also saw how you
can capture events that are generated by the ActiveX control so that you can program
your application to react to the events.</P>
<P>
<H2><A NAME="Heading11"></A>Q&amp;A</H2>

<DL>
	<DT></DT>
	<DD><B>Q How can I determine what methods are available to me when working with an
	ActiveX control?</B>
	<P>
	<DT><B></B></DT>
	<DD><B>A</B> By examining the C++ classes that Visual C++ builds to encapsulate the
	control, you can get a good idea of what functionality is available to you. If you
	have documentation for the control, you can compare it to the C++ class to determine
	which class method calls which control method. You can examine the events listed
	for the control in the Class Wizard to determine which events are also available.
	<P>
	<DT></DT>
	<DD><B>Q How can I use the ActiveX controls that were installed on my machine with
	another application in my Visual C++ applications?</B>
	<P>
	<DT><B></B></DT>
	<DD><B>A</B> It depends on how the controls are licensed and what application installed
	the controls. If the controls were installed by another application development tool,
	chances are that you have a development license for the control, in which case you
	should be able to use them in your Visual C++ applications. If the controls were
	installed by an end-user application, such as Word or Quicken, then odds are that
	you have only a runtime license for the control. If you want to use these controls
	in your own applications, you need to contact the control developer to acquire a
	development license for the controls.
	<P>
	<DT></DT>
	<DD><B>Q Because the FlexGrid control does not allow me to enter data directly into
	the control, how can I let my users enter data into the grid as if they were using
	a spreadsheet?</B>
	<P>
	<DT><B></B></DT>
	<DD><B>A</B> To implement this functionality for the FlexGrid control, you need to
	add a floating Edit Box control to your window. Your code needs to determine which
	cell the user wants to edit and float the edit box in front of that cell. This arrangement
	allows the user to feel as if he is entering data directly into the cell. Another
	approach is to have a data-entry field outside the grid, much like is used in Excel,
	into which the user enters the data. You can highlight the cells as the user maneuvers
	around the Grid control to give the user visceral feedback for her actions.
	<P>
</DL>

<H2><A NAME="Heading12"></A>Workshop</H2>
<P>The Workshop provides quiz questions to help you solidify your understanding of
the material covered and exercises to provide you with experience in using what you've
learned. The answers to the quiz questions and exercises are provided in Appendix
B, &quot;Answers.&quot;</P>
<P>
<H3><A NAME="Heading13"></A>Quiz</H3>

<DL>
	<DT></DT>
	<DD><B>1. </B>How does an ActiveX container call methods in an ActiveX control?
	<P>
	<DT></DT>
	<DD><B>2. </B>How does an ActiveX control trigger events in the container application?
	<P>
	<DT></DT>
	<DD><B>3. </B>What AppWizard option must be selected for ActiveX controls to work
	properly in a Visual C++ application?
	<P>
	<DD><B>4. </B>How does Visual C++ make it easy to work with ActiveX controls?
	<DT></DT>
	<DD><B>5. </B>Why might it be difficult to work with older controls in Visual C++?
	<P>
</DL>

<H3><A NAME="Heading14"></A>Exercise</H3>
<P>Modify the application so that the user can double-click a column header and make
it the first column in the grid.</P>
<H1></H1>
<CENTER>
<P>
<HR>
<A HREF="../ch08/ch08.htm"><IMG SRC="../button/previous.gif" WIDTH="128" HEIGHT="28"
ALIGN="BOTTOM" ALT="Previous chapter" BORDER="0"></A><A HREF="../ch10/ch10.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>
</P>

<P>&copy; <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 + -