test: menuddc.c Source File

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# menuddc.c

Go to the documentation of this file.

    00001 /****************************** Module Header ******************************\
    00002 * Module Name: menudd.c
    00003 *
    00004 * Copyright (c) 1985 - 1999, Microsoft Corporation
    00005 *
    00006 * Menu drag and drop - client
    00007 *
    00008 * History:
    00009 * 10/29/96  GerardoB    Created
    00010 \***************************************************************************/
    00011 #include "precomp.h"
    00012 #pragma hdrstop
    00013
    00014 /*
    00015  * OLE's GUID initialization
    00016  */
    00017 #include "initguid.h"
    00018
    00019 /*
    00020  * Macro to cast OLE's IDropTarget pointer to internal pointer
    00021  */
    00022 #define PMNIDT(pdt) ((PMNIDROPTARGET)pdt)
    00023
    00024 /*
    00025  * The mndt* functions implement the IDropTarget interface
    00026  */
    00027 /**************************************************************************\
    00028 * mndtAddRef
    00029 *
    00030 * 10/28/96 GerardoB     Created
    00031 \**************************************************************************/
    00032 ULONG mndtAddRef(LPDROPTARGET pdt)
    00033 {
    00034     return ++(PMNIDT(pdt)->dwRefCount);
    00035 }
    00036
    00037 /**************************************************************************\
    00038 * mndtQueryInterface
    00039 *
    00040 * 10/28/96 GerardoB     Created
    00041 \**************************************************************************/
    00042 HRESULT mndtQueryInterface(LPDROPTARGET pdt, REFIID riid, PVOID * ppvObj)
    00043 {
    00044     if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDropTarget)) {
    00045         mndtAddRef(pdt);
    00046         *ppvObj = pdt;
    00047         return NOERROR;
    00048     } else {
    00049         return E_NOINTERFACE;
    00050     }
    00051 }
    00052
    00053
    00054 /**************************************************************************\
    00055 * mndtRelease
    00056 *
    00057 * 10/28/96 GerardoB     Created
    00058 \**************************************************************************/
    00059 ULONG mndtRelease(LPDROPTARGET pdt)
    00060 {
    00061     if (--(PMNIDT(pdt)->dwRefCount) != 0) {
    00062         return PMNIDT(pdt)->dwRefCount;
    00063     }
    00064
    00065     LocalFree(pdt);
    00066     return NOERROR;
    00067 }
    00068
    00069 /**************************************************************************\
    00070 * mndtDragOver
    00071 *
    00072 * 10/28/96 GerardoB     Created
    00073 \**************************************************************************/
    00074 HRESULT mndtDragOver(LPDROPTARGET pdt, DWORD grfKeyState, POINTL ptl, LPDWORD pdwEffect)
    00075 {
    00076     MNDRAGOVERINFO mndoi;
    00077     MENUGETOBJECTINFO mngoi;
    00078
    00079     /*
    00080      * Get the dragover info for the selection corresponding to this point
    00081      */
    00082     if (!NtUserMNDragOver((POINT *)&ptl, &mndoi)) {
    00083         RIPMSG0(RIP_WARNING, "mndtDragOver: NtUserDragOver failed");
    00084         *pdwEffect = DROPEFFECT_NONE;
    00085         return NOERROR;
    00086     }
    00087
    00088     /*
    00089      * If not switching items or crossing gap boundaries, pass the
    00090      *  the drag over.
    00091      */
    00092     if (!(mndoi.dwFlags & MNGOF_CROSSBOUNDARY)) {
    00093         if (PMNIDT(pdt)->pidt != NULL) {
    00094             return PMNIDT(pdt)->pidt->lpVtbl->DragOver(PMNIDT(pdt)->pidt, grfKeyState, ptl, pdwEffect);
    00095         }
    00096     } else {
    00097         /*
    00098          *  DragLeave and Release the current item, if any
    00099          */
    00100         if (PMNIDT(pdt)->pidt != NULL) {
    00101             PMNIDT(pdt)->pidt->lpVtbl->DragLeave(PMNIDT(pdt)->pidt);
    00102             PMNIDT(pdt)->pidt->lpVtbl->Release(PMNIDT(pdt)->pidt);
    00103             PMNIDT(pdt)->pidt = NULL;
    00104         }
    00105
    00106         /*
    00107          * If an item is selected, Get the interface for it
    00108          */
    00109         if (mndoi.uItemIndex != MFMWFP_NOITEM) {
    00110             mngoi.hmenu = mndoi.hmenu;
    00111             mngoi.dwFlags = mndoi.dwFlags & MNGOF_GAP;
    00112             mngoi.uPos = mndoi.uItemIndex;
    00113             mngoi.riid = (PVOID)&IID_IDropTarget;
    00114             mngoi.pvObj = NULL;
    00115
    00116             if (MNGO_NOERROR == SendMessage(mndoi.hwndNotify, WM_MENUGETOBJECT, 0, (LPARAM)&mngoi)) {
    00117                 PMNIDT(pdt)->pidt = mngoi.pvObj;
    00118             }
    00119         }
    00120
    00121         /*
    00122          * If we got a new interface, AddRef and DragEnter it
    00123          */
    00124         if (PMNIDT(pdt)->pidt != NULL) {
    00125             PMNIDT(pdt)->pidt->lpVtbl->AddRef(PMNIDT(pdt)->pidt);
    00126             return PMNIDT(pdt)->pidt->lpVtbl->DragEnter(PMNIDT(pdt)->pidt, PMNIDT(pdt)->pido, grfKeyState, ptl, pdwEffect);
    00127         }
    00128     } /* if (!(mndoi.dwFlags & MNGOF_CROSSBOUNDARY)) */
    00129
    00130     *pdwEffect = DROPEFFECT_NONE;
    00131     return NOERROR;
    00132 }
    00133 /**************************************************************************\
    00134 * mndtDragEnter
    00135 *
    00136 * 10/28/96 GerardoB     Created
    00137 \**************************************************************************/
    00138
    00139 HRESULT mndtDragEnter(LPDROPTARGET pdt, LPDATAOBJECT pdo, DWORD grfKeyState, POINTL ptl, LPDWORD pdwEffect)
    00140 {
    00141     /*
    00142      * Save the IDataObject
    00143      */
    00144     PMNIDT(pdt)->pido = pdo;
    00145
    00146     /*
    00147      * DragEnter is the same as a DragOver; only that we will never fail it
    00148      */
    00149     mndtDragOver(pdt, grfKeyState, ptl, pdwEffect);
    00150
    00151     return NOERROR;
    00152 }
    00153 /**************************************************************************\
    00154 * mndtDragLeave
    00155 *
    00156 * 10/28/96 GerardoB     Created
    00157 \**************************************************************************/
    00158 HRESULT mndtDragLeave(LPDROPTARGET pdt)
    00159 {
    00160     /*
    00161      * Let the kernel mode clean up
    00162      */
    00163     NtUserMNDragLeave();
    00164
    00165     /*
    00166      *  DragLeave and Release the current item, if any
    00167      */
    00168     if (PMNIDT(pdt)->pidt != NULL) {
    00169         PMNIDT(pdt)->pidt->lpVtbl->DragLeave(PMNIDT(pdt)->pidt);
    00170         PMNIDT(pdt)->pidt->lpVtbl->Release(PMNIDT(pdt)->pidt);
    00171         PMNIDT(pdt)->pidt = NULL;
    00172     }
    00173
    00174     return NOERROR;
    00175 }
    00176
    00177 /**************************************************************************\
    00178 * mndtDrop
    00179 *
    00180 * 10/28/96 GerardoB     Created
    00181 \**************************************************************************/
    00182 HRESULT mndtDrop(LPDROPTARGET pdt, LPDATAOBJECT pdo, DWORD grfKeyState, POINTL ptl, LPDWORD pdwEffect)
    00183 {
    00184     HRESULT hres;
    00185
    00186     /*
    00187      * If we got a target, pass the drop and release it.
    00188      */
    00189     if (PMNIDT(pdt)->pidt != NULL) {
    00190         hres = PMNIDT(pdt)->pidt->lpVtbl->Drop(PMNIDT(pdt)->pidt, pdo, grfKeyState, ptl, pdwEffect);
    00191         PMNIDT(pdt)->pidt->lpVtbl->Release(PMNIDT(pdt)->pidt);
    00192         PMNIDT(pdt)->pidt = NULL;
    00193     } else {
    00194         *pdwEffect = DROPEFFECT_NONE;
    00195         hres = NOERROR;
    00196     }
    00197
    00198     /*
    00199      * Clean up
    00200      */
    00201     mndtDragLeave(pdt);
    00202
    00203     return hres;
    00204 }
    00205
    00206 /**************************************************************************\
    00207 * Drop target VTable
    00208 *
    00209 \**************************************************************************/
    00210 IDropTargetVtbl idtVtbl = {
    00211     mndtQueryInterface,
    00212     mndtAddRef,
    00213     mndtRelease,
    00214     mndtDragEnter,
    00215     mndtDragOver,
    00216     mndtDragLeave,
    00217     mndtDrop
    00218 };
    00219 /**************************************************************************\
    00220 * __ClientRegisterDragDrop
    00221 *
    00222 * 10/28/96 GerardoB     Created
    00223 \**************************************************************************/
    00224 DWORD __ClientRegisterDragDrop(HWND * phwnd)
    00225 {
    00226     HRESULT hres = STATUS_UNSUCCESSFUL;
    00227     PMNIDROPTARGET pmnidt;
    00228
    00229     /*
    00230      * Allocate the IDropTarget interface struct & additional data
    00231      */
    00232     pmnidt = (PMNIDROPTARGET)LocalAlloc(LPTR, sizeof(MNIDROPTARGET));
    00233     if (pmnidt == NULL) {
    00234         RIPMSG0(RIP_WARNING, "__ClientRegisterDragDrop allocation Failed");
    00235         hres = STATUS_UNSUCCESSFUL;
    00236         goto BackToKernel;
    00237     }
    00238
    00239     /*
    00240      * Initialize it
    00241      */
    00242     pmnidt->idt.lpVtbl = &idtVtbl;
    00243
    00244     /*
    00245      * Call RegisterDragDrop
    00246      */
    00247     hres = (*(REGISTERDDPROC)gpfnOLERegisterDD)(*phwnd, (LPDROPTARGET)pmnidt);
    00248     if (!SUCCEEDED(hres)) {
    00249         RIPMSG1(RIP_WARNING, "__ClientRegisterDragDrop Failed:%#lx", hres);
    00250     }
    00251
    00252 BackToKernel:
    00253     return UserCallbackReturn(NULL, 0, hres);
    00254 }
    00255 /**************************************************************************\
    00256 * __ClientRevokeDragDrop
    00257 *
    00258 *
    00259 * 10/28/96 GerardoB     Created
    00260 \**************************************************************************/
    00261 DWORD __ClientRevokeDragDrop(HWND * phwnd)
    00262 {
    00263     HRESULT hres;
    00264
    00265     /*
    00266      * Call RevokeDragDrop
    00267      */
    00268     hres = (*(REVOKEDDPROC)gpfnOLERevokeDD)(*phwnd);
    00269     if (!SUCCEEDED(hres)) {
    00270         RIPMSG1(RIP_WARNING, "__ClientRevokeDragDrop Failed:%#lx", hres);
    00271     }
    00272
    00273     return UserCallbackReturn(NULL, 0, hres);
    00274 }
    00275 /**************************************************************************\
    00276 * LoadOLEOnce
    00277 *
    00278 *
    00279 * 10/31/96 GerardoB     Created
    00280 \**************************************************************************/
    00281 NTSTATUS LoadOLEOnce (void) {
    00282
    00283     NTSTATUS Status = STATUS_SUCCESS;
    00284     OLEINITIALIZEPROC pfnOLEOleInitialize;
    00285
    00286     /*
    00287      * These are the functions that we'll call.
    00288      */
    00289     GETPROCINFO gpi [] = {
    00290         {&((FARPROC)pfnOLEOleInitialize), (LPCSTR)"OleInitialize"},
    00291         {&gpfnOLEOleUninitialize, (LPCSTR)"OleUninitialize"},
    00292         {&gpfnOLERegisterDD, (LPCSTR)"RegisterDragDrop"},
    00293         {&gpfnOLERevokeDD, (LPCSTR)"RevokeDragDrop"},
    00294         {NULL, NULL}
    00295     };
    00296
    00297     GETPROCINFO * pgpi = gpi;
    00298
    00299     /*
    00300      * We should come here only once
    00301      */
    00302     UserAssert(ghinstOLE == NULL);
    00303
    00304     /*
    00305      * Load it
    00306      */
    00307     ghinstOLE = LoadLibrary(L"OLE32.DLL");
    00308     if (ghinstOLE == NULL) {
    00309         RIPMSG1(RIP_WARNING, "LoadOLEOnce: Failed to load OLE32.DLL: %#lx", GetLastError());
    00310         goto OLEWontLoad;
    00311     }
    00312
    00313     /*
    00314      * Get the address of all procs
    00315      */
    00316     while (pgpi->ppfn != NULL) {
    00317         *(pgpi->ppfn) = GetProcAddress(ghinstOLE, pgpi->lpsz);
    00318         if (*(pgpi->ppfn) == NULL) {
    00319             RIPMSG2(RIP_WARNING, "LoadOLEOnce: GetProcAddress failed: '%s': %#lx",
    00320                     pgpi->lpsz, GetLastError());
    00321             break;
    00322         }
    00323         pgpi++;
    00324     }
    00325
    00326     /*
    00327      * If it got all procs, call OleInitialize
    00328      */
    00329     if (pgpi->ppfn == NULL) {
    00330         Status = (*pfnOLEOleInitialize)(NULL);
    00331         if (SUCCEEDED(Status)) {
    00332             goto BackToKernel;
    00333         } else {
    00334             RIPMSG1(RIP_WARNING, "LoadOLEOnce: OleInitialize failed:%#lx", Status);
    00335         }
    00336     }
    00337
    00338     /*
    00339      * Something failed; NULL out all function pointers
    00340      *   free the library and mark hinstOLE so we won't comeback here
    00341      */
    00342     pgpi = gpi;
    00343     while (pgpi->ppfn != NULL) {
    00344         *(pgpi->ppfn) = NULL;
    00345         pgpi++;
    00346     }
    00347     FreeLibrary(ghinstOLE);
    00348
    00349 OLEWontLoad:
    00350     ghinstOLE = OLEWONTLOAD;
    00351     Status = STATUS_UNSUCCESSFUL;
    00352
    00353 BackToKernel:
    00354     return Status;
    00355 }
    00356 /**************************************************************************\
    00357 * __ClientLoadOLE
    00358 *
    00359 *
    00360 * 10/31/96 GerardoB     Created
    00361 \**************************************************************************/
    00362 DWORD __ClientLoadOLE (PVOID p) {
    00363
    00364     NTSTATUS Status;
    00365
    00366     UNREFERENCED_PARAMETER(p);
    00367
    00368     if (ghinstOLE == NULL) {
    00369         Status = LoadOLEOnce();
    00370     } else if (ghinstOLE == OLEWONTLOAD) {
    00371         Status = STATUS_UNSUCCESSFUL;
    00372     } else {
    00373         UserAssert(gpfnOLERegisterDD != NULL);
    00374         UserAssert(gpfnOLERevokeDD != NULL);
    00375         Status = STATUS_SUCCESS;
    00376     }
    00377
    00378     return UserCallbackReturn(NULL, 0, Status);
    00379 }
    00380