?? ch14.htm
字號:
</TR> <TR ALIGN="LEFT" rowspan="1"> <TD ALIGN="LEFT" VALIGN="TOP"><TT>IDI_HAND</TT></TD> <TD ALIGN="LEFT" VALIGN="TOP">Stop sign icon</TD> </TR> <TR ALIGN="LEFT" rowspan="1"> <TD ALIGN="LEFT" VALIGN="TOP"><TT>IDI_QUESTION</TT></TD> <TD ALIGN="LEFT" VALIGN="TOP">Question mark icon</TD> </TR> <TR ALIGN="LEFT" rowspan="1"> <TD ALIGN="LEFT" VALIGN="TOP"><TT>IDI_EXCLAMATION</TT></TD> <TD ALIGN="LEFT" VALIGN="TOP">Exclamation point icon</TD> </TR> <TR ALIGN="LEFT" rowspan="1"> <TD ALIGN="LEFT" VALIGN="TOP"><TT>IDI_ASTERISK</TT></TD> <TD ALIGN="LEFT" VALIGN="TOP">Asterisk or information icon</TD> </TR> <TR ALIGN="LEFT" rowspan="1"> <TD ALIGN="LEFT" VALIGN="TOP"><TT>IDI_WINLOGO</TT></TD> <TD ALIGN="LEFT" VALIGN="TOP">Windows logo icon</TD> </TR></TABLE></P><P>Using these cursors is similar to using stock objects. Listing 14.6 uses the <TT>IDC_UPARROW</TT>cursor in response to <TT>WM_SETCURSOR</TT>.<H4><FONT COLOR="#000077">TYPE: Listing 14.6. Using a standard Windows cursor.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT>BOOL CAboutDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest,</TT><TT> UINT message)</TT><TT>{</TT><TT> // Load and set the new cursor. Return TRUE to stop</TT><TT> // further processing of this message.</TT><TT> CWinApp* pApp = AfxGetApp();</TT><TT> HICON hIcon = pApp->LoadStandardCursor( IDC_UPARROW );</TT><TT> SetCursor( hIcon );</TT><TT> return TRUE;</TT><TT>}</TT></FONT></PRE><P>A cursor set in response to the <TT>WM_SETCURSOR</TT> message will interfere withthe remaining examples in the hour. After you are finished with this example, removethe <TT>OnSetCursor</TT> function using ClassWizard.<H3><FONT COLOR="#000077"><B>Changing the Cursor to the Hourglass</B></FONT></H3><BLOCKQUOTE> <P><HR><B> </B><FONT COLOR="#000077"><B>Just a Minute:</B></FONT><B> </B>When a large amount of processing is performed, ignoring input from the user is common. It's considered good manners for a Windows program to change the cursor to an hourglass when user input won't be acknowledged. <HR></BLOCKQUOTE><P>A common place to ignore user input is during long initialization routines. It'scommon to display a user interface but disregard user input until the initializationis complete. It can take several seconds before an application is ready for input,particularly in applications that work with large amounts of data that must be initialized.In these cases, you should use the <TT>BeginWaitCursor</TT> and <TT>EndWaitCursor</TT>functions.</P><P>To demonstrate how these functions are used, add a message-handling function tothe <TT>CAboutDlg</TT> class using ClassWizard. Add a message-handling function for<TT>WM_TIMER</TT>, and accept the default function name provided by ClassWizard.Listing 14.7 contains the source code for the <TT>OnInitDialog</TT> and <TT>OnTimer</TT>functions.<H4><FONT COLOR="#000077">TYPE: Listing 14.7. Modifying OnInitDialog and OnTimerto use the hourglass cursor.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT>BOOL CAboutDlg::OnInitDialog()</TT><TT>{</TT><TT> CDialog::OnInitDialog();</TT><TT> CWinApp* pApp = AfxGetApp();</TT><TT> if( pApp != 0 )</TT><TT> {</TT><TT> m_hIconOkay = pApp->LoadIcon( IDI_GREEN );</TT><TT> m_hIconCancel = pApp->LoadIcon( IDI_RED );</TT><TT> ASSERT(m_hIconOkay);</TT><TT> ASSERT(m_hIconCancel);</TT><TT> m_btnOkay.SetIcon( m_hIconOkay );</TT><TT> m_btnCancel.SetIcon( m_hIconCancel );</TT><TT> }</TT><TT> SetCapture();</TT><TT> BeginWaitCursor();</TT><TT> SetTimer( 1, 15000, NULL );</TT><TT> return TRUE;</TT><TT>}</TT><TT>void CAboutDlg::OnTimer(UINT nIDEvent)</TT><TT>{</TT><TT> ReleaseCapture();</TT><TT> EndWaitCursor();</TT><TT> KillTimer( 1 );</TT><TT>}</TT></FONT></PRE><P>In Listing 14.7, the <TT>OnInitDialog</TT> function simulates the beginning ofa long processing period. The <TT>SetCapture</TT> and <TT>BeginWaitCursor</TT> functionsare called to change the cursor to an hourglass. While changed, the cursor cannotbe used to interact with any controls. A five-second timer is started, which callsthe <TT>OnTimer</TT> function when the timer expires. The <TT>OnTimer</TT> functionrestores the cursor and kills the timer.<BLOCKQUOTE> <P><HR><B> </B><FONT COLOR="#000077"><B>Time Saver:</B></FONT><B> </B>The order of the statements in <TT>OnInitDialog</TT> is important. Before calling <TT>BeginWaitCursor</TT>, the mouse must be captured using <TT>SetCapture</TT>; otherwise, the hourglass cursor immediately reverts to the arrow cursor. <HR></BLOCKQUOTE><H3><FONT COLOR="#000077"><B>Clipping a Cursor</B></FONT></H3><P>There are times when restricting a cursor to a single window is convenient. Thisis usually the case when you are working with error messages, or in other situationsin which you would like to force the user to make a selection. Forcing a cursor tostay with the boundaries of a single window is known as <I>clipping the cursor</I>.</P><P>As an example, force the cursor to stay over the Cursor project's About dialogbox. Using ClassWizard, add message-handling functions for <TT>WM_DESTROY</TT> and<TT>WM_MOVE</TT> to the <TT>CAboutDlg</TT> class. Add the source code in Listing14.8 to the <TT>CAbout::OnMove</TT> and <TT>CAbout::OnDestroy</TT> member functions.<H4><FONT COLOR="#000077">TYPE: Listing 14.8. Source code used to form a clippingregion for the cursor.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT>void CAboutDlg::OnMove(int x, int y)</TT><TT>{</TT><TT> CDialog::OnMove(x, y);</TT><TT> CRect rcCursor;</TT><TT> GetWindowRect( rcCursor );</TT><TT> ClipCursor( &rcCursor );</TT><TT>}</TT><TT>void CAboutDlg::OnDestroy()</TT><TT>{</TT><TT> ClipCursor( NULL );</TT><TT> CDialog::OnDestroy();</TT><TT>}</TT></FONT></PRE><P>When the MFC framework creates the About dialog box and moves it to the centerof the view window, the <TT>WM_MOVE</TT> message is sent to the <TT>CAboutDlg</TT>class. Inside the <TT>OnMove</TT> function, the dialog box's screen coordinates areused to set the clipping rectangle for the cursor. When the dialog box is destroyed,the <TT>WM_DESTROY</TT> message is handled by the <TT>CAboutDlg::OnDestroy</TT> function,and the clipping rectangle is reset.<BLOCKQUOTE> <P><HR><B> </B><FONT COLOR="#000077"><B>CAUTION:</B></FONT><B> </B>It is important to reset the cursor clipping region by calling <TT>ClipCursor(NULL)</TT> when the window is destroyed or when the clipping region is no longer needed. If this function isn't called, the cursor will be restricted to the requested rectangle even after the window has disappeared. <HR></BLOCKQUOTE><H2><FONT COLOR="#000077"><B>Summary</B></FONT></H2><P>In this hour you learned how to use icons in Windows programs. You learned howto change the main program icon, as well as child icons. You used a sample programto learn the functions used to load, draw, and destroy icon resources. You also learnedhow to use cursors to provide feedback when programming Windows applications.<H2><FONT COLOR="#000077"><B>Q&A</B></FONT></H2><DL> <DD><B>Q What are the advantages of providing an icon for a button versus using the MFC <TT>CBitmapButton</TT> class?</B><BR> <BR> <B>A</B> Assigning an icon to a button is much simpler than using the <TT>CBitmapButton</TT> class. It is also more efficient because Windows will handle drawing the image instead of the MFC class library.<BR> <BR> <B>Q The <TT>CDC::DrawIcon</TT> function will only draw an icon the size of its original image. How can I draw an icon larger than its original size?</B><BR> <BR> <B>A</B> You can use the <TT>DrawIconEx</TT> function to draw an icon to an arbitrary size. Unlike <TT>DrawIcon</TT>, the <TT>DrawIconEx</TT> function isn't a member of the <TT>CDC</TT> class. You must pass the internal handle used by the <TT>CDC</TT> object as the first parameter in the call to <TT>DrawIconEx</TT>, as shown in the <TT>OnDraw</TT> function:</DL><BLOCKQUOTE> <PRE><FONT COLOR="#0066FF"><TT>void CMyTestView::OnDraw(CDC* pDC)</TT><TT>{</TT><TT> CRect rc;</TT><TT> GetClientRect(&rc);</TT><TT> HICON hIcon = AfxGetApp()->LoadIcon(IDI_TEST);</TT><TT> DrawIconEx(pDC->m_hDC,</TT><TT> 0,</TT><TT> 0,</TT><TT> hIcon,</TT><TT> rc.Width(),</TT><TT> rc.Height(),</TT><TT> 0,</TT><TT> NULL,</TT><TT> DI_NORMAL);</TT><TT> DestroyIcon(hIcon);</TT><TT>}</TT></FONT></PRE></BLOCKQUOTE><PRE><FONT COLOR="#0066FF"><TT></TT></FONT></PRE><DL> <DD>The really interesting parameters passed to <TT>DrawIconEx</TT> are parameters five and six; these are the width and height of the final image.</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. What function is used to associate an icon with a pushbutton?<BR> <BR> 2. What is the name of the area on the cursor that is used as the current mouse location?<BR> <BR> 3. What function is used to restrict a cursor to a specific rectangle?<BR> <BR> 4. What function is used to trap all mouse messages?<BR> <BR> 5. What function is used to change the current cursor?<BR> <BR> 6. What message must be handled in order to change the current cursor?<BR> <BR> 7. What is the size of an application's small icon?<BR> <BR> 8. What function is used to change to the hourglass cursor?</DL><H3><FONT COLOR="#000077"><B>Exercise</B></FONT></H3><DL> <DD>1. Modify Listing 14.5 so that the hourglass cursor is shown unless the mouse is over the OK or Cancel button.<FONT COLOR="#000077"></FONT></DL><CENTER><P><HR><A HREF="../ch13/ch13.htm"><IMG SRC="../button/previous.gif" WIDTH="128" HEIGHT="28"ALIGN="BOTTOM" ALT="Previous chapter" BORDER="0"></A><A HREF="../ch15/ch15.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>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -