Subversion Repositories decoder

Rev

Blame | Last modification | View Log | RSS feed

  1. unit DropBMPSource;
  2.  
  3. // -----------------------------------------------------------------------------
  4. // Project:         Drag and Drop Component Suite
  5. // Component Names: TDropBMPSource
  6. // Module:          DropBMPSource
  7. // Description:     Implements Dragging & Dropping of Bitmaps
  8. //                  FROM your application to another.
  9. // Version:         3.7
  10. // Date:            22-JUL-1999
  11. // Target:          Win32, Delphi 3 - Delphi 5, C++ Builder 3, C++ Builder 4
  12. // Authors:         Angus Johnson,   ajohnson@rpi.net.au
  13. //                  Anders Melander, anders@melander.dk
  14. //                                   http://www.melander.dk
  15. // Copyright        © 1997-99 Angus Johnson & Anders Melander
  16. // -----------------------------------------------------------------------------
  17. // Acknowledgements:
  18. // Thanks to Dieter Steinwedel for some help with DIBs.
  19. // http://godard.oec.uni-osnabrueck.de/student_home/dsteinwe/delphi/DietersDelphiSite.htm
  20. // -----------------------------------------------------------------------------
  21.  
  22. interface
  23.  
  24. uses
  25.   DropSource,
  26.   Classes, Graphics, ActiveX;
  27.  
  28. {$include DragDrop.inc}
  29.  
  30. type
  31.   TDropBMPSource = class(TDropSource)
  32.   private
  33.     fBitmap: TBitmap;
  34.     procedure SetBitmap(Bmp: TBitmap);
  35.   protected
  36.     function DoGetData(const FormatEtcIn: TFormatEtc; OUT Medium: TStgMedium):HRESULT; Override;
  37.   public
  38.     constructor Create(aOwner: TComponent); Override;
  39.     destructor Destroy; Override;
  40.     function CutOrCopyToClipboard: boolean; Override;
  41.   published
  42.     property Bitmap: TBitmap Read fBitmap Write SetBitmap;
  43.   end;
  44.  
  45. procedure Register;
  46.  
  47. implementation
  48.  
  49. uses
  50.   Windows,
  51.   SysUtils,
  52.   ClipBrd;
  53.  
  54. procedure Register;
  55. begin
  56.   RegisterComponents('DragDrop', [TDropBMPSource]);
  57. end;
  58.  
  59. // -----------------------------------------------------------------------------
  60. //     Miscellaneous DIB Function
  61. // -----------------------------------------------------------------------------
  62.  
  63. function GetHGlobalDIBFromBitmap(Bitmap: Graphics.TBitmap): HGlobal;
  64. var
  65.   Stream: TMemoryStream;
  66.   DIB: pointer;
  67.   DIBSize: integer;
  68.   bfh: TBitmapFileHeader;
  69. begin
  70.   Stream := TMemoryStream.Create;
  71.   try
  72.     //let Graphics.pas do the work...
  73.     Bitmap.SaveToStream(Stream);
  74.     //BitmapFileHeader will be discarded
  75.     DIBSize := Stream.Size - sizeof(TBitmapFileHeader);
  76.     Result:=GlobalAlloc(GMEM_MOVEABLE or GMEM_ZEROINIT or GMEM_SHARE, DIBSize);
  77.     if Result = 0 then exit;
  78.     DIB := GlobalLock(Result);
  79.     if DIB = nil then
  80.     begin
  81.       GlobalFree(Result);
  82.       Result := 0;
  83.     end else
  84.     begin
  85.       Stream.Seek(0,soFromBeginning);
  86.       //skip BitmapFileHeader...
  87.       Stream.readbuffer(bfh,sizeof(TBitmapFileHeader));
  88.       //copy data...
  89.       Stream.readbuffer(DIB^,DIBSize);
  90.       GlobalUnlock(Result);
  91.     end;
  92.   finally
  93.     Stream.free;
  94.   end;
  95. end;
  96.  
  97. // -----------------------------------------------------------------------------
  98. //                      TDropBMPSource
  99. // -----------------------------------------------------------------------------
  100.  
  101. constructor TDropBMPSource.Create(aOwner: TComponent);
  102. begin
  103.   inherited Create(aOwner);
  104.   fBitmap := Graphics.TBitmap.Create;
  105.   DragTypes := [dtCopy]; // Default to Copy
  106.  
  107.   AddFormatEtc(CF_BITMAP, NIL, DVASPECT_CONTENT, -1, TYMED_GDI);
  108.   AddFormatEtc(CF_PALETTE, NIL, DVASPECT_CONTENT, -1, TYMED_GDI);
  109.   AddFormatEtc(CF_DIB, NIL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
  110. end;
  111. // -----------------------------------------------------------------------------
  112.  
  113. destructor TDropBMPSource.destroy;
  114. begin
  115.   fBitmap.Free;
  116.   inherited Destroy;
  117. end;
  118. // -----------------------------------------------------------------------------
  119.  
  120. procedure TDropBMPSource.SetBitmap(Bmp: Graphics.TBitmap);
  121. begin
  122.   fBitmap.assign(Bmp);
  123. end;
  124. // -----------------------------------------------------------------------------
  125.  
  126. function TDropBMPSource.CutOrCopyToClipboard: boolean;
  127. var
  128.   data: HGlobal;
  129. begin
  130.   result := false;
  131.   if fBitmap.empty then exit;
  132.   try
  133.     data := GetHGlobalDIBFromBitmap(fBitmap);
  134.     if data = 0 then exit;
  135.     Clipboard.SetAsHandle(CF_DIB,data);
  136.     result := true;
  137.   except
  138.     raise Exception.create('Unable to copy BMP to clipboard.');
  139.   end;
  140. end;
  141. // -----------------------------------------------------------------------------
  142.  
  143. function TDropBMPSource.DoGetData(const FormatEtcIn: TFormatEtc; OUT Medium: TStgMedium):HRESULT;
  144. var
  145.   fmt: WORD;
  146.   pal: HPALETTE;
  147. begin
  148.  
  149.   Medium.tymed := 0;
  150.   Medium.UnkForRelease := nil;
  151.   Medium.HGlobal := 0;
  152.   //--------------------------------------------------------------------------
  153.   if not fBitmap.empty and
  154.      (FormatEtcIn.cfFormat = CF_DIB) and
  155.      (FormatEtcIn.dwAspect = DVASPECT_CONTENT) and
  156.      (FormatEtcIn.tymed and TYMED_HGLOBAL <> 0) then
  157.   begin
  158.     try
  159.       Medium.HGlobal := GetHGlobalDIBFromBitmap(fBitmap);
  160.       if Medium.HGlobal <> 0 then
  161.       begin
  162.         Medium.tymed := TYMED_HGLOBAL;
  163.         result := S_OK
  164.       end else
  165.         result := E_OUTOFMEMORY;
  166.     except
  167.       result := E_OUTOFMEMORY;
  168.     end;
  169.   end
  170.   //--------------------------------------------------------------------------
  171.   else if not fBitmap.empty and
  172.      (FormatEtcIn.cfFormat = CF_BITMAP) and
  173.      (FormatEtcIn.dwAspect = DVASPECT_CONTENT) and
  174.      (FormatEtcIn.tymed and TYMED_GDI <> 0) then
  175.   begin
  176.     try
  177.       //This next line just gets a copy of the bitmap handle...
  178.       fBitmap.SaveToClipboardFormat(fmt, THandle(Medium.hBitmap), pal);
  179.       if pal <> 0 then DeleteObject(pal);
  180.       if Medium.hBitmap <> 0 then
  181.       begin
  182.         Medium.tymed := TYMED_GDI;
  183.         result := S_OK
  184.       end else
  185.         result := E_OUTOFMEMORY;
  186.     except
  187.       result := E_OUTOFMEMORY;
  188.     end;
  189.   end
  190.   //--------------------------------------------------------------------------
  191.   else if not fBitmap.empty and
  192.      (FormatEtcIn.cfFormat = CF_PALETTE) and
  193.      (FormatEtcIn.dwAspect = DVASPECT_CONTENT) and
  194.      (FormatEtcIn.tymed and TYMED_GDI <> 0) then
  195.   begin
  196.     try
  197.       Medium.hBitmap := CopyPalette(fBitmap.palette);
  198.       if Medium.hBitmap <> 0 then
  199.       begin
  200.         Medium.tymed := TYMED_GDI;
  201.         result := S_OK
  202.       end else
  203.         result := E_OUTOFMEMORY;
  204.     except
  205.       result := E_OUTOFMEMORY;
  206.     end {try}
  207.   end else
  208.     result := DV_E_FORMATETC;
  209. end;
  210. // -----------------------------------------------------------------------------
  211. // -----------------------------------------------------------------------------
  212.  
  213. end.
  214.