Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=43073
-- v2: comctl32: Skip restoring window proc if it has been modified. comctl32: Always use unicode messages for subclass procedures. comctl32: Save unicode window nature on SetWindowSubclass call. comctl32/tests: Test unicode nature of window subclasses.
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=43073 --- dlls/comctl32/tests/subclass.c | 70 ++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+)
diff --git a/dlls/comctl32/tests/subclass.c b/dlls/comctl32/tests/subclass.c index e2e8573f4c0..684593e6ed7 100644 --- a/dlls/comctl32/tests/subclass.c +++ b/dlls/comctl32/tests/subclass.c @@ -34,9 +34,14 @@ static BOOL (WINAPI *pSetWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR static BOOL (WINAPI *pRemoveWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR); static LRESULT (WINAPI *pDefSubclassProc)(HWND, UINT, WPARAM, LPARAM);
+#define IS_WNDPROC_HANDLE(x) (((ULONG_PTR)(x) >> 16) == (~0u >> 16)) + #define SEND_NEST 0x01 #define DELETE_SELF 0x02 #define DELETE_PREV 0x04 +#define EXPECT_UNICODE 0x10 +#define EXPECT_WNDPROC_1 0x20 +#define EXPECT_WNDPROC_3 0x40
struct message { int procnum; /* WndProc id message is expected from */ @@ -166,15 +171,47 @@ static void ok_sequence(const struct message *expected, const char *context) flush_sequence(); }
+static LRESULT WINAPI wnd_proc_1(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); +static LRESULT WINAPI wnd_proc_3(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + +#define check_unicode(a, b) check_unicode_(__LINE__, a, b) +static void check_unicode_(int line, HWND hwnd, DWORD flags) +{ + WNDPROC proc; + BOOL ret; + + ret = IsWindowUnicode(hwnd); + ok_(__FILE__, line)(ret == !!(flags & EXPECT_UNICODE), "IsWindowUnicode returned %u\n", ret); + + proc = (WNDPROC)GetWindowLongPtrW(hwnd, GWLP_WNDPROC); + ok_(__FILE__, line)(IS_WNDPROC_HANDLE(proc) == !(flags & EXPECT_UNICODE), "got proc %p\n", proc); + + proc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_WNDPROC); + if (flags & EXPECT_UNICODE) + ok_(__FILE__, line)(IS_WNDPROC_HANDLE(proc), "got proc %p\n", proc); + else if (flags & EXPECT_WNDPROC_1) + ok_(__FILE__, line)(proc == wnd_proc_1, "got proc %p\n", proc); + else if (flags & EXPECT_WNDPROC_3) + todo_wine_if(proc == wnd_proc_1) ok_(__FILE__, line)(proc == wnd_proc_3, "got proc %p\n", proc); + else + ok_(__FILE__, line)(!IS_WNDPROC_HANDLE(proc), "got proc %p\n", proc); +} + static LRESULT WINAPI wnd_proc_1(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { + DWORD flags = GetWindowLongA(hwnd, GWLP_USERDATA); struct message msg; + + todo_wine_if(flags & EXPECT_UNICODE) check_unicode(hwnd, flags);
if(message == WM_USER) { msg.wParam = wParam; msg.procnum = 1; add_message(&msg); } + if (message == WM_CHAR) { + ok(!(wParam & ~0xff), "got wParam %#Ix\n", wParam); + } return DefWindowProcA(hwnd, message, wParam, lParam); }
@@ -194,7 +231,10 @@ static LRESULT WINAPI wnd_proc_3(HWND hwnd, UINT message, WPARAM wParam, LPARAM
static LRESULT WINAPI wnd_proc_sub(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, UINT_PTR uldSubclass, DWORD_PTR dwRefData) { + DWORD flags = GetWindowLongA(hwnd, GWLP_USERDATA); struct message msg; + + todo_wine_if(flags & EXPECT_UNICODE) check_unicode(hwnd, flags);
if(message == WM_USER) { msg.wParam = wParam; @@ -205,13 +245,24 @@ static LRESULT WINAPI wnd_proc_sub(HWND hwnd, UINT message, WPARAM wParam, LPARA if(dwRefData & DELETE_SELF) { pRemoveWindowSubclass(hwnd, wnd_proc_sub, uldSubclass); pRemoveWindowSubclass(hwnd, wnd_proc_sub, uldSubclass); + todo_wine_if(flags & EXPECT_UNICODE) check_unicode(hwnd, flags); } if(dwRefData & DELETE_PREV) + { pRemoveWindowSubclass(hwnd, wnd_proc_sub, uldSubclass-1); + todo_wine_if(flags & EXPECT_UNICODE) check_unicode(hwnd, flags); + } if(dwRefData & SEND_NEST) + { SendMessageA(hwnd, WM_USER, wParam+1, 0); + todo_wine_if(flags & EXPECT_UNICODE) check_unicode(hwnd, flags); + } } } + if (message == WM_CHAR) { + todo_wine + ok(wParam == 0x30c2, "got wParam %#Ix\n", wParam); + } return pDefSubclassProc(hwnd, message, wParam, lParam); }
@@ -221,17 +272,27 @@ static void test_subclass(void) HWND hwnd = CreateWindowExA(0, "TestSubclass", "Test subclass", WS_OVERLAPPEDWINDOW, 100, 100, 200, 200, 0, 0, 0, NULL); ok(hwnd != NULL, "failed to create test subclass wnd\n"); + check_unicode(hwnd, EXPECT_WNDPROC_1); + SetWindowLongA(hwnd, GWLP_USERDATA, EXPECT_WNDPROC_1);
ret = pSetWindowSubclass(hwnd, wnd_proc_sub, 2, 0); ok(ret == TRUE, "Expected TRUE\n"); + todo_wine check_unicode(hwnd, EXPECT_UNICODE); + SetWindowLongA(hwnd, GWLP_USERDATA, EXPECT_UNICODE); + SendMessageA(hwnd, WM_USER, 1, 0); SendMessageA(hwnd, WM_USER, 2, 0); ok_sequence(Sub_BasicTest, "Basic"); + SendMessageW(hwnd, WM_CHAR, 0x30c2, 1);
ret = pSetWindowSubclass(hwnd, wnd_proc_sub, 2, DELETE_SELF); ok(ret == TRUE, "Expected TRUE\n"); + todo_wine check_unicode(hwnd, EXPECT_UNICODE); + SendMessageA(hwnd, WM_USER, 1, 1); ok_sequence(Sub_DeletedTest, "Deleted"); + check_unicode(hwnd, EXPECT_WNDPROC_1); + SetWindowLongA(hwnd, GWLP_USERDATA, EXPECT_WNDPROC_1);
SendMessageA(hwnd, WM_USER, 1, 0); ok_sequence(Sub_AfterDeletedTest, "After Deleted"); @@ -239,15 +300,22 @@ static void test_subclass(void) ret = pSetWindowSubclass(hwnd, wnd_proc_sub, 2, 0); ok(ret == TRUE, "Expected TRUE\n"); orig_proc_3 = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (LONG_PTR)wnd_proc_3); + check_unicode(hwnd, EXPECT_WNDPROC_3); + SetWindowLongA(hwnd, GWLP_USERDATA, EXPECT_WNDPROC_3); + SendMessageA(hwnd, WM_USER, 1, 0); SendMessageA(hwnd, WM_USER, 2, 0); ok_sequence(Sub_OldAfterNewTest, "Old after New");
ret = pSetWindowSubclass(hwnd, wnd_proc_sub, 4, 0); ok(ret == TRUE, "Expected TRUE\n"); + check_unicode(hwnd, EXPECT_WNDPROC_3); + SendMessageA(hwnd, WM_USER, 1, 0); ok_sequence(Sub_MixTest, "Mix");
+ check_unicode(hwnd, EXPECT_WNDPROC_3); + /* Now the fun starts */ ret = pSetWindowSubclass(hwnd, wnd_proc_sub, 4, SEND_NEST); ok(ret == TRUE, "Expected TRUE\n"); @@ -275,6 +343,8 @@ static void test_subclass(void) pRemoveWindowSubclass(hwnd, wnd_proc_sub, 2); pRemoveWindowSubclass(hwnd, wnd_proc_sub, 5);
+ check_unicode(hwnd, EXPECT_WNDPROC_3); + DestroyWindow(hwnd); }
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=43073 --- dlls/comctl32/comctl32.h | 1 + dlls/comctl32/commctrl.c | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/dlls/comctl32/comctl32.h b/dlls/comctl32/comctl32.h index 7dfdf089eb1..faff3f30717 100644 --- a/dlls/comctl32/comctl32.h +++ b/dlls/comctl32/comctl32.h @@ -209,6 +209,7 @@ typedef struct SUBCLASSPROCS *SubclassProcs; SUBCLASSPROCS *stackpos; WNDPROC origproc; + int is_unicode; int running; } SUBCLASS_INFO, *LPSUBCLASS_INFO;
diff --git a/dlls/comctl32/commctrl.c b/dlls/comctl32/commctrl.c index c5910b40869..37cb66b9bbb 100644 --- a/dlls/comctl32/commctrl.c +++ b/dlls/comctl32/commctrl.c @@ -1103,7 +1103,8 @@ BOOL WINAPI SetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass, SetPropW (hWnd, COMCTL32_wSubclass, stack);
/* set window procedure to our own and save the current one */ - if (IsWindowUnicode (hWnd)) + stack->is_unicode = IsWindowUnicode (hWnd); + if (stack->is_unicode) stack->origproc = (WNDPROC)SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)COMCTL32_SubclassProc); else @@ -1127,7 +1128,7 @@ BOOL WINAPI SetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass, proc = Alloc(sizeof(SUBCLASSPROCS)); if (!proc) { ERR ("Failed to allocate subclass entry in stack\n"); - if (IsWindowUnicode (hWnd)) + if (stack->is_unicode) SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc); else SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc); @@ -1246,7 +1247,7 @@ BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR u if (!stack->SubclassProcs && !stack->running) { TRACE("Last Subclass removed, cleaning up\n"); /* clean up our heap and reset the original window procedure */ - if (IsWindowUnicode (hWnd)) + if (stack->is_unicode) SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc); else SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc); @@ -1288,7 +1289,7 @@ static LRESULT WINAPI COMCTL32_SubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam if (!stack->SubclassProcs && !stack->running) { TRACE("Last Subclass removed, cleaning up\n"); /* clean up our heap and reset the original window procedure */ - if (IsWindowUnicode (hWnd)) + if (stack->is_unicode) SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc); else SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc); @@ -1331,7 +1332,7 @@ LRESULT WINAPI DefSubclassProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar /* If we are at the end of stack then we have to call the original * window procedure */ if (!stack->stackpos) { - if (IsWindowUnicode (hWnd)) + if (stack->is_unicode) ret = CallWindowProcW (stack->origproc, hWnd, uMsg, wParam, lParam); else ret = CallWindowProcA (stack->origproc, hWnd, uMsg, wParam, lParam);
From: Rémi Bernon rbernon@codeweavers.com
Final Fantasy XIV Online depends on this for its text input.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=43073 --- dlls/comctl32/commctrl.c | 8 ++------ dlls/comctl32/tests/subclass.c | 16 ++++++++-------- 2 files changed, 10 insertions(+), 14 deletions(-)
diff --git a/dlls/comctl32/commctrl.c b/dlls/comctl32/commctrl.c index 37cb66b9bbb..80ea575881e 100644 --- a/dlls/comctl32/commctrl.c +++ b/dlls/comctl32/commctrl.c @@ -1104,12 +1104,8 @@ BOOL WINAPI SetWindowSubclass (HWND hWnd, SUBCLASSPROC pfnSubclass,
/* set window procedure to our own and save the current one */ stack->is_unicode = IsWindowUnicode (hWnd); - if (stack->is_unicode) - stack->origproc = (WNDPROC)SetWindowLongPtrW (hWnd, GWLP_WNDPROC, - (DWORD_PTR)COMCTL32_SubclassProc); - else - stack->origproc = (WNDPROC)SetWindowLongPtrA (hWnd, GWLP_WNDPROC, - (DWORD_PTR)COMCTL32_SubclassProc); + stack->origproc = (WNDPROC)SetWindowLongPtrW (hWnd, GWLP_WNDPROC, + (DWORD_PTR)COMCTL32_SubclassProc); } else { /* Check to see if we have called this function with the same uIDSubClass diff --git a/dlls/comctl32/tests/subclass.c b/dlls/comctl32/tests/subclass.c index 684593e6ed7..9a78580e506 100644 --- a/dlls/comctl32/tests/subclass.c +++ b/dlls/comctl32/tests/subclass.c @@ -202,7 +202,7 @@ static LRESULT WINAPI wnd_proc_1(HWND hwnd, UINT message, WPARAM wParam, LPARAM DWORD flags = GetWindowLongA(hwnd, GWLP_USERDATA); struct message msg;
- todo_wine_if(flags & EXPECT_UNICODE) check_unicode(hwnd, flags); + check_unicode(hwnd, flags);
if(message == WM_USER) { msg.wParam = wParam; @@ -210,6 +210,7 @@ static LRESULT WINAPI wnd_proc_1(HWND hwnd, UINT message, WPARAM wParam, LPARAM add_message(&msg); } if (message == WM_CHAR) { + todo_wine ok(!(wParam & ~0xff), "got wParam %#Ix\n", wParam); } return DefWindowProcA(hwnd, message, wParam, lParam); @@ -234,7 +235,7 @@ static LRESULT WINAPI wnd_proc_sub(HWND hwnd, UINT message, WPARAM wParam, LPARA DWORD flags = GetWindowLongA(hwnd, GWLP_USERDATA); struct message msg;
- todo_wine_if(flags & EXPECT_UNICODE) check_unicode(hwnd, flags); + check_unicode(hwnd, flags);
if(message == WM_USER) { msg.wParam = wParam; @@ -245,22 +246,21 @@ static LRESULT WINAPI wnd_proc_sub(HWND hwnd, UINT message, WPARAM wParam, LPARA if(dwRefData & DELETE_SELF) { pRemoveWindowSubclass(hwnd, wnd_proc_sub, uldSubclass); pRemoveWindowSubclass(hwnd, wnd_proc_sub, uldSubclass); - todo_wine_if(flags & EXPECT_UNICODE) check_unicode(hwnd, flags); + check_unicode(hwnd, flags); } if(dwRefData & DELETE_PREV) { pRemoveWindowSubclass(hwnd, wnd_proc_sub, uldSubclass-1); - todo_wine_if(flags & EXPECT_UNICODE) check_unicode(hwnd, flags); + check_unicode(hwnd, flags); } if(dwRefData & SEND_NEST) { SendMessageA(hwnd, WM_USER, wParam+1, 0); - todo_wine_if(flags & EXPECT_UNICODE) check_unicode(hwnd, flags); + check_unicode(hwnd, flags); } } } if (message == WM_CHAR) { - todo_wine ok(wParam == 0x30c2, "got wParam %#Ix\n", wParam); } return pDefSubclassProc(hwnd, message, wParam, lParam); @@ -277,7 +277,7 @@ static void test_subclass(void)
ret = pSetWindowSubclass(hwnd, wnd_proc_sub, 2, 0); ok(ret == TRUE, "Expected TRUE\n"); - todo_wine check_unicode(hwnd, EXPECT_UNICODE); + check_unicode(hwnd, EXPECT_UNICODE); SetWindowLongA(hwnd, GWLP_USERDATA, EXPECT_UNICODE);
SendMessageA(hwnd, WM_USER, 1, 0); @@ -287,7 +287,7 @@ static void test_subclass(void)
ret = pSetWindowSubclass(hwnd, wnd_proc_sub, 2, DELETE_SELF); ok(ret == TRUE, "Expected TRUE\n"); - todo_wine check_unicode(hwnd, EXPECT_UNICODE); + check_unicode(hwnd, EXPECT_UNICODE);
SendMessageA(hwnd, WM_USER, 1, 1); ok_sequence(Sub_DeletedTest, "Deleted");
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=43073 --- dlls/comctl32/commctrl.c | 4 +++- dlls/comctl32/tests/subclass.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/dlls/comctl32/commctrl.c b/dlls/comctl32/commctrl.c index 80ea575881e..40da5516fb4 100644 --- a/dlls/comctl32/commctrl.c +++ b/dlls/comctl32/commctrl.c @@ -1243,7 +1243,9 @@ BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR u if (!stack->SubclassProcs && !stack->running) { TRACE("Last Subclass removed, cleaning up\n"); /* clean up our heap and reset the original window procedure */ - if (stack->is_unicode) + if ((WNDPROC)GetWindowLongPtrW (hWnd, GWLP_WNDPROC) != COMCTL32_SubclassProc) + WARN("Window procedure has been modified, skipping restore\n"); + else if (stack->is_unicode) SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc); else SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc); diff --git a/dlls/comctl32/tests/subclass.c b/dlls/comctl32/tests/subclass.c index 9a78580e506..1e2d38c03a9 100644 --- a/dlls/comctl32/tests/subclass.c +++ b/dlls/comctl32/tests/subclass.c @@ -192,7 +192,7 @@ static void check_unicode_(int line, HWND hwnd, DWORD flags) else if (flags & EXPECT_WNDPROC_1) ok_(__FILE__, line)(proc == wnd_proc_1, "got proc %p\n", proc); else if (flags & EXPECT_WNDPROC_3) - todo_wine_if(proc == wnd_proc_1) ok_(__FILE__, line)(proc == wnd_proc_3, "got proc %p\n", proc); + ok_(__FILE__, line)(proc == wnd_proc_3, "got proc %p\n", proc); else ok_(__FILE__, line)(!IS_WNDPROC_HANDLE(proc), "got proc %p\n", proc); }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=128806
Your paranoid android.
=== debian11 (32 bit report) ===
comctl32: updown.c:418: Test failed: Expected 50, got 5 updown.c:420: Test failed: test updown pos, no change: the msg sequence is not complete: expected 0000 - actual 000c updown.c:434: Test failed: Expected 40, got 5 updown.c:435: Test failed: Expected 1, got 0 updown.c:438: Test failed: Expected 40, got 5 updown.c:453: Test failed: Expected 0, got 1 updown.c:460: Test failed: Expected 40, got 4 updown.c:549: Test failed: test updown pos, no change: the msg sequence is not complete: expected 0000 - actual 000c updown.c:732: Test failed: Expected '10', got '1' updown.c:879: Test failed: Expected '50', got '5' updown.c:885: Test failed: Expected '20', got '2' updown.c:890: Test failed: Expected 10, got 1 updown.c:894: Test failed: Expected 11, got 1 updown.c:900: Test failed: Expected 11, got 2 updown.c:901: Test failed: Expected 1, got 0 updown.c:907: Test failed: Expected '30', got '3' updown.c:955: Test failed: test updown to parent notify (vertical): in msg 0x0115 expecting wParam 0x330004 got 0x60004 updown.c:955: Test failed: test updown to parent notify (vertical): in msg 0x0115 expecting wParam 0x330008 got 0x60008 updown.c:974: Test failed: test updown to parent notify (horizontal): in msg 0x0114 expecting wParam 0x330004 got 0x60004 updown.c:974: Test failed: test updown to parent notify (horizontal): in msg 0x0114 expecting wParam 0x330008 got 0x60008
=== debian11 (32 bit zh:CN report) ===
comctl32: updown.c:418: Test failed: Expected 50, got 5 updown.c:420: Test failed: test updown pos, no change: the msg sequence is not complete: expected 0000 - actual 000c updown.c:434: Test failed: Expected 40, got 5 updown.c:435: Test failed: Expected 1, got 0 updown.c:438: Test failed: Expected 40, got 5 updown.c:453: Test failed: Expected 0, got 1 updown.c:460: Test failed: Expected 40, got 4 updown.c:549: Test failed: test updown pos, no change: the msg sequence is not complete: expected 0000 - actual 000c updown.c:732: Test failed: Expected '10', got '1' updown.c:879: Test failed: Expected '50', got '5' updown.c:885: Test failed: Expected '20', got '2' updown.c:890: Test failed: Expected 10, got 1 updown.c:894: Test failed: Expected 11, got 1 updown.c:900: Test failed: Expected 11, got 2 updown.c:901: Test failed: Expected 1, got 0 updown.c:907: Test failed: Expected '30', got '3' updown.c:955: Test failed: test updown to parent notify (vertical): in msg 0x0115 expecting wParam 0x330004 got 0x60004 updown.c:955: Test failed: test updown to parent notify (vertical): in msg 0x0115 expecting wParam 0x330008 got 0x60008 updown.c:974: Test failed: test updown to parent notify (horizontal): in msg 0x0114 expecting wParam 0x330004 got 0x60004 updown.c:974: Test failed: test updown to parent notify (horizontal): in msg 0x0114 expecting wParam 0x330008 got 0x60008
=== debian11b (64 bit WoW report) ===
comctl32: updown.c:420: Test failed: test updown pos, no change: the msg sequence is not complete: expected 0000 - actual 000c updown.c:443: Test failed: Expected 0, got 1 updown.c:453: Test failed: Expected 0, got 1 updown.c:461: Test failed: Expected 0, got 1 updown.c:549: Test failed: test updown pos, no change: the msg sequence is not complete: expected 0000 - actual 000c updown.c:732: Test failed: Expected '10', got '1' updown.c:879: Test failed: Expected '50', got '5' updown.c:885: Test failed: Expected '20', got '2' updown.c:890: Test failed: Expected 10, got 1 updown.c:894: Test failed: Expected 11, got 1 updown.c:900: Test failed: Expected 11, got 2 updown.c:901: Test failed: Expected 1, got 0 updown.c:907: Test failed: Expected '30', got '3' updown.c:955: Test failed: test updown to parent notify (vertical): in msg 0x0115 expecting wParam 0x330004 got 0x60004 updown.c:955: Test failed: test updown to parent notify (vertical): in msg 0x0115 expecting wParam 0x330008 got 0x60008 updown.c:974: Test failed: test updown to parent notify (horizontal): in msg 0x0114 expecting wParam 0x330004 got 0x60004 updown.c:974: Test failed: test updown to parent notify (horizontal): in msg 0x0114 expecting wParam 0x330008 got 0x60008
v2: Add more detailed window procedure tests. Ignore original window procedure unicode-ness when calling it. Fix the button test failures.
This adds a todo_wine as it now ignores the original window ansi nature, but I hope it shouldn't matter. I couldn't find a way to force the WtoA conversion to happen, when calling CallWindowProc with the original procedure, while at the same time keeping the unicode nature and window procedures unchanged;