2008-12-09 92 views
16

Windows應用程序是否可以訪問其他應用程序數據(更具體地說是GUI中的文本輸入字段),然後獲取文本以便在我們自己的應用程序中處理?從另一個應用程序的窗口中的文本字段讀取

如果有可能,有沒有辦法「屏蔽」你的應用程序來防止它?

編輯:三個第一個答案似乎是獲得另一個應用程序窗口標題,而不是該窗口中的特定文本輸入字段。

我不是Windows API的預期,所以你可以更準確地如何找到該窗口中的某個文本字段,它有什麼先決條件(好像知道一個窗口句柄是必需的,是否需要知道文本字段句柄以及如何得到那個?等等......)

C++中的代碼片段真的很值得讚賞。 MSDN幫助很難瀏覽,因爲Win32-API具有這樣可怕的命名約定。

已完成!請參閱下面的答案,瞭解C++中的操作方法。

回答

14

對於從另一個應用程序的文本框中讀取文本內容,您需要以某種方式獲取該文本框控件的窗口句柄。根據應用程序UI的設計方式(如果它具有UI),可以使用幾種不同的方法來獲取此句柄。您可以使用「FindWindow」/「FindWindowEx」來定位您的控件,或者使用「WindowFromPoint」(如果有意義的話)。無論哪種方式,一旦你有了文本控件的句柄,你就可以發送一個「WM_GETTEXT」消息來檢索它的內容(假設它是一個標準的文本框控件)。下面是一個編造的樣品(沒有錯誤檢查):

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); 

我用「間諜++」來獲得句柄文本框窗口,正好是躺在附近。

至於保護你自己的文本框不被這樣檢查,你總是可以對你的文本框進行分類(參見「SetWindowLong」和「GWL_WNDPROC」中的「nIndex」參數),並對「 WM_GETTEXT「消息來確保只有來自同一進程的請求被服務。

1

看看AutoHotkey。如果您需要爲您的應用程序提供API,請查看其來源。 要防止它,請使用自定義小部件而不是WinForms,MFC或Win32 API。這不是萬無一失的,但有助於。

+0

我不知道要在來源中搜索什麼,給我一個指針? – Tuminoid 2008-12-09 09:58:55

0

是的,它有很多可能的方法(一種方法是使用WINAPI GetWindow和GetWindowText)。

首先,得到一個處理你想要從(使用FindWindow API,EnumChildWindows和其他API)文本的文本框,然後:

舊VB6-codeexample,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 

代碼中提取文本:

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

關於如何屏蔽應用程序以防止它,你可以做很多事情。 其中一種方法是擁有一個自己的控件來處理文本輸入,這些文本輸入可以讓文本放置在文本所在的位置,或者以圖形方式繪製文本。

6

好的,我有點想通了。現在

的出發點是知道的窗口句柄確切地說,我們只知道部分窗口標題,所以首先要做的就是發現,主窗口:

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

它通過在桌面上的所有窗口枚舉。這使得與這些窗口的回調處理:

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

,並通過使用wsTitle和小正則表達式魔術,我們可以找到我們想要的窗口。

通過使用之前提到的間諜++我能想出的文本編輯字段的類名,並用它來查找hwndWindow通緝領域:

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

,然後我們可以讀取該字段中的文本:

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

我希望這可以幫助任何人解決同一個問題!

+0

什麼是wsText?你可以發佈你的來源?謝謝。 – 2014-01-16 05:58:36

+0

這是chararray,與回調代碼中的`TCHAR wsTitle [2048];`相同。來源已經丟失,對不起。 – Tuminoid 2014-01-16 08:52:30

0

您還可以使用EM_GETTEXTRANGE消息從RichEdit控件獲取文本,但它僅在與創建控件相同的過程中起作用。

相關問題