using System; using System.Runtime.InteropServices; using System.Windows.Forms; namespace TfsExcelImporter { /// /// 输入框空态占位文字(cue banner)。net48 的 TextBox 没有 PlaceholderText, /// 用原生 EM_SETCUEBANNER 实现;ComboBox(DropDown)要发给它内嵌的 Edit 子窗口, /// 直接发给组合框本体无效。文字只在输入框为空时显示,与 Web 表单 placeholder 手感一致。 /// internal static class CueBanner { private const int EM_SETCUEBANNER = 0x1501; private const uint GW_CHILD = 5; [DllImport("user32.dll", CharSet = CharSet.Unicode)] private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, string lParam); [DllImport("user32.dll")] private static extern IntPtr GetWindow(IntPtr hWnd, uint cmd); /// 设置占位文字。控件句柄可能尚未创建,挂 HandleCreated 兜底; /// wParam=1 让占位文字在聚焦时也显示(有真实输入后自然消失)。 public static void Set(Control c, string text) { if (c == null || string.IsNullOrEmpty(text)) return; Action apply = () => Send(c, text); if (c.IsHandleCreated) apply(); c.HandleCreated += (s, e) => apply(); } private static void Send(Control c, string text) { IntPtr target = c.Handle; if (c is ComboBox) { // DropDown 组合框的内嵌 Edit 子窗口:cue banner 只认它 target = GetWindow(c.Handle, GW_CHILD); if (target == IntPtr.Zero) return; } SendMessage(target, EM_SETCUEBANNER, (IntPtr)1, text); } } }