2012-01-08 14 views
2

私は私のprogram.andで開いたメモ帳からテキストを読んでいます、これは私のコードメモ帳では、文字のデコード

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

それがテキストを取得しますが、特殊なエンコーディングでされています。 たとえば、入力されたテキストが「こんにちは」の場合、「興梀㇨ȿڳㇺ」が得られます。 このテキストのエンコードとは何ですか?私はそれをASCIIにデコードできますか?

+1

あなたは中間ステップとしてメモ帳を使用しての代わりに、直接ファイルストリームを開いている理由はありますか? –

+1

はい、私は、ユーザーが –

+0

の可能な複製を書いている間にテキストを取得したいと思います。[Windowsアプリケーションのテキストボックスからテキストを傷つける](http://stackoverflow.com/questions/8374531/scrape-text-from-textbox-in- windows-application) –

答えて

4

あなたの問題は、あなたが実際にあなたがsb.Capacityを渡すあるいは単にlengthれるべきWM_GETTEXTメッセージにsb.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_GETTEXTlength < int.MaxValueに64K以上の文字を返さないことを指摘したいです。


もちろん、長い実行では、国際的なテキストをサポートできるように、全面的にUnicodeを使用する方が良いかもしれません。

私は個人的には常にUnicode APIを使用してを選ぶと、次のpを使用/宣言を呼び出します:

[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); 
+0

まだ動作していないので、CharSetをAnsiに変更してから、テキストをUTF8に変換しました –

+0

UTF8はどこに入っていますか? –

+0

GetTextメソッドを呼び出すとき –

3

あなたは、マネージコードで書いているので、あなたにも、マネージコードオートメーションインターフェイスを使用することができますあなたのためのすべてのinteropを行います。なぜ車を再発明するのですか?

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