using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Windows.Forms; using Vanara.InteropServices; using Vanara.PInvoke; using static Vanara.PInvoke.Shell32; using static Vanara.PInvoke.User32; namespace Vanara.Extensions { /// Extension methods for . public static partial class TextBoxExtension { /// Sets the textual cue, or tip, that is displayed by the edit control to prompt the user for information. /// The text box. /// A string that contains the text to display as the textual cue. /// if set to true the cue banner should show even when the edit control has focus. /// Must be Windows Vista or later. public static void SetCueBanner(this TextBox textBox, string cueBannerText, bool retainOnFocus = false) { if (Environment.OSVersion.Version.Major >= 6) { SendMessage(textBox.Handle, (uint)EditMessage.EM_SETCUEBANNER, new IntPtr(retainOnFocus ? 1 : 0), cueBannerText); textBox.Invalidate(); } else throw new PlatformNotSupportedException(); } /// Sets a custom automatic complete list. /// The text box. /// The autocomplete strings. /// The autocomplete options. public static void SetCustomAutoCompleteList(this TextBox textBox, IList items, AUTOCOMPLETEOPTIONS options = AUTOCOMPLETEOPTIONS.ACO_AUTOSUGGEST) { var ac = new IAutoComplete2(); ac.Init(textBox.Handle, new ComEnumStringImpl(items), null, null); ac.SetOptions(options); Marshal.ReleaseComObject(ac); } /// Sets the tab stops in a multiline edit control. When text is copied to the control, any tab character in the text causes space to be generated up to the next tab stop. /// The text box. /// An array of unsigned integers specifying the tab stops, in dialog template units. If this parameter is not supplied, default tab stops are set at every 32 dialog template units. If a single value is provided, this value is the distance between all tab stops, in dialog template units. If two or more values are provided, each value represents a tab stop in dialog template units. public static void SetTabStops(this TextBox textBox, params uint[] tabs) { if (tabs == null) tabs = new uint[0]; using (var ptr = SafeCoTaskMemHandle.CreateFromList(tabs)) SendMessage(textBox.Handle, (uint)EditMessage.EM_SETTABSTOPS, (IntPtr)tabs.Length, (IntPtr)ptr); textBox.Invalidate(); } private class ComEnumStringImpl : IEnumString { private readonly IList list; private int cur; public ComEnumStringImpl(IList items) { list = items; } void IEnumString.Clone(out IEnumString ppenum) { ppenum = new ComEnumStringImpl(list) { cur = cur }; } int IEnumString.Next(int celt, string[] rgelt, IntPtr pceltFetched) { if (celt < 0) return -2147024809; var idx = 0; while (cur < list.Count && celt > 0) { rgelt[idx] = list[cur]; idx++; cur++; celt--; } if (pceltFetched != IntPtr.Zero) Marshal.WriteInt32(pceltFetched, idx); return celt == 0 ? 0 : 1; } void IEnumString.Reset() { cur = 0; } int IEnumString.Skip(int celt) => (cur += celt) >= list.Count ? 1 : 0; } } }