user32: CallWindowProc[AW] for mismatched built-in winprocs should take into account if the window is Unicode.
This commit is contained in:
parent
5c04d1fe41
commit
5e9ced90f7
|
@ -33,6 +33,10 @@
|
||||||
#include "wingdi.h"
|
#include "wingdi.h"
|
||||||
#include "winuser.h"
|
#include "winuser.h"
|
||||||
|
|
||||||
|
/* we don't want to include commctrl.h: */
|
||||||
|
static const CHAR WC_EDITA[] = "Edit";
|
||||||
|
static const WCHAR WC_EDITW[] = {'E','d','i','t',0};
|
||||||
|
|
||||||
#define NUMCLASSWORDS 4
|
#define NUMCLASSWORDS 4
|
||||||
|
|
||||||
static LRESULT WINAPI ClassTest_WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
static LRESULT WINAPI ClassTest_WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
|
@ -40,6 +44,11 @@ static LRESULT WINAPI ClassTest_WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPA
|
||||||
return DefWindowProcW (hWnd, msg, wParam, lParam);
|
return DefWindowProcW (hWnd, msg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LRESULT WINAPI ClassTest_WndProc2 (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
return DefWindowProcA (hWnd, msg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
*/
|
*/
|
||||||
static void ClassTest(HINSTANCE hInstance, BOOL global)
|
static void ClassTest(HINSTANCE hInstance, BOOL global)
|
||||||
|
@ -560,7 +569,12 @@ static void test_defwndproc()
|
||||||
{
|
{
|
||||||
static const char classA[] = "deftest";
|
static const char classA[] = "deftest";
|
||||||
static const WCHAR classW[] = {'d','e','f','t','e','s','t',0};
|
static const WCHAR classW[] = {'d','e','f','t','e','s','t',0};
|
||||||
|
WCHAR unistring[] = {0x142, 0x40e, 0x3b4, 0}; /* a string that would be destoryed by a W->A->W conversion */
|
||||||
WNDPROC pDefWindowProcA, pDefWindowProcW;
|
WNDPROC pDefWindowProcA, pDefWindowProcW;
|
||||||
|
WNDCLASSEXA cls; /* the memory layout of WNDCLASSEXA and WNDCLASSEXW is the same */
|
||||||
|
WCHAR buf[128];
|
||||||
|
ATOM atom;
|
||||||
|
HWND hwnd;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
pDefWindowProcA = (void *)GetProcAddress(GetModuleHandle("user32.dll"), "DefWindowProcA");
|
pDefWindowProcA = (void *)GetProcAddress(GetModuleHandle("user32.dll"), "DefWindowProcA");
|
||||||
|
@ -568,9 +582,6 @@ static void test_defwndproc()
|
||||||
|
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
WNDCLASSEXA cls; /* the memory layout of WNDCLASSEXA and WNDCLASSEXW is the same */
|
|
||||||
ATOM atom;
|
|
||||||
HWND hwnd;
|
|
||||||
ZeroMemory(&cls, sizeof(cls));
|
ZeroMemory(&cls, sizeof(cls));
|
||||||
cls.cbSize = sizeof(cls);
|
cls.cbSize = sizeof(cls);
|
||||||
cls.hInstance = GetModuleHandle(NULL);
|
cls.hInstance = GetModuleHandle(NULL);
|
||||||
|
@ -608,8 +619,110 @@ static void test_defwndproc()
|
||||||
DestroyWindow(hwnd);
|
DestroyWindow(hwnd);
|
||||||
UnregisterClass((LPSTR)(DWORD_PTR)atom, GetModuleHandle(NULL));
|
UnregisterClass((LPSTR)(DWORD_PTR)atom, GetModuleHandle(NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* built-in winproc - window A/W type automatically detected */
|
||||||
|
ZeroMemory(&cls, sizeof(cls));
|
||||||
|
cls.cbSize = sizeof(cls);
|
||||||
|
cls.hInstance = GetModuleHandle(NULL);
|
||||||
|
cls.hbrBackground = GetStockObject (WHITE_BRUSH);
|
||||||
|
cls.lpszClassName = classA;
|
||||||
|
cls.lpfnWndProc = pDefWindowProcW;
|
||||||
|
atom = RegisterClassExA(&cls);
|
||||||
|
|
||||||
|
hwnd = CreateWindowExW(0, classW, NULL, WS_OVERLAPPEDWINDOW,
|
||||||
|
CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, GetModuleHandleA(NULL), 0);
|
||||||
|
ok(IsWindowUnicode(hwnd), "Windows should be Unicode\n");
|
||||||
|
SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)pDefWindowProcA);
|
||||||
|
ok(IsWindowUnicode(hwnd), "Windows should have remained Unicode\n");
|
||||||
|
ok(GetWindowLongPtrW(hwnd, GWLP_WNDPROC) == (LONG_PTR)pDefWindowProcW, "Invalid ANSI winproc\n");
|
||||||
|
ok(GetWindowLongPtrA(hwnd, GWLP_WNDPROC) == (LONG_PTR)pDefWindowProcA, "Invalid Unicode winproc\n");
|
||||||
|
SetWindowLongPtrA(hwnd, GWL_WNDPROC, (LONG_PTR)ClassTest_WndProc);
|
||||||
|
ok(IsWindowUnicode(hwnd) == FALSE, "SetWindowLongPtrA should have switched window to ANSI\n");
|
||||||
|
|
||||||
|
DestroyWindow(hwnd);
|
||||||
|
UnregisterClass((LPSTR)(DWORD_PTR)atom, GetModuleHandle(NULL));
|
||||||
|
|
||||||
|
/* custom winproc - the same function can be used as both A and W*/
|
||||||
|
ZeroMemory(&cls, sizeof(cls));
|
||||||
|
cls.cbSize = sizeof(cls);
|
||||||
|
cls.hInstance = GetModuleHandle(NULL);
|
||||||
|
cls.hbrBackground = GetStockObject (WHITE_BRUSH);
|
||||||
|
cls.lpszClassName = classA;
|
||||||
|
cls.lpfnWndProc = ClassTest_WndProc2;
|
||||||
|
atom = RegisterClassExA(&cls);
|
||||||
|
|
||||||
|
hwnd = CreateWindowExW(0, classW, NULL, WS_OVERLAPPEDWINDOW,
|
||||||
|
CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, GetModuleHandleA(NULL), 0);
|
||||||
|
ok(IsWindowUnicode(hwnd) == FALSE, "Window should be ANSI\n");
|
||||||
|
SetWindowLongPtrW(hwnd, GWL_WNDPROC, (LONG_PTR)ClassTest_WndProc);
|
||||||
|
ok(IsWindowUnicode(hwnd), "SetWindowLongPtrW should have changed window to Unicode\n");
|
||||||
|
SetWindowLongPtrA(hwnd, GWL_WNDPROC, (LONG_PTR)ClassTest_WndProc);
|
||||||
|
ok(IsWindowUnicode(hwnd) == FALSE, "SetWindowLongPtrA should have changed window to ANSI\n");
|
||||||
|
|
||||||
|
DestroyWindow(hwnd);
|
||||||
|
UnregisterClass((LPSTR)(DWORD_PTR)atom, GetModuleHandle(NULL));
|
||||||
|
|
||||||
|
/* calling built-in and custom winprocs with CallWindowProc[AW]. Despite
|
||||||
|
* a slightly different nature the end result is the same */
|
||||||
|
hwnd = CreateWindowW(WC_EDITW, unistring, WS_OVERLAPPEDWINDOW,
|
||||||
|
CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, NULL, 0);
|
||||||
|
CallWindowProcW((WNDPROC)GetWindowLongPtrW(hwnd, GWLP_WNDPROC), hwnd, WM_GETTEXT, 120, (LPARAM)buf);
|
||||||
|
ok(memcmp(buf, unistring, sizeof(unistring)) == 0, "WM_GETTEXT invalid return\n");
|
||||||
|
CallWindowProcA((WNDPROC)GetWindowLongPtrW(hwnd, GWLP_WNDPROC), hwnd, WM_GETTEXT, 120, (LPARAM)buf);
|
||||||
|
ok(memcmp(buf, unistring, sizeof(unistring)) == 0, "WM_GETTEXT invalid return\n");
|
||||||
|
CallWindowProcW((WNDPROC)GetWindowLongPtrA(hwnd, GWLP_WNDPROC), hwnd, WM_GETTEXT, 120, (LPARAM)buf);
|
||||||
|
ok(memcmp(buf, unistring, sizeof(unistring)) == 0, "WM_GETTEXT invalid return\n");
|
||||||
|
|
||||||
|
SetWindowTextW(hwnd, classW);
|
||||||
|
CallWindowProcA((WNDPROC)GetWindowLongPtrA(hwnd, GWLP_WNDPROC), hwnd, WM_GETTEXT, 120, (LPARAM)buf);
|
||||||
|
ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT invalid return\n");
|
||||||
|
|
||||||
|
SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (LONG_PTR)ClassTest_WndProc2);
|
||||||
|
ok(IsWindowUnicode(hwnd) == FALSE, "SetWindowLongPtrA should have changed window to ANSI\n");
|
||||||
|
SetWindowTextA(hwnd, classA); /* Windows resets the title to WideStringToMultiByte(unistring) */
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
CallWindowProcA((WNDPROC)GetWindowLongPtrA(hwnd, GWLP_WNDPROC), hwnd, WM_GETTEXT, 120, (LPARAM)buf);
|
||||||
|
ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT invalid return\n");
|
||||||
|
CallWindowProcA((WNDPROC)GetWindowLongPtrW(hwnd, GWLP_WNDPROC), hwnd, WM_GETTEXT, 120, (LPARAM)buf);
|
||||||
|
ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT invalid return\n");
|
||||||
|
CallWindowProcW((WNDPROC)GetWindowLongPtrA(hwnd, GWLP_WNDPROC), hwnd, WM_GETTEXT, 120, (LPARAM)buf);
|
||||||
|
ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT invalid return\n");
|
||||||
|
|
||||||
|
CallWindowProcW((WNDPROC)GetWindowLongPtrW(hwnd, GWLP_WNDPROC), hwnd, WM_GETTEXT, 120, (LPARAM)buf);
|
||||||
|
ok(memcmp(buf, classW, sizeof(classW)) == 0, "WM_GETTEXT invalid return\n");
|
||||||
|
|
||||||
|
DestroyWindow(hwnd);
|
||||||
|
|
||||||
|
hwnd = CreateWindowA(WC_EDITA, classA, WS_OVERLAPPEDWINDOW,
|
||||||
|
CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, NULL, 0);
|
||||||
|
|
||||||
|
CallWindowProcA((WNDPROC)GetWindowLongPtrA(hwnd, GWLP_WNDPROC), hwnd, WM_GETTEXT, 120, (LPARAM)buf);
|
||||||
|
ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT invalid return\n");
|
||||||
|
CallWindowProcA((WNDPROC)GetWindowLongPtrW(hwnd, GWLP_WNDPROC), hwnd, WM_GETTEXT, 120, (LPARAM)buf);
|
||||||
|
ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT invalid return\n");
|
||||||
|
CallWindowProcW((WNDPROC)GetWindowLongPtrA(hwnd, GWLP_WNDPROC), hwnd, WM_GETTEXT, 120, (LPARAM)buf);
|
||||||
|
ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT invalid return\n");
|
||||||
|
|
||||||
|
CallWindowProcW((WNDPROC)GetWindowLongPtrW(hwnd, GWLP_WNDPROC), hwnd, WM_GETTEXT, 120, (LPARAM)buf);
|
||||||
|
ok(memcmp(buf, classW, sizeof(classW)) == 0, "WM_GETTEXT invalid return\n");
|
||||||
|
|
||||||
|
SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)ClassTest_WndProc);
|
||||||
|
SetWindowTextW(hwnd, unistring);
|
||||||
|
CallWindowProcW((WNDPROC)GetWindowLongPtrW(hwnd, GWLP_WNDPROC), hwnd, WM_GETTEXT, 120, (LPARAM)buf);
|
||||||
|
ok(memcmp(buf, unistring, sizeof(unistring)) == 0, "WM_GETTEXT invalid return\n");
|
||||||
|
CallWindowProcA((WNDPROC)GetWindowLongPtrW(hwnd, GWLP_WNDPROC), hwnd, WM_GETTEXT, 120, (LPARAM)buf);
|
||||||
|
ok(memcmp(buf, unistring, sizeof(unistring)) == 0, "WM_GETTEXT invalid return\n");
|
||||||
|
CallWindowProcW((WNDPROC)GetWindowLongPtrA(hwnd, GWLP_WNDPROC), hwnd, WM_GETTEXT, 120, (LPARAM)buf);
|
||||||
|
ok(memcmp(buf, unistring, sizeof(unistring)) == 0, "WM_GETTEXT invalid return\n");
|
||||||
|
|
||||||
|
SetWindowTextW(hwnd, classW);
|
||||||
|
CallWindowProcA((WNDPROC)GetWindowLongPtrA(hwnd, GWLP_WNDPROC), hwnd, WM_GETTEXT, 120, (LPARAM)buf);
|
||||||
|
ok(memcmp(buf, classA, sizeof(classA)) == 0, "WM_GETTEXT invalid return\n");
|
||||||
|
|
||||||
|
DestroyWindow(hwnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static LRESULT WINAPI TestDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
static LRESULT WINAPI TestDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||||
|
|
|
@ -2283,8 +2283,13 @@ LRESULT WINAPI CallWindowProcA(
|
||||||
|
|
||||||
if (!func) return 0;
|
if (!func) return 0;
|
||||||
|
|
||||||
if (!(proc = handle_to_proc( func )) && !(proc = find_builtin_proc( func )))
|
if (!(proc = handle_to_proc( func )))
|
||||||
call_window_proc( hwnd, msg, wParam, lParam, &result, func );
|
{
|
||||||
|
if ((proc = find_builtin_proc( func )) && !IsWindowUnicode( hwnd ))
|
||||||
|
call_window_proc( hwnd, msg, wParam, lParam, &result, proc->procA );
|
||||||
|
else
|
||||||
|
call_window_proc( hwnd, msg, wParam, lParam, &result, func );
|
||||||
|
}
|
||||||
else if (proc->procA)
|
else if (proc->procA)
|
||||||
call_window_proc( hwnd, msg, wParam, lParam, &result, proc->procA );
|
call_window_proc( hwnd, msg, wParam, lParam, &result, proc->procA );
|
||||||
else if (proc->procW)
|
else if (proc->procW)
|
||||||
|
@ -2309,8 +2314,13 @@ LRESULT WINAPI CallWindowProcW( WNDPROC func, HWND hwnd, UINT msg,
|
||||||
|
|
||||||
if (!func) return 0;
|
if (!func) return 0;
|
||||||
|
|
||||||
if (!(proc = handle_to_proc( func )) && !(proc = find_builtin_proc( func )))
|
if (!(proc = handle_to_proc( func )))
|
||||||
call_window_proc( hwnd, msg, wParam, lParam, &result, func );
|
{
|
||||||
|
if ((proc = find_builtin_proc( func )) && IsWindowUnicode( hwnd ))
|
||||||
|
call_window_proc( hwnd, msg, wParam, lParam, &result, proc->procW );
|
||||||
|
else
|
||||||
|
call_window_proc( hwnd, msg, wParam, lParam, &result, func );
|
||||||
|
}
|
||||||
else if (proc->procW)
|
else if (proc->procW)
|
||||||
call_window_proc( hwnd, msg, wParam, lParam, &result, proc->procW );
|
call_window_proc( hwnd, msg, wParam, lParam, &result, proc->procW );
|
||||||
else if (proc->procA)
|
else if (proc->procA)
|
||||||
|
@ -2367,8 +2377,13 @@ INT_PTR WINPROC_CallDlgProcA( DLGPROC func, HWND hwnd, UINT msg, WPARAM wParam,
|
||||||
|
|
||||||
if (!func) return 0;
|
if (!func) return 0;
|
||||||
|
|
||||||
if (!(proc = handle_to_proc( func )) && !(proc = find_builtin_proc( func )))
|
if (!(proc = handle_to_proc( func )))
|
||||||
ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, func );
|
{
|
||||||
|
if ((proc = find_builtin_proc( func )) && !IsWindowUnicode( hwnd ))
|
||||||
|
ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, proc->procA );
|
||||||
|
else
|
||||||
|
ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, func );
|
||||||
|
}
|
||||||
else if (proc->procA)
|
else if (proc->procA)
|
||||||
ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, proc->procA );
|
ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, proc->procA );
|
||||||
else if (proc->procW)
|
else if (proc->procW)
|
||||||
|
@ -2397,8 +2412,13 @@ INT_PTR WINPROC_CallDlgProcW( DLGPROC func, HWND hwnd, UINT msg, WPARAM wParam,
|
||||||
|
|
||||||
if (!func) return 0;
|
if (!func) return 0;
|
||||||
|
|
||||||
if (!(proc = handle_to_proc( func )) && !(proc = find_builtin_proc( func )))
|
if (!(proc = handle_to_proc( func )))
|
||||||
ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, func );
|
{
|
||||||
|
if ((proc = find_builtin_proc( func )) && IsWindowUnicode( hwnd ))
|
||||||
|
ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, proc->procW );
|
||||||
|
else
|
||||||
|
ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, func );
|
||||||
|
}
|
||||||
else if (proc->procW)
|
else if (proc->procW)
|
||||||
ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, proc->procW );
|
ret = call_dialog_proc( hwnd, msg, wParam, lParam, &result, proc->procW );
|
||||||
else if (proc->procA)
|
else if (proc->procA)
|
||||||
|
|
Loading…
Reference in New Issue