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

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

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

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

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

20.08.2008 19:43:24
3 ОТВЕТА

Вы можете сделать это, если этот текст в Unicode на самом деле является окном с заголовком, отправив сообщение 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, вы можете использовать эти знания, чтобы добраться до текста.

5
7.06.2012 20:57:12
Это также работает для стандартных ярлыков и кнопок win32. Взаимодействие: SendMessage должен вернуть IntPtr и взять IntPtr для wParam. Может не иметь значения в случае WM_TEXT (хотя неправильный wParam может быть проблемой, если он работает как 64-битный код?), Но это хорошая практика - использовать правильные типы в случае, если код будет перерезан и вставлен повторно.
BrendanMcK 14.06.2012 22:42:58

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

const int WM_GETTEXT = 0x0D;
const int WM_GETTEXTLENGTH = 0x0E;
2
20.08.2008 21:08:33

Если вам нужна стандартная метка Win32, то WM_GETTEXT будет работать нормально, как указано в других ответах.

-

Существует API доступности - UIAutomation - для стандартных меток, он также использует WM_GETTEXT за кулисами. Однако одним из преимуществ является то, что он может получать текст от нескольких других типов элементов управления, включая большинство системных элементов управления, и часто пользовательский интерфейс, использующий несистемные элементы управления - включая 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 );
    }
}
5
14.06.2012 22:34:33