Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Text aus fremder Anwendung läßt sich nicht kopieren (https://www.delphipraxis.net/169111-text-aus-fremder-anwendung-laesst-sich-nicht-kopieren.html)

golisan 29. Jun 2012 11:22

Text aus fremder Anwendung läßt sich nicht kopieren
 
Liste der Anhänge anzeigen (Anzahl: 5)
Hallo Leute,

ich habe die Suchfunktion und Google schon bemüht aber alle gefundenen Lösungsansätze haben
mir leider nicht geholfen.

Vielleicht habt ihr ja einen Tipp:

Ich möchte an den Text aus einer fremden Anwendung kommen. Wie ist mir im Prinzip egal :)
Die Anwendung ist die Entwicklungsumgebung der Sprache NATURAL.(wie das aussieht, siehe Bild 1)
Ich habe alle möglichen Handles im Zugriff.
Die Fensterstruktur könnt' ihr auf Bild 2 sehen.
Der Text an den ich ran möchte, steht in der Fensterklasse "PgmEdtEditWin"
Die Properties des Fensters seht ihr in Bild 3 bis 5.
Wie es aussieht, hat das Fenster keine weiteren Fenster(Edits etc), also muss der Text ja wohl "da drin stecken"

Meine Idee war, an den Text über die Zwischenablage zu kommen.
Aber alle meine Versuche mit WM_COPY bzw. Tasten senden sind gescheitert.
Passiert nix :pale:

Etwas erschwerend kommt hinzu, dass mein Code per Hook aufgerufen wird.. ich weiß nicht, ob das einen Einfluss hat(Taste senden etc.)
(der Hook reagiert auf die rechte Maustaste bzw. auf das sich dann öffnende Popupmenü)
Hier mal ein Stück Code(ist nicht vollständig!)
Delphi-Quellcode:
if nCode = HC_ACTION then
    begin
      fillchar(cwps,Sizeof(CWPStruct),0);
      CopyMemory(@cwps, Pointer(lParam), SizeOf(CWPSTRUCT));
      GetClassName(cwps.hwnd, szClassName, SizeOf(szClassName));
      klasse := szClassName;
      if pos('NIDE', klasse) > 0 then
      begin
        case cwps.message of
        WM_INITMENU:
        begin
        focus := getfocus;
        GetClassName(focus, szClassName, SizeOf(szClassName));
        klasse := szClassName;
        if klasse = 'PgmEdtEditWin' then
        begin

          SendMessage(focus,WM_COPY , 0, 0);
          s := clipboard.AsText;
          MessageBox(0,pchar(s),'Info',0);

          // STRG A und STRG C senden
          Keybd_Event(VK_CONTROL,0,0,0);
          Keybd_Event(byte('A'),0,0,0);
          Keybd_Event(byte('A'),0,KEYEVENTF_KEYUP,0);
          Keybd_Event(VK_CONTROL,0,KEYEVENTF_KEYUP,0);
          sleep(200);
          Keybd_Event(VK_CONTROL,0,0,0);
          Keybd_Event(byte('C'),0,0,0);
          Keybd_Event(byte('C'),0,KEYEVENTF_KEYUP,0);
          Keybd_Event(VK_CONTROL,0,KEYEVENTF_KEYUP,0);


          s := clipboard.AsText;
          MessageBox(0,pchar(s),'Info',0);
         end;
       end;
Habt ihr eine Idee?

Wenn ich per Winspector die Messages anschaue, die bei einem manuellen STRG A + C ausgelöst werden, sind da ein
Haufen WM_USER+Zahl dabei aber kein WM_COPY :?:

Danke schon mal

p80286 29. Jun 2012 11:55

AW: Text aus fremder Anwendung läßt sich nicht kopieren
 
Zitat:

Zitat von golisan (Beitrag 1172959)
Wie es aussieht, hat das Fenster keine weiteren Fenster(Edits etc), also muss der Text ja wohl "da drin stecken"

Muß er?
warum sollte nicht so etwas dahinter stecken?

Delphi-Quellcode:
for i:=0 to liste.Count-1 do
  mycanvas.Textout(x,y,liste[i]);
Gruß
K-H

DeddyH 29. Jun 2012 12:02

AW: Text aus fremder Anwendung läßt sich nicht kopieren
 
Vielleicht führt die Kombination von MSDN-Library durchsuchenWM_GETTEXTLENGTH und MSDN-Library durchsuchenWM_GETTEXT zum Erfolg.

golisan 29. Jun 2012 12:38

AW: Text aus fremder Anwendung läßt sich nicht kopieren
 
@DeddyH: habe ich auch schon probiert. Leider keinen Erfolg. Wenn die Klasse nicht von Edit, Memo oder RichEdit
abgeleitet ist, kommt man mit GETTEXT&Co nicht ran.(wenn es z. Bsp. so gemacht wurde wie von p80286 beschrieben)
Deshalb hatte ich ja die Idee mit der Zwischenablage. Aber anscheinend "sperrt" sich die Anwendung auch gegen ein "fernsteuern" :cry:

jaenicke 29. Jun 2012 12:53

AW: Text aus fremder Anwendung läßt sich nicht kopieren
 
Dass das selbst gezeichnet wird, ist ja relativ offensichtlich. Und wenn auch die Standard-Windowsmessages zur Textabfrage nicht behandelt werden, und du auch im Menü nicht an den Eintrag, der den Text kopiert, herankommst (wobei das den Benutzer wohl auch ziemlich stören würde), bleibt wohl nur einen Hook auf die Zeichenfunktionen zu setzen.

golisan 29. Jun 2012 13:17

AW: Text aus fremder Anwendung läßt sich nicht kopieren
 
So, drei Schokoladenstückchen weiter ... :-D
Die Anwendung sperrt sich nicht gegen das Strg-A+C, sondern die Tasten kommen schon im Kontextmenü an :?
Das widerspricht aber dem MSDN:
WM_INITMENUPOPUP
Sent when a drop-down menu or submenu is about to become active. This allows an application to modify the menu before it is displayed, without changing the entire menu.
Das Menü ist noch nicht sichtbar aber hat schon den Focus :roll:

lbccaleb 29. Jun 2012 16:55

AW: Text aus fremder Anwendung läßt sich nicht kopieren
 
Zitat:

Zitat von golisan (Beitrag 1172959)
... Wie ist mir im Prinzip egal :)

Schau dir mal diese Unit an, vllt kann Sie dir weiter helfen:

Ole Drop

Tipp: Im 2ten Beitrag ist ne überarbeitete Version von Tonic ;)

golisan 2. Jul 2012 17:45

AW: Text aus fremder Anwendung läßt sich nicht kopieren
 
Hallo,
also mit dem OLE-Drop bin ich nicht so recht klar gekommen...habe aber nur die Demo mal angeschaut. :roll:

Ich bin aber trotzdem einen Schritt weiter. Es scheint aber wirklich so zu sein, dass die
Anwendung sich dagegen "wehrt", dass man ihr den Text klaut.
Tastaturevents schicken ging nicht.
Mit Winspector Spy habe ich mir mal die Messages angeschaut, welche durch ein STRG-A/C ausgelöst werden
und habe die mal genauso "nachgebaut"

Delphi-Quellcode:
// Ctrl-A
sendMessage(focus, WM_user + 5018, $0017573,0);
sendMessage(focus, WM_user + 5694, 0,0);
sendMessage(focus, WM_user + 5678, 0,$0012e27c);

// Ctrl-C
sendMessage(focus, WM_user + 5018, $0017570,0);
sendMessage(focus, WM_user + 5694, 0,0);
sendMessage(focus, WM_user + 5678, 0,$0012e294 );
Was die Zahlen bedeuten, weiß ich nicht... aber es tut. :stupid:
Habe die Anwendung auch mehrfach gestartet, auch Win neu gestartet, die Zahlen blieben immer gleich.
So richtig glücklich bin ich damit nicht, da ich nicht genau weiß, was da abgeht...

Durch den simulierten CTRL-A ist nun aber der Text selektiert. Weiß jemand, wie
man einen Text nun wieder "deselektiert"?

Bummi 2. Jul 2012 18:06

AW: Text aus fremder Anwendung läßt sich nicht kopieren
 
Schick ein "Pfeil auf" oder ähnliches ...

golisan 2. Jul 2012 19:32

AW: Text aus fremder Anwendung läßt sich nicht kopieren
 
Liste der Anhänge anzeigen (Anzahl: 1)
OK, danke für die schnelle Antwort.

Im Anhang könnt' ihr mal das Ergebnis "bewundern" :-D
Links im Bild seht ihr das Popupmenü, welches ich um das Untermenü "Jump" erweitert habe.
Im Untermenü stehen nun alle Subroutinen(ähnlich Prozeduren in Delphi) der NATURAL-Programmsource.

Nächste Herausforderung:
Bei der Vergabe der Command-Id, dache ich, wäre man recht wahlfrei. Ist aber nicht so.

Ich habe mir eine globale Variable definiert:

Delphi-Quellcode:
id : Integer = 400;

Die einzelnen Menüeinträge hänge ich so an:

Delphi-Quellcode:
id := id + 1;
AppendMenu(jump, MF_STRING or MF_ENABLED, id, PChar(s));
Dummerweise sind so alle Einträge des Untermenüs Jump disabled.
Setzte ich den Startwert von id auf 400000 sind die Einträge auswählbar(fragt nicht wie lange ich da rum gesucht habe :evil:)

Gibt es einen definierten "Startwert"? WM_USER + ????? ab dem ich "meine" Command-Ids vergeben kann?
Kann es nicht vorkommen, dass meine Einträge mit den bestehenden Einträgen kollidieren könnten :?:

lbccaleb 2. Jul 2012 20:52

AW: Text aus fremder Anwendung läßt sich nicht kopieren
 
Zitat:

Zitat von golisan (Beitrag 1173194)
Hallo,
also mit dem OLE-Drop bin ich nicht so recht klar gekommen...habe aber nur die Demo mal angeschaut. :roll:
...

Also, wenn du den in deinem Programm makierten Text, per Drag und Drop in die Bsp. Anwendung gezogen bekommst, dann sollte es mit der Unit gehen was du vorhast.

golisan 2. Jul 2012 21:37

AW: Text aus fremder Anwendung läßt sich nicht kopieren
 
Nein, der markierte Text läßt sich leider nicht droppen :?

golisan 4. Jul 2012 09:08

AW: Text aus fremder Anwendung läßt sich nicht kopieren
 
Ich habe leider immer noch das Problem, dass
ich nicht weiss, wie ich die Command-ID(oder Menüitem-ID)
versorgen muss.
Bis jetzt mache ich es ja so
Delphi-Quellcode:
var
id : Integer = 400000;
Delphi-Quellcode:
id := id + 1;
AppendMenu(jump, MF_STRING or MF_ENABLED, id, PChar(s));
Gelesen habe ich schon von IdCmdFirst und IdCmdLast, konnte aber bis jetzt
nicht rausfinden, wie ich an diese Werte komme.

Kann mir jemand einen Tipp geben?

golisan 6. Jul 2012 09:13

AW: Text aus fremder Anwendung läßt sich nicht kopieren
 
*push*

hat keiner eine Idee, wie man die Command-IDs vergeben muss? :cry:

lbccaleb 6. Jul 2012 09:46

AW: Text aus fremder Anwendung läßt sich nicht kopieren
 
Zitat:

Zitat von golisan (Beitrag 1173207)
Kann es nicht vorkommen, dass meine Einträge mit den bestehenden Einträgen kollidieren könnten :?:

Klar kann das vorkommen. Du hast ja keine Ahnung, welche Messages in dem Programm bereits deklariert sind. Nun kommst du und erweiterst diese.
Es ist also nicht so verkehrt, die IDs von dir hoch anzusetzen.

golisan 9. Jul 2012 10:14

AW: Text aus fremder Anwendung läßt sich nicht kopieren
 
Es ist zum verzweifeln...ich glaube ich habe jetzt schon ganz Google durchgelesen :wink:
Aber irgendwie bekomme ich es nicht gebacken... oder verstehe es nicht.

Ich lege die Menüitems folgendermassen an:

Delphi-Quellcode:
ZeroMemory(@mii, sizeof(TMENUITEMINFO));
mii.cbSize      := sizeof(TMENUITEMINFO);
mii.fMask       := MIIM_TYPE or MIIM_ID or MIIM_DATA or MIIM_STATE;
mii.dwTypeData  := PChar(s); // Text des Menüitems
mii.dwItemData  := cardinal(v.Stmt.lineNr);
mii.cch         := Length(s);
mid := mid +1;
mii.wID         := mid ;
mii.fType      := MFT_STRING;
mii.fState     := MFS_ENABLED;

count := GetMenuItemCount(jump);
count := count + 1  ;
InsertMenuItem(jump, count, true, mii);
So weit so gut...
Wie ich bis jetzt gelernt habe(oder dachte gelernt zu haben!) sollte mii.wID dazu da sein, später festzustellen,
welches Menuitem ausgewählt wurde.(eindeutige ID)
Da ich ja nicht weiß, wie die IDs der bestehenden Menuitems sind, habe ich einen recht hohen Wert angesetzt
mid := 64000
Das tut ja schon mal.

Aber wie bekomme ich mit, wenn ein Menueintrag angeklickt wurde?

Da ich eh' schon einen DLL-Hook verwende, dachte ich, dass ich den WM_COMMAND abfange:

Hier mal der Hook
Delphi-Quellcode:
try
  begin
    if HookHandleMSG = 0 then
    begin
      HookHandleMsg := SetWindowsHookEx(WH_CALLWNDPROC, @MsgHookProc,
      HInstance, 0);
      MessageBox(0,'Msg-Hook installiert','Info',0);
    end
    else MessageBox(0,'MsgHook bereits installiert','Info',0);
  end;
    except MessageBox(0,'Msg-Hook konnte nicht installiert werden!','Info',0);
  end;
und so fange ich die Messages ab:

Delphi-Quellcode:
 if nCode < HC_ACTION then Result := CallNextHookEx(HookHandleMsg, nCode, wParam, lParam)
   else
    begin
      fillchar(cwps,Sizeof(CWPStruct),0);
      CopyMemory(@cwps, Pointer(lParam), SizeOf(CWPSTRUCT));

      case cwps.message of
      WM_INITMENU:
      // Menüeinträge erzeugen...

      WM_COMMAND:
        begin
        if cwps.lParam = 0 then
          begin
            s := inttostr(loword(wParam));
            MessageBox(0,pchar(s),'Info',0);
          end;
.
.
.
Laut Google bedeutet lParam=0 -> es wurde ein Menüeintrag ausgewählt... aber die MessaageBox erscheint nie. Auch nicht bei den nicht von mir erzeugten Einträgen.
Mache ich das IF vor der MessageBox weg, werde ich mit MessageBoxen überschwemmt... :?

Weiß jemand mehr?


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:09 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