GDI32中Color结构 和 .Net中Color结构的区别

来源:互联网 发布:mac itunes铃声制作 编辑:程序博客网 时间:2024/06/07 18:36


        最近在开发一个C#程序的过程中因为需要用到win32里面的绘图函数,因此采用dllimport的方式声明了CreatePen方法,代码如下:

[DllImport("gdi32.dll")]        private static extern IntPtr CreatePen(int nPenStyle, int nWidth, Int32 crColor);

   这里面的nPenStyle是一个整形,表示不同的线型,比如直线、虚线等等;nWidth表示线的宽度;这些都比较好理解。

   而这里的参数crColor是一个32位整形(四个字节),第一个字节没软用。后三个字节分别代表Blue,Green,Red分量(注意顺序)。

   以msdn官方上给出的情况来看,Color结构标准定义为这样 0x00bbggrr。即第一个字节必须定义为0,其他每个每个字节为0x00-0xff。

   那么我想在C#里面无缝地引入这个gdi32.dll提供的方法肯定要将这个CreatePen方法封装起来。自然而然的要借助.NET里面的Color结构去替换这个不是很直观的crColor整型。

   假设npenStyle固定为0,那么代码如下

public IntPtr CreatePen(int nWidth,Color color){       return CreatePen(0,nWidth,color.ToArgb());}

   可以看到借助.Net中Color的ToArgb方法,可以直接地把.NET中的Color结构转换成int32类型,但是这样绘制出来的图形颜色是根本不正确的。

   经过调试才发现,.NET里面Color.ToArgb方法获取到的int32是这样构造的 AARRGGBB,(A代表alpha 分量值),这样的话如果利用.NET中内置的蓝色,Color.Blue。它调用.ToArgb()方法得到的是0xff0000ff.先不说红色和蓝色位置与上面的crColor定义是相反的。就最开始的第一个字节是0xff就使得我们不可能得到我们想要的颜色。

   因此我换了一种方法,转化一下。这样就可以使用了

public IntPtr CreatePen(int nWidth,Color color){       IntPtr cpen = CreatePen(0, nWidth, Color.FromArgb(0, color.B, color.G, color.R).ToArgb());}

   由此可见,写代码不能想当然,特别是这种人家封装好的结构,一定要搞清楚其内部结构是怎样的,方法的参数每个都是什么含义,特别是这样调用多年前制定下来API,历史的车轮滚滚而来,谁能想到以前大家整天说RGB,RGB,多年以前的结构竟是BGR,不知这里面是不是又有什么复杂的兼容性故事(毕竟丧心病狂软)。


0 0
原创粉丝点击