[PATCH] Use window property to store registered drop target

Nikolay Sivov nsivov at codeweavers.com
Mon May 17 17:21:49 CDT 2010


---
 dlls/ole32/compobj.c        |    1 -
 dlls/ole32/ole2.c           |  187 ++++++++++++++-----------------------------
 dlls/ole32/tests/dragdrop.c |    4 +
 3 files changed, 63 insertions(+), 129 deletions(-)

diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index 0fb074d..937f3d8 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -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();
diff --git a/dlls/ole32/ole2.c b/dlls/ole32/ole2.c
index 73a2d2d..41989f3 100644
--- a/dlls/ole32/ole2.c
+++ b/dlls/ole32/ole2.c
@@ -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
  */
@@ -158,22 +150,12 @@ 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 void OLEDD_Initialize(void);
+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;
 }
@@ -1886,57 +1857,6 @@ static void OLEDD_Initialize(void)
 }
 
 /***
- * 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()
  *
  * This method is the WindowProcedure of the drag n drop tracking
@@ -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)));
 
-      trackerInfo->curDragTargetHWND = hwndNewTarget;
-      trackerInfo->curDragTarget     = newDropTargetNode ? newDropTargetNode->dropTarget : 0;
+      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     = new_target;
+      }
 
       /*
        * If there is, notify it that we just dragged-in
diff --git a/dlls/ole32/tests/dragdrop.c b/dlls/ole32/tests/dragdrop.c
index e098354..55a5167 100644
--- a/dlls/ole32/tests/dragdrop.c
+++ b/dlls/ole32/tests/dragdrop.c
@@ -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);
 
-- 
1.5.6.5


--=-T9d94fBPrvDfW6LtSI2M--




More information about the wine-patches mailing list