Net-Base Dergi

26.09.2026

VCL: Unicode ve HTML formatında Kopyala&Yapıştır – Panodaki formatları doğru şekilde ayarlama ve okuma

VCL'den Outlook, Teams veya web düzenleyicilerine Copy&Paste yapıldığında biçimlendirme kayboluyor veya Umlautlar bozuluyorsa, sorun sıklıkla CF_HTML paketinden kaynaklanır. Böylece Unicode metni ve "HTML Format"ı temiz şekilde ayarlayıp okursunuz — offset'ler, fallback ve hata ayıklama dahil.

26.09.2026

Dergi konusundan proje pratiğine

İçeriğe Uygun Hizmet ve Teknik Sayfalar

Der Moment kommt meistens nicht im Code-Review, sondern im Testlauf: In Ihrer VCL-Anwendung markiert jemand eine sauber formatierte Passage, drückt Strg+C und fügt sie in Outlook ein. Statt fett und klickbar kommt ein flacher Textblock. Oder schlimmer: „Müller & Söhne“ wird zu „Müller & Söhne“. In Notepad war alles korrekt, also scheint es „nicht an uns“ zu liegen. Genau dieser Irrtum kostet später Zeit, weil Copy&Paste unter Windows nicht „ein Text“, sondern ein Aushandlungsprozess zwischen Sender und Empfänger ist.

Wenn Sie VCL Clipboard Unicode HTML-Format sauber lösen wollen, müssen Sie zwei Dinge gleichzeitig beherrschen: Unicode-Text als robusten Fallback bereitstellen und HTML als strukturiertes Clipboard-Format korrekt paketieren. Der Knackpunkt ist nicht „HTML generieren“, sondern CF_HTML korrekt setzen und auslesen – inklusive Header, Byte-Offsets und Fragment-Markern. Sobald das passt, verhalten sich Outlook, Teams, Word und viele Web-Editoren deutlich berechenbarer.

Der entscheidende Moment: Was die Zwischenablage wirklich tut

Arbeitsplatzszene mit unscharfen Monitoren und Unterlagen zur Analyse von Clipboard-Daten und Offsets.
Debugging in der Praxis: CF_HTML-Bytes auslesen und Header/Offsets gegen die tatsächliche Länge validieren.
Abstrakte Darstellung eines CF_HTML-Datenblocks mit Header, Body und markiertem Fragmentbereich.
CF_HTML besteht aus Header und HTML-Body; Offsets referenzieren Bytepositionen innerhalb des gesamten Datenblocks.
Schematische Darstellung einer Zwischenablage mit Unicode-Text und HTML als parallele Formate und mehreren Empfängern.
Mehrformat-Prinzip: Zielprogramme wählen das reichste passende Format – HTML als Primärpfad, Unicode als Fallback.

Weniger hilfreich ist die übliche Sofortreaktion: „Dann nehmen wir einfach Clipboard.AsText, Unicode ist doch in Delphi drin.“ Das führt zu einem trügerisch stabilen Zustand: Notepad, Logs und viele interne Tools funktionieren, also gilt das Problem als „Office-Zickigkeit“. In Wahrheit liefern Sie nur einen Teil dessen, was der Empfänger abfragt.

Die bessere Reaktion: Sie betrachten die Zwischenablage als Transportcontainer mit mehreren Formaten. Windows erlaubt, denselben Inhalt parallel in unterschiedlichen Clipboard-Formaten abzulegen. Empfänger wählen daraus das passendste. Microsoft beschreibt dieses Mehrformat-Prinzip ausdrücklich: Anwendungen sollen Daten in mehr als einem Format anbieten, damit Zielprogramme je nach Fähigkeiten und Sicherheitsregeln auswählen können.[Quelle] Praktische Folgerung: Sie liefern mindestens (1) Unicode-Plain-Text und (2) CF_HTML. Wenn HTML abgelehnt wird, bleibt der Fallback sauber.

VCL Clipboard Unicode HTML-Format: Was Sie dafür verstehen müssen

1) TClipboard ist nur die Kapsel – die Formate sind der Vertrag

Die VCL stellt Ihnen mit TClipboard eine bequeme Abstraktion über die Windows-Zwischenablage bereit. Entscheidend ist: Nicht jeder Zugriff läuft über AsText. Wenn Sie wissen wollen, ob ein Format vorhanden ist, nutzen Sie Format-IDs und HasFormat().[Quelle] Das klingt nach API-Detail, ist aber ein Architekturpunkt: Sie reduzieren Unschärfe. „Ist CF_HTML da?“ ist eine klare Frage. „Kommt beim Einfügen irgendwas raus?“ ist Support-Nebel.

