--- a/dlls/riched20/tests/editor.c 2010-06-20 16:47:44.000000000 -0700 +++ b/dlls/riched20/tests/editor.c 2010-06-20 14:51:01.000000000 -0700 @@ -50,9 +50,13 @@ static HWND new_window(LPCTSTR lpClassName, DWORD dwStyle, HWND parent) { HWND hwnd; - hwnd = CreateWindow(lpClassName, NULL, dwStyle|WS_POPUP|WS_HSCROLL|WS_VSCROLL - |WS_VISIBLE, 0, 0, 200, 60, parent, NULL, - hmoduleRichEdit, NULL); +/* hwnd = CreateWindow(lpClassName, NULL, dwStyle|WS_POPUP|WS_HSCROLL|WS_VSCROLL + |WS_VISIBLE, 0, 0, 200, 60, parent, NULL, + hmoduleRichEdit, NULL); */ + /* Set screen to VGA proportions for teasing purposes, will be removed from final patch release */ + hwnd = CreateWindow(lpClassName, NULL, dwStyle|WS_POPUP|WS_HSCROLL|WS_VSCROLL + |WS_VISIBLE, 0, 0, 480, 640, parent, NULL, + hmoduleRichEdit, NULL); ok(hwnd != NULL, "class: %s, error: %d\n", lpClassName, (int) GetLastError()); return hwnd; } @@ -7067,6 +7071,280 @@ DestroyWindow(hwRichEdit); DestroyWindow(hwParent); } +static INT CALLBACK find_font_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam) +{ + return 0; +} + +static void test_em_setmargins(void) +{ + HWND hwndRichEdit; + RECT old_rect, new_rect; + + hwndRichEdit = new_richedit(NULL); + + HDC hdc = GetDC (hwndRichEdit); + LOGFONTW lf; + LOGFONTW sentLogFont; + HFONT hfont, hfont2; + CHARFORMAT2W CharFont1Unicode; + + TEXTMETRICW tmw; + + UINT ret; + + CharFont1Unicode.cbSize = sizeof(CharFont1Unicode); + memset(&sentLogFont, 0, sizeof(LOGFONTW)); + + if(EnumFontFamiliesA(hdc, "Arial", find_font_proc, 0)) + { + trace("Arial not found - skipping font change margin tests\n"); + ReleaseDC(hwndRichEdit, hdc); + return; + } + + HFONT testFont = CreateFontW (12,0,0,0,FW_LIGHT, 0, 0, 0, ANSI_CHARSET, + OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | + FF_DONTCARE, "Courier"); + + HFONT testFont2 = CreateFontW (12,0,0,0,FW_LIGHT, 0, 0, 0, ANSI_CHARSET, + OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | + FF_DONTCARE, "MS Sans Serif"); + + HFONT testFont3 = CreateFontW (16,0,0,0,FW_LIGHT, 0, 0, 0, ANSI_CHARSET, + OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | + FF_DONTCARE, "Arial"); + + HFONT testFont4 = CreateFontW (30,0,0,0,FW_LIGHT, 0, 0, 0, ANSI_CHARSET, + OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | + FF_DONTCARE, "Arial"); + + memset(&lf, 0, sizeof(lf)); + strcpy(lf.lfFaceName, "Arial"); + lf.lfHeight = 16; + lf.lfCharSet = DEFAULT_CHARSET; + hfont = CreateFontIndirectW(&lf); + lf.lfHeight = 30; + hfont2 = CreateFontIndirectW(&lf); + + /*Initialize old_rect variable to be the size of the entire richedit window */ + SendMessage(hwndRichEdit, EM_SETRECT, 0, (LPARAM)&old_rect); + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&old_rect); + + /*Set Left Margin to five pixels in size */ + SendMessage(hwndRichEdit, EM_SETMARGINS, EC_LEFTMARGIN, MAKELONG (5,0)); + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&new_rect); + ok(new_rect.left == old_rect.left + 5, "The left border of the rectangle is wrong. The value of it is %d.\n", new_rect.left); + ok(new_rect.right == old_rect.right, "The right border was changed\n"); + ok(new_rect.top == old_rect.top, "The top border was changed\n"); + ok(new_rect.bottom == old_rect.bottom, "The bottom border was changed\n"); + + /*Set Right Margin to five pixels in size. The left margin should remain at 5 pixels*/ + SendMessage(hwndRichEdit, EM_SETMARGINS, EC_RIGHTMARGIN, MAKELONG (0,5)); + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&new_rect); + ok(new_rect.right == (old_rect.right - 5), "The right border of the rectangle is wrong. The value of it is %d. The value of the prior margin was %d.\n", new_rect.right, old_rect.right); + ok(new_rect.left == old_rect.left + 5, "The left border was changed. It changed to %d from %d\n", new_rect.left, old_rect.left); + ok(new_rect.top == old_rect.top, "The top border was changed\n"); + ok(new_rect.bottom == old_rect.bottom, "The bottom border was changed\n"); + + /* Test changing of Margins to a larger margin size */ + SendMessage(hwndRichEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(5, 5)); + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&old_rect); + SendMessage(hwndRichEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(15, 20)); + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&new_rect); + ok(new_rect.left == old_rect.left + 10, "The left border of the rectangle is wrong\n"); + ok(new_rect.right == old_rect.right - 15, "The right border of the rectangle is wrong\n"); + ok(new_rect.top == old_rect.top, "The top border of the rectangle must not change\n"); + ok(new_rect.bottom == old_rect.bottom, "The bottom border of the rectangle must not change\n"); + + /* Verify if we use the same margins, the size of the rectangle does not change */ + SendMessage(hwndRichEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(10, 10)); + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&old_rect); + SendMessage(hwndRichEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(10, 10)); + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&new_rect); + ok(new_rect.left == old_rect.left, "The left border of the rectangle has changed to %d\n", new_rect.left); + ok(new_rect.right == old_rect.right, "The right border of the rectangle has changed to %d\n", new_rect.right); + ok(new_rect.top == old_rect.top, "The top border of the rectangle has changed\n"); + ok(new_rect.bottom == old_rect.bottom, "The bottom border of the rectangle has changed\n"); + + /* Test case of EC_USEFONTINFO */ + /* First with no font information set */ + SendMessageW(hwndRichEdit, WM_SETFONT, 0, 0); + SendMessage(hwndRichEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, 0); + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&old_rect); + SendMessage(hwndRichEdit, EM_SETMARGINS, EC_USEFONTINFO, 0); + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&new_rect); + ok(new_rect.left == old_rect.left, "No Font USEFONTINFO did not return zero\n"); + ok(new_rect.right == old_rect.right, "No Font USEFONTINFO did not return zero\n"); + ok(new_rect.top == old_rect.top, "No Font USEFONTINFO moved top margin\n"); + ok(new_rect.bottom == old_rect.bottom, "No Font USEFONTINFO moved bottom margin\n"); + + if (is_win9x) + { + skip ("Cannot perform EC_USEFONTINFO tests on Richedit 1.0 and 2.0 as lparam\n"); + return; + } + + /*Set test font to be Courier font */ + SendMessage(hwndRichEdit, WM_SETFONT, (WPARAM)testFont, MAKELPARAM(TRUE, 0)); + /*Verify font is set */ + SendMessage(hwndRichEdit, EM_GETCHARFORMAT, SCF_DEFAULT, (LPARAM) &CharFont1Unicode); + GetObjectW(testFont, sizeof(LOGFONTW), &sentLogFont); + ok (!strcmp(sentLogFont.lfFaceName, CharFont1Unicode.szFaceName), "WM_SETFONT set wrong font. Font was set to %s, was supposed to be \"Courier\".\n", CharFont1Unicode.szFaceName); + + ret = GetTextMetricsW (hdc, &tmw); + ok (ret, "GetTextMetricsW failed\n"); + + ok (0 == tmw.tmAveCharWidth, "Average Character Width for Courier 12 is %d\n", tmw.tmAveCharWidth); + + SendMessage(hwndRichEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, 0); + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&old_rect); + /* This seems to do nothing with Windows 7 + SendMessage(hwndRichEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN | EC_USEFONTINFO, MAKELONG(0, 0)); */ + ok(new_rect.left == old_rect.left, "wParam Courier EC_LEFT/RIGHT/USEFONTINFO Zero Left did not return non-zero, value is %d\n", new_rect.left); + ok(new_rect.right == old_rect.right, "wParam Courier EC_LEFT/RIGHT/USEFONTINFO Zero Right did not return non-zero, value is %d\n", new_rect.right); + ok(new_rect.top == old_rect.top, "wParam USEFONTINFO 10 moved top margin\n"); + ok(new_rect.bottom == old_rect.bottom, "wParam USEFONTINFO 10 moved bottom margin\n"); + + /* Per http://www.piclist.com/techref/os/win/api/win32/mess/src/msg06_7.htm the Left Margin + should be set to the 'C' value, that is the value used to set white space after a character + and the Right Margin should be set to the 'A' value, that is the value use to set white space to the + current position before drawing the next character. The margin value passed in the lParam variable + is ignored */ + SendMessage(hwndRichEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_USEFONTINFO, MAKELONG(10, 10)); + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&new_rect); + ok(new_rect.left == old_rect.left, "wParam Courier USEFONTINFO Left did not return non-zero, value is %d\n", new_rect.left); + ok(new_rect.right == old_rect.right, "wParam Courier USEFONTINFO Right did not return non-zero, value is %d\n", new_rect.right); + ok(new_rect.top == old_rect.top, "wParam USEFONTINFO 10 moved top margin\n"); + ok(new_rect.bottom == old_rect.bottom, "wParam USEFONTINFO 10 moved bottom margin\n"); + + /* Per http://msdn.microsoft.com/en-us/library/bb761649%(VS.85).asp if the lparam is + EC_USEFONTINFO the Left and Right Margins should be set to a narrow width if the + font has been set */ + + SendMessage(hwndRichEdit, EM_SETMARGINS, EC_LEFTMARGIN, MAKELONG(EC_USEFONTINFO, 0)); + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&new_rect); + ok(new_rect.left == old_rect.left, "lParam Courier USEFONTINFO Left did not return zero, value is %d\n", new_rect.left); + ok(new_rect.right == old_rect.right, "lParam Courier USEFONTINFO Right did not return zero, value is %d\n", new_rect.right); + ok(new_rect.top == old_rect.top, "lParam Courier USEFONTINFO moved top margin\n"); + ok(new_rect.bottom == old_rect.bottom, "Unset USEFONTINFO moved bottom margin\n"); + + SendMessage(hwndRichEdit, EM_SETMARGINS, EC_USEFONTINFO, MAKELONG(5, 5)); + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&new_rect); + ok(new_rect.left == old_rect.left +5 , "wParam with margin of 5 USEFONTINFO Left did not return zero, value is %d\n", new_rect.left); + ok(new_rect.right == old_rect.right - 5, "wParam with margin of 5 USEFONTINFO Right did not return zero, value is %d\n", new_rect.right); + ok(new_rect.top == old_rect.top, "Top USEFONTINFO moved top margin\n"); + ok(new_rect.bottom == old_rect.bottom, "Bottom USEFONTINFO moved bottom margin\n"); + + /*Set test font to be MS San Serif font (for reliable tests) */ + SendMessage(hwndRichEdit, WM_SETFONT, (WPARAM)testFont2, MAKELPARAM(TRUE, 0)); + /*Verify font is set */ + SendMessage(hwndRichEdit, EM_GETCHARFORMAT, SCF_DEFAULT, (LPARAM) &CharFont1Unicode); + GetObjectW(testFont2, sizeof(LOGFONTW), &sentLogFont); + ok (!strcmp(sentLogFont.lfFaceName, CharFont1Unicode.szFaceName), "WM_SETFONT set wrong font." \ + "Font was set to %s, was supposed to be \"MS Sans Serif\".\n", CharFont1Unicode.szFaceName); + + ret = GetTextMetricsW (hdc, &tmw); + ok (ret, "GetTextMetricsW failed\n"); + + ok (0 == tmw.tmAveCharWidth, "Average Character Width for MS Sans Serif is %d\n", tmw.tmAveCharWidth); + + SendMessage(hwndRichEdit, EM_SETMARGINS, EC_LEFTMARGIN, MAKELONG(EC_USEFONTINFO, 0)); + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&new_rect); + ok(new_rect.left == old_rect.left, "lParam MS Sans Serif USEFONTINFO Left did not return zero, value is %d\n", new_rect.left); + ok(new_rect.right == old_rect.right, "lParam MS Sans Serif USEFONTINFO Right did not return zero, value is %d\n", new_rect.right); + ok(new_rect.top == old_rect.top, "USEFONTINFO moved top margin\n"); + ok(new_rect.bottom == old_rect.bottom, "USEFONTINFO moved bottom margin\n"); + + /* reset rect to original settings */ + SendMessage(hwndRichEdit, EM_SETRECT, 0, (LPARAM)&old_rect); + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&old_rect); + + /*Set test font to be Arial font at a height of 16 */ + SendMessage(hwndRichEdit, WM_SETFONT, (WPARAM)hfont, MAKELPARAM(TRUE, 0)); + /*Verify font is set to Arial */ + SendMessage(hwndRichEdit, EM_GETCHARFORMAT, SCF_DEFAULT, (LPARAM) &CharFont1Unicode); + GetObjectW(hfont, sizeof(LOGFONTW), &sentLogFont); + ok (!strcmp(sentLogFont.lfFaceName, CharFont1Unicode.szFaceName), "WM_SETFONT set wrong font. Font was set to %s, was supposed to be \"Arial\".\n", CharFont1Unicode.szFaceName); + + ret = GetTextMetricsW (hdc, &tmw); + ok (ret, "GetTextMetricsW failed\n"); + + ok (0 == tmw.tmAveCharWidth, "Average Character Width for Arial 16 is %d\n", tmw.tmAveCharWidth); + + SendMessageW(hwndRichEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(0,0)); + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&new_rect); + ok(new_rect.left == old_rect.left, "Arial Left Zero did not return zero, old value is %d, new value is %d\n", old_rect.left, new_rect.left); + ok(new_rect.right == old_rect.right, "Arial Right Zero did not return zero, old value is %d, new value is %d\n", old_rect.right, new_rect.right); + ok(new_rect.top == old_rect.top, "Arial moved top margin\n"); + ok(new_rect.bottom == old_rect.bottom, "Arial moved bottom margin\n"); + + /* Set Left Margin to 1 */ + SendMessageW(hwndRichEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,0)); + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&new_rect); + ok(new_rect.left == old_rect.left + 1, "Set Left Margin for Arial to one, got %d\n", new_rect.left); + ok(new_rect.right == old_rect.right, "Set Left Margin to one for Arial. Right margin moved, got %d\n", new_rect.right); + + /* Set Left and Right margins to 1 */ + SendMessageW(hwndRichEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,1)); + SendMessageW(hwndRichEdit, WM_SETFONT, (WPARAM)testFont3, 0); + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&new_rect); + ok(new_rect.left == old_rect.left + 1, "Set Left Margin for Arial, should be 1, got %d\n", new_rect.left); + ok(new_rect.right == old_rect.right - 1, "Set Right Margin (1) for Arial, should be %d, got %d\n", old_rect.right, new_rect.right); + + /* Set margins using EC_USEFONTINFO */ + SendMessageW(hwndRichEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO,EC_USEFONTINFO)); + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&new_rect); + ok(new_rect.left == old_rect.left + 1, "Set Left Margin (USEFONTINFO) for Arial 16 pt, should be 1, got %d\n", new_rect.left); + ok(new_rect.right == old_rect.right - 1, "Set Right Margin (USEFONTINFO) for Arial 16 pt, should be %d, got %d\n",old_rect.right - 1, new_rect.right); + + /* Set margins using EC_USEFONTINFO wParam */ + SendMessageW(hwndRichEdit, EM_SETMARGINS, EC_USEFONTINFO, MAKELONG(0,0)); + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&new_rect); + ok(new_rect.left == old_rect.left + 1, "Set Left Margin (USEFONTINFO wParam) for Arial, should be 1, got %d\n", new_rect.left); + ok(new_rect.right == old_rect.right - 1, "Set Right Margin (USEFONTINFO wParam) for Arial, should be %d, got %d\n",old_rect.right - 1, new_rect.right); + + /* Set Arial font to larger font size, margins should NOT move */ + SendMessageW(hwndRichEdit, WM_SETFONT, (WPARAM)hfont2, MAKELPARAM(TRUE, 0)); + SendMessage(hwndRichEdit, EM_GETCHARFORMAT, SCF_DEFAULT, (LPARAM) &CharFont1Unicode); + GetObjectW(hfont2, sizeof(LOGFONTW), &sentLogFont); + ok (!strcmp(sentLogFont.lfFaceName, CharFont1Unicode.szFaceName), "WM_SETFONT set wrong font. Font was set to %s, was supposed to be \"Arial\".\n", CharFont1Unicode.szFaceName); + + ret = GetTextMetricsW (hdc, &tmw); + ok (ret, "GetTextMetricsW failed\n"); + + ok (0 == tmw.tmAveCharWidth, "Average Character Width for Arial 30 is %d\n", tmw.tmAveCharWidth); + + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&new_rect); + ok(new_rect.left == old_rect.left + 1, "Set Left Margin for Arial 30 pt, should be 1, got %d\n", new_rect.left); + ok(new_rect.right == old_rect.right - 1, "Set Right Margin for Arial 30 pt, should be %d, got %d\n",old_rect.left -1, new_rect.right); + + /* Above a certain size threshold then the margin is updated */ + SendMessageW(hwndRichEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,0)); + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&new_rect); + ok(new_rect.left == old_rect.left + 1, "Set Left Margin Arial 30pt did not return one, value is %d\n", new_rect.left); + ok(new_rect.right == old_rect.right, "Set Right Margin to zero for Arial 30pt Right did not return zero, value is %d\n", new_rect.right); + + SendMessageW(hwndRichEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,1)); + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&new_rect); + ok(new_rect.left == old_rect.left +1 , "Set Left Margin Arial 30 pt to one did not return one, value is %d\n", new_rect.left); + ok(new_rect.right == old_rect.right -1, "Set Right Margin Arial 30 to one did not return %d, value is %d\n", old_rect.left -1, new_rect.right); + + SendMessageW(hwndRichEdit, EM_SETMARGINS, EC_USEFONTINFO, MAKELONG(10,10)); + SendMessage(hwndRichEdit, EM_GETRECT, 0, (LPARAM)&new_rect); + ok(new_rect.left == old_rect.left, "Set Left Margin Arial 30pt to USEFONTINFO (wParam) did not return zero, value is %d\n", new_rect.left); + ok(new_rect.right == old_rect.right, "Set Right Margin Arial 30pt to USEFONTINFO (wParam) did not return zero, value is %d\n", new_rect.right); + + ReleaseDC (hwndRichEdit, hdc); + DeleteObject(testFont); + DeleteObject(testFont2); + DeleteObject(testFont4); + DeleteObject(testFont3); + DeleteObject(hfont); + DeleteObject(hfont2); + DestroyWindow (hwndRichEdit); +} + START_TEST( editor ) { @@ -7077,6 +7355,7 @@ START_TEST( editor ) is_win9x = GetVersion() & 0x80000000; + if (winetest_debug > 1) { test_WM_CHAR(); test_EM_FINDTEXT(); test_EM_GETLINE(); @@ -7125,6 +7404,8 @@ START_TEST( editor ) test_WM_GETDLGCODE(); test_zoom(); test_dialogmode(); + } + test_em_setmargins(); /* Set the environment variable WINETEST_RICHED20 to keep windows * responsive and open for 30 seconds. This is useful for debugging.