+ -
当前位置:首页 → 问答吧 → 如何获取另一程序子窗口中StringGrid Cell中的内容

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

时间:2011-12-14

来源:互联网

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

TestDll.dpr
Delphi(Pascal) code

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
Delphi(Pascal) code

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.




主程序
Delphi(Pascal) code

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;

作者: foxe   发布时间: 2011-12-14

var
  title: pchar;

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

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

作者: zhangqiwen   发布时间: 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 

作者: zhangqiwen   发布时间: 2011-12-19

该回复于2011-12-19 09:27:05被管理员删除

  • 对我有用[0]
  • 丢个板砖[0]
  • 引用
  • 举报
  • 管理
  • TOP
#4楼 得分:0回复于:2011-12-19 09:36:34
我记得半水大哥以前写过
而且我也获取到了。
楼主可以搜搜

作者: sgzhou12345   发布时间: 2011-12-19