vbAccelerator - Contents of code file: FileIcon\AutoCompleteTextBoxLib.cs

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace vbAccelerator.Controls.TextBox
{
   /// <summary>
   /// Adds Shell File System and URL AutoCompletion facilities to 
   /// a text box
   /// </summary>
   public class AutoCompleteTextBox : System.Windows.Forms.TextBox 
   {
      #region Unmanaged Code
      /// <summary>
      /// Flags which control FileIcon creation
      /// </summary>
      [Flags]
      public enum SHAutoCompleteFlags : uint
      {
         /// <summary>
         /// Equivalent to (SHACF_FILESYSTEM | SHACF_URLALL)
         /// </summary>
         SHACF_DEFAULT = 0x0,
         /// <summary>
         /// This includes the File System as well as the rest of the 
         /// shell (Desktop\My Computer\Control Panel\)
         /// </summary>
         SHACF_FILESYSTEM = 0x1,
         /// <summary>
         /// Include URLs in the User's History
         /// </summary>
         SHACF_URLHISTORY = 0x2,
         /// <summary>
         /// Include URLs in the User's Recently Used list.
         /// </summary>
         SHACF_URLMRU = 0x4,
         /// <summary>
         /// Use the tab to move thru the autocomplete possibilities instead of 
         /// to the next dialog/window control.
         /// </summary>
         SHACF_USETAB = 0x8,
         /// <summary>
         /// Include all URLs. Equivalent to SHACF_URLHISTORY | SHACF_URLMRU
         /// </summary>
         SHACF_URLALL = (SHACF_URLHISTORY | SHACF_URLMRU),
         /// <summary>
         /// Only include the File System
         /// </summary>
         SHACF_FILESYS_ONLY = 0x10,
         /// <summary>
         /// Same as SHACF_FILESYS_ONLY except it only includes directories, 
         /// UNC servers, and UNC server shares.
         /// </summary>
         SHACF_FILESYS_DIRS = 0x20,
         /// <summary>
         /// Ignore the registry default and force AutoComplete
         /// drop-down to show.
         /// </summary>
         SHACF_AUTOSUGGEST_FORCE_ON = 0x10000000,
         /// <summary>
         /// Ignore the registry default and force AutoComplete
         /// drop-down not to show.
         /// </summary>
         SHACF_AUTOSUGGEST_FORCE_OFF = 0x20000000,
         /// <summary>
         /// Ignore the registry default and force AutoAppend feature on.
         /// </summary>
         SHACF_AUTOAPPEND_FORCE_ON = 0x40000000,
         /// <summary>
         /// Ignore the registry default and force AutoAppend feature off. 
         /// </summary>
         SHACF_AUTOAPPEND_FORCE_OFF = 0x80000000       
      }
      
      [DllImport("shlwapi.dll")]
      private static extern int SHAutoComplete (
         IntPtr hwndEdit, 
         AutoCompleteTextBox.SHAutoCompleteFlags dwFlags );

      #endregion

      #region Member Variables
      private AutoCompleteTextBox.SHAutoCompleteFlags autoCompleteFlags = 
         SHAutoCompleteFlags.SHACF_FILESYS_ONLY;
      private bool flagsSet = false;
      private bool handleCreated = false;
      #endregion

      #region Implementation

      /// <summary>
      /// Gets/sets the flags controlling automcompletion for the 
      /// text box
      /// </summary>
      public AutoCompleteTextBox.SHAutoCompleteFlags AutoCompleteFlags
      {
         get
         {
            return this.autoCompleteFlags;
         }
         set
         {
            this.autoCompleteFlags = value;
            this.flagsSet = true;
            if (handleCreated)
            {
               SetAutoComplete();
            }
         }
      }

      /// <summary>
      /// Called when the text box handle is created.  Used to
      /// initialise AutoCompletion if set prior to handle
      /// creation.
      /// </summary>
      /// <param name="e">Event Arguments</param>
      protected override void OnHandleCreated ( System.EventArgs e )
      {
         // call this first as SHAutoComplete may not be supported
         // on the OS
         base.OnHandleCreated(e);
         // don't do anything if we're in design mode:
         if (!this.DesignMode)
         {
            // remember we've created the handle for any future 
            // get/ set
            handleCreated = true;

            // if we've provided some flags then start autocompletion:
            if (flagsSet)
            {
               SetAutoComplete();
            }
         }
      }

      private void SetAutoComplete()
      {
         SHAutoComplete(this.Handle, this.autoCompleteFlags);
      }

      /// <summary>
      ///  Constructs an auto-complete capable text box but
      ///  does not automatically start auto-completion.
      /// </summary>
      public AutoCompleteTextBox() : base()
      {
      }

      /// <summary>
      /// Constructs an auto-complete capable text box and
      /// starts auto-completion with the specified flags.
      /// </summary>
      /// <param name="autoCompleteFlags">Flags controlling
      /// auto-completion</param>
      public AutoCompleteTextBox(
         AutoCompleteTextBox.SHAutoCompleteFlags autoCompleteFlags
         ) : this()
      {
         // Handle will not be available at this point; we need
         // to wait for HandleCreated:
         this.autoCompleteFlags = autoCompleteFlags;
         this.flagsSet = true;
      }

      #endregion
   }
}