NET, use GDI to accurately measure the actual drawing dimensions of text (C #)

Source: Internet
Author: User
Read requirements: Understand the basic principles and practices of C # call Win32API
--------------------------------------------------------------------------------


When you develop a WinForm control, you usually need to measure the actual size of the text when it is drawn.
The GDI + Class--system.drawing.graphics in. NET FCL provides the MeasureString method for the above needs, which returns the result of a floating point representation of a SizeF structure that appears to be accurate on the surface, However, it is found that sometimes this method does not accurately measure the actual width of the text in practical use.
Also decompile System.Drawing.Dll, but did not see anything.
If using GDI is a good measure of the actual drawing width of the text, the following provides a C # implementation source code to be measured by invoking the GDI Win32API for reference.

Note: The WINDOWSAPI in the code is a custom class that wraps the C # definition of most WIN32API calls.

<summary>
Measures the actual plotting dimensions of the text in the specified rectangular area, in the specified format.
</summary>
<param name= "Graphics" > Drawing objects </param>
<param name= "text" > measured text </param>
<param name= "Font" > Measuring font </param>
<param name= "RC" > Rectangle to Draw area </param>
<param name= "Drawflags" > Text Format </param>
<returns> Dimensions </returns>
public static Size GetTextSize (Graphics Graphics, string text, font font, Rectangle RC, Drawtextformatflags drawflags)
{
A variable that records the device context handle
INTPTR hdc = IntPtr.Zero;

if (graphics!= null)
{
Gets the device context handle associated with the supplied Graphics
HDC = Graphics. GetHdc ();
}
Else
{
If Graphics is not provided, use the screen as the device context
HDC = WINDOWSAPI.GETDC (IntPtr.Zero);
}

To measure the handle of the font used
IntPtr fonthandle = font. Tohfont ();

Add the font used for measurement to the device context
and record the original font used
IntPtr Oldhfont = Windowsapi.selectobject (hdc, fonthandle);


RECT is used for WIN32API calls, Retangle in. NET FCL does not apply to WIN32API calls.
The definition is as follows:
//
[StructLayout (LayoutKind.Sequential)]//This is a must.
public struct RECT
// {
public int left;
public int top;
public int right;
public int bottom;
// }


Create a RECT instance required for a GDI Win32API call
RECT RECT = new RECT ();
Rect.left = RC. Left;
Rect.right = RC. right;
Rect.top = RC. Top;
Rect.bottom = RC. Bottom;


Enumeration definition for text drawing format flags:
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
// }

Invokes the GDI Win32API to measure the actual drawing time dimensions of the text.
Windowsapi.drawtext (hdc, text, text.) Length, ref rect,
(int) (Drawflags | Drawtextformatflags.dt_calcrect));

Reset to the original font, which is required by GDI.
Windowsapi.selectobject (hdc, Oldhfont);

Remove the handle of the created measurement font
Windowsapi.deleteobject (Fonthandle);

Frees the acquired device context handle
if (graphics!= null)
Graphics. RELEASEHDC (HDC);
Else
Windowsapi.releasedc (IntPtr.Zero, HDC);

Return to measured results
return new Size (Rect.right-rect.left, rect.bottom-rect.top);
}


Here are three useful overloaded methods:

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)
{
Sets a text drawing format that is measured in a single left alignment.
Drawtextformatflags drawflags =
Drawtextformatflags.dt_singleline |
Drawtextformatflags.dt_left |
Drawtextformatflags.dt_calcrect; This sign means to measure

Rectangle rect = rectangle.empty;

Return GetTextSize (graphics, text, font, rect, drawflags);
}

public static Size GetTextSize (string text, font font)
{
return gettextsize (null, text, font);
}




Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.