AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Zugriff auf ein TImage einer externen Anwendung
Thema durchsuchen
Ansicht
Themen-Optionen

Zugriff auf ein TImage einer externen Anwendung

Ein Thema von KoS · begonnen am 15. Feb 2007 · letzter Beitrag vom 21. Mär 2007
Antwort Antwort
Seite 3 von 12     123 45     Letzte »    
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#21

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 20. Feb 2007, 15:51
Zitat von sirius:
@namenlozer(ihr wisst anscheinend noch nicht, was virtueller Adressraum bedeutet -->unbedingt mal bei Wiki oder so reinlesen).
Also eigentlich schon, aber da dein code so kompliziert aussah, bin ich davon ausgegangen, dass er das umgeht xD
  Mit Zitat antworten Zitat
KoS

Registriert seit: 9. Jun 2006
55 Beiträge
 
#22

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 20. Feb 2007, 16:03
Das die von Canvas gezeichnete Grafik verschwindet ist mir schon aufgefallen, sollte aber hoffe ich kein Problem darstellen. Oder gibt es da noch ne Möglichkeit das ganze (ohne ein Timer) permanent sichtbar zu machen?
--- Hehe, da is mir grad was witziges eingefallen. Es müsste doch eigentlich klappen wenn ich ein eigenes Form für jedes Image erstelle es an die entsprechende Position schiebe, Border:=None und Always OnTop. Allerdings wäre dann das Orginal-Bild nicht mehr mittels OnClick ausführbar, das müsste man dann auch wieder durchschleifen, Fenster schließen und ein Mouse-Click event auf diesen Punkt ausführen. Ich glaub das wird jetzt aber etwas zu ausführlich

Also bisher läuft alles was du fabriziert hast super!
Das einzige was mir aufgefallen ist wenn ich versuche das Caption eines TButton auszulesen das sich dann die fremde Anwendung killt. Aber das war auch nur ein test und wir nicht in der Praxis angewand. Nur ne allgemeine Info.

Die bisher letzte Frage die ich hätte bezieht sich auf Optimierung.
Ich hab jetzt eine Prozedur geschrieben die das Event aus dem ButtonClick ausführt und ich nur den Komponenten/ClassNamen sowie den SearchType übergeben muss. Wie kann man das ganze noch mehr Optimieren und nur die zeilen ausführen die wirklich für die Datenbeschaffung gebraucht werden? D.h. die Handler Zuweisung kann ich ja z.B. außerhalb der Prozedur machen. Aber ich weiß hier eben nicht was speziell für das beziehen der Informationen nötig ist bzw. was zusammen hängt.

Es sollen letztendlich mehrere Abfragen hintereinander durchgeführt werden, die Informationen gesammelt und dann weitere Aktion wie z.B. die Bilder zeichnen durchgeführt werden.

Vielen Dank!

Hier mal meine leicht modifizierte Prozedur:
Delphi-Quellcode:
procedure TForm1.GetData(ComponentName: string; SearchType : TSearchtype);
var mem:TMemory;
    lib:THandle;
    size:integer;
    process:cardinal;
    processid:cardinal;
    procmem:PMemory;
    tmp:cardinal;
    threadID:cardinal;
    thread:THandle;
