Windows应用程序是否有办法访问另一个应用程序数据,更具体地说是GUI中的文本输入字段,并在那里获取文本以便在我们自己的应用程序中进行处理?
如果有可能,是否有办法“屏蔽”您的应用程序以防止它?
编辑:三个第一个答案似乎是关于获取另一个应用程序窗口标题,而不是该窗口中的特定文本输入字段。
我不是Windows API所期望的,所以你能更准确地说明如何在该窗口中找到某个文本字段,它的先决条件是什么(似乎知道窗口处理需要什么,是否需要知道文本字段句柄也是如何?我如何得到它?等等......)
C ++中的代码片段确实非常值得赞赏。 MSDN帮助很难浏览,因为Win32-API有如此可怕的命名约定。
已完成!请参阅下面的答案,了解C ++中的操作方法。
答案 0 :(得分: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 );
我使用“Spy ++”来获取正好位于文本框窗口的句柄。
至于保护您自己的文本框不被这样检查,您可以随时对文本框进行子类化(对于“nIndex”参数,请参阅“SetWindowLong”和“GWL_WNDPROC”)并对“WM_GETTEXT”进行一些特殊处理“确保只有来自同一进程的请求才能得到服务的消息。
答案 1 :(得分: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和小正则表达式魔术,我们可以找到我们想要的窗口。
通过使用前面提到的Spy ++,我可以找出文本编辑字段类名,并使用它在 hwndWindow 中找到想要的字段:
hwndEdit = FindWindowEx(hwndWindow, NULL, L"RichEdit20W", NULL);
然后我们可以阅读该字段中的文字:
result = SendMessage(hwndEdit, WM_GETTEXT, (WPARAM) 4096, (LPARAM) wsText);
我希望这可以帮助任何人解决同样的问题!
答案 2 :(得分:1)
看看AutoHotkey。如果您的应用程序需要API,请查看其来源。 要防止它,请使用自定义小部件而不是WinForms,MFC或Win32 API。这不是万无一失,但有帮助。
答案 3 :(得分:0)
是的,它可以通过多种方式实现(一种方法是使用WINAPI GetWindow和GetWindowText)。
首先,获取要从中检索文本的文本框的句柄(使用FindWindow,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
答案 4 :(得分:0)
关于如何保护应用程序以防止它,你可以做很多事情。 一种方法是拥有一个自己的控件来处理文本输入,这些文本输入可以构建文本,比如放置文本所在的几个标签,或以图形方式绘制文本。
答案 5 :(得分:0)
您还可以使用EM_GETTEXTRANGE消息从richedit控件获取文本,但它仅在创建控件的同一进程中有效。
答案 6 :(得分:-1)
HWND FindWindow(
LPCTSTR lpClassName,
LPCTSTR lpWindowName
);