2) CF_HTML ist kein HTML-String, sondern ein Byte-Stream mit Header

CF_HTML (Formatname: „HTML Format“) ist auf Windows-Seite klar spezifiziert. Es besteht aus einem Header (im Wesentlichen ASCII-Text) und einem HTML-Kontext. Der Header enthält Offsets wie StartHTML, EndHTML, StartFragment, EndFragment; zusätzlich markieren <!--StartFragment--> und <!--EndFragment--> den relevanten Ausschnitt. Diese Offsets beziehen sich auf Byte-Positionen im gesamten Stream. Wenn sie nicht zu den tatsächlichen Bytes passen, ist das Format für Empfänger unzuverlässig.[Quelle]

Konsequenz für Delphi: Sie können nicht „einfach einen String“ in die Zwischenablage legen und hoffen, dass Empfänger HTML daraus erraten. Sie müssen ein korrektes CF_HTML-Paket bauen.

Welche Clipboard-Formate Sie setzen sollten – und wozu

Format Charakter Wofür es im Alltag sorgt Typische Empfänger Häufige Fehlerbilder
CF_UNICODETEXT Standardformat (Unicode) Stabiler Fallback: Inhalt kommt an, ohne Formatierung Notepad, Ticketsysteme im Plain-Mode, viele Admin-Tools Nur dieses Format gesetzt: Formatierung fehlt überall
„HTML Format“ (CF_HTML via RegisterClipboardFormat) Registriertes Format Formatierung, Links, Tabellenfragmente; Empfänger wählen es, wenn möglich Outlook, Teams, Word, viele Web-Editoren Offsets falsch, Fragment-Marker fehlen, Encoding-Übergänge unsauber
CF_TEXT Standardformat (ANSI) Nur für echte Legacy-Empfänger, die kein Unicode können Alte Tools, Spezialsoftware Umlaute kaputt (Codepage-Mismatch), falsche Sonderzeichen

Für die meisten Unternehmensanwendungen ist die pragmatische Kombi: CF_UNICODETEXT + CF_HTML. CF_TEXT nur dann, wenn Sie bewusst einen Legacy-Empfänger bedienen müssen und die Risiken akzeptieren.

CF_HTML identifizieren: „HTML Format“ registrieren, dann mit Format-ID arbeiten

CF_HTML ist kein Delphi-Constant wie CF_UNICODETEXT. Sie bekommen die Format-ID zur Laufzeit, indem Sie den Namen registrieren. Genau dafür ist das Konzept „registrierte Clipboard-Formate“ gedacht: Der Name ist stabil, die numerische ID ist pro System/Laufzeit vergeben. Microsoft beschreibt das Prinzip hinter RegisterClipboardFormat() explizit: benannte Formate werden registriert und dann über die zurückgegebene ID abgefragt und übertragen.[Quelle]

Delphi-seitig ist das etablierte Muster: einmal registrieren, ID cachen, dann konsequent darüber arbeiten. DelphiDabbler zeigt den Ansatz für CF_HTML ebenfalls: Format-ID registrieren und dann handle-basiert lesen/schreiben.[Quelle] Für Ihren Code bedeutet das weniger „Magic“, mehr Diagnosefähigkeit: Sie wissen, welches Format Sie setzen und ob es wirklich vorhanden ist.

Der saubere Ablauf beim Kopieren: Mehrformat statt Hoffnung

Wenn Copy&Paste öfter gebraucht wird (nicht nur „nice to have“), lohnt sich eine kleine, getestete Routine. Die Kunst ist nicht Komplexität, sondern Konsistenz.

  1. Inhalt trennen: Erzeugen Sie (a) Plain-Text für CF_UNICODETEXT und (b) HTML-Fragment für CF_HTML. Halten Sie beides logisch getrennt, auch wenn der Inhalt ähnlich aussieht.
  2. Clipboard atomar beschreiben: Clipboard öffnen, leeren, befüllen, schließen. Die Zwischenablage ist global; kurze, atomare Phasen reduzieren Konflikte mit anderen Programmen.
  3. Fallback zuerst setzen: CF_UNICODETEXT ist Ihr Sicherheitsnetz. Wenn später CF_HTML nicht akzeptiert wird, bleibt wenigstens Unicode sauber.
  4. CF_HTML paketieren: Header (ASCII), HTML-Teil (Bytefolge), Offsets auf Bytebasis. Dann als Handle in die Zwischenablage.
  5. Optional verifizieren: In Debug-/Diagnosemodus nach dem Setzen wieder auslesen und Header/Offsets plausibilisieren. Das spart später Sucherei.

