📄 chap11_1.htm
字号:
</td>
<td width="84%">
<p align="JUSTIFY">指定RGB引用。此时三个低位字节含有红、绿、蓝色的强度,Windows将抖动20种保留的颜色来匹配指定的颜色,而不管程序是否实现了自己的调色板。
</td>
</tr>
<tr>
<td width="16%">
<p align="JUSTIFY">0x01
</td>
<td width="84%">
<p align="JUSTIFY">指定调色板索引引用。此时最低位字节含有逻辑调色板的索引,Windows根据该索引在逻辑调色板中找到所需的颜色。
</td>
</tr>
<tr>
<td width="16%">
<p align="JUSTIFY">0x02
</td>
<td width="84%">
<p align="JUSTIFY">指定调色板RGB引用。此时三个低位字节含有红、绿、蓝色的强度,Windows会在逻辑调色板中找到最匹配的颜色。
</td>
</tr>
</table>
<p align="JUSTIFY">为了方便用户的使用,Windows提供了三个宏来构建三种不同的COLORREF数据,它们是:</p>
<blockquote>
<blockquote>
<p align="JUSTIFY">COLORREF RGB(BYTE bRed,BYTE bGreen,BYTE bBlue);
//RGB引用</p>
<p align="JUSTIFY">COLORREF PALETTEINDEX(WORD wPaletteIndex); //调色板索引引用</p>
<p align="JUSTIFY">COLORREF PALETTERGB(BYTE bRed,BYTE bGreen, //调色板RGB引用<br>
BYTE bBlue); </p>
</blockquote>
</blockquote>
<p align="JUSTIFY">例如,我们可以用上述三种方法来指定刷子的颜色。下面的代码用系统调色板中的红色建立一个刷子:</p>
<blockquote>
<p align="JUSTIFY">CBrush brush;</p>
<p align="JUSTIFY">brush.CreateSolidBrush(RGB(255,0,0));</p>
<p align="JUSTIFY">pDC->SelectObject(&brush);</p>
</blockquote>
<p align="JUSTIFY">下面的代码用逻辑调色板的索引2中的颜色来创建一个刷子:</p>
<blockquote>
<p align="JUSTIFY">pDC->SelectPalette(&m_Palette,FALSE);</p>
<p align="JUSTIFY">pDC->RealizePalette( );</p>
<p align="JUSTIFY">CBrush brush;</p>
<p align="JUSTIFY">brush.CreateSolidBrush(PALETTEINDEX(2));</p>
<p align="JUSTIFY">pDC->SelectObject(&brush);</p>
</blockquote>
<p align="JUSTIFY">下面的代码用逻辑调色板中最匹配的深灰色来创建一个刷子:</p>
<blockquote>
<p align="JUSTIFY">pDC->SelectPalette(&m_Palette,FALSE);</p>
<p align="JUSTIFY">pDC->RealizePalette( );</p>
<p align="JUSTIFY">CBrush brush;</p>
<p align="JUSTIFY">brush.CreateSolidBrush(PALETTERGB(20,20,20));</p>
<p align="JUSTIFY">pDC->SelectObject(&brush);</p>
</blockquote>
<p align="JUSTIFY"><b></b><font color="#3973DE" face="Times New Roman" size="3">11.1.4
</font><font size="3" color="#3973DE">与系统调色板有关的消息</font></p>
<p align="JUSTIFY"> 为了协调各个窗口对系统调色板的使用,Windows在必要的时侯会向顶层窗口和重叠窗口发送消息WM_QUERYNEWPALETTE和WM_PALETTECHANGED。</p>
<p align="JUSTIFY"> 当某一顶层或重叠窗口(如主框架窗口)被激活时,会收到WM_QUERYNEWPALETTE消息,在窗口创建之初也会收到该消息,该消息先于WM_PAINT消息到达窗口。如果活动窗口要使用特殊的颜色,则在收到该消息时应该实现自己的逻辑调色板并重绘窗口。如果窗口实现了逻辑调色板,那么WM_QUERYNEWPALETTE消息的处理函数应返回TRUE。通常窗口在收到该消息后应该为有输入焦点的窗口(如视图)实现前景调色板,但如果程序觉得它显示的颜色并不重要,那么在收到该消息后可以把逻辑调色板作为背景调色板实现(指定CDC::SelectPalette函数的bForceBackground参数为TRUE),这样程序就失去了使用系统调色板的最高优先权。</p>
<p align="JUSTIFY"> 当活动窗口实现其前景调色板并改变了系统调色板时,Windows会向包括活动窗口在内的所有的顶层窗口和重叠窗口发送WM_PALETTECHANGED消息,在该消息的wParam参数中包含了改变系统调色板的窗口的句柄。其它窗口如果使用了自己的逻辑调色板,那么应该重新实现其逻辑调色板,并重绘窗口。这是因为系统调色板已经被改变了,必需重新建立调色板映射表并重绘,否则可能会显示错误的颜色。当然,非活动窗口只能使用背景调色板,所以显示的颜色肯定没有在前台的时侯好。要注意只有在活动窗口实现了前景调色板且改变了系统调色板时,才会产生WM_PALETTECHANGED消息。也就是说,如果窗口在调用CDC::SelectPalette时指定bForceBackground参数为TRUE,那么是不会产生WM_PALETTECHANGED消息。</p>
<p align="JUSTIFY"> 总之,WM_QUERYNEWPALETTE消息为活动窗口提供了实现前景调色板的机会,而WM_PALETTECHANGED消息为窗口提供了适应系统调色板变化的机会。</p>
<p align="JUSTIFY"> 需要指出的是,子窗口是收不到与调色板有关的消息的。因此,如果子窗口(如视图)要使用自己的逻辑调色板,那么顶层窗口或重叠窗口应该及时通知子窗口与调色板有关的消息。</p>
<p align="JUSTIFY"><b></b><font color="#3973DE" face="Times New Roman" size="3">11.1.5
</font><font size="3" color="#3973DE">具体实例</font></p>
<p align="JUSTIFY"> 现在让我们来看一个使用调色板的演示程序。该程序名为TestPal,如图11.3所示,该程序显示了两组红色方块,每组方块都是16×16共256个。左边的这组方块是用逻辑调色板画的,红色的强度从0到255递增,作为对比,在右边用RGB引用画出了256个递增的红色方块。读者可以对比这两组方块的颜色质量,以体会调色板索引引用和RGB引用的区别。该程序也着重向读者演示了处理调色板消息的方法。</p>
<p align="center"><img src="T11_3.gif" alt="T11_3.tif (237628 bytes)" width="466" height="295"></p>
<p align="center">图11.3 TestPal程序</p>
<p align="JUSTIFY"> </p>
<p align="JUSTIFY"> 首先,请读者用AppWizard建立一个名为TestPal的MFC单文挡应用程序。然后,用ClassWizard为CMainFrame类加入WM_QUERYNEWPALETTE和WM_PALETTECHANGED消息的处理函数,使用缺省的函数名。接着,在TestPal.h文件中类CTestPalApp的定义前加入下面一行:</p>
<b>
<p align="JUSTIFY">#define WM_DOREALIZE WM_USER+200</p>
</b>
<p align="JUSTIFY">当收到调色板消息时,主框架窗口会发送用户定义的WM_DOREALIZE消息通知视图。</p>
<p align="JUSTIFY">最后,请读者按清单11.1和11.2修改程序。</p>
<p align="JUSTIFY"><b> </b></p>
<b>
<p align="JUSTIFY">清单11.1 CMainFrame类的部分代码</p>
</b>
<p align="JUSTIFY">BOOL CMainFrame::OnQueryNewPalette() </p>
<p align="JUSTIFY">{</p>
<p align="JUSTIFY">// TODO: Add your message handler code here and/or
call default</p>
<p><b> </b></p>
<b>
<p align="JUSTIFY">GetActiveView()->SendMessage(WM_DOREALIZE);</p>
<p align="JUSTIFY">return TRUE; //返回TRUE表明实现了逻辑调色板</p>
</b>
<p align="JUSTIFY">}</p>
<p align="JUSTIFY"> </p>
<p align="JUSTIFY">void CMainFrame::OnPaletteChanged(CWnd* pFocusWnd)
</p>
<p align="JUSTIFY">{</p>
<p align="JUSTIFY">CFrameWnd::OnPaletteChanged(pFocusWnd);</p>
<p align="JUSTIFY">// TODO: Add your message handler code here</p>
<p><b> </b></p>
<b>
<p align="JUSTIFY">if(GetActiveView()!=pFocusWnd)</p>
<p align="JUSTIFY">GetActiveView()->SendMessage(WM_DOREALIZE);</p>
</b>
<p align="JUSTIFY">}</p>
<p align="JUSTIFY"> </p>
<b>
<p align="JUSTIFY">清单11.2 CTestPalView类的部分代码</p>
</b>
<p align="JUSTIFY">// TestPalView.h : interface of the CTestPalView
class</p>
<p align="JUSTIFY">class CTestPalView : public CView</p>
<p align="JUSTIFY">{</p>
<p>. . .</p>
<b></b>
<p align="JUSTIFY">protected:</p>
<p><b> </b></p>
<b>
<p align="JUSTIFY">CPalette m_Palette;</p>
</b>
<p align="JUSTIFY"><b>. . .</b></p>
<b>
<p align="JUSTIFY">afx_msg LRESULT OnDoRealize(WPARAM wParam, LPARAM
lParam); </p>
</b>
<p align="JUSTIFY">DECLARE_MESSAGE_MAP()</p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -