From: Jacek Caban jacek@codeweavers.com
--- dlls/user32/tests/msg.c | 42 +++++++++++++++++++++++++++++++++++++++++ dlls/user32/win.c | 17 +++++++++++++++-- dlls/user32/winproc.c | 17 +++++++++++++++-- 3 files changed, 72 insertions(+), 4 deletions(-)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index 2d43c1ad1aa..2ed1046b6f7 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -18990,6 +18990,47 @@ static void test_button_style(void) } }
+static LRESULT WINAPI test_create_name_procW( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) +{ + switch (msg) + { + case WM_NCCREATE: + case WM_CREATE: + { + CREATESTRUCTW *cs = (CREATESTRUCTW *)lparam; + ok(!wcscmp(cs->lpszName, L"\xffff\x6162"), "lpszName = %s\n", debugstr_w(cs->lpszName)); + break; + } + case WM_SETTEXT: + trace("%s\n", debugstr_w((const WCHAR *)lparam)); + break; + } + + return DefWindowProcW( hwnd, msg, wparam, lparam ); +} + +static void test_create_name(void) +{ + WNDCLASSW clsW = { 0 }; + HWND hwnd; + + clsW.lpfnWndProc = test_create_name_procW; + clsW.lpszClassName = L"TestCreateNameClassW"; + RegisterClassW( &clsW ); + + hwnd = CreateWindowExW( 0, L"TestCreateNameClassW", L"\xffff\x6162", + WS_POPUP, 0,0,0,0,0,0,0, NULL ); + ok( hwnd != NULL, "CreateWindowEx failed: %lu\n", GetLastError() ); + DestroyWindow( hwnd ); + + hwnd = CreateWindowExA( 0, "TestCreateNameClassW", "\xff\x62\x61\x60", + WS_POPUP, 0,0,0,0,0,0,0, NULL ); + ok( hwnd != NULL, "CreateWindowEx failed: %lu\n", GetLastError() ); + DestroyWindow( hwnd ); + + UnregisterClassW( L"TestCreateNameClassW", NULL ); +} + START_TEST(msg) { char **test_argv; @@ -19105,6 +19146,7 @@ START_TEST(msg) test_TrackPopupMenu(); test_TrackPopupMenuEmpty(); test_DoubleSetCapture(); + test_create_name(); /* keep it the last test, under Windows it tends to break the tests * which rely on active/foreground windows being correct. */ diff --git a/dlls/user32/win.c b/dlls/user32/win.c index 9507486754b..7bec515cedb 100644 --- a/dlls/user32/win.c +++ b/dlls/user32/win.c @@ -304,6 +304,7 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module, HWND hwnd, top_child = 0; MDICREATESTRUCTW mdi_cs; WNDCLASSEXW info; + WCHAR name_buf[8]; HMENU menu;
if (!get_class_info( module, className, &info, &class, FALSE )) return FALSE; @@ -400,8 +401,20 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module,
if (unicode || !cs->lpszName) RtlInitUnicodeString( &window_name, cs->lpszName ); - else if (!RtlCreateUnicodeStringFromAsciiz( &window_name, (const char *)cs->lpszName )) - return 0; + else + { + const char *nameA = (const char *)cs->lpszName; + /* resource ID string is a special case */ + if (nameA[0] == '\xff') + { + name_buf[0] = 0xffff; + name_buf[1] = nameA[1] ? MAKEWORD( nameA[1], nameA[2] ) : 0; + name_buf[2] = 0; + RtlInitUnicodeString( &window_name, name_buf ); + } + else if (!RtlCreateUnicodeStringFromAsciiz( &window_name, (const char *)cs->lpszName )) + return 0; + }
menu = cs->hMenu; if (!menu && info.lpszMenuName && (cs->style & (WS_CHILD | WS_POPUP)) != WS_CHILD) diff --git a/dlls/user32/winproc.c b/dlls/user32/winproc.c index 7e2be5b1be0..deae1a061f8 100644 --- a/dlls/user32/winproc.c +++ b/dlls/user32/winproc.c @@ -475,6 +475,7 @@ static LRESULT WINPROC_CallProcWtoA( winproc_callback_t callback, HWND hwnd, UIN CREATESTRUCTA csA = *(CREATESTRUCTA *)csW; MDICREATESTRUCTA mdi_cs; DWORD name_lenA = 0, name_lenW = 0, class_lenA = 0, class_lenW = 0; + char int_name_buf[4];
if (!IS_INTRESOURCE(csW->lpszClass)) { @@ -483,8 +484,20 @@ static LRESULT WINPROC_CallProcWtoA( winproc_callback_t callback, HWND hwnd, UIN } if (!IS_INTRESOURCE(csW->lpszName)) { - name_lenW = (lstrlenW(csW->lpszName) + 1) * sizeof(WCHAR); - RtlUnicodeToMultiByteSize(&name_lenA, csW->lpszName, name_lenW); + /* resource ID string is a special case */ + if (csW->lpszName[0] == 0xffff) + { + int_name_buf[0] = 0xff; + int_name_buf[1] = csW->lpszName[1]; + int_name_buf[2] = csW->lpszName[1] >> 8; + int_name_buf[3] = 0; + csA.lpszName = int_name_buf; + } + else + { + name_lenW = (lstrlenW(csW->lpszName) + 1) * sizeof(WCHAR); + RtlUnicodeToMultiByteSize(&name_lenA, csW->lpszName, name_lenW); + } }
if (!(cls = get_buffer( buffer, sizeof(buffer), class_lenA + name_lenA ))) break;