headkaze Posted September 5, 2006 Posted September 5, 2006 Hi, my first post to the boards so hello! :) I've written a class that will auto size the height of a label based on the text inside. It works fine for normal text, but if I make the text bold it seems to ignore that it's bold and still measure the label as if it was regular text. This means it won't resize the label properly. I have to have this working for bold text! Does anyone have any ideas how I can modify it to work with bold text? public class clsAutoSizeLabel { [DllImport("gdi32.dll")] private static extern bool DeleteObject(IntPtr hObject); [DllImport("user32.dll")] private static extern int DrawText(IntPtr hDC, string lpString, int nCount, ref RECT lpRect, uint uFormat); [DllImport("gdi32.dll")] private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj); private struct RECT { public int Left; public int Top; public int Right; public int Bottom; } private const int DT_CALCRECT = 0x400; private const int DT_WORDBREAK = 0x10; public static void AutoSizeLabelHeight(Label ctlLabel) { RECT uRECT; uRECT.Left=0; uRECT.Top=0; uRECT.Right=0; uRECT.Bottom=0; try { Graphics objGraphics = ctlLabel.CreateGraphics(); IntPtr hDc = objGraphics.GetHdc(); IntPtr hFont = ctlLabel.Font.ToHfont(); IntPtr hFontOld = SelectObject(hDc, hFont); uRECT.Right = ctlLabel.Width - 4; if(DrawText(hDc, ctlLabel.Text, -1, ref uRECT, DT_CALCRECT | DT_WORDBREAK) != 0) ctlLabel.Height = uRECT.Bottom + 4; SelectObject(hDc, hFontOld); DeleteObject(hFont); objGraphics.ReleaseHdc(hDc); objGraphics.Dispose(); } catch { } } } Here is an example of how I would call the method. If I change it from bold to regular the measurement is the same. myLabel.Font = new System.Drawing.Font("Verdana", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); myLabel.Location = new System.Drawing.Point(168, 8); myLabel.Name = "myLabel"; myLabel.Size = new System.Drawing.Size(432, 32); myLabel.Text = "This is the text inside the label, but it dosn't seem to work properlly when I use bold!"; myLabel.BackColor = System.Drawing.Color.Blue; // set background to blue so we can see the sizing properly clsAutoSizeLabel.AutoSizeLabelHeight(myLabel); this.Controls.Add(myLabel); Quote
headkaze Posted September 7, 2006 Author Posted September 7, 2006 Found the solution to this problem... changed the following line: myLabel.Font = new System.Drawing.Font("Verdana Bold", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); Notice, the name of the font is now "Verdana Bold". It seems you need to specify bold in the name for it to measure a bold font properly :rolleyes: Quote
Leaders snarfblam Posted September 7, 2006 Leaders Posted September 7, 2006 Just out of curiousity, why GDI instead of GDI+? Quote [sIGPIC]e[/sIGPIC]
headkaze Posted September 8, 2006 Author Posted September 8, 2006 Just out of curiousity' date=' why GDI instead of GDI+?[/quote'] What would the GDI+ equivelent of this class be? Of course if I could write this class using GDI+ and even the System.Drawing.Graphics namespace using pure managed code I would. As far as I know there is no method in managed code that can measure multi-line text. Please correct me if I'm wrong. Quote
Cags Posted September 8, 2006 Posted September 8, 2006 Heres a quick test I knocked up, it seems to work ok. You should be able to adopt this technique to create an inherited control if you wish. // init vars Graphics g = this.CreateGraphics(); string testString = "This is a test to see if the graphics object measurestring works."; int maxWidth = 30; Font testFont = new Font("Tahoma", 12); StringFormat sf = new StringFormat(); // measure string SizeF stringSize = g.MeasureString(testString, testFont, maxWidth, sf); // create label and add to form Label myLbl = new Label(); myLbl.Text = testString; myLbl.Size = new Size(maxWidth, stringSize.Height); this.Controls.Add(myLbl); Quote Anybody looking for a graduate programmer (Midlands, England)?
headkaze Posted September 8, 2006 Author Posted September 8, 2006 (edited) Heres a quick test I knocked up' date=' it seems to work ok. You should be able to adopt this technique to create an inherited control if you wish.[/quote'] Works great and in managed code, thanks for that mate! :) Here's the class in managed code: public class AutoSizeLabel { public static void AutoSizeLabelHeight(Label ctlLabel) { Graphics g = ctlLabel.CreateGraphics(); Font font = new Font(ctlLabel.Font.Name, ctlLabel.Font.Size); StringFormat sf = new StringFormat(); SizeF stringSize = g.MeasureString(ctlLabel.Text, font, ctlLabel.Width, sf); ctlLabel.Height = (int) stringSize.Height + 2; g.Dispose(); } } Edited September 8, 2006 by headkaze Quote
Leaders snarfblam Posted September 8, 2006 Leaders Posted September 8, 2006 Much, much easier on the eyes. Quote [sIGPIC]e[/sIGPIC]
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.