Monday, August 29, 2005

I've made a few updates to the code I'd posted last time mainly by moving the text wrapping functionality inside of the ToolTip control, therefore making it more self contained and useful for other scenarious. I optimized the MeasureStringExtend function to use StringBuilder and improving its speed by 50-70%. Here's the new version:

private SizeF MeasureStringExtend(Graphics g, string text, Font font, int desWidth)

{

      int sp_pos = 0;

      int line = 0;

      int nWidth = 0;

      StringBuilder sb = new StringBuilder();

 

      //get original size

      SizeF size = g.MeasureString(text, font);

 

      if (size.Width > desWidth)

      {

            string[] words = text.Split(' ');

            for (int i = 0; i < words.Length; i++)

            {

                  sb.Append(words[i] + " ");

                  nWidth = (int)g.MeasureString(sb.ToString(), font).Width;

 

                  if (nWidth > desWidth)

                  {

                        //try to find a space

                        sp_pos = sb.ToString().LastIndexOf(" ");

                        if (sp_pos > 0)

                        {

                              //cut out the wrap line we've found

                              sb.Remove(0, sb.Length);

                              sb.Append(words[i] + " ");

                              line++;

                        }

                        else //no space

                        {

                              sb.Remove(0, sb.Length);

                              line++;

                        }

                  }

            }

            // Check for the last line

            if (sb.Length > 0)

            {

                  line++;

            }

      }

      else

      {

            line++;

      }

 

      return new SizeF(desWidth, (line * size.Height));

}

 

I've also created a VS 2005 and CF v2 version of the ListViewExtender and ListViewLabel classes. Instead of ApplicationEx and IMessageFilter I utilized my NativeWindow implementation. Here's the ListViewSubclass class, the sole purpose of which to catch the WM_LBUTTONDOWN message and raise the MouseDown event:

public class ListViewSubclass : NativeWindow

{

      public event MouseEventHandler MouseDown;

 

      private const int WM_LBUTTONDOWN = 0x0201;

      private ListView listView;

 

      public ListViewSubclass(ListView listView)

      {

            this.listView = listView;

            this.AssignHandle(listView.Handle);

      }

 

      protected override void WndProc(ref Message m)

      {

            if (m.Msg == WM_LBUTTONDOWN)

            {

                  int y = HiWord((int)m.LParam);

                  int x = LoWord((int)m.LParam);

                  MouseEventArgs args = new MouseEventArgs(0, 1, x, y, 0);

                  if (MouseDown != null)

                  {

                        MouseDown(listView, args);

                  }

            }

            base.WndProc(ref m);

      }

 

      private static int HiWord(int number)

      {

            if ((number & 0x80000000) == 0x80000000)

                  return (number >> 16);

            else

                  return (number >> 16) & 0xffff;

      }

 

      private static int LoWord(int number)

      {

            return number & 0xffff;

      }

}

Download the updated VS 2003 version from here.

ListViewToolTip2003.zip (10.08 KB)

And here's the VS 2005 version for your pleasure:

ListViewToolTip2005.zip (14.25 KB)

 

 

8/29/2005 4:40:50 PM (GMT Daylight Time, UTC+01:00)  #     |