Index: trunk/src/user32/edit.cpp
===================================================================
--- trunk/src/user32/edit.cpp	(revision 1715)
+++ trunk/src/user32/edit.cpp	(revision 1717)
@@ -1,3 +1,3 @@
-/* $Id: edit.cpp,v 1.12 1999-11-11 17:13:45 cbratschi Exp $ */
+/* $Id: edit.cpp,v 1.13 1999-11-12 17:16:36 cbratschi Exp $ */
 /*
  *      Edit control
@@ -7,5 +7,5 @@
  *      Copyright  Frans van Dorsselaer, 1996, 1997
  *
- *      Copyright  1999 Christoph Bratschi (ported from WINE)
+ *      Copyright  1999 Christoph Bratschi
  *
  * WINE version: 990923
@@ -15,4 +15,12 @@
  *      please read EDIT.TODO (and update it when you change things)
  */
+
+/* CB: todo
+  - EN_UPDATE: send before update
+  - EN_CHANGE: send after update -> WM_PAINT isn't the right place
+  - EN_HSCROLL/EN_VSCROLL: send before update
+  - still problems with caret
+  - WS_BORDER -> bug in Win32BaseWindow::SetWindowLong
+*/
 
 #include <os2win.h>
@@ -143,4 +151,5 @@
 static void     EDIT_MovePageUp_ML(HWND hwnd, EDITSTATE *es, BOOL extend);
 static void     EDIT_MoveUp_ML(HWND hwnd, EDITSTATE *es, BOOL extend);
+static VOID     EDIT_UpdateScrollBars(HWND hwnd,EDITSTATE *es,BOOL updateHorz,BOOL updateVert);
 /*
  *      Helper functions valid for both single line _and_ multi line controls
@@ -166,4 +175,7 @@
 static void     EDIT_UnlockBuffer(HWND hwnd, EDITSTATE *es, BOOL force);
 static INT      EDIT_WordBreakProc(LPSTR s, INT index, INT count, INT action);
+static VOID     EDIT_Draw(HWND hwnd,EDITSTATE *es,HDC hdc);
+static VOID     EDIT_Refresh(HWND hwnd,EDITSTATE *es);
+
 /*
  *      EM_XXX message handlers
@@ -331,5 +343,5 @@
                 if ((es->style & ES_MULTILINE) && lParam) {
                         EDIT_SetRectNP(hwnd, es, (LPRECT)lParam);
-                        InvalidateRect(hwnd, NULL, TRUE);
+                        EDIT_Refresh(hwnd,es);
                 }
                 break;
@@ -597,5 +609,5 @@
                 //DPRINTF_EDIT_MSG32("WM_ENABLE");
                 es->bEnableState = (BOOL)wParam;
-                InvalidateRect(hwnd, NULL, TRUE);
+                EDIT_Refresh(hwnd,es);
                 break;
 
@@ -830,4 +842,5 @@
                 SelectObject(dc, old_font);
         ReleaseDC(hwnd, dc);
+        EDIT_UpdateScrollBars(hwnd,es,TRUE,TRUE);
 }
 
@@ -1634,4 +1647,5 @@
         if ((es->style & ES_MULTILINE) && !(es->style & ES_AUTOHSCROLL))
                 EDIT_BuildLineDefs_ML(hwnd, es);
+        EDIT_UpdateScrollBars(hwnd,es,TRUE,TRUE);
 }
 
@@ -1996,4 +2010,35 @@
 }
 
+static VOID EDIT_UpdateScrollBars(HWND hwnd,EDITSTATE *es,BOOL updateHorz,BOOL updateVert)
+{
+  if (updateHorz && (es->style & WS_HSCROLL) && !(es->flags & EF_HSCROLL_TRACK))
+  {
+    SCROLLINFO si;
+    INT fw = es->format_rect.right - es->format_rect.left;
+
+    si.cbSize       = sizeof(SCROLLINFO);
+    si.fMask        = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_DISABLENOSCROLL;
+    si.nMin         = 0;
+    si.nMax         = es->text_width + fw - 1;
+    si.nPage        = fw;
+    si.nPos         = es->x_offset;
+    SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
+  }
+
+  if (updateVert && (es->style & WS_VSCROLL) && !(es->flags & EF_VSCROLL_TRACK))
+  {
+    INT vlc = (es->format_rect.bottom-es->format_rect.top)/es->line_height;
+    SCROLLINFO si;
+
+    si.cbSize       = sizeof(SCROLLINFO);
+    si.fMask        = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_DISABLENOSCROLL;
+    si.nMin         = 0;
+    si.nMax         = es->line_count + vlc - 2;
+    si.nPage        = vlc;
+    si.nPos         = es->y_offset;
+    SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
+  }
+}
+
 
 /*********************************************************************
@@ -2031,4 +2076,5 @@
                 es->y_offset = nyoff;
                 es->x_offset += dx;
+                EDIT_UpdateScrollBars(hwnd,es,dx,dy);
         }
         if (dx && !(es->flags & EF_HSCROLL_TRACK))
@@ -2204,5 +2250,5 @@
 
         /* FIXME: really inefficient */
-        InvalidateRect(hwnd, NULL, TRUE);
+        EDIT_Refresh(hwnd,es);
 }
 
@@ -2292,5 +2338,6 @@
                 x = SLOWORD(EDIT_EM_PosFromChar(hwnd, es, es->selection_end, FALSE));
                 format_width = es->format_rect.right - es->format_rect.left;
-                if (x < es->format_rect.left) {
+                if (x < es->format_rect.left)
+                {
                         goal = es->format_rect.left + format_width / HSCROLL_FRACTION;
                         do {
@@ -2299,6 +2346,8 @@
                         } while ((x < goal) && es->x_offset);
                         /* FIXME: use ScrollWindow() somehow to improve performance */
-                        InvalidateRect(hwnd, NULL, TRUE);
-                } else if (x > es->format_rect.right) {
+                        EDIT_Refresh(hwnd,es);
+                        EDIT_UpdateScrollBars(hwnd,es,TRUE,FALSE);
+                } else if (x > es->format_rect.right)
+                {
                         INT x_last;
                         INT len = lstrlenA(es->text);
@@ -2310,5 +2359,6 @@
                         } while ((x > goal) && (x_last > es->format_rect.right));
                         /* FIXME: use ScrollWindow() somehow to improve performance */
-                        InvalidateRect(hwnd, NULL, TRUE);
+                        EDIT_Refresh(hwnd,es);
+                        EDIT_UpdateScrollBars(hwnd,es,TRUE,FALSE);
                 }
         }
@@ -2353,6 +2403,7 @@
         es->flags &= ~EF_UPDATE;
         EDIT_BuildLineDefs_ML(hwnd, es);
-        InvalidateRect(hwnd, NULL, TRUE);
+        EDIT_Refresh(hwnd,es);
         EDIT_EM_ScrollCaret(hwnd, es);
+        EDIT_UpdateScrollBars(hwnd,es,TRUE,TRUE);
 }
 
@@ -2431,5 +2482,5 @@
                 es->style &= ~ES_PASSWORD;
         }
-        InvalidateRect(hwnd, NULL, TRUE);
+        EDIT_Refresh(hwnd,es);
 }
 
@@ -2470,5 +2521,4 @@
         ORDER_UINT(start, old_start);
         ORDER_UINT(old_start, old_end);
-        if (es->flags & EF_FOCUSED) HideCaret(hwnd);
         if (end != old_start)
         {
@@ -2492,5 +2542,4 @@
         }
         else EDIT_InvalidateText(hwnd, es, start, old_end);
-        if (es->flags & EF_FOCUSED) ShowCaret(hwnd);
 }
 
@@ -2531,5 +2580,5 @@
         if ((es->style & ES_MULTILINE) && !(es->style & ES_AUTOHSCROLL)) {
                 EDIT_BuildLineDefs_ML(hwnd, es);
-                InvalidateRect(hwnd, NULL, TRUE);
+                EDIT_Refresh(hwnd,es);
         }
 }
@@ -3326,4 +3375,120 @@
 }
 
+static VOID EDIT_Draw(HWND hwnd,EDITSTATE *es,HDC hdc,BOOL eraseBkGnd)
+{
+  INT i;
+  HFONT old_font = 0;
+  RECT rc;
+  RECT rcLine;
+  RECT rcRgn;
+  BOOL rev = es->bEnableState && ((es->flags & EF_FOCUSED) || (es->style & ES_NOHIDESEL));
+
+  if (es->flags & EF_UPDATE) EDIT_NOTIFY_PARENT(hwnd, EN_UPDATE);
+
+  if (es->flags & EF_FOCUSED) HideCaret(hwnd);
+
+  if (eraseBkGnd)
+  {
+    HBRUSH brush;
+
+    if (!es->bEnableState || (es->style & ES_READONLY))
+      brush = (HBRUSH)EDIT_SEND_CTLCOLORSTATIC(hwnd, hdc);
+    else
+      brush = (HBRUSH)EDIT_SEND_CTLCOLOR(hwnd, hdc);
+
+    if (!brush)
+      brush = (HBRUSH)GetStockObject(WHITE_BRUSH);
+
+    GetClientRect(hwnd, &rc);
+    /*
+     *      FIXME:  specs say that we should UnrealizeObject() the brush,
+     *              but the specs of UnrealizeObject() say that we shouldn't
+     *              unrealize a stock object.  The default brush that
+     *              DefWndProc() returns is ... a stock object.
+     */
+    FillRect(hdc, &rc, brush);
+  }
+
+  if(es->style & WS_BORDER)
+  {
+    GetClientRect(hwnd, &rc);
+    if(es->style & ES_MULTILINE)
+    {
+      if(es->style & WS_HSCROLL) rc.bottom++;
+      if(es->style & WS_VSCROLL) rc.right++;
+    }
+    Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom);
+  }
+
+  IntersectClipRect(hdc, es->format_rect.left,
+                        es->format_rect.top,
+                        es->format_rect.right,
+                        es->format_rect.bottom);
+  if (es->style & ES_MULTILINE)
+  {
+    GetClientRect(hwnd, &rc);
+    IntersectClipRect(hdc, rc.left, rc.top, rc.right, rc.bottom);
+  }
+  if (es->font) old_font = SelectObject(hdc, es->font);
+  if (!es->bEnableState || (es->style & ES_READONLY))
+    EDIT_SEND_CTLCOLORSTATIC(hwnd, hdc);
+  else
+    EDIT_SEND_CTLCOLOR(hwnd, hdc);
+  if (!es->bEnableState)
+    SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT));
+  GetClipBox(hdc, &rcRgn);
+  if (es->style & ES_MULTILINE)
+  {
+    INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
+
+    for (i = es->y_offset ; i <= MIN(es->y_offset + vlc, es->y_offset + es->line_count - 1) ; i++)
+    {
+      EDIT_GetLineRect(hwnd, es, i, 0, -1, &rcLine);
+      if (IntersectRect(&rc, &rcRgn, &rcLine))
+        EDIT_PaintLine(hwnd, es, hdc, i, rev);
+    }
+  } else
+  {
+    EDIT_GetLineRect(hwnd, es, 0, 0, -1, &rcLine);
+    if (IntersectRect(&rc, &rcRgn, &rcLine))
+      EDIT_PaintLine(hwnd, es, hdc, 0, rev);
+  }
+  if (es->font) SelectObject(hdc, old_font);
+  if (es->flags & EF_FOCUSED)
+    EDIT_SetCaretPos(hwnd, es, es->selection_end,es->flags & EF_AFTER_WRAP);
+
+  if (es->flags & EF_FOCUSED) ShowCaret(hwnd);
+
+  //CB: replace
+  if (es->flags & EF_UPDATE)
+  {
+    es->flags &= ~EF_UPDATE;
+    EDIT_NOTIFY_PARENT(hwnd, EN_CHANGE);
+  }
+}
+
+static VOID EDIT_Refresh(HWND hwnd,EDITSTATE *es)
+{
+  HDC hdc,hdcCompatible;
+  HBITMAP bitmap,oldbmp;
+  RECT rect;
+
+  //CB: original controls redraws many times, cache drawing
+  if (es->flags & EF_FOCUSED) HideCaret(hwnd);
+  GetClientRect(hwnd,&rect);
+  hdc = GetDC(hwnd);
+  hdcCompatible = CreateCompatibleDC(hdc);
+  bitmap = CreateCompatibleBitmap(hdc,rect.right,rect.bottom);
+  oldbmp = SelectObject(hdcCompatible,bitmap);
+  EDIT_Draw(hwnd,es,hdcCompatible,TRUE);
+  SelectClipRgn(hdcCompatible,0);
+  BitBlt(hdc,0,0,rect.right,rect.bottom,hdcCompatible,0,0,SRCCOPY);
+  SelectObject(hdcCompatible,oldbmp);
+  DeleteObject(bitmap);
+  DeleteDC(hdcCompatible);
+  ReleaseDC(hwnd,hdc);
+  if (es->flags & EF_FOCUSED) ShowCaret(hwnd);
+}
+
 /*********************************************************************
  *
@@ -3333,93 +3498,13 @@
 static void EDIT_WM_Paint(HWND hwnd, EDITSTATE *es,WPARAM wParam)
 {
-        PAINTSTRUCT ps;
-        INT i;
-        HDC dc;
-        HFONT old_font = 0;
-        RECT rc;
-        RECT rcLine;
-        RECT rcRgn;
-        BOOL rev = es->bEnableState &&
-                                ((es->flags & EF_FOCUSED) ||
-                                        (es->style & ES_NOHIDESEL));
-
-        if (es->flags & EF_UPDATE)
-                EDIT_NOTIFY_PARENT(hwnd, EN_UPDATE);
-
-        if (!wParam)
-            dc = BeginPaint(hwnd, &ps);
-        else
-            dc = (HDC) wParam;
-
-        if(es->style & WS_BORDER) {
-                GetClientRect(hwnd, &rc);
-                if(es->style & ES_MULTILINE) {
-                        if(es->style & WS_HSCROLL) rc.bottom++;
-                        if(es->style & WS_VSCROLL) rc.right++;
-                }
-                Rectangle(dc, rc.left, rc.top, rc.right, rc.bottom);
-        }
-        IntersectClipRect(dc, es->format_rect.left,
-                                es->format_rect.top,
-                                es->format_rect.right,
-                                es->format_rect.bottom);
-        if (es->style & ES_MULTILINE) {
-                GetClientRect(hwnd, &rc);
-                IntersectClipRect(dc, rc.left, rc.top, rc.right, rc.bottom);
-        }
-        if (es->font)
-                old_font = SelectObject(dc, es->font);
-        if (!es->bEnableState || (es->style & ES_READONLY))
-                EDIT_SEND_CTLCOLORSTATIC(hwnd, dc);
-        else
-                EDIT_SEND_CTLCOLOR(hwnd, dc);
-        if (!es->bEnableState)
-                SetTextColor(dc, GetSysColor(COLOR_GRAYTEXT));
-        GetClipBox(dc, &rcRgn);
-        if (es->style & ES_MULTILINE) {
-                INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
-                for (i = es->y_offset ; i <= MIN(es->y_offset + vlc, es->y_offset + es->line_count - 1) ; i++) {
-                        EDIT_GetLineRect(hwnd, es, i, 0, -1, &rcLine);
-                        if (IntersectRect(&rc, &rcRgn, &rcLine))
-                                EDIT_PaintLine(hwnd, es, dc, i, rev);
-                }
-        } else {
-                EDIT_GetLineRect(hwnd, es, 0, 0, -1, &rcLine);
-                if (IntersectRect(&rc, &rcRgn, &rcLine))
-                        EDIT_PaintLine(hwnd, es, dc, 0, rev);
-        }
-        if (es->font)
-                SelectObject(dc, old_font);
-        if (es->flags & EF_FOCUSED)
-                EDIT_SetCaretPos(hwnd, es, es->selection_end,
-                                 es->flags & EF_AFTER_WRAP);
-        if (!wParam) EndPaint(hwnd, &ps);
-        if ((es->style & WS_VSCROLL) && !(es->flags & EF_VSCROLL_TRACK)) {
-                INT vlc = (es->format_rect.bottom - es->format_rect.top) / es->line_height;
-                SCROLLINFO si;
-                si.cbSize       = sizeof(SCROLLINFO);
-                si.fMask        = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_DISABLENOSCROLL;
-                si.nMin         = 0;
-                si.nMax         = es->line_count + vlc - 2;
-                si.nPage        = vlc;
-                si.nPos         = es->y_offset;
-                SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
-        }
-        if ((es->style & WS_HSCROLL) && !(es->flags & EF_HSCROLL_TRACK)) {
-                SCROLLINFO si;
-                INT fw = es->format_rect.right - es->format_rect.left;
-                si.cbSize       = sizeof(SCROLLINFO);
-                si.fMask        = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_DISABLENOSCROLL;
-                si.nMin         = 0;
-                si.nMax         = es->text_width + fw - 1;
-                si.nPage        = fw;
-                si.nPos         = es->x_offset;
-                SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
-        }
-
-        if (es->flags & EF_UPDATE) {
-                es->flags &= ~EF_UPDATE;
-                EDIT_NOTIFY_PARENT(hwnd, EN_CHANGE);
-        }
+  PAINTSTRUCT ps;
+  HDC hdc;
+
+  if (!wParam) hdc = BeginPaint(hwnd, &ps);
+  else hdc = (HDC) wParam;
+
+  EDIT_Draw(hwnd,es,hdc,FALSE);
+
+  if (!wParam) EndPaint(hwnd, &ps);
 }
 
@@ -3462,5 +3547,4 @@
         EDIT_NOTIFY_PARENT(hwnd, EN_SETFOCUS);
 }
-
 
 /*********************************************************************
@@ -3505,5 +3589,5 @@
 
         if (redraw)
-                InvalidateRect(hwnd, NULL, TRUE);
+                EDIT_Refresh(hwnd,es);
         if (es->flags & EF_FOCUSED) {
                 DestroyCaret();
@@ -3547,4 +3631,5 @@
         EDIT_EM_SetSel(hwnd, es, 0, 0, FALSE);
         EDIT_EM_ScrollCaret(hwnd, es);
+        EDIT_UpdateScrollBars(hwnd,es,TRUE,TRUE);
 }
 
@@ -3561,5 +3646,5 @@
                 SetRect(&rc, 0, 0, width, height);
                 EDIT_SetRectNP(hwnd, es, &rc);
-                InvalidateRect(hwnd, NULL, TRUE);
+                EDIT_Refresh(hwnd,es);
         }
 }
Index: trunk/src/user32/scroll.cpp
===================================================================
--- trunk/src/user32/scroll.cpp	(revision 1715)
+++ trunk/src/user32/scroll.cpp	(revision 1717)
@@ -1,3 +1,3 @@
-/* $Id: scroll.cpp,v 1.20 1999-11-10 17:11:30 cbratschi Exp $ */
+/* $Id: scroll.cpp,v 1.21 1999-11-12 17:16:37 cbratschi Exp $ */
 /*
  * Scrollbar control
@@ -701,4 +701,5 @@
     static POINT prevPt;       /* Previous mouse position for timer events */
     static UINT trackThumbPos; /* Thumb position when tracking started. */
+    static BOOL thumbTrackSent;
     static INT lastClickPos;   /* Position in the scroll-bar of the last button-down event. */
     static INT lastMousePos;   /* Position in the scroll-bar of the last mouse event. */
@@ -942,4 +943,5 @@
             SCROLL_TrackingVal = infoPtr->CurVal;
             SCROLL_MovingThumb = TRUE;
+            thumbTrackSent = FALSE;
             SCROLL_DrawMovingThumb(hdc, &rect, vertical, arrowSize, thumbSize);
         } else if (msg == WM_LBUTTONUP || msg == WM_CAPTURECHANGED)
@@ -954,5 +956,5 @@
                                     trackThumbPos + lastMousePos - lastClickPos );
 
-          if (val != infoPtr->CurVal)
+          if (val != infoPtr->CurVal || thumbTrackSent)
             SendMessageA( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                           MAKEWPARAM( SB_THUMBPOSITION, val ), hwndCtl );
@@ -991,4 +993,5 @@
                                 MAKEWPARAM( SB_THUMBTRACK, SCROLL_TrackingVal),
                                 hwndCtl );
+                thumbTrackSent = TRUE;
             }
         }
