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 4 von 12   « Erste     234 56     Letzte »    
KoS

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

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 21. Feb 2007, 18:51
Also ich muss nochmal korrigieren ...

mit dem "neuen" Code von dir, killt sich das Programm nicht mehr selbst, sondern bringt lediglich eine Zugriffsverletzung und das Form schließt sich, das Programm selbst bleibt offen.

Zudem hab ich mal folgendes Versucht, was nicht funktioniert:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  memo1.clear;
  myhandle:=findwindow(nil,'PImage');
  if myhandle=0 then exit;
  memo1.Lines.add('window found!');
  delay(1000);
  startobservation;

  //eine Besipielanfrage an die newwndProc
  communicate('Image2',sImageSize);
  //hier oder in einer anderen Funktion können noch mehr solche Anfragen gestartet werden

  delay(1000);
  stopobservation;
end;
Ohne die delay Funktion würde sich das eigene Programm aufhängen, aber es kommt kein ergebnis zurück und das Ziel-Form hängt sich dann auch nicht auf, als ob irgendwie die Adressen nicht angesprochen werden.
D.h. also wenn das myhandle und startobservation im FormCreate ist funzt es, so nicht.

Was deine Frage betrifft was für eine Software das ist, kann ich nur sagen das es sich um eine Präsentationssoftware handelt.

Das die Software in Delphi programmiert ist, ist zu 100% sicher, zum einen durch die Formulare die ich in ResHack ermittelt hab und zum anderen wenn ich die Software im HexEditor anschaue steht auch Delphi drin, und das schreibt meines wissens nur Delphi rein.

Welche Version von Delphi, kann ich leider nicht sagen, du kannst schon recht haben das da ne ältere Version hinter steckt.

Da ich so langsam die Vermutung hab das die Namen die ich ermittelt hatte, zur Laufzeit vielleicht anders lauten, kann ich irgendwie eine Liste aller Elemente, also die Namen und ggf. die Klasse dazu die auf dem Form existieren auslesen? Mit den Klassen hatten wir das ja schonmal, wobei er mit der grund Version ich glaub auf Seite 1 des Threads, aufhängt bzw. Zugriffsverletzung bekommt (also eigenes Programm).

Ich glaub langsam wird kompliziert, oder?
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

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

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 21. Feb 2007, 19:56
Zitat von KoS:
mit dem "neuen" Code von dir, killt sich das Programm nicht mehr selbst, sondern bringt lediglich eine Zugriffsverletzung und das Form schließt sich, das Programm selbst bleibt offen.
Ja. Das ist, weil der Zugriffsfehler (der immer noch derselbe ist) nicht mehr in unserem (ungesicherten) Thread passiert sondern in der WndProc, also in dem Thread des Formulars. Und dort wird Exception-Behandlung betrieben. Deswegen stürzt nicht gleich das ganze Programm ab.

Zitat von KoS:
Zudem hab ich mal folgendes Versucht, was nicht funktioniert:
...
Ohne die delay Funktion würde sich das eigene Programm aufhängen, aber es kommt kein ergebnis zurück und das Ziel-Form hängt sich dann auch nicht auf, als ob irgendwie die Adressen nicht angesprochen werden.
D.h. also wenn das myhandle und startobservation im FormCreate ist funzt es, so nicht.
Das ist komisch, muss ich gleich mal überprüfen.

Zitat von KoS:
Das die Software in Delphi programmiert ist, ist zu 100% sicher,
Die Gründe sind einleuchtend

Zitat von KoS:
Ich glaub langsam wird kompliziert, oder?
Ja, der letzte Teil war mir etwas zu kompliziert. Wieso hängt sich jetzt da wieder etwas auf, was eigentlich bisher klappte?

Für ein Delphi 4 wüsste ich noch, wo eine Lizenz ungenutzt herumliegt. Aber das jetzt zu installieren um auf Verdacht weiterzusuchen....nicht unbedingt. Es war ein Versuch wert. Schade dass er nicht geklappt hat. War aber mal ne schöne Übung.
Es ist halt recht schwer auf die Ferne jetzt noch etwas am Code zu drehen. Du müsstest wahrscheinlich selber noch ein bisschen probieren. Als erstes würde ich ständig Messages senden, wenn er wieder eine Codezeile geschafft hat. Dadurch weisst du wo er hängen bleibt.
Ich kann dir das mit dem Classname in die letzte Variante noch mal reinprogrammieren. Dürfte aber nix bringen.

Die Namen der Komponenten kann man zur Laufzeit meines Wissens nicht mehr ändern.
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
 
#33

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 21. Feb 2007, 20:13
Ok, in deinem TestProgramm ist ein Laufzeitproblem.
[Nebenbei: Seit wann gibts denn die delay-Funktion wieder. Die kenne ich noch aus Turbo Pascal, aber mein D7 hat die nicht.]

