Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

411 lines
11 KiB

/****************************** 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);
}