Subversion Repositories decoder

Rev

Blame | Last modification | View Log | RSS feed

  1. unit DropURLSource;
  2.  
  3. // -----------------------------------------------------------------------------
  4. // Project:         Drag and Drop Component Suite
  5. // Component Names: TDropURLSource
  6. // Module:          DropURLSource
  7. // Description:     Implements Dragging & Dropping of URLs
  8. //                  FROM your application to another.
  9. // Version:         3.7
  10. // Date:            22-APR-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.  
  18. interface
  19.  
  20. uses
  21.   DropSource,
  22.   Classes, ActiveX;
  23.  
  24. {$include DragDrop.inc}
  25.  
  26. type
  27.   TDropURLSource = class(TDropSource)
  28.   private
  29.     fURL: String;
  30.     fTitle: String;
  31.   protected
  32.     function DoGetData(const FormatEtcIn: TFormatEtc; OUT Medium: TStgMedium):HRESULT; Override;
  33.   public
  34.     constructor Create(aOwner: TComponent); Override;
  35.     function CutOrCopyToClipboard: boolean; Override;
  36.   published
  37.     property URL: String Read fURL Write fURL;
  38.     property Title: String Read fTitle Write fTitle;
  39.   end;
  40.  
  41. procedure Register;
  42.  
  43. implementation
  44.  
  45. uses
  46.   Windows,
  47.   SysUtils,
  48.   ClipBrd,
  49.   ShlObj;
  50.  
  51. procedure Register;
  52. begin
  53.   RegisterComponents('DragDrop', [TDropURLSource]);
  54. end;
  55. // -----------------------------------------------------------------------------
  56.  
  57. function ConvertURLToFilename(url: string): string;
  58. const
  59.   Invalids = '\/:?*<>,|''"';
  60. var
  61.   i: integer;
  62. begin
  63.   if lowercase(copy(url,1,7)) = 'http://' then
  64.     url := copy(url,8,128) // limit to 120 chars.
  65.   else if lowercase(copy(url,1,6)) = 'ftp://' then
  66.     url := copy(url,7,127)
  67.   else if lowercase(copy(url,1,7)) = 'mailto:' then
  68.     url := copy(url,8,128)
  69.   else if lowercase(copy(url,1,5)) = 'file:' then
  70.     url := copy(url,6,126);
  71.  
  72.   if url = '' then url := 'untitled';
  73.   result := url;
  74.   for i := 1 to length(result) do
  75.     if result[i] = '/'then
  76.     begin
  77.       result := copy(result,1,i-1);
  78.       break;
  79.     end
  80.     else if pos(result[i],Invalids) <> 0 then
  81.       result[i] := ' ';
  82.    appendstr(result,'.url');
  83. end;
  84.  
  85. // -----------------------------------------------------------------------------
  86. //                      TDropURLSource
  87. // -----------------------------------------------------------------------------
  88.  
  89. constructor TDropURLSource.Create(aOwner: TComponent);
  90. begin
  91.   inherited Create(aOwner);
  92.   fURL := '';
  93.   fTitle := '';
  94.   DragTypes := [dtLink]; // Only dtLink allowed
  95.  
  96.   AddFormatEtc(CF_URL, NIL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
  97.   AddFormatEtc(CF_FILEGROUPDESCRIPTOR, NIL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
  98.   AddFormatEtc(CF_FILECONTENTS, NIL, DVASPECT_CONTENT, 0, TYMED_HGLOBAL);
  99.   AddFormatEtc(CF_TEXT, NIL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
  100. end;
  101. // -----------------------------------------------------------------------------
  102.  
  103. function TDropURLSource.CutOrCopyToClipboard: boolean;
  104. var
  105.   FormatEtcIn: TFormatEtc;
  106.   Medium: TStgMedium;
  107. begin
  108.   result := false;
  109.   FormatEtcIn.cfFormat := CF_URL;
  110.   FormatEtcIn.dwAspect := DVASPECT_CONTENT;
  111.   FormatEtcIn.tymed := TYMED_HGLOBAL;
  112.   if fURL = '' then exit;
  113.   if GetData(formatetcIn,Medium) = S_OK then
  114.   begin
  115.     Clipboard.SetAsHandle(CF_URL,Medium.hGlobal);
  116.     result := true;
  117.   end else exit;
  118.  
  119.   //render several formats...
  120.   FormatEtcIn.cfFormat := CF_TEXT;
  121.   FormatEtcIn.dwAspect := DVASPECT_CONTENT;
  122.   FormatEtcIn.tymed := TYMED_HGLOBAL;
  123.   if GetData(formatetcIn,Medium) = S_OK then
  124.   begin
  125.     Clipboard.SetAsHandle(CF_TEXT,Medium.hGlobal);
  126.     result := true;
  127.   end;
  128. end;
  129. // -----------------------------------------------------------------------------
  130.  
  131. function TDropURLSource.DoGetData(const FormatEtcIn: TFormatEtc; OUT Medium: TStgMedium):HRESULT;
  132. const
  133.   URLPrefix = '[InternetShortcut]'#10'URL=';
  134. var
  135.   pFGD: PFileGroupDescriptor;
  136.   pText: PChar;
  137. begin
  138.  
  139.   Medium.tymed := 0;
  140.   Medium.UnkForRelease := NIL;
  141.   Medium.hGlobal := 0;
  142.  
  143.   //--------------------------------------------------------------------------
  144.   if ((FormatEtcIn.cfFormat = CF_URL) or (FormatEtcIn.cfFormat = CF_TEXT)) and
  145.     (FormatEtcIn.dwAspect = DVASPECT_CONTENT) and
  146.     (FormatEtcIn.tymed and TYMED_HGLOBAL <> 0) then
  147.   begin
  148.     Medium.hGlobal := GlobalAlloc(GMEM_SHARE or GHND, Length(fURL)+1);
  149.     if (Medium.hGlobal = 0) then
  150.       result := E_OUTOFMEMORY
  151.     else
  152.     begin
  153.       medium.tymed := TYMED_HGLOBAL;
  154.       pText := PChar(GlobalLock(Medium.hGlobal));
  155.       try
  156.         StrCopy(pText, PChar(fURL));
  157.       finally
  158.         GlobalUnlock(Medium.hGlobal);
  159.       end;
  160.       result := S_OK;
  161.     end;
  162.   end
  163.   //--------------------------------------------------------------------------
  164.   else if (FormatEtcIn.cfFormat = CF_FILECONTENTS) and
  165.     (FormatEtcIn.dwAspect = DVASPECT_CONTENT) and
  166.     (FormatEtcIn.tymed and TYMED_HGLOBAL <> 0) then
  167.   begin
  168.     Medium.hGlobal := GlobalAlloc(GMEM_SHARE or GHND, Length(URLPrefix + fURL)+1);
  169.     if (Medium.hGlobal = 0) then
  170.       result := E_OUTOFMEMORY
  171.     else
  172.     begin
  173.       medium.tymed := TYMED_HGLOBAL;
  174.       pText := PChar(GlobalLock(Medium.hGlobal));
  175.       try
  176.         StrCopy(pText, PChar(URLPrefix + fURL));
  177.       finally
  178.         GlobalUnlock(Medium.hGlobal);
  179.       end;
  180.       result := S_OK;
  181.     end;
  182.   end
  183.   //--------------------------------------------------------------------------
  184.   else if (FormatEtcIn.cfFormat = CF_FILEGROUPDESCRIPTOR) and
  185.     (FormatEtcIn.dwAspect = DVASPECT_CONTENT) and
  186.     (FormatEtcIn.tymed and TYMED_HGLOBAL <> 0) then
  187.   begin
  188.     Medium.hGlobal := GlobalAlloc(GMEM_SHARE or GHND, SizeOf(TFileGroupDescriptor));
  189.     if (Medium.hGlobal = 0) then
  190.     begin
  191.       result := E_OUTOFMEMORY;
  192.       Exit;
  193.     end;
  194.     medium.tymed := TYMED_HGLOBAL;
  195.     pFGD := pointer(GlobalLock(Medium.hGlobal));
  196.     try
  197.       with pFGD^ do
  198.       begin
  199.         cItems := 1;
  200.         fgd[0].dwFlags := FD_LINKUI;
  201.         if title = '' then
  202.           StrPCopy(fgd[0].cFileName,ConvertURLToFilename(fURL))
  203.         else
  204.           StrPCopy(fgd[0].cFileName,ConvertURLToFilename(fTitle));
  205.       end;
  206.     finally
  207.       GlobalUnlock(Medium.hGlobal);
  208.     end;
  209.     result := S_OK;
  210.   //--------------------------------------------------------------------------
  211.   end else
  212.     result := DV_E_FORMATETC;
  213. end;
  214. // -----------------------------------------------------------------------------
  215. // -----------------------------------------------------------------------------
  216.  
  217. end.
  218.