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

发布于 2024-11-18 17:03:47 字数 1933 浏览 2 评论 0原文

我正在摆弄 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);
            }

        } 

I'm messing around with Win32 API and windows messaging trying to figure out how things work and I found this question very helpful.

I'd like to improve upon the solution provided there so that it appends the text instead of just replacing the text in notepad via WM_SETTEXT.

My question is, how would I use WM_GETTEXTLENGHT, followed by WM_GETTEXT, to get the current text in the notepad window so I could then append new text to it before using WM_SETTEXT?

Does using WM_XXXTEXT work on both 32 and 64-bit machines? If there is a lot of text in notepad would the proposed get/set algorithm still work or would it hog a bunch of resources? If so, is there another way to append text to the notepad window without copying everything in it first?

Thanks for you help!!

UPDATE:

Here is the code I came up with based on David Heffernan's help and Google/SO cut n pasting. As I'm new to the Win32API and copied many lines from different sources I'd appreciate any and all feedback.

[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);
            }

        } 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧情别恋 2024-11-25 17:03:47

发送 EM_SETSEL 将插入符号置于编辑窗口的末尾。然后发送 EM_REPLACESEL 以附加文本。

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

这些方法可以毫无困难地跨越 32/64 位进程边界。

Send EM_SETSEL to put the caret to the end of the edit window. Then send EM_REPLACESEL to append text.

This is much better than reading the entire contents, appending your addition and then setting the entire contents if the edit control contains a large amount of text.

These methods can cross 32/64 bit process boundaries without difficulty.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文