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));
+
+