欢迎光临
我们一直在努力

NET 中,使用 GDI 来精确测量文本的实际绘出尺寸(C#)-.NET教程,C#语言

建站超值云服务器,限时71元/月

阅读要求:了解 c# 调用 win32api 的基本原理和操作方式

——————————————————————————–

在开发 winform 控件时,通常需要测量文本绘出时的实际尺寸。

.net fcl 中的 gdi+ 类——system.drawing.graphics 提供了用于上述需要的 measurestring 方法,该方法返回了一个 sizef 结构的浮点数表示的结果,从表面上看起来似乎很精确,但在实际使用中发现有时此方法并不能精确测量出文本的实际宽度。

也曾反编译 system.drawing.dll,但没看出什么名堂来。

如果使用 gdi 却能很好地测量出文本的实际绘出宽度,下面提供了调用 gdi win32api 来测量的 c# 实现源代码,以供参考。

注: 代码中的 windowsapi 是一个自定义类,包装了大部分 win32api 调用的 c# 定义。

/// <summary>

/// 在指定的矩形区域内,按照指定的格式,测量文本的实际绘出尺寸。

/// </summary>

/// <param name="graphics">绘图对象</param>

/// <param name="text">被测量的文本</param>

/// <param name="font">测量所用字体</param>

/// <param name="rc">以矩形表示的要绘制区域</param>

/// <param name="drawflags">文本格式</param>

/// <returns>尺寸</returns>

public static size gettextsize(graphics graphics, string text, font font, rectangle rc, drawtextformatflags drawflags)

{

// 一个记录设备上下文句柄的变量

intptr hdc = intptr.zero;

if ( graphics != null )

{

// 获取与提供的 graphics 关联的设备上下文句柄

hdc = graphics.gethdc();

}

else

{

// 如果未提供 graphics,使用屏幕作为设备上下文

hdc = windowsapi.getdc(intptr.zero);

}

// 测量所用字体的句柄

intptr fonthandle = font.tohfont();

// 将测量所用字体添加到设备上下文

// 并记录原来所使用的字体

intptr oldhfont = windowsapi.selectobject(hdc, fonthandle);

// rect 用于 win32api 调用,.net fcl 中的 retangle 不适用于 win32api 调用。

// 其定义如下:

//

// [structlayout(layoutkind.sequential)] // 这是必须的。

// public struct rect

// {

// public int left;

// public int top;

// public int right;

// public int bottom;

// }

// 创建一个 gdi win32api 调用所需的 rect 实例

rect rect = new rect();

rect.left = rc.left;

rect.right = rc.right;

rect.top = rc.top;

rect.bottom = rc.bottom;

// 文本绘制格式标志的枚举定义:

// public enum drawtextformatflags

// {

// dt_top = 0x00000000,

// 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,

// dt_editcontrol = 0x00002000,

// dt_path_ellipsis = 0x00004000,

// dt_end_ellipsis = 0x00008000,

// dt_modifystring = 0x00010000,

// dt_rtlreading = 0x00020000,

// dt_word_ellipsis = 0x00040000

// }

// 调用 gdi win32api 以测量文本的实际绘出时尺寸。

windowsapi.drawtext(hdc, text, text.length, ref rect,

(int)(drawflags | drawtextformatflags.dt_calcrect));

// 重设为原来的字体,这是 gdi 必须的。

windowsapi.selectobject(hdc, oldhfont);

// 删除创建的测量用字体的句柄

windowsapi.deleteobject(fonthandle);

// 释放已获取的设备上下文句柄

if ( graphics != null )

graphics.releasehdc(hdc);

else

windowsapi.releasedc(intptr.zero, hdc);

// 返回实测结果

return new size(rect.right – rect.left, rect.bottom – rect.top);

}

以下是三个有用的重载方法:

public static size gettextsize(string text, font font, rectangle rc, drawtextformatflags drawflags)

{

return gettextsize(null, text, font, rc, drawflags);

}

public static size gettextsize(graphics graphics, string text, font font)

{

// 设置一个文本绘制格式,以单行左对齐方式来测量。

drawtextformatflags drawflags =

drawtextformatflags.dt_singleline |

drawtextformatflags.dt_left |

drawtextformatflags.dt_calcrect; // 这个标志表示要测量

rectangle rect = rectangle.empty;

return gettextsize(graphics, text, font, rect, drawflags) ;

}

public static size gettextsize(string text, font font)

{

return gettextsize(null, text, font);

}

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » NET 中,使用 GDI 来精确测量文本的实际绘出尺寸(C#)-.NET教程,C#语言
分享到: 更多 (0)