Entwickler-Ecke
Windows API - STRG+C an fremde Anwendung senden / markierten Text kopieren
N8Falter74 - Mo 06.03.06 12:57
Titel: STRG+C an fremde Anwendung senden / markierten Text kopieren
Hallo Forum,
bevor jetzt wieder einige auf die Suche verweisen, die habe ich jetzt mehr als 30 min benutzt und noch nicht den richtigen tipp gefunden.
Also folgendes Problem:
Ich möchte mit einem kleinen Tool auf ein bestimmtes HotKey reagieren (STRG+S) und dann eine Datenbanksuche ausführen.
Das klappt auch soweit schon. Der Suchbegriff soll das aktuell markierte Wort/Satz usw. in der aktiven Anwendung sein.
Beispiel: In einer eMail markiere ich eine Telefonnummer und mit STRG+S sucht meine Anwendung zB. den Namen des Inhabers raus.
Zuerst habe ich das so versucht:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| procedure FindActiveControl; var hWindow: HWND; Pid1, Pid2: Cardinal; begin Pid1 := GetWindowThreadProcessId(Application.Handle); Pid2 := GetWindowThreadProcessId(GetForeGroundWindow); if AttachThreadInput(Pid1, Pid2, True) then begin hWindow := GetFocus; SendMessage(hWindow, WM_COPY, 0, 0); memo1.PasteFromClipboard; end; AttachThreadInput(Pid1, Pid2, False); end; |
Doch leider reagieren nur Edits und Comboboxen auf die Windows Message WM_COPY. Ich könnte jetzt natürlich alle Controls extra behandeln, aber das ist ja nie vollständig. Deshalb möchte lieber ein STRG+C an das Control senden, das ist zwar nicht so richtig professionell aber jedes Control das STRG+C unterstützt, sollte dann funktionieren.
Ich habe dann das
SendMessage(hWindow, WM_COPY, 0, 0); durch folgendes ersetzt:
Delphi-Quelltext
1: 2: 3: 4:
| SendMessage(hWindow, WM_KEYDOWN, VK_CONTROL, 0); SendMessage(hWindow, WM_KEYDOWN, Ord('C'), 0); SendMessage(hWindow, WM_KEYUP, Ord('C'), 0); SendMessage(hWindow, WM_KEYUP, VK_CONTROL, 0); |
Das funktioniert aber so nicht. Hat jemand eine Idee warum? Oder wie ich das eleganter lösen kann? :gruebel:
grüße
Sebastian
digi_c - Mo 06.03.06 15:03
Die werden doch nacheinander gesendet und nicht STRG+C gleichzeit, oder?
N8Falter74 - Mo 06.03.06 15:44
digi_c hat folgendes geschrieben: |
Die werden doch nacheinander gesendet und nicht STRG+C gleichzeit, oder? |
Sorry aber wie meinst du das :?:
Wenn ich einen Text irgendwo markiere und möchte den in die Zwischenablage kopieren, dann muß ich doch STRG drücken, dann dazu die Taste 'C' und dann beide loslassen. Oder?
Das wollte ich jedenfalls so simulieren.
Ich bin beim googlen darauf gestoßen, dass die KeyDown und KeyUp Messages nur als Reaktion auf einen Tastendruck in die Message Queue gestellt werden, das Fenster/Control selber reagiert aber nicht auf diese Messages. Ob das so richtig ist, habe ich leider auch nicht feststellen können. Das Platform SDK ist jedenfalls nicht gerade einfach zu lesen :-)
Es gibt auch noch eine WM_HOTKEY Message, aber diese bringt auch nicht die gewünschte Reaktion. Weder auf das Handle des Applications Fenster noch auf das Fensterhandle des Controls. :-(
Man kann wohl auch per SendInput direkt in den Tastaturpuffer schreiben, aber das wollte ich nur als letzte Möglichkeit verwenden, da man dabei nicht mehr das empfangende Fenster festlegen kann.
Hat jemand noch eine idee?
grüße
Sebastian
N8Falter74 - Mo 06.03.06 17:07
Ich hab eine Lösung gefunden:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39:
| procedure FindActiveControl; var hWindow: HWND; Pid1, Pid2: Cardinal; lParam: LongInt; ksNew, ksOld: TKeyboardState; begin Pid1 := GetWindowThreadProcessId(Application.Handle); Pid2 := GetWindowThreadProcessId(GetForeGroundWindow); if AttachThreadInput(Pid1, Pid2, True) then begin hWindow := GetFocus; lParam := MakeLong(0, MapVirtualKey($43, 0)); ksNew[VK_CONTROL] := $80; GetKeyboardState(ksOld); SetKeyboardState(ksNew); PostMessage(hWindow, WM_KEYDOWN, $43, lParam); PostMessage(hWindow, WM_KEYUP, $43, lParam or $C0000000); Application.ProcessMessages; Sleep(100); memo1.PasteFromClipboard; SetKeyboardState(ksOld); end; AttachThreadInput(Pid1, Pid2, False); end; |
Hab ich natürlich nicht komplett alleine gefunden ;-) Dank dem Board, dem Platform SDK und diesem Link
http://www.delphi-forum.de/viewtopic.php?t=36449&highlight=sendmessage war es dann doch ganz einfach :grin:
grüße
Sebastian
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!