https://git.reactos.org/?p=reactos.git;a=commitdiff;h=bfd42c67a1255f8d3e2aa…
commit bfd42c67a1255f8d3e2aa974f435942a06ca7925
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Wed Jun 14 18:51:40 2023 +0900
Commit: GitHub <noreply(a)github.com>
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))