2016-08-18 7 views
0

別のアプリケーションからテキストを抽出しようとしています。このアプリケーションは、今のところ単純なものであっても、今は(今のところ)うまくいきたいと思うかもしれません。別のアプリケーション(ウィンドウ)からテキストを取得できません

私が使用するコード:

public static class ModApi 
{ 
    [DllImport("user32.dll", EntryPoint = "SendMessageTimeout", SetLastError =  true, CharSet = CharSet.Unicode)] 
    public static extern uint SendMessageTimeoutText(IntPtr hWnd, int Msg, int countOfChars, StringBuilder text, uint flags, uint uTimeoutj, uint result); 

    public static string GetText(IntPtr hwnd) 
    { 
     var text = new StringBuilder(1024); 

     if (SendMessageTimeoutText(hwnd, 0xd, 1024, text, 0x2, 5000, 0) != 0) 
     { 
      return text.ToString(); 
     } 

     MessageBox.Show(text.ToString()); 
     return ""; 
    } 
} 

私が使用してこのコードを呼び出す:

0x00788600は、私が実行しているアプリケーションの一つの例である(私は100%確信している
IntPtr MytestHandle = new IntPtr(0x00788600); 
HandleRef hrefHWndTarget = new HandleRef(null, MytestHandle); 

にこれがメインウィンドウのハンドルです)。

私は「他」のアプリケーション内部の1つのテキストボックスからテキストを持っている必要がありますが、私は自分のコードを使用するとき、それは空の文字列が

提案するたびに返しますか?

+0

正確にどのようなものをハードコーディングされたマジックナンバーの全てが行うことになっていますか? HWNDとして使用している数値は実際には有効なウィンドウハンドルだと思いますか? (ええ、私は100%確信しています*が読んでいますが、それは本当ではないと言っているからです - [IsWindow](https://msdn.microsoft.com/en-us/library/windows/) desktop/ms633528(v = vs.85).aspx)とは?) –

答えて

1

あなたのコードで間違いはありません。あなたのハンドルが正しいかどうかを確認することをお勧めします。

ただし、TextBoxのテキストを取得するには、実際のコントロールのハンドルを使用する必要があります。 MainWindowHandleはフォームキャプションのみを返します。

私はそれでいくつかのコントロールにダミーアプリケーション「WindowsFormsApplication1」を作成し、すべてのテキストを取得するには、次のコードを使用:

[Flags] 
internal enum SendMessageTimeoutFlags : uint 
{ 
    SMTO_NORMAL = 0x0, 
    SMTO_BLOCK = 0x1, 
    SMTO_ABORTIFHUNG = 0x2, 
    SMTO_NOTIMEOUTIFNOTHUNG = 0x8, 
    SMTO_ERRORONEXIT = 0x20 
} 

// Specific import for WM_GETTEXTLENGTH 
[DllImport("user32.dll", EntryPoint = "SendMessageTimeout", CharSet = CharSet.Auto)] 
internal static extern int SendMessageTimeout(
    IntPtr hwnd, 
    uint Msg,    // Use WM_GETTEXTLENGTH 
    int wParam, 
    int lParam, 
    SendMessageTimeoutFlags flags, 
    uint uTimeout, 
    out int lpdwResult); 

// Specific import for WM_GETTEXT 
[DllImport("user32.dll", EntryPoint = "SendMessageTimeout", SetLastError = true, CharSet = CharSet.Auto)] 
internal static extern uint SendMessageTimeoutText(
    IntPtr hWnd, 
    uint Msg,    // Use WM_GETTEXT 
    int countOfChars, 
    StringBuilder text, 
    SendMessageTimeoutFlags flags, 
    uint uTImeoutj, 
    out IntPtr result); 

[DllImport("user32")] 
[return: MarshalAs(UnmanagedType.Bool)] 
private static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i); 

// callback to enumerate child windows 
private delegate bool EnumWindowProc(IntPtr hwnd, IntPtr parameter); 

private static bool EnumChildWindowsCallback(IntPtr handle, IntPtr pointer) 
{ 
    // this method will be called foreach child window 
    // create a GCHandle from pointer 
    var gcHandle = GCHandle.FromIntPtr(pointer); 

    // cast pointer as list 
    var list = gcHandle.Target as List<IntPtr>; 

    if (list == null) 
     throw new InvalidCastException("Invalid cast of GCHandle as List<IntPtr>"); 

    // Adds the handle to the list. 
    list.Add(handle); 

    return true; 
} 

private static IEnumerable<IntPtr> GetChildWindows(IntPtr parent) 
{ 
    // Create list to store child window handles. 
    var result = new List<IntPtr>(); 

    // Allocate list handle to pass to EnumChildWindows. 
    var listHandle = GCHandle.Alloc(result); 

    try 
    { 
     // enumerates though the children 
     EnumChildWindows(parent, EnumChildWindowsCallback, GCHandle.ToIntPtr(listHandle)); 
    } 
    finally 
    { 
     // free unmanaged list handle 
     if (listHandle.IsAllocated) 
      listHandle.Free(); 
    } 

    return result; 
} 

internal static string GetText(IntPtr hwnd) 
{ 
    const uint WM_GETTEXTLENGTH = 0x000E; 
    const uint WM_GETTEXT = 0x000D; 
    int length; 
    IntPtr p; 

    var result = SendMessageTimeout(hwnd, WM_GETTEXTLENGTH, 0, 0, SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 5, out length); 

    if (result != 1 || length <= 0) 
     return string.Empty; 

    var sb = new StringBuilder(length + 1); 

    return SendMessageTimeoutText(hwnd, WM_GETTEXT, sb.Capacity, sb, SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 5, out p) != 0 ? 
      sb.ToString() : 
      string.Empty; 
} 

public static void Main(string[] args) 
{ 
    var p = Process.GetProcessesByName("WindowsFormsApplication1").First();    

    Console.WriteLine(GetText(p.MainWindowHandle)); // main window handle of form, returns "Form1" 
    Console.WriteLine(GetText(new IntPtr(0x70BA0))); // actual textbox handle, used Winspector, returns "quertz" 

    // iterate through dynamic handles of children 
    foreach (var hwnd in GetChildWindows(p.MainWindowHandle)) 
     Console.WriteLine($"{hwnd}:{GetText(hwnd)}"); 

    Console.ReadLine(); 
}  
+0

あなたはAAAA-AMAZINGです! Winspector(あなたがコメントとして書いた)で周りをじっくりとやっていただきありがとうございました。どうもありがとうございます :) – Merlijn

関連する問題