// sClipFormat: array[TConvType] of string = ('HTML Format', 'Rich Text Format');
// TConvType = (ctHTML, ctRTF);
procedure
TfrmMain.AddToClip(const psFormatText, psText: string;
const ConvType: TConvType);
var
bIsAddToClip, bIsAddSourceCodeTextOfFormat: boolean;
begin
bIsAddToClip := mmConvAfterAddToClip.Checked;
//
是否加入剪贴板
bIsAddSourceCodeTextOfFormat := mmAddToClipTextIsSourceCode.Checked;
//
加到剪贴板文本格式是否源码
if not bIsAddToClip then
Exit;
if bIsAddSourceCodeTextOfFormat then
begin
if ConvType = ctHTML then
AddFormatToClipBoard(
GetHTMLClipFormat(psFormatText),
//
转换
HTML
源码为剪贴板格式
psFormatText,
//
剪贴板文本格式放
HTML
源码
sClipFormat[ConvType])
//
注册到剪贴板的格式
else
AddFormatToClipBoard(
psFormatText,
psFormatText,
sClipFormat[ConvType]);
end
else
begin
if ConvType = ctHTML then
AddFormatToClipBoard(
GetHTMLClipFormat(psFormatText),
//
转换
HTML
源码为剪贴板格式
psText,
//
剪贴板文本格式放未转换前源码
sClipFormat[ConvType])
//
注册到剪贴板的格式
else
AddFormatToClipBoard(
psFormatText,
psText,
sClipFormat[ConvType]);
end;
end
;
procedure
AddFormatToClipBoard(const psFormatText,psText,psFormat:string);
var
iFormatTextLen,iTextLen :integer;
uFormat :UINT;
hData: THandle;
pData: Pointer;
begin
// psFormat :
// Rich Text Format =
多信息文本格式到剪贴板
// HTML Format =
网页格式到剪贴板
iFormatTextLen := Length(psFormatText);
// StrLen
iTextLen := Length(psText);
Clipboard.Open;
try
EmptyClipboard;
// Add Format = psFormat
if iFormatTextLen >
0
then
begin
uFormat := RegisterClipboardFormat(PChar(psFormat));
hData := GlobalAlloc(GMEM_MOVEABLE + GMEM_DDESHARE, iFormatTextLen +
1
);
try
pData := GlobalLock(hData);
try
Move(PChar(psFormatText)^,pData^,iFormatTextLen +
1
);
SetClipboardData(uFormat,hData);
finally
GlobalUnlock(hData);
end;
except
GlobalFree(hData);
raise;
end;
end;
// Add Text Format = CF_TEXT
if iTextLen >
0
then
begin
hData := GlobalAlloc(GMEM_MOVEABLE + GMEM_DDESHARE, iTextLen +
1
);
try
pData := GlobalLock(hData);
try
Move(PChar(psText)^,pData^,iTextLen +
1
);
SetClipboardData(CF_TEXT,hData);
finally
GlobalUnlock(hData);
end;
except
GlobalFree(hData);
raise;
end;
end;
finally
Clipboard.Close;
end;
end
;
function
GetHTMLClipFormat(const psInput: string):string;
const
CRLF = System.sLineBreak;
sClipHead =
'Version:1.0'
+ CRLF +
// 1.0
版本
'StartHTML:%.10d'
+ CRLF +
//
从第一字符到
DocHand
前一字符数量
'EndHTML:%.10d'
+ CRLF +
//
整个内容数量
(
注:这里的数量最大
10
位数
)
'StartFragment:%.10d'
+ CRLF +
//
第一个字符到
<!--StartFragment-->
后
数量
'EndFragment:%.10d'
+ CRLF +
//
第一个字符到
<!--EndFragment-->
前
数量
'StartSelection:%.10d'
+ CRLF +
// =StartFragment
'EndSelection:%.10d'
+ CRLF +
// =EndFragment
'SourceURL:%s'
+ CRLF;
//
来源地址
http://xx.xx.xx/xxx.htm -- about:blank
sDocHead =
// html
文档中开始
--
假设原来还没有
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">'
+ CRLF;
sStartFragment =
'<!--StartFragment-->'
;
sEndFragment =
'<!--EndFragment-->'
;
var
iBodyPosStart ,iBodyPosEnd ,
iStartPos, iEndPos, iHeadLen,iUtf8Pos :Integer;
ssOutput :TStringStream;
sHeadStr,sUtf8Str :string;
p :PChar;
begin
//
把剪贴板源码转换为剪贴板格式
HTML Format
Result :=
''
;
if psInput =
''
then Exit;
// ToDo: Check Utf8 Format : Utf8Encode(psInput)
//
检查是否已经过
UTF-8
编码
,
防止重复编码
iUtf8Pos := Pos(
'charset= utf-8">'
,LowerCase(psInput));
if iUtf8Pos=
0
then
sUtf8Str := Utf8Encode(psInput)
else
sUtf8Str := psInput;
{
在
MSDN
中查找:
HTML Clipboard Format
内容是
UTF8
格式
HeadStr -> ClipHead
DocHead -> HTML First Row
<html> |
<head> |
<title></title> | -> HTMLHead
<mete .... |
</head> |
<body class="g1"> |
<!--StartFragment-->
<pre> |
<div .. | -> HTMLBody
</pre> |
<!--EndFragment-->
</body> | -> HTMLEnd
</html> |
}
ssOutput := TStringStream.Create(
''
);
try
sHeadStr := Format(sClipHead,[
0
,
0
,
0
,
0
,
0
,
0
,
'about:blank'
]);
//
先留位置
iHeadLen := Length(sHeadStr);
ssOutput.Write(sHeadStr[
1
],iHeadLen);
ssOutput.Write(sDocHead[
1
],Length(sDocHead));
//
确定
<body>...</body>
范围
iBodyPosEnd := Pos(
'</body>'
,LowerCase(sUtf8Str));
if iBodyPosEnd =-
1
then iBodyPosEnd := Length(sUtf8Str);
iBodyPosStart := Pos(
'<body'
,LowerCase(sUtf8Str));
Inc(iBodyPosStart,
4
);
while (iBodyPosStart< iBodyPosEnd) and (sUtf8Str[iBodyPosStart]<>
'>'
) do
Inc(iBodyPosStart);
Inc(iBodyPosStart);
//
写源码头
<html>...<body>
ssOutput.Write(sUtf8Str[
1
],iBodyPosStart);
iStartPos := ssOutput.Position;
//
写内容开始标识
ssOutput.Write(sStartFragment,Length(sStartFragment));
//
写源码内容
<body> ... </body>
之间数据
//msOutput.Write((Pointer(Integer(@sUtf8Str[1]) + iBodyPosStart))^,
// iBodyPosEnd - iBodyPosStart -1 );
ssOutput.Write(sUtf8Str[iBodyPosStart+
1
],
iBodyPosEnd - iBodyPosStart -
1
);
iEndPos := ssOutput.Position ;
//
写内容结束标识
ssOutput.Write(sEndFragment,Length(sEndFragment));
//
写源码结尾
</body>...</html>
//msOutput.Write((Pointer(Integer(@sUtf8Str[1]) + iBodyPosEnd -1)^),
// Length(sUtf8Str) - iBodyPosEnd+1);
ssOutput.Write(sUtf8Str[iBodyPosEnd],
Length(sUtf8Str) - iBodyPosEnd +
1
);
sHeadStr := Format(sClipHead,[iHeadLen,ssOutput.Size,iStartPos,iEndPos,
iStartPos,iEndPos,
'about:blank'
]);
p := PChar(sHeadStr);
CopyMemory(PChar(ssOutput.DataString),p,iHeadLen);
Result := ssOutput.DataString;
finally
ssOutput.Free;
end;
end
;