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

2008-07-14 Thread Hongbo Ni

> > ==>
> >  > # Patch> > 
> > ==>
> >  > --- wine-1.1.1-orig/dlls/user32/win.c 2008-07-12 01:55:55.0 
> > +1000> > +++ wine-1.1.1/dlls/user32/win.c 2008-07-14 16:49:21.0 
> > +1000> > @@ -173,6 +173,13 @@ static WND *create_window_handle( HWND p> > 
> > win->owner = full_owner;> > win->class = class;> > win->winproc = 
> > get_class_winproc( class );> > + /* This is a window hack - When builtin 
> > Edit class has been subclassed by SetClassLong(Ptr)W */> > + /* If creating 
> > ansi Edit window & the class does not have a ansi proc, use unicode proc as 
> > ansi */> > + if(!unicode && !IS_INTRESOURCE(name) && !strcmpiW( name, 
> > EDIT_builtin_class.name )> > + && WINPROC_IsUnicode( win->winproc, 0 ) && 
> > WINPROC_IsUnicode( win->winproc, 1 ))> > + {> > + win->winproc = 
> > WINPROC_AllocProc((WNDPROC)WINPROC_GetProc( win->winproc, 1 ), NULL);> > + 
> > }> > It doesn't seem likely that this behaviour just applies to edit> 
> > controls. More likely, it applies to all builtin classes.> > -- > Rob 
> > Shearman
 
Yes you are right, this behaviour applies to all builtin classes. I can either 
 
1. add more strcmpiW to compare with all the class names, 

   This can slow down create_window_handle() a little bit.
 
or
2. prove that there is no need for other builtin classes.
 
   The major difference before Edit and other builtin controls is: the Text in 
other builtin control does
   not interact with user, the WM_SETTEXT message do A->W conversion, 
WM_GETTEXT do a 
   W->A conversion, it can get same string back.  so current wine can handle it.
 
  The Edit control interact with user and input system, W->A conversion of 
SendMessageA(WM_GETTEXT)
  will not get eact the same string as user entered (eg CJK text). So if we 
create a Ansi Edit window, we do
  not want W->A  conversion. That is why my patch is needed to make Edit window 
a Ansi window.
 
So what do you think we should do?
 
Regards
Hongbo
_
It's simple! Sell your car for just $40 at CarPoint.com.au
http://a.ninemsn.com.au/b.aspx?URL=http%3A%2F%2Fsecure%2Dau%2Eimrworldwide%2Ecom%2Fcgi%2Dbin%2Fa%2Fci%5F450304%2Fet%5F2%2Fcg%5F801459%2Fpi%5F1004813%2Fai%5F859641&_t=762955845&_r=tig_OCT07&_m=EXT


Re: [PATCH2+TEST] RE: user32: Problem using SetClassLongW to subclass built-in control (Edit)

2008-07-14 Thread Rob Shearman
2008/7/14 Hongbo Ni <[EMAIL PROTECTED]>:
>
> Now I have fixed the problem, or corrected to window behaviour. Included is
> the Patch, Test and Debug (play with windows). Can anyone please test or 
> comment ?
>
> Regards
> Hongbo Ni
>
> ==
> # Patch
> ==
> --- wine-1.1.1-orig/dlls/user32/win.c   2008-07-12 01:55:55.0 +1000
> +++ wine-1.1.1/dlls/user32/win.c2008-07-14 16:49:21.0 +1000
> @@ -173,6 +173,13 @@ static WND *create_window_handle( HWND p
> win->owner  = full_owner;
> win->class  = class;
> win->winproc= get_class_winproc( class );
> +/* This is a window hack - When builtin Edit class has been subclassed 
> by SetClassLong(Ptr)W   */
> +/* If creating ansi Edit window & the class does not have a ansi proc, 
> use unicode proc as ansi */
> +if(!unicode && !IS_INTRESOURCE(name) && !strcmpiW( name, 
> EDIT_builtin_class.name )
> +   && WINPROC_IsUnicode( win->winproc, 0 ) &&  WINPROC_IsUnicode( 
> win->winproc, 1 ))
> +{
> +win->winproc = WINPROC_AllocProc((WNDPROC)WINPROC_GetProc( 
> win->winproc, 1 ), NULL);
> +}

It doesn't seem likely that this behaviour just applies to edit
controls. More likely, it applies to all builtin classes.

-- 
Rob Shearman




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

2008-07-14 Thread Hongbo Ni

Hello,

Now I have fixed the problem, or corrected to window behaviour. Included is
the Patch, Test and Debug (play with windows). Can anyone please test or 
comment ?

Regards
Hongbo Ni

==
# Patch 
==
--- wine-1.1.1-orig/dlls/user32/win.c   2008-07-12 01:55:55.0 +1000
+++ wine-1.1.1/dlls/user32/win.c2008-07-14 16:49:21.0 +1000
@@ -173,6 +173,13 @@ static WND *create_window_handle( HWND p
 win->owner  = full_owner;
 win->class  = class;
 win->winproc= get_class_winproc( class );
+/* This is a window hack - When builtin Edit class has been subclassed by 
SetClassLong(Ptr)W   */
+/* If creating ansi Edit window & the class does not have a ansi proc, use 
unicode proc as ansi */
+if(!unicode && !IS_INTRESOURCE(name) && !strcmpiW( name, 
EDIT_builtin_class.name )
+   && WINPROC_IsUnicode( win->winproc, 0 ) &&  WINPROC_IsUnicode( 
win->winproc, 1 ))
+{
+win->winproc = WINPROC_AllocProc((WNDPROC)WINPROC_GetProc( 
win->winproc, 1 ), NULL);
+}
 win->dwMagic= WND_MAGIC;
 win->cbWndExtra = extra_bytes;
 if (WINPROC_IsUnicode( win->winproc, unicode )) win->flags |= 
WIN_ISUNICODE;

==
# Debug - following debug shows the window hack 
#>>show var: is value show by the MSVC debuger
==
WNDPROC EditWndProcA=NULL, EditClassProcA=NULL;
WNDPROC EditWndProcW=NULL, EditClassProcW=NULL;
HWND hEditWnd1,hEditWnd2;
static const CHAR classNameA[] = "Edit";
static const WCHAR classNameW[] = {'E','d','i','t',0};
int i=0;
HWND hEditWnd0 = CreateWindowExA(0,classNameA, NULL,WS_POPUP,0, 0, 1, 
1,NULL,NULL,hInst,NULL);
EditClassProcA =(WNDPROC)GetClassLongPtrA(hEditWnd0, GCLP_WNDPROC);
EditClassProcW =(WNDPROC)GetClassLongPtrW(hEditWnd0, GCLP_WNDPROC);
>>show var: EditClassProcA=0x77246feb  EditClassProcW=0x7726f52f

EditWndProcA =(WNDPROC)GetWindowLongPtrA(hEditWnd0, GWLP_WNDPROC);
EditWndProcW =(WNDPROC)GetWindowLongPtrW(hEditWnd0, GWLP_WNDPROC);
>>show var: EditWndProcA  =0x77246feb  EditWndProcW=0x0597(handle)

if(IsWindowUnicode(hEditWnd0)) i++;
>>show var: i = 0 -- not a unciode windows

OldEditWndProcW =(WNDPROC)SetClassLongPtrW(hEditWnd0, GCLP_WNDPROC , 
(DWORD)EditWndProc );
>>show var: OldEditWndProcW=0x7726f52f

EditClassProcA =(WNDPROC)GetClassLongPtrA(hEditWnd1, GCLP_WNDPROC);
EditClassProcW =(WNDPROC)GetClassLongPtrW(hEditWnd1, GCLP_WNDPROC);
>>show var: EditClassProcA=0x05bf  EditClassProcW=0x00401014

hEditWnd1 = CreateWindowA(classNameA, NULL,WS_POPUP,0, 16, 100, 
16,hWnd,NULL,hInst,NULL);
EditWndProcA =(WNDPROC)GetWindowLongPtrA(hEditWnd1, GWLP_WNDPROC);
EditWndProcW =(WNDPROC)GetWindowLongPtrW(hEditWnd1, GWLP_WNDPROC);
>>show var: EditWndProcA  =0x00401014  EditWndProcW=0x0637

if(IsWindowUnicode(hEditWnd1)) i++;
>>show var: i = 0 -- not a unicode windows

Now you can see EditWndProcA==EditClassProcW and it's not a Unicode Window

I have got a screenshot showing the same debug result on MSVC 6.0
http://www.njstar.com/devimg/SetClassLongW-debug.png

==
# Test -  Following tests are added to dlls/user32/tests/class.c
# Latest 4 added tests fails on current wine 1.1.1
==
--- wine-1.1.1-orig/dlls/user32/tests/class.c   2008-07-12 01:55:55.0 
+1000
+++ wine-1.1.1/dlls/user32/tests/class.c2008-07-14 16:44:34.0 
+1000
@@ -590,6 +590,7 @@ static void test_builtinproc(void)
 WCHAR buf[128];
 ATOM atom;
 HWND hwnd;
+HWND hwnd2;
 int i;

 pDefWindowProcA = (void *)GetProcAddress(GetModuleHandle("user32.dll"), 
"DefWindowProcA");
@@ -775,6 +776,72 @@ static void test_builtinproc(void)
 CallWindowProcA((WNDPROC)GetWindowLongPtrA(hwnd, GWLP_WNDPROC), hwnd, 
WM_GETTEXT, 120, (LPARAM)buf);
 ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT invalid 
return\n");

+/** subclass Edit class using SetClassLongPtrA with ClassTest_WndProc2 **/
+oldproc = (WNDPROC)SetClassLongPtrA( hwnd, GCLP_WNDPROC, 
(ULONG_PTR)ClassTest_WndProc2);
+ok(!IS_WNDPROC_HANDLE(GetClassLongPtrA(hwnd, GCLP_WNDPROC)),
+   "GetClassLongPtrA expect to return a Ansi wndproc, got %p\n",(void 
*)GetClassLongPtrA(hwnd, GCLP_WNDPROC));
+ok(IS_WNDPROC_HANDLE(GetClassLongPtrW(hwnd, GCLP_WNDPROC)),
+   "GetClassLongPtrW expect to return a wndproc handle, got %p\n", (void 
*)GetClassLongPtrW(hwnd, GCLP_WNDPROC));
+
+