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/comctl32.h | 1 + dlls/comctl32/commctrl.c | 29 +++++++++++++++++------------ dlls/comctl32/tests/subclass.c | 2 -- 3 files changed, 18 insertions(+), 14 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..9be205d8b02 100644 --- a/dlls/comctl32/commctrl.c +++ b/dlls/comctl32/commctrl.c @@ -1103,12 +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->origproc = (WNDPROC)SetWindowLongPtrW (hWnd, GWLP_WNDPROC, - (DWORD_PTR)COMCTL32_SubclassProc); - else - stack->origproc = (WNDPROC)SetWindowLongPtrA (hWnd, GWLP_WNDPROC, - (DWORD_PTR)COMCTL32_SubclassProc); + stack->is_unicode = IsWindowUnicode (hWnd); + 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 @@ -1127,7 +1123,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 +1242,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 +1284,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,10 +1327,19 @@ 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)) - ret = CallWindowProcW (stack->origproc, hWnd, uMsg, wParam, lParam); + BOOL unicode = IsWindowUnicode (hWnd); + WNDPROC proc; + /* original proc may have changed, we only need its original unicode/ansi nature */ + if (stack->is_unicode) + proc = (WNDPROC)SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc); + else + proc = (WNDPROC)SetWindowLongPtrA (hWnd, GWLP_WNDPROC, (DWORD_PTR)stack->origproc); + ret = CallWindowProcW (stack->origproc, hWnd, uMsg, wParam, lParam); + /* restore previous proc and original unicode/ansi nature */ + if (unicode) + SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)proc); else - ret = CallWindowProcA (stack->origproc, hWnd, uMsg, wParam, lParam); + SetWindowLongPtrW (hWnd, GWLP_WNDPROC, (DWORD_PTR)proc); } else { const SUBCLASSPROCS *proc = stack->stackpos; stack->stackpos = stack->stackpos->next; diff --git a/dlls/comctl32/tests/subclass.c b/dlls/comctl32/tests/subclass.c index f0bd8e08245..3345d8155f8 100644 --- a/dlls/comctl32/tests/subclass.c +++ b/dlls/comctl32/tests/subclass.c @@ -216,7 +216,6 @@ static LRESULT WINAPI wnd_proc_sub(HWND hwnd, UINT message, WPARAM wParam, LPARA } } if (message == WM_CHAR) { - todo_wine ok(wParam == 0x30c2, "got wParam %#Ix\n", wParam); } return pDefSubclassProc(hwnd, message, wParam, lParam); @@ -238,7 +237,6 @@ static void test_subclass(void) ok_sequence(Sub_BasicTest, "Basic");
ret = IsWindowUnicode(hwnd); - todo_wine ok(ret, "got unicode window\n"); SendMessageW(hwnd, WM_CHAR, 0x30c2, 1);