记事本字符解码

我正在阅读由我的程序打开的记事本中的文本,这是我的代码

const int WM_GETTEXT = 0x000D; const int WM_GETTEXTLENGTH = 0x000E; [DllImport("User32.dll", EntryPoint = "SendMessage")] extern static int SendMessageGetTextLength(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); [DllImport("User32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] extern static IntPtr SendMessageGetText(IntPtr hWnd, int msg, IntPtr wParam, [Out] StringBuilder lParam); [DllImport("user32.dll", EntryPoint = "FindWindowEx")] public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); public static string GetText(IntPtr hwnd) { if (hwnd == IntPtr.Zero) throw new ArgumentNullException("hwnd"); IntPtr handler = FindWindowEx(hwnd, new IntPtr(0), "Edit", null); int length = SendMessageGetTextLength(handler, WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero); if (length > 0 && length < int.MaxValue) { length++; StringBuilder sb = new StringBuilder(length); SendMessageGetText(handler, WM_GETTEXT, (IntPtr)sb.Length, sb); return sb.ToString(); } return String.Empty; } 

它是获取文本,但在一个特殊的编码。 例如,如果input的文字是“hello”,就会得到“兴梀㇨ȿڳㇺ”。 什么是这个文本的编码,所以我可以解码为ASCII?

你的问题实际上是你在WM_GETTEXT消息中传递sb.Length ,实际上你应该传递sb.Capacity或者甚至是length

我会这样做:

 if (length > 0 && length < int.MaxValue) { StringBuilder sb = new StringBuilder(length+1); SendMessageGetText(handler, WM_GETTEXT, (IntPtr)length+1, sb); return sb.ToString(); } 

我也指出, WM_GETTEXT将不会返回超过64k字符的length < int.MaxValue是不是你所需要的。


当然,从长远来看,在整个过程中使用Unicode可能会更好,以便支持国际文本。

我个人总是选择使用Unicode API,并使用下面的p / invoke声明:

 [DllImport("User32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Unicode, SetLastError = true)] extern static int SendMessageGetTextLength(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); [DllImport("User32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Unicode, SetLastError = true)] extern static IntPtr SendMessageGetText(IntPtr hWnd, int msg, IntPtr wParam, StringBuilder lParam); [DllImport("user32.dll", EntryPoint = "FindWindowEx", CharSet = CharSet.Unicode, SetLastError = true)] public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); 

由于您使用托管代码编写代码,因此您最好使用托管代码自动化接口,它可以为您完成所有的互操作。 为什么重新发明轮子?

 using System.Windows.Automation; public static string GetText(IntPtr hwnd) { IntPtr hwndEdit = FindWindowEx(hwnd, IntPtr.Zero, "Edit", null); return (string)AutomationElement.FromHandle(hwndEdit). GetCurrentPropertyValue(AutomationElement.NameProperty); } 

你甚至可以自动为你做FindWindowEx

 public static string GetText(IntPtr hwnd) { var editElement = AutomationElement.FromHandle(hwnd). FindFirst(TreeScope.Subtree, new PropertyCondition( AutomationElement.ClassNameProperty, "Edit")); return (string)editElement.GetCurrentPropertyValue(AutomationElement.NameProperty); }