使用C# / Win32将文本写入记事本

16

我正在研究Win32 API和Windows消息传递,尝试弄清楚它们的工作原理,我发现这个问题非常有帮助

我想改进那里提供的解决方案,使其附加文本,而不仅是通过WM_SETTEXT替换记事本中的文本。

我的问题是,如何使用WM_GETTEXTLENGHT,接着是WM_GETTEXT,获取记事本窗口中的当前文本,以便在使用WM_SETTEXT之前将新文本附加到其中?

使用WM_XXXTEXT在32位和64位机器上都有效吗?如果记事本中有很多文本,所提出的获取/设置算法仍然有效,还是会占用大量资源?如果是,是否有另一种方法可以将文本附加到记事本窗口而无需首先复制其中所有内容?

感谢您的帮助!

更新:

基于David Heffernan的帮助和Google/SO复制粘贴,这是我想出的代码。由于我对Win32API很新,并从不同的来源复制了许多行,因此我会感激任何反馈。

[DllImport("User32.dll", CharSet = CharSet.Auto)]
        extern static IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, [In] string lpClassName, [In] string lpWindowName);

        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        extern static int SendMessageGetTextLength(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

        [DllImport("User32.dll")]
        public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);

        [DllImport("User32.dll")]
        public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, int lParam);

        const int WM_GETTEXTLENGTH = 0x000E;

        const int EM_SETSEL = 0x00B1;

        const int EM_REPLACESEL = 0x00C2;

        public void testAppendText(string text)
        {
            Process[] notepads = Process.GetProcessesByName("notepad");
            if (notepads.Length == 0) return;
            if (notepads[0] != null)
            {
                IntPtr editBox = FindWindowEx(notepads[0].MainWindowHandle, new IntPtr(0), "Edit", null);
                int length = SendMessageGetTextLength(editBox, WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero);
                SendMessage(editBox, EM_SETSEL, length, length);
                SendMessage(editBox, EM_REPLACESEL, 1, text);
            }

        } 
1个回答

10

发送EM_SETSEL以将插入点移动到编辑窗口的末尾。然后发送EM_REPLACESEL以追加文本。

如果编辑控件包含大量文本,则这比读取整个内容、添加您的附加内容,然后设置整个内容要好得多。

这些方法可以轻松跨越32/64位进程边界。


EM_SETSEL和/或EM_REPLACESEL需要窗口焦点吗? - Evan
1
它似乎不需要焦点,我会根据你的解决方案更新我的问题所使用的代码。感谢你的帮助! - Evan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接