unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, commctrl;
type
TForm1 =
class(TForm)
ListBox1: TListBox;
ListFensterButton: TButton;
GetListViewButton: TButton;
procedure ListFensterButtonClick(Sender: TObject);
procedure GetListViewButtonClick(Sender: TObject);
procedure get_lv_items(wnd:hwnd);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function EnumChildProc(wnd:hwnd; lparam:integer):bool;
stdcall;
var listbox:Tlistbox;
classname:
array[0..127]
of char;
begin
listbox:=TListbox(lparam);
getclassname(wnd,classname,127);
listbox.Items.add('
$'+inttohex(wnd,8)+'
='+classname);
end;
procedure TForm1.ListFensterButtonClick(Sender: TObject);
var wnd:hwnd;
begin
wnd:=findwindow(
nil,'
Windows Media Player');
listbox1.Items.Add(inttohex(wnd,8));
enumchildwindows(wnd,@enumchildproc,integer(self.ListBox1));
end;
procedure TForm1.GetListViewButtonClick(Sender: TObject);
var wnd:hwnd;
i,count:integer;
item:lv_item;
processid:integer;
begin
wnd:=0;
for i:=0
to listbox1.Count-1
do if listbox1.Selected[i]
then
begin
wnd:=strtoint(listbox1.Items.Names[i]);
break;
end;
listbox1.Clear;
get_lv_items(wnd);
end;
procedure TForm1.get_lv_items(wnd:hwnd);
var i,count:integer;
item:lv_item;
pitem:pointer;
process,processid:cardinal;
text:
array[0..127]
of char;
ptext:pointer;
tmp:cardinal;
begin
//Anzahl der Einträge in Listview ermitteln
count:=sendmessage(wnd,lvm_getitemcount,0,0);
listbox1.Items.Add('
Anzahl: '+inttostr(count));
//ID vom Zielprocess ermitteln
getwindowthreadprocessid(wnd,processid);
if processid=0
then raise Exception.create('
Fehler bei ProcessID');
//Handle auf Zielprocess bekommen
process:=openprocess(PROCESS_ALL_ACCESS,false,processid);
if process=0
then raise Exception.Create('
Kein Zugriff auf Process');
try
//Speicher für String im fremden Process reservieren
ptext:=virtualallocEx(process,
nil,sizeof(text),mem_commit,PAGE_READWRITE);
if ptext=nil
then raise Exception.Create('
Kein freier Speicher im Process');
//Speicher für Record im fremden Process reservieren
pitem:=virtualallocEx(process,
nil,sizeof(lv_item),mem_commit,PAGE_READWRITE);
if pitem=nil
then
begin
virtualfreeEx(process,ptext,sizeof(text),mem_decommit);
raise Exception.Create('
Kein freier Speicher im Process');
end;
//Record füllen (mit pszText auf reservierten Speicher für String
item.mask:=LVIF_TEXT;
item.iSubItem:=0;
item.pszText:=ptext;
item.cchTextMax:=sizeof(text)-1;
for i:=0
to count-1
do
begin
item.iItem:=i;
//welchen Eintrag?
//record in anderen Process kopieren
if writeprocessmemory(process,pitem,@item,sizeof(item),tmp)
then
begin
//Message senden (liest den record und füllt damit psztext,
//also den reservierten "Stringspeicher")
if bool(sendmessage(wnd,lvm_getitem,0,integer(pitem)))
then
begin
//String auslesen
if readprocessmemory(process,ptext,@text,sizeof(text),tmp)
then
begin
//..und anzeigen
listbox1.Items.Add(text);
end;
end;
end;
end;
//Speicher im anderen Process freigeben
virtualfreeEx(process,ptext,sizeof(text),mem_decommit);
virtualfreeEx(process,pitem,sizeof(lv_item),mem_decommit);
finally
//Handle freigeben
closehandle(process);
end;
end;
end.