Jak umieścić słowo pod kursorem w systemie Windows?

Chcę stworzyć aplikację, która dostanie słowo pod kursor (nie tylko dla pól tekstowych), ale nie mogę znaleźć, jak to zrobić. Używanie OCR jest dość trudne. Jedyne, co widziałem działa, to Komponenty biurkowe. Wspierają "natywny" sposób, ale kosztują dużo. Teraz staram się rozgryźć, co to jest ten "natywny" sposób (może jakoś zaczepiania). Każda pomoc będzie mile widziana.

EDIT: Znalazłem sposób, ale dostaje tylko cały tekst kontroli. Każdy pomysł jak aby uzyskać tylko słowo pod kursorem z całego tekstu?

Author: blez, 2011-01-12

6 answers

W najnowszych wersjach systemu Windows zalecanym sposobem zbierania informacji z jednej aplikacji do drugiej (jeśli oczywiście nie posiadasz docelowej aplikacji) jest użycie technologii UI Automation. Wikipedia jest całkiem dobra, aby uzyskać więcej informacji na ten temat: Microsoft UI Automation

Zasadniczo Automatyzacja interfejsu użyje wszystkich niezbędnych środków, aby zebrać to, co można zebrać

Oto mały kod aplikacji konsolowej, który będzie szpiegował interfejs innych aplikacji. Run it i przesuń kursor myszy do różnych aplikacji. Każda aplikacja ma inną obsługę różnych "wzorców automatyzacji interfejsu użytkownika". Na przykład, istnieje wzorzec wartości i wzorzec tekstowy, jak pokazano tutaj.

static void Main(string[] args)
{
    do
    {
        System.Drawing.Point mouse = System.Windows.Forms.Cursor.Position; // use Windows forms mouse code instead of WPF
        AutomationElement element = AutomationElement.FromPoint(new System.Windows.Point(mouse.X, mouse.Y));
        if (element == null)
        {
            // no element under mouse
            return;
        }

        Console.WriteLine("Element at position " + mouse + " is '" + element.Current.Name + "'");

        object pattern;
        // the "Value" pattern is supported by many application (including IE & FF)
        if (element.TryGetCurrentPattern(ValuePattern.Pattern, out pattern))
        {
            ValuePattern valuePattern = (ValuePattern)pattern;
            Console.WriteLine(" Value=" + valuePattern.Current.Value);
        }

        // the "Text" pattern is supported by some applications (including Notepad)and returns the current selection for example
        if (element.TryGetCurrentPattern(TextPattern.Pattern, out pattern))
        {
            TextPattern textPattern = (TextPattern)pattern;
            foreach(TextPatternRange range in textPattern.GetSelection())
            {
                Console.WriteLine(" SelectionRange=" + range.GetText(-1));
            }
        }
        Thread.Sleep(1000);
        Console.WriteLine(); Console.WriteLine();
    }
    while (true);
}

Automatyzacja interfejsu użytkownika jest faktycznie obsługiwana przez Internet Explorer i Firefox, ale nie przez Chrome według mojej wiedzy. Zobacz ten link: Kiedy Google Chrome będzie dostępny?

To dopiero początek pracy dla Ciebie :-), ponieważ:
  • Przez większość czasu, wszystko to ma poważne implikacje bezpieczeństwa. Korzystanie z tej technologii (lub bezpośredniej technologii Windows, takiej jak WindowFromPoint) będzie wymagało wystarczających praw do tego (takich jak bycie administratorem). I myślę, że DExperience nie ma żadnego sposobu na przezwyciężenie tych ograniczeń, chyba że zainstalują sterownik jądra na komputerze.

  • Niektóre aplikacje nie ujawnią niczego nikomu, nawet z odpowiednimi prawami. Na przykład, jeśli piszę aplikacja bankowa, nie chcę, żebyś szpiegował to, co wyświetli moja aplikacja :-). Inne aplikacje, takie jak Outlook z DRM, nie ujawnią niczego z tych samych powodów.

  • Tylko obsługa wzorców tekstowych automatyzacji interfejsu użytkownika może dostarczyć więcej informacji (takich jak słowo) niż tylko cały tekst. Niestety, ten specyficzny wzorzec nie jest obsługiwany przez IE ani FF, nawet jeśli obsługuje automatyzację interfejsu użytkownika na całym świecie.

