📄 chap11_1.htm
字号:
<p align="JUSTIFY">};</p>
<p align="JUSTIFY"> </p>
<p align="JUSTIFY">// TestPalView.cpp : implementation of the CTestPalView
class</p>
<p align="JUSTIFY"> </p>
<p align="JUSTIFY">BEGIN_MESSAGE_MAP(CTestPalView, CView)</p>
<p><b> </b></p>
<b>
<p align="JUSTIFY">. . .</p>
<p align="JUSTIFY">ON_MESSAGE(WM_DOREALIZE, OnDoRealize)</p>
</b>
<p align="JUSTIFY">END_MESSAGE_MAP()</p>
<p align="JUSTIFY"> </p>
<p align="JUSTIFY">CTestPalView::CTestPalView()</p>
<p align="JUSTIFY">{</p>
<p align="JUSTIFY">// TODO: add construction code here</p>
<p><b> </b></p>
<b>
<p align="JUSTIFY">LPLOGPALETTE pLogPal;</p>
<p align="JUSTIFY">pLogPal=(LPLOGPALETTE)malloc(sizeof(LOGPALETTE)+</p>
<p align="JUSTIFY">sizeof(PALETTEENTRY)*256);</p>
<p align="JUSTIFY">pLogPal->palVersion=0x300;</p>
<p align="JUSTIFY">pLogPal->palNumEntries=256;</p>
<p align="JUSTIFY">for(int i=0;i<256;i++)</p>
<p align="JUSTIFY">{</p>
<p align="JUSTIFY">pLogPal->palPalEntry[i].peRed=i; //初始化为红色</p>
<p align="JUSTIFY">pLogPal->palPalEntry[i].peGreen=0;</p>
<p align="JUSTIFY">pLogPal->palPalEntry[i].peBlue=0;</p>
<p align="JUSTIFY">pLogPal->palPalEntry[i].peFlags=0;</p>
<p align="JUSTIFY">}</p>
<p align="JUSTIFY">if(!m_Palette.CreatePalette(pLogPal))</p>
<p align="JUSTIFY">AfxMessageBox("Can't create palette!");</p>
</b>
<p align="JUSTIFY">}</p>
<p align="JUSTIFY"> </p>
<p align="JUSTIFY">void CTestPalView::OnDraw(CDC* pDC)</p>
<p align="JUSTIFY">{</p>
<p align="JUSTIFY">CTestPalDoc* pDoc = GetDocument();</p>
<p align="JUSTIFY">ASSERT_VALID(pDoc);</p>
<p align="JUSTIFY"> </p>
<p align="JUSTIFY">// TODO: add draw code for native data here</p>
<p><b> </b></p>
<b>
<p align="JUSTIFY">CBrush brush,*pOldBrush;</p>
<p align="JUSTIFY">int x,y,i;</p>
<p align="JUSTIFY"> </p>
<p align="JUSTIFY">pDC->SelectPalette(&m_Palette,FALSE);</p>
<p align="JUSTIFY">pDC->RealizePalette();</p>
<p align="JUSTIFY">pDC->SelectStockObject(BLACK_PEN);</p>
<p align="JUSTIFY">for(i=0;i<256;i++)</p>
<p align="JUSTIFY">{</p>
<p align="JUSTIFY">x=(i%16)*16;</p>
<p align="JUSTIFY">y=(i/16)*16;</p>
<p align="JUSTIFY">brush.CreateSolidBrush(PALETTEINDEX(i)); //调色板索引引用</p>
<p align="JUSTIFY">pOldBrush=pDC->SelectObject(&brush);</p>
<p align="JUSTIFY">pDC->Rectangle(x,y,x+16,y+16);</p>
<p align="JUSTIFY">pDC->SelectObject(pOldBrush);</p>
<p align="JUSTIFY">brush.DeleteObject();</p>
<p align="JUSTIFY">}</p>
<p align="JUSTIFY">for(i=0;i<256;i++)</p>
<p align="JUSTIFY">{</p>
<p align="JUSTIFY">x=(i%16)*16+300;</p>
<p align="JUSTIFY">y=(i/16)*16;</p>
<p align="JUSTIFY">brush.CreateSolidBrush(RGB(i,0,0)); //RGB引用</p>
<p align="JUSTIFY">pOldBrush=pDC->SelectObject(&brush);</p>
<p align="JUSTIFY">pDC->Rectangle(x,y,x+16,y+16);</p>
<p align="JUSTIFY">pDC->SelectObject(pOldBrush);</p>
<p align="JUSTIFY">brush.DeleteObject();</p>
<p align="JUSTIFY">}</p>
</b>
<p align="JUSTIFY">}</p>
<p><b> </b></p>
<b>
<p align="JUSTIFY"> </p>
<p align="JUSTIFY">LRESULT CTestPalView::OnDoRealize(WPARAM wParam,
LPARAM)</p>
<p align="JUSTIFY">{</p>
<p align="JUSTIFY">CClientDC dc(this);</p>
<p align="JUSTIFY">dc.SelectPalette(&m_Palette,FALSE);</p>
<p align="JUSTIFY">if(dc.RealizePalette()) //若调色板映射被改变则刷新视图</p>
<p align="JUSTIFY">GetDocument()->UpdateAllViews(NULL);</p>
<p align="JUSTIFY">return 0L;</p>
<p align="JUSTIFY">}</p>
</b>
<p align="JUSTIFY"><b></b> 在CTestPalView的构造函数中创建了一个含有256个递增红色的逻辑调色板。</p>
<p align="JUSTIFY"> 当变为活动窗口以及窗口创建时,TestPal程序的主框架窗口都会收到WM_QUERYNEWPALETTE消息,该消息的处理函数OnQueryNewPalette负责发送WM_DOREALIZE消息通知视图,
并返回TRUE以表明活动窗口实现了逻辑调色板。WM_DOREALIZE消息的处理函数CTestPalView::OnDoRealize为视图实现一个前景调色板,该函数中有一个判断语句可提高程序运行的效率:如果CDC::RealizePalette返回值大于零,则说明调色板映射表发生了变化,此时必须刷新视图,否则制图中的颜色将失真。如果RealizePalette返回零则说明调色板映射没有变化,这时就没有必要刷新视图。</p>
<p align="JUSTIFY"> 无论是TestPal还是别的应用程序在实现前景调色板并改变了系统调色板时,TestPal程序的主框架窗口都会收到WM_PALETTECHANGED消息。请注意该消息的处理函数CMainFrame::OnPaletteChanged有一个pFocusWnd参数,该参数表明是哪一个窗口改变了系统调色板。函数用pFocusWnd来判断,如果是别的应用程序实现了前景调色板,则通知视图调用OnDoRealize实现其逻辑调色板,注意虽然CDC::SelectPalette的bForceBackground参数是FALSE,但这时视图的逻辑调色板是作为背景调色板实现的。如果是TestPal自己的视图实现了前景调色板,则没有必要调用OnDoRealize。</p>
<p align="JUSTIFY"> 请读者将Windows当前的显示模式设置为256色,然后编译并运行TestPal,对比一下RGB引用与调色板索引引用的效果,读者不难发现左边用调色板索引引用输出的颜色比右边好的多。通过该程序我们可以看出,即使在系统调色板中已实现了丰富的红色的情况下,RGB引用得到的红色仍然是20种保留颜色的抖动色。</p>
<p align="JUSTIFY"> 读者可以打开Windows的画笔程序,并在该程序中打开一幅256色的位图(如Windows目录下的Forest.bmp)。在画笔和TestPal程序之间来回切换,读者可以看到,由于两个应用程序都正确的处理了调色板消息,在前台的应用程序总是具有最好的颜色显示,而后台程序的颜色虽然有些失真,但还比较令人满意。</p>
<p align="JUSTIFY"> 需要指出的是,TestPal程序只使用了一个逻辑调色板,所以它处理调色板消息的方法比较简单。如果程序要用到多个逻辑调色板,那么就需要采取一些新措施来保证只有一个逻辑调色板作为前景调色板使用。在11.4节读者可以看到使用多个逻辑调色板时的处理方法。</p>
<div align="center">
<center>
<table border="0" cellpadding="0" cellspacing="0" width="615">
<tr>
<td><a href="chap11.htm">上一页</a></td>
<td>
<p align="right"><a href="chap11_2.htm">下一页</a>
</td>
</tr>
</table>
<p><a href="http://www.cpcw.com">电脑报首页</a> <a href="../../index.htm">网络学院首页</a></p>
</center>
</div>
<font size="5">
<hr noshade color="#3973DE" size="1">
</font>
<p align="center"><font size="5"></font><font size="2" color="#000000">本教程由<a href="http://vcdynasty.yeah.net">Visual
C++王朝(Where programmers come together)</a>协助制作<br>
未经许可,请勿以任何形式复制</font>
</td>
</tr>
</table>
</center>
</div>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -