home *** CD-ROM | disk | FTP | other *** search
/ Chip 2003 January / Chip_2003-01_cd1.bin / zkuste / delphi / kolekce / d567 / FLEXCEL.ZIP / Design / UOleDrag.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2002-09-26  |  7.3 KB  |  252 lines

  1. unit UOleDrag;
  2. // This unit is based on the works of Graham Wideman
  3. //          graham@wideman-one.com
  4. //          www.wideman-one.com
  5. // Thanks!
  6.  
  7.  
  8. interface
  9. uses Windows, Activex, SysUtils;
  10. type
  11.   TFlxDropSource= class(TInterfacedObject, IDropSource)
  12.     function QueryContinueDrag(fEscapePressed: BOOL; grfKeyState: Longint): HResult; stdcall;
  13.     function GiveFeedback(dwEffect: Longint): HResult; stdcall;
  14.   end;
  15.  
  16.   TFlxEnumformatEtc=class(TInterfacedObject, IEnumFORMATETC)
  17.   private
  18.     FIndex: integer;
  19.   public
  20.     function Next(celt: Longint; out elt; pceltFetched: PLongint): HResult; stdcall;
  21.     function Skip(celt: Longint): HResult; stdcall;
  22.     function Reset: HResult; stdcall;
  23.     function Clone(out Enum: IEnumFormatEtc): HResult; stdcall;
  24.  
  25.     constructor Create;
  26.   end;
  27.  
  28.   TFlxDataObject= class(TInterfacedObject, IDataObject)
  29.   private
  30.     FText: string;
  31.   public
  32.     function GetData(const formatetcIn: TFormatEtc; out medium: TStgMedium): HResult; stdcall;
  33.     function GetDataHere(const formatetc: TFormatEtc; out medium: TStgMedium): HResult; stdcall;
  34.     function QueryGetData(const formatetc: TFormatEtc): HResult; stdcall;
  35.     function GetCanonicalFormatEtc(const formatetc: TFormatEtc; out formatetcOut: TFormatEtc): HResult; stdcall;
  36.     function SetData(const formatetc: TFormatEtc; var medium: TStgMedium; fRelease: BOOL): HResult; stdcall;
  37.     function EnumFormatEtc(dwDirection: Longint; out enumFormatEtc: IEnumFormatEtc): HResult; stdcall;
  38.     function DAdvise(const formatetc: TFormatEtc; advf: Longint; const advSink: IAdviseSink; out dwConnection: Longint): HResult; stdcall;
  39.     function DUnadvise(dwConnection: Longint): HResult; stdcall; function EnumDAdvise(out enumAdvise: IEnumStatData): HResult; stdcall;
  40.  
  41.     constructor Create(const aText: string);
  42.   end;
  43. implementation
  44.  
  45. { TFlxDropSource }
  46.  
  47. function TFlxDropSource.GiveFeedback(dwEffect: Integer): HResult;
  48. begin
  49.   Result := DRAGDROP_S_USEDEFAULTCURSORS;
  50. end;
  51.  
  52. function TFlxDropSource.QueryContinueDrag(fEscapePressed: BOOL; grfKeyState: Integer): HResult;
  53. begin
  54.   Result := S_OK;
  55.   If fEscapePressed then Result := DRAGDROP_S_CANCEL else
  56.     if ((grfKeyState and MK_LBUTTON) = 0) then // mouse-up
  57.       Result := DRAGDROP_S_DROP;
  58. end;
  59.  
  60. { TFlxDataObject }
  61.  
  62. constructor TFlxDataObject.Create(const aText: string);
  63. begin
  64.   inherited Create;
  65.   FText:=aText;
  66. end;
  67.  
  68. function TFlxDataObject.DAdvise(const formatetc: TFormatEtc; advf: Integer;
  69.   const advSink: IAdviseSink; out dwConnection: Integer): HResult;
  70. begin
  71.   Result := OLE_E_ADVISENOTSUPPORTED;
  72. end;
  73.  
  74. function TFlxDataObject.DUnadvise(dwConnection: Integer): HResult;
  75. begin
  76.   Result := OLE_E_ADVISENOTSUPPORTED;
  77. end;
  78.  
  79. function TFlxDataObject.EnumDAdvise(
  80.   out enumAdvise: IEnumStatData): HResult;
  81. begin
  82.   Result := OLE_E_ADVISENOTSUPPORTED;
  83. end;
  84.  
  85. function TFlxDataObject.EnumFormatEtc(dwDirection: Integer;
  86.   out enumFormatEtc: IEnumFormatEtc): HResult;
  87. begin
  88.   if dwDirection <> DATADIR_GET then
  89.   Begin
  90.     enumFormatEtc := nil;
  91.     Result := E_NOTIMPL;
  92.     exit;
  93.   end;
  94.   //--------------------------------------------------------------------
  95.   // Finer OLE point: assigning to enumFormatEtc will auto increment the
  96.   // RefCount to 1, since enumFormatEtc is an IEnumFormatEtc.
  97.   // ie: no need to _AddRef, in fact that will lead to enumFormatEtc
  98.   // never getting deleted.
  99.   // Note, this conflicts with Cantu 1998 Delphi Developer Handbook P465
  100.   //--------------------------------------------------------------------
  101.   enumFormatEtc := TFlxEnumFormatEtc.Create;
  102.   Result := S_OK;
  103. end;
  104.  
  105. function TFlxDataObject.GetCanonicalFormatEtc(const formatetc: TFormatEtc;
  106.   out formatetcOut: TFormatEtc): HResult;
  107. begin
  108.   formatetcOut.ptd := nil;
  109.   Result := E_NOTIMPL;
  110. end;
  111.  
  112. function TFlxDataObject.GetData(const formatetcIn: TFormatEtc; out medium: TStgMedium): HResult;
  113. var
  114.   HGlobalData: HGlobal;
  115.   PGlobalData: PChar;
  116.  
  117.   OutString: string;
  118.   OutStringLen: integer;
  119.   AllocLen: integer;
  120. begin
  121.   Result := DV_E_FORMATETC;
  122.   if QueryGetData(formatetcIn) <> S_OK then exit;
  123.  
  124.   // most medium fields are already initialized by this point
  125.   medium.tymed := TYMED_HGLOBAL;
  126.  
  127.   OutString     := FText;
  128.   OutStringLen  := Length(OutString);
  129.  
  130.   case formatetcIn.cfFormat of
  131.     CF_TEXT:        AllocLen := OutStringLen + 1;
  132.     CF_UNICODETEXT: AllocLen := OutStringLen * 2 + 2;
  133.     else exit;
  134.   end; //case
  135.  
  136.   HGlobalData := GlobalAlloc((GMEM_SHARE or GMEM_MOVEABLE or GMEM_ZEROINIT), AllocLen);
  137.   if (HGlobalData <> 0) then
  138.   begin
  139.     PGlobalData := GlobalLock (HGlobalData); // lock while we are using it
  140.     try
  141.       case formatetcIn.cfFormat of
  142.         CF_TEXT:        StrCopy(PGlobalData, PChar(OutString));
  143.         CF_UNICODETEXT: StringToWideChar(OutString, PWideChar(PGlobalData), OutStringLen+1);
  144.       end; //case
  145.     finally
  146.       GlobalUnlock (HGlobalData);
  147.     end; //finally
  148.     medium.hGlobal := HGlobalData;
  149.     Result := S_OK;
  150.   end;
  151. end;
  152.  
  153. function TFlxDataObject.GetDataHere(const formatetc: TFormatEtc;
  154.   out medium: TStgMedium): HResult;
  155. begin
  156.   Result := DV_E_FORMATETC;
  157. end;
  158.  
  159. function TFlxDataObject.QueryGetData(const formatetc: TFormatEtc): HResult;
  160. begin
  161.   Result := DV_E_FORMATETC;
  162.   if (formatetc.dwAspect = DVASPECT_CONTENT) and
  163.      ((formatetc.cfFormat = CF_TEXT) or (formatetc.cfFormat = CF_UNICODETEXT)) and
  164.      (formatetc.tymed = TYMED_HGLOBAL) then Result := S_OK;
  165. end;
  166.  
  167. function TFlxDataObject.SetData(const formatetc: TFormatEtc;
  168.   var medium: TStgMedium; fRelease: BOOL): HResult;
  169. begin
  170.   Result := E_NOTIMPL;
  171. end;
  172.  
  173. //-----------------------
  174. { TFlxEnumformat }
  175. type
  176.   TFormatEtcArray = array[0..19] of TFormatEtc;
  177.   PFormatEtcArray = ^TFormatEtcArray;
  178.  
  179. function TFlxEnumformatEtc.Clone(out Enum: IEnumFormatEtc): HResult;
  180. begin
  181.   Result := S_FALSE;
  182. end;
  183.  
  184. constructor TFlxEnumformatEtc.create;
  185. begin
  186.   inherited;
  187.   FIndex:=0;
  188. end;
  189.  
  190. function TFlxEnumformatEtc.Next(celt: Integer; out elt;
  191.   pceltFetched: PLongint): HResult;
  192. var
  193.   N: integer;
  194.   FormatEtcArrayOut: TFormatEtcArray absolute elt;
  195. begin
  196.   Result := S_FALSE;
  197.   N := 0;
  198.   while (N < celt) and (FIndex < 2) do
  199.   begin
  200.     case FIndex of
  201.       1: begin
  202.         FormatEtcArrayOut[N].cfFormat := CF_UNICODETEXT;
  203.         FormatEtcArrayOut[N].ptd      := nil;
  204.         FormatEtcArrayOut[N].dwAspect := DVASPECT_CONTENT;
  205.         FormatEtcArrayOut[N].lindex   := -1;
  206.         FormatEtcArrayOut[N].tymed    := TYMED_HGLOBAL;
  207.       end;
  208.       else Begin
  209.         FormatEtcArrayOut[N].cfFormat := CF_TEXT;
  210.         FormatEtcArrayOut[N].ptd      := nil;
  211.         FormatEtcArrayOut[N].dwAspect := DVASPECT_CONTENT;
  212.         FormatEtcArrayOut[N].lindex   := -1;
  213.         FormatEtcArrayOut[N].tymed    := TYMED_HGLOBAL;
  214.       end;
  215.     end; //case
  216.  
  217.     Inc(FIndex);
  218.     Inc(N);
  219.   end;
  220.   If PceltFetched <> nil then PceltFetched^ := N;
  221.   if N = celt then Result := S_OK;
  222. end;
  223.  
  224. function TFlxEnumformatEtc.Reset: HResult;
  225. begin
  226.   FIndex := 0;
  227.   Result := S_OK;
  228. end;
  229.  
  230. function TFlxEnumformatEtc.Skip(celt: Integer): HResult;
  231. begin
  232.   FIndex := FIndex + celt;
  233.   if FIndex > 2 then
  234.   begin
  235.     FIndex := 2;
  236.     Result := S_FALSE;
  237.   end
  238.   else Result := S_OK;
  239. end;
  240.  
  241. initialization
  242. //-----------------------
  243.   OleInitialize (Nil);
  244.  
  245. //-----------------------
  246. finalization
  247. //-----------------------
  248.   OleUninitialize;
  249.  
  250.  
  251. end.
  252.