[PATCH] RE: user32: Problem using SetClassLongW to subclass built-in control (Edit)

Hongbo Ni hongbo_ni at hotmail.com
Thu Jul 10 03:00:40 CDT 2008


Hi,

I have write a patch for the problem, please comment.

===========================================================================
--- wine-1.1.0-orig/dlls/user32/class.c 2008-06-28 00:24:42.000000000 +1000
+++ wine-1.1.0/dlls/user32/class.c      2008-07-10 17:35:11.000000000 +1000
@@ -906,9 +906,18 @@ static ULONG_PTR CLASS_SetClassLong( HWN
         retval = 0;  /* Old value is now meaningless anyway */
         break;
     case GCLP_WNDPROC:
-        retval = (ULONG_PTR)WINPROC_GetProc( class->winproc, unicode );
-        class->winproc = WINPROC_AllocProc( unicode ? NULL : (WNDPROC)newval,
-                                            unicode ? (WNDPROC)newval : NULL );
+        if( unicode && class->winproc == EDIT_winproc_handle )
+        {
+            retval = class->winproc;
+            /* if subclassing Edit class, WndProc must handle both Ansi and Unicode Message*/
+            class->winproc = WINPROC_AllocProc( (WNDPROC)newval, (WNDPROC)newval );
+        }
+        else
+        {
+            retval = (ULONG_PTR)WINPROC_GetProc( class->winproc, unicode );
+            class->winproc = WINPROC_AllocProc( unicode ? NULL : (WNDPROC)newval,
+                                                unicode ? (WNDPROC)newval : NULL );
+        }
         break;
     case GCLP_HBRBACKGROUND:
         retval = (ULONG_PTR)class->hbrBackground;

--- wine-1.1.0-orig/dlls/user32/winproc.c       2008-06-28 00:24:42.000000000 +1000
+++ wine-1.1.0/dlls/user32/winproc.c    2008-07-10 17:35:11.000000000 +1000
@@ -145,7 +145,7 @@ static inline WINDOWPROC *alloc_winproc(
     /* check if we already have a winproc for that function */
     if (!(proc = find_winproc( funcA, funcW )))
     {
-        if (funcA && funcW)
+        if (funcA && funcW && builtin_used < BUILTIN_WINPROCS )
         {
             assert( builtin_used < BUILTIN_WINPROCS );
             proc = &winproc_array[builtin_used++];

=====================================================================================
________________________________
> From: hongbo_ni at hotmail.com
> To: wine-devel at winehq.org
> Subject: user32: Problem using SetClassLongW to subclass built-in control (Edit)
> Date: Wed, 9 Jul 2008 22:06:22 +1000
> 
> Hi,
> 
> Summary: SetClassLongW(hEdit, GCL_WNDPROC,(DWORD)NewEditWndProc) in Wine differs from Windows.
> 
> Background:  when a standard built-in window class (such as Edit for example) is registered initially,
> the window system register the class with two Procedures (procA and ProcW) and assign a handle as
> WNDPROC to the class.  If a Edit window is created using CreateWindowExA, it will be an Ansi Window.
> If a Edit window is created using CreateWindowExW, it will be an Unicode Window. This fine in Wine.
> 
> Problem: I globally subclass the Edit class using SetClassLongW using following code
> ------------------------------------------------------------------------------------------------------------
>   HWND hEdit = CreateWindowExA(0,"Edit", "E1",WS_POPUP,0, 0, 1,1,NULL,NULL,NULL,NULL);
>   OldEditWndProc =(WNDPROC)SetClassLongW(hEdit, GCL_WNDPROC,(DWORD)NewEditWndProc);
> ------------------------------------------------------------------------------------------------------------
> After this subclass, Wine behaves different from Windows
> 
> In Windows: a new Edit windows created by CreateWindowsExA((0,"Edit",...) is a Still an Ansi Windows
>                    a new Edit windows created by CreateWindowsExW((0,"Edit",...) is a Unicode Windows
> 
> But in Wine, new Edit windows created by CreateWindowsExA or CreateWindowsExW are all Unicode Windows.
> I checked wine 1.1 source code , basically the call to
> SetClassLongW(hEdit, GCL_WNDPROC,(DWORD)NewEditWndProc) has set the Edit class proc to Unicode Only.
> So regardless how you create the Edit window, it will be Unicode window.
> 
> This is understandable but it's different form windows. causing my application to mis-behave.
> 
> More problem, the OldEditWndProc returned above is only the procW of Edit class, if we try to
> undo the subclass with
>        SetClassLongW(hEdit, GCL_WNDPROC,(DWORD)OldEditWndProc );
> the Edit class also lost it's procA.
> 
> Discussion: How wine could do the same as windows?
> 
> SetClassLongW(hEdit, GCL_WNDPROC,(DWORD)NewEditWndProc) should
> 
> 1. return the proc handle of the class, instead of procW.
> 
> 2. set both ProcA and ProcW of Edit class to NewEditWndProc.
>     so  NewEditWndProc need to handle both messages from Ansi and Unicode Edit control.
> 
> I don't know what is the best way to fix this. Please help.
> 
> I have posted a Test application on Bugzilla #14350, please try.
> 
> Regards
> Hongbo
> 
> 
> 
> 
> ________________________________
> Find out: SEEK Salary Centre Are you paid what you're worth? 

_________________________________________________________________
Are you paid what you're worth? Find out: SEEK Salary Centre
http://a.ninemsn.com.au/b.aspx?URL=http%3A%2F%2Fninemsn%2Eseek%2Ecom%2Eau%2Fcareer%2Dresources%2Fsalary%2Dcentre%2F%3Ftracking%3Dsk%3Ahet%3Asc%3Anine%3A0%3Ahot%3Atext&_t=764565661&_r=OCT07_endtext_salary&_m=EXT


More information about the wine-devel mailing list