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.000000000 +1000 +++ wine-1.1.1/dlls/user32/win.c 2008-07-14 16:49:21.000000000 +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=0xffff0597(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=0xffff05bf 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=0xffff0637
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.000000000 +1000 +++ wine-1.1.1/dlls/user32/tests/class.c 2008-07-14 16:44:34.000000000 +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)); + + /* create a unicode edit window */ + hwnd2 = CreateWindowExW(0, WC_EDITW, NULL, WS_POPUP, + 0, 0, 100, 100, GetDesktopWindow(), 0, 0, NULL); + ok(!IsWindowUnicode(hwnd2), "CreateWindowExW should create a Ansi Edit window (subclassed by SetClassLongPtrA)\n"); + ok(!IS_WNDPROC_HANDLE(GetWindowLongPtrA(hwnd2, GWLP_WNDPROC)), + "GetWindowLongPtrA expect to return a Ansi wndproc, got %p\n",(void *)GetWindowLongPtrA(hwnd2, GWLP_WNDPROC)); + ok(IS_WNDPROC_HANDLE(GetWindowLongPtrW(hwnd2, GWLP_WNDPROC)), + "GetWindowLongPtrW expect to return a wndproc handle, got %p\n",(void *)GetWindowLongPtrW(hwnd2, GWLP_WNDPROC)); + DestroyWindow(hwnd2); + + /* create a ansi edit window */ + hwnd2 = CreateWindowExA(0, WC_EDITA, NULL, WS_POPUP, + 0, 0, 100, 100, GetDesktopWindow(), 0, 0, NULL); + ok(!IsWindowUnicode(hwnd2), "CreateWindowExA should create a Ansi Edit window (subclassed by SetClassLongPtrA)\n"); + ok(!IS_WNDPROC_HANDLE(GetWindowLongPtrA(hwnd2, GWLP_WNDPROC)), + "GetWindowLongPtrA expect to return a Ansi wndproc, got %p\n",(void *)GetWindowLongPtrA(hwnd2, GWLP_WNDPROC)); + ok(IS_WNDPROC_HANDLE(GetWindowLongPtrW(hwnd2, GWLP_WNDPROC)), + "GetWindowLongPtrW expect to return a wndproc handle, got %p\n",(void *)GetWindowLongPtrW(hwnd2, GWLP_WNDPROC)); + DestroyWindow(hwnd2); + + SetWindowLongPtrA( hwnd, GCLP_WNDPROC, (ULONG_PTR)oldproc); /* restore procA */ + + /** subclass Edit class using SetClassLongPtrW with ClassTest_WndProc **/ + oldproc = (WNDPROC)SetClassLongPtrW( hwnd, GCLP_WNDPROC, (ULONG_PTR)ClassTest_WndProc); + ok(IS_WNDPROC_HANDLE(GetClassLongPtrA(hwnd, GCLP_WNDPROC)), + "GetClassLongPtrA expect to return a wndproc handle, got %p\n",(void *)GetClassLongPtrA(hwnd, GCLP_WNDPROC)); + ok(!IS_WNDPROC_HANDLE(GetClassLongPtrW(hwnd, GCLP_WNDPROC)), + "GetClassLongPtrW expect to return a Unicode wndproc, got %p\n",(void *)GetClassLongPtrW(hwnd, GCLP_WNDPROC)); + + /* create a unicode edit window */ + hwnd2 = CreateWindowExW(0, WC_EDITW, NULL, WS_POPUP, + 0, 0, 100, 100, GetDesktopWindow(), 0, 0, NULL); + ok(IsWindowUnicode(hwnd2), "CreateWindowExW should create a Unicode Edit window (subclassed by SetClassLongPtrW)\n"); + ok(IS_WNDPROC_HANDLE(GetWindowLongPtrA(hwnd2, GWLP_WNDPROC)), + "GetWindowLongPtrA expect to return a wndproc handle, got %p\n",(void *)GetWindowLongPtrA(hwnd2, GWLP_WNDPROC)); + ok(!IS_WNDPROC_HANDLE(GetWindowLongPtrW(hwnd2, GWLP_WNDPROC)), + "GetWindowLongPtrW expect to return a Unicode wndproc, got %p\n",(void *)GetWindowLongPtrW(hwnd2, GWLP_WNDPROC)); + /* ClassTest_WndProc handles Unciode message - expected */ + ok(((WNDPROC)GetWindowLongPtrW(hwnd2, GWLP_WNDPROC)==ClassTest_WndProc), + "GetWindowLongPtrW expect to be ClassTest_WndProc, %p vs %p\n", + (void *)GetWindowLongPtrW(hwnd2, GWLP_WNDPROC),ClassTest_WndProc); + DestroyWindow(hwnd2); + + /* create a ansi edit window */ + hwnd2 = CreateWindowExA(0, WC_EDITA, NULL, WS_POPUP, + 0, 0, 100, 100, GetDesktopWindow(), 0, 0, NULL); + ok(!IsWindowUnicode(hwnd2), "CreateWindowExA should create a Ansi Edit window (subclassed by SetClassLongPtrW)\n"); + ok(!IS_WNDPROC_HANDLE(GetWindowLongPtrA(hwnd2, GWLP_WNDPROC)), + "GetWindowLongPtrA expect to return a Ansi wndproc, got %p\n",(void *)GetWindowLongPtrA(hwnd2, GWLP_WNDPROC)); + ok(IS_WNDPROC_HANDLE(GetWindowLongPtrW(hwnd2, GWLP_WNDPROC)), + "GetWindowLongPtrW expect to return a wndproc handle, got %p\n",(void *)GetWindowLongPtrW(hwnd2, GWLP_WNDPROC)); + /* ClassTest_WndProc should also handle Ansi message - a window Hack */ + ok(((WNDPROC)GetWindowLongPtrA(hwnd2, GWLP_WNDPROC)==ClassTest_WndProc), + "GetWindowLongPtrA expect to be ClassTest_WndProc, %p vs %p\n", + (void *)GetWindowLongPtrA(hwnd2, GWLP_WNDPROC),ClassTest_WndProc); + DestroyWindow(hwnd2); + + SetWindowLongPtrW( hwnd, GCLP_WNDPROC, (ULONG_PTR)oldproc); /* restore procW */ + DestroyWindow(hwnd); } ==============================================================================
_________________________________________________________________ Meet singles near you. Try ninemsn dating now! http://a.ninemsn.com.au/b.aspx?URL=http%3A%2F%2Fdating%2Eninemsn%2Ecom%2Eau%...