| |
Reading requirements: understand the basic principles and operation methods of C # Calling WIN32API When developing the winform control, you usually need to measure the actual size of the text during plotting. . The GDI + class in net FCL -- system. drawing. graphics provides the measurestring method used in the preceding steps. This method returns the result of a floating point number representation of the sizef structure, which appears to be accurate on the surface, however, in actual use, it is found that sometimes this method cannot accurately measure the actual width of the text. We also decompiled system. Drawing. dll, but we didn't see any details. If you can use GDI to measure the actual width of the text, the following provides the C # implementation that calls the GDI WIN32API for measurement.Source codeFor reference. Note: windowsapi in Code is a custom class that encapsulates C # definitions of most WIN32API calls. /// // within the specified rectangle, the format is specified, measure the actual drawing size of the text. /// /// Drawing Object /// measured text // measurement font // area to be drawn in a rectangle // text format /// size Public static size gettextsize (Graphics graphics, string text, Font font, rectangle RC, drawtextformatflags drawflags) {< br> // A Record Device Context handle variable intptr HDC = intptr. Zero; If (graphics! = NULL) {< br> // obtain the device context handle associated with the provided graphics HDC = graphics. gethdc (); }< br> else {< br> // If graphics is not provided, use the screen as the device context HDC = windowsapi. getdc (intptr. zero); }// Handle of the font used for measurement Intptr fonthandle = font. tohfont (); // Add the measurement font to the device context // Record the original font Intptr oldhfont = windowsapi. SelectObject (HDC, fonthandle ); // Rect is used for WIN32API call. The retangle in. Net FCL is not applicable to WIN32API call. // Its definition is as follows: // // [Structlayout (layoutkind. Sequential)] // This is required. // Public struct rect //{ // Public int left; // Public int top; // Public int right; // Public int bottom; //} // Create a rect instance required for calling the GDI WIN32API Rect = new rect (); Rect. Left = RC. Left; Rect. Right = RC. Right; Rect. Top = RC. Top; Rect. Bottom = RC. bottom; // Enumeration definition of text-drawn format flag: // 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 //} // Call the GDI WIN32API to measure the actual drawing size of the text. Windowsapi. drawtext (HDC, text, text. length, ref rect, (INT) (drawflags | drawtextformatflags. dt_calcrect )); // Reset it to the original font, which is required by GDI. Windowsapi. SelectObject (HDC, oldhfont ); // Delete the font handle of the created measurement. Windowsapi. deleteobject (fonthandle ); // Release the obtained device context handle If (graphics! = NULL) Graphics. releasehdc (HDC ); Else Windowsapi. releasedc (intptr. Zero, HDC ); // Return the measured result Return new size (rect. Right-rect. Left, rect. Bottom-rect. Top ); } The following are three useful methods for overloading: 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 drawing format, which is measured in the left alignment of a single row. Drawtextformatflags drawflags = Drawtextformatflags. dt_singleline | Drawtextformatflags. dt_left | Drawtextformatflags. dt_calcrect; // this flag indicates that you want 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 ); } |