我想获取外部程序Label的caption,具体见http://topic.csdn.net/u/20090313/19/ae2b7f38-43de-4b9b-be52-ed28f6ddeba7.html我已经尝试了好几个思路了,现在在这样考虑:用Label显示或者更新数据,就用label2.caption='XXX',那么我要获取该数据(即Label的caption),可以考虑HOOK API,但是在Delphi里面label2.caption='XXX'是通过什么函数来实现的呢?label是个类?caption是Label类的一个成员变量吗?还是怎么回事?不明白这个,即使想HOOK API也不知道该hook哪个API函数啊,哎。
或者各位有什么其它办法或者思路可以获取目标进程界面的Label,也可以拿出来一起探讨,谢谢!!!!!!!
小弟一直没怎么接触过Delphi,请各位指教!!谢谢。
或者各位有什么其它办法或者思路可以获取目标进程界面的Label,也可以拿出来一起探讨,谢谢!!!!!!!
小弟一直没怎么接触过Delphi,请各位指教!!谢谢。
请问:目标界面上有很多的Label,我要获取每个的caption。它textout出来的是所有Label的caption总和吗?
如果是这样,它既然可以分Label1.caption,,Label2.caption等等分别的表示出来,那我能否也一一分别截获下来呢?而不是一股脑的截获所有的caption混在一起。谢谢QQ286251099,也请各位老大都过来指点小弟几招!!
procedure EnumChildProc(hwnd: HWND; lparam: LPARAM); stdcall;
var
wndClassName: array[0..255] of Char;
WndCaption: array[0..255] of Char;
begin
GetClassName(hwnd, wndClassName, 255);
GetWindowText(hwnd, WndCaption, 255);
if GetClassName = 'Tlable' then
....
end;procedure TForm1.Button3Click(Sender: TObject);
var
handle: HWND;
begin
handle := FindWindow(nil, PChar(FormCaption));
if 0 <> handle then
EnumChildWindows(handle, @EnumChildProc, 0);
end;
你能不能解释下你的代码?
GetClassName(hwnd, wndClassName, 255);你这个hwnd怎么得到呢?Label是没有句柄的。。而且我要得到外部程序的caption, GetWindowText貌似只能得到自己程序的内容,外部程序是不行的。
请问你说的caption的句柄是什么意思?我很菜,你能不能多解释一下?
function FindControl(Handle: HWnd): TWinControl;
begin
Result := nil;
if (Handle <> 0) then
begin
if GlobalFindAtom(PChar(ControlAtomString)) = ControlAtom then
Result := Pointer(GetProp(Handle, MakeIntAtom(ControlAtom)))
else
Result := ObjectFromHWnd(Handle);
end;
end;由于,进程间内存地址是相对的,所以直接访问这个对象会出现内存异常。procedure InitControls;
var
UserHandle: HMODULE;
begin
WindowAtomString := Format('Delphi%.8X',[GetCurrentProcessID]);
WindowAtom := GlobalAddAtom(PChar(WindowAtomString));
ControlAtomString := Format('ControlOfs%.8X%.8X', [HInstance, GetCurrentThreadID]);
ControlAtom := GlobalAddAtom(PChar(ControlAtomString));
RM_GetObjectInstance := RegisterWindowMessage(PChar(ControlAtomString));
//...
end;另外FindControl函数用到的变量(如:WindowAtomString)和具体线程ID有关。大概的步骤是:
1、创建一个hook,以便跨进程访问内存空间;
2、自定义FindControl方法,按目标窗体所在线程组装参数;
3、获得TWinControl对象;
4、通过WM_COPYDATA消息返回查询内容。关键代码:
(*//
标题:窗体嗅探器
作者:王集鹄(Zswang)
博客:http://blog.csdn.net/zswang
日期:2009年3月14日
.//*)unit Sniffer;interfaceuses Windows;function ExeSniffer( // 执行嗅探
AHandle: THandle; // 窗体句柄
AParam: Integer // 附加参数
): BOOL; stdcall;implementation// 尊重作者,转贴请注明出处 王集鹄(Zswang) 2009年3月14日uses SysUtils, Classes, Controls, StdCtrls, Messages;var
WM_SNIFFWINDOW: Longword;type
TSnifferInfo = packed record
rHOOK: HHOOK;
rHandle: HWND;
rParam: Integer;
end;
PSnifferInfo = ^TSnifferInfo;var
vMapFile: THandle;
vSnifferInfo: PSnifferInfo;var
ControlAtom: TAtom;
ControlAtomString: string = '';
RM_GetObjectInstance: DWORD; // registered window messagefunction FindControl(Handle: HWnd): TWinControl;
var
OwningProcess: DWORD;
begin
Result := nil;
if (Handle <> 0) and (GetWindowThreadProcessID(Handle, OwningProcess) <> 0) and
(OwningProcess = GetCurrentProcessId) then
begin
if GlobalFindAtom(PChar(ControlAtomString)) = ControlAtom then
Result := Pointer(GetProp(Handle, MakeIntAtom(ControlAtom)))
else
Result := Pointer(SendMessage(Handle, RM_GetObjectInstance, 0, 0));
end;
end; { FindControl }function SnifferProc(code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT; stdcall;
var
vWinControl: TWinControl;
vCopyDataStruct: TCopyDataStruct;
I: Integer;
S: string;
begin
case code of
HC_ACTION:
begin
if PCWPStruct(lParam)^.message = WM_SNIFFWINDOW then
begin
if ControlAtomString = '' then
begin
ControlAtomString := Format('ControlOfs%.8X%.8X', [
GetWindowLong(vSnifferInfo^.rHandle, GWL_HINSTANCE),
GetWindowThreadProcessId(vSnifferInfo^.rHandle)]);
ControlAtom := GlobalAddAtom(PChar(ControlAtomString));
RM_GetObjectInstance := RegisterWindowMessage(PChar(ControlAtomString));
end;
vWinControl := FindControl(vSnifferInfo^.rHandle);
if Assigned(vWinControl) then
begin
for I := 0 to vWinControl.ComponentCount - 1 do
begin
S := '';
if SameText(vWinControl.Components[I].ClassName, 'TLabel') then
begin
S := Format('%s: %s', [vWinControl.Components[I].Name,
QuotedStr(TLabel(vWinControl.Components[I]).Caption)]);
end else if SameText(vWinControl.Components[I].ClassName, 'TMemo')
or SameText(vWinControl.Components[I].ClassName, 'TEdit') then
begin
S := Format('%s: %s', [vWinControl.Components[I].Name,
QuotedStr(TLabel(vWinControl.Components[I]).Caption)]);
end;
vCopyDataStruct.cbData := Length(S);
vCopyDataStruct.dwData := 0;
vCopyDataStruct.lpData := @S[1];
SendMessage(vSnifferInfo^.rParam, WM_COPYDATA,
vSnifferInfo^.rHandle, Integer(@vCopyDataStruct));
end;
end;
end;
end;
end;
Result := CallNextHookEx(vSnifferInfo^.rHOOK, code, wParam, lParam);
end;function ExeSniffer( // 执行嗅探
AHandle: THandle; // 窗体句柄
AParam: Integer // 附加参数
): BOOL; stdcall;
begin
vSnifferInfo^.rHandle := AHandle;
vSnifferInfo^.rParam := AParam;
vSnifferInfo^.rHOOK := SetWindowsHookEx(
WH_CALLWNDPROC, SnifferProc, HInstance, GetWindowThreadProcessId(AHandle));
Result := SendMessageTimeout(AHandle, WM_SNIFFWINDOW, 0, 0,
SMTO_NORMAL, 3000, THandle(Result)) = 0;
UnhookWindowsHookEx(vSnifferInfo^.rHOOK);
end;initialization
WM_SNIFFWINDOW := RegisterWindowMessage('SnifferLib.SniffWindow');
vMapFile := OpenFileMapping(FILE_MAP_ALL_ACCESS, False, '~Sniffer');
if vMapFile = 0 then
vMapFile := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,
SizeOf(TSnifferInfo), '~Sniffer');
vSnifferInfo := MapViewOfFile(vMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);finalization
UnmapViewOfFile(vSnifferInfo);
CloseHandle(vMapFile);end.
不过要花10个资源分(50个可用分)
如果资源分不足可以用:可用分兑换资源分(5:1)
我先把你的代码理一下,你知道对于我这样的菜鸟没个半天时间消化不了,分一定给,这个绝对不是问题,要是这30分不够我都可以另外开个帖子给你分,,
先把zswang的代码消化下,结贴去也。。
谢谢指教!!