Jeżeli starałeś się zbudować dynamiczne GUI w .NET Compact Framework, prawdopodobnie zauważyłeś niedostatek metody MeasureString z parametrem SizeF.
W .NET CF, Graphics ma tylko jedną metodę mierzenia napisów:
///
/// Measures the specified string when drawn with the specified Font.
///
public SizeF MeasureString(string text, Font font);
Dla długiego napisu w którym nie ma znaków łamania powyższa metoda zwraca kosmicznie długi rozmiar.
Jeżeli pisałeś wcześniej w wersji desktopowej to pewnie zauważyłeś, że jest wersja tej metody z parametrem SizeF, który określa docelowy rozmiar w który napis będzie wpasowywany i łamany. Obejściem tego problemu jest poniższy class extension na Graphicsa, który przyjmuje parametr Rectangle jako prostokąt do wpasowania napisu.
internal static class GraphicExtensions
{
private struct Rect
{
public int Left;
public int Top;
public int Right;
public int Bottom;
public Rect(Rectangle r)
{
Left = r.Left;
Top = r.Top;
Bottom = r.Bottom;
Right = r.Right;
}
}
public static SizeF MeasureString(this Graphics graphic, string text, Font font, Rectangle rectangle)
{
Rect bounds = new Rect(rectangle);
IntPtr hFont = font.ToHfont();
IntPtr hDc = graphic.GetHdc();
IntPtr originalObject = SelectObject(hDc, hFont);
DrawText(hDc, text, text.Length, ref bounds, DT_CALCRECT | DT_WORDBREAK);
SelectObject(hDc, originalObject);
graphic.ReleaseHdc(hDc);
return new SizeF(bounds.Right - bounds.Left, bounds.Bottom - bounds.Top);
}
private static int DT_CALCRECT = 0x00000400;
private static int DT_WORDBREAK = 0x00000010;
[DllImport("coredll.dll")]
private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);
[DllImport("coredll.dll")]
private static extern int DrawText(IntPtr hdc, string lpStr, int nCount, ref Rect lpRect, int wFormat);
}







One ResponseLeave one →
Leave a Reply