EnumProps* patch

Andreas Mohr a.mohr at mailto.de
Fri Apr 20 11:53:54 CDT 2001


Hi all,

whoever wrote EnumProps*()... didn't *really* test it ;-)

(hmm, OTOH ChangeLog suggests that nobody ever did anything about that stuff,
and cvs log is *completely* blank on this...)

At least EnumPropsA() retrieves the real string value in case an atom is given
to pass it to the function (I added a test for that to a program of mine).
So I assumed that every Win32 implementation does this.

EnumProps16 seems to be a different matter, though.
My old Win16 docu says that it passes either string *or* atom.
So the current implementation seems to be correct here.

Oh, BTW, about that "didn't *really* test it":
Guess what the difference between EnumProps*() and EnumPropsEx*() is ??
The parameter count of the callback function is *different*, of course !!

- make sure that we really use the correct amount of parameters each time
  for the callback function
- always pass strings instead of atoms to Win32 enum proc
- fix trace crash due to string format displaying of atom (LOWORD only) handle

This fixes SpyGuru window properties display.

My God, that was an awful lot of brokenness.
I'm doing an educated guess that this stuff has never been working before...

Andreas Mohr
-------------- next part --------------
Determining best CVS host...
Using CVSROOT :pserver:cvs at wine.codeweavers.com:/home/cvs/wine
Index: windows/property.c
===================================================================
RCS file: /home/cvs/wine/wine/windows/property.c,v
retrieving revision 1.11
diff -u -r1.11 property.c
--- windows/property.c	2001/02/23 01:13:42	1.11
+++ windows/property.c	2001/04/20 16:44:29
@@ -287,8 +287,15 @@
         /* function removes the current property.    */
         next = prop->next;
 
-        TRACE("  Callback: handle=%08x str='%s'\n",
-                      prop->handle, prop->string );
+	/* SDK docu seems to suggest that EnumProps16 does not retrieve
+	 * the string in case of an atom handle, in contrast to Win32 */
+
+        if (HIWORD(prop->string))
+            TRACE("  Callback: handle=%08x str='%s'\n",
+                prop->handle, prop->string );
+        else
+            TRACE("  Callback: handle=%08x str=#%04x\n",
+		prop->handle, LOWORD(prop->string) );
         ret = func( hwnd, SEGPTR_GET(prop->string), prop->handle );
         if (!ret) break;
     }
@@ -297,21 +304,58 @@
 }
 
 
-/***********************************************************************
- *		EnumPropsA (USER32.@)
- */
-INT WINAPI EnumPropsA( HWND hwnd, PROPENUMPROCA func )
+#define MAX_ATOM_LEN              255
+INT PROPS_EnumPropsA( HWND hwnd, PROPENUMPROCA func, LPARAM lParam, BOOL ex )
 {
-    return EnumPropsExA( hwnd, (PROPENUMPROCEXA)func, 0 );
+    PROPERTY *prop, *next;
+    WND *pWnd;
+    INT ret = -1;
+    char atomStr[MAX_ATOM_LEN+1];
+    char *pStr;
+
+    TRACE("%04x %08x %08lx%s\n",
+                  hwnd, (UINT)func, lParam, ex ? " [Ex]" : "" );
+    if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
+    for (prop = pWnd->pProp; (prop); prop = next /* yes, "next" is ok */)
+    {
+        /* Already get the next in case the callback */
+        /* function removes the current property.    */
+        next = prop->next;
+
+	if (!(HIWORD(prop->string)))
+	{ /* get "real" string the atom points to.
+	   * This seems to be done for Win32 only */
+	    if (!(GlobalGetAtomNameA((ATOM)LOWORD(prop->string), atomStr, MAX_ATOM_LEN+1)))
+	    {
+		ERR("huh ? Atom %04x not an atom ??\n",
+				(ATOM)LOWORD(prop->string));
+		atomStr[0] = '\0';
+	    }
+	    pStr = atomStr;
+	}
+	else
+	    pStr = prop->string;
+
+        TRACE("  Callback: handle=%08x str='%s'\n",
+            prop->handle, prop->string );
+
+	if (ex) /* EnumPropsEx has an additional lParam !! */
+            ret = func( hwnd, pStr, prop->handle, lParam );
+	else
+            ret = func( hwnd, pStr, prop->handle );
+        if (!ret) break;
+    }
+    WIN_ReleaseWndPtr(pWnd);
+    return ret;
 }
 
 
 /***********************************************************************
- *		EnumPropsW (USER32.@)
+ *		EnumPropsA (USER32.@)
  */
-INT WINAPI EnumPropsW( HWND hwnd, PROPENUMPROCW func )
+INT WINAPI EnumPropsA( HWND hwnd, PROPENUMPROCA func )
 {
-    return EnumPropsExW( hwnd, (PROPENUMPROCEXW)func, 0 );
+    return PROPS_EnumPropsA(hwnd, func, 0, FALSE);
 }
 
 
@@ -320,22 +364,52 @@
  */
 INT WINAPI EnumPropsExA(HWND hwnd, PROPENUMPROCEXA func, LPARAM lParam)
 {
+    return PROPS_EnumPropsA(hwnd, (PROPENUMPROCA)func, lParam, TRUE);
+}
+
+
+INT PROPS_EnumPropsW( HWND hwnd, PROPENUMPROCW func, LPARAM lParam, BOOL ex )
+{
     PROPERTY *prop, *next;
     WND *pWnd;
     INT ret = -1;
+    char atomStr[MAX_ATOM_LEN+1];
+    char *pStr;
+    LPWSTR strW;
 
-    TRACE("%04x %08x %08lx\n",
-                  hwnd, (UINT)func, lParam );
+    TRACE("%04x %08x %08lx%s\n",
+                  hwnd, (UINT)func, lParam, ex ? " [Ex]" : "" );
     if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
-    for (prop = pWnd->pProp; (prop); prop = next)
+    for (prop = pWnd->pProp; (prop); prop = next /* yes, "next" is ok */)
     {
         /* Already get the next in case the callback */
         /* function removes the current property.    */
         next = prop->next;
 
+	if (!(HIWORD(prop->string)))
+	{ /* get "real" string the atom points to.
+	   * This seems to be done for Win32 only */
+	    if (!(GlobalGetAtomNameA((ATOM)LOWORD(prop->string), atomStr, MAX_ATOM_LEN+1)))
+	    {
+		ERR("huh ? Atom %04x not an atom ??\n",
+				(ATOM)LOWORD(prop->string));
+		atomStr[0] = '\0';
+	    }
+	    pStr = atomStr;
+	}
+	else
+	    pStr = prop->string;
+
         TRACE("  Callback: handle=%08x str='%s'\n",
-                      prop->handle, prop->string );
-        ret = func( hwnd, prop->string, prop->handle, lParam );
+            prop->handle, prop->string );
+
+        strW = HEAP_strdupAtoW( GetProcessHeap(), 0, pStr );
+
+	if (ex) /* EnumPropsEx has an additional lParam !! */
+            ret = func( hwnd, strW, prop->handle, lParam );
+	else
+            ret = func( hwnd, strW, prop->handle );
+        HeapFree( GetProcessHeap(), 0, strW );
         if (!ret) break;
     }
     WIN_ReleaseWndPtr(pWnd);
@@ -344,36 +418,17 @@
 
 
 /***********************************************************************
+ *		EnumPropsW (USER32.@)
+ */
+INT WINAPI EnumPropsW( HWND hwnd, PROPENUMPROCW func )
+{
+    return PROPS_EnumPropsW(hwnd, func, 0, FALSE);
+}
+
+/***********************************************************************
  *		EnumPropsExW (USER32.@)
  */
 INT WINAPI EnumPropsExW(HWND hwnd, PROPENUMPROCEXW func, LPARAM lParam)
 {
-    PROPERTY *prop, *next;
-    WND *pWnd;
-    INT ret = -1;
-
-    TRACE("%04x %08x %08lx\n",
-                  hwnd, (UINT)func, lParam );
-    if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
-    for (prop = pWnd->pProp; (prop); prop = next)
-    {
-        /* Already get the next in case the callback */
-        /* function removes the current property.    */
-        next = prop->next;
-
-        TRACE("  Callback: handle=%08x str='%s'\n",
-                      prop->handle, prop->string );
-        if (HIWORD(prop->string))
-        {
-            LPWSTR str = HEAP_strdupAtoW( GetProcessHeap(), 0, prop->string );
-            ret = func( hwnd, str, prop->handle, lParam );
-            HeapFree( GetProcessHeap(), 0, str );
-        }
-        else
-            ret = func( hwnd, (LPCWSTR)(UINT)LOWORD( prop->string ),
-                        prop->handle, lParam );
-        if (!ret) break;
-    }
-    WIN_ReleaseWndPtr(pWnd);
-    return ret;
+    return PROPS_EnumPropsW(hwnd, (PROPENUMPROCW)func, 0, TRUE);
 }


More information about the wine-patches mailing list