begin
  memo1.clear;
  myhandle:=findwindow(nil,'PImage'); //Beispielprogramm finden
  if myhandle=0 then exit;

  //mem ist der Record der nachher in den anderen Process kopiert wird
  mem.backwnd:=self.Handle; //Handle, damit wir Nachrichten zurückschicken können
  mem.backmsg:=mymsg; //Message-Nr., damit wir unsere Message wiederfinden
  mem.watchwnd:=myhandle; //Das Handle für getwindowlong
  mem.count:=6; //welches TControl (=mem.vgl)? (nur für Searchtype=sClassName)
  StrPCopy(@mem.vgl,ComponentName);
  mem.vgllength:=Length(ComponentName); //Länge des Vergleichsstrings
  mem.SearchType:=SearchType; //vgl vergleichen mit Classname oder Name oder Caption zurücksenden
  //kopieren der funktion injectthread in den Record
  size:=integer(@endpoint)-integer(@injectThread);
  move(injectthread,mem.thread,size);
  //EinsprungAdresse von 3 WinAPI-funktionen, die nacher benötigt werden
  //Die Adressen sind in jedem Process gleich
  lib:=getmodulehandle('user32.dll');
  mem.Postmessage:=getprocaddress(lib,'PostMessageA');
  mem.getwindowlong:=getprocaddress(lib,'GetWindowLongA');
  lib:=getmodulehandle('kernel32.dll');
  mem.exitthread:=getprocaddress(lib,'ExitThread');

  //Thread-Record in anderen Process kopieren und mem.Thread starten
  getwindowthreadprocessid(myhandle,@processid);
  process:=openprocess(PROCESS_ALL_ACCESS,false,processid);
  //Speicher reservieren
  procmem:=virtualallocex(process,nil,sizeof(Tmemory),MEM_COMMIT,PAGE_EXECUTE_READWRITE);
  //Kopieren
  writeprocessmemory(process,procmem,@mem,sizeof(TMemory),tmp);
  //Starten
  thread:=createremotethread(process,nil,0,@procmem.thread,procmem,0,threadid);
  //Warten bis injectthread beendet ist

  waitforsingleobject(thread,infinite);
  //Speicher wieder freigeben
  closehandle(thread);
  virtualfreeex(process,procmem,0,mem_decommit);
  closehandle(process);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
    GetData(Edit1.Text,sName);
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
    GetData(Edit2.Text,sCaption);
end;
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

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

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 20. Feb 2007, 16:04
Zitat von NamenLozer:
Zitat von sirius:
@namenlozer(ihr wisst anscheinend noch nicht, was virtueller Adressraum bedeutet -->unbedingt mal bei Wiki oder so reinlesen).
Also eigentlich schon, aber da dein code so kompliziert aussah, bin ich davon ausgegangen, dass er das umgeht xD
Naja, was heist kompliziert? Ein bisschen Adressrechnung, mehr ist es ja nicht. Sieht wahrscheinlich von außen nur ein wenig verstrickt aus.
Aber die Sicherheiten der CPU umgehen, schaffe ich so einfach nicht, dazu brauche ich schon Windows und die WIN-API
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

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

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 20. Feb 2007, 20:21
Zitat von KoS:
Das die von Canvas gezeichnete Grafik verschwindet ist mir schon aufgefallen, sollte aber hoffe ich kein Problem darstellen. Oder gibt es da noch ne Möglichkeit das ganze (ohne ein Timer) permanent sichtbar zu machen?
Ja, das geht. Irgendjemand hatte ja bereits erwähnt, dass du die WM_Paint Message (an das fremde Formular) abfangen musst.

Zitat von KoS:
Es müsste doch eigentlich klappen wenn ich ein eigenes Form für jedes Image erstelle es an die entsprechende Position schiebe,
Ach nee, die jetzige Variante ist schon besser. Man könnte nur noch überlegen, von TCanvas wegzugehen und mit der Win-API direkt auf den DC (Device Context) zu zeichen. Dazu brauchst du allerdings das Original als Bitmap... ist nur so ne Idee. Tcanvas macht wahrscheinlich auch nix anderes als "BitBlt" von Windows.

Zitat von KoS:
Also bisher läuft alles was du fabriziert hast super!
Das einzige was mir aufgefallen ist wenn ich versuche das Caption eines TButton auszulesen das sich dann die fremde Anwendung killt. Aber das war auch nur ein test und wir nicht in der Praxis angewand. Nur ne allgemeine Info.
Das war höchst wahrscheinlich, dass dies nicht klappt. Weil ein TButton ja ein wenig anders aufgebaut ist. Dadurch funktioniert die Adressrechnugn nicht mehr und ich greife auf eine Adresse zu, wo ich keinen Zugriff habe ->EAccessViolation und das Programm, in dem sie auftrat (also der fremde Process) stürzt ab.
Aber ein TButton stammt von TWinControl ab, da kommt man meist recht einfach an den Text ran. Der Button hat ja schonmal ein "echtes" Window-Handle.

