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
Marco Steinebach

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

AW: Autotext-Programm - aber wie?

  Alt 7. Dez 2012, 18: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
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: Autotext-Programm - aber wie?

  Alt 7. Dez 2012, 21:59
Es wäre sehr freundlich, wenn du uns die Exception Meldung verraten würdest (Einfach Strg-C) und dann hier einfügen und auch an welcher Stell das passiert (ausführen des Programms im Debugger, dann wird dir die Stelle angezeigt)
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Marco Steinebach

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

AW: Autotext-Programm - aber wie?

  Alt 8. Dez 2012, 11:10
... genau das ist ja mein Problem, daß ich eben keine Exception der üblichen Form bekomme, sondern
- entweder eine Schutzverletzung "lesen von Adresse bla..."
- oder "Clipboardtest.exe hat einen Fehler verursacht und muß beendet werden"
oder es funktioniert ein, zwei mal, und dann kriege ich eine Schutzverletzung beim Schließen des Programms.
Offensichtlich wühle ich irgendwo im Arbeitsspeicher rum, wo ich nichts zu suchen habe.

Probiere ich das Ganze, während Delphi läuft, lande ich nach druck auf strg+c einfach ohne weitere Meldungen im CPU-Fenster.

Laufe ich mit dem Debugger drüber, läuft die Funktion WMDrawClipBoard scheinbar durch, und erst beim "end" lande ich CPU-Fenster.
Übrigens geht daß auch schief, wenn man einen text nimmt, der kein CopyTextToClipBoard zur folge hat, also biespielsweise im Word "test" schreibt und anschließend strg+c drückt.

Viele Grüße
Marco
Marco Steinebach
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Autotext-Programm - aber wie?

  Alt 8. Dez 2012, 15:23
Wenn du das CPU Fenster siehst, dann wird dir auch der Aufruf Stack gezeigt, und daran kann man nachverfolgen, welcher Aufruf in deinem Quellcode da gerade am Zug ist.

Ich vermute mal, dass du beim Zugriff auf die Zwischenablage diesen Fehler bekommst.
Da dein Programm ja nicht den exklusiven Zugriff auf die Zwischenablage hat (ist ja für alle gedacht), musst du prüfen und ggfs warten, bis du wirklich den Zugriff auf die Zwischenablage hast.

Macht man das nicht, dann knallt es eben
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Marco Steinebach

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

AW: Autotext-Programm - aber wie?

  Alt 8. Dez 2012, 15:51
Der Stack zeigt nur, daß WMDrawClipBoard gerade am zug ist...

Gibt's eine extra Methode um zu prüfen, ob ich an die Zwischenablage ran darf, oder einfach eine Schleife um OpenClipBoard herum? ...

Ich brauch nochmal 'n Schups, bitte...
Marco Steinebach
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: Autotext-Programm - aber wie?

  Alt 8. Dez 2012, 16:26
Werte doch mal den Resultcode von MSDN-Library durchsuchenOpenClipboard aus
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Marco Steinebach

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

AW: Autotext-Programm - aber wie?

  Alt 29. Dez 2012, 12:50
Hallo zusammen,
meine Güte, warum schlage ich mich eigentlich nicht mit was einfacherem Rumm.
Also: ich bin jetzt soweit, daß die Methode, das wort vor dem Cursr zu markieren, in die Zwischenablage zu kopieren, es auszuwerten, ggf. zu ersetzen, und dann mittels strg+v wieder einzufügen läuft, bis auf Outlook. Ich weiß nicht, was mein Outlook mit der Zwischenablage tut, aber irgendwie halten die sich da offensichtlich nicht an ihre eigenen Regeln.
Gibt es irgend eine Möglichkeit, das wort, welches vor dem Cursor steht, auszulesen? Oder wird's doch ernsthaft ein Keyboard-Hook?
Falls ja, würde das nämlich auch die Zwischenablage in ruhe lassen...
Viele Grüße
Marco
Marco Steinebach
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#8

AW: Autotext-Programm - aber wie?

  Alt 8. Dez 2012, 06:16
Und wo bekommst du die Exception?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Antwort Antwort


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 08:26 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