AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi [D7] TRichEdit verweigert ein einem Rechner PasteFromClipboard
Thema durchsuchen
Ansicht
Themen-Optionen

[D7] TRichEdit verweigert ein einem Rechner PasteFromClipboard

Ein Thema von Hobbycoder · begonnen am 22. Jul 2025 · letzter Beitrag vom 23. Jul 2025
Antwort Antwort
Hobbycoder

Registriert seit: 22. Feb 2017
1.017 Beiträge
 
#1

[D7] TRichEdit verweigert ein einem Rechner PasteFromClipboard

  Alt 22. Jul 2025, 17:52
Hi,

in einem alten Projekt habe ich einen merkwürdigen Fehler:
In der Zeile PasteFromClipboard wird nicht eingefügt, sondern lediglich ein Beep ausgegeben.
Das Problem: Es tritt nur an einem Kundenrechner und nur bei einem Kunden auf. Ich konnte den Fehler bei mir nicht reproduzieren, beim Kunden aber jedes mal. Irgendwann hat er dann doch einmal was eingefügt, aber das ging wirklich auch nur einmal. Danach wieder troz Neustarts der Software und auch des Rechners nicht mehr.

Es wird auch keine Exception ausgelöst und GetLastError liefert 0.
Was aber geht ist das Einfügen im RichEdit per Strg+V und ich kann den auch dein Text, der in der Prozedur vorher mit CopyToClipboard in der Zwischenablage abgelegt wurde problemlos z.B. in Word einfügen.

Das einzige, was sich geändert hat (und danach ist der Fehler aufgetreten) ist, dass der Arbeitsplatz einen neuen PC bekommen hat. Die Festplatte wurde jedoch per Image-Backup übernommen. Betriebssystem am Problemrechner ist Win-10-Pro. Leider kann der Zielrechner nicht mal eben neu installiert werden, weil da wohl sehr viele Software drauf ist, die täglich benötigt wird. (Aussage des Kunden)
Virenscanner ist Sophos, wie bei allen anderen Rechnern des Netzwerks auch, und ansonsten hat der Rechner keine Probleme.

Delphi-Quellcode:
  try
    if (Arow>0) and (ACol<2) then begin
      RichEdit_vorlage.SelectAll;
      RichEdit_vorlage.SelLength:=RichEdit_vorlage.SelLength-1;
      RichEdit_vorlage.CopyToClipboard;
      RichEdit1.PasteFromClipboard;
      RichEdit1.SetFocus;
      lblLastOSError.Caption:=IntToStr(GetLastError);
    end;
  except
    on E: Exception do
    begin
      OnError(Self, 'PasteFromClipboard', 0, E.Message);
      ShowMessage('Fehler: '+E.Message+sLineBreak+'OS Error: '+IntToStr(GetLastError));
    end;
  end;
Hat einer sowas schon mal gehabt, oder ne Idee, wo ich suchen könnte?
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.

Geändert von Hobbycoder (22. Jul 2025 um 17:54 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: [D7] TRichEdit verweigert ein einem Rechner PasteFromClipboard

  Alt 22. Jul 2025, 18:31
Es gibt Programme, welche die Zwischenablage überwachen.
Während diese noch im Zugriff sind (nach der Change-Notification), kann dein zweites Edit nunmal noch nicht darauf zugreifen.

Aus dem selben Grund knallt(e) auch Delphi manchmal, weil es in der Notofication nicht immer sofort Zugriff bekommt und dieser Fehler beschissen behandelt wird)
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Redeemer

Registriert seit: 19. Jan 2009
Ort: Kirchlinteln (LK Verden)
1.134 Beiträge
 
Delphi 2009 Professional
 
#3

AW: [D7] TRichEdit verweigert ein einem Rechner PasteFromClipboard

  Alt 22. Jul 2025, 19:36
Wie verhält sich Excel? Das ist ja dafür bekannt, dass es die Zwischenablage komplett missbraucht, da beispielsweise alle Verschiebe- und Kopieroperationen ausschließlich über die Zwischenablage implementiert sind.
Janni
2005 PE, 2009 PA, XE2 PA
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
10.055 Beiträge
 
Delphi 12 Athens
 
#4

AW: [D7] TRichEdit verweigert ein einem Rechner PasteFromClipboard

  Alt 22. Jul 2025, 20:09
Du könntest einmal versuchen, die Zwischenablage manuell anzusprechen. Wenn du z.B. OpenClipboard verwendest, solltest du im Fehlerfall mit SysErrorMessage(GetLastError) auch eine passende Fehlermeldung bekommen.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: [D7] TRichEdit verweigert ein einem Rechner PasteFromClipboard

  Alt 22. Jul 2025, 20:09