Zitat von KoS:
Die bisher letzte Frage die ich hätte bezieht sich auf Optimierung.
Da kann man sicherlich noch einiges optimieren. Du kannst ja das TMemory vorbereiten und musst es nicht jedesmal neu füllen, oder nur den Teil den du änderst. Alles ab " getwindowthreadprocessid" würde ich ungern auseinanderreißen, außer man programmiert alles um.
Da ich nicht genau weis, in welcher Reihenfolge und zu welcher Zeit du die Infos brauchst, fällt es mir schwer darauf zu optimieren.
Wenn ich allerdings die Sache mit WM_Paint mit reinbringe wird die Sache wahrscheinlich gleich ganz kompliziert aussehen, aber dann ist der Rest (mit den Images etc) Nebensache.
Ich versuch mal was.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
KoS

Registriert seit: 9. Jun 2006
55 Beiträge
 
#25

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 20. Feb 2007, 22:05
Lassen wir mal jetzt von dem ganzen Text alles außen vor und sprechen grad nur mal über die Frage der Optimierung.
Geh einfach mal davon aus das ich eine Prozedur haben werden die mittels der gewünschten Funktion den Text eines Labels (sagen wir mal Label_n von 3) holt, was in der Datenbank dazu sucht und ein Bild auf Image_n (ebenfalls von 3) zeichnet.

D.h. die optimierte Prozedur soll dann n mal aufgerufen werden und eben dann auch nicht unbedingt jedes mal den Handle und ich sag mal alle unnötigen sachen neu setzten, sondern sich auf den Kern der Aufgabe konzentrieren und die Daten beschaffen.

Wenn du möchtest kannst du gern mal was mit dem WM_Paint basteln, aber wie gesagt war nur eine Idee vorher mit den Forms und ich denke ich werde auch ein fixes Image nicht benötigen. Genaueres allerdings dazu kann ich erst morgen spät nachmittag geben, sobald ich das ganze mal mit der entsprechenden Anwendung testen kann.

Nochmals vielen Dank!
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

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

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 20. Feb 2007, 23:00
Ok, jetzt wirds ganz konfus. Ich hab auch etwas länger gebraucht als ich eigentlich dachte. Man muss hier so hintenrum denken, da hatte ich ein paar kleine Fehlerchen drinn. Jetzt sind sie hoffentlich alle raus (einer ist ohne mein zutun verschwunden ).

Ich lass dich heute abend erstmal mit dem Code alleine. Erklärungen gibts später, oder auf direkte Anfrage:

Delphi-Quellcode:
unit U_getImage;

interface

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


const mymsg=WM_User+1;

type TSearchtype=(sImageSize,sCaption); //Ich hab die Bezeichnungen mal angepasst und sClassname gibts nicht mehr
type PMemory=^TMemory;
     TMemory=packed record
       newwndProc:array[0..511] of char; //hier kommt die neue WndProc-Funktion für das fremde Window rein
       Thread:array[0..255] of char; //hier kommt die Thread-Funktion rein (die schließlich gestartet wird)
       getInfo:array[0..1023] of char; //hier kommt die Funktion zur Ermiitlung der Infos über Image und Label rein
       //API-Funktionen bzw. deren Addressen
       Postmessage:function(wnd:hwnd;msg,wparam,lparam:cardinal):bool;stdcall;
       exitthread:procedure(exitcode:integer);stdcall;
       sleep:procedure(ms:cardinal);stdcall;
       getwindowlong:function(wnd:hwnd;index:integer):pointer;stdcall;
       setwindowlong:function(wnd:hwnd;index:integer;newvalue:pointer):integer;stdcall;
       callwindowProc:function(proc:pointer;wnd:hwnd;msg,wparam,lparam:cardinal):integer;stdcall;
       globalgetatomname:function(nAtom:cardinal;buf:pointer;size:integer):integer;stdcall;
       getupdaterect:function(wnd:hwnd;rect:prect;erase:bool):bool;stdcall;


       getInfoFunc:procedure(memory:PMemory;wparam,lparam:cardinal);stdcall; //Funktionszeiger auf getInfo, also die Info-Funktion
       
       oldwindowProc:Pointer;//Zeiger auf die alte WndProc
       watchwnd:hwnd;
       backwnd:hwnd;
       backmsg:integer;
       updateRect:TRect;
       running:boolean; //Thread (und newwndProc) läuft bis running=false

     end;



