diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index c9e924697fb..6b09b2644cd 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -237,12 +237,24 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit); +static BOOL ME_RegisterEditorClass(HINSTANCE); + +static const WCHAR RichEdit20W[] = {'R', 'i', 'c', 'h', 'E', 'd', 'i', 't', '2', '0', 'W', 0}; +static const WCHAR RichEdit50W[] = {'R', 'i', 'c', 'h', 'E', 'd', 'i', 't', '5', '0', 'W', 0}; +static const WCHAR REListBox20W[] = {'R','E','L','i','s','t','B','o','x','2','0','W', 0}; +static const WCHAR REComboBox20W[] = {'R','E','C','o','m','b','o','B','o','x','2','0','W', 0}; + int me_debug = 0; HANDLE me_heap = NULL; static BOOL ME_ListBoxRegistered = FALSE; static BOOL ME_ComboBoxRegistered = FALSE; +static inline int is_version_nt(void) +{ + return !(GetVersion() & 0x80000000); +} + static ME_TextBuffer *ME_MakeText(void) { ME_TextBuffer *buf = ALLOC_OBJ(ME_TextBuffer); @@ -1232,11 +1244,6 @@ void ME_DestroyEditor(ME_TextEditor *editor) FREE_OBJ(editor); } -static const WCHAR wszClassName[] = {'R', 'i', 'c', 'h', 'E', 'd', 'i', 't', '2', '0', 'W', 0}; -static const WCHAR wszClassName50[] = {'R', 'i', 'c', 'h', 'E', 'd', 'i', 't', '5', '0', 'W', 0}; -static const WCHAR wszClassNameListBox[] = {'R','E','L','i','s','t','B','o','x','2','0','W', 0}; -static const WCHAR wszClassNameComboBox[] = {'R','E','C','o','m','b','o','B','o','x','2','0','W', 0}; - BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { TRACE("\n"); @@ -1245,19 +1252,19 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls(hinstDLL); me_heap = HeapCreate (0, 0x10000, 0); - ME_RegisterEditorClass(hinstDLL); + if (!ME_RegisterEditorClass(hinstDLL)) return FALSE; LookupInit(); break; case DLL_PROCESS_DETACH: - UnregisterClassW(wszClassName, 0); - UnregisterClassW(wszClassName50, 0); + UnregisterClassW(RichEdit20W, 0); + UnregisterClassW(RichEdit50W, 0); UnregisterClassA("RichEdit20A", 0); UnregisterClassA("RichEdit50A", 0); if (ME_ListBoxRegistered) - UnregisterClassW(wszClassNameListBox, 0); + UnregisterClassW(REListBox20W, 0); if (ME_ComboBoxRegistered) - UnregisterClassW(wszClassNameComboBox, 0); + UnregisterClassW(REComboBox20W, 0); LookupCleanup(); HeapDestroy (me_heap); me_heap = NULL; @@ -1901,7 +1908,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP ME_EmptyUndoStack(editor); ME_SetSelection(editor, 0, 0); ME_UpdateRepaint(editor); - return 0; + return 1; } case EM_CANPASTE: { @@ -2703,9 +2710,8 @@ int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int nStart, int nChars, in return nWritten; } -void ME_RegisterEditorClass(HINSTANCE hInstance) +static BOOL ME_RegisterEditorClass(HINSTANCE hInstance) { - BOOL bResult; WNDCLASSW wcW; WNDCLASSA wcA; @@ -2718,12 +2724,22 @@ void ME_RegisterEditorClass(HINSTANCE hInstance) wcW.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(IDC_IBEAM)); wcW.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH); wcW.lpszMenuName = NULL; - wcW.lpszClassName = wszClassName; - bResult = RegisterClassW(&wcW); - assert(bResult); - wcW.lpszClassName = wszClassName50; - bResult = RegisterClassW(&wcW); - assert(bResult); + + if (is_version_nt()) + { + wcW.lpszClassName = RichEdit20W; + if (!RegisterClassW(&wcW)) return FALSE; + wcW.lpszClassName = RichEdit50W; + if (!RegisterClassW(&wcW)) return FALSE; + } + else + { + /* WNDCLASSA/W have the same layout */ + wcW.lpszClassName = (LPCWSTR)"RichEdit20W"; + if (!RegisterClassA((WNDCLASSA *)&wcW)) return FALSE; + wcW.lpszClassName = (LPCWSTR)"RichEdit50W"; + if (!RegisterClassA((WNDCLASSA *)&wcW)) return FALSE; + } wcA.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_GLOBALCLASS; wcA.lpfnWndProc = RichEditANSIWndProc; @@ -2735,11 +2751,11 @@ void ME_RegisterEditorClass(HINSTANCE hInstance) wcA.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH); wcA.lpszMenuName = NULL; wcA.lpszClassName = "RichEdit20A"; - bResult = RegisterClassA(&wcA); - assert(bResult); + if (!RegisterClassA(&wcA)) return FALSE; wcA.lpszClassName = "RichEdit50A"; - bResult = RegisterClassA(&wcA); - assert(bResult); + if (!RegisterClassA(&wcA)) return FALSE; + + return TRUE; } LRESULT WINAPI REComboWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { @@ -2781,7 +2797,7 @@ LRESULT WINAPI REExtendedRegisterClass(void) { wcW.style = CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS; wcW.lpfnWndProc = REListWndProc; - wcW.lpszClassName = wszClassNameListBox; + wcW.lpszClassName = REListBox20W; if (RegisterClassW(&wcW)) ME_ListBoxRegistered = TRUE; } @@ -2789,7 +2805,7 @@ LRESULT WINAPI REExtendedRegisterClass(void) { wcW.style = CS_PARENTDC | CS_DBLCLKS | CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW; wcW.lpfnWndProc = REComboWndProc; - wcW.lpszClassName = wszClassNameComboBox; + wcW.lpszClassName = REComboBox20W; if (RegisterClassW(&wcW)) ME_ComboBoxRegistered = TRUE; } diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h index ec56e3fd286..83292035a04 100644 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -266,7 +266,6 @@ extern LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *); /* wintest.c */ /* editor.c */ -void ME_RegisterEditorClass(HINSTANCE hInstance); ME_TextEditor *ME_MakeEditor(HWND hWnd); void ME_DestroyEditor(ME_TextEditor *editor); void ME_SendOldNotify(ME_TextEditor *editor, int nCode); diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index 60ab7ab8fdd..2d66f742b29 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -1562,6 +1562,89 @@ static void test_EM_StreamIn_Undo(void) } +static void test_unicode_conversions(void) +{ + static const WCHAR textW[] = {'t','e','s','t',0}; + static const char textA[] = "test"; + char bufA[64]; + WCHAR bufW[64]; + HWND hwnd; + int is_win9x, ret; + + is_win9x = GetVersion() & 0x80000000; + +#define set_textA(hwnd, txt) \ + do { \ + ret = SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)txt); \ + ok(ret, "SendMessageA(WM_SETTEXT) error %u\n", GetLastError()); \ + } while(0) +#define expect_textA(hwnd, txt, todo) \ + do { \ + memset(bufA, 0xAA, sizeof(bufA)); \ + ret = SendMessageA(hwnd, WM_GETTEXT, 64, (LPARAM)bufA); \ + ok(ret, "SendMessageA(WM_GETTEXT) error %u\n", GetLastError()); \ + ret = lstrcmpA(bufA, txt); \ + if (todo) \ + todo_wine ok(!ret, "strings not match: expected %s got %s\n", txt, bufA); \ + else \ + ok(!ret, "strings not match: expected %s got %s\n", txt, bufA); \ + } while(0) + +#define set_textW(hwnd, txt) \ + do { \ + ret = SendMessageW(hwnd, WM_SETTEXT, 0, (LPARAM)txt); \ + ok(ret, "SendMessageW(WM_SETTEXT) error %u\n", GetLastError()); \ + } while(0) +#define expect_textW(hwnd, txt) \ + do { \ + memset(bufW, 0xAA, sizeof(bufW)); \ + ret = SendMessageW(hwnd, WM_GETTEXT, 64, (LPARAM)bufW); \ + ok(ret, "SendMessageW(WM_GETTEXT) error %u\n", GetLastError()); \ + ret = lstrcmpW(bufW, txt); \ + ok(!ret, "strings not match\n"); \ + } while(0) + + hwnd = CreateWindowExA(0, "RichEdit20W", NULL, WS_POPUP, + 0, 0, 200, 60, 0, 0, 0, 0); + ok(hwnd != 0, "CreateWindowExA error %u\n", GetLastError()); + + ret = IsWindowUnicode(hwnd); + if (is_win9x) + ok(!ret, "RichEdit20W should NOT be unicode under Win9x\n"); + else + ok(ret, "RichEdit20W should be unicode under NT\n"); + + if (is_win9x) + set_textA(hwnd, textW); + else + set_textA(hwnd, textA); + expect_textA(hwnd, textA, is_win9x); + + if (!is_win9x) + { + set_textW(hwnd, textW); + expect_textW(hwnd, textW); + } + DestroyWindow(hwnd); + + hwnd = CreateWindowExA(0, "RichEdit20A", NULL, WS_POPUP, + 0, 0, 200, 60, 0, 0, 0, 0); + ok(hwnd != 0, "CreateWindowExA error %u\n", GetLastError()); + + ret = IsWindowUnicode(hwnd); + ok(!ret, "RichEdit20A should NOT be unicode\n"); + + set_textA(hwnd, textA); + expect_textA(hwnd, textA, FALSE); + + if (!is_win9x) + { + set_textW(hwnd, textW); + expect_textW(hwnd, textW); + } + DestroyWindow(hwnd); +} + START_TEST( editor ) { MSG msg; @@ -1571,6 +1654,7 @@ START_TEST( editor ) * RICHED20.DLL, so the linker doesn't actually link to it. */ hmoduleRichEdit = LoadLibrary("RICHED20.DLL"); ok(hmoduleRichEdit != NULL, "error: %d\n", (int) GetLastError()); + test_EM_FINDTEXT(); test_EM_GETLINE(); test_EM_SCROLLCARET(); @@ -1591,6 +1675,7 @@ START_TEST( editor ) test_EM_EXSETSEL(); test_WM_PASTE(); test_EM_StreamIn_Undo(); + test_unicode_conversions(); /* Set the environment variable WINETEST_RICHED20 to keep windows * responsive and open for 30 seconds. This is useful for debugging.