edit control: add support for ES_RIGHT and ES_CENTER

Lauri Tulmin lauri_ at ut.ee
Sat Sep 25 11:57:53 CDT 2004


Changelog:
- add support for ES_RIGHT and ES_CENTER
-------------- next part --------------
--- dlls/user/edit.c	2004-09-25 15:26:34.890945792 +0300
+++ dlls/user/edit.c	2004-09-25 15:31:15.026358736 +0300
@@ -21,8 +21,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * TODO:
- *   - ES_CENTER
- *   - ES_RIGHT
  *   - ES_OEMCONVERT
  *   -!ES_AUTOVSCROLL (every multi line control *is* auto vscroll)
  *   -!ES_AUTOHSCROLL (every single line control *is* auto hscroll)
@@ -1255,9 +1253,13 @@
 		rc.top = es->format_rect.top + nstart_line * es->line_height -
 			(es->y_offset * es->line_height); /* Adjust for vertical scrollbar */
 		rc.bottom = rc.top + es->line_height;
-		rc.left = es->format_rect.left + (INT)LOWORD(GetTabbedTextExtentW(dc,
+		if ((es->style & ES_RIGHT) || (es->style & ES_CENTER)) {
+			rc.left = es->format_rect.left;
+		} else {
+			rc.left = es->format_rect.left + (INT)LOWORD(GetTabbedTextExtentW(dc,
 					es->text + nstart_index, istart - nstart_index,
 					es->tabs_count, es->tabs)) - es->x_offset; /* Adjust for horz scroll */
+		}
 		rc.right = es->format_rect.right;
 		SetRectRgn(hrgn, rc.left, rc.top, rc.right, rc.bottom);
 
@@ -1293,7 +1295,8 @@
  */
 static void EDIT_CalcLineWidth_SL(EDITSTATE *es)
 {
-    es->text_width = (short)LOWORD(EDIT_EM_PosFromChar(es, strlenW(es->text), FALSE));
+	es->text_width = (short)LOWORD(EDIT_EM_PosFromChar(es, strlenW(es->text), FALSE)) -
+		(short)LOWORD(EDIT_EM_PosFromChar(es, 0, FALSE));
 }
 
 /*********************************************************************
@@ -1386,6 +1389,8 @@
 	INT index;
 	HDC dc;
 	HFONT old_font = 0;
+	INT line_width;
+	INT fw = es->format_rect.right - es->format_rect.left;
 
 	if (es->style & ES_MULTILINE) {
 		INT line = (y - es->format_rect.top) / es->line_height + es->y_offset;
@@ -1397,7 +1402,13 @@
 			line_def = line_def->next;
 			line--;
 		}
-		x += es->x_offset - es->format_rect.left;
+		line_width = line_def->width;
+		if ((es->style & ES_RIGHT) && (fw > line_width))
+			x -= es->format_rect.right - line_width;
+		else if ((es->style & ES_CENTER) && (fw > line_width))
+			x -= es->format_rect.left + (fw - line_width) / 2;
+		else
+			x += es->x_offset - es->format_rect.left;
 		if (x >= line_def->width) {
 			if (after_wrap)
 				*after_wrap = (line_def->ending == END_WRAP);
@@ -1429,13 +1440,21 @@
 		SIZE size;
 		if (after_wrap)
 			*after_wrap = FALSE;
-		x -= es->format_rect.left;
-		if (!x)
-			return es->x_offset;
 		text = EDIT_GetPasswordPointer_SL(es);
 		dc = GetDC(es->hwndSelf);
 		if (es->font)
 			old_font = SelectObject(dc, es->font);
+
+		GetTextExtentPoint32W( dc, text, strlenW(es->text), &size );
+		line_width = size.cx;
+		if ((es->style & ES_RIGHT) && (fw > line_width))
+			x -= es->format_rect.right - line_width;
+		else if ((es->style & ES_CENTER) && (fw > line_width))
+			x -= es->format_rect.left + (fw - line_width) / 2;
+		else
+			x -= es->format_rect.left;
+		if (!x)
+			return es->x_offset;
 		if (x < 0)
                 {
                     INT low = 0;
@@ -2835,39 +2854,43 @@
 static LRESULT EDIT_EM_PosFromChar(EDITSTATE *es, INT index, BOOL after_wrap)
 {
 	INT len = strlenW(es->text);
-	INT l;
-	INT li;
 	INT x;
 	INT y = 0;
 	HDC dc;
 	HFONT old_font = 0;
 	SIZE size;
+	INT line_width;
 
 	index = min(index, len);
 	dc = GetDC(es->hwndSelf);
 	if (es->font)
 		old_font = SelectObject(dc, es->font);
 	if (es->style & ES_MULTILINE) {
-		l = EDIT_EM_LineFromChar(es, index);
+		INT l = 0;
+		LINEDEF *line_def = es->first_line_def;
+		INT li = index - line_def->length;
+		LINEDEF *previous = NULL;
+		while ((li >= 0) && line_def->next) {
+			l++;
+			previous = line_def;
+			line_def = line_def->next;
+			li -= line_def->length;
+		}
+		li = index - li - line_def->length; /* starting index of line */
 		y = (l - es->y_offset) * es->line_height;
-		li = EDIT_EM_LineIndex(es, l);
 		if (after_wrap && (li == index) && l) {
-			INT l2 = l - 1;
-			LINEDEF *line_def = es->first_line_def;
-			while (l2) {
-				line_def = line_def->next;
-				l2--;
-			}
-			if (line_def->ending == END_WRAP) {
-				l--;
+			if (previous->ending == END_WRAP) {
 				y -= es->line_height;
-				li = EDIT_EM_LineIndex(es, l);
+				li -= previous->length;
 			}
 		}
+		line_width = line_def->width;
 		x = LOWORD(GetTabbedTextExtentW(dc, es->text + li, index - li,
 				es->tabs_count, es->tabs)) - es->x_offset;
 	} else {
 		LPWSTR text = EDIT_GetPasswordPointer_SL(es);
+		GetTextExtentPoint32W(dc, text, strlenW(es->text), &size);
+		line_width = size.cx;
 		if (index < es->x_offset) {
 			GetTextExtentPoint32W(dc, text + index,
 					es->x_offset - index, &size);
@@ -2881,7 +2904,15 @@
 		if (es->style & ES_PASSWORD)
 			HeapFree(GetProcessHeap(), 0, text);
 	}
-	x += es->format_rect.left;
+	if ((es->style & ES_RIGHT) && 
+		(es->format_rect.right - es->format_rect.left > line_width)) {
+		x += es->format_rect.right - line_width;
+	} else if ((es->style & ES_CENTER) && 
+		(es->format_rect.right - es->format_rect.left > line_width)) {
+		x += (es->format_rect.left + es->format_rect.right - line_width) / 2;
+	} else {
+		x += es->format_rect.left;
+	}
 	y += es->format_rect.top;
 	if (es->font)
 		SelectObject(dc, old_font);
@@ -3150,6 +3181,20 @@
 			/* FIXME: use ScrollWindow() somehow to improve performance */
 			EDIT_UpdateText(es, NULL, TRUE);
 		}
+
+		if ((es->style & ES_CENTER) || (es->style & ES_RIGHT)) {
+			INT good_offset = es->x_offset;
+			x = (short)LOWORD(EDIT_EM_PosFromChar(es, strlenW(es->text), FALSE));
+			while (es->x_offset > 0 && x < es->format_rect.right) {
+				good_offset = es->x_offset;
+				es->x_offset--;
+				x = (short)LOWORD(EDIT_EM_PosFromChar(es, strlenW(es->text), FALSE));
+			}
+			if (x > es->format_rect.right) {
+				es->x_offset = good_offset;
+			}
+			EDIT_UpdateText(es, NULL, TRUE);
+		}
 	}
 
     if(es->flags & EF_FOCUSED)
@@ -4393,8 +4438,10 @@
 		es->style |= ES_AUTOVSCROLL;
 	} else {
 		es->buffer_limit = BUFLIMIT_SINGLE;
-		es->style &= ~ES_CENTER;
-		es->style &= ~ES_RIGHT;
+		if ((es->style & ES_CENTER) || (es->style & ES_RIGHT)) {
+			if (es->style & ES_RIGHT)
+				es->style &= ~ES_CENTER;
+		}
 		es->style &= ~WS_HSCROLL;
 		es->style &= ~WS_VSCROLL;
 		es->style &= ~ES_AUTOVSCROLL;


More information about the wine-patches mailing list