Huw Davies : user32: Only adjust the margins if the edit control is above a certain size.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Mar 22 15:09:02 CST 2006


Module: wine
Branch: refs/heads/master
Commit: c4b44245fbb188218fedba2ad3e33ee2f4086338
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=c4b44245fbb188218fedba2ad3e33ee2f4086338

Author: Huw Davies <huw at codeweavers.com>
Date:   Wed Mar 22 12:16:44 2006 +0000

user32: Only adjust the margins if the edit control is above a certain size.

---

 dlls/user/edit.c       |   35 ++++++++++++++--
 dlls/user/tests/edit.c |  103 +++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 130 insertions(+), 8 deletions(-)

diff --git a/dlls/user/edit.c b/dlls/user/edit.c
index 98cf736..ed013af 100644
--- a/dlls/user/edit.c
+++ b/dlls/user/edit.c
@@ -246,7 +246,7 @@ static void	EDIT_EM_ScrollCaret(EDITSTAT
 static void	EDIT_EM_SetHandle(EDITSTATE *es, HLOCAL hloc);
 static void	EDIT_EM_SetHandle16(EDITSTATE *es, HLOCAL16 hloc);
 static void	EDIT_EM_SetLimitText(EDITSTATE *es, INT limit);
-static void	EDIT_EM_SetMargins(EDITSTATE *es, INT action, INT left, INT right, BOOL repaint);
+static void	EDIT_EM_SetMargins(EDITSTATE *es, INT action, WORD left, WORD right, BOOL repaint);
 static void	EDIT_EM_SetPasswordChar(EDITSTATE *es, WCHAR c);
 static void	EDIT_EM_SetSel(EDITSTATE *es, UINT start, UINT end, BOOL after_wrap);
 static BOOL	EDIT_EM_SetTabStops(EDITSTATE *es, INT count, LPINT tabs);
@@ -747,7 +747,7 @@ static LRESULT WINAPI EditWndProc_common
 	/* The following EM_xxx are new to win95 and don't exist for 16 bit */
 
 	case EM_SETMARGINS:
-		EDIT_EM_SetMargins(es, (INT)wParam, (short)LOWORD(lParam), (short)HIWORD(lParam), TRUE);
+		EDIT_EM_SetMargins(es, (INT)wParam, LOWORD(lParam), HIWORD(lParam), TRUE);
 		break;
 
 	case EM_GETMARGINS:
@@ -2326,7 +2326,7 @@ static void EDIT_SetCaretPos(EDITSTATE *
 static void EDIT_AdjustFormatRect(EDITSTATE *es)
 {
 	RECT ClientRect;
-	
+
 	es->format_rect.right = max(es->format_rect.right, es->format_rect.left + es->char_width);
 	if (es->style & ES_MULTILINE)
 	{
@@ -3660,9 +3660,24 @@ static void EDIT_EM_SetLimitText(EDITSTA
  * of the char's width as the margin, but this is not how Windows handles this.
  * For all other fonts Windows sets the margins to zero.
  *
+ * FIXME - When EC_USEFONTINFO is used the margins only change if the
+ * edit control is equal to or larger than a certain size.
+ * Interestingly if one subtracts both the left and right margins from
+ * this size one always seems to get an even number.  The extents of
+ * the (four character) string "'**'" match this quite closely, so
+ * we'll use this until we come up with a better idea.
  */
+static int calc_min_set_margin_size(HDC dc, INT left, INT right)
+{
+    WCHAR magic_string[] = {'\'','*','*','\'', 0};
+    SIZE sz;
+
+    GetTextExtentPointW(dc, magic_string, sizeof(magic_string)/sizeof(WCHAR) - 1, &sz);
+    return sz.cx + left + right;
+}
+
 static void EDIT_EM_SetMargins(EDITSTATE *es, INT action,
-			       INT left, INT right, BOOL repaint)
+			       WORD left, WORD right, BOOL repaint)
 {
 	TEXTMETRICW tm;
 	INT default_left_margin  = 0; /* in pixels */
@@ -3675,9 +3690,17 @@ static void EDIT_EM_SetMargins(EDITSTATE
             GetTextMetricsW(dc, &tm);
             /* The default margins are only non zero for TrueType or Vector fonts */
             if (tm.tmPitchAndFamily & ( TMPF_VECTOR | TMPF_TRUETYPE )) {
+                int min_size;
+                RECT rc;
                 /* This must be calculated more exactly! But how? */
-                default_left_margin = tm.tmAveCharWidth / 3;
-                default_right_margin = tm.tmAveCharWidth / 3;
+                default_left_margin = tm.tmAveCharWidth / 2;
+                default_right_margin = tm.tmAveCharWidth / 2;
+                min_size = calc_min_set_margin_size(dc, default_left_margin, default_right_margin);
+                GetClientRect(es->hwndSelf, &rc);
+                if(rc.right - rc.left < min_size) {
+                    default_left_margin = es->left_margin;
+                    default_right_margin = es->right_margin;
+                }
             }
             SelectObject(dc, old_font);
             ReleaseDC(es->hwndSelf, dc);
diff --git a/dlls/user/tests/edit.c b/dlls/user/tests/edit.c
index 1a830c2..e880ea2 100644
--- a/dlls/user/tests/edit.c
+++ b/dlls/user/tests/edit.c
@@ -760,10 +760,108 @@ static void test_margins(void)
     ok(new_rect.right == old_rect.right, "The right border of the rectangle has changed\n");
     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");
-    
+
     DestroyWindow (hwEdit);
 }
 
+static INT CALLBACK find_font_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
+{
+    return 0;
+}
+
+static void test_margins_font_change(void)
+{
+    HWND hwEdit;
+    DWORD margins, font_margins;
+    LOGFONT lf;
+    HFONT hfont, hfont2;
+    HDC hdc = GetDC(0);
+
+    if(EnumFontFamiliesA(hdc, "Arial", find_font_proc, 0))
+    {
+        trace("Arial not found - skipping font change margin tests\n");
+        ReleaseDC(0, hdc);
+        return;
+    }
+    ReleaseDC(0, hdc);
+
+    hwEdit = create_child_editcontrol(0, 0);
+
+    SetWindowPos(hwEdit, NULL, 10, 10, 1000, 100, SWP_NOZORDER | SWP_NOACTIVATE);
+
+    memset(&lf, 0, sizeof(lf));
+    strcpy(lf.lfFaceName, "Arial");
+    lf.lfHeight = 16;
+    lf.lfCharSet = DEFAULT_CHARSET;
+    hfont = CreateFontIndirectA(&lf);
+    lf.lfHeight = 30;
+    hfont2 = CreateFontIndirectA(&lf);
+
+    SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
+    font_margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
+    ok(LOWORD(font_margins) != 0, "got %d\n", LOWORD(font_margins));
+    ok(HIWORD(font_margins) != 0, "got %d\n", HIWORD(font_margins));
+
+    /* With 'small' edit controls, test that the margin doesn't get set */
+    SetWindowPos(hwEdit, NULL, 10, 10, 16, 100, SWP_NOZORDER | SWP_NOACTIVATE);
+    SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(0,0));
+    SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
+    margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
+    ok(LOWORD(margins) == 0, "got %d\n", LOWORD(margins));
+    ok(HIWORD(margins) == 0, "got %d\n", HIWORD(margins));
+ 
+    SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,0));
+    SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
+    margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
+    ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
+    ok(HIWORD(margins) == 0, "got %d\n", HIWORD(margins));  
+
+    SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,1));
+    SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
+    margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
+    ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
+    ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins));  
+
+    SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO,EC_USEFONTINFO));
+    margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
+    ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
+    ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins)); 
+    SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0);
+    margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
+    ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins));
+    ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins)); 
+ 
+    /* Above a certain size threshold then the margin is updated */
+    SetWindowPos(hwEdit, NULL, 10, 10, 1000, 100, SWP_NOZORDER | SWP_NOACTIVATE);
+    SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,0));
+    SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
+    margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
+    ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
+    ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins)); 
+
+    SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,1));
+    SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
+    margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
+    ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
+    ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins)); 
+
+    SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO,EC_USEFONTINFO));
+    margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
+    ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins));
+    ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins)); 
+    SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0);
+    margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
+    ok(LOWORD(margins) != LOWORD(font_margins), "got %d\n", LOWORD(margins));
+    ok(HIWORD(margins) != HIWORD(font_margins), "got %d\n", HIWORD(margins)); 
+
+    SendMessageA(hwEdit, WM_SETFONT, 0, 0);
+    
+    DeleteObject(hfont2);
+    DeleteObject(hfont);
+    destroy_child_editcontrol(hwEdit);
+
+}
+
 #define edit_pos_ok(exp, got, txt) \
     ok(exp == got, "wrong " #txt " expected %d got %ld\n", exp, got);
 
@@ -968,7 +1066,8 @@ START_TEST(edit)
     test_edit_control_4();
     test_edit_control_5();
     test_margins();
+    test_margins_font_change();
     test_text_position();
-    
+
     UnregisterWindowClasses();
 }




More information about the wine-cvs mailing list