Selecting Control Text#

Last year I wrote a post on selecting text in a textbox control in two parts.  You can find Part 1 here and Part 2 here.  Another question came up in the news groups on selecting the text of a NumericUpDown control.  Again sounds straight forward since the full .NET framework supports UpDownBase.Select.  To get this functionality requires a little bit of work but is possible. 

Basically to send a message to a control you have to PInvoke SendMessage in coredll.dll (user32.dll for the desktop).  Here is the signature for that:

[DllImport("coredll.dll", SetLastError = true)]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);

To tell the control to select the text, the int msg parameter should be EM_SETSEL which is defined as follows:

private const int SETSEL = 0x00B1;

Now putting all together.  Using Visual Studio 2005 we can create a class called NumericUpDownWithSelect and override the OnGotFocus method.  Here is the implementation

protected override void OnGotFocus(EventArgs e)
{
     base.OnGotFocus(e);

     if (!this.suppressOnGotFocus)
     {
          ThreadStart t = delegate()
          {
               this.Invoke(new SelectAllInvoke(SelectAll));
          };
     new Thread(t).Start();
}

You will notice we are using an anonymous method to invoke the SelectAll Method on the main thread.  Here is the delegate signature and the implementation of SelectAll() and Select():

private delegate void SelectAllInvoke();
public void SelectAll()
{
     this.SelectInternal(0, this.Value.ToString().Length);
}

public void Select(int start, int length)
{
     this.SelectInternal(start, length);
}

SelectInternal() is the code that does the actual work. 

private void SelectInternal(int start, int length)
{
     this.suppressOnGotFocus = true;
     if (!this.Focused)
          this.Focus();
     IntPtr ret = SendMessage(this.Handle, SETSEL, start, length);
     this.suppressOnGotFocus = false;
}

So putting it all together in a nice class that inherits from System.Windows.Forms.NumericUpDown you can extend the functionality of the base class.  Here is the full implementation:

public class NumericUpDownWithSelect : NumericUpDown
{
     public NumericUpDownWithSelect()
     {
     }

     [DllImport("coredll.dll", SetLastError = true)]
     private static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);

     private const int GETSEL = 0x00B0;
     private const int SETSEL = 0x00B1;

     private delegate void SelectAllInvoke();

     private bool suppressOnGotFocus = false;

     protected override void OnGotFocus(EventArgs e)
     {
          base.OnGotFocus(e);
          if (!this.suppressOnGotFocus)
          {
               ThreadStart t = delegate()
               {
                    this.Invoke(new SelectAllInvoke(SelectAll));
               };
               new Thread(t).Start();
          }
     }

     public void SelectAll()
     {
          this.SelectInternal(0, this.Value.ToString().Length);
     }

     public void Select(int start, int length)
     {
          this.SelectInternal(start, length);
     }

     private void SelectInternal(int start, int length)
     {
          this.suppressOnGotFocus = true;
          if (!this.Focused)
               this.Focus();
          IntPtr ret = SendMessage(this.Handle, SETSEL, start, length);
          this.suppressOnGotFocus = false;
     }
}

Download the binaries here: NumericUpDownWithSelect_Binaries.zip (3.67 KB) 


Tuesday, January 17, 2006 12:15:32 PM (Eastern Standard Time, UTC-05:00) #    Comments [8]  | 

 

All content © 2010, Mark Arteaga
On this page
Related Sites
Archives
Sitemap
Disclaimer

Powered by: newtelligence dasBlog 1.9.7174.0

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

Send mail to the author(s) E-mail

Theme design by Jelle Druyts