0,0 → 1,988 |
unit DragDropGraphics; |
|
// ----------------------------------------------------------------------------- |
// Project: Drag and Drop Component Suite. |
// Module: DragDropGraphics |
// Description: Implements Dragging and Dropping of graphic data. |
// Version: 4.0 |
// Date: 18-MAY-2001 |
// Target: Win32, Delphi 5-6 |
// Authors: Anders Melander, anders@melander.dk, http://www.melander.dk |
// Copyright © 1997-2001 Angus Johnson & Anders Melander |
// ----------------------------------------------------------------------------- |
|
interface |
|
uses |
DragDrop, |
DropTarget, |
DropSource, |
ActiveX, |
Windows, |
Graphics, |
Classes; |
|
{$include DragDrop.inc} |
|
type |
//////////////////////////////////////////////////////////////////////////////// |
// |
// TGDIClipboardFormat |
// |
//////////////////////////////////////////////////////////////////////////////// |
// Base class for GDI clipboard formats (TYMED_GDI). |
//////////////////////////////////////////////////////////////////////////////// |
TGDIClipboardFormat = class(TClipboardFormat) |
public |
constructor Create; override; |
end; |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TPaletteClipboardFormat |
// |
//////////////////////////////////////////////////////////////////////////////// |
// Only used internally by TBitmapClipboardFormat - Not registered |
//////////////////////////////////////////////////////////////////////////////// |
TPaletteClipboardFormat = class(TGDIClipboardFormat) |
private |
FPalette : hPalette; |
public |
function GetClipboardFormat: TClipFormat; override; |
function DoGetData(ADataObject: IDataObject; const AMedium: TStgMedium): boolean; override; |
function DoSetData(const FormatEtcIn: TFormatEtc; |
var Medium: TStgMedium): boolean; override; |
procedure Clear; override; |
property Palette: hPalette read FPalette write FPalette; |
end; |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TCustomBitmapClipboardFormat |
// |
//////////////////////////////////////////////////////////////////////////////// |
TCustomBitmapClipboardFormat = class(TGDIClipboardFormat) |
private |
FBitmap : TBitmap; |
protected |
constructor CreateFormat(Atymed: Longint); override; |
public |
destructor Destroy; override; |
procedure Clear; override; |
property Bitmap: TBitmap read FBitmap; |
end; |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TBitmapClipboardFormat |
// |
//////////////////////////////////////////////////////////////////////////////// |
TBitmapClipboardFormat = class(TCustomBitmapClipboardFormat) |
protected |
function DoGetData(ADataObject: IDataObject; const AMedium: TStgMedium): boolean; override; |
function DoSetData(const FormatEtcIn: TFormatEtc; |
var AMedium: TStgMedium): boolean; override; |
public |
function GetClipboardFormat: TClipFormat; override; |
end; |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TDIBClipboardFormat |
// |
//////////////////////////////////////////////////////////////////////////////// |
TDIBClipboardFormat = class(TCustomBitmapClipboardFormat) |
private |
protected |
function DoGetData(ADataObject: IDataObject; const AMedium: TStgMedium): boolean; override; |
function DoSetData(const FormatEtcIn: TFormatEtc; |
var AMedium: TStgMedium): boolean; override; |
public |
constructor Create; override; |
function GetClipboardFormat: TClipFormat; override; |
end; |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TCustomMetaFileClipboardFormat |
// |
//////////////////////////////////////////////////////////////////////////////// |
TCustomMetaFileClipboardFormat = class(TClipboardFormat) |
private |
FMetaFile : TMetaFile; |
protected |
public |
constructor Create; override; |
destructor Destroy; override; |
procedure Clear; override; |
property MetaFile: TMetaFile read FMetaFile; |
end; |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TMetaFileClipboardFormat |
// |
//////////////////////////////////////////////////////////////////////////////// |
TMetaFileClipboardFormat = class(TCustomMetaFileClipboardFormat) |
private |
protected |
function DoGetData(ADataObject: IDataObject; const AMedium: TStgMedium): boolean; override; |
public |
function GetClipboardFormat: TClipFormat; override; |
end; |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TEnhMetaFileClipboardFormat |
// |
//////////////////////////////////////////////////////////////////////////////// |
TEnhMetaFileClipboardFormat = class(TCustomMetaFileClipboardFormat) |
private |
protected |
function DoGetData(ADataObject: IDataObject; const AMedium: TStgMedium): boolean; override; |
public |
function GetClipboardFormat: TClipFormat; override; |
end; |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TBitmapDataFormat |
// |
//////////////////////////////////////////////////////////////////////////////// |
TBitmapDataFormat = class(TCustomDataFormat) |
private |
FBitmap : TBitmap; |
protected |
public |
constructor Create(AOwner: TDragDropComponent); override; |
destructor Destroy; override; |
function Assign(Source: TClipboardFormat): boolean; override; |
function AssignTo(Dest: TClipboardFormat): boolean; override; |
procedure Clear; override; |
function HasData: boolean; override; |
function NeedsData: boolean; override; |
property Bitmap: TBitmap read FBitmap; |
end; |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TMetaFileDataFormat |
// |
//////////////////////////////////////////////////////////////////////////////// |
TMetaFileDataFormat = class(TCustomDataFormat) |
private |
FMetaFile : TMetaFile; |
protected |
public |
constructor Create(AOwner: TDragDropComponent); override; |
destructor Destroy; override; |
function Assign(Source: TClipboardFormat): boolean; override; |
procedure Clear; override; |
function HasData: boolean; override; |
function NeedsData: boolean; override; |
property MetaFile: TMetaFile read FMetaFile; |
end; |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TDropBMPTarget |
// |
//////////////////////////////////////////////////////////////////////////////// |
TDropBMPTarget = class(TCustomDropMultiTarget) |
private |
FBitmapFormat : TBitmapDataFormat; |
protected |
function GetBitmap: TBitmap; |
public |
constructor Create(AOwner: TComponent); override; |
destructor Destroy; override; |
property Bitmap: TBitmap read GetBitmap; |
end; |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TDropBMPSource |
// |
//////////////////////////////////////////////////////////////////////////////// |
TDropBMPSource = class(TCustomDropMultiSource) |
private |
FBitmapFormat : TBitmapDataFormat; |
protected |
procedure SetBitmap(const Value: TBitmap); |
function GetBitmap: TBitmap; |
public |
constructor Create(AOwner: TComponent); override; |
destructor Destroy; override; |
published |
property Bitmap: TBitmap read GetBitmap write SetBitmap; |
end; |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TDropMetaFileTarget |
// |
//////////////////////////////////////////////////////////////////////////////// |
TDropMetaFileTarget = class(TCustomDropMultiTarget) |
private |
FMetaFileFormat : TMetaFileDataFormat; |
protected |
function GetMetaFile: TMetaFile; |
public |
constructor Create(AOwner: TComponent); override; |
destructor Destroy; override; |
property MetaFile: TMetaFile read GetMetaFile; |
end; |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TDropImageTarget |
// |
//////////////////////////////////////////////////////////////////////////////// |
TDropImageTarget = class(TCustomDropMultiTarget) |
private |
FMetaFileFormat : TMetaFileDataFormat; |
FBitmapFormat : TBitmapDataFormat; |
FPicture : TPicture; |
protected |
function DoGetData: boolean; override; |
procedure ClearData; override; |
public |
constructor Create(AOwner: TComponent); override; |
destructor Destroy; override; |
property Picture: TPicture read FPicture; |
end; |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// Component registration |
// |
//////////////////////////////////////////////////////////////////////////////// |
procedure Register; |
|
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// Misc. |
// |
//////////////////////////////////////////////////////////////////////////////// |
procedure CopyDIBToBitmap(Bitmap: TBitmap; BitmapInfo: PBitmapInfo; DIBSize: integer); |
function GetHGlobalDIBFromBitmap(Bitmap: TBitmap): HGlobal; |
|
|
//////////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
// |
// IMPLEMENTATION |
// |
//////////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
implementation |
|
uses |
SysUtils; |
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// Component registration |
// |
//////////////////////////////////////////////////////////////////////////////// |
procedure Register; |
begin |
RegisterComponents(DragDropComponentPalettePage, [TDropBMPTarget, |
TDropBMPSource, TDropMetaFileTarget, TDropImageTarget]); |
end; |
|
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// Misc. |
// |
//////////////////////////////////////////////////////////////////////////////// |
procedure CopyDIBToBitmap(Bitmap: TBitmap; BitmapInfo: PBitmapInfo; DIBSize: integer); |
var |
BitmapFileHeader : TBitmapFileHeader; |
FileSize : integer; |
InfoSize : integer; |
Stream : TMemoryStream; |
begin |
// Write DIB to a stream in the BMP file format |
Stream := TMemoryStream.Create; |
try |
FileSize := sizeof(TBitmapFileHeader) + DIBSize; |
InfoSize := sizeof(TBitmapInfoHeader); |
if (BitmapInfo^.bmiHeader.biBitCount > 8) then |
begin |
if ((BitmapInfo^.bmiHeader.biCompression and BI_BITFIELDS) <> 0) then |
Inc(InfoSize, 12); |
end else |
Inc(InfoSize, sizeof(TRGBQuad) * (1 shl BitmapInfo^.bmiHeader.biBitCount)); |
Stream.SetSize(FileSize); |
// Initialize file header |
FillChar(BitmapFileHeader, sizeof(TBitmapFileHeader), 0); |
with BitmapFileHeader do |
begin |
bfType := $4D42; // 'BM' = Windows BMP signature |
bfSize := FileSize; // File size (not needed) |
bfOffBits := sizeof(TBitmapFileHeader) + InfoSize; // Offset of pixel data |
end; |
// Save file header |
Stream.Write(BitmapFileHeader, sizeof(TBitmapFileHeader)); |
// Save TBitmapInfo structure and pixel data |
Stream.Write(BitmapInfo^, DIBSize); |
|
// Rewind and load bitmap from stream |
Stream.Position := 0; |
Bitmap.LoadFromStream(Stream); |
finally |
Stream.Free; |
end; |
end; |
|
function GetHGlobalDIBFromBitmap(Bitmap: TBitmap): HGlobal; |
var |
Stream : TMemoryStream; |
DIB : pointer; |
DIBSize : integer; |
begin |
Stream := TMemoryStream.Create; |
try |
// Write bitmap to a stream and extract the DIB data from it. |
Bitmap.SaveToStream(Stream); |
|
// Calculate size of DIB block. |
DIBSize := Stream.Size - SizeOf(TBitmapFileHeader); |
|
// Allocate memory for DIB data. |
Result := GlobalAlloc(GMEM_MOVEABLE or GMEM_SHARE, DIBSize); |
if (Result = 0) then |
exit; |
|
DIB := GlobalLock(Result); |
if DIB = nil then |
begin |
GlobalFree(Result); |
Result := 0; |
end else |
begin |
// Skip BMP file header. |
Stream.Seek(SizeOf(TBitmapFileHeader), soFromBeginning); |
// Transfer data from stream to global memory. |
if (Stream.Read(DIB^, DIBSize) <> DIBSize) then |
begin |
GlobalUnlock(Result); |
GlobalFree(Result); |
Result := 0; |
end else |
GlobalUnlock(Result); |
end; |
finally |
Stream.free; |
end; |
end; |
|
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TGDIClipboardFormat |
// |
//////////////////////////////////////////////////////////////////////////////// |
constructor TGDIClipboardFormat.Create; |
begin |
CreateFormat(TYMED_GDI); |
end; |
|
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TPaletteClipboardFormat |
// |
//////////////////////////////////////////////////////////////////////////////// |
function TPaletteClipboardFormat.GetClipboardFormat: TClipFormat; |
begin |
Result := CF_PALETTE; |
end; |
|
procedure TPaletteClipboardFormat.Clear; |
begin |
if (FPalette <> 0) then |
begin |
DeleteObject(FPalette); |
FPalette := 0; |
end; |
end; |
|
function TPaletteClipboardFormat.DoGetData(ADataObject: IDataObject; const AMedium: TStgMedium): boolean; |
begin |
if (AMedium.hBitmap <> 0) then |
begin |
FPalette := CopyPalette(AMedium.hBitmap); |
Result := (FPalette <> 0); |
end else |
Result := False; |
end; |
|
function TPaletteClipboardFormat.DoSetData(const FormatEtcIn: TFormatEtc; |
var Medium: TStgMedium): boolean; |
begin |
Result := False; |
|
try |
Medium.hBitmap := CopyPalette(FPalette); |
except |
exit; |
end; |
|
if (Medium.hBitmap <> 0) then |
begin |
Medium.tymed := TYMED_GDI; |
result := True; |
end; |
end; |
|
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TBitmapClipboardFormat |
// |
//////////////////////////////////////////////////////////////////////////////// |
constructor TCustomBitmapClipboardFormat.CreateFormat(Atymed: Longint); |
begin |
inherited CreateFormat(Atymed); |
|
FBitmap := Graphics.TBitmap.Create; |
end; |
|
destructor TCustomBitmapClipboardFormat.Destroy; |
begin |
if (FBitmap <> nil) then |
FBitmap.Free; |
|
inherited Destroy; |
end; |
|
procedure TCustomBitmapClipboardFormat.Clear; |
begin |
FBitmap.Handle := 0; |
end; |
|
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TBitmapClipboardFormat |
// |
//////////////////////////////////////////////////////////////////////////////// |
function TBitmapClipboardFormat.GetClipboardFormat: TClipFormat; |
begin |
Result := CF_BITMAP; |
end; |
|
function TBitmapClipboardFormat.DoGetData(ADataObject: IDataObject; const AMedium: TStgMedium): boolean; |
var |
Palette : TPaletteClipboardFormat; |
begin |
Result := False; |
if (AMedium.hBitmap = 0) then |
exit; |
Palette := TPaletteClipboardFormat.Create; |
try |
// Attempt to get palette from source. However in case the bitmap is in a |
// format which doesn't use palettes, there might not be one available. |
// The CF_BITMAP/CF_PALETTE documentation doesn't mention if CF_BITMAP must |
// always be accompanied with a CF_PALETTE. |
Palette.GetData(ADataObject); |
// Let TBitmap do the work for us. |
FBitmap.LoadFromClipboardFormat(CF_BITMAP, AMedium.hBitmap, Palette.Palette); |
finally |
Palette.Free; |
end; |
Result := True; |
end; |
|
function TBitmapClipboardFormat.DoSetData(const FormatEtcIn: TFormatEtc; |
var AMedium: TStgMedium): boolean; |
var |
Palette : HPalette; |
Format : Word; |
hBitmap : THandle; |
begin |
Result := False; |
|
try |
Format := CF_BITMAP; |
FBitmap.SaveToClipboardFormat(Format, hBitmap, Palette); |
AMedium.hBitmap := hBitmap; |
except |
exit; |
end; |
|
try |
if (Format <> CF_BITMAP) then |
begin |
DeleteObject(AMedium.hBitmap); |
AMedium.hBitmap := 0; |
exit; |
end; |
AMedium.tymed := TYMED_GDI; |
finally |
DeleteObject(Palette); |
end; |
Result := True; |
end; |
|
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TDIBClipboardFormat |
// |
//////////////////////////////////////////////////////////////////////////////// |
constructor TDIBClipboardFormat.Create; |
begin |
// Note: We must override Create since base class Create sets tymed to |
// TYMED_GDI. |
CreateFormat(TYMED_HGLOBAL); |
end; |
|
function TDIBClipboardFormat.GetClipboardFormat: TClipFormat; |
begin |
Result := CF_DIB; |
end; |
|
// http://x5.dejanews.com/[ST_rn=ps]/getdoc.xp?AN=382056726.2&CONTEXT=925473183.2090336317&hitnum=0 |
function TDIBClipboardFormat.DoGetData(ADataObject: IDataObject; const AMedium: TStgMedium): boolean; |
var |
BitmapInfo : PBitmapInfo; |
BitmapFileHeader : TBitmapFileHeader; |
DIBSize : integer; |
FileSize : integer; |
InfoSize : integer; |
Stream : TMemoryStream; |
begin |
// Get data source's DIB block |
BitmapInfo := GlobalLock(AMedium.HGlobal); |
try |
Result := (BitmapInfo <> nil); |
if (not Result) then |
exit; |
|
// Write DIB to a stream in the BMP file format |
Stream := TMemoryStream.Create; |
try |
// Get size of data source's DIB block |
DIBSize := GlobalSize(AMedium.HGlobal); |
// Calculate total bitmap file size |
FileSize := sizeof(TBitmapFileHeader) + DIBSize; |
// Calculate bitmap header size |
InfoSize := sizeof(TBitmapInfoHeader); |
if (BitmapInfo^.bmiHeader.biBitCount > 8) then |
begin |
if ((BitmapInfo^.bmiHeader.biCompression and BI_BITFIELDS) <> 0) then |
Inc(InfoSize, 12); |
end else |
Inc(InfoSize, sizeof(TRGBQuad) * (1 shl BitmapInfo^.bmiHeader.biBitCount)); |
|
Stream.SetSize(FileSize); |
// Initialize file header |
FillChar(BitmapFileHeader, sizeof(TBitmapFileHeader), 0); |
with BitmapFileHeader do |
begin |
bfType := $4D42; // 'BM' = Windows BMP signature |
bfSize := FileSize; // File size (not needed) |
bfOffBits := sizeof(TBitmapFileHeader) + InfoSize; // Offset of pixel data |
end; |
// Save file header |
Stream.Write(BitmapFileHeader, sizeof(TBitmapFileHeader)); |
// Save TBitmapInfo structure and pixel data |
Stream.Write(BitmapInfo^, DIBSize); |
|
// Rewind and load bitmap from stream |
Stream.Position := 0; |
FBitmap.LoadFromStream(Stream); |
finally |
Stream.Free; |
end; |
finally |
GlobalUnlock(AMedium.HGlobal); |
end; |
end; |
|
function TDIBClipboardFormat.DoSetData(const FormatEtcIn: TFormatEtc; |
var AMedium: TStgMedium): boolean; |
begin |
AMedium.hBitmap := GetHGlobalDIBFromBitmap(FBitmap); |
Result := (AMedium.hBitmap <> 0); |
if (Result) then |
AMedium.tymed := TYMED_HGLOBAL; |
end; |
|
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TCustomMetaFileClipboardFormat |
// |
//////////////////////////////////////////////////////////////////////////////// |
constructor TCustomMetaFileClipboardFormat.Create; |
begin |
CreateFormat(TYMED_MFPICT); |
FMetaFile := TMetaFile.Create; |
end; |
|
destructor TCustomMetaFileClipboardFormat.Destroy; |
begin |
if (FMetaFile <> nil) then |
FMetaFile.Free; |
inherited Destroy; |
end; |
|
procedure TCustomMetaFileClipboardFormat.Clear; |
begin |
FMetaFile.Clear; |
end; |
|
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TMetaFileClipboardFormat |
// |
//////////////////////////////////////////////////////////////////////////////// |
function TMetaFileClipboardFormat.GetClipboardFormat: TClipFormat; |
begin |
Result := CF_METAFILEPICT; |
end; |
|
function WMF2EMF(const MetaFile: TMetaFilePict): hEnhMetaFile; |
var |
Bits : Pointer; |
Length : UINT; |
RefDC : HDC; |
begin |
Length := GetMetaFileBitsEx(MetaFile.hMF, 0, nil); |
if (Length = 0) then |
_RaiseLastWin32Error; |
GetMem(Bits, Length); |
try |
if (GetMetaFileBitsEx(MetaFile.hMF, Length, Bits) < Length) then |
_RaiseLastWin32Error; |
RefDC := GetDC(0); |
try |
Result := SetWinMetaFileBits(Length, Bits, RefDC, MetaFile); |
finally |
ReleaseDC(0, RefDC); |
end; |
if (Result = 0) then |
_RaiseLastWin32Error; |
finally |
FreeMem(Bits); |
end; |
end; |
|
function TMetaFileClipboardFormat.DoGetData(ADataObject: IDataObject; const AMedium: TStgMedium): boolean; |
var |
pMetaFile : PMetaFilePict; |
begin |
pMetaFile := GlobalLock(AMedium.hMetaFilePict); |
try |
Result := (pMetaFile <> nil); |
if (Result) then |
FMetaFile.Handle := WMF2EMF(pMetaFile^); |
finally |
GlobalUnlock(AMedium.hMetaFilePict); |
end; |
end; |
|
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TEnhMetaFileClipboardFormat |
// |
//////////////////////////////////////////////////////////////////////////////// |
function TEnhMetaFileClipboardFormat.GetClipboardFormat: TClipFormat; |
begin |
Result := CF_ENHMETAFILE; |
end; |
|
function TEnhMetaFileClipboardFormat.DoGetData(ADataObject: IDataObject; const AMedium: TStgMedium): boolean; |
begin |
Result := (AMedium.hEnhMetaFile <> 0); |
if (Result) then |
FMetaFile.Handle := CopyEnhMetafile(AMedium.hEnhMetaFile, nil); |
end; |
|
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TBitmapDataFormat |
// |
//////////////////////////////////////////////////////////////////////////////// |
constructor TBitmapDataFormat.Create(AOwner: TDragDropComponent); |
begin |
inherited Create(AOwner); |
FBitmap := TBitmap.Create; |
// TGraphic.OnChange is fired too late (after change), but it's the best |
// we can get. |
FBitmap.OnChange := DoOnChanging; |
end; |
|
destructor TBitmapDataFormat.Destroy; |
begin |
Clear; |
FBitmap.Free; |
inherited Destroy; |
end; |
|
function TBitmapDataFormat.Assign(Source: TClipboardFormat): boolean; |
begin |
Result := True; |
|
if (Source is TDIBClipboardFormat) then |
FBitmap.Assign(TDIBClipboardFormat(Source).Bitmap) |
|
else if (Source is TBitmapClipboardFormat) then |
FBitmap.Assign(TBitmapClipboardFormat(Source).Bitmap) |
|
// TODO -oanme : Is this nescessary? Palette is extracted in TBitmapClipboardFormat GetData. |
else if (Source is TPaletteClipboardFormat) then |
FBitmap.Palette := CopyPalette(TPaletteClipboardFormat(Source).Palette) |
|
else |
Result := inherited Assign(Source); |
end; |
|
function TBitmapDataFormat.AssignTo(Dest: TClipboardFormat): boolean; |
begin |
Result := True; |
|
if (Dest is TDIBClipboardFormat) then |
TDIBClipboardFormat(Dest).Bitmap.Assign(FBitmap) |
|
else if (Dest is TBitmapClipboardFormat) then |
TBitmapClipboardFormat(Dest).Bitmap.Assign(FBitmap) |
|
else if (Dest is TPaletteClipboardFormat) then |
TPaletteClipboardFormat(Dest).Palette := CopyPalette(FBitmap.Palette) |
|
else |
Result := inherited AssignTo(Dest); |
end; |
|
procedure TBitmapDataFormat.Clear; |
begin |
Changing; |
FBitmap.Handle := 0; |
end; |
|
function TBitmapDataFormat.HasData: boolean; |
begin |
Result := (not FBitmap.Empty); |
end; |
|
function TBitmapDataFormat.NeedsData: boolean; |
begin |
Result := (FBitmap.Empty); |
end; |
|
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TMetaFileDataFormat |
// |
//////////////////////////////////////////////////////////////////////////////// |
constructor TMetaFileDataFormat.Create(AOwner: TDragDropComponent); |
begin |
inherited Create(AOwner); |
FMetaFile := TMetaFile.Create; |
// TGraphic.OnChange is fired too late (after change), but it's the best |
// we can get. |
FMetaFile.OnChange := DoOnChanging; |
end; |
|
destructor TMetaFileDataFormat.Destroy; |
begin |
Clear; |
FMetaFile.Free; |
inherited Destroy; |
end; |
|
function TMetaFileDataFormat.Assign(Source: TClipboardFormat): boolean; |
begin |
Result := True; |
|
if (Source is TMetaFileClipboardFormat) then |
FMetaFile.Assign(TMetaFileClipboardFormat(Source).MetaFile) |
|
else if (Source is TEnhMetaFileClipboardFormat) then |
FMetaFile.Assign(TEnhMetaFileClipboardFormat(Source).MetaFile) |
|
else |
Result := inherited Assign(Source); |
end; |
|
procedure TMetaFileDataFormat.Clear; |
begin |
Changing; |
FMetaFile.Clear; |
end; |
|
function TMetaFileDataFormat.HasData: boolean; |
begin |
Result := (FMetaFile.Handle <> 0); |
end; |
|
function TMetaFileDataFormat.NeedsData: boolean; |
begin |
Result := (FMetaFile.Handle = 0); |
end; |
|
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TDropBMPTarget |
// |
//////////////////////////////////////////////////////////////////////////////// |
constructor TDropBMPTarget.Create(AOwner: TComponent); |
begin |
inherited Create(AOwner); |
FBitmapFormat := TBitmapDataFormat.Create(Self); |
end; |
|
destructor TDropBMPTarget.Destroy; |
begin |
FBitmapFormat.Free; |
inherited Destroy; |
end; |
|
function TDropBMPTarget.GetBitmap: TBitmap; |
begin |
Result := FBitmapFormat.Bitmap; |
end; |
|
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TDropBMPSource |
// |
//////////////////////////////////////////////////////////////////////////////// |
constructor TDropBMPSource.Create(AOwner: TComponent); |
begin |
inherited Create(AOwner); |
|
DragTypes := [dtCopy]; // Default to Copy |
|
FBitmapFormat := TBitmapDataFormat.Create(Self); |
end; |
|
destructor TDropBMPSource.destroy; |
begin |
FBitmapFormat.Free; |
inherited Destroy; |
end; |
|
function TDropBMPSource.GetBitmap: TBitmap; |
begin |
Result := FBitmapFormat.Bitmap; |
end; |
|
procedure TDropBMPSource.SetBitmap(const Value: TBitmap); |
begin |
FBitmapFormat.Bitmap.Assign(Value); |
end; |
|
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TDropMetaFileTarget |
// |
//////////////////////////////////////////////////////////////////////////////// |
constructor TDropMetaFileTarget.Create(AOwner: TComponent); |
begin |
inherited Create(AOwner); |
FMetaFileFormat := TMetaFileDataFormat.Create(Self); |
end; |
|
destructor TDropMetaFileTarget.Destroy; |
begin |
FMetaFileFormat.Free; |
inherited Destroy; |
end; |
|
function TDropMetaFileTarget.GetMetaFile: TMetaFile; |
begin |
Result := FMetaFileFormat.MetaFile; |
end; |
|
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// TDropMetaFileTarget |
// |
//////////////////////////////////////////////////////////////////////////////// |
constructor TDropImageTarget.Create(AOwner: TComponent); |
begin |
inherited Create(AOwner); |
FMetaFileFormat := TMetaFileDataFormat.Create(Self); |
FBitmapFormat := TBitmapDataFormat.Create(Self); |
FPicture := TPicture.Create; |
end; |
|
destructor TDropImageTarget.Destroy; |
begin |
FPicture.Free; |
FBitmapFormat.Free; |
FMetaFileFormat.Free; |
inherited Destroy; |
end; |
|
procedure TDropImageTarget.ClearData; |
begin |
inherited ClearData; |
FPicture.Assign(nil); |
end; |
|
function TDropImageTarget.DoGetData: boolean; |
begin |
Result := inherited DoGetData; |
if (Result) then |
begin |
if (FBitmapFormat.HasData) then |
FPicture.Assign(FBitmapFormat.Bitmap) |
else if (FMetaFileFormat.HasData) then |
FPicture.Assign(FMetaFileFormat.MetaFile) |
else |
Result := False; |
end; |
end; |
|
|
//////////////////////////////////////////////////////////////////////////////// |
// |
// Initialization/Finalization |
// |
//////////////////////////////////////////////////////////////////////////////// |
|
initialization |
// Data format registration |
TBitmapDataFormat.RegisterDataFormat; |
TMetaFileDataFormat.RegisterDataFormat; |
// Clipboard format registration |
TBitmapDataFormat.RegisterCompatibleFormat(TDIBClipboardFormat, 0, csSourceTarget, [ddRead]); |
TBitmapDataFormat.RegisterCompatibleFormat(TBitmapClipboardFormat, 1, csSourceTarget, [ddRead]); |
TBitmapDataFormat.RegisterCompatibleFormat(TPaletteClipboardFormat, 1, csSourceTarget, [ddRead]); |
TMetaFileDataFormat.RegisterCompatibleFormat(TEnhMetaFileClipboardFormat, 0, [csTarget], [ddRead]); |
TMetaFileDataFormat.RegisterCompatibleFormat(TMetaFileClipboardFormat, 1, [csTarget], [ddRead]); |
|
finalization |
// It is not nescessary to unregister *both* the TClipboardFormats and |
// the TTargetFormat, but we do it here to demo how the unregister |
// methods are used. |
|
// Clipboard format unregistration |
TDIBClipboardFormat.UnregisterClipboardFormat; |
TBitmapClipboardFormat.UnregisterClipboardFormat; |
TPaletteClipboardFormat.UnregisterClipboardFormat; |
TEnhMetaFileClipboardFormat.UnregisterClipboardFormat; |
TMetaFileClipboardFormat.UnregisterClipboardFormat; |
|
// Target format unregistration |
TBitmapDataFormat.UnregisterDataFormat; |
TMetaFileDataFormat.UnregisterDataFormat; |
end. |
|