如何获取另一程序子窗口中StringGrid Cell中的内容

foxe 2011-12-14 09:57:35
网上获知,无法直接通过StringGrid的handle通过WM_GetText获取。
查看了DLL注入,参考后写了如下代码,但仍无法获取,请大家帮忙。
写了一个取注入记事本的,然后取记事本的标题,但未成空

TestDll.dpr

library TestDll;

uses
SysUtils,
Windows,
Controls,
Classes,
forms,Dialogs,
dllUnit1 in 'dllUnit1.pas';

{$R *.res}

var
hFrm:TForm;
h:HWND;
begin
h := Findwindow('notepad',nil);
ShowMessage(inttohex(h,8));
hFrm:=TForm(FindControlNew(h));
ShowMessage(hFrm.Caption);
end.


dllUnit1.pas

unit dllUnit1;

interface

uses windows,controls,Forms,SysUtils;

function FindControlNew(Handle: HWnd): TWinControl;

implementation

var
ControlAtom: TAtom;
ControlAtomString: string;
RM_GetObjectInstance: DWORD; // registered window message


function FindControlNew(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;

initialization
ControlAtomString := Format('ControlOfs%.8X%.8X', [GetModuleHandle(nil), GetCurrentThreadID]);
ControlAtom := GlobalAddAtom(PChar(ControlAtomString));
RM_GetObjectInstance := RegisterWindowMessage(PChar(ControlAtomString));
finalization
GlobalDeleteAtom(ControlAtom);
ControlAtomString := '';

end.



主程序

unit d7exeunit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

//注入部分代码
function InjectDLLToTarget(dllName:string;TargetProcessID:DWORD):boolean;
var
libname:pointer;
hprocess,threadhandle:longword;
BytesWritten,TheadID:DWORD;
begin
result:=false;
hprocess:=OpenProcess(PROCESS_ALL_ACCESS,FALSE,TargetProcessID);
if(hprocess=0) then exit;
//为宿主进程分配空间
LibName:=VirtualAllocEx(hprocess,0,length(dllName)+5,MEM_COMMIT,PAGE_READWRITE);
if(LibName<>nil) then
begin
//写入要待注入线程的路径到进程空间地址中 --其中工作包括我们上面分析的几个步骤
WriteProcessMemory(hprocess,LibName,pchar(dllName),length(dllName),BYtesWritten);
end;
threadhandle:=CreateRemoteThread(hprocess,nil,0,
GetProcAddress(LoadLibrary('kernel32.dll'),'LoadLibraryA'),
LibName,0,TheadID);
result:=threadhandle<>0;
WaitForSingleObject(threadhandle,INFINITE);
VirtualFreeEx(hprocess,LibName,0,MEM_RELEASE); //释放dll占用的空间
CloseHandle(hprocess);
end;


procedure TForm1.Button1Click(Sender: TObject);
var
h,ThreadHandle:longword; //放句柄,中间顺便暂放下PID
tmp:longword;//这个专门来占格式收集垃圾
DllName:pchar;
Mysize:longword;//放字符串长度
Parameter:pointer;//放那个参数的指针(位置在目标进程内)
DllModule, SendPro, WriteCount: DWORD;
ExitPro, ExitTPro: DWORD;
str:pchar;
begin
DLLName:='TestDll.dll';
Mysize:=strlen(Dllname)+1;
winexec('notepad',1);
GetWindowThreadProcessId(FindWindow('notepad', nil), @h);
InjectDLLToTarget(dllname,h);
//h:=OpenProcess(PROCESS_ALL_ACCESS, False, h);
{Parameter:= VirtualAllocEx(h, nil, Mysize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(h, Parameter, @DllName, MySize, tmp);
CreateRemoteThread(h,nil, 0,
GetProcAddress(GetModuleHandle('KERNEL32.DLL'),'LoadLibraryA'),
Parameter, 0 , tmp);}

end;
...全文
246 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
一剑飘雪 2012-01-16
  • 打赏
  • 举报
回复
楼主解决了吗
我的一个疑问就是截取别人的grid数据
蓝色光芒 2012-01-16
  • 打赏
  • 举报
回复
参考这个
http://topic.csdn.net/u/20120106/12/fcc2dbfe-b06b-45a8-ab51-7fd74d7d3f71.html
foxe 2011-12-19
  • 打赏
  • 举报
回复
谢谢各位,终于有回复了。
一剑飘雪 2011-12-19
  • 打赏
  • 举报
回复
我记得半水大哥以前写过
而且我也获取到了。
楼主可以搜搜
代码跳动 2011-12-19
  • 打赏
  • 举报
回复
已经注入了,下面应该适用.

procedure TForm1.Button1Click(Sender: TObject);
var

fori,vi : integer;
begin

vi:=1;

for fori := 0 to self.ControlCount -1 do

begin



if not (self.Controls[fori] is TEdit ) then continue;



(self.Controls[fori] as TEdit ).Text:= 'edit '+inttostr(vi);



inc(vi);

end;
end;
-------------------------------------------
如果你的Edit放在panel上面 就把 self 换为 panel
-------------------------------------------
这个最主要的就是:
self.Controls[fori] is TEdit 和
self.Controls[fori] as TEdit

代码跳动 2011-12-19
  • 打赏
  • 举报
回复
var
title: pchar;

h:=Findwindow('notepad',nil);
GetWindowText(h, title, 255);

得到句柄后就可以遍历他的子窗体控件;

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