Więc, jeśli to wszystko nie zadziała dla ciebie, będziesz musiał zanurz się głębiej i wykorzystaj techniki OCR lub rozpoznawania kształtów. Nawet z tym, będą przypadki, w których nie będzie w stanie to zrobić w ogóle (z powodu praw bezpieczeństwa).

 49
Author: Simon Mourier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-19 10:40:26

Jest to nietrywialne, jeśli aplikacja, na której chcesz "szpiegować", rysuje sam tekst. Jednym z możliwych rozwiązań jest uruchomienie drugiej aplikacji do malowania części okna, unieważniając obszar bezpośrednio pod kursorem.

Kiedy druga aplikacja maluje, będziesz musiał przechwycić wywołania rysowania tekstu. Jednym ze sposobów na to jest wstrzyknięcie kodu w drugiej aplikacji i przechwycenie wywołań do funkcji GDI, które rysują tekst. Podczas debugowania natywnych aplikacji, to jest to, co visual studio robi, aby wdrożyć punkty przerwania. Aby przetestować pomysł, możesz użyć biblioteki typu detours (ale nie jest ona darmowa do użytku komercyjnego).

Możesz również sprawdzić, czy aplikacja obsługuje jeden z API dostępu, które są w systemie Windows, aby ułatwić takie rzeczy, jak czytniki ekranu dla osób niewidomych.

Jedno słowo ostrzeżenia: sam nic z tego nie zrobiłem.

 10
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-12 09:59:32

Jeśli aplikacja musi obsługiwać nie tylko aplikacje. Net, zacznę od importowania funkcji ( P / Invoke):

Później możesz iterować nad kontrolkami i spróbować pobrać tekst z wnętrza na podstawie typu. Jeśli znajdę trochę czasu postaram się opublikować taki kod.

Po pewnym sprawdzeniu wygląda na to, że najlepszym sposobem (niestety również trudnym) jest podłączenie się do renderowania tekstu GDI some discussion

 7
Author: baalazamon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-21 10:48:12

Powtórzyłbym to, co powiedział Patricker, ale myślę, że nie ma wiarygodnego sposobu, aby zrobić to, co chcesz.

Prawdopodobnie uzyskałeś tekst okna lub coś w tym stylu. Ale co, jeśli kursor znajduje się nad oknem, które nie używa tekstu okna do przechowywania swojej zawartości? Windows nie ma obowiązku przechowywania swoich danych w określony sposób.

To kończy się wskazaniem na rozpoznawanie znaków, gdzie patrzysz na piksele pod kursorem i próbujesz dowiedzieć się, jakie są słowa. Ale nie tylko jest to bardzo nietrywialne, ale także nie jest niezawodne. Co zrobić, jeśli część słowa nie jest widoczna, ponieważ rozciąga się przez okno?

To na pewno nie jest trywialne. Jest kilka sposobów, aby to zrobić. Ale nie ma niezawodnego sposobu, który będzie działał ze wszystkimi oknami.

 5
Author: Jonathan Wood,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-28 02:55:21

Istnieje sdk do pobierania tekstu za pomocą OCR. Nie jest darmowy, ale jest dość tani w porównaniu do innych produktów: http://www.screenocr.com/screen-ocr-library-sdk.htm mają aplikację, która zapewnia te same funkcje, więc można spróbować demo zbyt.

 2
Author: Giorgi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-21 20:32:22

Aby to osiągnąć, potrzebujesz podejścia wielopłaszczyznowego.

UIA działa w wielu aplikacjach, ale musisz poeksperymentować, aby zobaczyć, gdzie tekst jest zwracany. Może to być Element, wartość lub zakres. Nie ma spójności nawet we wszystkich aplikacjach biurowych.

Jeśli UIA nie powiedzie się, wylicz running object table (ROT) i przywróć wskaźniki COM do różnych aplikacji zarejestrowanych w ROT. Następnie możesz rzucić te wskaźniki do podstawowych typów biur:
na przykład:

enumerate ROT  - then
 wb = (Excel._Workbook)enumerator.Value;
string strText = wb.Application.ActiveCell.Text.ToString();

Jeśli powyższe dwie metody zawiodą, użyj darmowego systemu OCR w MODI (Biblioteka typu Microsoft Office Document Imaging 12.0)

 0
Author: RichardB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-16 16:53:07