ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

dragdrop.c
Go to the documentation of this file.
00001 /*
00002  * ReactOS Explorer
00003  *
00004  * Copyright 2006 - 2007 Thomas Weidenmueller <w3seek@reactos.org>
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00019  */
00020 
00021 #include <precomp.h>
00022 
00023 static const IDropTargetVtbl IDropTargetImpl_Vtbl;
00024 
00025 /*
00026  * IDropTarget
00027  */
00028 
00029 typedef struct
00030 {
00031     const IDropTargetVtbl *lpVtbl;
00032     LONG Ref;
00033     HWND hwndTarget;
00034     IDropTargetHelper *DropTargetHelper;
00035     PVOID Context;
00036     BOOL CanDrop;
00037     DROPTARGET_CALLBACKS Callbacks;
00038     DWORD FormatsCount;
00039     FORMATETC Formats[0];
00040 } IDropTargetImpl;
00041 
00042 static IUnknown *
00043 IUnknown_from_impl(IDropTargetImpl *This)
00044 {
00045     return (IUnknown *)&This->lpVtbl;
00046 }
00047 
00048 static IDropTarget *
00049 IDropTarget_from_impl(IDropTargetImpl *This)
00050 {
00051     return (IDropTarget *)&This->lpVtbl;
00052 }
00053 
00054 static IDropTargetImpl *
00055 impl_from_IDropTarget(IDropTarget *iface)
00056 {
00057     return (IDropTargetImpl *)((ULONG_PTR)iface - FIELD_OFFSET(IDropTargetImpl,
00058                                                                lpVtbl));
00059 }
00060 
00061 static VOID
00062 IDropTargetImpl_Free(IDropTargetImpl *This)
00063 {
00064     IDropTargetHelper_Release(This->DropTargetHelper);
00065 }
00066 
00067 static ULONG STDMETHODCALLTYPE
00068 IDropTargetImpl_Release(IN OUT IDropTarget *iface)
00069 {
00070     IDropTargetImpl *This = impl_from_IDropTarget(iface);
00071     ULONG Ret;
00072 
00073     Ret = InterlockedDecrement(&This->Ref);
00074     if (Ret == 0)
00075         IDropTargetImpl_Free(This);
00076 
00077     return Ret;
00078 }
00079 
00080 static ULONG STDMETHODCALLTYPE
00081 IDropTargetImpl_AddRef(IN OUT IDropTarget *iface)
00082 {
00083     IDropTargetImpl *This = impl_from_IDropTarget(iface);
00084 
00085     return InterlockedIncrement(&This->Ref);
00086 }
00087 
00088 static HRESULT STDMETHODCALLTYPE
00089 IDropTargetImpl_QueryInterface(IN OUT IDropTarget *iface,
00090                                IN REFIID riid,
00091                                OUT LPVOID *ppvObj)
00092 {
00093     IDropTargetImpl *This;
00094 
00095     if (ppvObj == NULL)
00096         return E_POINTER;
00097 
00098     This = impl_from_IDropTarget(iface);
00099 
00100     if (IsEqualIID(riid,
00101                    &IID_IUnknown))
00102     {
00103         *ppvObj = IUnknown_from_impl(This);
00104     }
00105     else if (IsEqualIID(riid,
00106                         &IID_IDropTarget))
00107     {
00108         *ppvObj = IDropTarget_from_impl(This);
00109     }
00110     else
00111     {
00112         *ppvObj = NULL;
00113         return E_NOINTERFACE;
00114     }
00115 
00116     IDropTargetImpl_AddRef(iface);
00117     return S_OK;
00118 }
00119 
00120 IDropTarget *
00121 CreateDropTarget(IN HWND hwndTarget,
00122                  IN DWORD nSupportedFormats,
00123                  IN const FORMATETC *Formats  OPTIONAL,
00124                  IN PVOID Context  OPTIONAL,
00125                  IN const DROPTARGET_CALLBACKS *Callbacks  OPTIONAL)
00126 {
00127     IDropTargetImpl *This;
00128     HRESULT hr;
00129 
00130     This = (IDropTargetImpl *)HeapAlloc(hProcessHeap,
00131                                         0,
00132                                         FIELD_OFFSET(IDropTargetImpl,
00133                                                      Formats[nSupportedFormats]));
00134     if (This != NULL)
00135     {
00136         ZeroMemory(This,
00137                    sizeof(*This));
00138 
00139         This->lpVtbl = &IDropTargetImpl_Vtbl;
00140         This->Ref = 1;
00141         This->hwndTarget = hwndTarget;
00142         This->FormatsCount = nSupportedFormats;
00143         if (nSupportedFormats != 0)
00144         {
00145             CopyMemory(This->Formats,
00146                        Formats,
00147                        sizeof(Formats[0]) * nSupportedFormats);
00148         }
00149 
00150         This->Context = Context;
00151         if (Callbacks != NULL)
00152         {
00153             CopyMemory(&This->Callbacks,
00154                        Callbacks,
00155                        sizeof(*Callbacks));
00156         }
00157 
00158         hr = CoCreateInstance(&CLSID_DragDropHelper,
00159                               NULL,
00160                               CLSCTX_INPROC_SERVER,
00161                               &IID_IDropTargetHelper,
00162                               (PVOID)&This->DropTargetHelper);
00163 
00164         if (!SUCCEEDED(hr))
00165         {
00166             HeapFree(hProcessHeap,
00167                      0,
00168                      This);
00169             return NULL;
00170         }
00171 
00172         return IDropTarget_from_impl(This);
00173     }
00174 
00175     return NULL;
00176 }
00177 
00178 static const FORMATETC *
00179 IDropTargetImpl_FindSupportedFormat(IN OUT IDropTargetImpl *This,
00180                                     IN IDataObject *pDataObject)
00181 {
00182     FORMATETC *Current, *Last;
00183     HRESULT hr;
00184 
00185     /* NOTE: we could use IDataObject::EnumFormatEtc(),
00186              but this appears to be a lot easier! */
00187     Last = This->Formats + This->FormatsCount;
00188     for (Current = This->Formats;
00189          Current != Last;
00190          Current++)
00191     {
00192         hr = IDataObject_QueryGetData(pDataObject,
00193                                       Current);
00194         if (SUCCEEDED(hr))
00195             return Current;
00196     }
00197 
00198     return NULL;
00199 }
00200 
00201 static HRESULT STDMETHODCALLTYPE
00202 IDropTargetImpl_DragEnter(IN OUT IDropTarget *iface,
00203                           IN IDataObject *pDataObject,
00204                           IN DWORD grfKeyState,
00205                           IN POINTL pt,
00206                           IN OUT DWORD *pdwEffect)
00207 {
00208     IDropTargetImpl *This = impl_from_IDropTarget(iface);
00209     const FORMATETC *Format;
00210     HRESULT hr;
00211 
00212     if (pDataObject == NULL)
00213         return E_INVALIDARG;
00214 
00215     This->CanDrop = FALSE;
00216 
00217     hr = IDropTargetHelper_DragEnter(This->DropTargetHelper,
00218                                      This->hwndTarget,
00219                                      pDataObject,
00220                                      (POINT *)&pt,
00221                                      *pdwEffect);
00222 
00223     if (SUCCEEDED(hr))
00224     {
00225         Format = IDropTargetImpl_FindSupportedFormat(This,
00226                                                      pDataObject);
00227         if (Format != NULL)
00228         {
00229             /* We found a format that we support! */
00230             if (This->Callbacks.OnDragEnter != NULL)
00231             {
00232                 hr = This->Callbacks.OnDragEnter(iface,
00233                                                  This->Context,
00234                                                  Format,
00235                                                  grfKeyState,
00236                                                  pt,
00237                                                  pdwEffect);
00238                 if (SUCCEEDED(hr))
00239                 {
00240                     if (hr == S_OK)
00241                         This->CanDrop = TRUE;
00242                     else
00243                     {
00244                         /* Special return value by the callback routine,
00245                            doesn't want to allow dragging */
00246                         *pdwEffect = DROPEFFECT_NONE;
00247                     }
00248 
00249                     hr = S_OK;
00250                 }
00251                 else
00252                 {
00253                     *pdwEffect = DROPEFFECT_NONE;
00254                     hr = S_OK;
00255                 }
00256             }
00257             else
00258                 *pdwEffect = DROPEFFECT_NONE;
00259         }
00260         else
00261             *pdwEffect = DROPEFFECT_NONE;
00262     }
00263 
00264     return hr;
00265 }
00266 
00267 static HRESULT STDMETHODCALLTYPE
00268 IDropTargetImpl_DragOver(IN OUT IDropTarget *iface,
00269                          IN DWORD grfKeyState,
00270                          IN POINTL pt,
00271                          IN OUT DWORD *pdwEffect)
00272 {
00273     IDropTargetImpl *This = impl_from_IDropTarget(iface);
00274     HRESULT hr;
00275 
00276     hr = IDropTargetHelper_DragOver(This->DropTargetHelper,
00277                                     (POINT *)&pt,
00278                                     *pdwEffect);
00279 
00280     if (SUCCEEDED(hr))
00281     {
00282         if (This->CanDrop)
00283         {
00284             if (This->Callbacks.OnDragOver != NULL)
00285             {
00286                 hr = This->Callbacks.OnDragOver(iface,
00287                                                 This->Context,
00288                                                 grfKeyState,
00289                                                 pt,
00290                                                 pdwEffect);
00291                 if (SUCCEEDED(hr))
00292                 {
00293                     if (hr != S_OK)
00294                     {
00295                         /* Special return value by the callback routine,
00296                            doesn't want to allow dropping here */
00297                         *pdwEffect = DROPEFFECT_NONE;
00298                     }
00299 
00300                     hr = S_OK;
00301                 }
00302                 else
00303                 {
00304                     *pdwEffect = DROPEFFECT_NONE;
00305                     hr = S_OK;
00306                 }
00307             }
00308             else
00309                 *pdwEffect = DROPEFFECT_NONE;
00310         }
00311         else
00312             *pdwEffect = DROPEFFECT_NONE;
00313     }
00314 
00315     return hr;
00316 }
00317 
00318 static HRESULT STDMETHODCALLTYPE
00319 IDropTargetImpl_DragLeave(IN OUT IDropTarget *iface)
00320 {
00321     IDropTargetImpl *This = impl_from_IDropTarget(iface);
00322     HRESULT hr;
00323 
00324     hr = IDropTargetHelper_DragLeave(This->DropTargetHelper);
00325     if (SUCCEEDED(hr))
00326     {
00327         if (This->Callbacks.OnDragLeave != NULL)
00328         {
00329             hr = This->Callbacks.OnDragLeave(iface,
00330                                              This->Context);
00331         }
00332     }
00333 
00334     return hr;
00335 }
00336 
00337 static HRESULT STDMETHODCALLTYPE
00338 IDropTargetImpl_Drop(IN OUT IDropTarget *iface,
00339                      IN IDataObject *pDataObject,
00340                      IN DWORD grfKeyState,
00341                      IN POINTL pt,
00342                      IN OUT DWORD *pdwEffect)
00343 {
00344     IDropTargetImpl *This = impl_from_IDropTarget(iface);
00345     const FORMATETC *Format;
00346     HRESULT hr;
00347 
00348     if (pDataObject == NULL)
00349         return E_INVALIDARG;
00350 
00351     hr = IDropTargetHelper_Drop(This->DropTargetHelper,
00352                                 pDataObject,
00353                                 (POINT *)&pt,
00354                                 *pdwEffect);
00355 
00356     if (SUCCEEDED(hr) && This->CanDrop)
00357     {
00358         Format = IDropTargetImpl_FindSupportedFormat(This,
00359                                                      pDataObject);
00360         if (Format != NULL)
00361         {
00362             /* We found a format that we support! */
00363             if (This->Callbacks.OnDrop != NULL)
00364             {
00365                 hr = This->Callbacks.OnDrop(iface,
00366                                             This->Context,
00367                                             Format,
00368                                             grfKeyState,
00369                                             pt,
00370                                             pdwEffect);
00371                 if (SUCCEEDED(hr))
00372                 {
00373                     if (hr == S_OK)
00374                         This->CanDrop = TRUE;
00375                     else
00376                     {
00377                         /* Special return value by the callback routine,
00378                            doesn't want to allow dragging */
00379                         *pdwEffect = DROPEFFECT_NONE;
00380                     }
00381 
00382                     hr = S_OK;
00383                 }
00384                 else
00385                 {
00386                     *pdwEffect = DROPEFFECT_NONE;
00387                     hr = S_OK;
00388                 }
00389             }
00390             else
00391                 *pdwEffect = DROPEFFECT_NONE;
00392         }
00393         else
00394             *pdwEffect = DROPEFFECT_NONE;
00395     }
00396 
00397     return hr;
00398 }
00399 
00400 static const IDropTargetVtbl IDropTargetImpl_Vtbl =
00401 {
00402     /* IUnknown */
00403     IDropTargetImpl_QueryInterface,
00404     IDropTargetImpl_AddRef,
00405     IDropTargetImpl_Release,
00406     /* IDropTarget */
00407     IDropTargetImpl_DragEnter,
00408     IDropTargetImpl_DragOver,
00409     IDropTargetImpl_DragLeave,
00410     IDropTargetImpl_Drop
00411 };

Generated on Fri May 25 2012 04:16:35 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.