首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >记事本字符解码

记事本字符解码
EN

Stack Overflow用户
提问于 2012-01-09 06:38:43
回答 2查看 846关注 0票数 2

我正在从program.and打开的记事本中读取文本这是我的代码

代码语言:javascript
复制
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;
}

它以一种特殊的编码方式获取文本。例如,如果输入的文本是'hello‘,则会得到'興梀㇨ȿڳㇺ’。这个文本的编码是什么,这样我就可以把它解码成ASCII了?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-01-09 06:58:12

您的问题在于,您实际上是在WM_GETTEXT消息中传递sb.Length,而实际上您应该传递sb.Capacity,甚至只是传递length

我会这样做:

代码语言:javascript
复制
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不会向length < int.MaxValue返回超过64k个字符,这不是您所需要的。

当然,从长远来看,从头到尾使用Unicode可能更好,这样您就可以支持国际文本。

就我个人而言,我总是选择使用Unicode API,并使用以下p/invoke声明:

代码语言:javascript
复制
[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);
票数 4
EN

Stack Overflow用户

发布于 2012-01-10 02:07:01

既然您是用托管代码编写的,那么您也可以使用托管代码自动化接口,它可以为您完成所有的互操作。为什么要重新发明轮子呢?

代码语言:javascript
复制
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

代码语言:javascript
复制
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);
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8782006

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档