type
  TForm1 = class(TForm)

    Memo1: TMemo;
    Button1: TButton;
    Button2: TButton;
    procedure Button2Click(Sender: TObject);
    procedure GetMyMsg(var msg:TMessage);message mymsg;
    procedure GetMyCaption(var msg:TMessage);message mymsg+1;
    procedure GetCommandMsg(var msg:TMessage);message mymsg+2;
    procedure startObservation;
    procedure stopObservation;
    procedure communicate(vgl:string;Searchtype:TSearchtype);
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private-Deklarationen }
    myhandle:hwnd;
    process:cardinal;
    procmem:PMemory;
    thread:THandle;
    observed:boolean;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function MyWndProc(Memory: PMemory; Wnd: hWnd; Msg,wParam,lParam: Integer): Integer; stdcall; forward;
procedure WndProcDispatcher;
//Funktion zum Finden des Records PMemory
asm
     CALL @@1
@@1: POP EAX
     SUB EAX,5
     POP EDX
     PUSH EAX
     PUSH EDX
     JMP MyWndProc
end;
function MyWndProc(Memory: PMemory; Wnd: hWnd; Msg,wParam,lParam: Integer): Integer; stdcall;
//die neue WindowProc-funktion des fremden Formulars
//die "alte" wird mittels CallWindowproc auch noch aufgerufen
begin
  case msg of
     wm_close:begin
               memory^.running:=false;
               result:=memory^.CallWindowProc(memory^.oldwindowProc,wnd,msg,wparam,lparam);
               memory^.Postmessage(memory^.backwnd,memory^.backmsg+2,msg,0);
             end;
    wm_paint:begin
               memory^.getupdaterect(memory^.watchwnd,@memory^.updaterect,false);
               result:=memory^.CallWindowProc(memory^.oldwindowProc,wnd,msg,wparam,lparam);
               memory^.Postmessage(memory^.backwnd,memory^.backmsg+2,msg,cardinal(@memory^.updateRect));
             end;
    mymsg: begin
               memory^.getinfofunc(memory,wparam,lparam);
               result:=1;
             end;
    mymsg+1: begin
               memory^.running:=false;
               result:=1;
             end;
    else
      result:=memory^.CallWindowProc(memory^.oldwindowProc,wnd,msg,wparam,lparam);
  end;
end;

function injectThread(memory:Pmemory):integer;stdcall;
//Die eigentliche Thread-Funktion
//Hauptaufgabe: einklinken und am Ende wieder ausklinken unserer neuen WndProc
//dazwischen nur sleep, bis die Message mymsg+1 and die neue WndProc kommt
begin
  memory^.running:=true;
  memory^.oldwindowProc:=memory^.getwindowlong(memory^.watchwnd,gwl_wndproc);
  memory^.getInfoFunc:=@memory^.getInfo;
  memory^.setwindowlong(memory^.watchwnd,gwl_wndproc,memory);
  while memory^.running do memory^.sleep(200);
  memory^.setwindowlong(memory^.watchwnd,gwl_wndproc,memory^.oldwindowproc);
  result:=0;
  memory^.exitthread(0);
end;

procedure Info(memory:Pmemory;wparam,lparam:cardinal); stdcall;
//Die bisherige Funktion zum ermitteln und senden der Infos bezüglich TImage und TLabel
var pi,p,pm:ppointer;
    i,a:integer;
    c:pchar;
    left,top,width,height:smallint;
    same:boolean;
    SearchType:TSearchType;
    vgl:array[0..31] of char;
    vgllength:integer;
begin

  Searchtype:=TSearchType(lparam);
  //Da Strings nicht über Messages gesendet werden können, benötigen wir ein Atom
  vgllength:=memory^.GlobalGetAtomName(wparam,@vgl,32);

  wparam:=0;
  lparam:=0;
  p:=pointer(cardinal(memory^.oldwindowproc)+9);


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


  for a:=0 to pinteger(integer(pm^)+8)^-1 do begin //von 0 bis componentcount
    p:=pointer(cardinal(pm^)+4);
    p:=pointer(cardinal(p^)+4*a);
    pi:=p; //pi^ ist Zeiger auf ein Objekt


    p:=pointer(cardinal(p^)+8);
    p:=p^;

    c:=pchar(p);
    same:=false;
    for i:=1 to vgllength do begin
      if vgl[i-1]<>c^ then break;
      same:=i=vgllength;
      inc(c);
    end;
    if same then begin
      if SearchType=sCaption then begin
        p:=pointer(cardinal(pi^)+$64);
        wparam:=cardinal(p^);
        c:=pchar(p^);
        while c^<>#0 do begin
          inc(c);
          inc(lparam);
        end;
        inc(memory^.backmsg);
      end else begin
        left:=pinteger(integer(pi^)+$40)^;
        top:=pinteger(integer(pi^)+$44)^;
        width:=pinteger(integer(pi^)+$48)^;
        height:=pinteger(integer(pi^)+$4C)^;
        wparam:=left*65536+top;
        lparam:=width*65536+height;
      end;
      break;
    end;
  end;
  //Ergebnis Nach Hause senden
  memory^.Postmessage(memory^.backwnd,memory^.backmsg,wparam,lparam);
end;
procedure endpoint;
//ohne Funktion nur zum finden des Address-endes von Info
asm
nop
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  close;
end;

procedure TForm1.startObservation;
//1. Record wird mit allen Infos gefüllt und in den fremden Prozess geschrieben
//2. Thread-Funktion aus dem Record wird gestartet
var mem:TMemory;
    lib:THandle;
    size:integer;
    processid:cardinal;
    tmp:cardinal;
    threadID:cardinal;
begin
  if observed then exit;

  //mem ist der Record der nachher in den anderen Process kopiert wird
  mem.backwnd:=self.Handle; //Handle, damit wir Nachrichten zurückschicken können
  mem.backmsg:=mymsg; //Message-Nr., damit wir unsere Message wiederfinden
  mem.watchwnd:=myhandle; //Das Handle für getwindowlong

  //kopieren der ganzen compilierten Funktionen
  size:=integer(@endpoint)-integer(@Info);
  move(Info,mem.getInfo,size);
  size:=integer(@info)-integer(@injectThread);
  move(injectthread,mem.Thread,size);
  size:=integer(@injectThread)-integer(@wndProcDispatcher);
  move(wndprocdispatcher,mem.newwndproc,size);

  //EinsprungAdresse von allen WinAPI-funktionen, die nacher benötigt werden
  //Die Adressen sind in jedem Process gleich
  lib:=getmodulehandle('user32.dll');
  mem.Postmessage:=getprocaddress(lib,'PostMessageA');
  mem.getwindowlong:=getprocaddress(lib,'GetWindowLongA');
  mem.setwindowlong:=getprocaddress(lib,'SetWindowLongA');
  mem.callwindowproc:=getprocaddress(lib,'CallWindowProcA');
  mem.getupdaterect:=getprocaddress(lib,'GetUpdateRect');
  lib:=getmodulehandle('kernel32.dll');
  mem.exitthread:=getprocaddress(lib,'ExitThread');
  mem.sleep:=getprocaddress(lib,'Sleep');
  mem.globalgetatomname:=getprocaddress(lib,'GlobalGetAtomNameA');
  
  //Thread-Record in anderen Process kopieren und mem.Thread starten
  getwindowthreadprocessid(myhandle,@processid);
  process:=openprocess(PROCESS_ALL_ACCESS,false,processid);
  //Speicher reservieren
  procmem:=virtualallocex(process,nil,sizeof(Tmemory),MEM_COMMIT,PAGE_EXECUTE_READWRITE);
  //Kopieren
  writeprocessmemory(process,procmem,@mem,sizeof(TMemory),tmp);
  //Starten
  thread:=createremotethread(process,nil,0,@procmem.thread,procmem,0,threadid);
  
  observed:=true;

