https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0839711566bf13a111bba72f8bc88fa1392c3cd0

commit 0839711566bf13a111bba72f8bc88fa1392c3cd0
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Sun Jan 30 12:05:23 2022 +0900
Commit:     GitHub <[email protected]>
CommitDate: Sun Jan 30 12:05:23 2022 +0900

    [MSPAINT] Improve Undo/Redo and finishing tool (#4324)
    
    - Fix Undo/Redo mechanism.
    - Finish drawing when the tool is to be chanaged and when the file is to be 
saved.
    - Add ToolBase::OnFinishDraw to virtualize finishing drawing.
    - Extend bClearRedo parameter to ImageModel::Undo.
    - Add ImageModel::DrawSelectionBackground and ImageModel::DeleteSelection 
methods.
    - Fix some WM_PAINT message handling.
    CORE-17969
---
 base/applications/mspaint/history.cpp        |  32 +++-
 base/applications/mspaint/history.h          |   5 +-
 base/applications/mspaint/imgarea.cpp        |   9 +-
 base/applications/mspaint/imgarea.h          |   7 +-
 base/applications/mspaint/mouse.cpp          | 219 +++++++++++++++++++--------
 base/applications/mspaint/palette.cpp        |   6 +-
 base/applications/mspaint/selection.cpp      |  67 ++++----
 base/applications/mspaint/selection.h        |  13 ++
 base/applications/mspaint/selectionmodel.cpp |   5 -
 base/applications/mspaint/selectionmodel.h   |   1 -
 base/applications/mspaint/toolsettings.cpp   |   7 +-
 base/applications/mspaint/toolsmodel.cpp     |  31 ++--
 base/applications/mspaint/toolsmodel.h       |   2 +
 base/applications/mspaint/winproc.cpp        |  56 +++++--
 14 files changed, 311 insertions(+), 149 deletions(-)

diff --git a/base/applications/mspaint/history.cpp 
b/base/applications/mspaint/history.cpp
index 7aa36fab4dc..bc0749148fa 100644
--- a/base/applications/mspaint/history.cpp
+++ b/base/applications/mspaint/history.cpp
@@ -57,7 +57,7 @@ void ImageModel::CopyPrevious()
     imageSaved = FALSE;
 }
 
-void ImageModel::Undo()
+void ImageModel::Undo(BOOL bClearRedo)
 {
     ATLTRACE("%s: %d\n", __FUNCTION__, undoSteps);
     if (undoSteps > 0)
@@ -68,7 +68,9 @@ void ImageModel::Undo()
         currInd = (currInd + HISTORYSIZE - 1) % HISTORYSIZE;
         SelectObject(hDrawingDC, hBms[currInd]);
         undoSteps--;
-        if (redoSteps < HISTORYSIZE - 1)
+        if (bClearRedo)
+            redoSteps = 0;
+        else if (redoSteps < HISTORYSIZE - 1)
             redoSteps++;
         if (GetWidth() != oldWidth || GetHeight() != oldHeight)
             NotifyDimensionsChanged();
@@ -251,3 +253,29 @@ void ImageModel::RotateNTimes90Degrees(int iN)
     }
     NotifyImageChanged();
 }
+
+void ImageModel::DrawSelectionBackground(COLORREF rgbBG)
+{
+    if (toolsModel.GetActiveTool() == TOOL_FREESEL)
+        selectionModel.DrawBackgroundPoly(hDrawingDC, rgbBG);
+    else
+        selectionModel.DrawBackgroundRect(hDrawingDC, rgbBG);
+}
+
+void ImageModel::DeleteSelection()
+{
+    if (selectionWindow.IsWindowVisible())
+        ResetToPrevious();
+    CopyPrevious();
+    if (selectionWindow.IsWindowVisible())
+        Undo(TRUE);
+    DrawSelectionBackground(paletteModel.GetBgColor());
+    selectionWindow.ShowWindow(SW_HIDE);
+    NotifyImageChanged();
+}
+
+void ImageModel::Bound(POINT& pt)
+{
+    pt.x = max(0, min(pt.x, GetWidth()));
+    pt.y = max(0, min(pt.y, GetHeight()));
+}
diff --git a/base/applications/mspaint/history.h 
b/base/applications/mspaint/history.h
index 697b65bf128..17ef43b9e48 100644
--- a/base/applications/mspaint/history.h
+++ b/base/applications/mspaint/history.h
@@ -26,7 +26,7 @@ private:
 public:
     ImageModel();
     void CopyPrevious(void);
-    void Undo(void);
+    void Undo(BOOL bClearRedo = FALSE);
     void Redo(void);
     void ResetToPrevious(void);
     void ClearHistory(void);
@@ -45,4 +45,7 @@ public:
     void FlipHorizontally();
     void FlipVertically();
     void RotateNTimes90Degrees(int iN);
+    void DrawSelectionBackground(COLORREF rgbBG);
+    void DeleteSelection();
+    void Bound(POINT& pt);
 };
diff --git a/base/applications/mspaint/imgarea.cpp 
b/base/applications/mspaint/imgarea.cpp
index 0cb2f8de2ab..c0a5f832251 100644
--- a/base/applications/mspaint/imgarea.cpp
+++ b/base/applications/mspaint/imgarea.cpp
@@ -259,7 +259,7 @@ LRESULT CImgAreaWindow::OnKeyDown(UINT nMsg, WPARAM wParam, 
LPARAM lParam, BOOL&
         }
         else
         {
-            if (drawing || ToolBase::pointSP != 0)
+            if (drawing || ToolBase::pointSP != 0 || 
selectionWindow.IsWindowVisible())
                 cancelDrawing();
         }
     }
@@ -411,3 +411,10 @@ LRESULT CImgAreaWindow::OnCtlColorEdit(UINT nMsg, WPARAM 
wParam, LPARAM lParam,
     SetBkMode(hdc, TRANSPARENT);
     return (LRESULT)GetStockObject(NULL_BRUSH);
 }
+
+void CImgAreaWindow::finishDrawing()
+{
+    toolsModel.OnFinishDraw();
+    drawing = FALSE;
+    Invalidate(FALSE);
+}
diff --git a/base/applications/mspaint/imgarea.h 
b/base/applications/mspaint/imgarea.h
index a898f1e893b..384b8ac3ff4 100644
--- a/base/applications/mspaint/imgarea.h
+++ b/base/applications/mspaint/imgarea.h
@@ -17,6 +17,10 @@ public:
     {
     }
 
+    BOOL drawing;
+    void cancelDrawing();
+    void finishDrawing();
+
     DECLARE_WND_CLASS_EX(_T("ImgAreaWindow"), CS_DBLCLKS, COLOR_BTNFACE)
 
     BEGIN_MSG_MAP(CImgAreaWindow)
@@ -40,8 +44,6 @@ public:
         MESSAGE_HANDLER(WM_CTLCOLOREDIT, OnCtlColorEdit)
     END_MSG_MAP()
 
-    BOOL drawing;
-
 private:
     LRESULT OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
     LRESULT OnEraseBkGnd(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& 
bHandled);
@@ -63,5 +65,4 @@ private:
     LRESULT OnCtlColorEdit(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& 
bHandled);
 
     void drawZoomFrame(int mouseX, int mouseY);
-    void cancelDrawing();
 };
diff --git a/base/applications/mspaint/mouse.cpp 
b/base/applications/mspaint/mouse.cpp
index b442d0c9daf..fda0bc64a81 100644
--- a/base/applications/mspaint/mouse.cpp
+++ b/base/applications/mspaint/mouse.cpp
@@ -76,6 +76,10 @@ void updateLast(LONG x, LONG y)
 void ToolBase::reset()
 {
     pointSP = 0;
+    start.x = start.y = last.x = last.y = -1;
+    selectionModel.ResetPtStack();
+    if (selectionWindow.IsWindow())
+        selectionWindow.ShowWindow(SW_HIDE);
 }
 
 void ToolBase::OnCancelDraw()
@@ -83,6 +87,11 @@ void ToolBase::OnCancelDraw()
     reset();
 }
 
