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

📄 ch12.htm

📁 VC 21天 学习VC 的好东西
💻 HTM
📖 第 1 页 / 共 5 页
字号:
</P>
<P>The second argument is the rectangle that the combo box is to occupy. This argument
is the position within the parent window--in this case, the toolbar--that the combo
box will stay in. It will move with the parent window (the toolbar), staying in this
position the entire time.</P>
<P>The third argument is a pointer to the parent window. This is the address of the
color toolbar variable.</P>
<P>The fourth argument is the object ID for the combo box.</P>
<P>
<H4>Populating the Combo Box</H4>
<P>The final action that you have to do in creating the combo box on the color toolbar
is populate the drop-down list with the available items that the user can select
from. You do this with the combination of two functions:</P>
<P>
<PRE>if (szStyle.LoadString(IDS_WIDTH_VTHIN))
    m_ctlWidth.AddString((LPCTSTR)szStyle);
</PRE>
<P>The first function is a CString function, LoadString. This function takes a string
ID and loads the string matching the ID from the string table. The second function
is a combo box function, AddString, which adds the string passed in as an argument
to the drop-down list. By calling this function combination for each of the elements
that should be in the drop-down list, you can populate the combo box from the application
string table.</P>
<P>
<H4>Updating the OnCreate Function</H4>
<P>After moving all of the code to create the color toolbar to a separate function,
you can update the OnCreate function so that it calls the CreateColorBar function
where it used to create the color toolbar, as in Listing 12.6.</P>
<P>
<H4>LISTING 12.6. THE MODIFIED CMainFrame.OnCreate FUNCTION.</H4>
<PRE> 1:  int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
 2: {
 3:     if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
 4:         return -1;
 5: 
 6:     if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT,
                  &Acirc;WS_CHILD | WS_VISIBLE | CBRS_TOP
 7:         | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY |             &Acirc;CBRS_SIZE_DYNAMIC) ||
 8:         !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
 9:     {
10:         TRACE0(&quot;Failed to create toolbar\n&quot;);
11:         return -1;      // fail to create
12:     }
13: 
14:     ///////////////////////
15:     // MY CODE STARTS HERE
16:     ///////////////////////
17: 
18:     // Add the color toolbar
19:     if (!CreateColorBar())
20:     {
21:         TRACE0(&quot;Failed to create color toolbar\n&quot;);
22:         return -1;      // fail to create
23:     }
24: 
25:     ///////////////////////
26:     // MY CODE ENDS HERE
27:     ///////////////////////
28: 
29:     if (!m_wndStatusBar.Create(this) ||
30:         !m_wndStatusBar.SetIndicators(indicators,
31:           sizeof(indicators)/sizeof(UINT)))
32:     {
33:         TRACE0(&quot;Failed to create status bar\n&quot;);
34:         return -1;      // fail to create
35:     }
36: 
37:     // TODO: Delete these three lines if you don't want the toolbar to
38:     //  be dockable
39:     m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
40: 
41:     ///////////////////////
42:     // MY CODE STARTS HERE
43:     ///////////////////////
44: 
45:     // Enable docking for the Color Toolbar
46:     m_wndColorBar.EnableDocking(CBRS_ALIGN_ANY);
47: 
48:     ///////////////////////
49:     // MY CODE ENDS HERE
50:     ///////////////////////
51: 
</PRE>
<PRE>52:     EnableDocking(CBRS_ALIGN_ANY);
</PRE>
<PRE>53:     DockControlBar(&amp;m_wndToolBar);
54: 
55:     ///////////////////////
56:     // MY CODE STARTS HERE
57:     ///////////////////////
58: 
59:     // Dock the Color Toolbar
60:     DockControlBar(&amp;m_wndColorBar);
61: 
62:     ///////////////////////
63:     // MY CODE ENDS HERE
64:     ///////////////////////
65: 
66:     return 0;
67: }
</PRE>
<P>Now when you compile and run your application, you should have a combo box on
the end of your color toolbar, as in Figure 12.5. However, the combo box doesn't
do anything yet.</P>
<P><A HREF="javascript:popUp('12fig05tif.gif')"><B>FIGURE 12.5.</B></A><B> </B><I>The
color toolbar with a width combo box.</I></P>

