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

commit bfd42c67a1255f8d3e2aa974f435942a06ca7925
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Wed Jun 14 18:51:40 2023 +0900
Commit:     GitHub <[email protected]>
CommitDate: Wed Jun 14 18:51:40 2023 +0900

    [MSPAINT] Improve CMiniatureWindow (#5337)
    
    - Save the position and size of the miniature window.
    - Improve drawing of the miniature window.
    - Sync with the canvas.
    CORE-18867
---
 base/applications/mspaint/history.cpp        |  4 +-
 base/applications/mspaint/history.h          |  5 +--
 base/applications/mspaint/miniature.cpp      | 60 ++++++++++++++++++++++++++--
 base/applications/mspaint/miniature.h        |  6 +++
 base/applications/mspaint/mouse.cpp          | 16 ++++----
 base/applications/mspaint/selectionmodel.cpp | 17 +++-----
 base/applications/mspaint/selectionmodel.h   |  1 -
 base/applications/mspaint/toolsmodel.cpp     |  3 +-
 base/applications/mspaint/winproc.cpp        |  8 ++--
 9 files changed, 86 insertions(+), 34 deletions(-)

diff --git a/base/applications/mspaint/history.cpp 
b/base/applications/mspaint/history.cpp
index ae6fb27b451..92ef896afd0 100644
--- a/base/applications/mspaint/history.cpp
+++ b/base/applications/mspaint/history.cpp
@@ -17,6 +17,8 @@ void ImageModel::NotifyImageChanged()
 {
     if (canvasWindow.IsWindow())
         canvasWindow.Invalidate(FALSE);
+    if (miniature.IsWindow())
+        miniature.Invalidate(FALSE);
 }
 
 ImageModel::ImageModel()
@@ -264,7 +266,7 @@ void ImageModel::DeleteSelection()
     NotifyImageChanged();
 }
 
-void ImageModel::Bound(POINT& pt)
+void ImageModel::Bound(POINT& pt) const
 {
     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 86c312df871..00e66950425 100644
--- a/base/applications/mspaint/history.h
+++ b/base/applications/mspaint/history.h
@@ -36,7 +36,8 @@ public:
     void FlipVertically();
     void RotateNTimes90Degrees(int iN);
     void DeleteSelection();
-    void Bound(POINT& pt);
+    void Bound(POINT& pt) const;
+    void NotifyImageChanged();
 
 protected:
     HDC hDrawingDC; // The device context for this class
@@ -44,6 +45,4 @@ protected:
     int undoSteps; // The undo-able count
     int redoSteps; // The redo-able count
     HBITMAP hBms[HISTORYSIZE]; // A rotation buffer of HBITMAPs
-
-    void NotifyImageChanged();
 };
diff --git a/base/applications/mspaint/miniature.cpp 
b/base/applications/mspaint/miniature.cpp
index c048d0d2c15..d496a7f74a7 100644
--- a/base/applications/mspaint/miniature.cpp
+++ b/base/applications/mspaint/miniature.cpp
@@ -5,6 +5,7 @@
  * PURPOSE:     Window procedure of the main window and all children apart from
  *              hPalWin, hToolSettings and hSelection
  * PROGRAMMERS: Benedikt Freisen
+ *              Katayama Hirofumi MZ
  */
 
 #include "precomp.h"
@@ -32,6 +33,30 @@ HWND CMiniatureWindow::DoCreate(HWND hwndParent)
     return Create(hwndParent, rc, strTitle, style, WS_EX_PALETTEWINDOW);
 }
 
