100165570.htm
来自「C#高级编程(第三版),顶死你们。。 。up」· HTM 代码 · 共 162 行 · 第 1/3 页
HTM
162 行
<p style="FTEL: 8.15pt" align="center"><span style="COLOR: black; FONT-FAMILY: 宋体">图</span><span lang="EN-US" style="COLOR: black"> 20-11</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">为了使该图更清晰,我们向下向右扩展了该文档,超出了屏幕的边界,但这不会改变我们的推论,我们还假定其上还有一个水平滚动条和一个垂直滚动条。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">在该图中,细矩形标记了屏幕区域的边框和整个文档的边框。粗线条标记试图要绘制的矩形和椭圆。</span><span lang="EN-US">P</span><span style="FONT-FAMILY: 宋体">标记要绘制的某个随意点,这个点在后面会作为一个示例。在调用绘图方法时,提供</span><span lang="EN-US">graphics</span><span style="FONT-FAMILY: 宋体">实例和从</span><span lang="EN-US">B</span><span style="FONT-FAMILY: 宋体">点到</span><span lang="EN-US">P</span><span style="FONT-FAMILY: 宋体">点的矢量,这个矢量表示为一个</span><span lang="EN-US">Ponit</span><span style="FONT-FAMILY: 宋体">实例。我们实际上需要给出从点</span><span lang="EN-US">A</span><span style="FONT-FAMILY: 宋体">到点</span><span lang="EN-US">B</span><span style="FONT-FAMILY: 宋体">的矢量。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">问题是,我们不知道从</span><span lang="EN-US">A</span><span style="FONT-FAMILY: 宋体">点到</span><span lang="EN-US">P</span><span style="FONT-FAMILY: 宋体">点的矢量。而知道从</span><span lang="EN-US">B</span><span style="FONT-FAMILY: 宋体">点到</span><span lang="EN-US">P</span><span style="FONT-FAMILY: 宋体">点的矢量,这是</span><span lang="EN-US">P</span><span style="FONT-FAMILY: 宋体">相对于文档左上角的坐标<span style="LETTER-SPACING: -1pt">——</span></span><span style="LETTER-SPACING: -1pt"> </span><span style="FONT-FAMILY: 宋体">我们要在文档的</span><span lang="EN-US">P</span><span style="FONT-FAMILY: 宋体">点绘图。还知道从</span><span lang="EN-US">B</span><span style="FONT-FAMILY: 宋体">点到</span><span lang="EN-US">A</span><span style="FONT-FAMILY: 宋体">点的矢量,这是滚动的距离,它存储在</span><span lang="EN-US">Form</span><span style="FONT-FAMILY: 宋体">类的一个属性</span><span lang="EN-US">AutoScrollPosition</span><span style="FONT-FAMILY: 宋体">中。但是不知道从</span><span lang="EN-US">A</span><span style="FONT-FAMILY: 宋体">点到</span><span lang="EN-US">P</span><span style="FONT-FAMILY: 宋体">点的矢量。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">现在如果您还记得高中的数学知识,就知道得到该矢量的解决方案</span><span lang="EN-US" style="LETTER-SPACING: -1pt">—— </span><span style="FONT-FAMILY: 宋体">只需进行矢量相减即可。例如,要从</span><span lang="EN-US">B</span><span style="FONT-FAMILY: 宋体">点到</span><span lang="EN-US">P</span><span style="FONT-FAMILY: 宋体">点,可以水平移动</span><span lang="EN-US">150</span><span style="FONT-FAMILY: 宋体">个像素,垂直向下移动</span><span lang="EN-US">200</span><span style="FONT-FAMILY: 宋体">个像素。而要从</span><span lang="EN-US">B</span><span style="FONT-FAMILY: 宋体">点到</span><span lang="EN-US">A</span><span style="FONT-FAMILY: 宋体">点,就需要水平移动</span><span lang="EN-US">10</span><span style="FONT-FAMILY: 宋体">个像素,垂直向下移动</span><span lang="EN-US">57</span><span style="FONT-FAMILY: 宋体">个像素。这表示,要从</span><span lang="EN-US">A</span><span style="FONT-FAMILY: 宋体">点到</span><span lang="EN-US">P</span><span style="FONT-FAMILY: 宋体">点,需要水平移动</span><span lang="EN-US">140</span><span style="FONT-FAMILY: 宋体">个像素</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">=</span><span lang="EN-US">150–10)</span><span style="FONT-FAMILY: 宋体">,垂直向下移动</span><span lang="EN-US">143</span><span style="FONT-FAMILY: 宋体">个像素</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">=</span><span lang="EN-US">200–57)</span><span style="FONT-FAMILY: 宋体">。为了使之更简单,</span><span lang="EN-US">Graphics</span><span style="FONT-FAMILY: 宋体">类执行了一个方法来进行这些计算,这个方法是</span><span lang="EN-US">TranslateTransform</span><span style="FONT-FAMILY: 宋体">,我们给它传送水平和垂直坐标,表示客户区域的左上角相对于文档的左上角</span><span lang="EN-US">(AutoScrollPosition</span><span style="FONT-FAMILY: 宋体">属性,它是图中从</span><span lang="EN-US">B</span><span style="FONT-FAMILY: 宋体">到</span><span lang="EN-US">A</span><span style="FONT-FAMILY: 宋体">的矢量</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">,然后</span><span lang="EN-US">Graphics</span><span style="FONT-FAMILY: 宋体">设备考虑客户区域相对于文档区域的位置,处理这些坐标。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">解释完之后,所需做的是把下面这行代码添加到绘图代码中:</span></p>
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">dc.TranslateTransform(this.AutoScrollPosition.X, this.AutoScrollPosition.Y);</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">实际上在本示例中,它有点复杂,因为我们还要分别测试剪切区域,看看是否需要进行绘制工作。需要调整这个测试,把滚动的位置也考虑在内。完成后,该示例的整个绘图代码如下所示:</span></p>
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US"> protected override void OnPaint( PaintEventArgs e )</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> {</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> base.OnPaint(e);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> Graphics dc = e.Graphics;</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> Size scrollOffset = new Size(this.AutoScrollPosition);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> if (e.ClipRectangle.Top+scrollOffset.Width < 350 || </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> e.ClipRectangle.Left+scrollOffset.Height < 250)</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> {</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> Rectangle rectangleArea = new Rectangle</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> (rectangleTopLeft+scrollOffset, rectangleSize);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> Rectangle ellipseArea = new Rectangle</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> (ellipseTopLeft+scrollOffset, ellipseSize);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> dc.DrawRectangle(bluePen, rectangleArea);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> dc.DrawEllipse(redPen, ellipseArea);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> }</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US"> }</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">现在,滚动代码工作正常,最后得到正确的滚动屏幕图,如图</span><span lang="EN-US">20-12</span><span style="FONT-FAMILY: 宋体">所示。</span></p>
<p align="center"><span lang="EN-US"><img height="193" src="20/image013.jpg" width="201" alt="" /></span></p>
<p style="FTEL: 8.15pt" align="center"><span style="COLOR: black; FONT-FAMILY: 宋体">图</span><span lang="EN-US" style="COLOR: black"> 20-12</span></p>
<p class="a3" style="MARGIN-TOP: 8.15pt; FTEL: 21.45pt"><a ftel="_Toc507815364"><span style="FONT-FAMILY: 黑体">世界、页面和设备坐标</span></a></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">测量相对于文档区域左上角的位置和测量相对于屏幕</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">桌面</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">左上角的位置之间的区别非常重要,</span><span lang="EN-US">GDI+</span><span style="FONT-FAMILY: 宋体">为它们指定了不同的名称:</span></p>
<p class="1" style="MARGIN-LEFT: 37.25pt; FTEL: -15.8pt"><span lang="EN-US" style="LETTER-SPACING: -0.1pt">●<span style="FONT: 7pt 'Times New Roman'"> </span></span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -0.1pt">世界坐标</span><span lang="EN-US" style="LETTER-SPACING: -0.1pt">(World Coordinate)</span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -0.1pt">:是要测量的点距离文档区域左上角的位置</span><span lang="EN-US" style="LETTER-SPACING: -0.1pt">(</span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -0.1pt">以像素为单位</span><span lang="EN-US" style="LETTER-SPACING: -0.1pt">)</span><span style="FONT-FAMILY: 宋体; LETTER-SPACING: -0.1pt">。</span></p>
<p class="1" style="MARGIN-LEFT: 37.55pt; FTEL: -16.1pt"><span lang="EN-US">●<span style="FONT: 7pt 'Times New Roman'"> </span></span><span style="FONT-FAMILY: 宋体">页面坐标</span><span lang="EN-US">(Page Coordinate)</span><span style="FONT-FAMILY: 宋体">:是要测量的点距离客户区域左上角的位置</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">以像素为单位</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">。</span></p>
<p class="a3" style="MARGIN-TOP: 8.15pt; FTEL: 21.45pt"><span style="FONT-FAMILY: 黑体">注意:</span></p>
<p class="a1" style="FTEL: 21.45pt"><span style="FONT-FAMILY: 楷体_GB2312">熟悉</span><span lang="EN-US">GDI</span><span style="FONT-FAMILY: 楷体_GB2312">的开发人员要注意,世界坐标对应于</span><span lang="EN-US">GDI</span><span style="FONT-FAMILY: 楷体_GB2312">中的逻辑坐标。页面坐标对应于设备坐标。还要注意,编写逻辑和设备坐标之间的转换代码在</span><span lang="EN-US">GDI+</span><span style="FONT-FAMILY: 楷体_GB2312">中有了变化。在</span><span lang="EN-US">GDI</span><span style="FONT-FAMILY: 楷体_GB2312">中,转换是使用</span><span lang="EN-US">Windows API</span><span style="FONT-FAMILY: 楷体_GB2312">函数</span><span lang="EN-US">LPtoDP()</span><span style="FONT-FAMILY: 楷体_GB2312">和</span><span lang="EN-US">DPtoLP()</span><span style="FONT-FAMILY: 楷体_GB2312">通过设备环境进行的,而在</span><span lang="EN-US">GDI+</span><span style="FONT-FAMILY: 楷体_GB2312">中,由派生于</span><span lang="EN-US">Form</span><span style="FONT-FAMILY: 楷体_GB2312">和各种</span><span lang="EN-US">Windows </span><span style="FONT-FAMILY: 楷体_GB2312">窗体控件设备的</span><span lang="EN-US">Control</span><span style="FONT-FAMILY: 楷体_GB2312">类来维护转换过程中所需要的信息。</span></p>
<p class="MsoNormal"><span lang="EN-US">GDI+</span><span style="FONT-FAMILY: 宋体">还有第</span><span lang="EN-US">3</span><span style="FONT-FAMILY: 宋体">种坐标,即设备坐标</span><span lang="EN-US">(Device Coordinate)</span><span style="FONT-FAMILY: 宋体">。设备坐标类似于页面坐标,但其测量单位不是像素,而是用户通过调用</span><span lang="EN-US">Graphics.PageUnit</span><span style="FONT-FAMILY: 宋体">属性指定的单位。它可以使用的单位除了默认的像素外,还包括英寸和毫米。本章虽然没有使用</span><span lang="EN-US">PageUnit</span><span style="FONT-FAMILY: 宋体">属性,但它可用作获取设备的不同像素密度的方式。例如,在大多数监视器上,</span><span lang="EN-US">100</span><span style="FONT-FAMILY: 宋体">像素大约是</span><span lang="EN-US">1</span><span style="FONT-FAMILY: 宋体">英寸。但是,激光打印机可以达到</span><span lang="EN-US">1200 dpi(</span><span style="FONT-FAMILY: 宋体">点</span><span lang="EN-US">/</span><span style="FONT-FAMILY: 宋体">英寸</span><span lang="EN-US">)<span style="LETTER-SPACING: -1pt">—— </span></span><span style="FONT-FAMILY: 宋体">这表示一个</span><span lang="EN-US">100</span><span style="FONT-FAMILY: 宋体">像素宽的图形在该激光打印机上打印时会比较小。把单位设置为英寸,指定图形为</span><span lang="EN-US">1</span><span style="FONT-FAMILY: 宋体">英寸宽,就可以确保图形在不同的设备上有相同的大小。</span></p></div>
<!-- page -->
<div class="page" style="text-align: center">
<a href="100165569.htm">上一页</a> <a href="index.html">首页</a> <a href="100165571.htm">下一页</a>
</div>
<div style="margin: 0px auto; width: 700px; border: solid 1px #0b5f98;">
<div style="float: left; width: 16px; background-color: #0b5f98; color: White; padding: 1px;">
图书导读
</div>
<div style="float: right; width: 670px; text-align: left; line-height: 16pt; padding-left: 2px">
<!--导读-->
<h1 id="divCurrentNode2" style="color: #b83507; width: 100%; text-align: left; font-size: 12px; padding-left: 2px">当前章节:<a href='100165570.htm'><font color='red'>20.4 绘制可滚动的窗口</font></a></h1>
<div id="divRealteNod2" style="padding-left: 2px">
<div style='float:left;width:49%'>·<a href='100165567.htm'>20.2.3 Rectangle和RectangleF结构</a></div><div style='float:right;width:49%'>·<a href='100165568.htm'>20.2.4 Region</a></div><div style='float:left;width:49%'>·<a href='100165569.htm'>20.3 调试须知</a></div><div style='float:right;width:49%'>·<a href='100165571.htm'>20.5 颜色</a></div><div style='float:left;width:49%'>·<a href='100165572.htm'>20.5.1 红绿蓝(RGB)值</a></div><div style='float:right;width:49%'>·<a href='100165573.htm'>20.5.2 命名的颜色</a></div></div>
</div>
</div>
</div>
</div>
</body>
</html>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?