2010-05-04 2 views
5

Как читать выделенный/выделенный текст из любого окна с помощью C#.Захват выделенного текста из любого окна с помощью C#

Я пробовал 2 подхода.

  1. Отправить «^ c» всякий раз, когда пользователь выбирает какую-либо вещь. Но в этом случае мой буфер обмена заполнен множеством ненужных данных. Иногда он копировал пароли.

поэтому я переключил свой подход на второй метод, отправлю метод сообщения.

см Этот пример кода

[DllImport("user32.dll")] 
    static extern int GetFocus(); 

    [DllImport("user32.dll")] 
    static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach); 

    [DllImport("kernel32.dll")] 
    static extern uint GetCurrentThreadId(); 

    [DllImport("user32.dll")] 
    static extern uint GetWindowThreadProcessId(int hWnd, int ProcessId);  

    [DllImport("user32.dll") ] 
    static extern int GetForegroundWindow(); 

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] 
    static extern int SendMessage(int hWnd, int Msg, int wParam, StringBuilder lParam);  

    // second overload of SendMessage 

    [DllImport("user32.dll")] 
    private static extern int SendMessage(IntPtr hWnd, uint Msg, out int wParam, out int lParam); 

    const int WM_SETTEXT = 12; 
    const int WM_GETTEXT = 13;  

private string PerformCopy() 
    { 
     try 
     { 
      //Wait 5 seconds to give us a chance to give focus to some edit window, 
      //notepad for example 
      System.Threading.Thread.Sleep(5000); 
      StringBuilder builder = new StringBuilder(500); 

      int foregroundWindowHandle = GetForegroundWindow(); 
      uint remoteThreadId = GetWindowThreadProcessId(foregroundWindowHandle, 0); 
      uint currentThreadId = GetCurrentThreadId(); 

      //AttachTrheadInput is needed so we can get the handle of a focused window in another app 
      AttachThreadInput(remoteThreadId, currentThreadId, true); 
      //Get the handle of a focused window 
      int focused = GetFocus(); 
      //Now detach since we got the focused handle 
      AttachThreadInput(remoteThreadId, currentThreadId, false); 

      //Get the text from the active window into the stringbuilder 
      SendMessage(focused, WM_GETTEXT, builder.Capacity, builder); 

      return builder.ToString(); 
     } 
     catch (System.Exception oException) 
     { 
      throw oException; 
     } 
    } 

этот код работает отлично в блокноте. Но если я попытаюсь захватить из других приложений, таких как Mozilla firefox или Visual Studio IDE, он не возвращает текст.

Может кто-нибудь, пожалуйста, помогите мне, где я делаю неправильно? Прежде всего, я выбрал правильный подход?

ответ

3

Это потому, что Firefox и Visual Studio не используют встроенные элементы управления Win32 для отображения/редактирования текста.

Невозможно вообще, чтобы получить значение «любого» выделенного текста из-за того, что программы могут повторно реализовать свою собственную версию элементов управления Win32 любым способом, который они считают нужным, и ваша программа не может рассчитывать на работу со всеми из них.

Однако, вы можете использовать UI Automation API, которые позволят вам взаимодействовать с большинства контроля третьей стороной (по крайней мере, все хорошие, - такие как Visual Studio и Firefox - скорее всего, будет работать с пользовательским интерфейсом API автоматизации, поскольку это требование для доступности)

+0

В Firefox не реализована автоматизация пользовательского интерфейса, я пробовал версию 3.0, и она не работала, надеюсь, что она может поддерживать в будущем. –

+0

Можем ли мы что-то сделать, чтобы улучшить мой первый подход. Это работает очень хорошо, за исключением ненужных копий ........ – Dinesh

Смежные вопросы