Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Clipboard Fehler (https://www.delphipraxis.net/108129-clipboard-fehler.html)

dominikkv 7. Feb 2008 13:25


Clipboard Fehler
 
Hi

Ich will das Clipboard überwachen und bei Änderungen den Text auswerten.
Ich hab mir also nen Timer geschnappt der jede Sekunde das ausführt:
Delphi-Quellcode:
uses
  {...}, clipbrd, {...}

procedure TfMain.tmrClipboardTimerTimer(Sender: TObject);
begin
  if oldClipboardText <> Clipboard.AsText then
    begin
      oldClipboardText := Clipboard.AsText;
      if chk1.Checked then
        ClipboardChanged(oldClipboardText);
    end;
end;
Funktioniert auch recht gut...
...aber!

Wenn ich nun Outlook starte, ne E-mail öffne und nen Textausschnitt in die Zwischenablage kopiere wird wie gewollt meine procedure ClipboardChanged ausgeführt.
Nun schließe ich Outlook wieder und bekomme in meinem Programm den Fehler:
Zitat:

exception class : Exception
exception message : Zwischenablage kann nicht geöffnet werden.
Und hier noch der Stack:
Zitat:

main thread ($1188):
0047e1ff +04b MyProg.exe Clipbrd TClipboard.Open
0047e241 +011 MyProg.exe Clipbrd TClipboard.GetAsText
004b3fd8 +020 MyProg.exe uMain 131 +1 TfMain.tmrClipboardTimerTimer
0047d097 +01b MyProg.exe ExtCtrls 2281 +1 TTimer.Timer
0047cf03 +02f MyProg.exe ExtCtrls 2239 +4 TTimer.WndProc
...
Hat jemand ne Idee woran das liegt?

mfg.Dominik

DerDan 7. Feb 2008 13:40

Re: Clipboard Fehler
 
Hallo:

Es gibt auch eine Event, welches Ausgelöst wird, wenn sich der Inhalt des clipboards ändert:
Damit deine Applikation dieses Event bekommt muss sie sich als Clipboard Viewer im Betriebssystem anmelden.

such mal nach

SetClipboardViewer
WM_CHANGECBCHAIN
WM_DRAWCLIPBOARD

im Win32 API

auf das Event "WM_DRAWCLIPBOARD" hin kannst du den Inhalt prüfen und kopieren.

hab mal was für Bitmaps geschrieben hat gut funktioniert.

Vielleicht behebt die Umstellung von Pollen auf Events auch dein Problem mit den Exceptiones.

mfg

derDan

mashutu 7. Feb 2008 13:43

Re: Clipboard Fehler
 
Zitat:

Zitat von dominikkv
Hi
[...]
Hat jemand ne Idee woran das liegt?

mfg.Dominik

Daran dass MS-Anwendungen komische dinge mit dem Clipboard veranstalten.
Das ist mir schon frueher aufgefallen und Dein Fehler laesst sich voll nachvollziehen... :-(

DerDan 7. Feb 2008 13:44

Re: Clipboard Fehler
 
Hallo,

hab nochmal deine Code durchgesehen. vielleicht solltest du prüfen, ob überhaupt Text in der Zwischenablage drin ist.

Delphi-Quellcode:
  if Clipboard.HasFormat(CF_BITMAP) then begin
    CopyBmpFromClipboard;
du musst natürlich CF_TEXT nehmen.


mfg


DerDan

Luckie 7. Feb 2008 13:44

Re: Clipboard Fehler
 
Das macht man nicht mit einem Timer, sondern man hängt sich in die ClipboardChain ein, um bei Änderungen benachrichtigt zu werden. Siehe dazu mein Programm ClipView: http://www.michael-puff.de/Developer/Delphi/Programme/

RavenIV 7. Feb 2008 13:46

Re: Clipboard Fehler
 
Du musst prüfen, ob im Clipboard etwas drin ist.
Wenn nix drin ist, schmeisst AsText eine Exception.

Siehe Delphi-Hilfe bei TClipboard.AsText...

dominikkv 7. Feb 2008 14:08

Re: Clipboard Fehler
 
Danke erstmal für eure Antworten :hello:

:arrow: Das mit der ClipboardChain hatte ich schon ausprobiert (Clipboard Viewer), allerdings braucht der so ca 5 Sekunden bis er sich da eingeklinkt hat... zu lange!

:arrow: Ich hab den Timer jetzt mal so umgeändert:
Delphi-Quellcode:
procedure TfMain.tmrClipboardTimerTimer(Sender: TObject);
begin
  if Clipboard.HasFormat(CF_TEXT) then
    if oldClipboardText <> Clipboard.AsText then
      begin
        oldClipboardText := Clipboard.AsText;
        if chk1.Checked then
          ClipboardChanged(oldClipboardText);
      end;
end;
-> gleicher Fehler :(

:arrow: Überprüfen ob in der Zwischenablage nix drinnsteht geht ja schlecht... dazu müsste ich auf Clipboard.AsText zugreifen...
Außerdem habe ich keine entsprechende Methode dafür gefunden.
Außerdem ist nach dem Schließen von Outlook der Text in der Zwischenablage noch vorhanden (Paste in Editor geht)

Wäre es ne Lösung den Zugriff mit try...except zu klammern?

RavenIV 7. Feb 2008 14:17

Re: Clipboard Fehler
 
Schau Dir das Programm von Luckie nochmal an.
Das funktioniert und ist viel schneller.

dominikkv 7. Feb 2008 14:56

Re: Clipboard Fehler
 
ok, angeschaut -> abgeschrieben -> geht :angel2:

Delphi-Quellcode:
 TfMain = class(TForm)
  private
    hNextViewer: DWORD;
  protected
    procedure WMChangeCBChain(var Msg: TMessage); message WM_CHANGECBCHAIN;
    procedure WMDrawClipboard(var Msg: TMessage); message WM_DRAWCLIPBOARD;
  end;


  // FormCreate:
  hNextViewer := SetClipBoardViewer(Handle);

  // FormDestroy:
  ChangeClipBoardChain(Handle, hNextViewer);


procedure TfMain.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 TfMain.WMDrawClipboard(var Msg: TMessage);
var
  hClipbrdObj: THandle;
  pClipbrdObj: Pointer;
begin
  OpenClipboard(Handle);
  hClipbrdObj := GetClipboardData(CF_TEXT);
  if hClipbrdObj <> 0 then
    begin
      pClipbrdObj := GlobalLock(hClipbrdObj);
      if chk1.Checked then
        ClipboardChanged(PChar(pClipbrdObj));
    end;
  GlobalUnlock(DWORD(pClipbrdObj));
  GlobalFree(hClipbrdObj);
  CloseClipBoard;
end;
Thx @ all (und besonders an Luckie^^) :cheers:

:dp:

RavenIV 7. Feb 2008 15:00

Re: Clipboard Fehler
 
Zitat:

Zitat von dominikkv
ok, angeschaut -> abgeschrieben -> geht :angel2:

Hast Du auch kapiert, was da gemacht wird?
Abschreiben alleine reicht ja nicht.

dominikkv 8. Feb 2008 13:56

Re: Clipboard Fehler
 
Zitat:

Zitat von RavenIV
Zitat:

Zitat von dominikkv
ok, angeschaut -> abgeschrieben -> geht :angel2:

Hast Du auch kapiert, was da gemacht wird?
Abschreiben alleine reicht ja nicht.

ähh... so halber^^
...oder sagen wir zu dreiviertel xD

DeddyH 8. Feb 2008 13:59

Re: Clipboard Fehler
 
Wieso eigentlich abgeschrieben? Du hättest auch die Zwischenablage nutzen können :lol:

napstar 1. Apr 2008 19:51

Re: Clipboard Fehler
 
kann mir jemand erklähren was in diesem code hier gemacht wird.. ich will nicht einfach was übernehmen, ohne das ich was dabei lerne ^^

Delphi-Quellcode:
TfMain = class(TForm)
  private
    hNextViewer: DWORD;
  protected
    procedure WMChangeCBChain(var Msg: TMessage); message WM_CHANGECBCHAIN;
    procedure WMDrawClipboard(var Msg: TMessage); message WM_DRAWCLIPBOARD;
  end;


  // FormCreate:
  hNextViewer := SetClipBoardViewer(Handle);

  // FormDestroy:
  ChangeClipBoardChain(Handle, hNextViewer);


procedure TfMain.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 TfMain.WMDrawClipboard(var Msg: TMessage);
var
  hClipbrdObj: THandle;
  pClipbrdObj: Pointer;
begin
  OpenClipboard(Handle);
  hClipbrdObj := GetClipboardData(CF_TEXT);
  if hClipbrdObj <> 0 then
    begin
      pClipbrdObj := GlobalLock(hClipbrdObj);
      if chk1.Checked then
        ClipboardChanged(PChar(pClipbrdObj));
    end;
  GlobalUnlock(DWORD(pClipbrdObj));
  GlobalFree(hClipbrdObj);
  CloseClipBoard;
end;

dominikkv 1. Apr 2008 20:14

Re: Clipboard Fehler
 
Delphi-Quellcode:
TfMain = class(TForm)
  private
    hNextViewer: DWORD; // Handle des nächsten Kettenmitglieds
  protected
    procedure WMChangeCBChain(var Msg: TMessage); message WM_CHANGECBCHAIN; // wird aufgerufen wenn sich die Kette verändert
    procedure WMDrawClipboard(var Msg: TMessage); message WM_DRAWCLIPBOARD; // wird aufgerufen wenn sich das Clipboard verändert
  end;


  // FormCreate:
  hNextViewer := SetClipBoardViewer(Handle); // Dich in der Kette anmelden und das nächste Mitglied sichern

  // FormDestroy:
  ChangeClipBoardChain(Handle, hNextViewer); // Dich von der Kette ausklinken und dem Folgemitglied bescheid geben


procedure TfMain.WMChangeCBChain(var Msg: TMessage);
begin
  if Msg.WParam = hNextViewer then   // wenn die Nachricht von dem Folgemitglied kommt (d.h. er sich aus der Kette ausklinkt)
    hNextViewer := Msg.lParam        // das nächste Folgenmitglied sichern
  else if hNextViewer <> 0 then      // ansonsten wenn es ein Folgemitglied gibt
    SendMessage(hNextViewer, MSG.Msg, MSG.wParam, MSG.lParam); // die Nachricht weiterleiten
end;

procedure TfMain.WMDrawClipboard(var Msg: TMessage);
var
  hClipbrdObj: THandle;
  pClipbrdObj: Pointer;
begin
  OpenClipboard(Handle); // Clipboard öffnen
  hClipbrdObj := GetClipboardData(CF_TEXT); // schauen ob Text drinnsteht -> Handle
  if hClipbrdObj <> 0 then // wenn ja
    begin
      pClipbrdObj := GlobalLock(hClipbrdObj); // einen Zeiger auf die Daten ausrichten und den bereich Sperren
      if chk1.Checked then
        ClipboardChanged(PChar(pClipbrdObj)); // etwas mit den Daten machen
    end;
  GlobalUnlock(DWORD(pClipbrdObj)); // Sperrung aufheben
  GlobalFree(hClipbrdObj);          // Den Speicherbereich freigeben und Handle ungültig machen
  CloseClipBoard;                   // Clipboard schließen
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:03 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