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

Generated on Sat May 15 19:40:47 2004 for test by doxygen 1.3.7