Entwickler-Ecke
Windows API - Markierten Text systemweit auslesen oder Strg+C simulieren
Ja-Pa - Fr 03.10.03 15:17
Titel: Markierten Text systemweit auslesen oder Strg+C simulieren
Hallo,
ich möchte den Text der in einer beliebigen Windows-Anwendung markiert (aber nicht kopiert) wurde auslesen. Gibt es da irgendeine Möglichkeit?
Danke im Voraus,
Ja-Pa
P.S.: Weiter unten hat worm die Idee gehabt, Strg+C zu simulieren.
Aber wie simuliert man zwei Tastendrücke gleichzeitig?
In dem Forum findet man immer nur Lösungen für eine Taste.
Tana´Ri - Do 09.10.03 08:28
vielleicht hilft das weiter:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| Function GetSelText(H : THandle) : PCHAR; var P : array [0..1024] of char; n : integer; begin n := SendMessage(H,WM_GETTEXTLENGTH,0,0) + 1; if n > 1 then if SendMessage(H,WM_GETTEXT,n,Integer(@P)) > 0 then result := P else result := #0; end; |
Ja-Pa - Sa 11.10.03 13:06
Titel: Vielen Dank!
Vielen Dank! Ich hätte, ehrlich gesagt, es nicht für möglich gehalten!
Wie bekomme ich es hin, dass der Text erst dann ausgelesen wird, wenn man in meinem Form auf einen Button klickt? Dann ist das Fenster, in dem der Text markiert wurde nämlich nicht mehr aktiv...
Shark - Sa 11.10.03 20:29
Lass einen Timer laufen, der sich das Handle des aktiven Fensters holt und speichert...
Ja-Pa - So 12.10.03 09:52
| Shark hat folgendes geschrieben: |
| Lass einen Timer laufen, der sich das Handle des aktiven Fensters holt und speichert... |
Das ist mir dann auch eingefallen :) Ich habe es jetzt so gemacht, dass wenn mein Form deaktiviert wird (Application.onDeactivate) der Timer auf enabled gesetzt wird und jede Sekunde das Handle des aktiven Fensters speichert (GetActiveWindow).
Wenn das Form wieder aktiviert wird, wird der Timer gestoppt und das gespeicherte Handle der function GetSelText überheben.
Thanks2all!!!
Ja-Pa
Ja-Pa - Di 14.10.03 09:01
Titel: Das geht nicht!
Ich habe jetzt den Tipp von Tana'Ri ausprobiert, aber es gibt immer nur zwei undefinierte Zeichen als Ergebnis! Manchmal bekomme ich auch den Namen meiner Anwendung, aber beides ist nicht unbedingt das, was ich haben möchte.
Gruß, Ja-Pa
Ja-Pa - So 19.10.03 10:05
Hallo?
Hat da niemand mehr eine Idee :bawling:
toms - So 19.10.03 13:15
| Zitat: |
| SendMessage(H,WM_GETTEXT,n,Integer [...] |
WM_GETTEXT ist nicht eine universal Lösung um Text von
einem Control auszulesen.
Den Text von Winword bekommst du - beispielweise - damit nicht.
Dort müsstest du den Text über OLE auslesen.
Ja-Pa - So 19.10.03 15:48
Muss ich dann für jedes Programm ein OLE einbinden?
Ich möchte nämlich, dass das mit dem markierten Text auslesen bei allen Programmen, bei denen man Text bearbeiten kann, funktioniert.
Gibt es da nicht noch eine universelle Möglichkeit?
Verzweifelt :cry:, Ja-Pa
worm - Mo 20.10.03 00:03
Hmm... eine nicht so elegante Lösung wäre, ein STRG+C an die Anwendung zu schicken, so dass der markierte Text in der Zwischenablage landet (was man aber nicht immer garantieren kann, oder?). Falls der Inhalt der Zwischenablage erhalten bleiben soll, müsste dein Programm vorher den Inhalt der Zwischenablage sichern und nach dem Abholen des Textes den vorherigen Inhalt wieder in die Zwischenablage kopieren. Wirklich nicht elegant, aber sollte funktionieren. Würde zumindest den Umweg über OLE sparen.
Ja-Pa - Di 21.10.03 09:35
Gute Idee! :D :D :D
Aber wie kann ich Strg+C simulieren? In diesem Forum gibt es zwar schon viele Möglichkeiten, den Druck auf EINE Taste zu simulieren, aber auch zwei gleichzeitig?
Tana´Ri - Di 21.10.03 09:43
[API] SendInput
Hab das zwar noch nicht ausprobiert, aber selbst ist der Programmierer ;)
| Zitat: |
(PSDK)
The SendInput function synthesizes keystrokes, mouse motions, and button clicks.
Syntax
UINT SendInput( UINT nInputs,
LPINPUT pInputs,
int cbSize
);
Parameters
nInputs
[in] Specifies the number of structures in the pInputs array.
pInputs
[in] Pointer to an array of INPUT structures. Each structure represents an event to be inserted into the keyboard or mouse input stream.
cbSize
[in] Specifies the size, in bytes, of an INPUT structure. If cbSize is not the size of an INPUT structure, the function will fail.
Return Value
The function returns the number of events that it successfully inserted into the keyboard or mouse input stream. If the function returns zero, the input was already blocked by another thread.
To get extended error information, call GetLastError.
Remarks
The SendInput function inserts the events in the INPUT structures serially into the keyboard or mouse input stream. These events aren't interspersed with other keyboard or mouse input events inserted either by the user (with the keyboard or mouse) or by calls to keybd_event, mouse_event, or other calls to SendInput.
This function does not reset the keyboard's current state. Any keys that are already pressed when the function is called might interfere with the events that this function generates. To avoid this problem, check the keyboard's state with the GetAsyncKeyState function and correct as necessary.
Function Information
Header Declared in Winuser.h, include Windows.h
Import library User32.lib
Minimum operating systems Windows 98, Windows NT 4.0 Service Pack 3
|
Ja-Pa - Di 21.10.03 09:53
So ganz verstehe ich das aber nicht :oops:.
Wie erstellt man z.B. ein Array von "Input structures"?
Aber das hört sich nicht schlecht an.
Tana´Ri - Di 21.10.03 11:08
ganz einfach uses windows.pas
und dann
MyArray : array [0..n] of tagINPUT;
Ja-Pa - Di 21.10.03 15:35
Und wie speichere ich dann das Strg+C in dem tagInput?
Tana´Ri - Di 21.10.03 16:22
Nicht getestet (!)
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: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61:
| Type
TCOPYSEL = array [0..1] of TINPUT;
var KbInf_STRG, KbInf_C : TKeybdInput;
FirstInput,SecondInput : TInput;
SizeofInputStruct : cardinal;
P : TCOPYSEL;
PCOUNT : Integer;
begin
with KbInf_STRG do begin wVk := VK_SHIFT; wScan := 0; dwFlags := KEYEVENTF_KEYUP; time := round(Now); dwExtraInfo := GetMessageExtraInfo; end;
with KbInf_C do begin wVk := 43; wScan := 0; dwFlags := KEYEVENTF_KEYUP; time := round(Now); dwExtraInfo := GetMessageExtraInfo; end;
with FirstInput do begin Itype := 1; ki := KbInf_STRG; end;
with SecondInput do begin Itype := 1; ki := KbInf_C; end;
SizeofInputStruct := SizeOf(TInput);
P[0]:=FirstInput; P[1]:=SecondInput;
PCOUNT := High(P) + 1; SendInput(PCOUNT,P[0],SizeofInputStruct); |
so ungefähr ;)
ps: bei den dwFlags musst du noch nachsehn hab einfach mal default besetzt.
GetMessageExtraInfo hab ich mal dazu gesetzt ist aber glaub ich net so wichtig (?)
Ja-Pa - Di 21.10.03 17:01
Oh! :shock: Ein ganzer Quellcode, bei dem ich über die Hälfte so nicht gewusst habe :wink:, vielen Dank! Du scheinst dich mit solchen Sachen echt gut auszukennen. Weißt du das alles auswendig (die ganzen Eigenschaften)?
Ich werd´s gleich mal ausprobieren! *sagwieeinkinddassgeradeeinencomputergeschenktgekriegthatundnichtweißwiemanihnbenutzt* :D
Ja-Pa - Mi 22.10.03 09:49
Es funktioniert nicht! :bawling: :bawling: :bawling:
Es gibt keine Compilerfehler und auch keine Exceptions, aber das Simulieren des Tastendrucks funktioniert nicht.
Ich habe auch schon versucht, D und C zu simulieren (falls die Sonderfunktion von Strg+C nicht erkannt wird), aber es geht auch nicht. Das aktive Fenster scheint diese Eingaben einfach nicht zu erhalten :?
mfg, Ja-Pa
Ja-Pa - Mi 22.10.03 09:59
Titel: Zwischenablage
Wie wird eigentlich die Zwischanablage von Windows verwaltet?
Wenn man ein Programm programmiert, kann man ja mit Memo1.Lines (oder Strings?).CopyToClipboard (oder so ähnlich, weiß nicht mehr genau) den markierten Text in die Zwischenablage kopieren.
Das heißt also, dass Memo entweder intern den markierten Text ausliest und ihn an eine DLL oder so übergibt oder dass eine DLL oder so :wink: aufgerufen wird, die dann den markierten Text ermittelt und kopiert.
Wenn das so wäre könnte doch eigentlich jede Anwendung auslösen, dass der markierte Text in die Zwischschenablage kopiert wird :?:
Kennt sich da jemand näher mit aus???
Gruß, Ja-Pa
Ja-Pa - Mi 22.10.03 10:53
Ich habe
hier [
http://www.mjtnet.com/sendkeys.htm] eine Komponente gefunden, die folgendes kann:
| Zitat: |
SendKeys is a Delphi Component which provides similar functionality to that of the Visual Basic SendKeys function. However it is more advanced in that it includes a function to send key strokes to a specific window. This insures that the specified window has keyboard focus and also makes moving from one application/window to another very easy.
The SendKeys package includes components for Delphi 2.0, 3.0, 4.0 and 5.0.
|
Hört sich doch eigentlich nicht schlecht an, oder?
Ich werde es gleich mal ausprobieren, hoffentlich kann es auch mehrere Tasten gleichzeitig senden :wink:
Editiert: Es kann mehrere Tasten senden, aber es ist Shareware.
Hier gibt es auch noch kostenlose Komponenten, die mehrere Tasten gleichzeitig senden können. [
http://www.torry.net/keysandkeyboard.htm] Ich werde mal alle ausprobieren und dann hier posten, was die beste Lösung war.
Anonymous - Mi 22.10.03 13:15
Du kannst auch mal hier im Forum nach
SENDKEYS suchen, ich hab schon öfter eine Unit gepostet.
Die kannst du auch auf
http://www.utilmind.com finden (freeware)
Ja-Pa - Mi 22.10.03 15:49
Danke! Es funktioniert jetzt!!! :D :party: :dunce: :dance2: :beer: :!:
Hier der Lösungsvorschlag:
1. Lade dir die Unit von utilmind oder hier im Forum herunter.
2. Füge die Unit sendkeys zu deiner uses-Liste hinzu. :wink:
3. Benutze einen Timer, der gestartet wird, wenn die Anwendung deaktiviert wird (Application.onDeactivate) und gestoppt wird, wenn die Anwendung wieder aktiviert wird. Der Timer sollte im OnTimer-Ereignis jeweils das aktive Fenster holen (getActiveWindow) und es in einer hwnd-Variable speichern.
4. Wenn der Text ausgelesen werden soll, aktiviere das zuletzt aktive Fenster (das vom Timer ermittelt wurde) mit setActiveWindow.
5. Sendkeys.sendKeyString(SK_CTRL_DOWN + 'C' + SK_CTRL_UP);
6. Der Rückgabewert der Funktion unter 5. ist dann der markierte Text.
Danke an alle, die mir mit Ideen geholfen haben!!! :!:
Gruß, Ja-Pa
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 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!