ole32: Use window property to store registered drop target.
This commit is contained in:
parent
5568f33db3
commit
2c80e14eec
|
@ -4156,7 +4156,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
|
|||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
OLEDD_UnInitialize();
|
||||
COMPOBJ_UninitProcess();
|
||||
RPC_UnregisterAllChannelHooks();
|
||||
COMPOBJ_DllList_Free();
|
||||
|
|
|
@ -57,13 +57,6 @@ WINE_DECLARE_DEBUG_CHANNEL(accel);
|
|||
* These are static/global variables and internal data structures that the
|
||||
* OLE module uses to maintain it's state.
|
||||
*/
|
||||
typedef struct tagDropTargetNode
|
||||
{
|
||||
HWND hwndTarget;
|
||||
IDropTarget* dropTarget;
|
||||
struct list entry;
|
||||
} DropTargetNode;
|
||||
|
||||
typedef struct tagTrackerWindowInfo
|
||||
{
|
||||
IDataObject* dataObject;
|
||||
|
@ -119,6 +112,10 @@ static const WCHAR OLEDD_DRAGTRACKERCLASS[] =
|
|||
static const WCHAR prop_olemenuW[] =
|
||||
{'P','R','O','P','_','O','L','E','M','e','n','u','D','e','s','c','r','i','p','t','o','r',0};
|
||||
|
||||
/* property to store IDropTarget pointer */
|
||||
static const WCHAR prop_oledroptarget[] =
|
||||
{'O','l','e','D','r','o','p','T','a','r','g','e','t','I','n','t','e','r','f','a','c','e',0};
|
||||
|
||||
static const WCHAR clsidfmtW[] =
|
||||
{'C','L','S','I','D','\\','{','%','0','8','x','-','%','0','4','x','-','%','0','4','x','-',
|
||||
'%','0','2','x','%','0','2','x','-','%','0','2','x','%','0','2','x','%','0','2','x','%','0','2','x',
|
||||
|
@ -126,11 +123,6 @@ static const WCHAR clsidfmtW[] =
|
|||
|
||||
static const WCHAR emptyW[] = { 0 };
|
||||
|
||||
/*
|
||||
* This is the head of the Drop target container.
|
||||
*/
|
||||
static struct list targetListHead = LIST_INIT(targetListHead);
|
||||
|
||||
/******************************************************************************
|
||||
* These are the prototypes of miscellaneous utility methods
|
||||
*/
|
||||
|
@ -159,21 +151,11 @@ extern void OLEClipbrd_Initialize(void);
|
|||
* These are the prototypes of the utility methods used for OLE Drag n Drop
|
||||
*/
|
||||
static void OLEDD_Initialize(void);
|
||||
static DropTargetNode* OLEDD_FindDropTarget(
|
||||
HWND hwndOfTarget);
|
||||
static void OLEDD_FreeDropTarget(DropTargetNode*, BOOL);
|
||||
static LRESULT WINAPI OLEDD_DragTrackerWindowProc(
|
||||
HWND hwnd,
|
||||
UINT uMsg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
static void OLEDD_TrackMouseMove(
|
||||
TrackerWindowInfo* trackerInfo);
|
||||
static void OLEDD_TrackStateChange(
|
||||
TrackerWindowInfo* trackerInfo);
|
||||
static LRESULT WINAPI OLEDD_DragTrackerWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
static void OLEDD_TrackMouseMove(TrackerWindowInfo* trackerInfo);
|
||||
static void OLEDD_TrackStateChange(TrackerWindowInfo* trackerInfo);
|
||||
static DWORD OLEDD_GetButtonState(void);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* OleBuildVersion [OLE32.@]
|
||||
*/
|
||||
|
@ -284,14 +266,22 @@ HRESULT WINAPI OleInitializeWOW(DWORD x, DWORD y) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/***
|
||||
* OLEDD_FindDropTarget()
|
||||
*
|
||||
* Returns IDropTarget pointer registered for this window.
|
||||
*/
|
||||
static inline IDropTarget* OLEDD_FindDropTarget(HWND hwnd)
|
||||
{
|
||||
return GetPropW(hwnd, prop_oledroptarget);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* RegisterDragDrop (OLE32.@)
|
||||
*/
|
||||
HRESULT WINAPI RegisterDragDrop(
|
||||
HWND hwnd,
|
||||
LPDROPTARGET pDropTarget)
|
||||
HRESULT WINAPI RegisterDragDrop(HWND hwnd, LPDROPTARGET pDropTarget)
|
||||
{
|
||||
DropTargetNode* dropTargetInfo;
|
||||
DWORD pid = 0;
|
||||
|
||||
TRACE("(%p,%p)\n", hwnd, pDropTarget);
|
||||
|
||||
|
@ -310,32 +300,20 @@ HRESULT WINAPI RegisterDragDrop(
|
|||
return DRAGDROP_E_INVALIDHWND;
|
||||
}
|
||||
|
||||
/*
|
||||
* First, check if the window is already registered.
|
||||
*/
|
||||
dropTargetInfo = OLEDD_FindDropTarget(hwnd);
|
||||
/* block register for other processes windows */
|
||||
GetWindowThreadProcessId(hwnd, &pid);
|
||||
if (pid != GetCurrentProcessId())
|
||||
{
|
||||
FIXME("register for another process windows is disabled\n");
|
||||
return DRAGDROP_E_INVALIDHWND;
|
||||
}
|
||||
|
||||
if (dropTargetInfo!=NULL)
|
||||
/* check if the window is already registered */
|
||||
if (OLEDD_FindDropTarget(hwnd))
|
||||
return DRAGDROP_E_ALREADYREGISTERED;
|
||||
|
||||
/*
|
||||
* If it's not there, we can add it. We first create a node for it.
|
||||
*/
|
||||
dropTargetInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(DropTargetNode));
|
||||
|
||||
if (dropTargetInfo==NULL)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
dropTargetInfo->hwndTarget = hwnd;
|
||||
|
||||
/*
|
||||
* Don't forget that this is an interface pointer, need to nail it down since
|
||||
* we keep a copy of it.
|
||||
*/
|
||||
IDropTarget_AddRef(pDropTarget);
|
||||
dropTargetInfo->dropTarget = pDropTarget;
|
||||
|
||||
list_add_tail(&targetListHead, &dropTargetInfo->entry);
|
||||
SetPropW(hwnd, prop_oledroptarget, pDropTarget);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -343,10 +321,9 @@ HRESULT WINAPI RegisterDragDrop(
|
|||
/***********************************************************************
|
||||
* RevokeDragDrop (OLE32.@)
|
||||
*/
|
||||
HRESULT WINAPI RevokeDragDrop(
|
||||
HWND hwnd)
|
||||
HRESULT WINAPI RevokeDragDrop(HWND hwnd)
|
||||
{
|
||||
DropTargetNode* dropTargetInfo;
|
||||
IDropTarget* droptarget;
|
||||
|
||||
TRACE("(%p)\n", hwnd);
|
||||
|
||||
|
@ -356,18 +333,12 @@ HRESULT WINAPI RevokeDragDrop(
|
|||
return DRAGDROP_E_INVALIDHWND;
|
||||
}
|
||||
|
||||
/*
|
||||
* First, check if the window is already registered.
|
||||
*/
|
||||
dropTargetInfo = OLEDD_FindDropTarget(hwnd);
|
||||
|
||||
/*
|
||||
* If it ain't in there, it's an error.
|
||||
*/
|
||||
if (dropTargetInfo==NULL)
|
||||
/* no registration data */
|
||||
if (!(droptarget = OLEDD_FindDropTarget(hwnd)))
|
||||
return DRAGDROP_E_NOTREGISTERED;
|
||||
|
||||
OLEDD_FreeDropTarget(dropTargetInfo, TRUE);
|
||||
IDropTarget_Release(droptarget);
|
||||
RemovePropW(hwnd, prop_oledroptarget);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -1885,57 +1856,6 @@ static void OLEDD_Initialize(void)
|
|||
RegisterClassW (&wndClass);
|
||||
}
|
||||
|
||||
/***
|
||||
* OLEDD_FreeDropTarget()
|
||||
*
|
||||
* Frees the drag and drop data structure
|
||||
*/
|
||||
static void OLEDD_FreeDropTarget(DropTargetNode *dropTargetInfo, BOOL release_drop_target)
|
||||
{
|
||||
list_remove(&dropTargetInfo->entry);
|
||||
if (release_drop_target) IDropTarget_Release(dropTargetInfo->dropTarget);
|
||||
HeapFree(GetProcessHeap(), 0, dropTargetInfo);
|
||||
}
|
||||
|
||||
/***
|
||||
* OLEDD_UnInitialize()
|
||||
*
|
||||
* Releases the OLE drag and drop data structures.
|
||||
*/
|
||||
void OLEDD_UnInitialize(void)
|
||||
{
|
||||
/*
|
||||
* Simply empty the list.
|
||||
*/
|
||||
while (!list_empty(&targetListHead))
|
||||
{
|
||||
DropTargetNode* curNode = LIST_ENTRY(list_head(&targetListHead), DropTargetNode, entry);
|
||||
OLEDD_FreeDropTarget(curNode, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* OLEDD_FindDropTarget()
|
||||
*
|
||||
* Finds information about the drop target.
|
||||
*/
|
||||
static DropTargetNode* OLEDD_FindDropTarget(HWND hwndOfTarget)
|
||||
{
|
||||
DropTargetNode* curNode;
|
||||
|
||||
/*
|
||||
* Iterate the list to find the HWND value.
|
||||
*/
|
||||
LIST_FOR_EACH_ENTRY(curNode, &targetListHead, DropTargetNode, entry)
|
||||
if (hwndOfTarget==curNode->hwndTarget)
|
||||
return curNode;
|
||||
|
||||
/*
|
||||
* If we get here, the item is not in the list
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***
|
||||
* OLEDD_DragTrackerWindowProc()
|
||||
*
|
||||
|
@ -2039,35 +1959,46 @@ static void OLEDD_TrackMouseMove(TrackerWindowInfo* trackerInfo)
|
|||
}
|
||||
else
|
||||
{
|
||||
DropTargetNode* newDropTargetNode = 0;
|
||||
|
||||
/*
|
||||
* If we changed window, we have to notify our old target and check for
|
||||
* the new one.
|
||||
*/
|
||||
if (trackerInfo->curDragTarget!=0)
|
||||
{
|
||||
if (trackerInfo->curDragTarget)
|
||||
IDropTarget_DragLeave(trackerInfo->curDragTarget);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure we're hovering over a window.
|
||||
*/
|
||||
if (hwndNewTarget!=0)
|
||||
if (hwndNewTarget)
|
||||
{
|
||||
/*
|
||||
* Find-out if there is a drag target under the mouse
|
||||
*/
|
||||
HWND nexttar = hwndNewTarget;
|
||||
HWND next_target_wnd = hwndNewTarget;
|
||||
IDropTarget *new_target;
|
||||
DWORD pid;
|
||||
|
||||
trackerInfo->curTargetHWND = hwndNewTarget;
|
||||
|
||||
do {
|
||||
newDropTargetNode = OLEDD_FindDropTarget(nexttar);
|
||||
} while (!newDropTargetNode && (nexttar = GetParent(nexttar)) != 0);
|
||||
if(nexttar) hwndNewTarget = nexttar;
|
||||
new_target = OLEDD_FindDropTarget(next_target_wnd);
|
||||
} while (!new_target && (next_target_wnd = GetParent(next_target_wnd)));
|
||||
|
||||
if (next_target_wnd) hwndNewTarget = next_target_wnd;
|
||||
|
||||
GetWindowThreadProcessId(hwndNewTarget, &pid);
|
||||
if (pid != GetCurrentProcessId())
|
||||
{
|
||||
FIXME("drop to another process window is unsupported\n");
|
||||
trackerInfo->curDragTargetHWND = 0;
|
||||
trackerInfo->curTargetHWND = 0;
|
||||
trackerInfo->curDragTarget = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
trackerInfo->curDragTargetHWND = hwndNewTarget;
|
||||
trackerInfo->curDragTarget = newDropTargetNode ? newDropTargetNode->dropTarget : 0;
|
||||
trackerInfo->curDragTarget = new_target;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is, notify it that we just dragged-in
|
||||
|
|
|
@ -290,6 +290,7 @@ static ATOM register_dummy_class(void)
|
|||
|
||||
static void test_Register_Revoke(void)
|
||||
{
|
||||
HANDLE prop;
|
||||
HRESULT hr;
|
||||
HWND hwnd;
|
||||
|
||||
|
@ -318,6 +319,9 @@ static void test_Register_Revoke(void)
|
|||
ok_ole_success(hr, "RegisterDragDrop");
|
||||
ok(droptarget_addref_called == 1, "DropTarget_AddRef should have been called once, not %d times\n", droptarget_addref_called);
|
||||
|
||||
prop = GetPropA(hwnd, "OleDropTargetInterface");
|
||||
ok(prop == &DropTarget, "expected IDropTarget pointer %p, got %p\n", &DropTarget, prop);
|
||||
|
||||
hr = RegisterDragDrop(hwnd, &DropTarget);
|
||||
ok(hr == DRAGDROP_E_ALREADYREGISTERED, "RegisterDragDrop with already registered hwnd should return DRAGDROP_E_ALREADYREGISTERED instead of 0x%08x\n", hr);
|
||||
|
||||
|
|
Loading…
Reference in New Issue