zoukankan      html  css  js  c++  java
  • copy unicode HTML to clipboard

    How to copy unicode HTML code to the clipboard in html format, so it can be pasted into Writer, Word etc.

    Several articles show working code to copy an html structure to the clipboard registering as HTML Format (so it can be pasted in a word processor - rendered - instead of pasting the html code).

    This is my small contribution, just changing slightly the works you find in references, to also support fully unicode text, i.e. cyrillic copy and paste.


    procedure TPHTML.CopyHTMLToClipBoardUnicode(const str, htmlStr: string);

    /// Attempting to get real unicode to work.
    /// Альма матер, альма матер, легкая лаDдья.

    /// Works fine with Delphi 2010+ and accepts unicode text. But if you try to copy Unicode
    /// characters which do not have an ASCII representation, they will not be copied.

    /// Riccardo Zorn www.tmg.it
    ///

    //The second parameter is optional and is put into the clipboard as CF_HTML.
    //Function can be used standalone or in conjunction with the VCL clipboard so long as
    //you use the USEVCLCLIPBOARD conditional define
    //($define USEVCLCLIPBOARD}
    //(and clipboard.open, clipboard.close).
    //Code from http://www.lorriman.com
    // http://it.w3support.net/index.php?db=so&id=1114883


    // If you've ever tried sticking html into the clipboard using the usual CF_TEXT
    // format then you might have been disappointed to discover that wysiwyg html
    // editors paste your offering as if it were just text,
    // rather than recognising it as html. For that you need the CF_HTML format.
    // CF_HTML is entirely text format and uses the transformation format UTF-8.
    // It includes a description, a context, and within the context, the fragment.
    //
    // As you may know one can place multiple items of data onto the clipboard for
    // a single clipboard entry, which means that the same data can be pasted in a
    // variety of different formats in order to cope with target
    // applications of varying sophistocation.
    //
    // The following example shows how to stick CF_TEXT (and CF_HTML)
    // into the clipboard.

    //The second parameter is optional and is put into the clipboard as CF_HTML.
    //Function can be used standalone or in conjunction with the VCL clipboard so long as
    //you use the USEVCLCLIPBOARD conditional define
    //($define USEVCLCLIPBOARD}
    //(and clipboard.open, clipboard.close).
    //Code from http://www.lorriman.com

    function FormatHTMLClipboardHeader(HTMLText: string): string;
    const
    CrLf = #13#10;
    begin
    Result := 'Version:0.9' + CrLf;
    Result := Result + 'StartHTML:-1' + CrLf;
    Result := Result + 'EndHTML:-1' + CrLf;

    Result := Result + 'StartFragment:^^^^^^' + CrLf;
    Result := Result + 'EndFragment:°°°°°°' + CrLf;

    Result := StringReplace(Result, '^^^^^^', Format('%.6d', [Length(Result)*SizeOf(Char)]), []);

    Result := Result + HTMLText + CrLf;
    Result := StringReplace(Result, '°°°°°°', Format('%.6d', [Length(Result)*SizeOf(Char)]), []);
    end;


    var
    gMem: HGLOBAL;
    lp: PChar;
    Strings: array[0..1] of UTF8String;
    Formats: array[0..1] of UINT;
    i: Integer;
    begin
    gMem := 0;
    {$IFNDEF USEVCLCLIPBOARD}
    Win32Check(OpenClipBoard(0));
    {$ENDIF}
    try
    //most descriptive first as per api docs
    Strings[0] := FormatHTMLClipboardHeader(htmlStr);
    Strings[1] := str;
    Formats[0] := RegisterClipboardFormat('HTML Format');
    Formats[1] := CF_UNICODETEXT;
    {$IFNDEF USEVCLCLIPBOARD}
    Win32Check(EmptyClipBoard);
    {$ENDIF}
    for i := 0 to High(Strings) do
    begin
    if Strings[i] = '' then Continue;
    //an extra "1" for the null terminator
    gMem := GlobalAlloc(GMEM_DDESHARE + GMEM_MOVEABLE, (Length(Strings[i])+1)*sizeOf(Char));
    {Succeeded, now read the stream contents into the memory the pointer points at}
    try
    Win32Check(gmem <> 0);
    lp := GlobalLock(gMem);
    Win32Check(lp <> nil);
    CopyMemory(lp, PChar(Strings[i]), (Length(Strings[i])+1)*sizeOf(Char));
    finally
    GlobalUnlock(gMem);
    end;
    Win32Check(gmem <> 0);
    SetClipboardData(Formats[i], gMem);
    Win32Check(gmem <> 0);
    gmem := 0;
    end;
    finally
    {$IFNDEF USEVCLCLIPBOARD}
    Win32Check(CloseClipBoard);
    {$ENDIF}
    end;
    end;

    References:

    Torry, working version in non-unicode Delphis

    http://www.swissdelphicenter.ch/torry/showcode.php?id=1391

    StackOverflow, working version in D2009 with no unicode support

    http://stackoverflow.com/questions/1114883/how-do-i-put-some-formatted-text-into-the-clipboard

    Using the clipboard (MSDN)

    http://msdn.microsoft.com/en-us/library/ms649016%28v=VS.85%29.aspx#_win32_Registering_a_Clipboard_Format

    CF_HTML

    http://msdn.microsoft.com/en-us/library/aa767917%28v=vs.85%29.aspx

    Delphi Unicode migration tips

    http://edn.embarcadero.com/article/38693

  • 相关阅读:
    iOS (封装)一句话调用系统的alertView和alertController
    仿写从iOS8开始支持的UIAlertController:BGAAlertController-Android
    iOS开发之UIAlertController的适配
    使用dispatch_once实现单例
    关于内存警告
    Android之drawable state各个属性具体解释
    vijos 1115 火星人
    X-UA-Compatible IE 浏览器默认文档模式设置
    POJ--1300--Door Man【推断无向图欧拉通路】
    sharepoint 2013 附件控件FileUpload怎样检验是否为图片的方法
  • 原文地址:https://www.cnblogs.com/MaxWoods/p/3916588.html
Copyright © 2011-2022 走看看