<P><I></I>
<H3><A NAME="Heading9"></A>Handling the Toolbar Combo Box Events</H3>
<P>Adding an event handler for the combo box is fairly simple, although it does have
to be done by hand (because the Class Wizard doesn't even know that the combo box
exists). You have to add an ON_CBN_SELCHANGE entry into the message map and then
add the actual message-handler function into the CMainFrame class.</P>
<P>To start with, add the message-handler function by selecting the CMainFrame class
in the workspace pane and selecting New Member Function from the pop-up menu. Enter
the function type as afx_msg void, the function definition as OnSelChangeWidth, and
the access as protected. Edit the new function as in Listing 12.7.</P>
<P>
<H4>LISTING 12.7. THE OnSelChangeWidth FUNCTION.</H4>
<PRE> 1: void CMainFrame::OnSelChangeWidth()
 2: {
 3:     // Get the new combo selection
 4:     int nIndex = m_ctlWidth.GetCurSel();
 5:     if (nIndex == CB_ERR)
 6:         return;
 7: 
 8:     // Get the active document
 9:     CToolbarDoc* pDoc = (CToolbarDoc*)GetActiveDocument();
10:     // Do we have a valid document?
11:     if (pDoc)
12:         // Set the new drawing width
13:         pDoc-&gt;SetWidth(nIndex);
14: 
15: }
</PRE>
<P>In this function, you first get the current selection from the combo box. Remember
that the entries were added in order, and the CBS_SORT flag was not specified in
the combo box creation, so the selection index numbers should correspond to the widths
in the document. As a result, you can get a pointer to the current document instance,
using the GetActiveDocument function, and then pass the new width to the document
using its SetWidth function.</P>
<P>For the combo box selection changes to call this message-handler function, you
need to add the appropriate entry to the CMainFrame message map. Scroll to the top
of the CMainFrame source code until you find the message map section. Add line 12
in Listing 12.8 to the message map.</P>
<P>
<H4>LISTING 12.8. THE MODIFIED CMainFrame MESSAGE MAP.</H4>
<PRE> 1:///////////////////////////////////////////////////////////////////////
 2: // CMainFrame
 3: 
 4: IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
 5: 
 6: BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
 7:     //{{AFX_MSG_MAP(CMainFrame)
 8:     ON_WM_CREATE()
 9:     ON_COMMAND(ID_VIEW_COLORBAR, OnViewColorbar)
10:     ON_UPDATE_COMMAND_UI(ID_VIEW_COLORBAR, OnUpdateViewColorbar)
11:     //}}AFX_MSG_MAP
12:     ON_CBN_SELCHANGE(IDC_CBWIDTH, OnSelChangeWidth)
13: END_MESSAGE_MAP()
</PRE>
<P>This message map entry</P>
<P>
<PRE>ON_CBN_SELCHANGE(IDC_CBWIDTH, OnSelChangeWidth)
</PRE>
<P>specifies that on combo box selection change events with the object ID of the
color toolbar combo box, the OnSelChangeWidth function should be called. Now if you
compile and run your application, you should be able to change the drawing width
with the combo box on the color toolbar.</P>
<P>
<H3><A NAME="Heading10"></A>Updating the Toolbar Combo Box</H3>
<P>The one remaining problem with the combo box is that it needs to be updated if
the user selects a new value from the menu instead of the combo box. One of the most
efficient methods of doing this is to set the current selection in the combo box
when any of the menu selections are triggered. This requires a function in the main
frame class that can be called from the document class to accomplish this action.
All the function in the main frame needs to do is to set the current selection in
the combo box.</P>
<P>To implement this function in the main frame, add a new member function to the
CMainFrame class, specifying the function type as void, the definition as UpdateWidthCB(int
nIndex), and the access as public. Once you add this function, edit the function
as in Listing 12.9.</P>
<P></P>

<P><B>Listing 12.9. </B>The CMAINFRAME.UPDATEWIDTHCB function. 
<PRE>1: void CMainFrame::UpdateWidthCB(int nIndex)
2: {
3:     // Set the new selection in the combo box
4:     m_wndColorBar.m_ctlWidth.SetCurSel(nIndex);
5: }
</PRE>
<P>This function uses a single combo box function, SetCurSel, which sets the current
selection in the combo box drop-down list to the entry specified with the index number.
The edit control of the combo box is updated with the new selected list entry. If
an index number that doesn't exist in the drop-down list is supplied to the combo
box, then the function returns an error.</P>
<P>On the document side, you need to call this function in the main frame whenever
the appropriate menu event-handling functions are called. Because this could occur
in sev- eral functions, it makes the most sense to enclose the necessary functionality
in a single function. This function needs to get a pointer to the view associated
with the document and then, through the view, get a pointer to the frame, which can
then be used to call the UpdateWidthCB function that you just added to the main frame
class.</P>
<P>To add this function to your application, select the CToolbarDoc class in the
workspace pane, and select Add Member Function from the pop-up menu. Specify void
as the function type, UpdateColorbar(int nIndex) as the function definition, and
private as the function access. Edit the function as in Listing 12.10.</P>
<P>
<H4>LISTING 12.10. THE CToolbarDoc.UpdateColorbar FUNCTION.</H4>
<PRE> 1: void CToolbarDoc::UpdateColorbar(int nIndex)
 2: {
 3:     // Get the position of the first view
 4:     POSITION pos = GetFirstViewPosition();
 5:     // Did we get a valid position?
 6:     if (pos != NULL)
 7:     {
 8:         // Get a pointer to the view in that position
 9:         CView* pView = GetNextView(pos);
10:         // Do we have a valid pointer to the view?
11:         if (pView)
12:         {
13:             // Get a pointer to the frame through the view
14:             CMainFrame* pFrame = (CMainFrame*)pView-&Acirc;GetTopLevelFrame();
15:             // Did we get a pointer to the frame?
16:             if (pFrame)
17:                 // Update the combo box on the color toolbar
18:                 // through the frame
19:                 pFrame-&gt;UpdateWidthCB(nIndex);
20:         }
21:     }
22: }
</PRE>
<P>This function traces through the path that you have to follow to get to the application
frame from the document class. The first thing that you did was get the position
of the first view associated with the document, using the GetFirstViewPosition function.
A document may have multiple views open at the same time, and this function returns
the position of the first of those views.</P>
<P>The next function, GetNextView, returns a pointer to the view specified by the
position. This function also updates the position variable to point to the next view
in the list of views associated with the current document.</P>
<P>Once you have a pointer to the view, you can call the window function, GetTopLevelFrame,
which returns a pointer to the application frame window. You have to call this function
through the view because the document is not descended from the CWnd class, although
the view is.</P>
<P>Once you have a pointer to the frame window, you can use this pointer to call
the function you created earlier to update the combo box on the toolbar. Now if you
call this new function from the Width menu command event handlers, as in Listing
12.11, the combo box that you placed on the color toolbar is automatically updated
to reflect the currently selected drawing width, regardless of whether the width
was selected from the combo box or the pull-down menu.</P>
<P>
<H4>LISTING 12.11. AN UPDATED WIDTH MENU COMMAND EVENT HANDLER.</H4>
<PRE>1: void CToolbarDoc::OnWidthVthin()
2: {
3:     // TODO: Add your command handler code here
4:     // Set the new width
5:     m_nWidth = 0;
6:     // Update the combo box on the color toolbar
7:     UpdateColorbar(0);
8: }
</PRE>
<H2><A NAME="Heading11"></A>Adding a New Status Bar Element</H2>
<P>Earlier today, you learned how to specify status bar messages and tooltips for
both toolbar buttons and menus. What if you want to use the status bar to provide
the user with more substantial information? What if, as in the Visual C++ Developer
Studio, you want to provide information about what the user is doing, where he is
in the document he is editing, or the mode that the application is in? This information
goes beyond the Caps, Num, and Scroll lock keys that Visual C++ automatically reports
on the status bar.</P>
<P>It's actually easy to add additional panes to the status bar, as well as take
away the panes that are already there. To learn just how easy a change this is, you
will add a new pane to the status bar in your drawing application that will display
the color currently in use.</P>
<P>
<H3><A NAME="Head

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -