Listview: refcount the infoPtr

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Listview: refcount the infoPtr

Dimi Paun
Do we need to do this for other controls too?

ChangeLog
    Add refcounting to the listview to support destroying of
    the control from within notification messages.

--
Dimi Paun <[hidden email]>
Lattica, Inc.

Index: dlls/comctl32/listview.c
===================================================================
RCS file: /var/cvs/wine/dlls/comctl32/listview.c,v
retrieving revision 1.430
diff -u -p -r1.430 listview.c
--- dlls/comctl32/listview.c 13 Sep 2005 14:30:53 -0000 1.430
+++ dlls/comctl32/listview.c 26 Sep 2005 21:56:59 -0000
@@ -309,6 +309,7 @@ typedef struct tagLISTVIEW_INFO
   WCHAR szSearchParam[ MAX_PATH ];
   BOOL bIsDrawing;
   INT nMeasureItemHeight;
+  INT nRefCount;
 } LISTVIEW_INFO;
 
 /*
@@ -7526,6 +7527,7 @@ static LRESULT LISTVIEW_Create(HWND hwnd
   infoPtr = (LISTVIEW_INFO *)Alloc(sizeof(LISTVIEW_INFO));
   if (!infoPtr) return -1;
 
+  infoPtr->nRefCount = 1;
   SetWindowLongPtrW(hwnd, 0, (DWORD_PTR)infoPtr);
 
   infoPtr->hwndSelf = hwnd;
@@ -8271,6 +8273,25 @@ static LRESULT LISTVIEW_NCDestroy(LISTVI
   /* delete all items */
   LISTVIEW_DeleteAllItems(infoPtr);
 
+  infoPtr->nRefCount--;
+
+  return 0;
+}
+
+/***
+ * DESCRIPTION:
+ * Frees the resources associated with the listview control.
+ *
+ * PARAMETER(S):
+ * [I] infoPtr : valid pointer to the listview structure
+ *
+ * RETURN:
+ * None
+ */
+static void LISTVIEW_Free(LISTVIEW_INFO *infoPtr)
+{
+  SetWindowLongPtrW(infoPtr->hwndSelf, 0, 0);
+
   /* destroy data structure */
   DPA_Destroy(infoPtr->hdpaItems);
   DPA_Destroy(infoPtr->hdpaPosX);
@@ -8294,14 +8315,11 @@ static LRESULT LISTVIEW_NCDestroy(LISTVI
   if (infoPtr->hDefaultFont) DeleteObject(infoPtr->hDefaultFont);
   if (infoPtr->clrBk != CLR_NONE) DeleteObject(infoPtr->hBkBrush);
 
-  SetWindowLongPtrW(infoPtr->hwndSelf, 0, 0);
-
   /* free listview info pointer*/
   Free(infoPtr);
-
-  return 0;
 }
 
+
 /***
  * DESCRIPTION:
  * Handles notifications from header.
@@ -8972,19 +8990,12 @@ static INT LISTVIEW_StyleChanged(LISTVIE
 
 /***
  * DESCRIPTION:
- * Window procedure of the listview control.
+ * Dispatches message to the appropriate function.
  *
  */
 static LRESULT WINAPI
-LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+LISTVIEW_Dispatch(LISTVIEW_INFO *infoPtr, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
-  LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongPtrW(hwnd, 0);
-
-  TRACE("(uMsg=%x wParam=%x lParam=%lx)\n", uMsg, wParam, lParam);
-
-  if (!infoPtr && (uMsg != WM_CREATE))
-    return DefWindowProcW(hwnd, uMsg, wParam, lParam);
-
   switch (uMsg)
   {
   case LVM_APPROXIMATEVIEWRECT:
@@ -9153,7 +9164,7 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg
 
   case LVM_GETTOOLTIPS:
     if( !infoPtr->hwndToolTip )
-        infoPtr->hwndToolTip = COMCTL32_CreateToolTip( hwnd );
+        infoPtr->hwndToolTip = COMCTL32_CreateToolTip( infoPtr->hwndSelf );
     return (LRESULT)infoPtr->hwndToolTip;
 
   case LVM_GETTOPINDEX:
@@ -9341,9 +9352,6 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg
   case WM_COMMAND:
     return LISTVIEW_Command(infoPtr, wParam, lParam);
 
-  case WM_CREATE:
-    return LISTVIEW_Create(hwnd, (LPCREATESTRUCTW)lParam);
-
   case WM_DESTROY:
     return LISTVIEW_Destroy(infoPtr);
 
@@ -9447,7 +9455,7 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg
 
   case WM_MOUSEWHEEL:
       if (wParam & (MK_SHIFT | MK_CONTROL))
-          return DefWindowProcW(hwnd, uMsg, wParam, lParam);
+          return DefWindowProcW(infoPtr->hwndSelf, uMsg, wParam, lParam);
       return LISTVIEW_MouseWheel(infoPtr, (short int)HIWORD(wParam));
 
   case WM_WINDOWPOSCHANGED:
@@ -9474,7 +9482,7 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg
   LISTVIEW_UpdateSize(infoPtr);
   LISTVIEW_UpdateScroll(infoPtr);
       }
-      return DefWindowProcW(hwnd, uMsg, wParam, lParam);
+      return DefWindowProcW(infoPtr->hwndSelf, uMsg, wParam, lParam);
 
 /* case WM_WININICHANGE: */
 
@@ -9484,13 +9492,43 @@ LISTVIEW_WindowProc(HWND hwnd, UINT uMsg
 
   fwd_msg:
     /* call default window procedure */
-    return DefWindowProcW(hwnd, uMsg, wParam, lParam);
+    return DefWindowProcW(infoPtr->hwndSelf, uMsg, wParam, lParam);
   }
 
 }
 
 /***
  * DESCRIPTION:
+ * Window procedure of the listview control.
+ *
+ */
+static LRESULT WINAPI
+LISTVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+    LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongPtrW(hwnd, 0);
+    LRESULT result;
+
+    TRACE("(uMsg=%x wParam=%x lParam=%lx)\n", uMsg, wParam, lParam);
+
+    if (uMsg == WM_CREATE)
+        return LISTVIEW_Create(hwnd, (LPCREATESTRUCTW)lParam);
+
+    if (!infoPtr)
+        return DefWindowProcW(hwnd, uMsg, wParam, lParam);
+
+    infoPtr->nRefCount++;
+    result = LISTVIEW_Dispatch(infoPtr, uMsg, wParam, lParam);
+    infoPtr->nRefCount--;
+
+    if (infoPtr->nRefCount == 0)
+        LISTVIEW_Free(infoPtr);
+  
+    return result;
+}
+
+
+/***
+ * DESCRIPTION:
  * Registers the window class.
  *
  * PARAMETER(S):


Reply | Threaded
Open this post in threaded view
|

Re: Listview: refcount the infoPtr (Dropped patch)

Troy Rollo
On Tue, 27 Sep 2005 08:00, Dimi Paun wrote:
> Do we need to do this for other controls too?
>
> ChangeLog
>     Add refcounting to the listview to support destroying of
>     the control from within notification messages.
<http://www.winehq.org/pipermail/wine-patches/2005-September/021003.html>

This patch does not appear to have gone in, but it fixes a SEGV that occurs
quite frequently when you double-click on a folder in the file open dialog.
Is there a (good) reason it hasn't gone in?