Make controls redraw themselves immediately in certain situations
Michael Kaufmann
hallo at michael-kaufmann.ch
Sat Oct 9 17:42:23 CDT 2004
I've sent this patch to wine-devel before, please have a look for
explanations and a demo program:
http://www.winehq.org/hypermail/wine-devel/2004/09/0535.html
Changelog:
- Combobox: Redraw immediately if the current selection is changed
- Edit control: Redraw immediately if the user types something and
upon EM_REPLACESEL, EM_SETSEL, WM_CLEAR, WM_PASTE, WM_CUT
- Listbox: Redraw immediately if the current selection is changed and
upon LB_SETCURSEL, LB_SETTOPINDEX
- Static control: Redraw immediately if the text is changed
- Progress control: Redraw immediately if the "progress value" is changed
- Statusbar: Redraw immediately if the displayed text is changed
- Tab control: Redraw immediately if the tab is changed
- Trackbar: Redraw immediately if the thumb position or the selection
is changed
- Treeview: Redraw before sending a notification message if the user
changes the selection
- Added new tests
-------------- next part --------------
Index: dlls/comctl32/progress.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/progress.c,v
retrieving revision 1.38
diff -u -r1.38 progress.c
--- dlls/comctl32/progress.c 25 Aug 2004 17:33:01 -0000 1.38
+++ dlls/comctl32/progress.c 9 Oct 2004 21:17:51 -0000
@@ -485,7 +485,7 @@
infoPtr->MinVal = low;
infoPtr->MaxVal = high;
PROGRESS_CoercePos(infoPtr);
- InvalidateRect(infoPtr->Self, NULL, TRUE);
+ RedrawWindow(infoPtr->Self, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UPDATENOW);
return res;
}
@@ -562,6 +562,7 @@
PROGRESS_CoercePos (infoPtr);
TRACE("PBM_DELTAPOS: current pos changed from %d to %d\n", oldVal, infoPtr->CurVal);
PROGRESS_Invalidate( infoPtr, oldVal, infoPtr->CurVal );
+ UpdateWindow(infoPtr->Self);
}
return oldVal;
}
@@ -575,6 +576,7 @@
PROGRESS_CoercePos(infoPtr);
TRACE("PBM_SETPOS: current pos changed from %d to %d\n", oldVal, infoPtr->CurVal);
PROGRESS_Invalidate( infoPtr, oldVal, infoPtr->CurVal );
+ UpdateWindow(infoPtr->Self);
}
return oldVal;
}
@@ -601,6 +603,7 @@
{
TRACE("PBM_STEPIT: current pos changed from %d to %d\n", oldVal, infoPtr->CurVal);
PROGRESS_Invalidate( infoPtr, oldVal, infoPtr->CurVal );
+ UpdateWindow(infoPtr->Self);
}
return oldVal;
}
Index: dlls/comctl32/status.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/status.c,v
retrieving revision 1.66
diff -u -r1.66 status.c
--- dlls/comctl32/status.c 14 Sep 2004 00:45:26 -0000 1.66
+++ dlls/comctl32/status.c 9 Oct 2004 21:17:52 -0000
@@ -539,14 +539,14 @@
return TRUE;
infoPtr->part0.hIcon = hIcon;
if (infoPtr->simple)
- InvalidateRect(infoPtr->Self, &infoPtr->part0.bound, FALSE);
+ RedrawWindow(infoPtr->Self, &infoPtr->part0.bound, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
} else {
if (infoPtr->parts[nPart].hIcon == hIcon) /* same as - no redraw */
return TRUE;
infoPtr->parts[nPart].hIcon = hIcon;
if (!(infoPtr->simple))
- InvalidateRect(infoPtr->Self, &infoPtr->parts[nPart].bound, FALSE);
+ RedrawWindow(infoPtr->Self, &infoPtr->parts[nPart].bound, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
}
return TRUE;
}
@@ -641,7 +641,7 @@
}
}
STATUSBAR_SetPartBounds (infoPtr);
- InvalidateRect(infoPtr->Self, NULL, FALSE);
+ RedrawWindow(infoPtr->Self, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
return TRUE;
}
@@ -708,7 +708,7 @@
Free (part->text);
part->text = ntext;
}
- InvalidateRect(infoPtr->Self, &part->bound, FALSE);
+ RedrawWindow(infoPtr->Self, &part->bound, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
return TRUE;
}
@@ -780,7 +780,8 @@
nmhdr.idFrom = GetWindowLongPtrW (infoPtr->Self, GWLP_ID);
nmhdr.code = SBN_SIMPLEMODECHANGE;
SendMessageW (infoPtr->Notify, WM_NOTIFY, 0, (LPARAM)&nmhdr);
- InvalidateRect(infoPtr->Self, NULL, FALSE);
+ RedrawWindow(infoPtr->Self, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
+
return TRUE;
}
@@ -839,9 +840,7 @@
i = SendMessageW(infoPtr->Notify, WM_NOTIFYFORMAT, (WPARAM)hwnd, NF_QUERY);
infoPtr->NtfUnicode = (i == NFR_UNICODE);
- GetClientRect (hwnd, &rect);
- InvalidateRect (hwnd, &rect, 0);
- UpdateWindow(hwnd);
+ RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
ZeroMemory (&nclm, sizeof(nclm));
nclm.cbSize = sizeof(nclm);
@@ -1051,7 +1050,7 @@
}
}
- InvalidateRect(infoPtr->Self, &part->bound, FALSE);
+ RedrawWindow(infoPtr->Self, &part->bound, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
return TRUE;
}
Index: dlls/comctl32/tab.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/tab.c,v
retrieving revision 1.100
diff -u -r1.100 tab.c
--- dlls/comctl32/tab.c 9 Oct 2004 02:27:00 -0000 1.100
+++ dlls/comctl32/tab.c 9 Oct 2004 21:17:54 -0000
@@ -239,6 +239,7 @@
infoPtr->iSelected=iItem;
TAB_EnsureSelectionVisible(hwnd, infoPtr);
TAB_InvalidateTabArea(hwnd, infoPtr);
+ UpdateWindow(hwnd);
}
return prevItem;
}
Index: dlls/comctl32/trackbar.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/trackbar.c,v
retrieving revision 1.62
diff -u -r1.62 trackbar.c
--- dlls/comctl32/trackbar.c 14 Sep 2004 00:45:26 -0000 1.62
+++ dlls/comctl32/trackbar.c 9 Oct 2004 21:17:55 -0000
@@ -375,12 +375,6 @@
TRACKBAR_CalcThumb(infoPtr, infoPtr->lPos, &infoPtr->rcThumb);
}
-static inline void
-TRACKBAR_InvalidateAll(TRACKBAR_INFO * infoPtr)
-{
- InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);
-}
-
static void
TRACKBAR_InvalidateThumb (TRACKBAR_INFO *infoPtr, LONG thumbPos)
{
@@ -951,7 +945,8 @@
infoPtr->lSelMax = 0;
infoPtr->flags |= TB_SELECTIONCHANGED;
- if (fRedraw) TRACKBAR_InvalidateAll(infoPtr);
+ if (fRedraw)
+ RedrawWindow(infoPtr->hwndSelf, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
return 0;
}
@@ -966,7 +961,8 @@
infoPtr->uNumTics = 0;
}
- if (fRedraw) TRACKBAR_InvalidateAll(infoPtr);
+ if (fRedraw)
+ RedrawWindow(infoPtr->hwndSelf, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
return 0;
}
@@ -1096,7 +1092,11 @@
infoPtr->lPos = infoPtr->lRangeMax;
infoPtr->flags |= TB_THUMBPOSCHANGED;
- if (fPosition) TRACKBAR_InvalidateThumbMove(infoPtr, oldPos, lPosition);
+ if (fPosition)
+ {
+ TRACKBAR_InvalidateThumbMove(infoPtr, oldPos, lPosition);
+ UpdateWindow(infoPtr->hwndSelf);
+ }
return 0;
}
@@ -1121,7 +1121,8 @@
infoPtr->lPageSize = (infoPtr->lRangeMax - infoPtr->lRangeMin) / 5;
if (infoPtr->lPageSize == 0) infoPtr->lPageSize = 1;
- if (fRedraw) TRACKBAR_InvalidateAll(infoPtr);
+ if (fRedraw)
+ RedrawWindow(infoPtr->hwndSelf, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
return 0;
}
@@ -1139,7 +1140,8 @@
infoPtr->lPageSize = (infoPtr->lRangeMax - infoPtr->lRangeMin) / 5;
if (infoPtr->lPageSize == 0) infoPtr->lPageSize = 1;
- if (fRedraw) TRACKBAR_InvalidateAll(infoPtr);
+ if (fRedraw)
+ RedrawWindow(infoPtr->hwndSelf, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
return 0;
}
@@ -1157,7 +1159,8 @@
infoPtr->lPageSize = (infoPtr->lRangeMax - infoPtr->lRangeMin) / 5;
if (infoPtr->lPageSize == 0) infoPtr->lPageSize = 1;
- if (fRedraw) TRACKBAR_InvalidateAll(infoPtr);
+ if (fRedraw)
+ RedrawWindow(infoPtr->hwndSelf, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
return 0;
}
@@ -1178,7 +1181,8 @@
if (infoPtr->lSelMax > infoPtr->lRangeMax)
infoPtr->lSelMax = infoPtr->lRangeMax;
- if (fRedraw) TRACKBAR_InvalidateAll(infoPtr);
+ if (fRedraw)
+ RedrawWindow(infoPtr->hwndSelf, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
return 0;
}
@@ -1196,7 +1200,8 @@
if (infoPtr->lSelMax > infoPtr->lRangeMax)
infoPtr->lSelMax = infoPtr->lRangeMax;
- if (fRedraw) TRACKBAR_InvalidateAll(infoPtr);
+ if (fRedraw)
+ RedrawWindow(infoPtr->hwndSelf, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
return 0;
}
@@ -1214,7 +1219,8 @@
if (infoPtr->lSelMin < infoPtr->lRangeMin)
infoPtr->lSelMin = infoPtr->lRangeMin;
- if (fRedraw) TRACKBAR_InvalidateAll(infoPtr);
+ if (fRedraw)
+ RedrawWindow(infoPtr->hwndSelf, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
return 0;
}
@@ -1226,7 +1232,7 @@
if (GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE) & TBS_FIXEDLENGTH) {
infoPtr->uThumbLen = iLength;
infoPtr->flags |= TB_THUMBSIZECHANGED;
- InvalidateRect (infoPtr->hwndSelf, &infoPtr->rcThumb, FALSE);
+ RedrawWindow(infoPtr->hwndSelf, &infoPtr->rcThumb, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
}
return 0;
@@ -1254,8 +1260,8 @@
}
infoPtr->tics[infoPtr->uNumTics-1] = lPos;
- TRACKBAR_InvalidateAll(infoPtr);
-
+ RedrawWindow(infoPtr->hwndSelf, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
+
return TRUE;
}
@@ -1266,7 +1272,7 @@
if (GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE) & TBS_AUTOTICKS) {
infoPtr->uTicFreq = wFreq;
TRACKBAR_RecalculateTics (infoPtr);
- TRACKBAR_InvalidateAll(infoPtr);
+ RedrawWindow(infoPtr->hwndSelf, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
}
return 0;
@@ -1412,7 +1418,7 @@
{
TRACE("\n");
infoPtr->bFocussed = FALSE;
- TRACKBAR_InvalidateAll(infoPtr);
+ InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);
return 0;
}
@@ -1496,7 +1502,7 @@
{
TRACE("\n");
infoPtr->bFocussed = TRUE;
- TRACKBAR_InvalidateAll(infoPtr);
+ InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);
return 0;
}
Index: dlls/comctl32/treeview.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/treeview.c,v
retrieving revision 1.156
diff -u -r1.156 treeview.c
--- dlls/comctl32/treeview.c 7 Oct 2004 17:34:31 -0000 1.156
+++ dlls/comctl32/treeview.c 9 Oct 2004 21:17:58 -0000
@@ -4162,7 +4162,9 @@
TREEVIEW_Invalidate(infoPtr, NULL);
break;
}
-
+
+ UpdateWindow(infoPtr->hwnd);
+
TRACE("Leaving state %d\n", newSelect ? newSelect->state : 0);
return TRUE;
}
Index: dlls/user/combo.c
===================================================================
RCS file: /home/wine/wine/dlls/user/combo.c,v
retrieving revision 1.3
diff -u -r1.3 combo.c
--- dlls/user/combo.c 6 Oct 2004 00:05:07 -0000 1.3
+++ dlls/user/combo.c 9 Oct 2004 21:18:10 -0000
@@ -1156,9 +1156,9 @@
SWP_NOACTIVATE | SWP_SHOWWINDOW);
- if( !(lphc->wState & CBF_NOREDRAW) )
- RedrawWindow( lphc->self, NULL, 0, RDW_INVALIDATE |
- RDW_ERASE | RDW_UPDATENOW | RDW_NOCHILDREN );
+ if( !(lphc->wState & CBF_NOREDRAW) && !IsRectEmpty(&lphc->buttonRect) )
+ RedrawWindow ( lphc->self, &lphc->buttonRect, 0, RDW_INVALIDATE |
+ RDW_ERASE | RDW_UPDATENOW);
EnableWindow( lphc->hWndLBox, TRUE );
if (GetCapture() != lphc->self)
@@ -1397,6 +1397,10 @@
CB_NOTIFY( lphc, CBN_SELCHANGE );
+ /* FIXME: Calling this before CB_NOTIFY looks much nicer,
+ but Windows does it this way */
+ UpdateWindow(lphc->self);
+
/* fall through */
case LBN_SETFOCUS:
Index: dlls/user/edit.c
===================================================================
RCS file: /home/wine/wine/dlls/user/edit.c,v
retrieving revision 1.5
diff -u -r1.5 edit.c
--- dlls/user/edit.c 8 Oct 2004 20:50:52 -0000 1.5
+++ dlls/user/edit.c 9 Oct 2004 21:18:13 -0000
@@ -247,7 +247,7 @@
static BOOL EDIT_EM_LineScroll(EDITSTATE *es, INT dx, INT dy);
static BOOL EDIT_EM_LineScroll_internal(EDITSTATE *es, INT dx, INT dy);
static LRESULT EDIT_EM_PosFromChar(EDITSTATE *es, INT index, BOOL after_wrap);
-static void EDIT_EM_ReplaceSel(EDITSTATE *es, BOOL can_undo, LPCWSTR lpsz_replace, BOOL send_update, BOOL honor_limit);
+static void EDIT_EM_ReplaceSel(EDITSTATE *es, BOOL can_undo, LPCWSTR lpsz_replace, BOOL send_update, BOOL honor_limit, BOOL drawImmediately);
static LRESULT EDIT_EM_Scroll(EDITSTATE *es, INT action);
static void EDIT_EM_ScrollCaret(EDITSTATE *es);
static void EDIT_EM_SetHandle(EDITSTATE *es, HLOCAL hloc);
@@ -255,7 +255,7 @@
static void EDIT_EM_SetLimitText(EDITSTATE *es, INT limit);
static void EDIT_EM_SetMargins(EDITSTATE *es, INT action, INT left, INT right);
static void EDIT_EM_SetPasswordChar(EDITSTATE *es, WCHAR c);
-static void EDIT_EM_SetSel(EDITSTATE *es, UINT start, UINT end, BOOL after_wrap);
+static void EDIT_EM_SetSel(EDITSTATE *es, UINT start, UINT end, BOOL after_wrap, BOOL drawImmediately);
static BOOL EDIT_EM_SetTabStops(EDITSTATE *es, INT count, LPINT tabs);
static BOOL EDIT_EM_SetTabStops16(EDITSTATE *es, INT count, LPINT16 tabs);
static void EDIT_EM_SetWordBreakProc(EDITSTATE *es, LPARAM lParam);
@@ -348,7 +348,7 @@
if(es->style & ES_READONLY)
return;
- EDIT_EM_ReplaceSel(es, TRUE, empty_stringW, TRUE, TRUE);
+ EDIT_EM_ReplaceSel(es, TRUE, empty_stringW, TRUE, TRUE, TRUE);
}
@@ -463,15 +463,15 @@
case EM_SETSEL16:
if ((short)LOWORD(lParam) == -1)
- EDIT_EM_SetSel(es, (UINT)-1, 0, FALSE);
+ EDIT_EM_SetSel(es, (UINT)-1, 0, FALSE, TRUE);
else
- EDIT_EM_SetSel(es, LOWORD(lParam), HIWORD(lParam), FALSE);
+ EDIT_EM_SetSel(es, LOWORD(lParam), HIWORD(lParam), FALSE, TRUE);
if (!wParam)
EDIT_EM_ScrollCaret(es);
result = 1;
break;
case EM_SETSEL:
- EDIT_EM_SetSel(es, wParam, lParam, FALSE);
+ EDIT_EM_SetSel(es, wParam, lParam, FALSE, TRUE);
EDIT_EM_ScrollCaret(es);
result = 1;
break;
@@ -626,7 +626,7 @@
MultiByteToWideChar(CP_ACP, 0, textA, -1, textW, countW);
}
- EDIT_EM_ReplaceSel(es, (BOOL)wParam, textW, TRUE, TRUE);
+ EDIT_EM_ReplaceSel(es, (BOOL)wParam, textW, TRUE, TRUE, TRUE);
result = 1;
if(!unicode)
@@ -1831,7 +1831,7 @@
e--;
}
}
- EDIT_EM_SetSel(es, extend ? es->selection_start : e, e, FALSE);
+ EDIT_EM_SetSel(es, extend ? es->selection_start : e, e, FALSE, TRUE);
EDIT_EM_ScrollCaret(es);
}
@@ -1857,7 +1857,7 @@
e = EDIT_CharFromPos(es, x, y + es->line_height, &after_wrap);
if (!extend)
s = e;
- EDIT_EM_SetSel(es, s, e, after_wrap);
+ EDIT_EM_SetSel(es, s, e, after_wrap, TRUE);
EDIT_EM_ScrollCaret(es);
}
@@ -1878,7 +1878,7 @@
HIWORD(EDIT_EM_PosFromChar(es, es->selection_end, es->flags & EF_AFTER_WRAP)), &after_wrap);
else
e = strlenW(es->text);
- EDIT_EM_SetSel(es, extend ? es->selection_start : e, e, after_wrap);
+ EDIT_EM_SetSel(es, extend ? es->selection_start : e, e, after_wrap, TRUE);
EDIT_EM_ScrollCaret(es);
}
@@ -1901,7 +1901,7 @@
e += 2;
}
}
- EDIT_EM_SetSel(es, extend ? es->selection_start : e, e, FALSE);
+ EDIT_EM_SetSel(es, extend ? es->selection_start : e, e, FALSE, TRUE);
EDIT_EM_ScrollCaret(es);
}
@@ -1923,7 +1923,7 @@
HIWORD(EDIT_EM_PosFromChar(es, es->selection_end, es->flags & EF_AFTER_WRAP)), NULL);
else
e = 0;
- EDIT_EM_SetSel(es, extend ? es->selection_start : e, e, FALSE);
+ EDIT_EM_SetSel(es, extend ? es->selection_start : e, e, FALSE, TRUE);
EDIT_EM_ScrollCaret(es);
}
@@ -1951,7 +1951,7 @@
&after_wrap);
if (!extend)
s = e;
- EDIT_EM_SetSel(es, s, e, after_wrap);
+ EDIT_EM_SetSel(es, s, e, after_wrap, TRUE);
EDIT_EM_ScrollCaret(es);
}
@@ -1979,7 +1979,7 @@
&after_wrap);
if (!extend)
s = e;
- EDIT_EM_SetSel(es, s, e, after_wrap);
+ EDIT_EM_SetSel(es, s, e, after_wrap, TRUE);
EDIT_EM_ScrollCaret(es);
}
@@ -2005,7 +2005,7 @@
e = EDIT_CharFromPos(es, x, y - es->line_height, &after_wrap);
if (!extend)
s = e;
- EDIT_EM_SetSel(es, s, e, after_wrap);
+ EDIT_EM_SetSel(es, s, e, after_wrap, TRUE);
EDIT_EM_ScrollCaret(es);
}
@@ -2037,7 +2037,7 @@
}
if (!extend)
s = e;
- EDIT_EM_SetSel(es, s, e, FALSE);
+ EDIT_EM_SetSel(es, s, e, FALSE, TRUE);
EDIT_EM_ScrollCaret(es);
}
@@ -2067,7 +2067,7 @@
}
if (!extend)
s = e;
- EDIT_EM_SetSel(es, s, e, FALSE);
+ EDIT_EM_SetSel(es, s, e, FALSE, TRUE);
EDIT_EM_ScrollCaret(es);
}
@@ -2917,7 +2917,7 @@
* FIXME: handle ES_NUMBER and ES_OEMCONVERT here
*
*/
-static void EDIT_EM_ReplaceSel(EDITSTATE *es, BOOL can_undo, LPCWSTR lpsz_replace, BOOL send_update, BOOL honor_limit)
+static void EDIT_EM_ReplaceSel(EDITSTATE *es, BOOL can_undo, LPCWSTR lpsz_replace, BOOL send_update, BOOL honor_limit, BOOL drawImmediately)
{
UINT strl = strlenW(lpsz_replace);
UINT tl = strlenW(es->text);
@@ -3029,7 +3029,7 @@
else
EDIT_CalcLineWidth_SL(es);
- EDIT_EM_SetSel(es, s, s, FALSE);
+ EDIT_EM_SetSel(es, s, s, FALSE, FALSE);
es->flags |= EF_MODIFIED;
if (send_update) es->flags |= EF_UPDATE;
if (hrgn)
@@ -3045,6 +3045,7 @@
/* force scroll info update */
EDIT_UpdateScrollInfo(es);
+ if (drawImmediately) UpdateWindow(es->hwndSelf);
if(es->flags & EF_UPDATE)
{
@@ -3441,7 +3442,7 @@
* In other words: this handler is OK
*
*/
-static void EDIT_EM_SetSel(EDITSTATE *es, UINT start, UINT end, BOOL after_wrap)
+static void EDIT_EM_SetSel(EDITSTATE *es, UINT start, UINT end, BOOL after_wrap, BOOL drawImmediately)
{
UINT old_start = es->selection_start;
UINT old_end = es->selection_end;
@@ -3486,6 +3487,8 @@
}
}
else EDIT_InvalidateText(es, start, old_end);
+
+ if (drawImmediately) UpdateWindow(es->hwndSelf);
}
@@ -3598,10 +3601,10 @@
TRACE("before UNDO:insertion length = %d, deletion buffer = %s\n",
es->undo_insert_count, debugstr_w(utext));
- EDIT_EM_SetSel(es, es->undo_position, es->undo_position + es->undo_insert_count, FALSE);
+ EDIT_EM_SetSel(es, es->undo_position, es->undo_position + es->undo_insert_count, FALSE, FALSE);
EDIT_EM_EmptyUndoBuffer(es);
- EDIT_EM_ReplaceSel(es, TRUE, utext, TRUE, TRUE);
- EDIT_EM_SetSel(es, es->undo_position, es->undo_position + es->undo_insert_count, FALSE);
+ EDIT_EM_ReplaceSel(es, TRUE, utext, TRUE, TRUE, FALSE);
+ EDIT_EM_SetSel(es, es->undo_position, es->undo_position + es->undo_insert_count, FALSE, FALSE);
/* send the notification after the selection start and end are set */
EDIT_NOTIFY_PARENT(es, EN_CHANGE, "EN_CHANGE");
EDIT_EM_ScrollCaret(es);
@@ -3636,7 +3639,7 @@
EDIT_MoveDown_ML(es, FALSE);
} else {
static const WCHAR cr_lfW[] = {'\r','\n',0};
- EDIT_EM_ReplaceSel(es, TRUE, cr_lfW, TRUE, TRUE);
+ EDIT_EM_ReplaceSel(es, TRUE, cr_lfW, TRUE, TRUE, TRUE);
}
}
break;
@@ -3644,7 +3647,7 @@
if ((es->style & ES_MULTILINE) && !(es->style & ES_READONLY))
{
static const WCHAR tabW[] = {'\t',0};
- EDIT_EM_ReplaceSel(es, TRUE, tabW, TRUE, TRUE);
+ EDIT_EM_ReplaceSel(es, TRUE, tabW, TRUE, TRUE, TRUE);
}
break;
case VK_BACK:
@@ -3653,7 +3656,7 @@
EDIT_WM_Clear(es);
else {
/* delete character left of caret */
- EDIT_EM_SetSel(es, (UINT)-1, 0, FALSE);
+ EDIT_EM_SetSel(es, (UINT)-1, 0, FALSE, TRUE);
EDIT_MoveBackward(es, TRUE);
EDIT_WM_Clear(es);
}
@@ -3680,7 +3683,7 @@
WCHAR str[2];
str[0] = c;
str[1] = '\0';
- EDIT_EM_ReplaceSel(es, TRUE, str, TRUE, TRUE);
+ EDIT_EM_ReplaceSel(es, TRUE, str, TRUE, TRUE, TRUE);
}
break;
}
@@ -3714,7 +3717,7 @@
EDIT_WM_Clear(es);
break;
case EM_SETSEL:
- EDIT_EM_SetSel(es, 0, (UINT)-1, FALSE);
+ EDIT_EM_SetSel(es, 0, (UINT)-1, FALSE, TRUE);
EDIT_EM_ScrollCaret(es);
break;
default:
@@ -3812,7 +3815,7 @@
EDIT_EM_EmptyUndoBuffer(es);
if (name && *name) {
- EDIT_EM_ReplaceSel(es, FALSE, name, FALSE, TRUE);
+ EDIT_EM_ReplaceSel(es, FALSE, name, FALSE, TRUE, FALSE);
/* if we insert text to the editline, the text scrolls out
* of the window, as the caret is placed after the insert
* pos normally; thus we reset es->selection... to 0 and
@@ -4178,17 +4181,17 @@
} else {
if (shift) {
/* delete character left of caret */
- EDIT_EM_SetSel(es, (UINT)-1, 0, FALSE);
+ EDIT_EM_SetSel(es, (UINT)-1, 0, FALSE, TRUE);
EDIT_MoveBackward(es, TRUE);
EDIT_WM_Clear(es);
} else if (control) {
/* delete to end of line */
- EDIT_EM_SetSel(es, (UINT)-1, 0, FALSE);
+ EDIT_EM_SetSel(es, (UINT)-1, 0, FALSE, TRUE);
EDIT_MoveEnd(es, TRUE);
EDIT_WM_Clear(es);
} else {
/* delete character right of caret */
- EDIT_EM_SetSel(es, (UINT)-1, 0, FALSE);
+ EDIT_EM_SetSel(es, (UINT)-1, 0, FALSE, TRUE);
EDIT_MoveForward(es, TRUE);
EDIT_WM_Clear(es);
}
@@ -4260,7 +4263,7 @@
ll = EDIT_EM_LineLength(es, e);
s = li + EDIT_CallWordBreakProc(es, li, e - li, ll, WB_LEFT);
e = li + EDIT_CallWordBreakProc(es, li, e - li, ll, WB_RIGHT);
- EDIT_EM_SetSel(es, s, e, FALSE);
+ EDIT_EM_SetSel(es, s, e, FALSE, TRUE);
EDIT_EM_ScrollCaret(es);
return 0;
}
@@ -4284,7 +4287,7 @@
SetCapture(es->hwndSelf);
EDIT_ConfinePoint(es, &x, &y);
e = EDIT_CharFromPos(es, x, y, &after_wrap);
- EDIT_EM_SetSel(es, (keys & MK_SHIFT) ? es->selection_start : e, e, after_wrap);
+ EDIT_EM_SetSel(es, (keys & MK_SHIFT) ? es->selection_start : e, e, after_wrap, TRUE);
EDIT_EM_ScrollCaret(es);
es->region_posx = es->region_posy = 0;
SetTimer(es->hwndSelf, 0, 100, NULL);
@@ -4343,7 +4346,7 @@
es->region_posx = (prex < x) ? -1 : ((prex > x) ? 1 : 0);
es->region_posy = (prey < y) ? -1 : ((prey > y) ? 1 : 0);
e = EDIT_CharFromPos(es, x, y, &after_wrap);
- EDIT_EM_SetSel(es, es->selection_start, e, after_wrap);
+ EDIT_EM_SetSel(es, es->selection_start, e, after_wrap, TRUE);
EDIT_SetCaretPos(es,es->selection_end,es->flags & EF_AFTER_WRAP);
return 0;
}
@@ -4553,7 +4556,7 @@
OpenClipboard(es->hwndSelf);
if ((hsrc = GetClipboardData(CF_UNICODETEXT))) {
src = (LPWSTR)GlobalLock(hsrc);
- EDIT_EM_ReplaceSel(es, TRUE, src, TRUE, TRUE);
+ EDIT_EM_ReplaceSel(es, TRUE, src, TRUE, TRUE, TRUE);
GlobalUnlock(hsrc);
}
CloseClipboard();
@@ -4654,20 +4657,20 @@
MultiByteToWideChar(CP_ACP, 0, textA, -1, text, countW);
}
- EDIT_EM_SetSel(es, 0, (UINT)-1, FALSE);
+ EDIT_EM_SetSel(es, 0, (UINT)-1, FALSE, FALSE);
if (text) {
TRACE("%s\n", debugstr_w(text));
- EDIT_EM_ReplaceSel(es, FALSE, text, FALSE, FALSE);
+ EDIT_EM_ReplaceSel(es, FALSE, text, FALSE, FALSE, FALSE);
if(!unicode)
HeapFree(GetProcessHeap(), 0, text);
} else {
static const WCHAR empty_stringW[] = {0};
TRACE("<NULL>\n");
- EDIT_EM_ReplaceSel(es, FALSE, empty_stringW, FALSE, FALSE);
+ EDIT_EM_ReplaceSel(es, FALSE, empty_stringW, FALSE, FALSE, FALSE);
}
es->x_offset = 0;
es->flags &= ~EF_MODIFIED;
- EDIT_EM_SetSel(es, 0, 0, FALSE);
+ EDIT_EM_SetSel(es, 0, 0, FALSE, FALSE);
/* Send the notification after the selection start and end have been set
* edit control doesn't send notification on WM_SETTEXT
* if it is multiline, or it is part of combobox
@@ -4910,7 +4913,7 @@
/*********************************************************************
*
- * EDIT_UpdateText
+ * EDIT_UpdateTextRegion
*
*/
static void EDIT_UpdateTextRegion(EDITSTATE *es, HRGN hrgn, BOOL bErase)
Index: dlls/user/listbox.c
===================================================================
RCS file: /home/wine/wine/dlls/user/listbox.c,v
retrieving revision 1.2
diff -u -r1.2 listbox.c
--- dlls/user/listbox.c 5 Oct 2004 22:31:00 -0000 1.2
+++ dlls/user/listbox.c 9 Oct 2004 21:18:16 -0000
@@ -2383,11 +2383,16 @@
!IS_MULTISELECT(descr))
descr->anchor_item = caret;
LISTBOX_MoveCaret( hwnd, descr, caret, TRUE );
-
if (descr->style & LBS_MULTIPLESEL)
descr->selected_item = caret;
else
LISTBOX_SetSelection( hwnd, descr, caret, TRUE, FALSE);
+
+ /* If the content has been scrolled, the new items
+ * need to be drawn immediately (Windows does it this way)
+ */
+ UpdateWindow(hwnd);
+
if (descr->style & LBS_NOTIFY)
{
if( descr->lphc )
@@ -2735,7 +2740,9 @@
case LB_SETTOPINDEX16:
case LB_SETTOPINDEX:
- return LISTBOX_SetTopItem( hwnd, descr, wParam, TRUE );
+ ret = LISTBOX_SetTopItem( hwnd, descr, wParam, TRUE );
+ UpdateWindow(hwnd); /* Windows does this too */
+ return ret;
case LB_SETCOLUMNWIDTH16:
case LB_SETCOLUMNWIDTH:
@@ -2854,7 +2861,9 @@
case LB_SETCURSEL:
if (IS_MULTISELECT(descr)) return LB_ERR;
LISTBOX_SetCaretIndex( hwnd, descr, wParam, TRUE );
- return LISTBOX_SetSelection( hwnd, descr, wParam, TRUE, FALSE );
+ ret = LISTBOX_SetSelection( hwnd, descr, wParam, TRUE, FALSE );
+ UpdateWindow(hwnd); /* Windows does this too */
+ return ret;
case LB_GETSELCOUNT16:
case LB_GETSELCOUNT:
Index: dlls/user/static.c
===================================================================
RCS file: /home/wine/wine/dlls/user/static.c,v
retrieving revision 1.2
diff -u -r1.2 static.c
--- dlls/user/static.c 5 Oct 2004 04:11:29 -0000 1.2
+++ dlls/user/static.c 9 Oct 2004 21:18:16 -0000
@@ -348,8 +348,6 @@
else
lResult = DefWindowProcA( hwnd, WM_SETTEXT, wParam, lParam );
}
- if (uMsg == WM_SETTEXT)
- STATIC_TryPaintFcn( hwnd, full_style );
break;
}
default:
@@ -360,9 +358,10 @@
else
lResult = DefWindowProcA( hwnd, WM_SETTEXT, wParam, lParam );
}
- if(uMsg == WM_SETTEXT)
- InvalidateRect(hwnd, NULL, TRUE);
}
+
+ STATIC_TryPaintFcn( hwnd, full_style );
+
return 1; /* success. FIXME: check text length */
case WM_SETFONT:
Index: dlls/user/tests/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/user/tests/Makefile.in,v
retrieving revision 1.11
diff -u -r1.11 Makefile.in
--- dlls/user/tests/Makefile.in 20 Jul 2004 22:09:14 -0000 1.11
+++ dlls/user/tests/Makefile.in 9 Oct 2004 21:18:16 -0000
@@ -14,6 +14,7 @@
input.c \
listbox.c \
msg.c \
+ redraw.c \
resource.c \
sysparams.c \
text.c \
--- /dev/null 2004-08-22 23:26:44.000000000 +0200
+++ dlls/user/tests/redraw.c 2004-10-09 23:34:18.000000000 +0200
@@ -0,0 +1,183 @@
+/* Unit test suite for redraw behaviour (standard controls)
+ *
+ * Copyright 2004 Michael Kaufmann
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <assert.h>
+#include <windows.h>
+
+#include "wine/test.h"
+
+static const CHAR parent_class[] = "RedrawWindowClass";
+
+static LRESULT WINAPI redraw_window_procA(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+ return DefWindowProcA(hwnd, msg, wparam, lparam);
+}
+
+void do_redraw_test ()
+{
+ int i;
+ HWND parent;
+ HWND handle;
+
+
+ /* Register a class for the parent window */
+
+ WNDCLASSA cls;
+
+ cls.style = CS_HREDRAW | CS_VREDRAW;
+ cls.lpfnWndProc = redraw_window_procA;
+ cls.cbClsExtra = 0;
+ cls.cbWndExtra = 0;
+ cls.hInstance = GetModuleHandleA(0);
+ cls.hIcon = LoadIconA(NULL, IDI_APPLICATION);
+ cls.hCursor = LoadCursorA(NULL, (LPSTR)IDC_ARROW);
+ cls.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
+ cls.lpszMenuName = NULL;
+ cls.lpszClassName = parent_class;
+
+ assert(RegisterClassA(&cls));
+
+
+ /* Create the parent window */
+
+ parent = CreateWindowA (parent_class, "Redraw Test",
+ WS_OVERLAPPEDWINDOW,
+ 0, 0, 200, 200,
+ NULL, NULL, NULL, 0);
+
+
+ /* Static control */
+
+ handle = CreateWindow ("STATIC", "Static Test",
+ (WS_CHILD | WS_VISIBLE | SS_SIMPLE),
+ 0, 0, 200, 200,
+ parent, NULL, NULL, 0);
+
+ assert (handle);
+
+ ShowWindow(parent, SW_SHOW);
+ UpdateWindow(parent);
+
+ ok(!GetUpdateRect(handle, NULL, FALSE), "GetUpdateRect should return FALSE after UpdateWindow\n");
+
+ SendMessage(handle, WM_SETTEXT, 0, (LPARAM) (LPCTSTR) "New Text");
+ ok(!GetUpdateRect(handle, NULL, FALSE), "WM_SETTEXT: Static control should redraw itself\n");
+
+ assert(DestroyWindow(handle));
+
+
+
+ /* Listbox */
+
+ handle = CreateWindow ("LISTBOX", "ListboxTest",
+ (WS_CHILD | WS_VISIBLE | (LBS_STANDARD & ~LBS_SORT) | LBS_MULTIPLESEL),
+ 0, 0, 200, 200,
+ parent, NULL, NULL, 0);
+
+ assert (handle);
+
+ UpdateWindow(handle);
+ assert(!GetUpdateRect(handle, NULL, FALSE));
+
+ SendMessage (handle, LB_ADDSTRING, 0, (LPARAM) (LPCTSTR) "First added");
+ ok(GetUpdateRect(handle, NULL, FALSE), "LB_ADDSTRING: Listbox should not redraw itself\n");
+
+ UpdateWindow(handle);
+ assert(!GetUpdateRect(handle, NULL, FALSE));
+
+ SendMessage (handle, LB_SETSEL, TRUE, 0);
+ SendMessage (handle, LB_SETSEL, TRUE, 1);
+ ok(GetUpdateRect(handle, NULL, FALSE), "LB_SETSEL: Listbox should not redraw itself\n");
+
+ UpdateWindow(handle);
+ assert(!GetUpdateRect(handle, NULL, FALSE));
+
+ SendMessage (handle, LB_RESETCONTENT, 0, 0);
+ ok(GetUpdateRect(handle, NULL, FALSE), "LB_RESETCONTENT: Listbox should not redraw itself\n");
+
+ /* Add enough items to make scrolling necessary */
+ for (i=0; i < 100; i++) SendMessage(handle, LB_ADDSTRING, 0, (LPARAM) (LPCTSTR) "Listbox Item");
+
+ UpdateWindow(handle);
+ assert(!GetUpdateRect(handle, NULL, FALSE));
+
+ SendMessage(handle, LB_SETTOPINDEX, 90, 0);
+ ok(!GetUpdateRect(handle, NULL, FALSE), "LB_SETTOPINDEX: Listbox should redraw itself\n");
+
+ UpdateWindow(handle);
+ assert(!GetUpdateRect(handle, NULL, FALSE));
+
+ SendMessage(handle, LB_SETCURSEL, 5, 0);
+ ok(!GetUpdateRect(handle, NULL, FALSE), "LB_SETCURSEL: Listbox should redraw itself\n");
+
+ assert(DestroyWindow(handle));
+
+
+ /* Edit control */
+
+ handle = CreateWindow ("EDIT", "Edit Test",
+ (WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_AUTOVSCROLL),
+ 0, 0, 200, 200,
+ parent, NULL, NULL, 0);
+
+ UpdateWindow(handle);
+ assert(!GetUpdateRect(handle, NULL, FALSE));
+
+ SendMessage(handle, WM_SETTEXT, 0, (LPARAM) (LPCTSTR) "New Edit Text");
+ ok(GetUpdateRect(handle, NULL, FALSE), "WM_SETTEXT: Single-line edit control should not redraw itself\n");
+
+ UpdateWindow(handle);
+ assert(!GetUpdateRect(handle, NULL, FALSE));
+
+ SendMessage(handle, EM_REPLACESEL, TRUE, (LPARAM) (LPCTSTR) "Replacement Text");
+ ok(!GetUpdateRect(handle, NULL, FALSE), "EM_REPLACESEL: Single-line edit control should redraw itself\n");
+
+ UpdateWindow(handle);
+ assert(!GetUpdateRect(handle, NULL, FALSE));
+
+ SendMessage(handle, EM_SETSEL, 0, 10);
+ ok(!GetUpdateRect(handle, NULL, FALSE), "EM_SETSEL: Single-line edit control should redraw itself\n");
+
+ UpdateWindow(handle);
+ assert(!GetUpdateRect(handle, NULL, FALSE));
+
+ SendMessage(handle, WM_CUT, 0, 0);
+ ok(!GetUpdateRect(handle, NULL, FALSE), "WM_CUT: Single-line edit control should redraw itself\n");
+
+ UpdateWindow(handle);
+ assert(!GetUpdateRect(handle, NULL, FALSE));
+
+ SendMessage(handle, WM_PASTE, 0, 0);
+ ok(!GetUpdateRect(handle, NULL, FALSE), "WM_PASTE: Single-line edit control should redraw itself\n");
+
+ UpdateWindow(handle);
+ assert(!GetUpdateRect(handle, NULL, FALSE));
+
+ SendMessage(handle, WM_CLEAR, 0, 0);
+ ok(!GetUpdateRect(handle, NULL, FALSE), "WM_CLEAR: Single-line edit control should redraw itself\n");
+
+ assert(DestroyWindow(handle));
+ assert(DestroyWindow(parent));
+ assert(UnregisterClassA("RedrawWindowClass", GetModuleHandleA(0)));
+}
+
+START_TEST(redraw)
+{
+ do_redraw_test();
+}
More information about the wine-patches
mailing list