Zuerst würde ich das SetFocus vor dem PasteFromClipboard machen, damit schön ins aktive Control kopiert werden kann.


dass es die Zwischenablage komplett missbraucht, da beispielsweise alle Verschiebe- und Kopieroperationen ausschließlich über die Zwischenablage implementiert sind.
Du meinst so, wie hier?

Delphi-Quellcode:
var MS := TMemoryStream.Create;
try
  RichEdit1.Lines.SaveToStream(MS);
  MS.Position := 0;
  RichEdit2.Lines.LoadFromStream(MS);
finally
  MS.Free;
end;
PS: GetLastError ist so absolut nutzlos, wenn es nicht möglichst direkt nach der knallenden WinAPI abgerufen wird.
Es liefert nicht den LETZTEN Fehler, sondern den Status, welchen jemand zuletzt gesetzt hat. (und leider setzen zu viele API diesen auf 0, selbst wenn sie erfolgreich waren)

heißt, SetFocus kann diesen überschrieben haben, selbst wenn ein Fehlercode innerhalb von PasteFromClipboard gesetzt wurde.
Und im Except ... im OnError können Operationen passiert sein, welche den Fehlercode überschreiben,
außerdem können die Stringoperationen links vom GetLastError ebenfalls das gemacht haben, denn die darin genutzten Speicheroperationen (bezüglich der Strings) machen das gern.
Wenn, dann den Wert rechtzeitig lesen und zwischenspeichern.

WM_PASTE liefert zum Glück kein Result (laut Dokumentationen),
außerdem macht PasteFromClipboard nichts "Unglückliches, nach dem SendMessage.
Aber um sicher zu gehn, könnte man es mal so versuchen. (außer man lässt das Unding mit der Zwischenablage einfach sein)
Delphi-Quellcode:
RichEdit1.PasteFromClipboard;
Err := GetLastError;
ShowMessage(Err.ToHexString + ' ' + SysErrorMessage(Err));

Res := SendMessage(RichEdit1.Handle, WM_PASTE, 0, 0);
Err := GetLastError;
ShowMessage(Res.ToString + ' ' + Err.ToHexString + ' ' + SysErrorMessage(Err));
Ja, wenn zwischen SendMessage und GetLastError nix schlimmes WinAPIiges passiert, dann geht es auch direkt.
Delphi-Quellcode:
RichEdit1.PasteFromClipboard; // darin passiert nach dem SendMessage nix mehr
ShowMessage(SysErrorMessage(GetLastError)); // und hier wird GetLastError zuerst ausgeführt, vor den anderen beiden Funktionen.

RichEdit1.PasteFromClipboard;
RaiseLastOSError;
Als Nutzer macht es echt keinen Spaß, wenn Programme grob fahrlässig die Zwischenablage schrotten. (auch wenn ich inzwischen die Historie aktiviert hab und notfalls keine Daten mehr bösartig zerstört werden).
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (22. Jul 2025 um 20:16 Uhr)
  Mit Zitat antworten Zitat
mandras

Registriert seit: 22. Mai 2019
4 Beiträge
 
#6

AW: [D7] TRichEdit verweigert ein einem Rechner PasteFromClipboard

  Alt 22. Jul 2025, 21:27
Versuche einmal, zwischen dem Copy und dem Paste eine
Verzögerung einzubauen oder alternativ vor dem paste
ein Openclipboard, welches im Fehlerfall wiederholt wird,
bis es geklappt hat oder ein Timeout auftritt.

Ich hatte einmal einen ähnlich schwer zu reproduzierenden Fehler,
dort lag es daran, daß zum Zeitpunkt des Paste das Clipboard noch durch
einen anderen Prozess gesperrt war, der angestoßen wurde direkt nach dem
Copy (vgl. Post von Himitsu)
  Mit Zitat antworten Zitat
Redeemer

Registriert seit: 19. Jan 2009
Ort: Kirchlinteln (LK Verden)
1.134 Beiträge
 
Delphi 2009 Professional
 
#7

AW: [D7] TRichEdit verweigert ein einem Rechner PasteFromClipboard

  Alt 22. Jul 2025, 21:30
Zuerst würde ich das SetFocus vor dem PasteFromClipboard machen, damit schön ins aktive Control kopiert werden kann.