Du musst eigentlich nicht zwischen findwindo und startobservation warten, sondern zwischen startobservation und communicate.
Das Problem ist wie in einer MultiThreadanwendung. die haben wir eigentlich auch. Nur das unser Nebenthread auch gelich in einem anderen Process ist.
Der letzte Befehl in Startobservation ist "CreateRemoteThread" Da wird der neue Thread gestartet. Das dauert aber meistens eine Weile. In der Zeit ist unse rHauptthread schon längst in communicate bei sendmessage angekommen. Schickt als eine Message und wartet auf Antwort. Da aber unser Nebenthread die wndProc-Funktion noch nicht umgelenkt hat, kriegen wir keine Antwort und warten ewig. Und deswegen wird in dem Nebenthread (also eigentlich in der neuen wndProc) auch nicht die Info-Prozedur aufgerufen. Und weil die Zugriffsverletzungen nur dort passieren, passiert dann eben nix.


Edit: Die Idee ist ja auch, nicht alles hintereinander zu machen, sondern erst einmalig startobservation. Und dann bei Gelegenheit (von mir aus) hundertmal communicate. Soviel du halt an Infos brauchst. In der ganzen Zeit seit startobservation bekommst du auch die WM_Paint Messages mit. Und ganz am Ende des Programms rufst du einmal stopobservation.
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
 
#34

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 21. Feb 2007, 20:34
So, ich hab die Sache mit Classname wieder reingebracht, dürfte aber wie gesagt nicht viel bringen.
folgende Änderungen vom letzten Mal:
type TSearchtype=(sImageSize,sCaption,sImageSizefromClassname);
Delphi-Quellcode:
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:integer;
    a:cardinal;
    c:pchar;
    left,top,width,height:smallint;
    same:boolean;
    SearchType:TSearchType;
    vgl:array[0..31] of char;
    vgllength:integer;
    index:word;
begin

  Searchtype:=TSearchType(lparam mod 65536);
  index:=lparam div 65536;

  //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


    if searchtype=simagesizefromclassname then begin
      p:=p^;
      p:=pointer(cardinal(p^)-44);
    end else
      p:=pointer(cardinal(p^)+8);
    p:=p^;

    c:=pchar(p);
    if (pbyte(p)^=vgllength)or(SearchType<>sImagesizefromClassname) then begin
      if SearchType=sImagesizefromClassName then inc(c);
      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
        dec(index);
        if (index=0)or(SearchType<>sImagesizefromClassname) 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;
    end;
  end;
  //Ergebnis Nach Hause senden
  memory^.Postmessage(memory^.backwnd,memory^.backmsg,wparam,lparam);
end;
Delphi-Quellcode:
procedure TForm1.communicate(vgl:string;Searchtype:TsearchType;index:word=0);
//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
  if searchtype=sImageSizefromclassname
    then lparam:=cardinal(Searchtype)+index*65536
    else lparam:=cardinal(Searchtype);
  sendmessage(myhandle,mymsg,wparam,lparam); //Message für unsere newwndproc; und warten bis sie dort verarbeitet wurde
  globaldeleteatom(wparam); //Atom wieder löschen
end;
Und die Testroutine:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  //Besipielanfragen an die newwndProc
  communicate('TImage',sImageSizefromclassname,2);
  communicate('Image2',sImageSize);
  communicate('Label1',sCaption);
  //hier oder in einer anderen Funktion können noch mehr solche Anfragen gestartet werden
end;
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
KoS

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

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 21. Feb 2007, 20:55
Das Delay ist eine Funktion die ich hier irgendwo aus dem Board gezogen hab.

Das Problem warum ich das mit dem start/stopobservation in ein buttonclick gesetzt hab, ist jenes weil das spezielle Form was die TImages enthält nicht permanent geöffnet ist, was ich dann auch noch irgendwie z.B. mit Timer überprüfen muss.
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

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

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 21. Feb 2007, 21:10
Aslo entweder du baust dann die Verzögerung ein nach startobservation (ein einfaches Sleep(100) dürfte aber ausreichen) oder ich sende aus dem Remotethread eine Message, dass alles vorbereitet ist:

Delphi-Quellcode:
//Deklaration in TForm1
procedure GetReadyMsg(var msg:TMessage);message mymsg+3;
.
.
.
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);
  memory^.Postmessage(memory^.backwnd,memory^.backmsg+3,0,0); //Message, dass alles eingerichtet/vorbereitet ist
  while memory^.running do memory^.sleep(200);
  memory^.setwindowlong(memory^.watchwnd,gwl_wndproc,memory^.oldwindowproc);
  result:=0;
  memory^.exitthread(0);
end;
Delphi-Quellcode:
procedure Tform1.GetReadyMsg(var msg:TMessage);
begin
  //wird automatisch vom Remotethread "gestartet", wenn er soweit ist
  communicate('TImage',sImageSizefromclassname,2);
  communicate('Image2',sImageSize);
  communicate('Label1',sCaption);
  stopobservation; //hier oder später
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
  memo1.clear;
  myhandle:=findwindow(nil,'PImage');
  if myhandle=0 then exit;
  startobservation;
end;
Aber, wenn du gleich stopobservation aufrufst, dann bekommst du ja nicht mehr mit, wenn das Window eine WM_Paint Message zum neuzeichnen bekommt.
Du kannst übrigens auch das Erstellen und das Entfernen des Formulars ereignisgesteuert überwachen.

Aber solange wir das mit dem Communicate, also die Info-funktion nicht hinbekommen, brauchen wir den Rest nicht mehr zu probieren. Da bräuchten wir wirklich die entspr. Delphiversion.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
KoS

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

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 22. Feb 2007, 09:14
Zitat:
Aber solange wir das mit dem Communicate, also die Info-funktion nicht hinbekommen, brauchen wir den Rest nicht mehr zu probieren. Da bräuchten wir wirklich die entspr. Delphiversion.
Da geb ich dir allerdings Recht! Ich probier das heute Nachmittag nochmal aus. Ich hoffe das klappt dann, wobei ich nicht sehr optimistisch bin.

Hier mal neben bei die Delay-Prozedur:
Delphi-Quellcode:
procedure Delay(Milliseconds: Integer);
var
  Tick: DWord;
  Event: THandle;
begin
  Event := CreateEvent(nil, False, False, nil);
  try
    Tick := GetTickCount + DWord(Milliseconds);
    while (Milliseconds > 0) and
          (MsgWaitForMultipleObjects(1, Event, False, Milliseconds, QS_ALLINPUT) <> WAIT_TIMEOUT) do
    begin
      Application.ProcessMessages;
      if Application.Terminated then Exit;
      Milliseconds := Tick - GetTickcount;
    end;
  finally
    CloseHandle(Event);
  end;
end;
Die benutze ich in Verbindung mit Windows-Diensten, damit der Prozess nicht mit 100% Auslastung fährt.
  Mit Zitat antworten Zitat
KoS

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

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 22. Feb 2007, 18:43
Hmm hab grad nochmal rum getestet... das Ergebnis ist leider sehr enttäuschend. Kurz um: Zugriffsverletzung im Ziel-Programm.

Gut dann müsste man mal eine andere Taktik angehen. Lassen wir mal das mit dem finden der TImage. Passt zwar jetzt nicht zum Topic, aber es gibt noch noch eine andere Möglichkeit die TLabel zu finden als über die Adress-Rechnung oder? Ich hatte früher mal so sachen gehabt, aber die zu finden, dürften schwierig sein.
Die Position und die größe der TImage lässt sich zur Not auch noch manuell und fix programmieren, aber ich brauch auf alle Fälle den Text der Labels.
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

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

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 22. Feb 2007, 19:19
Bei TLabel besteht genau dasselbe Problem, wie bei TImage. Es hat kein Window-Handle. Ansonsten könnet man mit einer WM_GetText Message o.ä. daran kommen. Also es bedarf zum Beispiel nur weniger Schritte um die Playlist aus dem Win-Media Player herauszubekommen, auch im Explorer kann man recht einfach von außen mitlesen. Aber dort benutzt Microsoft halt die grundlegenden Window-Typen aus ihrer eigenen Win-API. TLabel ist aber nur ein Objekt in Delphi, was halt immer auf das formular gezeichnet wird. es hat sogar eine eigene WndProc-Funktion. die wird aber nur über das Parent-window angesteuert. wenn wir die Finden könnten wie sogar den Text bekommen. Aber wie?

Da muss ich erstmal mindestens eine Nacht drüber schlafen.


Ich hatte vorhin vesucht noch eine Exception-Behandlung mit einzubauen (in die Info). Aber die funktioniert nicht. Da geht das Programm im Fehlerfall dann einfach aus, ohne sich irgendwie abzumelden und ohne Fehlermeldung. Im eigenen Programm funktioniert die Exceptionbehandlung wunderbar. Musste sie ja in ASM schreiben, weil das try..except ja gleich wieder Klassen instanziert.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
KoS

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

Re: Zugriff auf ein TImage einer externen Anwendung

  Alt 23. Feb 2007, 08:43
Also kurz zum Verständnis, ein RichEdit (sei es nun von Delphi oder generell) besitzt ein eigenes Handle, ein Memo auch? nur ein Label wird in dem sinne sozusagen einfach nur draufgezeichnet, d.h. der Text existiert schon irgendwo im Hauptprogramm?

Früher hatte ich ja mal ein Programm mit dem ich RichEdit und ich glaub auch Memos auslesen konnte, aber das eben ohne Adress-Rechnung. Das ganze war einfacher gestrickt. Hab aber wie gesagt den Code nicht mehr zumindest müsste ich wenn doch in tiefen Archiven graben.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 4 von 12   « Erste     234 56     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 23:47 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