📄 book_text7.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0062)http://www1.ustc.edu.cn/personal/csli/insidec++/book_text7.htm -->
<HTML><HEAD><TITLE>Visual C++</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META content="MSHTML 6.00.2900.2995" name=GENERATOR>
<META content=FrontPage.Editor.Document name=ProgId><LINK
href="book_text7.files/style.css" type=text/css rel=stylesheet></HEAD>
<BODY bgColor=#f7fbff leftMargin=0 topMargin=0>
<TABLE height="100%" cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD width="3%" background=book_text7.files/page_side.gif
height="100%"> </TD>
<TD vAlign=top align=middle width="97%">
<P
style="mso-line-height-alt: 1.3pt; tab-stops: right dotted 402.1pt"><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt"></O:P></SPAN></P>
<TABLE height=23 width="99%" border=0>
<TBODY>
<TR>
<TD width="2%" height=29></TD>
<TD width="95%" height=29><PRE><A name=_Toc419881628><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: MS Sans Serif; mso-bookmark: _Toc419740446"><B>三 深入<SPAN lang=EN-US>MFC类库</SPAN></B></SPAN></A></PRE></TD>
<TD width="3%" height=29></TD></TR>
<TR>
<TD width="2%" height=15></TD>
<TD width="95%" height=15>
<H2 style="mso-line-height-alt: 1.3pt"><A name=_Toc419881632><SPAN
lang=EN-US
style="FONT-SIZE: 18pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: MS Sans Serif; mso-bookmark: _Toc419740450">2
有关屏幕输出</SPAN></A><SPAN lang=EN-US
style="FONT-SIZE: 18pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: Arial"><O:P>
</O:P></SPAN></H2>
<H3 style="mso-line-height-alt: 1.3pt"><A name=_Toc419881633><SPAN
lang=EN-US
style="FONT-FAMILY: 宋体; mso-hansi-font-family: MS Sans Serif; mso-bookmark: _Toc419740451">2.1
设备上下文工作原理</SPAN></A></H3>
<P class=MsoNormal
style="WORD-BREAK: break-all; TEXT-INDENT: 1cm; mso-line-height-alt: 1.3pt; mso-layout-grid-align: none; punctuation-wrap: simple"><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">在绝大多数的</SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt">WINDOWS</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">应用都需要在屏幕上显示自己的数据。由于</SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt">WINDOWS</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">是一个设备无关的操作系统,所以任何向屏幕上进行输出的功能都要间接地通一个叫做设备上下文</SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt">(device
context)</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">的对象来完成。我们向设备上下文提出屏幕输出的要求,然后由</SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt">WINDOWS</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">自己来调用具体的输出设备的驱动程序来完成实际的输出工作。围绕设备上下文,</SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt">MFC</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">提供了一系列与其配合使用的绘图对象,这其中包括画笔对象、刷子对象以及字体对象等等。它们的工作模型是这样的:首先对设备上下文对象</SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'MS Sans Serif'; mso-bidi-font-size: 10.0pt; mso-ascii-font-family: 宋体">——</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">我们简称为</SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt">DC</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">对象</SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 'MS Sans Serif'; mso-bidi-font-size: 10.0pt; mso-ascii-font-family: 宋体">——</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">进行设置,然后选择进行屏幕输出所需要的工具,最后用</SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt">DC</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">对象的输出函数绘制图形。屏幕输出的目标一般都是窗口的客户区,它是一个万能的输出区域,可以接受无论是文本、位图、还是其他类型的数据(比方说</SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt">OLE</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">对象)。</SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt"><O:P>
</O:P></SPAN></P>
<H3 style="mso-line-height-alt: 1.3pt"><A name=_Toc419881634><SPAN
lang=EN-US
style="FONT-FAMILY: 宋体; mso-hansi-font-family: MS Sans Serif; mso-bookmark: _Toc419740452">2.2
实例绘图原理剖析</SPAN></A></H3>
<P class=MsoNormal
style="WORD-BREAK: break-all; TEXT-INDENT: 20pt; mso-line-height-alt: 1.3pt; mso-layout-grid-align: none; punctuation-wrap: simple"><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">在有关用户输入部分的内容当中,我们曾经介绍过一个实例,</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">它访问一个保存歌曲曲目的数据库,用户可以通过对话框让用户定义一个曲目表,并选定一张背景图,然后在一个没有系统菜单的窗口客户区上滚动显示曲目的名字。我们已经介绍了通过对话框介绍用户输入的方法,接下来就着重介绍如何把用户输入的信息在屏幕上显示出来。</SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt"><O:P>
</O:P></SPAN></P>
<P class=MsoNormal
style="WORD-BREAK: break-all; TEXT-INDENT: 20pt; mso-line-height-alt: 1.3pt; mso-layout-grid-align: none; punctuation-wrap: simple"><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">我们将用户选定的字符串在一张背景图上面滚动输出。前面已经介绍了使用设备上下文进行工作的基本模型。即:首先选择绘图的工具,然后调用</SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt">DC</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">的绘图函数来进行绘制。在</SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt">WINDOWS</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">当中,每次窗口的外观发生改变的时候都会发出一个</SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt">WM_PAINT</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">消息,窗口的重绘工作都是在响应这个消息的处理函数当中进行的。可以使用</SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt">CLASSWIZARD</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">来添加这个消息响应函数。之后,就可以在这个函数当中进行屏幕输出了。还有什么时候会触发重绘事件呢</SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt">?</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">在程序中调</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">用</SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt">CWND</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">的</SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt">UpdateWindow
</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">和</SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt">RedrawWindow</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">数的时候都会触发重绘事件。我们还可以直接使用<SPAN
lang=EN-US>SendMessage函数向一个指定的窗口送出重绘消息。另外调用</SPAN></SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt">CWND</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">的<SPAN
lang=EN-US>Invalidate函数可以指示重绘的时候是否需要擦去背景,如果使用InvalidateRect函数还可以设置客户区的无效区域,系统重绘的时候将只把该区域的内容重新绘制,我们首先在窗口的客户区上帖一张位图,然后滚动输出文本。如何实现滚动输出呢我们的方法是在程序中设置一个定时器,在定时器计时已满事件</SPAN></SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt">WM_TIMER</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">触发的时候来,调用<SPAN
lang=EN-US>REDRAWWINDOW函数,触发重绘事件,我们只要在它的消息响应函数</SPAN></SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt">ONPAINT</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">当中</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">重新绘制背景,擦去原来的文本,然后不断的改变文本输出的位置就可以达到目的了。您可能会重绘整个背景的做法会很耗费了过多的系统时间并且可能产背景的闪烁。这种担心是必要的。在</SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt">WINDOWS95</SPAN><SPAN
style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-bidi-font-size: 10.0pt; mso-hansi-font-family: 'MS Sans Serif'">当中,系统对重绘的机制进行了优化,在我们没有指定无效区域的情况之下,系统自己会选择一个最小的无效区域,只对这一区域进行重绘。</SPAN><SPAN
lang=EN-US
style="FONT-SIZE: 10.5pt; mso-bidi-font-size: 10.0pt"><O:P>
</O:P></SPAN></P>
<H3 style="mso-line-height-alt: 1.3pt"><A name=_Toc419881635><SPAN
lang=EN-US
style="FONT-FAMILY: 宋体; mso-hansi-font-family: MS Sans Serif; mso-bookmark: _Toc419740453">2.3
绘图操作实现</SPAN></A></H3>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -