Markierten Text in Java-Anwendung in Zwischenablage befördern
-
Hallo zusammen,
ich brauche mal einen Tipp von euch, vielleicht hat das ja schon mal jemand gemacht: es geht darum, dass mein Programm im Hintergrund einen systemweiten Hotkey erzeugt, der mir nun aus dem aktuellen "Fremd"-Fenster (meist eine Java-Anwendung, kann aber auch was anderes sein wie z.B. ein Word-Dok. oder Browserfenster) den aktuell selektierten Text in die Zwischenablage schiebt. Also eigentlich genau das, was passiert, wenn man STRG+C oder STRG+EINFG drückt. Ich habe es auch schon so probiert, dass genau diese Tastencodes einfach in den Tastaturpuffer geschrieben werden, aber damit kommt die Java-Anwendung nicht zurecht (obwohl seltsamerweise ein "manuelles" STRG-C in einer Textbox in der Java-App funktioniert), alle anderen Anwendungen schon.
Der Inhalt der Zwischenablage wird danach an ein anderes Programm geschickt für eine Suche in einer Datenbank. Die User sollen halt nur markieren und den Hotkey drücken müssen und nicht jedesmal STRG-C drücken.
Bin dankbar für jeden Tipp!
Grüße,
Rob
-
Rob.Dispose(); schrieb:
es geht darum, dass mein Programm im Hintergrund einen systemweiten Hotkey erzeugt, der mir nun aus dem aktuellen "Fremd"-Fenster (meist eine Java-Anwendung, kann aber auch was anderes sein wie z.B. ein Word-Dok. oder Browserfenster) den aktuell selektierten Text in die Zwischenablage schiebt.
Es klingt im ersten Moment so, als ob du es bereits geschafft hättest, den jeweils selektierten Text auf den globalen Heap zu schieben.
Unmöglich ist das natürlich nicht, aber bedenke, dass du vorhast, dies mit egal welcher App zu tun. Am Besten fragst du mit deinem Hintergrundprogramm periodisch ab, ob Text in der Zwischenablage ist ( IsClipboardAvailable(CF_TEXT) ), wenn ja, prüfst du, ob du etwas damit anfagen kannst und schickst es anschließend an deine Datenbank.
-
Erstmal danke für deine Antwort! Da hab ich mich glaube ich nicht wirklich klar ausgedrückt, ich bin im Moment soweit, dass der Hotkey funktioniert. D.h. egal, in welcher Anwendung ich bin - das Drücken von Windows-Y wird registriert (öffnet z.B. einfach testweise eine Messagebox).
Was jetzt noch fehlt: ich will quasi das, was die Tastenkombi STRG-C macht (also die aktuelle Selektion in die Zwischenablage packen) per Code manuell auslösen. Ich will also nicht wirklich die Tastenkombi drücken müssen, sei es händisch oder in dem ich den Keyboardpuffer fülle, sondern direkt das aufrufen, was NACH dem Drücken der Kombi normalerweise ausgelöst wird.
-
Das Problem bei der ganzen Sache ist es nicht, irgendwelche Zeichenketten in die Zwischenablage zu kopieren, das Problem ist, erst einmal an diese zu kommen. Vom Prinzip her geht es so:
BOOL SetClpbData(HWND hwnd) { BOOL bRet = FALSE; if(OpenClipboard(hwnd)) { const char* pcClpbText = "Diese Zeichenkette bitte in die Zwischenablage"; const DWORD dwSize = strlen(pcClpbText)+1; // wegen abschließender Nullterminierung; HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwSize); if(hGlobal) { char* pcCopy = (char*) GlobalLock(hGlobal); if(pcCopy) { memcpy(pcCopy, pcClpbText, dwSize); GlobalUnlock(hGlobal); if(!::SetClipboardData(CF_TEXT, hGlobal)) { // oh, Problem } else { bRet = TRUE; } } else { // oh, Problem GlobalUnlock(hGlobal); } } } CloseClipboard(); return bRet; }
Mit UNICODE-Kompilierung hieße der Bezeichner CF_UNICODETEXT (statt CF_TEXT). Wie du siehst, ist es wirklich einfach, dein Problem ist aber, an pcClpbText, den man natürlich normalerweise als Argument an die Funktion übergeben würde, zu kommen.
Du müßtest das momentan aktive Fenster bestimmen, dir irgendwie ein Handle des Child-Fensters, das momentan den Focus besitzt, ergattern, prüfen ob es womöglich ein Textfeld ist, die Prosition der Selektion bestimmen, den Speicher über ReadProcessMemory in deine App laden (den Speicherbereich musst du selbstverständlich noch suchen), anschließend prüfen, ob es sich um UNICDOE - Text handelt und dann den Text in die Zwischenablage kopieren.
Da du aber Text aus einer Java-App haben möchtest, verkompliziert sich die ganze Sache noch "etwas".
Kurz gesagt, ich habe selber keine Ahnung, wie man so etwas machen sollte, daher mein Vorschlag gestern, einfach periodisch (vielleicht alle 2 s) die Zwischenablage kontrollieren und schauen, on du etwas mit dem Inhalt anfangen kannst.
LG Hendrik
-
P.S. Über UNICODE brauchst du dir keine Sorgen machen, eine Konvertierung übernimmt Windows für dich ( ISClipboardDataAvailable(CFTEXT | CF_UNICODETEXT).
-
Danke für eure ausführlichen Antworten!
Ich hatte das größte Problem tatsächlich mit dem Rankommen an den selektierten Text, weil man ja nie weiß, wo er sich jetzt gerade "rumtreibt". Und gerade bei Java-Fenstern ist das ja noch mal ne Ecke komplizierter..
Ich habe daher das ganze wieder auf die Keyboard-Geschichte umgemünzt, diesmal allerdings mit einer mittlerweile überholten (aber dafür hardwarenahen) Lösung names "keyb_event". Damit kommt sogar Java klar. Dann brauchte ich noch ein paar Stunden um rauszukriegen, wieso es immer noch nur sporadisch funktionierte, das lag aber dann daran, dass ich direkt nach dem Schicken von "STRG-C" die Zwischenablage ausgelesen habe. Das war aber zu schnell! Ich baute noch ein Sleep(100); ein danach funktionierte alles tadellos.
Danke nochmal und ne gute Woche,
MfG Rob