我想编写一个程序,它允许我在不同程序的文本框中更改值,或者自动将值从一个程序复制到另一个程序。
我找到了一种在targer程序中获取hWnd到大多数(不知道所有这些)控件的方法,并用鼠标光标指向它们。我做了一个简单的结构,以及它的数组
struct hWndpointer
{
HWND hWnd;
AnsiString text;
};
hWndpointer tbl[250];
EnumWindowProc和EnumChildWindowProc将窗口的句柄和文本加载到数组中并加载到程序中的列表控件中,这样我就可以单击列表中的项目(或用键盘选择它),光标指向控件(如像期望的那样按钮或文本框...不幸的是有些控件没有文本(或者更确切地说GetWindowText没有返回文本)所以无法识别控件。
问题是: 有没有办法获取/读取控件的名称? 有没有办法获取/读取并设置像'enabled'或'text'或'value'这样的specyfic值?
提前致谢
PS:对不起我的英文;)
答案 0 :(得分:0)
您可以使用SendMessage
和PostMessage
向其他进程拥有的Windows发送WM_GETTEXT
,WM_SETTEXT
,WM_ENABLE
。 (SendMessage
表示查询,PostMessage
表示只写操作)
通常,子ID将用于识别子窗口(特别是在对话框中),但是程序也可以完全依赖于动态HWND
值,在这种情况下,您将不得不退回窗口位置区分。
答案 1 :(得分:0)
从Win32 API的角度来看,UI控件没有Names,因此您不能要求API在另一个进程中返回UI控件的Name
,因为这样的值不存在。名称严格地是应用程序使用的UI框架的一个特性(在C ++ Builder的情况下为VCL),并且您不能跨过程边界直接访问框架。您需要来自控件拥有的应用程序的合作。
例如,一种方法是让两个应用调用RegisterWindowMessage()
来注册自定义窗口消息,然后您的应用可以将该消息发布到另一个应用,指定所需控件的HWND
和您自己的HWND
作为参数。然后,其他应用可以使用SendMessage()
消息Name
将控件的HWND
返回到您应用的WM_COPYDATA
,您可以使用该消息相应地更新您的列表。
在VCL框架中,您可以使用HWND
函数将TWinControl*
转换为FindControl()
指针。如果NULL
不属于调用进程,它将返回HWND
,否则您可以从其Name
属性中复制该值。例如:
const UINT WM_GETCONTROLNAME = RegisterWindowMessage("WM_GetControlName");
const UINT WM_GETCONTROLNAME_RESULT = RegisterWindowMessage("WM_GetControlName_Result");
#include <pshpack1.h>
struct sControlName
{
HWND hWnd;
int Length;
char Value[1];
};
#include <poppack.h>
void __fastcall TMyForm::WndProc(TMessage &Message)
{
if ((Message.Msg == WM_COPYDATA) && (WM_GETCONTROLNAME_RESULT != 0))
{
LPCOPYDATASTRUCT cds = (LPCOPYDATASTRUCT) Message.LParam;
if (cds->dwData == WM_GETCONTROLNAME_RESULT)
{
sControlName *pName = (sControlName*) cds->lpData;
AnsiString sName(pName->Value, pName->Length);
// locate pName->hWnd in your list and assign sName to it as needed...
return;
}
}
TForm::WndProc(Message);
}
void ___fastcall TMyForm::FillList()
{
...
if (WM_GETCONTROLNAME != 0)
{
HWND TheControlHWND = ...;
HWND OtherAppHWND = ...;
PostMessage(OtherAppHWND, WM_GETCONTROLNAME, (WPARAM)TheControlHWND, (LPARAM)this->Handle);
}
...
}
const UINT WM_GETCONTROLNAME = RegisterWindowMessage("WM_GetControlName");
const UINT WM_GETCONTROLNAME_RESULT = RegisterWindowMessage("WM_GetControlName_Result");
#include <pshpack1.h>
struct sControlName
{
HWND hWnd;
int Length;
char Value[1];
};
#include <poppack.h>
void __fastcall TMyForm::WndProc(TMessage &Message)
{
if ((Message.Msg == WM_GETCONTROLNAME) && (WM_GETCONTROLNAME != 0) && (WM_GETCONTROLNAME_RESULT != 0))
{
HWND hWnd = (HWND) Message.WParam;
TWinControl *Ctrl = FindControl(hWnd);
if (Ctrl)
{
AnsiString sName = Ctrl->Name;
std::vector<unsigned char> buffer((sizeof(sControlName) - 1) + sName.Length());
sControlName *pName = (sControlName*) &buffer[0];
pName->hWnd = hWnd;
pName->Length = sName.Length();
strncpy(pName->Value, sName.c_str(), pName->Length);
COPYDATASTRUCT cds = {0};
cds.dwData = WM_GETCONTROLNAME_RESULT;
cds.cdData = buffer.size();
cds.lpData = pName;
SendMessage((HWND)Message.LParam, WM_COPYDATA, (WPARAM)this->Handle, (LPARAM)&cds);
}
return;
}
TForm::WndProc(Message);
}