end;
procedure tForm1.stopObservation;
//Thread im fremden Process beenden (+WndProc zurücksetzen) und Speicher freigeben
begin
  if not observed then exit;
  Postmessage(myHandle,mymsg+1,0,0); //Message zum beenden des Threads (über Variable "running")

  waitforsingleobject(thread,infinite); //Warten bis Thread beendet wurde
  
  //Handles und Speicher freigeben
  closehandle(thread);
  virtualfreeex(process,procmem,0,mem_decommit); //Speicher freigeben
  closehandle(process);

  observed:=false;
end;
procedure TForm1.GetMyMsg(var msg:TMessage);
//Message über Image empfangen
begin
  memo1.Lines.add(inttostr(msg.WParamlo));
  memo1.Lines.add(inttostr(msg.WParamhi));
  memo1.Lines.add(inttostr(msg.lParamlo));
  memo1.Lines.add(inttostr(msg.lParamhi));
end;
procedure TForm1.GetMyCaption(var msg:TMessage);
//Message über TLabel empfangen
var process,processID,tmp:cardinal;
    s:string;
begin
  if myhandle=0 then exit;
  //in msg.wparam steht der Pointer auf das TLabel.caption im anderen Process
  //in msg.lparam die Länge des TCaption
  getwindowthreadprocessid(myhandle,@processid);
  process:=openprocess(PROCESS_VM_READ,false,processid);
  setlength(s,msg.LParam);
  readprocessmemory(process,pointer(msg.wparam),@s[1],msg.lparam,tmp);
  closehandle(process);
  memo1.Lines.add(s);
end;
procedure Tform1.getcommandmsg(var msg:Tmessage);
//Message empfangen wenn des fremde Window eine WM_Paint oder WM_close bekommt
var process,processID,tmp:cardinal;
    rec:Trect;
begin
  case msg.WParam of
    wm_paint:begin
      memo1.lines.Add('onPaint');
      if myhandle=0 then exit;
      getwindowthreadprocessid(myhandle,@processid);
      process:=openprocess(PROCESS_VM_READ,false,processid);
      readprocessmemory(process,pointer(msg.lparam),@rec,sizeof(rec),tmp);
      closehandle(process);
      //Der Bereich der neu gezeichnet werden muss
      memo1.lines.add(inttostr(rec.Left));
      memo1.lines.add(inttostr(rec.top));
      memo1.lines.add(inttostr(rec.right));
      memo1.lines.add(inttostr(rec.bottom));
    end;
    wm_close:begin
      observed:=false;
      close;
    end;
  end;
end;

procedure TForm1.communicate(vgl:string;Searchtype:TsearchType);
//Eine Anfrage an unsere neue WndProc starten
var wparam,lparam:cardinal;
begin
  wparam:=globaladdAtom(pchar(vgl)); //String in ein Atom laden; Nr. des Atoms in wparam
  lparam:=cardinal(Searchtype); //Searchtype in lparam
  sendmessage(myhandle,mymsg,wparam,lparam); //Message für unsere newwndproc; und warten bis sie dort verarbeitet wurde
  globaldeleteatom(wparam); //Atom wieder löschen
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  //eine Besipielanfrage an die newwndProc
  communicate('Image1',sImageSize);
  //hier oder in einer anderen Funktion können noch mehr solche Anfragen gestartet werden
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  //myhandle setzen und dann startobservation
  memo1.clear;
  myhandle:=findwindow(nil,'PImage');
  if myhandle=0 then exit;
  startobservation;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  //nicht vergessen!
  stopobservation;
end;

end.
Prinzipielle Idee:
Ich lasse den Thread (der mit StartObservation gestartet wird) in dem anderen Process einfach bestehen und lösche ihn erst mit StopObservation. Dann leite ich die windowProc des Formulars um und bekomme alle Messages an das Formular mit (meine eigenen und z.B. WM_Paint). Deswegen kann ich jetzt mit Messages mit meinem Thread kommunizieren. die "Communicate" kannst du also so oft wie du willst aufrufen. Du musst halt nur zuerst startobservation aufrufen und davor das myHandle setzen. Vergiss nicht stopobservation am Ende, wenn du auch keine WM_Paint Benachrichtigungen mehr willst. ansonsten bleiben Speicherlöcher in dem fremden Process.