+void ToolBase::OnFinishDraw()
+{
+    reset();
+}
+
 void ToolBase::beginEvent()
 {
     m_hdc = imageModel.GetDC();
@@ -100,48 +109,75 @@ void ToolBase::endEvent()
 // TOOL_FREESEL
 struct FreeSelTool : ToolBase
 {
-    FreeSelTool() : ToolBase(TOOL_FREESEL)
+    BOOL m_bLeftButton;
+
+    FreeSelTool() : ToolBase(TOOL_FREESEL), m_bLeftButton(FALSE)
     {
     }
 
     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
     {
-        imageModel.CopyPrevious();
-        selectionWindow.ShowWindow(SW_HIDE);
-        selectionModel.ResetPtStack();
-        selectionModel.PushToPtStack(x, y);
+        if (bLeftButton)
+        {
+            imageModel.CopyPrevious();
+            selectionWindow.ShowWindow(SW_HIDE);
+            selectionModel.ResetPtStack();
+            selectionModel.PushToPtStack(x, y);
+        }
+        m_bLeftButton = bLeftButton;
     }
 
     void OnMouseMove(BOOL bLeftButton, LONG x, LONG y)
     {
-        if (selectionModel.PtStackSize() == 1)
-            imageModel.CopyPrevious();
-        selectionModel.PushToPtStack(max(0, min(x, imageModel.GetWidth())), 
max(0, min(y, imageModel.GetHeight())));
-        imageModel.ResetToPrevious();
-        selectionModel.DrawFramePoly(m_hdc);
+        if (bLeftButton)
+        {
+            POINT pt = { x, y };
+            imageModel.Bound(pt);
+            selectionModel.PushToPtStack(pt.x, pt.y);
+            imageModel.ResetToPrevious();
+            selectionModel.DrawFramePoly(m_hdc);
+        }
     }
 
     void OnButtonUp(BOOL bLeftButton, LONG x, LONG y)
     {
-        selectionModel.CalculateBoundingBoxAndContents(m_hdc);
-        if (selectionModel.PtStackSize() > 1)
+        if (bLeftButton)
         {
-            selectionModel.DrawBackgroundPoly(m_hdc, m_bg);
-            imageModel.CopyPrevious();
-
-            selectionModel.DrawSelection(m_hdc);
+            imageModel.ResetToPrevious();
+            if (selectionModel.PtStackSize() > 2)
+            {
+                selectionModel.CalculateBoundingBoxAndContents(m_hdc);
+                placeSelWin();
+                selectionWindow.IsMoved(FALSE);
+                selectionWindow.ShowWindow(SW_SHOWNOACTIVATE);
+            }
+            else
+            {
+                imageModel.Undo(TRUE);
+                selectionWindow.IsMoved(FALSE);
+                selectionModel.ResetPtStack();
+                selectionWindow.ShowWindow(SW_HIDE);
+            }
+        }
+    }
 
-            placeSelWin();
-            selectionWindow.ShowWindow(SW_SHOW);
-            ForceRefreshSelectionContents();
+    void OnFinishDraw()
+    {
+        if (m_bLeftButton)
+        {
+            selectionWindow.IsMoved(FALSE);
+            selectionWindow.ForceRefreshSelectionContents();
         }
-        selectionModel.ResetPtStack();
+        m_bLeftButton = FALSE;
+        ToolBase::OnFinishDraw();
     }
 
     void OnCancelDraw()
     {
-        imageModel.ResetToPrevious();
-        selectionModel.ResetPtStack();
+        if (m_bLeftButton)
+            imageModel.Undo(TRUE);
+        m_bLeftButton = FALSE;
+        selectionWindow.IsMoved(FALSE);
         ToolBase::OnCancelDraw();
     }
 };
@@ -149,31 +185,32 @@ struct FreeSelTool : ToolBase
 // TOOL_RECTSEL
 struct RectSelTool : ToolBase
 {
-    RectSelTool() : ToolBase(TOOL_RECTSEL)
+    BOOL m_bLeftButton;
+
+    RectSelTool() : ToolBase(TOOL_RECTSEL), m_bLeftButton(FALSE)
     {
     }
 
     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
     {
-        imageModel.CopyPrevious();
         if (bLeftButton)
         {
             imageModel.CopyPrevious();
             selectionWindow.ShowWindow(SW_HIDE);
             selectionModel.SetSrcRectSizeToZero();
         }
+        m_bLeftButton = bLeftButton;
     }
 
     void OnMouseMove(BOOL bLeftButton, LONG x, LONG y)
     {
-        POINT temp;
         if (bLeftButton)
         {
             imageModel.ResetToPrevious();
-            temp.x = max(0, min(x, imageModel.GetWidth()));
-            temp.y = max(0, min(y, imageModel.GetHeight()));
-            selectionModel.SetSrcAndDestRectFromPoints(start, temp);
-            RectSel(m_hdc, start.x, start.y, temp.x, temp.y);
+            POINT pt = { x, y };
+            imageModel.Bound(pt);
+            selectionModel.SetSrcAndDestRectFromPoints(start, pt);
+            RectSel(m_hdc, start.x, start.y, pt.x, pt.y);
         }
     }
 
@@ -182,25 +219,35 @@ struct RectSelTool : ToolBase
         if (bLeftButton)
         {
             imageModel.ResetToPrevious();
+            if (start.x == x && start.y == y)
+                imageModel.Undo(TRUE);
+            selectionModel.CalculateContents(m_hdc);
+            placeSelWin();
+            selectionWindow.IsMoved(FALSE);
             if (selectionModel.IsSrcRectSizeNonzero())
-            {
-                selectionModel.CalculateContents(m_hdc);
-                selectionModel.DrawBackgroundRect(m_hdc, m_bg);
-                imageModel.CopyPrevious();
-
-                selectionModel.DrawSelection(m_hdc);
+                selectionWindow.ShowWindow(SW_SHOWNOACTIVATE);
+            else
+                selectionWindow.ShowWindow(SW_HIDE);
+        }
+    }
 
-                placeSelWin();
-                selectionWindow.ShowWindow(SW_SHOW);
-                ForceRefreshSelectionContents();
-            }
+    void OnFinishDraw()
+    {
+        if (m_bLeftButton)
+        {
+            selectionWindow.IsMoved(FALSE);
+            selectionWindow.ForceRefreshSelectionContents();
         }
+        m_bLeftButton = FALSE;
+        ToolBase::OnFinishDraw();
     }
 
     void OnCancelDraw()
     {
-        imageModel.ResetToPrevious();
-        selectionModel.ResetPtStack();
+        if (m_bLeftButton)
+            imageModel.Undo(TRUE);
+        m_bLeftButton = FALSE;
+        selectionWindow.IsMoved(FALSE);
         ToolBase::OnCancelDraw();
     }
 };
@@ -232,8 +279,7 @@ struct GenericDrawTool : ToolBase
     void OnCancelDraw()
     {
         OnButtonUp(FALSE, 0, 0);
-        imageModel.Undo();
-        selectionModel.ResetPtStack();
+        imageModel.Undo(TRUE);
         ToolBase::OnCancelDraw();
     }
 };
@@ -275,20 +321,29 @@ struct ColorTool : ToolBase
     {
     }
 
-    void OnButtonUp(BOOL bLeftButton, LONG x, LONG y)
+    void fetchColor(BOOL bLeftButton, LONG x, LONG y)
     {
-        COLORREF tempColor;
+        COLORREF rgbColor;
 
         if (0 <= x && x < imageModel.GetWidth() && 0 <= y && y < 
imageModel.GetHeight())
-            tempColor = GetPixel(m_hdc, x, y);
+            rgbColor = GetPixel(m_hdc, x, y);
         else
-            tempColor = RGB(255, 255, 255); // Outside is white
+            rgbColor = RGB(255, 255, 255); // Outside is white
 
         if (bLeftButton)
-            paletteModel.SetFgColor(tempColor);
+            paletteModel.SetFgColor(rgbColor);
         else
-            paletteModel.SetBgColor(tempColor);
+            paletteModel.SetBgColor(rgbColor);
+    }
 
+    void OnMouseMove(BOOL bLeftButton, LONG x, LONG y)
+    {
+        fetchColor(bLeftButton, x, y);
+    }
+
+    void OnButtonUp(BOOL bLeftButton, LONG x, LONG y)
+    {
+        fetchColor(bLeftButton, x, y);
         toolsModel.SetActiveTool(toolsModel.GetOldActiveTool());
     }
 };
@@ -368,12 +423,11 @@ struct TextTool : ToolBase
 
     void UpdatePoint(LONG x, LONG y)
     {
-        POINT temp;
         imageModel.ResetToPrevious();
-        temp.x = max(0, min(x, imageModel.GetWidth()));
-        temp.y = max(0, min(y, imageModel.GetHeight()));
-        selectionModel.SetSrcAndDestRectFromPoints(start, temp);
-        RectSel(m_hdc, start.x, start.y, temp.x, temp.y);
+        POINT pt = { x, y };
+        imageModel.Bound(pt);
+        selectionModel.SetSrcAndDestRectFromPoints(start, pt);
+        RectSel(m_hdc, start.x, start.y, pt.x, pt.y);
     }
 
     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
@@ -392,7 +446,7 @@ struct TextTool : ToolBase
 
     void OnButtonUp(BOOL bLeftButton, LONG x, LONG y)
     {
-        imageModel.ResetToPrevious();
+        imageModel.Undo(TRUE);
 
         BOOL bTextBoxShown = ::IsWindowVisible(textEditWindow);
         if (bTextBoxShown && textEditWindow.GetWindowTextLength() > 0)
@@ -405,6 +459,7 @@ struct TextTool : ToolBase
             textEditWindow.GetEditRect(&rc);
 
             INT style = (toolsModel.IsBackgroundTransparent() ? 0 : 1);
+            imageModel.CopyPrevious();
             Text(m_hdc, rc.left, rc.top, rc.right, rc.bottom, m_fg, m_bg, 
szText,
                  textEditWindow.GetFont(), style);
         }
@@ -451,13 +506,12 @@ struct TextTool : ToolBase
         }
     }
 
-    void OnCancelDraw()
+    void OnFinishDraw()
     {
-        imageModel.ResetToPrevious();
-        selectionModel.ResetPtStack();
-        textEditWindow.SetWindowText(NULL);
-        textEditWindow.ShowWindow(SW_HIDE);
-        ToolBase::OnCancelDraw();
+        toolsModel.OnButtonDown(TRUE, -1, -1, TRUE);
+        toolsModel.OnButtonUp(TRUE, -1, -1);
+        selectionWindow.IsMoved(FALSE);
+        ToolBase::OnFinishDraw();
     }
 };
 
@@ -481,7 +535,9 @@ struct LineTool : GenericDrawTool
 // TOOL_BEZIER
 struct BezierTool : ToolBase
 {
-    BezierTool() : ToolBase(TOOL_BEZIER)
+    BOOL m_bLeftButton;
+
+    BezierTool() : ToolBase(TOOL_BEZIER), m_bLeftButton(FALSE)
     {
     }
 
@@ -501,6 +557,7 @@ struct BezierTool : ToolBase
                 Bezier(m_hdc, pointStack[0], pointStack[2], pointStack[3], 
pointStack[1], rgb, toolsModel.GetLineWidth());
                 break;
         }
+        m_bLeftButton = bLeftButton;
     }
 
     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
@@ -535,10 +592,20 @@ struct BezierTool : ToolBase
     void OnCancelDraw()
     {
         OnButtonUp(FALSE, 0, 0);
-        imageModel.Undo();
-        selectionModel.ResetPtStack();
+        imageModel.Undo(TRUE);
         ToolBase::OnCancelDraw();
     }
+
+    void OnFinishDraw()
+    {
+        if (pointSP)
+        {
+            imageModel.ResetToPrevious();
+            --pointSP;
+            draw(m_bLeftButton);
+        }
+        ToolBase::OnFinishDraw();
+    }
 };
 
 // TOOL_RECT
@@ -563,7 +630,9 @@ struct RectTool : GenericDrawTool
 // TOOL_SHAPE
 struct ShapeTool : ToolBase
 {
-    ShapeTool() : ToolBase(TOOL_SHAPE)
+    BOOL m_bLeftButton;
+
+    ShapeTool() : ToolBase(TOOL_SHAPE), m_bLeftButton(FALSE)
     {
     }
 
@@ -576,6 +645,7 @@ struct ShapeTool : ToolBase
             else
                 Poly(m_hdc, pointStack, pointSP + 1, m_bg, m_fg, 
toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), bClosed, FALSE);
         }
+        m_bLeftButton = bLeftButton;
     }
 
     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
@@ -631,10 +701,25 @@ struct ShapeTool : ToolBase
 
     void OnCancelDraw()
     {
-        imageModel.ResetToPrevious();
-        selectionModel.ResetPtStack();
+        imageModel.Undo(TRUE);
         ToolBase::OnCancelDraw();
     }
+
+    void OnFinishDraw()
+    {
+        if (pointSP)
+        {
+            imageModel.ResetToPrevious();
+            --pointSP;
+            draw(m_bLeftButton, -1, -1, TRUE);
+            pointSP = 0;
+        }
+        else
+        {
+            imageModel.Undo(TRUE);
+        }
+        ToolBase::OnFinishDraw();
+    }
 };
 
 // TOOL_ELLIPSE
diff --git a/base/applications/mspaint/palette.cpp 
b/base/applications/mspaint/palette.cpp
index 9667397a5bf..24fe9c96bf5 100644
--- a/base/applications/mspaint/palette.cpp
+++ b/base/applications/mspaint/palette.cpp
@@ -19,9 +19,9 @@ LRESULT CPaletteWindow::OnPaint(UINT nMsg, WPARAM wParam, 
LPARAM lParam, BOOL& b
     HBRUSH oldBrush;
     int i, a, b;
 
-    DefWindowProc(WM_PAINT, wParam, lParam);
+    PAINTSTRUCT ps;
+    HDC hDC = BeginPaint(&ps);
 
-    HDC hDC = GetDC();
     for(b = 2; b < 30; b++)
         for(a = 2; a < 29; a++)
             if ((a + b) % 2 == 1)
@@ -54,7 +54,7 @@ LRESULT CPaletteWindow::OnPaint(UINT nMsg, WPARAM wParam, 
LPARAM lParam, BOOL& b
         DeleteObject(SelectObject(hDC, oldBrush));
         DeleteObject(SelectObject(hDC, oldPen));
     }
-    ReleaseDC(hDC);
+    EndPaint(&ps);
     return 0;
 }
 
diff --git a/base/applications/mspaint/selection.cpp 
b/base/applications/mspaint/selection.cpp
index 74083505bc2..d3e7fe6065a 100644
--- a/base/applications/mspaint/selection.cpp
+++ b/base/applications/mspaint/selection.cpp
@@ -54,14 +54,13 @@ ColorKeyedMaskBlt(HDC hdcDest, int nXDest, int nYDest, int 
nWidth, int nHeight,
     return TRUE;
 }
 
-void
-ForceRefreshSelectionContents()
+void CSelectionWindow::ForceRefreshSelectionContents()
 {
     if (::IsWindowVisible(selectionWindow))
     {
-        selectionWindow.SendMessage(WM_LBUTTONDOWN, 0, MAKELPARAM(0, 0));
-        selectionWindow.SendMessage(WM_MOUSEMOVE,   0, MAKELPARAM(0, 0));
-        selectionWindow.SendMessage(WM_LBUTTONUP,   0, MAKELPARAM(0, 0));
+        imageModel.ResetToPrevious();
+        imageModel.DrawSelectionBackground(m_rgbBack);
+        selectionModel.DrawSelection(imageModel.GetDC(), 
paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent());
     }
 }
 
@@ -90,16 +89,16 @@ int CSelectionWindow::IdentifyCorner(int iXPos, int iYPos, 
int iWidth, int iHeig
 
 LRESULT CSelectionWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, 
BOOL& bHandled)
 {
-    DefWindowProc(WM_PAINT, wParam, lParam);
+    PAINTSTRUCT ps;
+    HDC hDC = BeginPaint(&ps);
     if (!m_bMoving)
     {
-        HDC hDC = GetDC();
         SelectionFrame(hDC, 1, 1,
                        Zoomed(selectionModel.GetDestRectWidth()) + (GRIP_SIZE 
* 2) - 1,
                        Zoomed(selectionModel.GetDestRectHeight()) + (GRIP_SIZE 
* 2) - 1,
                        GetSysColor(COLOR_HIGHLIGHT));
-        ReleaseDC(hDC);
     }
+    EndPaint(&ps);
     return 0;
 }
 
@@ -145,6 +144,7 @@ LRESULT CSelectionWindow::OnLButtonDown(UINT nMsg, WPARAM 
wParam, LPARAM lParam,
     scrlClientWindow.SendMessage(WM_PAINT, 0, 0);
     imageArea.InvalidateRect(NULL, FALSE);
     imageArea.SendMessage(WM_PAINT, 0, 0);
+    m_rgbBack = paletteModel.GetBgColor();
     return 0;
 }
 
@@ -153,6 +153,7 @@ LRESULT CSelectionWindow::OnMouseMove(UINT nMsg, WPARAM 
wParam, LPARAM lParam, B
     if (m_bMoving)
     {
         imageModel.ResetToPrevious();
+        imageModel.DrawSelectionBackground(m_rgbBack);
         m_ptFrac.x += GET_X_LPARAM(lParam) - m_ptPos.x;
         m_ptFrac.y += GET_Y_LPARAM(lParam) - m_ptPos.y;
         m_ptDelta.x += UnZoomed(m_ptFrac.x);
@@ -173,17 +174,10 @@ LRESULT CSelectionWindow::OnMouseMove(UINT nMsg, WPARAM 
wParam, LPARAM lParam, B
         strSize.Format(_T("%ld x %ld"), selectionModel.GetDestRectWidth(), 
selectionModel.GetDestRectHeight());
         SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) (LPCTSTR) strSize);
 
-        if (toolsModel.GetActiveTool() == TOOL_TEXT)
-        {
-            selectionModel.DrawTextToolText(imageModel.GetDC(), 
paletteModel.GetFgColor(), paletteModel.GetBgColor(), 
toolsModel.IsBackgroundTransparent());
-        }
+        if (m_iAction != ACTION_MOVE)
+            selectionModel.DrawSelectionStretched(imageModel.GetDC());
         else
-        {
-            if (m_iAction != ACTION_MOVE)
-                selectionModel.DrawSelectionStretched(imageModel.GetDC());
-            else
-                selectionModel.DrawSelection(imageModel.GetDC(), 
paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent());
-        }
+            selectionModel.DrawSelection(imageModel.GetDC(), 
paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent());
         imageArea.InvalidateRect(NULL, FALSE);
         imageArea.SendMessage(WM_PAINT, 0, 0);
         m_ptPos.x = GET_X_LPARAM(lParam);
@@ -203,26 +197,26 @@ LRESULT CSelectionWindow::OnMouseMove(UINT nMsg, WPARAM 
wParam, LPARAM lParam, B
     return 0;
 }
 
+LRESULT CSelectionWindow::OnMove(UINT nMsg, WPARAM wParam, LPARAM lParam, 
BOOL& bHandled)
+{
+    m_bMoved = TRUE;
+    return 0;
+}
+
 LRESULT CSelectionWindow::OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, 
BOOL& bHandled)
 {
     if (m_bMoving)
     {
         m_bMoving = FALSE;
         ReleaseCapture();
-        if (m_iAction != ACTION_MOVE)
+        if (m_iAction != ACTION_MOVE && toolsModel.GetActiveTool() != 
TOOL_TEXT)
         {
-            if (toolsModel.GetActiveTool() == TOOL_TEXT)
-            {
-                // FIXME: What to do?
-            }
-            else
-            {
-                selectionModel.ScaleContentsToFit();
-            }
+            imageModel.Undo();
+            imageModel.DrawSelectionBackground(m_rgbBack);
+            selectionModel.ScaleContentsToFit();
+            imageModel.CopyPrevious();
         }
         placeSelWin();
-        ShowWindow(SW_HIDE);
-        ShowWindow(SW_SHOW);
     }
     return 0;
 }
