?? ch15.htm
字號:
<TT> pPal->palNumEntries = cPaletteEntries;</TT><TT> // Roll through the color table, and add each color to</TT><TT> // the logical palette.</TT><TT> for( int ndx = 0; ndx < cPaletteEntries; ndx++ )</TT><TT> {</TT><TT> pPal->palPalEntry[ndx].peRed = pColorTab[ndx].rgbRed;</TT><TT> pPal->palPalEntry[ndx].peGreen = pColorTab[ndx].rgbGreen;</TT><TT> pPal->palPalEntry[ndx].peBlue = pColorTab[ndx].rgbBlue;</TT><TT> pPal->palPalEntry[ndx].peFlags = NULL;</TT><TT> }</TT><TT> VERIFY( CreatePalette( pPal ) );</TT><TT> delete [] (BYTE*)pPal;</TT><TT>}</TT></FONT></PRE><H3><FONT COLOR="#000077"><TT><B>CDibDoc</B></TT><B> Class Changes</B></FONT></H3><P>In the Dib example, the <TT>CDibDoc</TT> class will be responsible for the bitmapobjects and will have two new member functions:<UL> <LI><TT>GetBitmap</TT> will return a pointer to a <TT>CDIBitmap</TT> object. <LI><TT>GetPalette</TT> will return a pointer to a <TT>CBmpPalette</TT> object.</UL><P>The <TT>CDibDoc</TT> class will contain a <TT>CDIBitmap</TT> object and a pointerto a <TT>CBmpPalette</TT> object. The <TT>CDibDoc</TT> class header is shown in Listing15.6. Add the source code in Listing 15.6 to the <TT>DibDoc.h</TT> source file, justafter the <TT>//Operations</TT> comments in the <TT>CDibDoc</TT> class declaration.<H4><FONT COLOR="#000077">TYPE: Listing 15.6. Changes to CDibDoc class declaration.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT>// Operations</TT><TT>public:</TT><TT> CDIBitmap* GetBitmap();</TT><TT> CPalette* GetPalette();</TT><TT>protected:</TT><TT> CDIBitmap m_dib;</TT><TT> CBmpPalette* m_pPal;</TT></FONT></PRE><P>Add the following two <TT>#include</TT> directives just before the <TT>CDibDoc</TT>class declaration:</P><PRE><FONT COLOR="#0066FF"><TT>#include "dib256.h"</TT><TT>#include "dibpal.h"</TT></FONT></PRE><P>The <TT>CDIBitmap</TT> object will be loaded during serialization. After it hasbeen loaded, the <TT>CBmpPalette</TT> object will be created dynamically. <TT>m_pPal</TT>,the pointer to <TT>CBmpPalette</TT>, will be initialized in the constructor and deletedin the destructor. The changes for the constructor, destructor, <TT>OnNewDocument</TT>,and <TT>Serialize</TT> member functions for the <TT>CDibDoc</TT> class are shownin Listing 15.7.<H4><FONT COLOR="#000077">TYPE: Listing 15.7. Changes to CDibDoc member functions.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT>CDibDoc::CDibDoc()</TT><TT>{</TT><TT> m_pPal = 0;</TT><TT>}</TT><TT>CDibDoc::"CDibDoc()</TT><TT>{</TT><TT> delete m_pPal;</TT><TT>}</TT><TT>BOOL CDibDoc::OnNewDocument()</TT><TT>{</TT><TT> if (!CDocument::OnNewDocument())</TT><TT> return FALSE;</TT><TT> delete m_pPal;</TT><TT> m_pPal = 0;</TT><TT> return TRUE;</TT><TT>}</TT><TT>void CDibDoc::Serialize(CArchive& ar)</TT><TT>{</TT><TT> if (ar.IsStoring())</TT><TT> {</TT><TT> TRACE( TEXT("Storing a bitmap is not supported") );</TT><TT> ASSERT(FALSE);</TT><TT> }</TT><TT> else</TT><TT> {</TT><TT> CFile* pFile = ar.GetFile();</TT><TT> ASSERT( pFile );</TT><TT> ar.Flush();</TT><TT> BOOL fLoaded = m_dib.Load( pFile );</TT><TT> if( fLoaded != FALSE )</TT><TT> {</TT><TT> delete m_pPal;</TT><TT> m_pPal = new CBmpPalette( &m_dib );</TT><TT> UpdateAllViews( NULL );</TT><TT> }</TT><TT> else</TT><TT> AfxMessageBox( TEXT("Error Loading Bitmap") );</TT><TT> }</TT><TT>}</TT></FONT></PRE><P>As discussed earlier, the <TT>CDibDoc</TT> class has two new member functionsto return pointers to the bitmap and palette data members. Add the source code providedin Listing 15.8 to the <TT>dibdoc.cpp</TT> file.<H4><FONT COLOR="#000077">TYPE: Listing 15.8. New CDibDoc member functions to returnthe bitmap and palette pointers.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT>CDIBitmap* CDibDoc::GetBitmap()</TT><TT>{</TT><TT> return &m_dib;</TT><TT>}</TT><TT>CPalette* CDibDoc::GetPalette()</TT><TT>{</TT><TT> return m_pPal;</TT><TT>}</TT></FONT></PRE><H3><FONT COLOR="#000077"><B>Main Frame Class Changes</B></FONT></H3><P>When the Dib application receives a palette message, Windows sends the messageto the application, where it will be routed to the <TT>CMainFrame</TT> class. Becausethe <TT>CMainFrame</TT> class has no knowledge about how the bitmap or palette isorganized, it must determine the active view and send it the message.</P><P>Using ClassWizard, add message-handling functions for <TT>WM_PALETTECHANGED</TT>and <TT>WM_QUERYNEWPALETTE</TT>. Edit the functions using the source code providedin Listing 15.9.<H4><FONT COLOR="#000077">TYPE: Listing 15.9. The new CMainFrame message-handlingfunctions.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT>void CMainFrame::OnPaletteChanged(CWnd* pFocusWnd)</TT><TT>{</TT><TT> CView* pView = GetActiveView();</TT><TT> if( pView )</TT><TT> {</TT><TT> HWND hWndFocus = pView->GetSafeHwnd();</TT><TT> pView->SendMessage( WM_PALETTECHANGED,</TT><TT> (WPARAM)hWndFocus,</TT><TT> (LPARAM)0 );</TT><TT> }</TT><TT>}</TT><TT>BOOL CMainFrame::OnQueryNewPalette()</TT><TT>{</TT><TT> CView* pView = GetActiveView();</TT><TT> if( pView )</TT><TT> {</TT><TT> HWND hWndFocus = pView->GetSafeHwnd();</TT><TT> pView->SendMessage( WM_QUERYNEWPALETTE,</TT><TT> (WPARAM)hWndFocus,</TT><TT> (LPARAM)0 );</TT><TT> }</TT><TT> return TRUE;</TT><TT>}</TT></FONT></PRE><H3><FONT COLOR="#000077"><TT><B>CDibView</B></TT><B> Class Changes</B></FONT></H3><P>The <TT>CDibView</TT> class has two main functions: drawing the 256-color bitmapand responding to palette messages. The <TT>CDibView::OnDraw</TT> function must bemodified to draw the bitmap, as shown in Listing 15.10.<H4><FONT COLOR="#000077">TYPE: Listing 15.10. A new version of CDibView::OnDraw.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT>void CDibView::OnDraw(CDC* pDC)</TT><TT>{</TT><TT> CDibDoc* pDoc = GetDocument();</TT><TT> ASSERT_VALID(pDoc);</TT><TT> CPalette* pPal = pDoc->GetPalette();</TT><TT> CPalette* pOldPal = pDC->SelectPalette( pPal, FALSE );</TT><TT> pDC->RealizePalette();</TT><TT> CDIBitmap* pBmp = pDoc->GetBitmap();</TT><TT> pBmp->DrawDIB( pDC, 0, 0 );</TT><TT> pDC->SelectPalette( pOldPal, FALSE );</TT><TT>}</TT></FONT></PRE><P><TT>OnDraw</TT> fetches pointers to the bitmap and palette from <TT>CDibDoc</TT>,using the new member functions added to the document class earlier. The palette isselected and realized, and then the bitmap is drawn. After drawing the bitmap, theprevious palette is selected back into the DC.</P><P>The <TT>CMainFrame</TT> class forwards <TT>WM_PALETTECHANGED</TT> and <TT>WM_QUERYNEWPALETTE</TT>messages to the view class. However, there is one small problem: ClassWizard doesn'toffer direct support for palette messages sent to child window classes such as <TT>CDibView</TT>.Therefore, some trickery is required. To add the palette-handling functions, followthese steps:<DL> <DD>1. Open ClassWizard.<BR> <BR> 2. Select the <TT>CDibView</TT> class.<BR> <BR> 3. Select the Class Info tab.<BR> <BR> 4. In the Advanced Options group, click the Message Filter combo box, and select Topmost Frame instead of Child Window.<BR> <BR> 5. Select the Message Maps tab and add the message-handling functions for <TT>WM_PALETTECHANGED</TT> and add <TT>WM_QUERYNEWPALETTE</TT> to the <TT>CDibView</TT> class.<BR> <BR> 6. Select the Class Info tab.<BR> <BR> 7. In the Advanced Options group, click the Message Filter combo box and select Child Window instead of Topmost Frame.<BR> <BR> 8. Close ClassWizard.</DL><P>The source code for the palette message-handling function is provided in Listing15.11.<H4><FONT COLOR="#000077">TYPE: Listing 15.11. New functions added to the CDibViewclass.</FONT></H4><PRE><FONT COLOR="#0066FF"><TT>// OnPaletteChanged - Handles WM_PALETTECHANGED, which is a</TT><TT>// notification that a window has changed the current palette. If</TT><TT>// this view did not change the palette, forward this message to</TT><TT>// OnQueryNewPalette so the palette can be updated, and redrawn</TT><TT>// if possible.</TT><TT>void CDibView::OnPaletteChanged(CWnd* pFocusWnd)</TT><TT>{</TT><TT> if( pFocusWnd != this )</TT><TT> OnQueryNewPalette();</TT><TT>}</TT><TT>// Notification that the view is about to become active,</TT><TT>// and the view should realize its palette.</TT><TT>BOOL CDibView::OnQueryNewPalette()</TT><TT>{</TT><TT> CDibDoc* pDoc = GetDocument();</TT><TT> ASSERT_VALID(pDoc);</TT><TT> CBmpPalette* pPal = (CBmpPalette*)pDoc->GetPalette();</TT><TT> if( pPal )</TT><TT> {</TT><TT> CDC* pDC = GetDC();</TT><TT> CPalette* pOldPal = pDC->SelectPalette( pPal, FALSE );</TT><TT> UINT uChanges = pDC->RealizePalette();</TT><TT> pDC->SelectPalette( pOldPal, FALSE );</TT><TT> ReleaseDC( pDC );</TT><TT> if( uChanges != 0 )</TT><TT> InvalidateRect( NULL );</TT><TT> }</TT><TT> return TRUE;</TT><TT>}</TT></FONT></PRE><P>In most cases, <TT>OnPaletteChanged</TT> calls the <TT>OnQueryNewPalette</TT>function directly. The only exception is when the <TT>WM_PALETTECHANGED</TT> messagewas sent because this view had updated the system palette. If this view is the foregroundwindow, the Windows NT Palette Manager gives you first crack at setting the system'spalette. If you are in the background, you have access to the unused entries only.If there's no more room in the palette, your palette is mapped to the closest possiblematch.</P><P>Remember to include the declarations for the <TT>CDIBitmap</TT> class at the topof the <TT>DibView.cpp</TT> source file, after the existing <TT>#include</TT> directives:</P><PRE><FONT COLOR="#0066FF"><TT>#include "dib256.h"</TT></FONT></PRE><P>Compile and run the Dib example. If you have a 256-color display, load a 256-colorbitmap and notice that you receive all the colors. If you run several instances ofthe program using different 256-color bitmaps, you might notice the palette changeif you switch between windows. Figure 15.7 shows the Dib example displaying the 256-colorWindows NT logo.</P><P><A NAME="07"></A><A HREF="07.htm"><B>Figure 15.7.</B></A> <BR><I>The Dib sample program displaying a 256-color bitmap.</I><H2><FONT COLOR="#000077"><B>Summary</B></FONT></H2><P>In this chapter you learned about bitmaps, a method used to display images ina Windows program. You learned the structures used by Windows bitmaps, how to simplifybitmap handling, and how to use color palettes.<H2><FONT COLOR="#000077"><B>Q&A</B></FONT></H2><DL> <DD><B>Q Must I manage the palette when displaying 256-color bitmaps if my display uses more than 256 colors?</B><BR> <BR> <B>A</B> No, your display will properly manage the colors used by the bitmap. However, if your application is used on a system with a 256-color display, the application will not display the bitmap properly.<BR> <BR> <B>Q Can my application use more than one color palette?</B><BR> <BR> <B>A</B> Yes, if you were to build an MDI version of the Dib sample program, each view would need to manage its own color palette.</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 MFC class is used to manage bitmaps stored in your resource file?<BR> <BR> 2. What MFC base class is used to manage color palettes?<BR> <BR> 3. What type of device context is used to draw into a bitmap off-screen?<BR> <BR> 4. What function is used to transfer bitmaps to an output device?<BR> <BR> 5. How many colors are kept by Windows in the system color palette?<BR> <BR> 6. How many entries in the system color palette are reserved by Windows?<BR> <BR> 7. What two messages must be handled in order to manage the color palette?<BR> <BR> 8. What are the differences between the two palette messages?</DL><H3><FONT COLOR="#000077"><B>Exercises</B></FONT></H3><DL> <DD>1. Modify the Bitmap project so that the bitmap image is displayed three times in a row across the view instead of once.<BR> <BR> 2. Modify the <TT>CBmpPalette</TT> class used in the Dib example so that it is monochromatic, with only various shades of one color selected for the palette instead of colors from the bitmap.</DL><CENTER><P><HR><A HREF="../ch14/ch14.htm"><IMG SRC="../button/previous.gif" WIDTH="128" HEIGHT="28"ALIGN="BOTTOM" ALT="Previous chapter" BORDER="0"></A><A HREF="../ch16/ch16.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 + -