100165561.htm
来自「C#高级编程(第三版),顶死你们。。 。up」· HTM 代码 · 共 103 行 · 第 1/2 页
HTM
103 行
<p class="a6" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US"> private void InitializeComponent()</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> {</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> this.AutoScaleBaseSize = new System.Drawing.Size(5,13);</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> this.ClientSize = new System.Drawing.Size(292,266);</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> this.Name = </span><span lang="ES">"</span><span lang="EN-US">Form1</span><span lang="ES">"</span><span lang="EN-US">;</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> this.Text = "DrawShapesSample";</span></p>
<p class="a6" 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"> this.BackColor = Color.White; </span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">接着,给</span><span lang="EN-US">Form1</span><span style="FONT-FAMILY: 宋体">构造函数添加代码。使用窗体的</span><span lang="EN-US">CreateGraphics()</span><span style="FONT-FAMILY: 宋体">方法创建一个</span><span lang="EN-US">Graphics</span><span style="FONT-FAMILY: 宋体">对象,这个对象包含绘图时需要使用的</span><span lang="EN-US">Windows </span><span style="FONT-FAMILY: 宋体">设备环境。创建的设备环境与显示设备相关,也与这个窗口相关。</span></p>
<p class="a6" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US"> public Form1()</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; LINE-HEIGHT: 15pt; FTEL: 18.45pt"><span lang="EN-US"> {</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; LINE-HEIGHT: 15pt; FTEL: 18.45pt"><span lang="EN-US"> InitializeComponent();</span></p>
<p class="a6" style="MARGIN-LEFT: 21.45pt; LINE-HEIGHT: 15pt; FTEL: 18.45pt"><span lang="EN-US"> </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; LINE-HEIGHT: 15pt; FTEL: 18.45pt"><span lang="EN-US"> Graphics dc = this.CreateGraphics();</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; LINE-HEIGHT: 15pt; FTEL: 18.45pt"><span lang="EN-US"> this.Show();</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; LINE-HEIGHT: 15pt; FTEL: 18.45pt"><span lang="EN-US"> Pen bluePen = new Pen(Color.Blue, 3);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; LINE-HEIGHT: 15pt; FTEL: 18.45pt"><span lang="EN-US"> dc.DrawRectangle(bluePen, 0,0,50,50);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; LINE-HEIGHT: 15pt; FTEL: 18.45pt"><span lang="EN-US"> Pen redPen = new Pen(Color.Red, 2);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; LINE-HEIGHT: 15pt; FTEL: 18.45pt"><span lang="EN-US"> dc.DrawEllipse(redPen, 0, 50, 80, 60);</span></p>
<p class="a6" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US"> }</span></p>
<p class="MsoNormal" style="LINE-HEIGHT: 17pt"><span style="FONT-FAMILY: 宋体">然后调用</span><span lang="EN-US">Show()</span><span style="FONT-FAMILY: 宋体">方法显示窗口。之所以让窗口立即显示,是因为在窗口显示出来之前,我们不能作任何工作</span><span lang="EN-US" style="LETTER-SPACING: -1pt">—— </span><span style="FONT-FAMILY: 宋体">没有可供绘图的地方。</span></p>
<p class="MsoNormal" style="LINE-HEIGHT: 17pt"><span style="FONT-FAMILY: 宋体">最后,显示一个矩形,其坐标是</span><span lang="EN-US">(0,0)</span><span style="FONT-FAMILY: 宋体">,宽度和高度是</span><span lang="EN-US">50</span><span style="FONT-FAMILY: 宋体">,再绘制一个椭圆,其坐标是</span><span lang="EN-US">(0, 50)</span><span style="FONT-FAMILY: 宋体">,宽度是</span><span lang="EN-US">80</span><span style="FONT-FAMILY: 宋体">,高度是</span><span lang="EN-US">50</span><span style="FONT-FAMILY: 宋体">。注意坐标</span><span lang="EN-US">(x,y)</span><span style="FONT-FAMILY: 宋体">表示从窗口的客户区域左上角开始向右的</span><span lang="EN-US">x</span><span style="FONT-FAMILY: 宋体">个像素,向下的</span><span lang="EN-US">y</span><span style="FONT-FAMILY: 宋体">个像素</span><span lang="EN-US" style="LETTER-SPACING: -1pt">—— </span><span style="FONT-FAMILY: 宋体">这些是显示出来的图形的左上角坐标。</span></p>
<p class="MsoNormal" style="LINE-HEIGHT: 17pt"><span style="FONT-FAMILY: 宋体">我们使用的</span><span lang="EN-US">DrawRectangle() </span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US"> DrawEllipse()</span><span style="FONT-FAMILY: 宋体">重载方法分别带</span><span lang="EN-US">5</span><span style="FONT-FAMILY: 宋体">个参数。第一个参数是类</span><span lang="EN-US">System.Drawing.Pen</span><span style="FONT-FAMILY: 宋体">的实例。</span><span lang="EN-US">Pen</span><span style="FONT-FAMILY: 宋体">是许多帮助绘图的支持对象中的一个,它包含如何绘制直线的信息。第一个</span><span lang="EN-US">Pen</span><span style="FONT-FAMILY: 宋体">表示线条应是蓝色的,其宽度为</span><span lang="EN-US">3</span><span style="FONT-FAMILY: 宋体">个像素,第二个</span><span lang="EN-US">Pen</span><span style="FONT-FAMILY: 宋体">表示线条应是红色的,其宽度为</span><span lang="EN-US">2</span><span style="FONT-FAMILY: 宋体">个像素。后面的</span><span lang="EN-US">4</span><span style="FONT-FAMILY: 宋体">个参数是坐标和大小。对于矩形,它们分别表示矩形的左上角坐标</span><span lang="EN-US">(x,y)</span><span style="FONT-FAMILY: 宋体">、其宽度和高度。对于椭圆,这些数值的含义表示相同的,但它们是指椭圆假想的外接矩形,而不是椭圆本身。运行代码,会得到如图</span><span lang="EN-US">20-1</span><span style="FONT-FAMILY: 宋体">所示的图形。当然,本书不是彩页书,所以看不到颜色。</span></p>
<p align="center"><span lang="EN-US"><img height="195" src="20/image001.jpg" width="196" alt="" /></span></p>
<p style="FTEL: 8.15pt" align="center"><span style="FONT-FAMILY: 宋体">图</span><span lang="EN-US"> 20-1</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">BackColor</span><span style="FONT-FAMILY: 宋体">属性设置的影响。还要注意,矩形放在该区域的一角,因为我们指定了坐标</span><span lang="EN-US">(0,0)</span><span style="FONT-FAMILY: 宋体">。其次,注意椭圆的顶部与矩形有轻度的重叠,这与代码中给出的坐标有点不同,这是因为</span><span lang="EN-US">Windows</span><span style="FONT-FAMILY: 宋体">在重叠的区域上放置了连接矩形和椭圆的线条。在默认情况下,</span><span lang="EN-US">Windows</span><span style="FONT-FAMILY: 宋体">会试图把图形边框所在的线条放在中心位置</span><span lang="EN-US" style="LETTER-SPACING: -1pt">—— </span><span style="FONT-FAMILY: 宋体">但这并不是总能做到的,因为线条是以像素为单位来绘制的,但每个图形的边框理论上位于两个像素之间。结果,</span><span lang="EN-US">1</span><span style="FONT-FAMILY: 宋体">个像素宽的线条就会正好位于图形顶边和左边的里面,而在右边和底边的外面。这样,从严格意义上讲,相邻图形的边框就会有一个像素的重叠。我们指定的线条宽度比较大,因此重叠区域也会比较大。设置</span><span lang="EN-US">Pen.Alignment</span><span style="FONT-FAMILY: 宋体">属性</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">详见</span><span lang="EN-US">MSDN</span><span style="FONT-FAMILY: 宋体">文档说明</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">,就可以改变默认的操作方式,但这里使用默认的操作方式就足够了。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">但如果运行这个示例,就会注意到窗体的执行过程有点奇怪。如果把它放在那里,或者用鼠标在屏幕移动该窗体,它就工作正常。但如果最小化该窗体,再恢复它,绘制好的图形就不见了。如果在示例中绘制另一个窗体,情况也是这样。如果在该窗体上拖动另一个窗口,使之只显示一部分图形,再把该窗口拖离这个窗体,临时被挡住的部分就消失了,只剩下一半椭圆或矩形了!</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">这是怎么回事?问题发生的原因是,如果窗口的一部分被隐藏了,</span><span lang="EN-US">Windows</span><span style="FONT-FAMILY: 宋体">通常会立即删除与其中显示的内容相关的所有信息。这是必须的,否则存储屏幕数据的内存量就会是个天文数字。一般的计算机在运行时,视频卡设置为显示</span><span lang="EN-US">1024×768</span><span style="FONT-FAMILY: 宋体">像素、</span><span lang="EN-US">24</span><span style="FONT-FAMILY: 宋体">位彩色模式,这表示屏幕上的每个像素占据</span><span lang="EN-US">3</span><span style="FONT-FAMILY: 宋体">个字节,则显示整个屏幕就需要</span><span lang="EN-US">2.25MB(</span><span style="FONT-FAMILY: 宋体">本章后面会说明</span><span lang="EN-US">24</span><span style="FONT-FAMILY: 宋体">位颜色的含义</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">。但是,用户很少让任务栏上有</span><span lang="EN-US">10</span><span style="FONT-FAMILY: 宋体">个或</span><span lang="EN-US">20</span><span style="FONT-FAMILY: 宋体">个最小化窗口。下面考虑一种最糟糕的情况:</span><span lang="EN-US">20</span><span style="FONT-FAMILY: 宋体">个窗口,每个窗口如果没有最小化,就占用整个屏幕,如果</span><span lang="EN-US">Windows</span><span style="FONT-FAMILY: 宋体">存储了这些窗口包含的可视化信息,当用户恢复它们时,它们就会有</span><span lang="EN-US">45MB</span><span style="FONT-FAMILY: 宋体">。目前,比较好的图形卡有</span><span lang="EN-US">64MB</span><span style="FONT-FAMILY: 宋体">的内存,可以应付这种情况,但在几年前图形卡有</span><span lang="EN-US">4MB</span><span style="FONT-FAMILY: 宋体">的内存就不错了。剩余的部分需要存储在计算机的主内存中。许多人仍在使用旧机器。很显然,</span><span lang="EN-US">Windows</span><span style="FONT-FAMILY: 宋体">不可能这样管理用户界面。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">在窗口的某一部分消失时,那些像素也就丢失了。因为</span><span lang="EN-US">Windows</span><span style="FONT-FAMILY: 宋体">释放了保存这些像素的内存。但要注意,窗口的一部分被隐藏了,当它检测到窗口不再被隐藏时,就请求拥有该窗口的应用程序重新绘制其内容。这个规则有一些例外</span><span lang="EN-US" style="LETTER-SPACING: -1pt">—— </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="MsoNormal"><span style="FONT-FAMILY: 宋体">这就是示例应用程序的一个问题。我们把绘图代码放在</span><span lang="EN-US">Form1</span><span style="FONT-FAMILY: 宋体">的构造函数中,当应用程序启动时,就调用该函数一次,不能在以后需要时再次调用该构造函数,重新绘制图形。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">在使用</span><span lang="EN-US">Windows</span><span style="FONT-FAMILY: 宋体">窗体的服务器控件时,不需要知道这些,这是因为标准控件非常专业,能在</span><span lang="EN-US">Windows</span><span style="FONT-FAMILY: 宋体">需要时重新绘制它们自己。这是编写控件时不需要担心实际绘图过程的原因之一。如果要应用程序在屏幕上绘图,还需要在</span><span lang="EN-US">Windows</span><span style="FONT-FAMILY: 宋体">要求重新绘制窗口的全部或部分时,确保应用程序会正确响应。下一节将修改这个示例,完成应用程序的响应。</span></p></div>
<!-- page -->
<div class="page" style="text-align: center">
<a href="100165560.htm">上一页</a> <a href="index.html">首页</a> <a href="100165562.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='100165561.htm'><font color='red'>20.1.2 绘制图形</font></a></h1>
<div id="divRealteNod2" style="padding-left: 2px">
<div style='float:left;width:49%'>·<a href='100165558.htm'>19.5 小结</a></div><div style='float:right;width:49%'>·<a href='100165559.htm'>20.1 理解绘图规则</a></div><div style='float:left;width:49%'>·<a href='100165560.htm'>20.1.1 GDI和GDI+</a></div><div style='float:right;width:49%'>·<a href='100165562.htm'>20.1.3 使用OnPaint()绘制图形</a></div><div style='float:left;width:49%'>·<a href='100165563.htm'>20.1.4 使用剪切区域</a></div><div style='float:right;width:49%'>·<a href='100165564.htm'>20.2 测量坐标和区域</a></div></div>
</div>
</div>
</div>
</div>
</body>
</html>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?