在C#中使用GDI的简单总结
2011-07-09 16:56
274 查看
在C#中使用GDI的简单总结在C#默认支持的是GDI+库,使用GDI+库,有很丰富的函数和排版手段,可以满足大部分的要求.除非,你需要使用bitmap字体,GDI+对于字体的支持有很大限制,支持truetype字体,而对于点阵字体(栅格字体)则不再支持,但是很多字体都是这种点阵字体,这样就带来一个问题,使用不了了.而很多公司则会自己制作某些用途的字体,比如说在LED显示屏上使用,这个时候使用GDI+则不再是一个明智的选择了.此外GDI+虽然强大,但是经过测试发现效率却是低下,速度比GDI慢了不少.但是CS的界面开发环境和编码习惯又很适合,所以比较折衷的解决方法是使用C#调用系统的gdiapi函数实现编程.首先C#环境中的color结构是AARRGGBB,而在win32的颜色结构却是AABBGGRR,所以如果不注意则会使到颜色出现偏差或者逆转.在.net环境的类库当中,在system.drawing的命名空间中有ColorTranslator.ToWin32()这个函数,来对color结构转换成win32的api使用的颜色结构.GDI中比较重要的函数,gdi函数基本都是来之一个dll.Gdi32.dll[DllImport("gdi32.dll")]
publicstaticexternIntPtrSelectObject(IntPtrhdc,IntPtrhgdiobj);
[DllImport("GDI32.dll")]
publicstaticexternboolDeleteObject(IntPtrobjectHandle);
[DllImport("gdi32.dll")]
publicstaticexternboolFillRgn(IntPtrhdc,IntPtrhrgn,IntPtrhbr);
[DllImport("gdi32.dll")]
publicstaticexternIntPtrCreateRectRgn(intnLeftRect,intnTopRect,intnRightRect,
intnBottomRect);
[DllImport("gdi32.dll")]
publicstaticexternIntPtrCreateSolidBrush(Int32crColor);
[DllImport("gdi32.dll")]
publicstaticexternintSetBkMode(IntPtrhdc,intiBkMode);
publicconstintTRANSPARENT=1;
publicconstintOPAQUE=2;
[DllImport("gdi32.dll")]
staticexternuintSetBkColor(IntPtrhdc,intcrColor);
[DllImport("gdi32.dll")]
staticexternuintSetTextColor(IntPtrhdc,intcrColor);
[DllImport("gdi32",EntryPoint="CreateFontW",CharSet=CharSet.Auto)]
staticexternIntPtrCreateFontW(
[In]Int32nHeight,
[In]Int32nWidth,
[In]Int32nEscapement,
[In]Int32nOrientation,
[In]FontWeightfnWeight,
[In]BooleanfdwItalic,
[In]BooleanfdwUnderline,
[In]BooleanfdwStrikeOut,
[In]FontCharSetfdwCharSet,
[In]FontPrecisionfdwOutputPrecision,
[In]FontClipPrecisionfdwClipPrecision,
[In]FontQualityfdwQuality,
[In]FontPitchAndFamilyfdwPitchAndFamily,
[In]StringlpszFace);
[DllImport("gdi32.dll")]
publicstaticexternintGetTextFace(IntPtrhdc,intnCount,
[Out]StringBuilderlpFaceName);
publicconstInt32LF_FACESIZE=32;
[DllImport("gdi32.dll",ExactSpelling=true)]
publicstaticexternboolBitBlt(
IntPtrhdcDest,//目标设备的句柄
intnXDest,//目标对象的左上角的X坐标
intnYDest,//目标对象的左上角的Y坐标
intnWidth,//目标对象的矩形的宽度
intnHeight,//目标对象的矩形的长度
IntPtrhdcSrc,//源设备的句柄
intnXSrc,//源对象的左上角的X坐标
intnYSrc,//源对象的左上角的X坐标
TernaryRasterOperationsdwRop//光栅的操作值
);
[DllImport("gdi32.dll")]
publicstaticexternboolStretchBlt(IntPtrhdcDest,intnXOriginDest,intnYOriginDest,
intnWidthDest,intnHeightDest,
IntPtrhdcSrc,intnXOriginSrc,intnYOriginSrc,intnWidthSrc,intnHeightSrc,
TernaryRasterOperationsdwRop);
[DllImport("gdi32.dll",CharSet=CharSet.Auto)]
publicstaticexternboolGetTextExtentPoint(IntPtrhdc,stringlpString,
intcbString,refSizelpSize);
[DllImport("Gdi32.dll",CharSet=CharSet.Auto)]
publicstaticexternboolGetTextMetrics(IntPtrhdc,outTEXTMETRIClptm);
[DllImport("gdi32.dll")]
publicstaticexternboolGetCharABCWidthsFloatW(IntPtrhdc,uintiFirstChar,uintiLastChar,[Out]ABCFloat[]lpABCF);
[DllImport("gdi32.dll",CharSet=CharSet.Auto)]
publicstaticexternboolTextOutW(IntPtrhdc,intnXStart,intnYStart,
stringlpString,intcbString);
[DllImport("gdi32.dll",CharSet=CharSet.Auto)]
publicstaticexternboolGetCharWidth32(IntPtrhdc,uintiFirstChar,uintiLastChar,
[Out]int[]lpBuffer);
[DllImport("user32.dll",CharSet=CharSet.Unicode)]
publicstaticexternintDrawText(IntPtrhdc,stringlpStr,intnCount,refRectlpRect,dwDTFormatwFormat);
[DllImport("gdi32.dll",ExactSpelling=true,SetLastError=true)]
staticexternIntPtrCreateCompatibleDC(IntPtrhdc);
[DllImport("gdi32.dll",ExactSpelling=true,SetLastError=true)]
staticexternboolDeleteDC(IntPtrhdc);
这些都是在GDI中比较常用的函数,其中SelectObject,和DeleteObject更是关键,在GDI的使用中最容易出现的问题就是内存泄漏,很多时候是因为没有正确释放资源引起的.所以需要特别小心,在GDI中释放资源使用DeleteObject这个函数来释放.
下面来实现一些具体的函数
///
///填充特定DC的一个区域的特定颜色
///
///给定DC
///给定区域
///给定颜色
publicstaticvoidFillRect(IntPtrhdc,RectangleRect,ColorFillColor)
{
IntPtrfillBrush=CreateSolidBrush(ColorTranslator.ToWin32(FillColor));
IntPtrrectR=CreateRectRgn(Rect.Left,Rect.Top,Rect.Right,Rect.Bottom);
FillRgn(hdc,rectR,fillBrush);
DeleteObject(rectR);
DeleteObject(fillBrush);
}
这个函数实现对一个区域填充一个颜色,当中创建了画笔,创建了区域,然后最后,当然还要记得释放两者占用的资源.
创建字体函数
publicstaticIntPtrCreatFont(StringFontName,Int32Height,FontStyleStyle)
{
IntPtrResult;//=IntPtr.Zero;
FontWeightboldWeight=FontWeight.FW_NORMAL;
BooleanItalic=false;
BooleanUnderline=false;
BooleanBold=false;
if((Style&FontStyle.Bold)!=0)
{
Bold=true;
}
if((Style&FontStyle.Italic)!=0)
{
Italic=true;
}
if((Style&FontStyle.Underline)!=0)
{
Underline=true;
}
if(Bold)
{
boldWeight=FontWeight.FW_BOLD;
}
Result=CreateFontW(Height,0,0,0,boldWeight,Italic,Underline,false,
FontCharSet.DEFAULT_CHARSET,FontPrecision.OUT_DEFAULT_PRECIS,
FontClipPrecision.CLIP_DEFAULT_PRECIS,FontQuality.DRAFT_QUALITY,
FontPitchAndFamily.DEFAULT_PITCH,FontName);
returnResult;
}
在.net中,默认的字体类,不支持点阵字体,所以要使用CreateFontW这个函数来创建自己的字体资源,其中大部分的选项都试用默认值即可.
然后就是设置画板字体,在GDI环境中,DC是带着字体的,而不像GDI+那样子是分离的,所以经常需要设置不同的字体
publicstaticIntPtrSetCanvasFont(IntPtrhdc,ApiFontNewFont)
{
IntPtrFontPtr=CreatFont(NewFont.Name,NewFont.Size,NewFont.Style);
IntPtrOldPtr=SelectObject(hdc,FontPtr);
DeleteObject(OldPtr);
returnOldPtr;
}
这个函数,将DC原来的字体资源释放掉,这样的实现会带来一个新的问题,因为一般来说都需要将DC原来的字体资源再通过selectobject函数放回去,然后将新的字体资源释放掉.所以这个函数是要小心使用的.
所以就有了第二个版本
这样子就可以手动的释放资源,但是需要特别注意,的是一定要记得释放掉字体资源.
一般的使用画图的步骤
这样子就可以将drawBmp画到e.graphics上面了.最重要的是后面释放掉资源,否则内存的泄漏速度是很厉害的.我的软件每次重画就有7M左右的泄漏.一下子从十几M的内存上升到几百M的内存占用
这个函数是设置透明度的,参数2如果为1则是透明,2则是不透明.
不透明的话,将字符串画上去的时候,会有白色的背景.一般来说设为透明.
获取字符或者字体的信息函数
这几个函数都可以获取字体或者字符串占用的空间大小,而又各有区别.
GetTextExtentPoint可以方便的获取一个字符串,或者字符串的部分的长度,因为可以通过cbString这个长度来控制获取的范围.
GetTextMetrics则是获取一个字体的各种高度信息,包括height,ascent,descent,还包括字体能够表现的字符范围等等信息.
GetCharABCWidthsFloatW则是获取某段连续字符串的abcwidth信息,abcwidth信息在某些情况下,需要特别注意,否则斜体会排版得很难看.
GetCharWidth32获取一个连续的字符段的宽度信息,但是根据实践,居然和GetTextExtentPoint获取的信息不大一致,暂时是少于实际占用的空间.使到计算出来的占用宽度实际上不足以容纳字符串的排版.
字符串的描绘
这是在gdi操作中非常重要的一部分,使用Gdi是因为需要使用特殊字体,而字体当然是针对字符串来使用的的.所以,这根本就是使用gdi的目的.
常用的字符串输出有来个函数
TextOutW是一个比较简单的函数,适合一般的场合,只需要设置X和Y的坐标即可
DrawText,则会控制输出的空间大小,排版规则.比较适合需要精确控制的场所,又或者比如说输出阿拉伯文字的时候,要设置为右对齐.
获取系统所有的字体
由于C#不支持点阵字体,所以自然地,使用.net提供的函数,获取的安装字体列表自然是不包含点阵字体的.所以并不符合我的要求.所以还得使用系统的api函数,来获取安装字体列表.
其中EnumFontCallBack为回调函数,通过这个回调函数,可以获取到系统所有的字体,包括点阵的字体.
附录A:
GDI使用的结构和常量
这些都是在GDI中比较常用的函数,其中SelectObject,和DeleteObject更是关键,在GDI的使用中最容易出现的问题就是内存泄漏,很多时候是因为没有正确释放资源引起的.所以需要特别小心,在GDI中释放资源使用DeleteObject这个函数来释放.
下面来实现一些具体的函数
这个函数实现对一个区域填充一个颜色,当中创建了画笔,创建了区域,然后最后,当然还要记得释放两者占用的资源.
创建字体函数
在.net中,默认的字体类,不支持点阵字体,所以要使用CreateFontW这个函数来创建自己的字体资源,其中大部分的选项都试用默认值即可.
然后就是设置画板字体,在GDI环境中,DC是带着字体的,而不像GDI+那样子是分离的,所以经常需要设置不同的字体
这个函数,将DC原来的字体资源释放掉,这样的实现会带来一个新的问题,因为一般来说都需要将DC原来的字体资源再通过selectobject函数放回去,然后将新的字体资源释放掉.所以这个函数是要小心使用的.
所以就有了第二个版本
publicstaticIntPtrSetCanvasFontNotDelete(IntPtrhdc,ApiFontNewFont) { IntPtrFontPtr=CreatFont(NewFont.Name,NewFont.Size,NewFont.Style); IntPtrOldPtr=SelectObject(hdc,FontPtr); returnOldPtr; }
一般的使用画图的步骤
IntPtrpTarget=e.Graphics.GetHdc();
IntPtrpSource=CreateCompatibleDC(pTarget);
IntPtrpOrig=SelectObject(pSource,drawBmp.GetHbitmap());
GDIApi.StretchBlt(pTarget,0,0,this.Width,this.Height,pSource,0,0,drawWidth,drawHeight,TernaryRasterOperations.SRCCOPY);
IntPtrpNew=SelectObject(pSource,pOrig);
DeleteObject(pNew);
DeleteDC(pSource);
e.Graphics.ReleaseHdc(pTarget);
这样子就可以将drawBmp画到e.graphics上面了.最重要的是后面释放掉资源,否则内存的泄漏速度是很厉害的.我的软件每次重画就有7M左右的泄漏.一下子从十几M的内存上升到几百M的内存占用
[DllImport("gdi32.dll")]
publicstaticexternintSetBkMode(IntPtrhdc,intiBkMode);
publicconstintTRANSPARENT=1;
publicconstintOPAQUE=2;
这个函数是设置透明度的,参数2如果为1则是透明,2则是不透明.
不透明的话,将字符串画上去的时候,会有白色的背景.一般来说设为透明.
获取字符或者字体的信息函数
[DllImport("gdi32.dll",CharSet=CharSet.Auto)]
publicstaticexternboolGetTextExtentPoint(IntPtrhdc,stringlpString,
intcbString,refSizelpSize);
[DllImport("Gdi32.dll",CharSet=CharSet.Auto)]
publicstaticexternboolGetTextMetrics(IntPtrhdc,outTEXTMETRIClptm);
[DllImport("gdi32.dll")]
publicstaticexternboolGetCharABCWidthsFloatW(IntPtrhdc,uintiFirstChar,uintiLastChar,[Out]ABCFloat[]lpABCF);
[DllImport("gdi32.dll",CharSet=CharSet.Auto)]
publicstaticexternboolGetCharWidth32(IntPtrhdc,uintiFirstChar,uintiLastChar,
[Out]int[]lpBuffer);
这几个函数都可以获取字体或者字符串占用的空间大小,而又各有区别.
GetTextExtentPoint可以方便的获取一个字符串,或者字符串的部分的长度,因为可以通过cbString这个长度来控制获取的范围.
GetTextMetrics则是获取一个字体的各种高度信息,包括height,ascent,descent,还包括字体能够表现的字符范围等等信息.
GetCharABCWidthsFloatW则是获取某段连续字符串的abcwidth信息,abcwidth信息在某些情况下,需要特别注意,否则斜体会排版得很难看.
GetCharWidth32获取一个连续的字符段的宽度信息,但是根据实践,居然和GetTextExtentPoint获取的信息不大一致,暂时是少于实际占用的空间.使到计算出来的占用宽度实际上不足以容纳字符串的排版.
字符串的描绘
这是在gdi操作中非常重要的一部分,使用Gdi是因为需要使用特殊字体,而字体当然是针对字符串来使用的的.所以,这根本就是使用gdi的目的.
常用的字符串输出有来个函数
[DllImport("gdi32.dll",CharSet=CharSet.Auto)]
publicstaticexternboolTextOutW(IntPtrhdc,intnXStart,intnYStart,
stringlpString,intcbString);
[DllImport("user32.dll",CharSet=CharSet.Unicode)]
publicstaticexternintDrawText(IntPtrhdc,stringlpStr,intnCount,refRectlpRect,dwDTFormatwFormat);
TextOutW是一个比较简单的函数,适合一般的场合,只需要设置X和Y的坐标即可
DrawText,则会控制输出的空间大小,排版规则.比较适合需要精确控制的场所,又或者比如说输出阿拉伯文字的时候,要设置为右对齐.
获取系统所有的字体
由于C#不支持点阵字体,所以自然地,使用.net提供的函数,获取的安装字体列表自然是不包含点阵字体的.所以并不符合我的要求.所以还得使用系统的api函数,来获取安装字体列表.
privateInt32EnumFontCallBack(refENUMLOGFONTEXlpelfe,IntPtrlpntme,intFontType,intlParam)
{
//Debug.WriteLine(lpelfe.elfFullName);
if(lpelfe.elfFullName.Substring(0,1)!="@")
{
if(!sysFontList.Contains(lpelfe.elfFullName))
{
sysFontList.Add(lpelfe.elfFullName);
}
}
return1;
}
LOGFONTlogfont=newLOGFONT();
logfont.lfCharSet=FontCharSet.DEFAULT_CHARSET;
Bitmapbmp=newBitmap(10,10);
Graphicsg=Graphics.FromImage(bmp);
IntPtrhDC=g.GetHdc();
EnumFontFamilies.EnumFontFamiliesEx(hDC,logfont,EnumFontCallBack,IntPtr.Zero,0);
g.ReleaseHdc(hDC);
g.Dispose();
bmp.Dispose();
publicclassEnumFontFamilies
{
publicconstintLF_FACESIZE=32;
publicdelegateintEnumFontExDelegate(refENUMLOGFONTEXlpelfe,IntPtrlpntme,intFontType,intlParam);
[DllImport("gdi32.dll",EntryPoint="EnumFontFamiliesEx",CharSet=CharSet.Unicode)]
publicstaticexternintEnumFontFamiliesEx(IntPtrhDC,[In]LOGFONTlogFont,EnumFontExDelegateenumFontExCallback,
IntPtrlParam,uintdwFlags);
}
其中EnumFontCallBack为回调函数,通过这个回调函数,可以获取到系统所有的字体,包括点阵的字体.
附录A:
GDI使用的结构和常量
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
publicstructENUMLOGFONTEX
{
publicLOGFONTelfLogFont;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=32)]
publicstringelfFullName;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=32)]
publicstringelfStyle;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=32)]
publicstringelfScript;
}
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
publicclassLOGFONT
{
publicintlfHeight;
publicintlfWidth;
publicintlfEscapement;
publicintlfOrientation;
publicFontWeightlfWeight;
[MarshalAs(UnmanagedType.U1)]
publicboollfItalic;
[MarshalAs(UnmanagedType.U1)]
publicboollfUnderline;
[MarshalAs(UnmanagedType.U1)]
publicboollfStrikeOut;
publicFontCharSetlfCharSet;
publicFontPrecisionlfOutPrecision;
publicFontClipPrecisionlfClipPrecision;
publicFontQualitylfQuality;
publicFontPitchAndFamilylfPitchAndFamily;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst=32)]
publicstringlfFaceName;
publicoverridestringToString()
{
StringBuildersb=newStringBuilder();
sb.Append("LOGFONT\n");
sb.AppendFormat("lfHeight:{0}\n",lfHeight);
sb.AppendFormat("lfWidth:{0}\n",lfWidth);
sb.AppendFormat("lfEscapement:{0}\n",lfEscapement);
sb.AppendFormat("lfOrientation:{0}\n",lfOrientation);
sb.AppendFormat("lfWeight:{0}\n",lfWeight);
sb.AppendFormat("lfItalic:{0}\n",lfItalic);
sb.AppendFormat("lfUnderline:{0}\n",lfUnderline);
sb.AppendFormat("lfStrikeOut:{0}\n",lfStrikeOut);
sb.AppendFormat("lfCharSet:{0}\n",lfCharSet);
sb.AppendFormat("lfOutPrecision:{0}\n",lfOutPrecision);
sb.AppendFormat("lfClipPrecision:{0}\n",lfClipPrecision);
sb.AppendFormat("lfQuality:{0}\n",lfQuality);
sb.AppendFormat("lfPitchAndFamily:{0}\n",lfPitchAndFamily);
sb.AppendFormat("lfFaceName:{0}\n",lfFaceName);
returnsb.ToString();
}
}
publicenumFontWeight:int
{
FW_DONTCARE=0,
FW_THIN=100,
FW_EXTRALIGHT=200,
FW_LIGHT=300,
FW_NORMAL=400,
FW_MEDIUM=500,
FW_SEMIBOLD=600,
FW_BOLD=700,
FW_EXTRABOLD=800,
FW_HEAVY=900,
}
publicenumFontCharSet:byte
{
ANSI_CHARSET=0,
DEFAULT_CHARSET=1,
SYMBOL_CHARSET=2,
SHIFTJIS_CHARSET=128,
HANGEUL_CHARSET=129,
HANGUL_CHARSET=129,
GB2312_CHARSET=134,
CHINESEBIG5_CHARSET=136,
OEM_CHARSET=255,
JOHAB_CHARSET=130,
HEBREW_CHARSET=177,
ARABIC_CHARSET=178,
GREEK_CHARSET=161,
TURKISH_CHARSET=162,
VIETNAMESE_CHARSET=163,
THAI_CHARSET=222,
EASTEUROPE_CHARSET=238,
RUSSIAN_CHARSET=204,
MAC_CHARSET=77,
BALTIC_CHARSET=186,
}
publicenumFontPrecision:byte
{
OUT_DEFAULT_PRECIS=0,
OUT_STRING_PRECIS=1,
OUT_CHARACTER_PRECIS=2,
OUT_STROKE_PRECIS=3,
OUT_TT_PRECIS=4,
OUT_DEVICE_PRECIS=5,
OUT_RASTER_PRECIS=6,
OUT_TT_ONLY_PRECIS=7,
OUT_OUTLINE_PRECIS=8,
OUT_SCREEN_OUTLINE_PRECIS=9,
OUT_PS_ONLY_PRECIS=10,
}
publicenumFontClipPrecision:byte
{
CLIP_DEFAULT_PRECIS=0,
CLIP_CHARACTER_PRECIS=1,
CLIP_STROKE_PRECIS=2,
CLIP_MASK=0xf,
CLIP_LH_ANGLES=(1<<4),
CLIP_TT_ALWAYS=(2<<4),
CLIP_DFA_DISABLE=(4<<4),
CLIP_EMBEDDED=(8<<4),
}
publicenumFontQuality:byte
{
DEFAULT_QUALITY=0,
DRAFT_QUALITY=1,
PROOF_QUALITY=2,
NONANTIALIASED_QUALITY=3,
ANTIALIASED_QUALITY=4,
CLEARTYPE_QUALITY=5,
CLEARTYPE_NATURAL_QUALITY=6,
}
[Flags]
publicenumFontPitchAndFamily:byte
{
DEFAULT_PITCH=0,
FIXED_PITCH=1,
VARIABLE_PITCH=2,
FF_DONTCARE=(0<<4),
FF_ROMAN=(1<<4),
FF_SWISS=(2<<4),
FF_MODERN=(3<<4),
FF_SCRIPT=(4<<4),
FF_DECORATIVE=(5<<4),
}
///<summary>
///EnumerationfortherasteroperationsusedinBitBlt.
///InC++theseareactually#define.Buttousethese
///constantswithC#,anewenumerationtypeisdefined.
///</summary>
publicenumTernaryRasterOperations
{
SRCCOPY=0x00CC0020,/*dest=source*/
SRCPAINT=0x00EE0086,/*dest=sourceORdest*/
SRCAND=0x008800C6,/*dest=sourceANDdest*/
SRCINVERT=0x00660046,/*dest=sourceXORdest*/
SRCERASE=0x00440328,/*dest=sourceAND(NOTdest)*/
NOTSRCCOPY=0x00330008,/*dest=(NOTsource)*/
NOTSRCERASE=0x001100A6,/*dest=(NOTsrc)AND(NOTdest)*/
MERGECOPY=0x00C000CA,/*dest=(sourceANDpattern)*/
MERGEPAINT=0x00BB0226,/*dest=(NOTsource)ORdest*/
PATCOPY=0x00F00021,/*dest=pattern*/
PATPAINT=0x00FB0A09,/*dest=DPSnoo*/
PATINVERT=0x005A0049,/*dest=patternXORdest*/
DSTINVERT=0x00550009,/*dest=(NOTdest)*/
BLACKNESS=0x00000042,/*dest=BLACK*/
WHITENESS=0x00FF0062,/*dest=WHITE*/
};
[Flags]
publicenumdwDTFormat:int
{
DT_TOP=0,DT_LEFT=0x00000000,DT_CENTER=0x00000001,DT_RIGHT=0x00000002,
DT_VCENTER=0x00000004,DT_BOTTOM=0x00000008,DT_WORDBREAK=0x00000010,DT_SINGLELINE=0x00000020,
DT_EXPANDTABS=0x00000040,DT_TABSTOP=0x00000080,DT_NOCLIP=0x00000100,DT_EXTERNALLEADING=0x00000200,
DT_CALCRECT=0x00000400,DT_NOPREFIX=0x00000800,DT_INTERNAL=0x00001000
};
publicstructRect
{
publicintLeft,Top,Right,Bottom;
publicRect(Rectangler)
{
this.Left=r.Left;
this.Top=r.Top;
this.Bottom=r.Bottom;
this.Right=r.Right;
}
}
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
publicstructTEXTMETRIC
{
publicInt32tmHeight;
publicInt32tmAscent;
publicInt32tmDescent;
publicInt32tmInternalLeading;
publicInt32tmExternalLeading;
publicInt32tmAveCharWidth;
publicInt32tmMaxCharWidth;
publicInt32tmWeight;
publicInt32tmOverhang;
publicInt32tmDigitizedAspectX;
publicInt32tmDigitizedAspectY;
publicchartmFirstChar;
publicchartmLastChar;
publicchartmDefaultChar;
publicchartmBreakChar;
publicbytetmItalic;
publicbytetmUnderlined;
publicbytetmStruckOut;
publicbytetmPitchAndFamily;
publicbytetmCharSet;
}
相关文章推荐
- 使用C#代码部署SharePoint 2013开发包简单总结(一)
- C# WinForm CheckedListBox 使用的相关简单总结
- C# WinForm CheckedListBox 使用的相关简单总结
- C#学习笔记之使用GDI绘制简单的图形
- C# Quartz.Net 定时任务的简单使用
- 简单实用的DataSet更新数据库的类+总结(c#)
- GDI 总结三: CImage类使用
- c# GDI+简单绘图(一)
- C#中 什么是接口Interface,以及如何简单使用
- C#中return语句使用简单介绍
- hsqldb简单使用总结
- 使用vs2010-C#开发简单语音系统
- C#中ListView的简单使用方法
- 使用C#调用windows API(从其它地方总结来的,以备查询) -转
- Mysql备份与恢复简单总结与tee命令的使用
- 七牛云存储的简单使用总结
- java之ThreadLocal简单使用总结
- ListView 使用方法简单总结
- C#强化系列文章八:HttpModule,HttpHandler,HttpHandlerFactory简单使用
- SQLite简单使用(C# ADO.net)