Delphi-PRAXiS
Seite 1 von 12  1 2311     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Zugriff auf ein TImage einer externen Anwendung (https://www.delphipraxis.net/86561-zugriff-auf-ein-timage-einer-externen-anwendung.html)

KoS 15. Feb 2007 16:57


Zugriff auf ein TImage einer externen Anwendung
 
Hallo,

ist es möglich das TImage einer anderen Applikation zu kontrollieren, bzw. andere Bilder hinein zu schreiben?
Wenn ja, wie?
Ich weiß sicher das es sich um ein TImage handelt und den Namen habe ich auch, jetzt stellt sich mir die Frage wie ich darauf zugreifen kann. Ich habe so mit Handles und WindowsAPI keine Erfahrungen.

Vielen Dank!

Gruß KoS

sirius 15. Feb 2007 17:03

Re: Zugriff auf ein TImage einer externen Anwendung
 
Das TImage selber kannst du dir nicht holen. Aber du kannst dir den Device Context des Fensters holen und da drauf rumkritzeln, bzw. du kapselst den DC in ein eigenes TCanvas.

Erklär mal genauer, wo du rummalen willst!

KoS 15. Feb 2007 17:10

Re: Zugriff auf ein TImage einer externen Anwendung
 
Hm wie erklär ich das jetzt am besten ...

Ich habe hier ein Programm welches ein Formular mit mehreren TImages hat, und ich möchte nun den Inhalt der TImages ändern, d.h. also ein neues Bild rein setzten.

sirius 18. Feb 2007 19:05

Re: Zugriff auf ein TImage einer externen Anwendung
 
Das Problem ist, dass TImage ein TGraphicControl ist und somit kein eigenes Window-Handle besitzt. Du kannst eigentlich nur auf dass dem TImage zugrundeliegende Window zeichnen. Ansonsten müsste man sich sehr weit in die Datenstruktur von Delphi einarbeiten.

Neutral General 18. Feb 2007 19:08

Re: Zugriff auf ein TImage einer externen Anwendung
 
Also ich habe mal ne "Idee" das was ich hier schreibe kann totaler Schwachsinn sein aaaaber...

TImage.Picture.BITMAP

und

TImage.CANVAS

und

TImage.Picture.Bitmap.CANVAS

haben alle Handles... Vielleicht wäre da ja was zu machen... Ich wüsste im ersten Moment auch nicht wie aaaaber ich gucke mal (*juhu endlich was zu tun bei meiner langeweile :)*) :coder:

Gruß
Neutral General

KoS 19. Feb 2007 08:34

Re: Zugriff auf ein TImage einer externen Anwendung
 
Hallo,

@sirius: Im grunde wäre das ja relativ egal, wenn man dann die Positionen Top und Left bekommen könnte um dann darüber ein Bild zu zeichnen, da die TImages immer einen gewissen Abstand zueinander haben.

@Neutral General: Wäre super wenn du ein weg finden würdest die TImages anzuprechen.

sirius 19. Feb 2007 09:27

Re: Zugriff auf ein TImage einer externen Anwendung
 
@General
Das sind Device Context Handles und keine Window Handles.

turboPASCAL 19. Feb 2007 09:33

Re: Zugriff auf ein TImage einer externen Anwendung
 
Zwischenfrage, ist das sicher das es sich bei den Bildern um ein TImage handelt ?
Wenn das Bild (ist und bleibt ein Bitmap wenn es Windows zeichnet) direkt gezeichnet wird in einer
sagen wir mal WM_PAINT - Message ist es nicht möglich zu "covern".

KoS 19. Feb 2007 11:22

Re: Zugriff auf ein TImage einer externen Anwendung
 
Ja, es ist sicher das es sich um ein TImage handelt, weil ich das Form schonmal mittels ResHack unter die Lupe genommen habe.

Ob das TImage ein *.bmp oder ein *.jpg darstellt, wenn es denn überhaupt was darstellt ist ja egal?

Edit: ähm ... mal ein anderer Ansatz, es dürfte aber möglich sein direkt etwas auf das Form ein Bild zu malen wenn man entsprechende Positionsangaben machen kann? Da die TImages ja immer auf der selben Position sitzen und lediglich die Bilder ändern.

sirius 19. Feb 2007 12:34

Re: Zugriff auf ein TImage einer externen Anwendung
 
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='TImage' then 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.


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:59 Uhr.
Seite 1 von 12  1 2311     Letzte »    

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz