![]() |
Autotext-Programm - aber wie?
Hallo zusammen,
ich will, eigentlich, nur ein kleines AutoText-Programm schreiben - also ich bin, in welchem Programm auch immer, schreibe beispielsweise mfg drücke, beispielsweise strg+leertaste und anschließend steht "mit freundlichen Grüßen" da. Mein erstes Problem: wie kriege ich raus, welche Anwendung, als strg+leertaste gedrückt wurde, aktiv war? Ich denke mir, das strg+Leertaste, als Hotkey definiert, meinem Programm ja mitteilen sollte, wann es startet - und ich, habe ich das Handle der aktiven Anwendung, mit wm_settext den zu ersetzenden Text schreiben kann. Oder nicht? ;-) Viele Grüße Marco |
AW: Autotext-Programm - aber wie?
Delphi-Quellcode:
function GetFocusedControlHandle: HWND;
var FG_Window_Handle:HWND; FocusedThreadID : DWORD; begin FG_Window_Handle := GetForegroundWindow; FocusedThreadID := GetWindowThreadProcessID(FG_Window_Handle, nil) ; if AttachThreadInput(GetCurrentThreadID, FocusedThreadID, true) then Result := GetFocus; AttachThreadInput(GetCurrentThreadID, FocusedThreadID, false) ; end; // kleiner test ....
Delphi-Quellcode:
procedure TForm3.Timer1Timer(Sender: TObject);
var s:AnsiString; begin s := 'Hallo'; SendMessage(GetFocusedControlHandle,wm_setText,0,Integer(@s[ 1])); end; |
AW: Autotext-Programm - aber wie?
Hattest du diesen GetFocusedControlHandle-Code nicht schonmal irgendwo gepostet?
Nja, dast iimmernoch ein Fehler drin, denn auf was wird Result denn wohl stehen, wenn AttachThreadInput Nee sagt? (aber das sollte der Compliler dir auch schon mehrfach gesagt haben) |
AW: Autotext-Programm - aber wie?
Hallo,
und ein herzliches Dankeschön für die Antwort. Das Result auf undefiniert steht, ist beseitigt. ;-) Aaaaber: Die WM_SetText wird offensichtlich nicht wirklich ausgewertet. Im Windows-Editor klappt alles prima, aber weder bei der Delphi-IDE noch bei Word kommt irgendwas an. Gibt es eine elegantere möglichkeit, als ernsthaft alle einzelnen Tastendrücke des zu schreibenden Strings per Sendmessage mit allen KeyUps und -downs simulieren zu müssen? Viele Grüße Marco |
AW: Autotext-Programm - aber wie?
Es wäre wohl das universellste. Fast. Da nicht alle Programme Eingabefelder aus den Reihen der Common Controls nimmt, und somit ein Textfeld in einem z.B. geskinnten Programm auch gerne mal ohne Handle und jegliche Kenntnis von Windows daher kommt, wäre noch besser daher die Verwendung von SendInput(), was (ohne bewusste Handlung seitens des Senders) kein Programm von tatsächlichen Eingabehandlungen unterscheiden kann. Sprich: Alles verhält sich so, als würde das jemand von seiner Tastatur aus direkt eintippern, und zwar bei egal was gerade den Fokus hat (und wie dann programmintern ggf. noch weiter unterverteilt wird).
|
AW: Autotext-Programm - aber wie?
Es kommt auch drauf an, welche Komponente angesteuert wird und worauf die Programme bei Eingaben letzendlich reagieren.
Bei Delphi und Word wird der Text garantiert nicht in einem billigen Edit/Memo/Richedit verwaltet und daher kann es gut sein, daß diese Komponenten nicht auf WM_SETTEXT reagieren. Das Notepad dagegen nutzt aber MultiLine-Edit (MEMO) und dieses Windows-Control kennt natürlich ![]() |
AW: Autotext-Programm - aber wie?
@himitsu
falls ich es schon mal geschickt haben sollte, dann habe ich wohl genauso schnell und schlampig zusammengetippt wie gestern. Ich kann es leider nicht mehr editieren. |
AW: Autotext-Programm - aber wie?
Hallo Zusammen,
Ich habe zu SendInput zumindest mal denSendInputHelper gefunden, der wäre auch schön, läuft aber bei mir nicht, weil mein Delphi steinalt ist - nun ja, dann muß es anders gehen. :-( Kann mir vielleicht jemand ein schlichtes Beispiel posten, wie ich via SendInput ein "H" und anschließend ein "a" senden kann? Und gleich noch 'ne Frage, ich dachte mittels
Delphi-Quellcode:
sollte man eigentlich auch ein "h" senden können - tut aber nicht. Hat jemand 'ne Idee warum?
keybd_event (ord('h'), MapVirtualKey (ord('h'), 0), 0, 0);
keybd_event (ord('h'), MapVirtualKey (ord('h'), 0), keyeventf_keyup, 0); Vielen Dank schonmal und viele Grüße Marco |
AW: Autotext-Programm - aber wie?
Hallo Marco, google nach
![]() |
AW: Autotext-Programm - aber wie?
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen,
Ich brauche bitte doch nochmal eure Hilfe. Ich hab's jetzt so umgebaut, daß das Wort, welches vor dem Cursor steht, in die Zwischenablage kopiert, ausgewertet, ggf. ersetzt, und dann mittels strg+v wieder eingefügt wird. Daß die Zwischenablage dabei überschrieben werden kann, ist klar, stör micht aber nicht - außer, es gibt eine schönere lösung. Aber, wenn ich das Programm ausführe, kommt es zu eine exception, und mir ist überhaupt nicht klar, warum. Hat jemand 'ne Idee, was ich hier falsch gemacht abe?
Delphi-Quellcode:
Viele Grüße
unit main;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; type TGlobalHotkey = record // damit's zusammengefaßt ist AtomName: string; atom: integer; end; TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private-Deklarationen } globalHotkey: TGlobalHotkey; hNextViewer: DWORD; // Handle des nexten Mitglieds in der Clipboard-Viewer-Kette hf: hwnd; // handle des fordergrundfensters, in dem strg+leertaste gedrückt wird. procedure CopyTextToClipboard (aWnd: HWND; aText: PChar); function GetFocusedControlHandle: HWND; public { Public-Deklarationen } procedure WMHotKey (var Msg: TWMHotKey); message WM_HOTKEY; procedure WMChangeCBChain(var Msg: TMessage); message WM_CHANGECBCHAIN; procedure WMDrawClipboard(var Msg: TMessage); message WM_DRAWCLIPBOARD; end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); begin with globalHotkey do begin AtomName := 'Test_Strg_Leertaste'; atom := GlobalFindAtom (pChar(AtomName)); if atom = 0 then // Atom gibt's noch nicht ... atom := GlobalAddAtom (pChar(AtomName)); // sonst wird das bereits vorhandene in Atom gespeichert. RegisterHotkey (handle, atom, mod_Control, vk_space) end; // hängen wir uns in die Clipboard-Kette..,. hNextViewer := SetClipBoardViewer (Handle); end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin // hotkey weg und raus aus der Clipboardkette... unregisterHotkey (handle, globalHotkey.Atom); ChangeClipBoardChain(Handle, hNextViewer); action := caFree; end; procedure TForm1.WMChangeCBChain(var Msg: TMessage); begin if Msg.WParam = hNextViewer then hNextViewer := Msg.lParam else if hNextViewer <> 0 then SendMessage(hNextViewer, MSG.Msg, MSG.wParam, MSG.lParam); end; procedure TForm1.CopyTextToClipboard(aWnd: HWND; aText: PChar); var Data: THandle; DataPtr: Pointer; Size: Integer; oldWND: HWND; begin Size := Length(aText) + 1; OpenClipboard(aWnd); //Open Clipboard try EmptyClipboard; // Clear Clipboard oldWND := SetClipboardViewer(aWnd); // Clipboard für Programm registr. Data := GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE, Size); // Get Memory try DataPtr := GlobalLock(Data); try Move(aText^, DataPtr^, Size); SetClipboardData(CF_TEXT, Data); // Clpbrd-Format as Text & send Text finally GlobalUnlock(Data); end; except GlobalFree(Data); // Free res. Memory raise; // Get global Memory Err end; ChangeClipboardChain(aWnd, oldWND); finally CloseClipboard; //Close Clipboard end; end; procedure TForm1.WMDrawClipboard(var Msg: TMessage); var hClipbrdObj: THandle; pClipbrdObj: Pointer; s: string; begin OpenClipboard(Handle); hClipbrdObj := GetClipboardData(CF_TEXT); if hClipbrdObj = 0 then // nix text oder drin... begin CloseClipBoard; exit; end; pClipbrdObj := GlobalLock(hClipbrdObj); s := pChar (pClipbrdObj); // sollte der im Clipboard stehende Text sein GlobalUnlock(DWORD(pClipbrdObj)); GlobalFree(hClipbrdObj); CloseClipBoard; if uppercase (s) <> 'MFG' then exit; // blos zum testen. s := 'Mit freundlichen Grüßen!'; CopyTextToClipboard (handle, pChar(s)); // strg+v keybd_event (vk_control, 0, 0, 0); keybd_event (vkKeyScan('v'), 0, 0, 0); keybd_event (vkKeyScan('v'), 0, keyeventf_keyup, 0); keybd_event (vk_control, 0, keyeventf_keyup, 0); end; function TForm1.GetFocusedControlHandle: HWND; var FG_Window_Handle: HWND; FocusedThreadID: DWORD; begin FG_Window_Handle := GetForegroundWindow; FocusedThreadID := GetWindowThreadProcessID (FG_Window_Handle, nil); if AttachThreadInput (GetCurrentThreadID, FocusedThreadID, true) then Result := GetFocus else result := 0; AttachThreadInput (GetCurrentThreadID, FocusedThreadID, false); end; procedure TForm1.WMHotKey(var Msg: TWMHotKey); begin hf := GetFocusedControlHandle; if hf = 0 then exit; // strg+shift+pfeil links - Wort vor'm Cursor markieren... keybd_event (vk_control, 0, 0, 0); keybd_event (vk_Shift, 0, 0, 0); keybd_event (vk_left, 0, 0, 0); keybd_event (vk_left, 0, keyeventf_keyup, 0); keybd_event (vk_shift, 0, keyeventf_keyup, 0); keybd_event (vk_control, 0, keyeventf_keyup, 0); // strg+c - ab in die Zwischenablage keybd_event (vk_control, 0, 0, 0); keybd_event (vkKeyScan('c'), 0, 0, 0); keybd_event (vkKeyScan('c'), 0, keyeventf_keyup, 0); keybd_event (vk_control, 0, keyeventf_keyup, 0); // jetzt, sollte, eigentlich WMDrawClipboard greifen... end; end. Marco p.s.: bitte entschuldigt, daß ich nicht mehr alle Querverweise parat habe, bei wem ich mir was abgeschaut habe! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:11 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz