|
|
/****************************** Module Header ******************************\
* Module Name: menudd.c * * Copyright (c) 1985 - 1999, Microsoft Corporation * * Menu drag and drop - client * * History: * 10/29/96 GerardoB Created \***************************************************************************/ #include "precomp.h"
#pragma hdrstop
/*
* OLE's GUID initialization. */ #include "initguid.h"
/*
* Macro to cast OLE's IDropTarget pointer to internal pointer. */ #define PMNIDT(pdt) ((PMNIDROPTARGET)pdt)
/*
* The mndt* functions implement the IDropTarget interface. */ /**************************************************************************\
* mndtAddRef * * 10/28/96 GerardoB Created \**************************************************************************/ ULONG mndtAddRef( LPDROPTARGET pdt) { return ++(PMNIDT(pdt)->dwRefCount); }
/**************************************************************************\
* mndtQueryInterface * * 10/28/96 GerardoB Created \**************************************************************************/ HRESULT mndtQueryInterface( LPDROPTARGET pdt, REFIID riid, PVOID * ppvObj) { if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDropTarget)) { mndtAddRef(pdt); *ppvObj = pdt; return NOERROR; } else { return E_NOINTERFACE; } }
/**************************************************************************\
* mndtRelease * * 10/28/96 GerardoB Created \**************************************************************************/ ULONG mndtRelease( LPDROPTARGET pdt) { if (--(PMNIDT(pdt)->dwRefCount) != 0) { return PMNIDT(pdt)->dwRefCount; }
UserLocalFree(pdt);
return NOERROR; }
/**************************************************************************\
* mndtDragOver * * 10/28/96 GerardoB Created \**************************************************************************/ HRESULT mndtDragOver( LPDROPTARGET pdt, DWORD grfKeyState, POINTL ptl, LPDWORD pdwEffect) { MNDRAGOVERINFO mndoi; MENUGETOBJECTINFO mngoi;
/*
* Get the dragover info for the selection corresponding to this point */ if (!NtUserMNDragOver((POINT *)&ptl, &mndoi)) { RIPMSG0(RIP_WARNING, "mndtDragOver: NtUserDragOver failed"); *pdwEffect = DROPEFFECT_NONE; return NOERROR; }
/*
* If not switching items or crossing gap boundaries, pass the * the drag over. */ if (!(mndoi.dwFlags & MNGOF_CROSSBOUNDARY)) { if (PMNIDT(pdt)->pidt != NULL) { return PMNIDT(pdt)->pidt->lpVtbl->DragOver(PMNIDT(pdt)->pidt, grfKeyState, ptl, pdwEffect); } } else { /*
* DragLeave and Release the current item, if any */ if (PMNIDT(pdt)->pidt != NULL) { PMNIDT(pdt)->pidt->lpVtbl->DragLeave(PMNIDT(pdt)->pidt); PMNIDT(pdt)->pidt->lpVtbl->Release(PMNIDT(pdt)->pidt); PMNIDT(pdt)->pidt = NULL; }
/*
* If an item is selected, Get the interface for it */ if (mndoi.uItemIndex != MFMWFP_NOITEM) { mngoi.hmenu = mndoi.hmenu; mngoi.dwFlags = mndoi.dwFlags & MNGOF_GAP; mngoi.uPos = mndoi.uItemIndex; mngoi.riid = (PVOID)&IID_IDropTarget; mngoi.pvObj = NULL;
if (MNGO_NOERROR == SendMessage(mndoi.hwndNotify, WM_MENUGETOBJECT, 0, (LPARAM)&mngoi)) { PMNIDT(pdt)->pidt = mngoi.pvObj; } }
/*
* If we got a new interface, AddRef and DragEnter it. */ if (PMNIDT(pdt)->pidt != NULL) { PMNIDT(pdt)->pidt->lpVtbl->AddRef(PMNIDT(pdt)->pidt); return PMNIDT(pdt)->pidt->lpVtbl->DragEnter(PMNIDT(pdt)->pidt, PMNIDT(pdt)->pido, grfKeyState, ptl, pdwEffect); } }
*pdwEffect = DROPEFFECT_NONE; return NOERROR; }
/**************************************************************************\
* mndtDragEnter * * 10/28/96 GerardoB Created \**************************************************************************/ HRESULT mndtDragEnter( LPDROPTARGET pdt, LPDATAOBJECT pdo, DWORD grfKeyState, POINTL ptl, LPDWORD pdwEffect) { /*
* Save the IDataObject. */ PMNIDT(pdt)->pido = pdo;
/*
* DragEnter is the same as a DragOver; only that we will never fail it. */ mndtDragOver(pdt, grfKeyState, ptl, pdwEffect);
return NOERROR; }
/**************************************************************************\
* mndtDragLeave * * 10/28/96 GerardoB Created \**************************************************************************/ HRESULT mndtDragLeave( LPDROPTARGET pdt) { /*
* Let the kernel mode clean up. */ NtUserMNDragLeave();
/*
* DragLeave and Release the current item, if any. */ if (PMNIDT(pdt)->pidt != NULL) { PMNIDT(pdt)->pidt->lpVtbl->DragLeave(PMNIDT(pdt)->pidt); PMNIDT(pdt)->pidt->lpVtbl->Release(PMNIDT(pdt)->pidt); PMNIDT(pdt)->pidt = NULL; }
return NOERROR; }
/**************************************************************************\
* mndtDrop * * 10/28/96 GerardoB Created \**************************************************************************/ HRESULT mndtDrop( LPDROPTARGET pdt, LPDATAOBJECT pdo, DWORD grfKeyState, POINTL ptl, LPDWORD pdwEffect) { HRESULT hres;
/*
* If we got a target, pass the drop and release it. */ if (PMNIDT(pdt)->pidt != NULL) { hres = PMNIDT(pdt)->pidt->lpVtbl->Drop(PMNIDT(pdt)->pidt, pdo, grfKeyState, ptl, pdwEffect); PMNIDT(pdt)->pidt->lpVtbl->Release(PMNIDT(pdt)->pidt); PMNIDT(pdt)->pidt = NULL; } else { *pdwEffect = DROPEFFECT_NONE; hres = NOERROR; }
/*
* Clean up. */ mndtDragLeave(pdt);
return hres; }
/**************************************************************************\
* Drop target VTable * \**************************************************************************/ IDropTargetVtbl idtVtbl = { mndtQueryInterface, mndtAddRef, mndtRelease, mndtDragEnter, mndtDragOver, mndtDragLeave, mndtDrop };
/**************************************************************************\
* __ClientRegisterDragDrop * * 10/28/96 GerardoB Created \**************************************************************************/ DWORD __ClientRegisterDragDrop( HWND * phwnd) { HRESULT hres = STATUS_UNSUCCESSFUL; PMNIDROPTARGET pmnidt;
/*
* Allocate the IDropTarget interface struct & additional data. */ pmnidt = (PMNIDROPTARGET)UserLocalAlloc(HEAP_ZERO_MEMORY, sizeof(MNIDROPTARGET)); if (pmnidt == NULL) { RIPMSG0(RIP_WARNING, "__ClientRegisterDragDrop allocation Failed"); hres = STATUS_UNSUCCESSFUL; goto BackToKernel; }
/*
* Initialize it */ pmnidt->idt.lpVtbl = &idtVtbl;
/*
* Call RegisterDragDrop */ hres = (*(REGISTERDDPROC)gpfnOLERegisterDD)(*phwnd, (LPDROPTARGET)pmnidt); if (!SUCCEEDED(hres)) { RIPMSG1(RIP_WARNING, "__ClientRegisterDragDrop Failed:%#lx", hres); }
BackToKernel: return UserCallbackReturn(NULL, 0, hres); }
/**************************************************************************\
* __ClientRevokeDragDrop * * * 10/28/96 GerardoB Created \**************************************************************************/ DWORD __ClientRevokeDragDrop( HWND * phwnd) { HRESULT hres;
/*
* Call RevokeDragDrop. */ hres = (*(REVOKEDDPROC)gpfnOLERevokeDD)(*phwnd); if (!SUCCEEDED(hres)) { RIPMSG1(RIP_WARNING, "__ClientRevokeDragDrop Failed: 0x%x", hres); }
return UserCallbackReturn(NULL, 0, hres); }
/**************************************************************************\
* LoadOLEOnce * * * 10/31/96 GerardoB Created \**************************************************************************/ NTSTATUS LoadOLEOnce( VOID) { NTSTATUS Status; OLEINITIALIZEPROC pfnOLEOleInitialize;
/*
* These are the functions that we'll call. */ GETPROCINFO gpi [] = { {&((FARPROC)pfnOLEOleInitialize), (LPCSTR)"OleInitialize"}, {&gpfnOLEOleUninitialize, (LPCSTR)"OleUninitialize"}, {&gpfnOLERegisterDD, (LPCSTR)"RegisterDragDrop"}, {&gpfnOLERevokeDD, (LPCSTR)"RevokeDragDrop"}, {NULL, NULL} };
GETPROCINFO * pgpi = gpi;
/*
* We should come here only once */ UserAssert(ghinstOLE == NULL);
/*
* Load it */ ghinstOLE = LoadLibrary(L"OLE32.DLL"); if (ghinstOLE == NULL) { RIPMSG1(RIP_WARNING, "LoadOLEOnce: Failed to load OLE32.DLL: %#lx", GetLastError()); goto OLEWontLoad; }
/*
* Get the address of all procs */ while (pgpi->ppfn != NULL) { *(pgpi->ppfn) = GetProcAddress(ghinstOLE, pgpi->lpsz); if (*(pgpi->ppfn) == NULL) { RIPMSG2(RIP_WARNING, "LoadOLEOnce: GetProcAddress failed: '%s': %#lx", pgpi->lpsz, GetLastError()); break; } pgpi++; }
/*
* If it got all procs, call OleInitialize. */ if (pgpi->ppfn == NULL) { Status = (*pfnOLEOleInitialize)(NULL); if (SUCCEEDED(Status)) { goto BackToKernel; } else { RIPMSG1(RIP_WARNING, "LoadOLEOnce: OleInitialize failed:%#lx", Status); } }
/*
* Something failed; NULL out all function pointers, free the library, * and mark ghinstOLE so we won't come back here. */ pgpi = gpi; while (pgpi->ppfn != NULL) { *(pgpi->ppfn) = NULL; pgpi++; } FreeLibrary(ghinstOLE);
OLEWontLoad: ghinstOLE = OLEWONTLOAD; Status = STATUS_UNSUCCESSFUL;
BackToKernel: return Status; }
/**************************************************************************\
* __ClientLoadOLE * * * 10/31/96 GerardoB Created \**************************************************************************/ DWORD __ClientLoadOLE( PVOID p) {
NTSTATUS Status;
UNREFERENCED_PARAMETER(p);
if (ghinstOLE == NULL) { Status = LoadOLEOnce(); } else if (ghinstOLE == OLEWONTLOAD) { Status = STATUS_UNSUCCESSFUL; } else { UserAssert(gpfnOLERegisterDD != NULL); UserAssert(gpfnOLERevokeDD != NULL); Status = STATUS_SUCCESS; }
return UserCallbackReturn(NULL, 0, Status); }
|