PS: WM_close (also wenn das fremde Programm geschlossen wird) schicke ich dir auch noch mit. (Ich hab dann auch gleich mal mein Programm geschlossen.)

PPS: Inspiration und Idee dazu von Hagen (negaH) : hier auf Seite 4

Edit: Kommentare ergänzt

Edit3: alles zu GetUpdateRect ergänzt. Damit kannst du feststellen, ob du überhaupt neu zeichnen musst. Zum vergleichen gibts die Funktion "IntersectRect" von Delphi.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#27

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 21. Feb 2007, 00:06
Jungs, das ist einfach nur krank.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

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

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 21. Feb 2007, 08:55
Zitat von Luckie:
Jungs, das ist einfach nur krank.
Sind das nicht alle Programmierer ?
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
KoS

Registriert seit: 9. Jun 2006
55 Beiträge
 
#29

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 21. Feb 2007, 18:05
Also ich hab jetzt mal die mein Prog mit der richtigen Software getestet und jetzt bin ich doch etwas enttäuscht.
Ich hab zwar noch den Code verwendet den du als vorletztes gepostet hast, aber das düfte ja grundlegend eigentlich kein Unterschied machen.
Das FindWindow klappt ja noch, aber wenn man dann versucht die Daten zu holen, sei es nun vom TImage oder TLabel, schmiert mir der fremde Prozess ab.

Ideen?
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

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

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 21. Feb 2007, 19:32
Zitat von KoS:
Ideen?
Derzeit nicht.

Die Bedingung war ja, dass dein Programm kompatibel zur VCL in D7 ist. Ansonsten funktioniert die Adressrechnung nicht und es kommt zur EAccessViolation. Die könnten wir zwar noch abfangen, aber ein Ergebnis bekommen wir trotzdem nicht.

Ich kann ja noch mal drüber nachdenken, aber außer dass man entweder die VCL (vielleicht ist es ja Delphi2 oder VisualBasic o.ä.) ermittelt und dann über diese Entwicklungsumgebung die Adressen herausfindet fällt mir nur noch Patchen des Programms ein. Aber sowas hab ich das letzte mal unter MS-DOS gemacht. Und es ist alles andere als leichter geworden.
Was ist denn das überhaupt für ein Programm und warum willst du da andere Bilder drüberlegen?

Nochmal zusammengefasst: Das gleiche Programm funktionert bei einem BeispielProgramm und bei dem Originalprogramm nicht. Dann sehe ich auch kaum Chancen. Du musst es ja so sehen, dass ich z.B. bei einem record (kann auch eine Klasse sein; Was es bei uns eigentlich auch immer ist.):
Delphi-Quellcode:
type TTest=record
       irgendetwas:integer;
       meinZeiger:pointer;// den will ich errechnen
       ....
end;
..., wenn ich den Pointer meinZeiger ermitteln will und ich "nur" den Zeiger auf den Record habe, dann addiere ich einfach alles was vor "meinZeiger" liegt. In dem Fall: 1 x Integer ist 1 x 4 Bytes.
Und der Zeiger zeigt dann auf die nächste Klasse, da brauch ich dann auch wieder eine bestimmte Variable bzw. Eigenschaft und addiere wieder eine bestimmte Zahl usw. Und diese Zahlen hab ich natürlich aus meiner VCL von D7 bekommen. Wenn sich an der Reihenfolge oder sonstwie irgendetwas anders ist funktioniert das ganze Konzept nicht mehr. Wenn da eben mal zufällig kein Pointer steht, ist das zwar erstmal egal. Ich lese jede Variable als Pointer, aber dann lande ich irgendwo (ist ja eher eine Zufallsadresse), und das ist zu 99,9% da, wo ich keine Zugriffsrechte hab ->EAccessVirolation. Um ne Hausnummer zu nennen. Der Adressraum beträgt 4GB und ein normales Programm benötigt vielleicht 10 bis 20 kB, der Rest zwischen 20kB und 4GB führt zu EAccessViolation.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 12     123 45     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:36 Uhr.
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