+LRESULT CMiniatureWindow::OnMove(UINT nMsg, WPARAM wParam, LPARAM lParam, 
BOOL& bHandled)
+{
+    if (IsWindowVisible() && !IsIconic() && !IsZoomed())
+    {
+        CRect rc;
+        GetWindowRect(&rc);
+        registrySettings.ThumbXPos = rc.left;
+        registrySettings.ThumbYPos = rc.top;
+    }
+    return 0;
+}
+
+LRESULT CMiniatureWindow::OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, 
BOOL& bHandled)
+{
+    if (IsWindowVisible() && !IsIconic() && !IsZoomed())
+    {
+        CRect rc;
+        GetWindowRect(&rc);
+        registrySettings.ThumbWidth = rc.Width();
+        registrySettings.ThumbHeight = rc.Height();
+    }
+    return 0;
+}
+
 LRESULT CMiniatureWindow::OnClose(UINT nMsg, WPARAM wParam, LPARAM lParam, 
BOOL& bHandled)
 {
     ShowWindow(SW_HIDE);
@@ -39,16 +64,45 @@ LRESULT CMiniatureWindow::OnClose(UINT nMsg, WPARAM wParam, 
LPARAM lParam, BOOL&
     return 0;
 }
 
+LRESULT CMiniatureWindow::OnEraseBkgnd(UINT nMsg, WPARAM wParam, LPARAM 
lParam, BOOL& bHandled)
+{
+    return TRUE; /* Avoid flickering */
+}
+
 LRESULT CMiniatureWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, 
BOOL& bHandled)
 {
     RECT rc;
     GetClientRect(&rc);
 
+    // Start painting
     PAINTSTRUCT ps;
     HDC hDC = BeginPaint(&ps);
-    StretchBlt(hDC, 0, 0, rc.right, rc.bottom,
-               imageModel.GetDC(), 0, 0, imageModel.GetWidth(), 
imageModel.GetHeight(),
-               SRCCOPY);
+    if (!hDC)
+        return 0;
+
+    // Use a memory bitmap to reduce flickering
+    HDC hdcMem = ::CreateCompatibleDC(hDC);
+    HGDIOBJ hbmOld = ::SelectObject(hdcMem, ::CreateCompatibleBitmap(hDC, 
rc.right, rc.bottom));
+
+    // FIXME: Consider aspect ratio
+
+    // Fill the background
+    ::FillRect(hdcMem, &rc, (HBRUSH)(COLOR_BTNFACE + 1));
+
+    // Draw the image (hdcMem <-- imageModel)
+    int cxImage = imageModel.GetWidth();
+    int cyImage = imageModel.GetHeight();
+    ::StretchBlt(hdcMem, 0, 0, rc.right, rc.bottom,
+                 imageModel.GetDC(), 0, 0, cxImage, cyImage,
+                 SRCCOPY);
+
+    // Move the image (hDC <-- hdcMem)
+    ::BitBlt(hDC, 0, 0, rc.right, rc.bottom, hdcMem, 0, 0, SRCCOPY);
+
+    // Clean up
+    ::DeleteObject(::SelectObject(hdcMem, hbmOld));
+    ::DeleteDC(hdcMem);
+
     EndPaint(&ps);
     return 0;
 }
diff --git a/base/applications/mspaint/miniature.h 
b/base/applications/mspaint/miniature.h
index 63f0fd6997a..c8126de691a 100644
--- a/base/applications/mspaint/miniature.h
+++ b/base/applications/mspaint/miniature.h
@@ -16,14 +16,20 @@ public:
                          COLOR_BTNFACE)
 
     BEGIN_MSG_MAP(CMiniatureWindow)
+        MESSAGE_HANDLER(WM_MOVE, OnMove)
+        MESSAGE_HANDLER(WM_SIZE, OnSize)
         MESSAGE_HANDLER(WM_CLOSE, OnClose)
+        MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
         MESSAGE_HANDLER(WM_PAINT, OnPaint)
     END_MSG_MAP()
 
     HWND DoCreate(HWND hwndParent);
 
 private:
+    LRESULT OnMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+    LRESULT OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
     LRESULT OnClose(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+    LRESULT OnEraseBkgnd(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& 
bHandled);
     LRESULT OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
     LRESULT OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& 
bHandled);
 };
diff --git a/base/applications/mspaint/mouse.cpp 
b/base/applications/mspaint/mouse.cpp
index 61395e8aa7f..3c0923bec58 100644
--- a/base/applications/mspaint/mouse.cpp
+++ b/base/applications/mspaint/mouse.cpp
@@ -78,11 +78,13 @@ void ToolBase::reset()
 void ToolBase::OnCancelDraw()
 {
     reset();
+    imageModel.NotifyImageChanged();
 }
 
 void ToolBase::OnFinishDraw()
 {
     reset();
+    imageModel.NotifyImageChanged();
 }
 
 void ToolBase::beginEvent()
