2008-08-20 4 views
4

Возможно ли получить текст пользовательского интерфейса из внешнего приложения на C#.Получение текста пользовательского интерфейса из внешнего приложения в C#

В частности, есть способ прочитать текст Unicode с ярлыка (предположим, что это обычный элемент управления меткой Windows) из внешнего приложения Win32, написанного сторонним лицом? Текст видим, но не выбирается мышью в пользовательском интерфейсе.

Я предполагаю, что есть некоторый API доступа (например, предназначенный для чтения с экрана), который позволяет это.

Редактировать: В настоящее время изучает использование чего-то вроде Managed Spy App, но по-прежнему ценит любые другие выводы.

ответ

5

Вы можете сделать это, если этот текст в виде юникода на самом деле является окном с надписью, отправив сообщение WM_GETTEXT.

[DllImport("user32.dll")] 
public static extern int SendMessage (IntPtr hWnd, int msg, int Param, System.Text.StringBuilder text); 

System.Text.StringBuilder text = new System.Text.StringBuilder(255) ; // or length from call with GETTEXTLENGTH 
int RetVal = Win32.SendMessage(hWnd , WM_GETTEXT, text.Capacity, text); 

Если это просто нарисовано на холсте, вам может быть повезло, если вы знаете, какую инфраструктуру использует приложение. Если он использует WinForms или VCL от Borland, вы можете использовать эти знания для доступа к тексту.

+0

Это также работает для стандартных меток и кнопок win32. Interop nit: SendMessage должен возвращать IntPtr и принимать IntPtr для wParam. Может быть, не имеет значения в случае WM_TEXT (хотя некорректный wParam может быть проблемой при запуске в виде 64-битного кода?), Но рекомендуется использовать правильные типы в случае, если код вырезается и вставляется повторно. – BrendanMcK 2012-06-14 22:42:58

2

не видел значения WM_GETTEXT или WM_GETTEXTLENGTH в этой статье, так что на всякий случай ..

const int WM_GETTEXT = 0x0D; 
const int WM_GETTEXTLENGTH = 0x0E; 
5

Если вы просто заботитесь о стандартной этикетки Win32, то WM_GETTEXT будет работать нормально, как указано в другие ответы.

-

Существует доступность API - UIAutomation - для стандартных этикеток, он тоже использует WM_GETTEXT за кулисами. Однако одно из преимуществ этого заключается в том, что он может получать текст из нескольких других типов элементов управления, включая большинство системных элементов управления, и часто UI с использованием несистемных элементов управления, включая WPF, текст в IE и Firefox и другие.

// compile as: 
// csc file.cs /r:UIAutomationClient.dll /r:UIAutomationTypes.dll /r:WindowsBase.dll 
using System.Windows.Automation; 
using System.Windows.Forms; 
using System; 

class Test 
{ 
    public static void Main() 
    { 
     // Get element under pointer. You can also get an AutomationElement from a 
      // HWND handle, or by navigating the UI tree. 
     System.Drawing.Point pt = Cursor.Position; 
     AutomationElement el = AutomationElement.FromPoint(new System.Windows.Point(pt.X, pt.Y)); 
     // Prints its name - often the context, but would be corresponding label text for editable controls. Can also get the type of control, location, and other properties. 
     Console.WriteLine(el.Current.Name); 
    } 
}