📄 chap11_1.htm
字号:
<p ALIGN="JUSTIFY"></font><font SIZE="3">为了协调各个窗口对系统调色板的使用,</font><font FACE="Times New Roman" SIZE="3">Windows</font><font SIZE="3">在必要的时侯会向顶层窗口和重叠窗口发送消息</font><font FACE="Times New Roman" SIZE="3">WM_QUERYNEWPALETTE</font><font SIZE="3">和</font><font FACE="Times New Roman" SIZE="3">WM_PALETTECHANGED</font><font SIZE="3">。</font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font><font SIZE="3">当某一顶层或重叠窗口</font><font FACE="Times New Roman" SIZE="3">(</font><font SIZE="3">如主框架窗口</font><font FACE="Times New Roman" SIZE="3">)</font><font SIZE="3">被激活时,会收到</font><font FACE="Times New Roman" SIZE="3">WM_QUERYNEWPALETTE</font><font SIZE="3">消息,在窗口创建之初也会收到该消息,该消息先于</font><font FACE="Times New Roman" SIZE="3">WM_PAINT</font><font SIZE="3">消息到达窗口。如果活动窗口要使用特殊的颜色,则在收到该消息时应该实现自己的逻辑调色板并重绘窗口。如果窗口实现了逻辑调色板,那么</font><font FACE="Times New Roman" SIZE="3">WM_QUERYNEWPALETTE</font><font SIZE="3">消息的处理函数应返回</font><font FACE="Times New Roman" SIZE="3">TRUE</font><font SIZE="3">。通常窗口在收到该消息后应该为有输入焦点的窗口</font><font FACE="Times New Roman" SIZE="3">(</font><font SIZE="3">如视图</font><font FACE="Times New Roman" SIZE="3">)</font><font SIZE="3">实现前景调色板,但如果程序觉得它显示的颜色并不重要,那么在收到该消息后可以把逻辑调色板作为背景调色板实现</font><font FACE="Times New Roman" SIZE="3">(</font><font SIZE="3">指定</font><font FACE="Times New Roman" SIZE="3">CDC::SelectPalette</font><font SIZE="3">函数的</font><font FACE="Times New Roman" SIZE="3">bForceBackground</font><font SIZE="3">参数为</font><font FACE="Times New Roman" SIZE="3">TRUE)</font><font SIZE="3">,这样程序就失去了使用系统调色板的最高优先权。</font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font><font SIZE="3">当活动窗口实现其前景调色板并改变了系统调色板时,</font><font FACE="Times New Roman" SIZE="3">Windows</font><font SIZE="3">会向包括活动窗口在内的所有的顶层窗口和重叠窗口发送</font><font FACE="Times New Roman" SIZE="3">WM_PALETTECHANGED</font><font SIZE="3">消息,在该消息的</font><font FACE="Times New Roman" SIZE="3">wParam</font><font SIZE="3">参数中包含了改变系统调色板的窗口的句柄。其它窗口如果使用了自己的逻辑调色板,那么应该重新实现其逻辑调色板,并重绘窗口。这是因为系统调色板已经被改变了,必需重新建立调色板映射表并重绘,否则可能会显示错误的颜色。当然,非活动窗口只能使用背景调色板,所以显示的颜色肯定没有在前台的时侯好。要注意只有在活动窗口实现了前景调色板且改变了系统调色板时,才会产生</font><font FACE="Times New Roman" SIZE="3">WM_PALETTECHANGED</font><font SIZE="3">消息。也就是说,如果窗口在调用</font><font FACE="Times New Roman" SIZE="3">CDC::SelectPalette</font><font SIZE="3">时指定</font><font FACE="Times New Roman" SIZE="3">bForceBackground</font><font SIZE="3">参数为</font><font FACE="Times New Roman" SIZE="3">TRUE</font><font SIZE="3">,那么是不会产生</font><font FACE="Times New Roman" SIZE="3">WM_PALETTECHANGED</font><font SIZE="3">消息。</font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font><font SIZE="3">总之,</font><font FACE="Times New Roman" SIZE="3">WM_QUERYNEWPALETTE</font><font SIZE="3">消息为活动窗口提供了实现前景调色板的机会,而</font><font FACE="Times New Roman" SIZE="3">WM_PALETTECHANGED</font><font SIZE="3">消息为窗口提供了适应系统调色板变化的机会。</font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font><font SIZE="3">需要指出的是,子窗口是收不到与调色板有关的消息的。因此,如果子窗口</font><font FACE="Times New Roman" SIZE="3">(</font><font SIZE="3">如视图</font><font FACE="Times New Roman" SIZE="3">)</font><font SIZE="3">要使用自己的逻辑调色板,那么顶层窗口或重叠窗口应该及时通知子窗口与调色板有关的消息。</font><font FACE="Times New Roman" SIZE="3"></p>
<b><p ALIGN="JUSTIFY"></b></font><font color="#3973DE" FACE="Times New Roman" SIZE="3">11.1.5
</font><font SIZE="3" color="#3973DE">具体实例</font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font><font SIZE="3">现在让我们来看一个使用调色板的演示程序。该程序名为</font><font FACE="Times New Roman" SIZE="3">TestPal</font><font SIZE="3">,如图</font><font FACE="Times New Roman" SIZE="3">11.3</font><font SIZE="3">所示,该程序显示了两组红色方块,每组方块都是</font><font FACE="Times New Roman" SIZE="3">16</font><font SIZE="3">×</font><font FACE="Times New Roman" SIZE="3">16</font><font SIZE="3">共</font><font FACE="Times New Roman" SIZE="3">256</font><font SIZE="3">个。左边的这组方块是用逻辑调色板画的,红色的强度从</font><font FACE="Times New Roman" SIZE="3">0</font><font SIZE="3">到</font><font FACE="Times New Roman" SIZE="3">255</font><font SIZE="3">递增,作为对比,在右边用</font><font FACE="Times New Roman" SIZE="3">RGB</font><font SIZE="3">引用画出了</font><font FACE="Times New Roman" SIZE="3">256</font><font SIZE="3">个递增的红色方块。读者可以对比这两组方块的颜色质量,以体会调色板索引引用和</font><font FACE="Times New Roman" SIZE="3">RGB</font><font SIZE="3">引用的区别。该程序也着重向读者演示了处理调色板消息的方法。</font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="center"></font><font SIZE="3"><img src="T11_3.gif" alt="T11_3.tif (237628 bytes)" WIDTH="466" HEIGHT="295"></font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="center"></font><font SIZE="3">图</font><font FACE="Times New Roman" SIZE="3">11.3
TestPal</font><font SIZE="3">程序</font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font><font SIZE="3">首先,请读者用</font><font FACE="Times New Roman" SIZE="3">AppWizard</font><font SIZE="3">建立一个名为</font><font FACE="Times New Roman" SIZE="3">TestPal</font><font SIZE="3">的</font><font FACE="Times New Roman" SIZE="3">MFC</font><font SIZE="3">单文挡应用程序。然后,用</font><font FACE="Times New Roman" SIZE="3">ClassWizard</font><font SIZE="3">为</font><font FACE="Times New Roman" SIZE="3">CMainFrame</font><font SIZE="3">类加入</font><font FACE="Times New Roman" SIZE="3">WM_QUERYNEWPALETTE</font><font SIZE="3">和</font><font FACE="Times New Roman" SIZE="3">WM_PALETTECHANGED</font><font SIZE="3">消息的处理函数,使用缺省的函数名。接着,在</font><font FACE="Times New Roman" SIZE="3">TestPal.h</font><font SIZE="3">文件中类</font><font FACE="Times New Roman" SIZE="3">CTestPalApp</font><font SIZE="3">的定义前加入下面一行:</font><font FACE="Times New Roman" SIZE="3"><b></p>
<p ALIGN="JUSTIFY">#define WM_DOREALIZE WM_USER+200</b></p>
<p ALIGN="JUSTIFY"></font><font SIZE="3">当收到调色板消息时,主框架窗口会发送用户定义的</font><font FACE="Times New Roman" SIZE="3">WM_DOREALIZE</font><font SIZE="3">消息通知视图。</font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font><font SIZE="3">最后,请读者按清单</font><font FACE="Times New Roman" SIZE="3">11.1</font><font SIZE="3">和</font><font FACE="Times New Roman" SIZE="3">11.2</font><font SIZE="3">修改程序。</font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font><b><font SIZE="3"> </p>
<p ALIGN="JUSTIFY">清单</font><font FACE="Times New Roman" SIZE="3">11.1 CMainFrame</font><font SIZE="3">类的部分代码</font></b><font FACE="Times New Roman" SIZE="3"></p>
<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></font><b><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY">GetActiveView()->SendMessage(WM_DOREALIZE);</p>
<p ALIGN="JUSTIFY">return TRUE; //</font><font SIZE="3">返回</font><font FACE="Times New Roman" SIZE="3">TRUE</font><font SIZE="3">表明实现了逻辑调色板</font></b><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY">}</p>
<p ALIGN="JUSTIFY"></font><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></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></font><b><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY">if(GetActiveView()!=pFocusWnd)</p>
<p ALIGN="JUSTIFY">GetActiveView()->SendMessage(WM_DOREALIZE);</b></p>
<p ALIGN="JUSTIFY">}</p>
<p ALIGN="JUSTIFY"></font><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<p></font><b><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY"></font><font SIZE="3"> </p>
<p ALIGN="JUSTIFY">清单</font><font FACE="Times New Roman" SIZE="3">11.2 CTestPalView</font><font SIZE="3">类的部分代码</font></b><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY">// TestPalView.h : interface of the CTestPalView class</p>
<p ALIGN="JUSTIFY">class CTestPalView : public CView</p>
<p ALIGN="JUSTIFY">{</p>
<p></font><b><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY">. . .</b></p>
<p ALIGN="JUSTIFY">protected:</p>
<p></font><b><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY">CPalette m_Palette;</b></p>
<p ALIGN="JUSTIFY"><b>. . .</p>
<p ALIGN="JUSTIFY">afx_msg LRESULT OnDoRealize(WPARAM wParam, LPARAM lParam); </b></p>
<p ALIGN="JUSTIFY">DECLARE_MESSAGE_MAP()</p>
<p ALIGN="JUSTIFY">};</p>
<p ALIGN="JUSTIFY"></font><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY">// TestPalView.cpp : implementation of the CTestPalView class</p>
<p ALIGN="JUSTIFY"></font><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY">BEGIN_MESSAGE_MAP(CTestPalView, CView)</p>
<p></font><b><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY">. . .</p>
<p ALIGN="JUSTIFY">ON_MESSAGE(WM_DOREALIZE, OnDoRealize)</b></p>
<p ALIGN="JUSTIFY">END_MESSAGE_MAP()</p>
<p ALIGN="JUSTIFY"></font><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<p ALIGN="JUSTIFY">CTestPalView::CTestPalView()</p>
<p ALIGN="JUSTIFY">{</p>
<p ALIGN="JUSTIFY">// TODO: add construction code here</p>
<p></font><b><font SIZE="3"> </font><font FACE="Times New Roman" SIZE="3"></p>
<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; //</font><font SIZE="3">初始化为红色</font><font FACE="Times New Roman" SIZE="3"></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!");</b></p>
<p ALIGN="JUSTIFY">}</p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -