{
example:
Copy:
EmbeddedWB1.Copy;
NDClipboard.CopyNDDataToClipboard;
Cut:
EmbeddedWB1.Cut;
NDClipboard.CopyNDDataToClipboard;
Paste:
if NDClipboard.HasFormat(CF_NDCONTENT) then
begin
NDClipboard.CopyNDDataFromClipboard;//从剪贴板取出数据,并进行解壳操作
EmbeddedWB1.Paste;//粘贴到目标中去
NDClipboard.CopyNDDataToClipboard; //再将剪贴板里的数据重新加壳
end
else
EmbeddedWB1.Paste;
}
unit uNDClipboardClass ;
interface
uses
Windows , Messages , SysUtils , Variants , Classes , Graphics , Controls , Forms ,
Dialogs , StdCtrls , Clipbrd ;
const
NDClipboardFormatStr = 'CF_NDCONTENT' ;
type
TNDClipboard = class ( TClipboard )
public
procedure SetNdData ;
procedure GetNdData ;
procedure CopyNDDataToClipboard ;
procedure CopyNDDataFromClipboard ;
procedure SaveClipDataToStream ( var AMem : TMemoryStream );
procedure LoadClipDataFromStream ( var AMem : TMemoryStream );
end ;
TDataIdnet = array [ 0..2 ] of Char ;
TClipboardFileHead = packed record
rIdent : TDataIdnet ;
rCount : Word ;
end ;
TClipboardFileItem = packed record
rFormat : Word ;
rSize : Longword ;
rData : Pointer ;
end ;
const rDataIdnet : TDataIdnet = 'cbf' ;
var
CF_NDCONTENT : Word ;
function NDClipboard : TNDClipboard ;
function ClipboardSaveToStream ( mStream : TStream ): Boolean ;
function ClipboardLoadFromStream ( mStream : TStream ): Boolean ;
procedure CopyStreamToClipboard ( fmt : Cardinal ; S : TStream );
procedure CopyStreamFromClipboard ( fmt : Cardinal ; S : TStream );
procedure SaveClipboardFormat ( fmt : Word ; writer : TWriter );
procedure LoadClipboardFormat ( reader : TReader );
procedure SaveClipboard ( S : TStream );
procedure LoadClipboard ( S : TStream );
implementation
function ClipboardSaveToStream ( mStream : TStream ): Boolean ;
var
vClipboardFileHead : TClipboardFileHead ;
vClipboardFileItem : TClipboardFileItem ;
I : Integer ;
vData : THandle ;
begin
Result := False ;
if not Assigned ( mStream ) then Exit ;
vClipboardFileHead . rIdent := rDataIdnet ;
vClipboardFileHead . rCount := Clipboard . FormatCount ;
mStream . Write ( vClipboardFileHead , SizeOf ( vClipboardFileHead ));
try
Clipboard . Open ;
for I := 0 to Clipboard . FormatCount - 1 do begin
vData := GetClipboardData ( Clipboard . Formats [ I ]);
vClipboardFileItem . rFormat := Clipboard . Formats [ I ];
vClipboardFileItem . rSize := GlobalSize ( vData );
vClipboardFileItem . rData := GlobalLock ( vData );
try
mStream . Write ( vClipboardFileItem , SizeOf ( vClipboardFileItem ) -
SizeOf ( vClipboardFileItem . rData ));
mStream . Write ( vClipboardFileItem . rData ^, vClipboardFileItem . rSize );
finally
GlobalUnlock ( vData );
end ;
end ;
finally
Clipboard . Close ;
end ;
Result := True ;
end ; { ClipboardSaveToStream }
procedure CopyStreamToClipboard ( fmt : Cardinal ; S : TStream );
var
hMem : THandle ;
pMem : Pointer ;
begin
Assert ( Assigned ( S ));
S . Position := 0 ;
hMem := GlobalAlloc ( GHND or GMEM_DDESHARE , S . Size );
if hMem <> 0 then
begin
pMem := GlobalLock ( hMem );
if pMem <> nil then
begin
try
S . Read ( pMem ^, S . Size );
S . Position := 0 ;
finally
GlobalUnlock ( hMem );
end ;
Clipboard . Open ;
try
Clipboard . SetAsHandle ( fmt , hMem );
finally
Clipboard . Close ;
end ;
end { If }
else
begin
GlobalFree ( hMem );
OutOfMemoryError ;
end ;
end { If }
else
OutOfMemoryError ;
end ; { CopyStreamToClipboard }
procedure CopyStreamFromClipboard ( fmt : Cardinal ; S : TStream );
var
hMem : THandle ;
pMem : Pointer ;
begin
Assert ( Assigned ( S ));
hMem := Clipboard . GetAsHandle ( fmt );
if hMem <> 0 then
begin
pMem := GlobalLock ( hMem );
if pMem <> nil then
begin
try
S . Write ( pMem ^, GlobalSize ( hMem ));
S . Position := 0 ;
finally
GlobalUnlock ( hMem );
end ;
end { If }
else
raise Exception . Create ( 'CopyStreamFromClipboard: could not lock global handle ' +
'obtained from clipboard!' );
end ; { If }
end ; { CopyStreamFromClipboard }
procedure SaveClipboardFormat ( fmt : Word ; writer : TWriter );
var
fmtname : array [ 0..128 ] of Char ;
ms : TMemoryStream ;
begin
Assert ( Assigned ( writer ));
if 0 = GetClipboardFormatName ( fmt , fmtname , SizeOf ( fmtname )) then
fmtname [ 0 ] := #0 ;
ms := TMemoryStream . Create ;
try
CopyStreamFromClipboard ( fmt , ms );
if ms . Size > 0 then
begin
writer . WriteInteger ( fmt );
writer . WriteString ( fmtname );
writer . WriteInteger ( ms . Size );
writer . Write ( ms . Memory ^, ms . Size );
end ; { If }
finally
ms . Free
end ; { Finally }
end ; { SaveClipboardFormat }
procedure LoadClipboardFormat ( reader : TReader );
var
fmt : Integer ;
fmtname : string ;
Size : Integer ;
ms : TMemoryStream ;
begin
Assert ( Assigned ( reader ));
fmt := reader . ReadInteger ;
fmtname := reader . ReadString ;
Size := reader . ReadInteger ;
ms := TMemoryStream . Create ;
try
ms . Size := Size ;
reader . Read ( ms . memory ^, Size );
if Length ( fmtname ) > 0 then
fmt := RegisterCLipboardFormat ( PChar ( fmtname ));
if fmt <> 0 then
CopyStreamToClipboard ( fmt , ms );
finally
ms . Free ;
end ; { Finally }
end ; { LoadClipboardFormat }
procedure SaveClipboard ( S : TStream );
var
writer : TWriter ;
i : Integer ;
begin
Assert ( Assigned ( S ));
writer := TWriter . Create ( S , 4096 );
try
Clipboard . Open ;
try
writer . WriteListBegin ;
for i := 0 to Clipboard . formatcount - 1 do
SaveClipboardFormat ( Clipboard . Formats [ i ], writer );
writer . WriteListEnd ;
finally
Clipboard . Close ;
end ; { Finally }
finally
writer . Free
end ; { Finally }
end ; { SaveClipboard }
procedure LoadClipboard ( S : TStream );
var
reader : TReader ;
begin
Assert ( Assigned ( S ));
reader := TReader . Create ( S , 4096 );
try
Clipboard . Open ;
try
clipboard . Clear ;
reader . ReadListBegin ;
while not reader . EndOfList do
LoadClipboardFormat ( reader );
reader . ReadListEnd ;
finally
Clipboard . Close ;
end ; { Finally }
finally
reader . Free
end ; { Finally }
end ; { LoadClipboard }
function ClipboardLoadFromStream ( mStream : TStream ): Boolean ;
var
vClipboardFileHead : TClipboardFileHead ;
vClipboardFileItem : TClipboardFileItem ;
I : Integer ;
vData : THandle ;
begin
Result := False ;
if not Assigned ( mStream ) then Exit ;
if mStream . Size <= SizeOf ( vClipboardFileHead ) then Exit ;
mStream . Read ( vClipboardFileHead , SizeOf ( vClipboardFileHead ));
if vClipboardFileHead . rIdent <> rDataIdnet then Exit ;
Clipboard . Clear ;
Clipboard . Open ;
try
for I := 0 to vClipboardFileHead . rCount - 1 do begin
mStream . Read ( vClipboardFileItem , SizeOf ( vClipboardFileItem ) -
SizeOf ( vClipboardFileItem . rData ));
vData := GlobalAlloc ( GMEM_MOVEABLE + GMEM_DDESHARE ,
vClipboardFileItem . rSize );
try
vClipboardFileItem . rData := GlobalLock ( vData );
try
mStream . Read ( vClipboardFileItem . rData ^, vClipboardFileItem . rSize );
SetClipboardData ( vClipboardFileItem . rFormat , vData );
finally
GlobalUnlock ( vData );
end ;
finally
GlobalFree ( vData );
end ;
end ;
finally
Clipboard . Close ;
end ;
Result := True ;
end ; { ClipboardLoadFromStream }
procedure TNDClipboard . SetNdData ;
var
Data : THandle ;
DataPtr : Pointer ;
MemStream : TMemoryStream ;
begin
Open ;
try
Data := NDclipboard . Handle ;
if Data = 0 then Exit ;
DataPtr := GlobalLock ( Data );
if DataPtr = nil then Exit ;
try
MemStream := TMemoryStream . Create ;
try
MemStream . WriteBuffer ( DataPtr ^, GlobalSize ( Data ));
MemStream . Position := 0 ;
SetBuffer ( CF_NDCONTENT , MemStream . Memory ^, MemStream . Size );
finally
MemStream . Free ;
end ;
finally
GlobalUnlock ( Data );
end ;
finally
Close ;
end ;
end ;
procedure TNDClipboard . GetNdData ;
var
Data : THandle ;
DataPtr : Pointer ;
MemStream : TMemoryStream ;
begin
Open ;
try
Data := GetClipboardData ( CF_NDCONTENT );
if Data = 0 then Exit ;
DataPtr := GlobalLock ( Data );
if DataPtr = nil then Exit ;
try
MemStream := TMemoryStream . Create ;
try
MemStream . WriteBuffer ( DataPtr ^, GlobalSize ( Data ));
MemStream . Position := 0 ;
finally
MemStream . Free ;
end ;
finally
GlobalUnlock ( Data );
end ;
finally
Close ;
end ;
end ;
var
FNDClipboard : TNDClipboard ;
function NDClipboard : TNDClipboard ;
begin
if FNDClipboard = nil then
FNDClipboard := TNDClipboard . Create ;
Result := FNDClipboard ;
end ;
procedure TNDClipboard . CopyNDDataFromClipboard ;
var
hbuf : THandle ;
bufptr : Pointer ;
mstream : TMemoryStream ;
begin
hbuf := Clipboard . GetAsHandle ( CF_NDCONTENT );
if hbuf <> 0 then begin
bufptr := GlobalLock ( hbuf );
if bufptr <> nil then begin
try
mstream := TMemoryStream . Create ;
try
mstream . WriteBuffer ( bufptr ^, GlobalSize ( hbuf ));
mstream . Position := 0 ;
//-- 处理流的代码 --
//ClipboardLoadFromStream(mstream)
//LoadClipDataFromStream(mstream);
LoadClipboard ( mstream );
finally
mstream . Free ;
end ;
finally
GlobalUnlock ( hbuf );
end ;
end ;
end ;
end ;
procedure TNDClipboard . CopyNDDataToClipboard ;
var
hbuf : THandle ;
bufptr : Pointer ;
mstream : TMemoryStream ;
begin
mstream := TMemoryStream . Create ;
try
//-- 处理流的代码 --
//ClipboardSaveToStream(mstream);
//SaveClipDataToStream(mstream);
SaveClipboard ( mstream );
//mstream.SaveToFile('test');
hbuf := GlobalAlloc ( GMEM_MOVEABLE , mstream . size );
try
bufptr := GlobalLock ( hbuf );
try
Move ( mstream . Memory ^, bufptr ^, mstream . size );
Clipboard . SetAsHandle ( CF_NDCONTENT , hbuf );
finally
GlobalUnlock ( hbuf );
end ;
except
GlobalFree ( hbuf );
raise ;
end ;
finally
mstream . Free ;
end ;
end ;
procedure TNDClipboard . LoadClipDataFromStream ( var AMem : TMemoryStream );
var
MemStream , DataStream : TMemoryStream ;
i , FormatListLen , DataStreamLen : Integer ;
tmpStrings : TStringList ;
begin
DataStream := TMemoryStream . Create ;
tmpStrings := TStringList . Create ;
try
clipbrd . Clipboard . Open ;
Clipboard . Clear ;
AMem . Position := 0 ;
AMem . ReadBuffer ( FormatListLen , SizeOf ( Integer ));
AMem . ReadBuffer ( DataStreamLen , SizeOf ( Integer ));
DataStream . CopyFrom ( AMem , FormatListLen );
DataStream . position := 0 ;
tmpStrings . LoadFromStream ( DataStream );
DataStream . Clear ;
DataStream . CopyFrom ( AMem , DataStreamLen );
DataStream . position := 0 ;
if DataStream . Size <> 0 then DataStream . Position := 0 ;
for i := 0 to tmpStrings . Count - 1 do
begin
FormatListLen := StrToInt ( tmpStrings . Names [ i ]);
DataStreamLen := StrToInt ( tmpStrings . Values [ tmpStrings . Names [ i ]]);
MemStream := TMemoryStream . Create ;
try
MemStream . CopyFrom ( DataStream , DataStreamLen );
MemStream . Position := 0 ;
SetBuffer ( FormatListLen , MemStream . Memory ^, DataStreamLen );
finally
MemStream . Free ;
end ;
end ;
finally
clipbrd . Clipboard . Close ;
tmpStrings . Free ;
DataStream . Free ;
end ;
end ;
procedure TNDClipboard . SaveClipDataToStream ( var AMem : TMemoryStream );
var
Data : THandle ;
DataPtr : Pointer ;
MemStream , DataStream : TMemoryStream ;
i , tmpInt : Integer ;
tmpStrings : TStringList ;
begin
DataStream := TMemoryStream . Create ;
tmpStrings := TStringList . Create ;
try
clipbrd . Clipboard . Open ;
for i := 0 to Clipboard . FormatCount - 1 do
begin
Data := GetClipboardData ( Clipboard . Formats [ i ]);
if Data = 0 then Continue ;
DataPtr := GlobalLock ( Data );
try
if DataPtr = nil then Continue ;
MemStream := TMemoryStream . Create ;
try
tmpInt := GlobalSize ( Data );
if tmpInt = 0 then
beep ;
MemStream . WriteBuffer ( DataPtr ^, GlobalSize ( Data ));
MemStream . Position := 0 ;
tmpStrings . Add ( IntToStr ( Clipboard . Formats [ i ]) + '=' + IntToStr ( GlobalSize ( Data )));
DataStream . WriteBuffer ( MemStream . Memory ^, MemStream . Size );
finally
MemStream . Free ;
end ;
finally
GlobalUnlock ( Data );
end ;
end ;
if tmpStrings . Count <> 0 then
begin
AMem . Clear ;
tmpInt := Length ( tmpStrings . Text );
AMem . WriteBuffer ( tmpInt , SizeOf ( Integer ));
tmpInt := DataStream . size ;
AMem . WriteBuffer ( tmpInt , Sizeof ( Integer ));
MemStream := TMemoryStream . Create ;
try
tmpStrings . SaveToStream ( MemStream );
AMem . WriteBuffer ( MemStream . Memory ^, MemStream . Size );
finally
MemStream . Free ;
end ;
AMem . WriteBuffer ( DataStream . Memory ^, DataStream . Size );
end ;
finally
clipbrd . Clipboard . Close ;
tmpStrings . Free ;
DataStream . Free ;
end ;
end ;
initialization
CF_NDCONTENT := RegisterClipboardFormat ( NDClipboardFormatStr );
FNDClipboard := nil ;
finalization
FNDClipboard . Free ;
end .