2008-12-09 31 views
16

Có cách nào để ứng dụng Windows truy cập dữ liệu ứng dụng khác, cụ thể hơn là trường nhập văn bản trong GUI và lấy văn bản ở đó để xử lý trong ứng dụng của riêng chúng tôi không?Đọc từ trường văn bản trong cửa sổ ứng dụng khác

Nếu có thể, có cách nào để "bảo vệ" ứng dụng của bạn để ngăn chặn không?

EDIT: Ba câu trả lời đầu tiên dường như là về việc nhận danh hiệu một cửa sổ khác các ứng dụng, không phải là một lĩnh vực đầu vào văn bản cụ thể trong cửa sổ đó.

Tôi không có Windows API mong đợi, vì vậy bạn có thể chính xác hơn làm cách nào để tìm một trường văn bản nhất định trong cửa sổ đó, các điều kiện tiên quyết cho nó (có vẻ như cần biết một cửa sổ xử lý điều gì đó là bắt buộc) biết lĩnh vực văn bản xử lý không? làm thế nào để có được điều đó? vv ...)

đoạn mã trong C++ thực sự sẽ được thực sự đánh giá cao. Trợ giúp MSDN khó duyệt vì Win32-API có quy ước đặt tên khủng khiếp như vậy.

Đã hoàn tất! Xem câu trả lời của tôi bên dưới để biết cách thực hiện trong C++.

Trả lời

14

Để đọc nội dung văn bản từ hộp văn bản của ứng dụng khác, bạn sẽ cần phải xử lý cửa sổ điều khiển hộp văn bản đó bằng cách nào đó. Tùy thuộc vào cách giao diện người dùng ứng dụng của bạn được thiết kế (nếu nó có giao diện người dùng), có một vài cách khác nhau mà bạn có thể sử dụng để có được xử lý này. Bạn có thể sử dụng "FindWindow"/"FindWindowEx" để xác định vị trí kiểm soát của bạn hoặc sử dụng "WindowFromPoint" nếu điều đó có ý nghĩa. Dù bằng cách nào, một khi bạn có tay cầm để điều khiển văn bản, bạn có thể gửi một tin nhắn "WM_GETTEXT" đến nó để lấy nội dung của nó (giả sử nó là một điều khiển hộp văn bản chuẩn). Dưới đây là một mẫu được pha chế (kiểm tra lỗi 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); 

Tôi đã sử dụng "Spy ++" để xử lý cửa sổ hộp văn bản nằm xung quanh.

Để bảo vệ các hộp văn bản của bạn không bị kiểm tra như thế này, bạn luôn có thể xếp lớp hộp văn bản của bạn (xem "SetWindowLong" với "GWL_WNDPROC" cho tham số "nIndex") và thực hiện một số xử lý đặc biệt của " WM_GETTEXT "tin nhắn để đảm bảo rằng chỉ yêu cầu từ cùng một quá trình được phục vụ.

1

Nhìn vào AutoHotkey. Nếu bạn cần một API cho ứng dụng của bạn, hãy xem các nguồn của họ. Để ngăn chặn nó, hãy sử dụng một widget tùy chỉnh thay vì WinForms, MFC hoặc Win32 API. Điều đó không phải là dễ dàng, nhưng giúp.

+0

Tôi không biết nên tìm kiếm gì trong các nguồn, cung cấp cho tôi một con trỏ? – Tuminoid

0

Có thể thực hiện theo nhiều cách (một cách là sử dụng WINAPI GetWindow và GetWindowText).

Đầu tiên, có được một tay cầm vào textbox bạn muốn để lấy văn bản từ (sử dụng FindWindow, EnumChildWindows và các API khác), sau đó:

Cũ VB6-codeexample, tuyên bố 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 

Mã để trích xuất văn bản:

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

Về cách bảo vệ ứng dụng để ngăn chặn ứng dụng, bạn có thể thực hiện nhiều việc. Có một cách để có quyền điều khiển riêng để xử lý nhập văn bản để xây dựng văn bản từ cho phép nói một vài nhãn được đặt ở vị trí văn bản sẽ được vẽ hoặc vẽ văn bản bằng đồ thị.

6

OK, tôi đã phần nào tìm ra điều này.

điểm Các khởi đầu tại là biết cửa sổ xử lý chính xác, chúng tôi chỉ biết tiêu đề cửa sổ một phần, vì vậy điều đầu tiên cần làm là thấy cửa sổ chính:

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

mà liệt kê qua tất cả các cửa sổ trên desktop. Gọi lại bằng mỗi tay cầm trong số các cửa sổ sau:

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

và bằng cách sử dụng phép thuật wsTitle và ít regex, chúng tôi có thể tìm thấy cửa sổ chúng tôi muốn.

Bằng việc sử dụng Spy trước khi đề cập ++ tôi có thể tìm ra các văn bản chỉnh sửa tên lớp trường và sử dụng nó để tìm lĩnh vực truy nã trong hwndWindow:

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

và sau đó chúng ta có thể đọc các văn bản từ trường :

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

Tôi hy vọng điều này sẽ giúp mọi người chiến đấu với cùng một vấn đề!

+0

wsText là gì? Bạn có thể đăng nguồn của mình không? Cảm ơn. –

+0

Nó là chararray, giống như 'TCHAR wsTitle [2048];' trong mã gọi lại. Nguồn đã bị mất rồi, xin lỗi. – Tuminoid

0

Bạn cũng có thể nhận văn bản từ điều khiển đa dạng với thông điệp EM_GETTEXTRANGE, nhưng nó chỉ hoạt động trong cùng một quá trình mà trong đó điều khiển được tạo.

+0

Thật không may là nó không phải là sau đó có thể sử dụng trong trường hợp này, như toàn bộ điểm là để truy cập một giao diện người dùng quá trình. – Tuminoid

Các vấn đề liên quan