When developing a WinForm control, you usually need to measure the actual size when text drawn. The GDI class in the .NET FCL --system.drawing.graphics provides the MeasureString method for the above needs, which returns a result of the floating point number of the Sizef structure, which seems very accurate from the surface, but in actual In use, it is found that this method does not accurately measure the actual width of the text. I have repeatedly compiled system.drawing.dll, but I didn't see what the name is coming. If you use GDI, you can measure the actual drawing width of the text well, the following provides the C # implementation source code for calling GDI Win32API for reference. Note: WindowsAPI in the code is a custom class, which is packaged in most Win32API calls C # definitions. ///
// Measure the font of the font used INTPTR FONTHANDLE = font.tohfont ();
// Add the font used in the measurement to the device context // and record the font used in the original INTPTROLDHFONT = Windowsapi.selectObject (HDC, FontHandle);
// RECT is used for Win32API calls, and Retangle in .NET FCL does not apply to Win32API calls. // The definition is as follows: // [StructLayout (layoutkind.sequential] // This is necessary. // public struct rest // {// public int {; // public int right; // public int →}
// Create a Rect Rect Rect Rect = New Rect () required for a GDI Win32API call; Rect.Top = rc.right; Rect.top = rc.top; Rect.bottom = RC. Bottom; // Text Drawing Format Sign Definition: // Public Enum DrawTextFormatFlags // {// DT_TOP = 0x00000000, // DT_EFT = 0x000000000000000, // 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 = 0x0000001000, // dt_EDitcontrol = 0x00002000, // DT_PATH_ELLIPSIS = 0x00004000, // DT_END_ELLIPSIS = 0x000 08000, // dt_modifystring = 0x00010000, // dt_rtlreaming = 0x00020000, // dt_word_llipsis = 0x00040000 //}
// Call GDI Win32API to measure the actual plot of the text. Windowsapi.drawtext (HDC, Text, Text.length, Ref RECT, (INT));
// Reset to the original font, this is GDI must. Windowsapi.selectObject (HDC, Oldhfont);
// Delete the created measurement font handle Windowsapi.DeleteObject (fonthandle);
/ / Release the acquired device context handle if (graphics! = Null) graphics.releaseHDC (HDC); Else WindowsApi.releaseDC (INTPTR.ZERO, HDC); // Return the measured results Return New size (Rect.right - Rect. LEFT, Rect.Bottom - Rect.top);
The following is three useful overload 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) Set a text draw format, measured in a single line. DrawTextFormatflags DrawFlags = DrawTextFormatFlags.dt_singLine | DrawTextFormatFlags.dt_left | DrawTextFormatFlags.dt_calcRect; // This flag indicates 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);}