Windows 11下C#程序向Notepad写入文本的代码适配问题
适配Windows 11记事本的C#文本写入解决方案
问题原因
Windows 11记事本新增标签页功能后,内部窗口层级结构发生变化:Windows 10中用于接收文本的Edit控件是记事本主窗口的直接子控件,而Windows 11中该控件被嵌套在NotepadTabs(标签页容器)和RichEditD2DPT(编辑区域容器)两层窗口之下,原代码直接查找主窗口下的Edit控件会返回无效句柄,导致无法写入文本。
修改后的代码
保留原有的DllImport声明,新增逐层查找嵌套Edit控件的辅助方法,再修改按钮点击事件逻辑:
using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading; using System.Windows.Forms; public class YourForm : Form { [DllImport("user32.dll", EntryPoint = "FindWindowEx")] public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); [DllImport("User32.dll")] public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam); private IntPtr FindNestedEditHandle(IntPtr parentHandle) { // 第一步:查找标签页容器窗口 IntPtr tabsContainer = FindWindowEx(parentHandle, IntPtr.Zero, "NotepadTabs", null); if (tabsContainer == IntPtr.Zero) return IntPtr.Zero; // 第二步:查找编辑区域容器窗口 IntPtr editContainer = FindWindowEx(tabsContainer, IntPtr.Zero, "RichEditD2DPT", null); if (editContainer == IntPtr.Zero) return IntPtr.Zero; // 第三步:查找最终的Edit文本控件 return FindWindowEx(editContainer, IntPtr.Zero, "Edit", null); } private void btnShowLog_Click(object sender, EventArgs e) { Process notepad = Process.Start("notepad.exe"); notepad.WaitForInputIdle(); // 循环查找Edit控件,最多重试30次(避免控件未加载完成) IntPtr editHandle = IntPtr.Zero; int retryCount = 0; while (editHandle == IntPtr.Zero && retryCount < 30) { Thread.Sleep(300); editHandle = FindNestedEditHandle(notepad.MainWindowHandle); retryCount++; } if (editHandle != IntPtr.Zero) { const int WM_SETTEXT = 0x000C; SendMessage(editHandle, WM_SETTEXT, 0, txbLog.Text); } else { MessageBox.Show("无法定位记事本的文本编辑控件"); } } }
注意事项
- 窗口类名适配:若部分Windows 11版本的记事本窗口类名有细微差异,可使用Windows自带的**Spy++**工具(Visual Studio工具集内)查看记事本的窗口层级结构,获取准确的容器类名。
- 等待逻辑:增加循环重试和延迟,确保记事本完全加载所有控件后再进行查找,避免因控件未初始化导致查找失败。
内容的提问来源于stack exchange,提问作者Daelian
相关产品推荐
相关产品推荐

