Einzelnen Beitrag anzeigen

Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#10

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 19. Feb 2007, 13:34
Auf einem Window rumzeichnen geht so:
Delphi-Quellcode:
var dc:hdc; //Device Context Handle
    Canvas:Tcanvas;
    myhandle:THandle;
begin

  //Devicecontext eines Window Handles besorgen

  //myhandle:=form1.Handle; //so
  //myhandle:=button2.Handle; //oder so
  //myhandle:=getforegroundwindow; //oder so
  myhandle:=getdesktopwindow; //oder so oder mit findwindow ...
  
  dc:=getwindowdc(myhandle);

  //TCanvas auf den Device Context setzen
  canvas:=TCanvas.Create;
  canvas.Handle:=dc;

  //Hier kann man ganz nach belieben malen
  canvas.Brush.Color:=clbtnface;
  canvas.Font.Color:=clred;
  canvas.Font.Size:=15;
  canvas.TextOut(0,0,'Hallo');

  //Speicher wieder freigeben
  canvas.Free;
  releasedc(myhandle,dc);
end;

Ergänzung:
Mit folgendem Code kann man ein TImage finden, wenn man nur das WindowHandle, des übergeordneten Fensters hat:
(mein Testcode)
Delphi-Quellcode:
var pi,p,pm:ppointer;
    s:string;
    c:pchar;
    i,a:integer;
begin
  memo1.clear;
  myhandle:=form1.handle; //myhandle ist das einzige, was ich benötige

  p:=pointer(getwindowlong(myhandle,gwl_wndproc)+35);


  pm:=p;
  p:=p^;
  p:=pointer(integer(p^)-44);
  p:=p^;
  c:=pchar(p);
  s:='';
  inc(c);
  for i:=1 to pbyte(p)^ do begin
    s:=s+c^;
    inc(c);
  end;
  memo1.lines.Add(s); //classname des Windows

  pm:=pointer(integer(pm^)+16);

  for a:=0 to pinteger(integer(pm^)+8)^-1 do begin //von 0 bis componentcount

    p:=pointer(integer(pm^)+4);
    p:=pointer(integer(p^)+4*a);
    pi:=p; //pi^ ist Zeiger auf ein Objekt


    p:=p^;
    p:=pointer(integer(p^)-44);
    p:=p^;
    c:=pchar(p);
    s:='';
    inc(c);
    for i:=1 to pbyte(p)^ do begin
      s:=s+c^;
      inc(c);
    end;
    memo1.lines.Add(s); //classname einer Komponente

    if s='TImagethen begin
      memo1.lines.Add(inttostr(pinteger(integer(pi^)+$40)^)); //left
      memo1.lines.Add(inttostr(pinteger(integer(pi^)+$44)^)); //top
      memo1.lines.Add(inttostr(pinteger(integer(pi^)+$48)^)); //widht
      memo1.lines.Add(inttostr(pinteger(integer(pi^)+$4C)^)); //height
    end;

  end;
Ich hab jetzt keine weiteren Kommentare, da ich nur ein wenig rumgespielt habe. Letztenendes macht es nix andere, als:
Delphi-Quellcode:
for i:=0 to Form1.componentcount-1 do begin
  memo1.lines.add(Form1.component[i].classname);
  //Und wenn classname TImage ist, dann noch die Abmaße aufschreiben
end;
Allerdings passiert dies ohne Zuhilfenahme der VCL, bezieht sich allerdings strikt darauf.
Das funktioniert also für alle Programme, die mit Hilfe der VCL programmiert wurden. Allerdings wird das ganze noch etwas umständlicher, wenn man sich in einem fremden Prozess befindet (siehe virtueller Addressraum).

PS: Diese ganze Type-casting zwischen integer und pointer könnte man sich natürlich mit ASM sparen.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat