UpdateWindow vs. WM_PAINT
Michael Kaufmann
hallo at michael-kaufmann.ch
Mon Sep 20 05:55:53 CDT 2004
Hi,
I've noticed that many Windows controls don't wait for a WM_PAINT
message. They redraw themselves immediately (with GetDC/ReleaseDC,
UpdateWindow or RedrawWindow). This is necessary if a program is
carrying out a lengthy operation without fetching messages. TextPad is
such a program: Its progress control doesn't get updated in WINE while
loading a file.
To see the redraw differences between Windows and WINE, I've created
this test program:
http://www.michael-kaufmann.ch/WINE/ControlsRepaintTest.zip
It changes properties of different controls and then calls Sleep() to
simulate a lengthy operation.
The big problem is that it's undocumented in which cases a control
should wait for a WM_PAINT message and in which cases it should redraw
itself immediately. I've observed that many controls redraw themselves
immediately if an important property of the control gets changed (e.g.
the position of a progress control, the text of a status bar) or if the
user selects an item (ListBox, ListView, TreeView) or if he presses a
key (Edit box). Most controls wait for WM_PAINT if the data that they
display was modified. But sometimes it's just arbitrary.
Examples (tested on Windows 2000):
Edit Control:
- Redraw immediately: WM_REPLACESEL, EM_SETSEL, WM_CLEAR, WM_PASTE, WM_CUT
- Don't redraw immediately: WM_SETTEXT, EM_UNDO, other messages
Listbox Control:
- Redraw immediately: LB_SETCURSEL, LB_SETTOPINDEX
- Don't redraw immediately: LB_SETSEL, LB_RESETCONTENT, LB_ADDSTRING,
other messages
I've created a patch which should work for most lazy programs. Please
review it.
Regards
Michael
-------------- 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 19 Sep 2004 21:45:55 -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 19 Sep 2004 21:45:56 -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.99
diff -u -r1.99 tab.c
--- dlls/comctl32/tab.c 14 Sep 2004 00:44:26 -0000 1.99
+++ dlls/comctl32/tab.c 19 Sep 2004 21:45:58 -0000
@@ -236,6 +236,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 19 Sep 2004 21:45:59 -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.151
diff -u -r1.151 treeview.c
--- dlls/comctl32/treeview.c 13 Sep 2004 23:22:30 -0000 1.151
+++ dlls/comctl32/treeview.c 19 Sep 2004 21:46:02 -0000
@@ -4114,7 +4114,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.1
diff -u -r1.1 combo.c
--- dlls/user/combo.c 31 Aug 2004 01:10:08 -0000 1.1
+++ dlls/user/combo.c 19 Sep 2004 21:46:07 -0000
@@ -1141,9 +1141,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)
@@ -1314,7 +1314,7 @@
case (EN_CHANGE >> 8):
/*
* In some circumstances (when the selection of the combobox
- * is changed for example) we don't wans the EN_CHANGE notification
+ * is changed for example) we don't want the EN_CHANGE notification
* to be forwarded to the parent of the combobox. This code
* checks a flag that is set in these occasions and ignores the
* notification.
@@ -1382,6 +1382,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.3
diff -u -r1.3 edit.c
--- dlls/user/edit.c 16 Sep 2004 20:28:10 -0000 1.3
+++ dlls/user/edit.c 19 Sep 2004 21:46:11 -0000
@@ -229,7 +229,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);
@@ -237,7 +237,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);
@@ -330,7 +330,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);
}
@@ -445,15 +445,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;
@@ -608,7 +608,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)
@@ -1813,7 +1813,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);
}
@@ -1839,7 +1839,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);
}
@@ -1860,7 +1860,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);
}
@@ -1883,7 +1883,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);
}
@@ -1905,7 +1905,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);
}
@@ -1933,7 +1933,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);
}
@@ -1961,7 +1961,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);
}
@@ -1987,7 +1987,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);
}
@@ -2019,7 +2019,7 @@
}
if (!extend)
s = e;
- EDIT_EM_SetSel(es, s, e, FALSE);
+ EDIT_EM_SetSel(es, s, e, FALSE, TRUE);
EDIT_EM_ScrollCaret(es);
}
@@ -2049,7 +2049,7 @@
}
if (!extend)
s = e;
- EDIT_EM_SetSel(es, s, e, FALSE);
+ EDIT_EM_SetSel(es, s, e, FALSE, TRUE);
EDIT_EM_ScrollCaret(es);
}
@@ -2897,7 +2897,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);
@@ -3009,7 +3009,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)
@@ -3025,6 +3025,7 @@
/* force scroll info update */
EDIT_UpdateScrollInfo(es);
+ if (drawImmediately) UpdateWindow(es->hwndSelf);
if(es->flags & EF_UPDATE)
{
@@ -3421,7 +3422,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;
@@ -3466,6 +3467,8 @@
}
}
else EDIT_InvalidateText(es, start, old_end);
+
+ if (drawImmediately) UpdateWindow(es->hwndSelf);
}
@@ -3578,10 +3581,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);
@@ -3616,7 +3619,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;
@@ -3624,7 +3627,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:
@@ -3633,7 +3636,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);
}
@@ -3660,7 +3663,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;
}
@@ -3694,7 +3697,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:
@@ -3792,7 +3795,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
@@ -4158,17 +4161,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);
}
@@ -4240,7 +4243,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;
}
@@ -4264,7 +4267,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);
@@ -4323,7 +4326,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;
}
@@ -4533,7 +4536,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();
@@ -4634,20 +4637,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
@@ -4890,7 +4893,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.1
diff -u -r1.1 listbox.c
--- dlls/user/listbox.c 31 Aug 2004 01:10:08 -0000 1.1
+++ dlls/user/listbox.c 19 Sep 2004 21:46:13 -0000
@@ -2363,6 +2363,12 @@
descr->anchor_item = caret;
LISTBOX_MoveCaret( hwnd, descr, caret, TRUE );
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 )
@@ -2712,7 +2718,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:
@@ -2831,7 +2839,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.1
diff -u -r1.1 static.c
--- dlls/user/static.c 31 Aug 2004 01:10:08 -0000 1.1
+++ dlls/user/static.c 19 Sep 2004 21:46:14 -0000
@@ -319,8 +319,6 @@
else
lResult = DefWindowProcA( hwnd, WM_SETTEXT, wParam, lParam );
}
- if (uMsg == WM_SETTEXT)
- STATIC_TryPaintFcn( hwnd, full_style );
break;
}
default:
@@ -331,9 +329,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:
More information about the wine-devel
mailing list