AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Autotext-Programm - aber wie?

Ein Thema von Marco Steinebach · begonnen am 16. Nov 2012 · letzter Beitrag vom 29. Dez 2012
Antwort Antwort
Seite 1 von 2  1 2      
Marco Steinebach

Registriert seit: 4. Aug 2006
502 Beiträge
 
Delphi 5 Enterprise
 
#1

Autotext-Programm - aber wie?

  Alt 16. Nov 2012, 17:00
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
Marco Steinebach
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#2

AW: Autotext-Programm - aber wie?

  Alt 16. Nov 2012, 17:40
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;
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.081 Beiträge
 
Delphi 12 Athens
 
#3

AW: Autotext-Programm - aber wie?

  Alt 19. Nov 2012, 10:21
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)
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Marco Steinebach

Registriert seit: 4. Aug 2006
502 Beiträge
 
Delphi 5 Enterprise
 
#4

AW: Autotext-Programm - aber wie?

  Alt 20. Nov 2012, 15:36
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
Marco Steinebach
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#5

AW: Autotext-Programm - aber wie?

  Alt 20. Nov 2012, 15:48
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).
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.081 Beiträge
 
Delphi 12 Athens
 
#6

AW: Autotext-Programm - aber wie?

  Alt 20. Nov 2012, 16:12
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 MSDN-Library durchsuchenWM_SETTEXT und Co.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#7

AW: Autotext-Programm - aber wie?

  Alt 20. Nov 2012, 16:58
@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.
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Marco Steinebach

Registriert seit: 4. Aug 2006
502 Beiträge
 
Delphi 5 Enterprise
 
#8

AW: Autotext-Programm - aber wie?

  Alt 21. Nov 2012, 05:46
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:
    keybd_event (ord('h'), MapVirtualKey (ord('h'), 0), 0, 0);
    keybd_event (ord('h'), MapVirtualKey (ord('h'), 0), keyeventf_keyup, 0);
sollte man eigentlich auch ein "h" senden können - tut aber nicht. Hat jemand 'ne Idee warum?

Vielen Dank schonmal und viele Grüße
Marco
Marco Steinebach
  Mit Zitat antworten Zitat
API

Registriert seit: 18. Apr 2004
637 Beiträge
 
#9

AW: Autotext-Programm - aber wie?

  Alt 21. Nov 2012, 06:18
Hallo Marco, google nach Bei Google suchenPostKeyEx32
  Mit Zitat antworten Zitat
Marco Steinebach

Registriert seit: 4. Aug 2006
502 Beiträge
 
Delphi 5 Enterprise
 
#10

AW: Autotext-Programm - aber wie?

  Alt 7. Dez 2012, 19:59
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:
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) <> 'MFGthen 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.
Viele Grüße
Marco
p.s.: bitte entschuldigt, daß ich nicht mehr alle Querverweise parat habe, bei wem ich mir was abgeschaut habe!
Angehängte Dateien
Dateityp: zip test_Clipboard.zip (2,4 KB, 7x aufgerufen)
Marco Steinebach
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:42 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