2008-12-09 11 views
16

Czy istnieje sposób, aby aplikacja systemu Windows mogła uzyskać dostęp do innych danych aplikacji, dokładniej pola wprowadzania tekstu w interfejsie GUI i pobrać tekst do przetwarzania w naszej aplikacji?Czytanie z pola tekstowego w oknie innej aplikacji

Jeśli jest to możliwe, czy istnieje sposób, aby "chronić" swoją aplikację, aby temu zapobiec?

EDYCJA: Trzy pierwsze odpowiedzi wydają się dotyczyć uzyskania innego tytułu okna aplikacji, a nie konkretnego pola wprowadzania tekstu w tym oknie.

Nie oczekuję interfejsu Windows API, więc czy mógłbyś być bardziej dokładny, jak znaleźć określone pole tekstowe w tym oknie, jakie są jego wymagania wstępne (wydaje się, że znasz uchwyt okna, który jest wymagany, czy wymaga znając uchwyt pola tekstowego, jak również? Jak mogę to uzyskać? itd ...)

Fragmenty kodu w C++ naprawdę byłyby docenione. Pomoc MSDN jest trudna do przeglądania, ponieważ Win32-API ma tak okropne konwencje nazewnictwa.

Zakończono! Zobacz moją odpowiedź poniżej, aby dowiedzieć się, jak to zrobić w C++.

Odpowiedz

14

Aby odczytać zawartość tekstową z pola tekstowego innej aplikacji, trzeba jakoś uchwycić uchwyt okna kontrolki pola tekstowego. W zależności od sposobu zaprojektowania interfejsu użytkownika aplikacji (jeśli ma taki interfejs użytkownika), istnieje kilka różnych sposobów na uzyskanie tego uchwytu. Możesz użyć "FindWindow"/"FindWindowEx", aby zlokalizować kontrolę lub użyć "WindowFromPoint", jeśli ma to sens. Tak czy inaczej, gdy już dojdziesz do kontroli tekstu, możesz wysłać do niego wiadomość "WM_GETTEXT", aby pobrać jej zawartość (zakładając, że jest to standardowa kontrolka pola tekstowego). Oto próbka wymyślił (sprawdza błędów sans):

HWND hwnd = (HWND)0x00310E3A; 
char szBuf[2048]; 
LONG lResult; 

lResult = SendMessage(hwnd, WM_GETTEXT, sizeof(szBuf)/sizeof(szBuf[0]), (LPARAM)szBuf); 
printf("Copied %d characters. Contents: %s\n", lResult, szBuf); 

użyłem „Spy ++”, aby uzyskać dojście do okna polu tekstowym, które stało się leżące wokół.

Jeśli chodzi o ochronę własnych pól tekstowych przed inspekcją w ten sposób, zawsze można podklasować swoje pole tekstowe (patrz "SetWindowLong" z "GWL_WNDPROC" dla parametru "nIndex") i wykonać specjalne przetwarzanie " WM_GETTEXT ", aby zapewnić, że obsługiwane są tylko żądania z tego samego procesu.

1

Spójrz na AutoHotkey. Jeśli potrzebujesz API do swojej aplikacji, spójrz na ich źródła. Aby temu zapobiec, użyj niestandardowego widgetu zamiast WinForms, MFC lub Win32 API. To nie jest niezawodny, ale pomaga.

+0

Nie mam pojęcia, czego szukać w źródłach, daj mi wskazówkę? – Tuminoid

0

Tak, jest to możliwe na wiele sposobów (jednym ze sposobów jest użycie WINAPI GetWindow i GetWindowText).

pierwsze, uzyskać dojście do pola tekstowego, które chcesz odzyskać tekst (za pomocą FindWindow, EnumChildWindows i innych API), wówczas:

Starego VB6-codeexample, deklaracja API:

Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long 
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long 

Kod wyodrębnić tekst:

Dim MyStr As String 
MyStr = String(GetWindowTextLength(TextBoxHandle) + 1, Chr$(0)) 
GetWindowText TextBoxHandle, MyStr, Len(MyStr) 
MsgBox MyStr 
0

O tym, jak osłonić aplikację, aby temu zapobiec, można zrobić wiele rzeczy. Jednym ze sposobów jest posiadanie własnego kontrolera do obsługi wprowadzania tekstu, który tworzy tekst, powiedzmy kilka etykiet umieszczonych w miejscu, w którym tekst się znajduje, lub które będą rysowały tekst w formie graficznej.

6

OK, trochę się domyśliłem.

punkt początkowy jest teraz wiedząc okno obsłużyć dokładnie, wiemy tylko częściowe tytuł okna, więc pierwszą rzeczą do zrobienia jest znaleźć to okno główne:

... 
EnumWindows((WNDENUMPROC)on_enumwindow_cb, 0); 
... 

który wylicza poprzez wszystkie okna na pulpicie. To sprawia, że ​​zwrotna z każdym z tych klamek okiennych:

BOOL CALLBACK on_enumwindow_cb(HWND hwndWindow, LPARAM lParam) { 
    TCHAR wsTitle[2048]; 
    LRESULT result; 
result = SendMessage(hwndWindow, WM_GETTEXT, (WPARAM) 2048, (LPARAM) wsTitle); 
    ... 

i za pomocą wsTitle i trochę magii regex, możemy znaleźć okno chcemy.

Dzięki zastosowaniu wspomnianych wcześniej Spy ++ mogłem zorientować się w edycji tekstu nazwy klasy pola i użyć go do znalezienia pola poszukiwanych w hwndWindow:

hwndEdit = FindWindowEx(hwndWindow, NULL, L"RichEdit20W", NULL); 

i wtedy możemy odczytać tekst z tej dziedziny :

result = SendMessage(hwndEdit, WM_GETTEXT, (WPARAM) 4096, (LPARAM) wsText); 

Mam nadzieję, że pomoże to każdemu walczyć z tym samym problemem!

+0

Co to jest wsText? Czy możesz opublikować swoje źródło? Dzięki. –

+0

To jest chararray, tak samo jak 'TCHAR wsTitle [2048];' w kodzie wywołania zwrotnego. Źródło jest już stracone, przepraszam. – Tuminoid

0

Tekst można również uzyskać z kontrolki RichEdit z komunikatem EM_GETTEXTRANGE, ale działa on tylko w tym samym procesie, w którym utworzono formant.

+0

Niestety, w tym przypadku nie można go użyć, ponieważ chodzi o dostęp do innego interfejsu procesu. – Tuminoid