MindScape

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  44 随笔 :: 17 文章 :: 48 评论 :: 4 引用

公告

2005年7月20日 #

今天在写UnitTest时发现有个测试死活通不过。
其中语句的关键代码是这样的:
float scale = 0.24f;
int actualWidth = 800;
int width = (int)(actualWidth * scale);
AssertEquals(192, width);

dotUnit报错, expected value 192, 191 was got.
但是如果这样写就对了。
float scale = 0.24f;
int actualWidth =  800;
float widthf = actualWidth * scale; // 这里是192.0
int width = (int)widthf; //这样就是192了。

最后改成了
int width = (int)(float)(actualWidth * scale);
搞定。

但是问题仍然存在,C#编译器(.Net runtime)对于这两种强制类型转换内部处理有何差异呢?
第一种强制类型转换的结果为什么不对?我还没有很明确的答案,有谁知道?



posted @ 2005-07-20 16:21 Jonny Yu 阅读(922) 评论(3) 编辑

首先, GDI+里坐标网格是通过每个象素的中心的
对于DrawRectangle
其中矩形的长度和宽度指的是象素之间的间隔数,因此如果要绘制
DrawRectangle ( Pens.Black, 0,0, 5,4);
最终会得到长为6个象素宽为5个象素的矩形框。

而在FillRectangle 的时候,指定的长度和宽度是实际矩形的长宽的象素数。
如果仍然按照GDI+的坐标网格来看实际填充的的矩形区域比指定填充区域向左,上各偏移了0.5个象素。

因此在很多时候我们需要为一个填充的矩形区域画边框我们需要小心的给出边界参数。
下面这段代码演示了,如何为矩形区域绘制内边框和外边框。

        private void Form1_Paint(object sender, PaintEventArgs e)
        
{
            Graphics g 
= e.Graphics;

            Rectangle rect 
= new Rectangle(10,10,40,30);

            
g.FillRectangle(Brushes.LightBlue, rect);

            Rectangle innerBounds 
= new Rectangle(rect.Left, rect.Top, rect.Width - 1, rect.Height - 1);
            Rectangle outerBounds 
= new Rectangle(rect.Left - 1, rect.Top - 1, rect.Width + 1, rect.Height + 1);

            g.DrawRectangle(Pens.Brown, innerBounds);
            g.DrawRectangle(Pens.Blue, outerBounds);
        }

这只是我的理解的解决方法,如果大家觉得不对或有更好的实现方法,请尽管拍砖过来啊!

BTW:进一步研究发现Rectangle.Contains的行为也和FillRectangle相同,Rectangle的右上,右下,左下点不算在矩形区域内。所以ClipRectangle的计算又得小心了。


posted @ 2005-07-20 12:29 Jonny Yu 阅读(2076) 评论(3) 编辑

set Control.CheckForIllegalCrossThreadCalls = false;
posted @ 2005-07-20 08:19 Jonny Yu 阅读(242) 评论(0) 编辑