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))