@@ -234,10 +228,10 @@ LRESULT CSelectionWindow::OnCaptureChanged(UINT nMsg, 
WPARAM wParam, LPARAM lPar
         m_bMoving = FALSE;
         if (m_iAction == ACTION_MOVE)
         {
-            // FIXME: dirty hack
-            placeSelWin();
-            imageModel.Undo();
-            imageModel.Undo();
+            if (toolsModel.GetActiveTool() == TOOL_RECTSEL)
+                imageArea.cancelDrawing();
+            else
+                placeSelWin();
         }
         else
         {
@@ -262,23 +256,16 @@ LRESULT CSelectionWindow::OnKeyDown(UINT nMsg, WPARAM 
wParam, LPARAM lParam, BOO
 
 LRESULT CSelectionWindow::OnPaletteModelColorChanged(UINT nMsg, WPARAM wParam, 
LPARAM lParam, BOOL& bHandled)
 {
-    if (toolsModel.GetActiveTool() == TOOL_TEXT)
-        ForceRefreshSelectionContents();
     return 0;
 }
 
 LRESULT CSelectionWindow::OnToolsModelSettingsChanged(UINT nMsg, WPARAM 
wParam, LPARAM lParam, BOOL& bHandled)
 {
-    if (toolsModel.GetActiveTool() == TOOL_FREESEL ||
-        toolsModel.GetActiveTool() == TOOL_RECTSEL ||
-        toolsModel.GetActiveTool() == TOOL_TEXT)
-        ForceRefreshSelectionContents();
     return 0;
 }
 
 LRESULT CSelectionWindow::OnSelectionModelRefreshNeeded(UINT nMsg, WPARAM 
wParam, LPARAM lParam, BOOL& bHandled)
 {
-    ForceRefreshSelectionContents();
     return 0;
 }
 
diff --git a/base/applications/mspaint/selection.h 
b/base/applications/mspaint/selection.h
index 82ba84a6016..8e61b77d9ef 100644
--- a/base/applications/mspaint/selection.h
+++ b/base/applications/mspaint/selection.h
@@ -12,6 +12,15 @@
 class CSelectionWindow : public CWindowImpl<CSelectionWindow>
 {
 public:
+    CSelectionWindow() : m_bMoved(FALSE)
+    {
+    }
+
+    BOOL IsMoved() const        { return m_bMoved; }
+    void IsMoved(BOOL bMoved)   { m_bMoved = bMoved; }
+
+    void ForceRefreshSelectionContents();
+
     DECLARE_WND_CLASS_EX(_T("Selection"), CS_DBLCLKS, COLOR_BTNFACE)
 
     BEGIN_MSG_MAP(CSelectionWindow)
@@ -24,6 +33,7 @@ public:
         MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
         MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel)
         MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
+        MESSAGE_HANDLER(WM_MOVE, OnMove)
         MESSAGE_HANDLER(WM_PALETTEMODELCOLORCHANGED, 
OnPaletteModelColorChanged)
         MESSAGE_HANDLER(WM_TOOLSMODELSETTINGSCHANGED, 
OnToolsModelSettingsChanged)
         MESSAGE_HANDLER(WM_TOOLSMODELZOOMCHANGED, OnToolsModelZoomChanged)
@@ -47,14 +57,17 @@ public:
     LRESULT OnSelectionModelRefreshNeeded(UINT nMsg, WPARAM wParam, LPARAM 
lParam, BOOL& bHandled);
     LRESULT OnCaptureChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& 
bHandled);
     LRESULT OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+    LRESULT OnMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
 
 private:
     static const LPCTSTR m_lpszCursorLUT[9];
+    BOOL m_bMoved;
     BOOL m_bMoving;
     int m_iAction;
     POINT m_ptPos;
     POINT m_ptFrac;
     POINT m_ptDelta;
+    COLORREF m_rgbBack;
 
     int IdentifyCorner(int iXPos, int iYPos, int iWidth, int iHeight);
 };
diff --git a/base/applications/mspaint/selectionmodel.cpp 
b/base/applications/mspaint/selectionmodel.cpp
index 50c6ad4a53f..86d34dbd86d 100644
--- a/base/applications/mspaint/selectionmodel.cpp
+++ b/base/applications/mspaint/selectionmodel.cpp
@@ -337,11 +337,6 @@ LONG SelectionModel::GetDestRectTop() const
     return m_rcDest.top;
 }
 
