M
mike.iles
I've seen a number of questions asking how to calculate the height of
a word-wrapped Label control and I haven't seen an answer that uses
DrawText yet, so I thought I would post.
I needed to dynamically lay out a form at runtime, and the problem I
found was that if I placed a Label on the form then I didn't know what
the height should be to account for word-wrapping.
I used the following imports:
[System.Runtime.InteropServices.DllImport("coredll.dll")]
public static extern IntPtr GetDC(IntPtr hwnd);
[System.Runtime.InteropServices.DllImport("coredll.dll")]
public static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);
[System.Runtime.InteropServices.DllImport("coredll.dll")]
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr
gdiObject);
private const int DT_TOP = 0x00000000;
private const int DT_LEFT = 0x00000000;
private const int DT_CENTER = 0x00000001;
private const int DT_RIGHT = 0x00000002;
private const int DT_VCENTER = 0x00000004;
private const int DT_BOTTOM = 0x00000008;
private const int DT_WORDBREAK = 0x00000010;
private const int DT_SINGLELINE = 0x00000020;
private const int DT_EXPANDTABS = 0x00000040;
private const int DT_TABSTOP = 0x00000080;
private const int DT_NOCLIP = 0x00000100;
private const int DT_EXTERNALLEADING = 0x00000200;
private const int DT_CALCRECT = 0x00000400;
private const int DT_NOPREFIX = 0x00000800;
private const int DT_INTERNAL = 0x00001000;
public struct RECT
{
public int Left, Top, Right, Bottom;
public RECT(int left, int top, int right, int bottom)
{
this.Left = left;
this.Top = top;
this.Right = right;
this.Bottom = bottom;
}
}
[System.Runtime.InteropServices.DllImport("coredll.dll")]
public static extern int DrawText(IntPtr hdc, string lpString,
int nCount,
ref RECT lpRect, uint uFormat);
Then (paraphrasing roughly), I did this:
Label label = new Label();
label.Text = text;
label.Location = new Point(...);
label.Width = ...;
IntPtr dc = GetDC(IntPtr.Zero);
SelectObject(dc, label.Font.ToHfont());
RECT rect = new RECT(0, 0, label.Width, 0);
DrawText(dc, text, text.Length, ref rect,
DT_CALCRECT | DT_LEFT | DT_WORDBREAK);
ReleaseDC(IntPtr.Zero, dc);
label.Height = rect.Bottom;
Any issues with this approach?
Mike.
a word-wrapped Label control and I haven't seen an answer that uses
DrawText yet, so I thought I would post.
I needed to dynamically lay out a form at runtime, and the problem I
found was that if I placed a Label on the form then I didn't know what
the height should be to account for word-wrapping.
I used the following imports:
[System.Runtime.InteropServices.DllImport("coredll.dll")]
public static extern IntPtr GetDC(IntPtr hwnd);
[System.Runtime.InteropServices.DllImport("coredll.dll")]
public static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);
[System.Runtime.InteropServices.DllImport("coredll.dll")]
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr
gdiObject);
private const int DT_TOP = 0x00000000;
private const int DT_LEFT = 0x00000000;
private const int DT_CENTER = 0x00000001;
private const int DT_RIGHT = 0x00000002;
private const int DT_VCENTER = 0x00000004;
private const int DT_BOTTOM = 0x00000008;
private const int DT_WORDBREAK = 0x00000010;
private const int DT_SINGLELINE = 0x00000020;
private const int DT_EXPANDTABS = 0x00000040;
private const int DT_TABSTOP = 0x00000080;
private const int DT_NOCLIP = 0x00000100;
private const int DT_EXTERNALLEADING = 0x00000200;
private const int DT_CALCRECT = 0x00000400;
private const int DT_NOPREFIX = 0x00000800;
private const int DT_INTERNAL = 0x00001000;
public struct RECT
{
public int Left, Top, Right, Bottom;
public RECT(int left, int top, int right, int bottom)
{
this.Left = left;
this.Top = top;
this.Right = right;
this.Bottom = bottom;
}
}
[System.Runtime.InteropServices.DllImport("coredll.dll")]
public static extern int DrawText(IntPtr hdc, string lpString,
int nCount,
ref RECT lpRect, uint uFormat);
Then (paraphrasing roughly), I did this:
Label label = new Label();
label.Text = text;
label.Location = new Point(...);
label.Width = ...;
IntPtr dc = GetDC(IntPtr.Zero);
SelectObject(dc, label.Font.ToHfont());
RECT rect = new RECT(0, 0, label.Width, 0);
DrawText(dc, text, text.Length, ref rect,
DT_CALCRECT | DT_LEFT | DT_WORDBREAK);
ReleaseDC(IntPtr.Zero, dc);
label.Height = rect.Bottom;
Any issues with this approach?
Mike.