dass es die Zwischenablage komplett missbraucht, da beispielsweise alle Verschiebe- und Kopieroperationen ausschließlich über die Zwischenablage implementiert sind.
Du meinst so, wie hier?
Ich seh's jetzt erst.
Was macht eine Vorlage überhaupt in einem TRichEdit und nicht in einer Ressource? Außer, das wird mehrfach hintereinander gehängt...
Janni
2005 PE, 2009 PA, XE2 PA
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.598 Beiträge
 
Delphi 7 Professional
 
#8

AW: [D7] TRichEdit verweigert ein einem Rechner PasteFromClipboard

  Alt 23. Jul 2025, 11:55
Die beiden würd' ich vertauschen:
Statt
Delphi-Quellcode:
RichEdit1.PasteFromClipboard;
RichEdit1.SetFocus;
lieber
Delphi-Quellcode:
RichEdit1.SetFocus;
RichEdit1.PasteFromClipboard;
Beim Einfügen aus der Zwischenablage beept es gerne, wenn die Stelle, die den Inhalt der Zwischenablage bekommen soll, keinen Focus hat.

Ist in RichEdit1 vor dem PasteFromClipboard etwas enthalten?

Ist es leer? Dann füge den Inhalt der Zwischenablage in einer Schleife ein, bis etwas vorhanden ist, sinngemäß sowas:
Delphi-Quellcode:
iError := 0;
RichEdit.SetFocus;
repeat
  Sleep(iError * 100); // Eine Pause machen, die bei jedem Versuch etwas größer wird.
  iError := iError + 1;
  RichEdit1.PasteFromClipboard;
until (RichEdit1.Text <> '') or (iError > 5);
if iError > 5 then begin
  // Fehlermeldung machen
end else
if RichEdit1.Text = 'then begin
  // andere Fehlermeldung machen
end;
Ein Beep tritt aber auch dann auf, wenn das Format in der Zwischenablage nicht vom RichEdit unterstützt wird. Eventuell vorher das Format prüfen, so in der (ungetesteten) Art:
Delphi-Quellcode:
function RichEditCanPaste: Boolean;
var
  RtfFormat: Word;
begin
  // Prüfe Plain Text
  if Clipboard.HasFormat(CF_TEXT) or Clipboard.HasFormat(CF_UNICODETEXT) then
    Exit(True);
  // Prüfe RTF
  RtfFormat := RegisterClipboardFormat('Rich Text Format');
  Result := Clipboard.HasFormat(RtfFormat);
end;

function ClipboardFormatToString(CF: Word): string;
begin
  case CF of
    1: Result := 'CF_TEXT';
    2: Result := 'CF_BITMAP';
    3: Result := 'CF_METAFILEPICT';
    4: Result := 'CF_SYLK';
    5: Result := 'CF_DIF';
    6: Result := 'CF_TIFF';
    7: Result := 'CF_OEMTEXT';
    8: Result := 'CF_DIB';
    9: Result := 'CF_PALETTE';
    10: Result := 'CF_PENDATA';
    11: Result := 'CF_RIFF';
    12: Result := 'CF_WAVE';
    13: Result := 'CF_UNICODETEXT';
    14: Result := 'CF_ENHMETAFILE';
    15: Result := 'CF_HDROP';
    16: Result := 'CF_LOCALE';
    // ... ggf. erweitern
  else
      begin
        // Falls kein Standardformat: Versuche, den Namen über API zu holen
        SetLength(Result, 255);
        if GetClipboardFormatName(CF, PChar(Result), 255) > 0 then
          SetLength(Result, StrLen(PChar(Result)))
        else
          Result := 'Unbekanntes Format (' + IntToStr(CF) + ')';
      end;
  end;
end;

var
  i : Integer;
  cf : Word;
  sl : TStringList;
begin
  sl := TStringList.Create;
  try
    try
      if RichEditCanPaste then
        RichEdit1.PasteFromClipboard
      else begin
        sl.Add('In der Zwischenablage enthaltene Formate:');
        sl.Add('');
        for i := 0 to Clipbrd.Clipboard.FormatCount - 1 do begin
          cf := Clipbrd.Clipboard.Formats[i];
          sl.Add(Format('%.5d - %s',[cf, ClipboardFormatToString(cf)]));
        end;
        ShowMessage(sl.Text);
      end;
    except
      on E: Exception do
      begin
        OnError(Self, 'PasteFromClipboard', 0, E.Message);
        ShowMessage('Fehler: '+E.Message+sLineBreak+'OS Error: '+IntToStr(GetLastError));
      end;
    end;
  finally
    sl.free;
  end;
end;
  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 07:01 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