-void SelectionModel::DrawTextToolText(HDC hDCImage, COLORREF crFg, COLORREF 
crBg, BOOL bBgTransparent)
-{
-    Text(hDCImage, m_rcDest.left, m_rcDest.top, m_rcDest.right, 
m_rcDest.bottom, crFg, crBg, textToolText, hfontTextFont, bBgTransparent);
-}
-
 void SelectionModel::NotifyRefreshNeeded()
 {
     selectionWindow.SendMessage(WM_SELECTIONMODELREFRESHNEEDED);
diff --git a/base/applications/mspaint/selectionmodel.h 
b/base/applications/mspaint/selectionmodel.h
index 523f22145fb..0243bc08f96 100644
--- a/base/applications/mspaint/selectionmodel.h
+++ b/base/applications/mspaint/selectionmodel.h
@@ -66,7 +66,6 @@ public:
     LONG GetDestRectLeft() const;
     LONG GetDestRectTop() const;
     void GetRect(LPRECT prc) const;
-    void DrawTextToolText(HDC hDCImage, COLORREF crFg, COLORREF crBg, BOOL 
bBgTransparent = FALSE);
 
 private:
     SelectionModel(const SelectionModel&);
diff --git a/base/applications/mspaint/toolsettings.cpp 
b/base/applications/mspaint/toolsettings.cpp
index 0c3d3e0bdf9..19f826ea825 100644
--- a/base/applications/mspaint/toolsettings.cpp
+++ b/base/applications/mspaint/toolsettings.cpp
@@ -33,12 +33,11 @@ LRESULT CToolSettingsWindow::OnVScroll(UINT nMsg, WPARAM 
wParam, LPARAM lParam,
 
 LRESULT CToolSettingsWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, 
BOOL& bHandled)
 {
+    PAINTSTRUCT ps;
     RECT rect1 = { 0, 0, 42, 66 };
     RECT rect2 = { 0, 70, 42, 136 };
 
-    DefWindowProc(WM_PAINT, wParam, lParam);
-
-    HDC hdc = GetDC();
+    HDC hdc = BeginPaint(&ps);
     DrawEdge(hdc, &rect1, BDR_SUNKENOUTER, (toolsModel.GetActiveTool() == 
TOOL_ZOOM) ? BF_RECT : BF_RECT | BF_MIDDLE);
     DrawEdge(hdc, &rect2, (toolsModel.GetActiveTool() >= TOOL_RECT) ? 
BDR_SUNKENOUTER : 0, BF_RECT | BF_MIDDLE);
     switch (toolsModel.GetActiveTool())
@@ -181,7 +180,7 @@ LRESULT CToolSettingsWindow::OnPaint(UINT nMsg, WPARAM 
wParam, LPARAM lParam, BO
         case TOOL_PEN:
             break;
     }
-    ReleaseDC(hdc);
+    EndPaint(&ps);
     return 0;
 }
 
diff --git a/base/applications/mspaint/toolsmodel.cpp 
b/base/applications/mspaint/toolsmodel.cpp
index 8811cf087ff..e42b04c6230 100644
--- a/base/applications/mspaint/toolsmodel.cpp
+++ b/base/applications/mspaint/toolsmodel.cpp
@@ -85,6 +85,11 @@ TOOLTYPE ToolsModel::GetOldActiveTool() const
 
 void ToolsModel::SetActiveTool(TOOLTYPE nActiveTool)
 {
+    OnFinishDraw();
+
+    if (m_activeTool == nActiveTool)
+        return;
+
     switch (m_activeTool)
     {
         case TOOL_FREESEL:
@@ -92,15 +97,7 @@ void ToolsModel::SetActiveTool(TOOLTYPE nActiveTool)
         case TOOL_RUBBER:
         case TOOL_COLOR:
         case TOOL_ZOOM:
-            break;
-
         case TOOL_TEXT:
-            if (nActiveTool != TOOL_TEXT)
-            {
-                // Finish the text
-                OnButtonDown(TRUE, -1, -1, TRUE);
-                OnButtonUp(TRUE, -1, -1);
-            }
             break;
 
         default:
@@ -171,15 +168,18 @@ void ToolsModel::NotifyToolChanged()
 
 void ToolsModel::NotifyToolSettingsChanged()
 {
-    toolSettingsWindow.SendMessage(WM_TOOLSMODELSETTINGSCHANGED);
-    selectionWindow.SendMessage(WM_TOOLSMODELSETTINGSCHANGED);
+    if (toolSettingsWindow.IsWindow())
+        toolSettingsWindow.SendMessage(WM_TOOLSMODELSETTINGSCHANGED);
+    if (selectionWindow.IsWindow())
+        selectionWindow.SendMessage(WM_TOOLSMODELSETTINGSCHANGED);
     if (textEditWindow.IsWindow())
         textEditWindow.SendMessage(WM_TOOLSMODELSETTINGSCHANGED);
 }
 
 void ToolsModel::NotifyZoomChanged()
 {
-    toolSettingsWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED);
+    if (toolSettingsWindow.IsWindow())
+        toolSettingsWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED);
     if (textEditWindow.IsWindow())
         textEditWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED);
     if (selectionWindow.IsWindow())
@@ -212,11 +212,20 @@ void ToolsModel::OnButtonUp(BOOL bLeftButton, LONG x, 
LONG y)
 
 void ToolsModel::OnCancelDraw()
 {
+    ATLTRACE("ToolsModel::OnCancelDraw()\n");
     m_pToolObject->beginEvent();
     m_pToolObject->OnCancelDraw();
     m_pToolObject->endEvent();
 }
 
+void ToolsModel::OnFinishDraw()
+{
+    ATLTRACE("ToolsModel::OnFinishDraw()\n");
+    m_pToolObject->beginEvent();
+    m_pToolObject->OnFinishDraw();
+    m_pToolObject->endEvent();
+}
+
 void ToolsModel::resetTool()
 {
     m_pToolObject->reset();
diff --git a/base/applications/mspaint/toolsmodel.h 
b/base/applications/mspaint/toolsmodel.h
index f6d4496d985..9d3a053e576 100644
--- a/base/applications/mspaint/toolsmodel.h
+++ b/base/applications/mspaint/toolsmodel.h
@@ -60,6 +60,7 @@ struct ToolBase
     }
 
     virtual void OnCancelDraw();
+    virtual void OnFinishDraw();
 
     void beginEvent();
     void endEvent();
@@ -110,6 +111,7 @@ public:
     void OnMouseMove(BOOL bLeftButton, LONG x, LONG y);
     void OnButtonUp(BOOL bLeftButton, LONG x, LONG y);
     void OnCancelDraw();
+    void OnFinishDraw();
 
     void resetTool();
     void selectAll();
diff --git a/base/applications/mspaint/winproc.cpp 
b/base/applications/mspaint/winproc.cpp
index 9105d85115e..b76a310070b 100644
--- a/base/applications/mspaint/winproc.cpp
+++ b/base/applications/mspaint/winproc.cpp
@@ -89,6 +89,8 @@ void CMainWindow::alignChildrenToMainWindow()
 
 void CMainWindow::saveImage(BOOL overwrite)
 {
+    imageArea.finishDrawing();
+
     if (isAFile && overwrite)
     {
         imageModel.SaveImage(filepathname);
@@ -156,7 +158,7 @@ void CMainWindow::InsertSelectionFromHBITMAP(HBITMAP 
bitmap, HWND window)
 
     placeSelWin();
     selectionWindow.ShowWindow(SW_SHOW);
-    ForceRefreshSelectionContents();
+    selectionWindow.ForceRefreshSelectionContents();
 }
 
 LRESULT CMainWindow::OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, 
BOOL& bHandled)
@@ -238,6 +240,8 @@ LRESULT CMainWindow::OnDestroy(UINT nMsg, WPARAM wParam, 
LPARAM lParam, BOOL& bH
 
 BOOL CMainWindow::ConfirmSave()
 {
+    imageArea.finishDrawing();
+
     if (imageModel.IsImageSaved())
         return TRUE;
 
@@ -407,14 +411,7 @@ LRESULT CMainWindow::OnKeyDown(UINT nMsg, WPARAM wParam, 
LPARAM lParam, BOOL& bH
         }
         else
         {
-            switch (toolsModel.GetActiveTool())
-            {
-                case TOOL_SHAPE: case TOOL_BEZIER:
-                    imageArea.SendMessage(nMsg, wParam, lParam);
-                    break;
-                default:
-                    break;
-            }
+            imageArea.SendMessage(nMsg, wParam, lParam);
         }
     }
     return 0;
@@ -430,6 +427,13 @@ LRESULT CMainWindow::OnSysColorChange(UINT nMsg, WPARAM 
wParam, LPARAM lParam, B
 
 LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& 
bHandled)
 {
+    // Disable commands while dragging mouse
+    if (imageArea.drawing && ::GetCapture())
+    {
+        ATLTRACE("locking!\n");
+        return 0;
+    }
+
     switch (LOWORD(wParam))
     {
         case IDM_HELPINFO:
@@ -531,12 +535,31 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, 
LPARAM lParam, BOOL& bH
         case IDM_EDITUNDO:
             if (toolsModel.GetActiveTool() == TOOL_TEXT && 
::IsWindowVisible(textEditWindow))
                 break;
+            if (selectionWindow.IsWindowVisible())
+            {
+                if (toolsModel.GetActiveTool() == TOOL_RECTSEL ||
+                    toolsModel.GetActiveTool() == TOOL_FREESEL)
+                {
+                    imageArea.cancelDrawing();
+                    break;
+                }
+            }
+            if (ToolBase::pointSP != 0) // drawing something?
+            {
+                imageArea.cancelDrawing();
+                break;
+            }
             imageModel.Undo();
             imageArea.Invalidate(FALSE);
             break;
         case IDM_EDITREDO:
             if (toolsModel.GetActiveTool() == TOOL_TEXT && 
::IsWindowVisible(textEditWindow))
                 break;
+            if (ToolBase::pointSP != 0) // drawing something?
+            {
+                imageArea.finishDrawing();
+                break;
+            }
             imageModel.Redo();
             imageArea.Invalidate(FALSE);
             break;
@@ -562,8 +585,19 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, 
LPARAM lParam, BOOL& bH
             break;
         case IDM_EDITDELETESELECTION:
         {
-            /* remove selection window and already painted content using undo 
*/
-            imageModel.Undo();
+            switch (toolsModel.GetActiveTool())
+            {
+                case TOOL_FREESEL:
+                case TOOL_RECTSEL:
+                    imageModel.DeleteSelection();
+                    break;
+
+                case TOOL_TEXT:
+                    imageArea.cancelDrawing();
+                    break;
+                default:
+                    break;
+            }
             break;
         }
         case IDM_EDITSELECTALL:

Reply via email to