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
Redeemer

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

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.075 Beiträge
 
Delphi 12 Athens
 
#2

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.587 Beiträge
 
Delphi 12 Athens
 
#3

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
 
#4

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.140 Beiträge
 
Delphi 2009 Professional
 
#5

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.599 Beiträge
 
Delphi 7 Professional
 
#6

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 09:13 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