Typische Fallstricke: wo Copy&Paste in Delphi-Projekten wirklich kippt

Byte-Offsets vs. Delphi-Strings (UTF-16)

Delphi-string ist in der modernen VCL UTF-16. CF_HTML-Offets sind Bytepositionen in der tatsächlich abgelegten Bytefolge. Das ist der zentrale Übergang, an dem viele Implementierungen scheitern: Sie rechnen Offsets auf Zeichenpositionen oder auf Length(string). Das kann nicht funktionieren, sobald Nicht-ASCII-Zeichen oder UTF-8 ins Spiel kommen.

Robust ist eine einfache Disziplin: Sie entscheiden sich für die Byte-Repräsentation des CF_HTML-Streams (Header + HTML) und rechnen Offsets ausschließlich auf dieser Bytefolge. Der Header bleibt ASCII, der HTML-Teil ist häufig UTF-8. Wichtig ist nicht „welches Encoding ist hübscher“, sondern dass Offsets und Bytes zusammenpassen.

Feste Feldbreiten im Header: sonst verschieben Sie sich selbst

Viele CF_HTML-Header verwenden Felder mit fester Breite, etwa StartHTML:00000097. Das ist nicht Folklore. Wenn Sie erst Platzhalter schreiben und später Zahlen unterschiedlicher Länge einsetzen, ändert sich die Headerlänge – und damit werden alle Offsets falsch, die Sie vorher berechnet haben.

Konsequenz: Nutzen Sie feste Breiten (typisch 8 oder 10 Ziffern) und halten Sie sie strikt ein. Das ist ein kleiner Aufwand mit großer Wirkung auf Interop-Stabilität.

Handle-Ownership: nach erfolgreichem Setzen gehört der Speicher dem System

Beim Transfer über die Windows-Zwischenablage arbeiten Sie (direkt oder indirekt über die VCL) mit globalen Memory-Handles. Der wichtigste Lebenszeitpunkt ist der Übergang: Wenn das System das Handle akzeptiert hat, dürfen Sie es nicht mehr freigeben. Wenn das Setzen scheitert, müssen Sie es hingegen selbst freigeben, sonst leaken Sie.

Das ist keine akademische Regel. In echten Anwendungen taucht das Problem gern in Fehlerpfaden auf: Ausnahme beim Kopieren, früher Return, Cleanup an falscher Stelle. Ergebnis: sporadische Access Violations beim Paste in anderen Programmen oder schwer zu findende Leaks.

Fragment-Marker: fehlt er, wird HTML manchmal ignoriert

Die Spezifikation sieht Fragment-Markup vor (<!--StartFragment--> / <!--EndFragment-->). Manche Empfänger sind tolerant, andere nicht. Wenn Sie Interop-Probleme sehen, liefern Sie die Marker und sorgen dafür, dass sie genau einmal vorkommen. Doppelte Marker durch Template-Logik oder Sanitizing sind ein typischer Grund für „Empfänger nimmt plötzlich nur noch Plain-Text“.

Auslesen beim Paste: besser wählen als raten

Beim Einfügen ist das Ziel nicht, alles zu konsumieren, sondern verlässlich das beste Format zu wählen, das Sie sauber verarbeiten können. Ein bewährtes Vorgehen ist:

  1. CF_HTML bevorzugen, wenn vorhanden: auslesen, Header parsen, Fragment extrahieren.
  2. Fallback auf CF_UNICODETEXT, wenn HTML fehlt oder ungültig ist.
  3. Optional weitere Formate je nach Anwendung (z. B. RTF, Dateien, Bilder) – aber nur, wenn Sie dafür klare Regeln haben.

Die Existenzprüfung machen Sie in der VCL mit TClipboard.HasFormat(). Das ist ausdrücklich der vorgesehene Weg, um das Vorhandensein eines Formats zu prüfen, statt blind über AsText zu gehen.[Quelle]

Header-Parsing: vier Validierungen, die Ihnen Support-Tickets sparen

