2016-08-18 3 views
0

Ich versuche, Text aus einer anderen Anwendung zu extrahieren. Diese Anwendung kann im Moment einfach sein, ich möchte nur, dass es funktioniert (vorerst).Text kann nicht aus einer anderen Anwendung (Fenster) abgerufen werden

Der Code ich benutze:

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

ich diesen Code aufrufen mit:

IntPtr MytestHandle = new IntPtr(0x00788600); 
HandleRef hrefHWndTarget = new HandleRef(null, MytestHandle); 

wo 0x00788600 ist ein Beispiel für eine der Anwendungen, die ich laufen bin (ich bin 100% sicher dass dies der Hauptfenstergriff ist).

Ich brauche den Text aus einem Textfeld in der „anderen“ Anwendung haben, aber wenn ich meinen Code verwenden, gibt es eine leere Zeichenfolge jedes Mal

Verbesserungsvorschläge?

+0

Was genau sind alle diese hartcodierte magischen Zahlen tun soll? Was lässt Sie glauben, dass die Nummer, die Sie als HWND verwenden, tatsächlich ein gültiges Fensterhandle ist? (Ja, ich lese * ich bin 100% sicher *, aber weil du sagst, dass es nicht wahr ist - was macht [IsWindow] (https://msdn.microsoft.com/en-us/library/windows/ desktop/ms633528 (v = vs.85) .aspx) sag ?.) –

Antwort

1

Ich kann keine Fehler mit Ihrem Code sehen. Ich schlage vor zu überprüfen, ob Ihr Griff richtig ist oder nicht.

Um jedoch den Text der TextBox zu erhalten, müssen Sie den Griff der tatsächlichen Kontrolle verwenden. Das MainWindowHandle wird nur die Formularbeschriftung zurückgeben.

habe ich eine Dummy-Anwendung „WindowsFormsApplication1“ mit einigen Kontrollen in sie und verwendet den folgenden Code alle Texte zu bekommen:

[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

Du bist AAAA-AMAZING! Vielen Dank, nachdem du mit Winspector (den du als Kommentar geschrieben hast) herumgespielt hast, hat alles funktioniert! Ich danke dir sehr :) – Merlijn

Verwandte Themen