@@ -151,15 +153,12 @@ struct FreeSelTool : ToolBase
                 selectionModel.ResetPtStack();
                 selectionModel.m_bShow = FALSE;
             }
-            canvasWindow.Invalidate(FALSE);
+            imageModel.NotifyImageChanged();
         }
     }
 
     void OnFinishDraw() override
     {
-        if (m_bLeftButton)
-            canvasWindow.Invalidate(FALSE);
-
         m_bLeftButton = FALSE;
         ToolBase::OnFinishDraw();
     }
@@ -214,15 +213,12 @@ struct RectSelTool : ToolBase
             if (start.x == x && start.y == y)
                 imageModel.Undo(TRUE);
             selectionModel.m_bShow = !selectionModel.m_rc.IsRectEmpty();
-            canvasWindow.Invalidate(FALSE);
+            imageModel.NotifyImageChanged();
         }
     }
 
     void OnFinishDraw() override
     {
-        if (m_bLeftButton)
-            canvasWindow.Invalidate(FALSE);
-
         m_bLeftButton = FALSE;
         ToolBase::OnFinishDraw();
     }
@@ -253,11 +249,13 @@ struct GenericDrawTool : ToolBase
     void OnMouseMove(BOOL bLeftButton, LONG x, LONG y) override
     {
         draw(bLeftButton, x, y);
+        imageModel.NotifyImageChanged();
     }
 
     void OnButtonUp(BOOL bLeftButton, LONG x, LONG y) override
     {
         draw(bLeftButton, x, y);
+        imageModel.NotifyImageChanged();
     }
 
     void OnCancelDraw() override
@@ -574,6 +572,7 @@ struct BezierTool : ToolBase
         pointSP++;
         if (pointSP == 4)
             pointSP = 0;
+        imageModel.NotifyImageChanged();
     }
 
     void OnCancelDraw() override
@@ -649,6 +648,7 @@ struct ShapeTool : ToolBase
         else
         {
             draw(bLeftButton, x, y, bDoubleClick);
+            imageModel.NotifyImageChanged();
         }
     }
 
diff --git a/base/applications/mspaint/selectionmodel.cpp 
b/base/applications/mspaint/selectionmodel.cpp
index 33ff6f05722..d70f324d805 100644
--- a/base/applications/mspaint/selectionmodel.cpp
+++ b/base/applications/mspaint/selectionmodel.cpp
@@ -179,7 +179,7 @@ BOOL SelectionModel::TakeOff()
         DrawBackgroundRect(hDCImage, paletteModel.GetBgColor());
     }
 
-    canvasWindow.Invalidate(FALSE);
+    imageModel.NotifyImageChanged();
     return TRUE;
 }
 
@@ -229,7 +229,7 @@ void SelectionModel::FlipHorizontally()
     }
     ::DeleteDC(hdcMem);
 
-    NotifyRefreshNeeded();
+    imageModel.NotifyImageChanged();
 }
 
 void SelectionModel::FlipVertically()
@@ -251,7 +251,7 @@ void SelectionModel::FlipVertically()
     }
     ::DeleteDC(hdcMem);
 
-    NotifyRefreshNeeded();
+    imageModel.NotifyImageChanged();
 }
 
 void SelectionModel::RotateNTimes90Degrees(int iN)
@@ -303,7 +303,7 @@ void SelectionModel::RotateNTimes90Degrees(int iN)
     }
 
     ::DeleteDC(hdcMem);
-    NotifyRefreshNeeded();
+    imageModel.NotifyImageChanged();
 }
 
 void SelectionModel::StretchSkew(int nStretchPercentX, int nStretchPercentY, 
int nSkewDegX, int nSkewDegY)
@@ -346,7 +346,7 @@ void SelectionModel::StretchSkew(int nStretchPercentX, int 
nStretchPercentY, int
     ::DeleteDC(hDC);
 
     m_bShow = TRUE;
-    NotifyRefreshNeeded();
+    imageModel.NotifyImageChanged();
 }
 
 HBITMAP SelectionModel::GetBitmap()
@@ -417,11 +417,6 @@ void SelectionModel::Dragging(CANVAS_HITTEST hit, POINT pt)
     m_ptHit = pt;
 }
 
-void SelectionModel::NotifyRefreshNeeded()
-{
-    canvasWindow.Invalidate(FALSE);
-}
-
 void SelectionModel::ClearMask()
 {
     if (m_hbmMask)
@@ -450,5 +445,5 @@ void SelectionModel::CancelSelection()
         imageModel.Undo(TRUE);
 
     m_bShow = FALSE;
-    canvasWindow.Invalidate(FALSE);
+    imageModel.NotifyImageChanged();
 }
diff --git a/base/applications/mspaint/selectionmodel.h 
b/base/applications/mspaint/selectionmodel.h
index af285e380d8..01a21c7bc62 100644
--- a/base/applications/mspaint/selectionmodel.h
+++ b/base/applications/mspaint/selectionmodel.h
@@ -49,7 +49,6 @@ public:
     void StretchSkew(int nStretchPercentX, int nStretchPercentY, int 
nSkewDegX, int nSkewDegY);
 
     void CancelSelection();
-    void NotifyRefreshNeeded();
     void Dragging(CANVAS_HITTEST hit, POINT pt);
     void ClearMask();
     void ClearColor();
diff --git a/base/applications/mspaint/toolsmodel.cpp 
b/base/applications/mspaint/toolsmodel.cpp
index bebb8687284..822547048f7 100644
--- a/base/applications/mspaint/toolsmodel.cpp
+++ b/base/applications/mspaint/toolsmodel.cpp
@@ -141,8 +141,7 @@ void ToolsModel::SetBackgroundTransparent(BOOL bTransparent)
 {
     m_transpBg = bTransparent;
     NotifyToolSettingsChanged();
-    if (canvasWindow.IsWindow())
-        canvasWindow.Invalidate(FALSE);
+    imageModel.NotifyImageChanged();
 }
 
 int ToolsModel::GetZoom() const
diff --git a/base/applications/mspaint/winproc.cpp 
b/base/applications/mspaint/winproc.cpp
index 80a225b8a8a..c3cc041ebe8 100644
--- a/base/applications/mspaint/winproc.cpp
+++ b/base/applications/mspaint/winproc.cpp
@@ -207,7 +207,7 @@ void CMainWindow::InsertSelectionFromHBITMAP(HBITMAP 
bitmap, HWND window)
     imageModel.PushImageForUndo();
     selectionModel.InsertFromHBITMAP(bitmap, 0, 0);
     selectionModel.m_bShow = TRUE;
-    canvasWindow.Invalidate(FALSE);
+    imageModel.NotifyImageChanged();
 }
 
 LRESULT CMainWindow::OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, 
BOOL& bHandled)
@@ -510,7 +510,7 @@ LRESULT CMainWindow::OnKeyDown(UINT nMsg, WPARAM wParam, 
LPARAM lParam, BOOL& bH
             {
                 selectionModel.Landing();
                 selectionModel.m_bShow = FALSE;
-                canvasWindow.Invalidate(FALSE);
+                imageModel.NotifyImageChanged();
             }
             break;
 
@@ -656,7 +656,6 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, 
LPARAM lParam, BOOL& bH
                 break;
             }
             imageModel.Undo();
-            canvasWindow.Invalidate(FALSE);
             break;
         case IDM_EDITREDO:
             if (toolsModel.GetActiveTool() == TOOL_TEXT && 
::IsWindowVisible(textEditWindow))
@@ -667,7 +666,6 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, 
LPARAM lParam, BOOL& bH
                 break;
             }
             imageModel.Redo();
-            canvasWindow.Invalidate(FALSE);
             break;
         case IDM_EDITCOPY:
             if (OpenClipboard())
@@ -763,7 +761,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, 
LPARAM lParam, BOOL& bH
         case IDM_IMAGEDELETEIMAGE:
             imageModel.PushImageForUndo();
             Rect(imageModel.GetDC(), 0, 0, imageModel.GetWidth(), 
imageModel.GetHeight(), paletteModel.GetBgColor(), paletteModel.GetBgColor(), 
0, TRUE);
-            canvasWindow.Invalidate(FALSE);
+            imageModel.NotifyImageChanged();
             break;
         case IDM_IMAGEROTATEMIRROR:
             switch (mirrorRotateDialog.DoModal(mainWindow.m_hWnd))

Reply via email to