Ein CF_HTML-Header ist schnell „irgendwie“ geparst. Entscheidend ist, dass Sie ihn auch bewerten. Diese Checks sind in der Praxis die sinnvollsten:

  • Vollständigkeit: Sind StartHTML/EndHTML und StartFragment/EndFragment vorhanden?
  • Bereich: Liegen alle Werte innerhalb der Gesamtlänge des Byte-Streams?
  • Hierarchie: Liegt das Fragment innerhalb des HTML-Bereichs?
  • Konsistenz: Passt die Fragmentgrenze grob zu den Marker-Positionen (falls Marker vorhanden sind)?

Wenn einer dieser Punkte scheitert, ist ein kontrollierter Rückfall auf Unicode-Text oft die bessere Nutzererfahrung als „halb kaputtes HTML“. Außerdem bekommen Sie klare Diagnosepunkte für Logging und Tests.

Debugging, das im Team funktioniert: reproduzierbar statt „bei mir geht’s“

Referenzvergleich: CF_HTML aus Browser/Word gegen Ihre Ausgabe

Wenn Sie nicht sicher sind, ob Ihr CF_HTML formal korrekt ist, hilft ein Referenzvergleich. Kopieren Sie denselben Inhalt aus einer Quelle, die CF_HTML zuverlässig setzt (Browser oder Word), und lesen Sie CF_HTML sowohl aus der Referenz als auch aus Ihrer Anwendung aus. Vergleichen Sie dann:

  • Header-Aufbau und Feldnamen
  • Zahlenbreite und Zeilenenden
  • Position und Anzahl der Fragment-Marker
  • Offets-Plausibilität (liegen sie auf sinnvollen Byte-Grenzen?)

Sie müssen die Referenz nicht imitieren, aber Abweichungen zeigen zuverlässig, wo Empfänger empfindlich reagieren.

Logging ohne Datenleck: nur Struktur, nicht Inhalt

Zwischenablage-Inhalte können personenbezogene Daten oder vertrauliche Informationen enthalten. Für Diagnosezwecke ist es daher sinnvoll, nicht den Inhalt zu loggen, sondern nur Strukturmerkmale:

  • Welche Formate sind vorhanden?
  • Byte-Längen des CF_HTML-Streams
  • Header-Offsets und Validierungsresultate
  • Optional Hashwerte zur Wiedererkennung, statt den Text selbst

Damit können Sie Probleme nachstellen, ohne Inhalte dauerhaft abzulegen. Das ist gerade in Unternehmensumgebungen oft der entscheidende Punkt, damit Diagnose überhaupt möglich bleibt.

Wann sich der Aufwand wirklich lohnt – und wo er bewusst endet

CF_HTML lohnt sich, wenn Formatierung Teil des Arbeitsprozesses ist: Tickettexte mit Links, strukturierte Statusmeldungen, HTML-E-Mails, Tabellenfragmente oder Prüfprotokolle, die direkt weiterverwendet werden. Dann spart eine saubere Mehrformat-Ablage spürbar Nacharbeit beim Einfügen und reduziert Reibung zwischen Systemen.

Es gibt aber klare Grenzen, die Sie nicht „wegcodieren“:

  • Security-Policies: Manche Umgebungen strippen HTML oder erlauben nur Plain-Text. Ihr Fallback muss dann tragen.
  • Editor-Dialekte: Web-Editoren sanitizen HTML unterschiedlich; ein Format, das Outlook akzeptiert, kann im Intranet-Editor bereinigt werden.
  • Globale Ressource Clipboard: Konkurrenzzugriffe sind normal. Halten Sie Clipboard-Operationen kurz, deterministisch und gut gekapselt.
  • Testmatrix: Ohne Tests gegen die realen Zielprogramme bleibt CF_HTML ein Glücksspiel.

Der pragmatische Zielzustand ist nicht „maximal viele Formate“, sondern zwei stabile Pfade: HTML, wenn es akzeptiert wird – und Unicode-Text, wenn nicht.

Review-Checkliste für Wartung und Modernisierung

  • Setzen wir CF_UNICODETEXT und CF_HTML im selben Copy-Vorgang?
  • Registrieren wir „HTML Format“ genau einmal und nutzen die ID überall konsistent?
  • Berechnen wir alle CF_HTML-Offets auf Bytebasis der tatsächlichen Bytefolge?
  • Hat der Header feste Feldbreiten, damit die Offsets stabil bleiben?
  • Ist die Handle-Ownership korrekt (nach erfolgreichem Setzen nicht freigeben)?
  • Validieren wir CF_HTML beim Paste und fallen bei Ungültigkeit kontrolliert auf Unicode zurück?
  • Gibt es einen reproduzierbaren Test (setzen → auslesen → Fragment prüfen), zumindest im Diagnosemodus?

Schluss: Copy&Paste ist eine Schnittstelle – behandeln Sie sie auch so

Copy&Paste wirkt wie UI-Detail, ist in vielen Desktop-Workflows aber eine Integrationsschnittstelle zwischen VCL-App, Office und Web-Tools. Sobald Unicode und HTML zusammenkommen, reicht AsText nicht mehr. Der saubere Ansatz ist: mehrere Formate anbieten, CF_HTML streng nach Spezifikation als Byte-Stream bauen, beim Paste validieren und bei Problemen sauber auf CF_UNICODETEXT zurückfallen. Das ist kein Glamour-Code, aber genau die Sorte Robustheit, die im Betrieb zählt.

Wenn Sie das in einer bestehenden Delphi/VCL-Anwendung systematisch konsolidieren möchten (Helper, Tests, Diagnosepfade, saubere Kapselung), lässt sich das am besten als kleines, klar abgegrenztes Modernisierungspaket angehen: Kontakt aufnehmen.

Quellen und weiterfuehrende Informationen

Die fachlichen Kernaussagen wurden anhand der folgenden externen Quellen redaktionell eingeordnet.

  1. Formato del Portapapeles HTML – Win32 apps | Microsoft Learn (learn.microsoft.com)
    CF_HTML („HTML Format“) ist als Windows-Clipboard-Format spezifiziert und nutzt Headerfelder wie StartHTML/EndHTML sowie StartFragment/EndFragment mit Byte-Offsets.
  2. Vcl.Clipbrd.TClipboard.HasFormat – RAD Studio API Documentation (docwiki.embarcadero.com)
    TClipboard.HasFormat ist der vorgesehene Weg in der VCL, um das Vorhandensein eines Clipboard-Formats zu prüfen, statt nur AsText zu verwenden.
  3. win32/desktop-src/dataxchg/clipboard-formats.md at docs · MicrosoftDocs/win32 · GitHub (github.com)
    Clipboard-Daten sollten in mehreren Formaten bereitgestellt werden, damit Empfänger das passendste Format wählen können (Mehrformat-Prinzip).
  4. win32/desktop-src/shell/clipboard.md at docs · MicrosoftDocs/win32 · GitHub (github.com)
    Benannte/registrierte Clipboard-Formate werden über RegisterClipboardFormat identifiziert; die ID wird dann zum Transfer genutzt.
  5. Use Delphi Pascal to receive data dragged from other applications | How to (delphidabbler.com)
    Delphi-typischer Zugriff auf CF_HTML erfolgt über RegisterClipboardFormat(‚HTML Format‘) und Handle-basiertes Lesen/Schreiben.

Für dieses Thema sind auch HTML Format Clipboard wichtig. Der Beitrag ordnet diese Aspekte verständlich ein und zeigt, worauf es im Alltag ankommt.

Projekt oder Modernisierungsvorhaben mit Net-Base besprechen.

Sonraki adım

Konu gerçek bir projeye dönüştüğünde, mimari, mevcut sistemler ve işletme erken dönemde birlikte değerlendirilmelidir.

Bireysel sorularda destek vermekle kalmıyoruz; kaynak kodu parçacıklarından, legacy konularından veya portal fikirlerinden sağlam bir kurumsal projeye dönüşene kadar da destek veriyoruz.

  • Mevcut durum, hedef durum ve teknik riskler birlikte değerlendirilir.
  • REST, veri erişimi, portallar ve Rollout daha sonra ortaya çıkan sonuçlar olarak ertelenmez.
  • Hangi yolun ekonomik ve işletme açısından sürdürülebilir olduğunu erken görürsünüz.

Gönderiyi paylaş

Bu gönderiyi doğrudan paylaş

LinkedIn, X, XING, Facebook, WhatsApp ve e-posta hemen kullanılabilir. Instagram için bağlantıyı ve kısa metni doğrudan hazırlıyoruz.

E-posta

Instagram yeni bir sekmede açılır. Bağlantı ve kısa metin önceden panoya kopyalanır.

Yorum yaz

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert