From efe7368c46f910beb19b3500c989d7d947effcf6 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Sat, 8 Apr 2023 22:25:27 +0900 Subject: [PATCH] [MSPAINT] Make imageArea window-less (#5215) - Move imageArea code into canvasWindow. - Delete imgarea.cpp, imgarea.h, and imageArea. - Add CCanvasWindow::ImageToCanvas and CCanvasWindow::CanvasToImage to convert the coordinates. - Realize drawing of resizing image area. CORE-18867 --- base/applications/mspaint/CMakeLists.txt | 1 - base/applications/mspaint/canvas.cpp | 483 +++++++++++++++++-- base/applications/mspaint/canvas.h | 34 +- base/applications/mspaint/drawing.cpp | 11 + base/applications/mspaint/drawing.h | 2 + base/applications/mspaint/globalvar.h | 1 - base/applications/mspaint/history.cpp | 8 +- base/applications/mspaint/imgarea.cpp | 480 ------------------ base/applications/mspaint/imgarea.h | 84 ---- base/applications/mspaint/mouse.cpp | 12 +- base/applications/mspaint/palettemodel.cpp | 4 +- base/applications/mspaint/precomp.h | 1 - base/applications/mspaint/selectionmodel.cpp | 6 +- base/applications/mspaint/textedit.cpp | 30 +- base/applications/mspaint/toolsmodel.cpp | 8 +- base/applications/mspaint/winproc.cpp | 45 +- 16 files changed, 544 insertions(+), 666 deletions(-) delete mode 100644 base/applications/mspaint/imgarea.cpp delete mode 100644 base/applications/mspaint/imgarea.h diff --git a/base/applications/mspaint/CMakeLists.txt b/base/applications/mspaint/CMakeLists.txt index 57532cba22d..94b8e26c680 100644 --- a/base/applications/mspaint/CMakeLists.txt +++ b/base/applications/mspaint/CMakeLists.txt @@ -13,7 +13,6 @@ list(APPEND SOURCE drawing.cpp fullscreen.cpp history.cpp - imgarea.cpp main.cpp miniature.cpp mouse.cpp diff --git a/base/applications/mspaint/canvas.cpp b/base/applications/mspaint/canvas.cpp index c0fc4ad9210..000a44d7987 100644 --- a/base/applications/mspaint/canvas.cpp +++ b/base/applications/mspaint/canvas.cpp @@ -13,20 +13,79 @@ CCanvasWindow canvasWindow; /* FUNCTIONS ********************************************************/ CCanvasWindow::CCanvasWindow() - : m_whereHit(HIT_NONE) - , m_ptOrig { 0, 0 } + : m_drawing(FALSE) + , m_hitSelection(HIT_NONE) + , m_whereHit(HIT_NONE) + , m_ptOrig { -1, -1 } { + ::SetRectEmpty(&m_rcNew); +} + +VOID CCanvasWindow::drawZoomFrame(INT mouseX, INT mouseY) +{ + // FIXME: Draw the border of the area that is to be zoomed in + CRect rc; + GetImageRect(rc); + ImageToCanvas(rc); + + HDC hdc = GetDC(); + DrawXorRect(hdc, &rc); + ReleaseDC(hdc); } RECT CCanvasWindow::GetBaseRect() { - CRect rcBase = { 0, 0, Zoomed(imageModel.GetWidth()), Zoomed(imageModel.GetHeight()) }; + CRect rcBase; + GetImageRect(rcBase); + ImageToCanvas(rcBase); ::InflateRect(&rcBase, GRIP_SIZE, GRIP_SIZE); - ::OffsetRect(&rcBase, GRIP_SIZE - GetScrollPos(SB_HORZ), GRIP_SIZE - GetScrollPos(SB_VERT)); return rcBase; } -CANVAS_HITTEST CCanvasWindow::HitTest(POINT pt) +VOID CCanvasWindow::ImageToCanvas(POINT& pt) +{ + pt.x = Zoomed(pt.x); + pt.y = Zoomed(pt.y); + pt.x += GRIP_SIZE - GetScrollPos(SB_HORZ); + pt.y += GRIP_SIZE - GetScrollPos(SB_VERT); +} + +VOID CCanvasWindow::ImageToCanvas(RECT& rc) +{ + rc.left = Zoomed(rc.left); + rc.top = Zoomed(rc.top); + rc.right = Zoomed(rc.right); + rc.bottom = Zoomed(rc.bottom); + ::OffsetRect(&rc, GRIP_SIZE - GetScrollPos(SB_HORZ), GRIP_SIZE - GetScrollPos(SB_VERT)); +} + +VOID CCanvasWindow::CanvasToImage(POINT& pt, BOOL bZoomed) +{ + pt.x -= GRIP_SIZE - GetScrollPos(SB_HORZ); + pt.y -= GRIP_SIZE - GetScrollPos(SB_VERT); + if (bZoomed) + return; + pt.x = UnZoomed(pt.x); + pt.y = UnZoomed(pt.y); +} + +VOID CCanvasWindow::CanvasToImage(RECT& rc, BOOL bZoomed) +{ + ::OffsetRect(&rc, GetScrollPos(SB_HORZ) - GRIP_SIZE, GetScrollPos(SB_VERT) - GRIP_SIZE); + if (bZoomed) + return; + rc.left = UnZoomed(rc.left); + rc.top = UnZoomed(rc.top); + rc.right = UnZoomed(rc.right); + rc.bottom = UnZoomed(rc.bottom); +} + +VOID CCanvasWindow::GetImageRect(RECT& rc) +{ + ::SetRect(&rc, 0, 0, imageModel.GetWidth(), imageModel.GetHeight()); +} + +CANVAS_HITTEST CCanvasWindow::CanvasHitTest(POINT pt) { RECT rcBase = GetBaseRect(); return getSizeBoxHitTest(pt, &rcBase); @@ -42,9 +101,62 @@ VOID CCanvasWindow::DoDraw(HDC hDC, RECT& rcClient, RECT& rcPaint) // Fill the background ::FillRect(hdcMem, &rcPaint, (HBRUSH)(COLOR_APPWORKSPACE + 1)); - // Draw the sizeboxes + // Draw the sizeboxes if necessary RECT rcBase = GetBaseRect(); - drawSizeBoxes(hdcMem, &rcBase, FALSE, &rcPaint); + if (!selectionModel.m_bShow) + drawSizeBoxes(hdcMem, &rcBase, FALSE, &rcPaint); + + // Draw the image + CRect rcImage; + GetImageRect(rcImage); + ImageToCanvas(rcImage); + SIZE sizeImage = { imageModel.GetWidth(), imageModel.GetHeight() }; + StretchBlt(hdcMem, rcImage.left, rcImage.top, rcImage.Width(), rcImage.Height(), + imageModel.GetDC(), 0, 0, sizeImage.cx, sizeImage.cy, SRCCOPY); + + // Draw the grid + if (showGrid && toolsModel.GetZoom() >= 4000) + { + HPEN oldPen = (HPEN) SelectObject(hdcMem, CreatePen(PS_SOLID, 1, RGB(160, 160, 160))); + for (INT counter = 0; counter < sizeImage.cy; counter++) + { + POINT pt0 = { 0, counter }, pt1 = { sizeImage.cx, counter }; + ImageToCanvas(pt0); + ImageToCanvas(pt1); + ::MoveToEx(hdcMem, pt0.x, pt0.y, NULL); + ::LineTo(hdcMem, pt1.x, pt1.y); + } + for (INT counter = 0; counter < sizeImage.cx; counter++) + { + POINT pt0 = { counter, 0 }, pt1 = { counter, sizeImage.cy }; + ImageToCanvas(pt0); + ImageToCanvas(pt1); + ::MoveToEx(hdcMem, pt0.x, pt0.y, NULL); + ::LineTo(hdcMem, pt1.x, pt1.y); + } + ::DeleteObject(::SelectObject(hdcMem, oldPen)); + } + + // Draw selection + if (selectionModel.m_bShow) + { + RECT rcSelection = selectionModel.m_rc; + ImageToCanvas(rcSelection); + + ::InflateRect(&rcSelection, GRIP_SIZE, GRIP_SIZE); + drawSizeBoxes(hdcMem, &rcSelection, TRUE, &rcPaint); + ::InflateRect(&rcSelection, -GRIP_SIZE, -GRIP_SIZE); + + INT iSaveDC = ::SaveDC(hdcMem); + ::IntersectClipRect(hdcMem, rcImage.left, rcImage.top, rcImage.right, rcImage.bottom); + selectionModel.DrawSelection(hdcMem, &rcSelection, paletteModel.GetBgColor(), + toolsModel.IsBackgroundTransparent()); + ::RestoreDC(hdcMem, iSaveDC); + } + + // Draw new frame if any + if (!::IsRectEmpty(&m_rcNew)) + DrawXorRect(hdcMem, &m_rcNew); // Transfer the bits ::BitBlt(hDC, @@ -65,7 +177,7 @@ VOID CCanvasWindow::Update(HWND hwndFrom) CSize sizeZoomed = { Zoomed(imageModel.GetWidth()), Zoomed(imageModel.GetHeight()) }; CSize sizeWhole = { sizeZoomed.cx + (GRIP_SIZE * 2), sizeZoomed.cy + (GRIP_SIZE * 2) }; - /* show/hide the scrollbars */ + // show/hide the scrollbars ShowScrollBar(SB_HORZ, sizePage.cx < sizeWhole.cx); ShowScrollBar(SB_VERT, sizePage.cy < sizeWhole.cy); @@ -85,12 +197,6 @@ VOID CCanvasWindow::Update(HWND hwndFrom) si.nMax = sizeWhole.cy; si.nPage = sizePage.cy; SetScrollInfo(SB_VERT, &si); - - if (imageArea.IsWindow() && hwndFrom != imageArea.m_hWnd) - { - INT dx = -GetScrollPos(SB_HORZ), dy = -GetScrollPos(SB_VERT); - imageArea.MoveWindow(dx + GRIP_SIZE, dy + GRIP_SIZE, sizeZoomed.cx, sizeZoomed.cy, TRUE); - } } LRESULT CCanvasWindow::OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) @@ -143,60 +249,221 @@ LRESULT CCanvasWindow::OnVScroll(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& return 0; } -LRESULT CCanvasWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +LRESULT CCanvasWindow::OnLRButtonDown(BOOL bLeftButton, UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - CANVAS_HITTEST hit = HitTest(pt); + CANVAS_HITTEST hitSelection = SelectionHitTest(pt); + if (hitSelection != HIT_NONE) + { + if (bLeftButton) + { + UnZoomed(pt); + StartSelectionDrag(hitSelection, pt); + } + return 0; + } + + CANVAS_HITTEST hit = CanvasHitTest(pt); if (hit == HIT_NONE || hit == HIT_BORDER) { switch (toolsModel.GetActiveTool()) { case TOOL_BEZIER: case TOOL_SHAPE: - if (ToolBase::pointSP != 0) - { - toolsModel.OnCancelDraw(); - imageArea.Invalidate(); - } + toolsModel.OnCancelDraw(); + canvasWindow.Invalidate(); break; case TOOL_FREESEL: case TOOL_RECTSEL: toolsModel.OnFinishDraw(); - imageArea.Invalidate(); + canvasWindow.Invalidate(); break; default: break; } - toolsModel.resetTool(); // resets the point-buffer of the polygon and bezier functions + toolsModel.resetTool(); // resets the point-buffer of the polygon and bezier functions return 0; } + CanvasToImage(pt, TRUE); + if (hit == HIT_INNER) { - // TODO: In the future, we handle the events of the window-less image area. + m_drawing = TRUE; + UnZoomed(pt); + SetCapture(); + toolsModel.OnButtonDown(bLeftButton, pt.x, pt.y, FALSE); + Invalidate(FALSE); return 0; } - // Start dragging - m_whereHit = hit; - m_ptOrig = pt; - SetCapture(); + if (bLeftButton) + { + m_whereHit = hit; + UnZoomed(pt); + m_ptOrig = pt; + SetCapture(); + } return 0; } +LRESULT CCanvasWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + return OnLRButtonDown(TRUE, nMsg, wParam, lParam, bHandled); +} + +LRESULT CCanvasWindow::OnRButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + return OnLRButtonDown(FALSE, nMsg, wParam, lParam, bHandled); +} + +LRESULT CCanvasWindow::OnLRButtonDblClk(BOOL bLeftButton, UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + CanvasToImage(pt); + + m_drawing = FALSE; + ReleaseCapture(); + + toolsModel.OnButtonDown(bLeftButton, pt.x, pt.y, TRUE); + toolsModel.resetTool(); + Invalidate(FALSE); + return 0; +} + +LRESULT CCanvasWindow::OnLButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + return OnLRButtonDblClk(TRUE, nMsg, wParam, lParam, bHandled); +} + +LRESULT CCanvasWindow::OnRButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + return OnLRButtonDblClk(FALSE, nMsg, wParam, lParam, bHandled); +} + LRESULT CCanvasWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { + POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + CanvasToImage(pt); + + if (m_hitSelection != HIT_NONE) + { + SelectionDragging(pt); + return 0; + } + + if (!m_drawing || toolsModel.GetActiveTool() <= TOOL_AIRBRUSH) + { + if (toolsModel.GetActiveTool() == TOOL_ZOOM) + { + Invalidate(FALSE); + UpdateWindow(); + CanvasToImage(pt); + drawZoomFrame(pt.x, pt.y); + } + + TRACKMOUSEEVENT tme = { sizeof(tme) }; + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = m_hWnd; + tme.dwHoverTime = 0; + ::TrackMouseEvent(&tme); + + if (!m_drawing) + { + CString strCoord; + strCoord.Format(_T("%ld, %ld"), pt.x, pt.y); + SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) (LPCTSTR) strCoord); + } + } + + if (m_drawing) + { + // values displayed in statusbar + LONG xRel = pt.x - start.x; + LONG yRel = pt.y - start.y; + + switch (toolsModel.GetActiveTool()) + { + // freesel, rectsel and text tools always show numbers limited to fit into image area + case TOOL_FREESEL: + case TOOL_RECTSEL: + case TOOL_TEXT: + if (xRel < 0) + xRel = (pt.x < 0) ? -start.x : xRel; + else if (pt.x > imageModel.GetWidth()) + xRel = imageModel.GetWidth() - start.x; + if (yRel < 0) + yRel = (pt.y < 0) ? -start.y : yRel; + else if (pt.y > imageModel.GetHeight()) + yRel = imageModel.GetHeight() - start.y; + break; + + // while drawing, update cursor coordinates only for tools 3, 7, 8, 9, 14 + case TOOL_RUBBER: + case TOOL_PEN: + case TOOL_BRUSH: + case TOOL_AIRBRUSH: + case TOOL_SHAPE: + { + CString strCoord; + strCoord.Format(_T("%ld, %ld"), pt.x, pt.y); + SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) (LPCTSTR) strCoord); + break; + } + default: + break; + } + + // rectsel and shape tools always show non-negative numbers when drawing + if (toolsModel.GetActiveTool() == TOOL_RECTSEL || toolsModel.GetActiveTool() == TOOL_SHAPE) + { + if (xRel < 0) + xRel = -xRel; + if (yRel < 0) + yRel = -yRel; + } + + if (wParam & MK_LBUTTON) + { + toolsModel.OnMouseMove(TRUE, pt.x, pt.y); + Invalidate(FALSE); + if ((toolsModel.GetActiveTool() >= TOOL_TEXT) || (toolsModel.GetActiveTool() == TOOL_RECTSEL) || (toolsModel.GetActiveTool() == TOOL_FREESEL)) + { + CString strSize; + if ((toolsModel.GetActiveTool() >= TOOL_LINE) && (GetAsyncKeyState(VK_SHIFT) < 0)) + yRel = xRel; + strSize.Format(_T("%ld x %ld"), xRel, yRel); + SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) (LPCTSTR) strSize); + } + } + + if (wParam & MK_RBUTTON) + { + toolsModel.OnMouseMove(FALSE, pt.x, pt.y); + Invalidate(FALSE); + if (toolsModel.GetActiveTool() >= TOOL_TEXT) + { + CString strSize; + if ((toolsModel.GetActiveTool() >= TOOL_LINE) && (GetAsyncKeyState(VK_SHIFT) < 0)) + yRel = xRel; + strSize.Format(_T("%ld x %ld"), xRel, yRel); + SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) (LPCTSTR) strSize); + } + } + return 0; + } + if (m_whereHit == HIT_NONE || ::GetCapture() != m_hWnd) return 0; // Dragging now... Calculate the new size INT cxImage = imageModel.GetWidth(), cyImage = imageModel.GetHeight(); - INT cxDelta = UnZoomed(GET_X_LPARAM(lParam) - m_ptOrig.x); - INT cyDelta = UnZoomed(GET_Y_LPARAM(lParam) - m_ptOrig.y); + INT cxDelta = pt.x - m_ptOrig.x; + INT cyDelta = pt.y - m_ptOrig.y; switch (m_whereHit) { case HIT_UPPER_LEFT: @@ -242,20 +509,62 @@ LRESULT CCanvasWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL strSize.Format(_T("%d x %d"), cxImage, cyImage); SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) (LPCTSTR) strSize); + CRect rc = { 0, 0, cxImage, cyImage }; + switch (m_whereHit) + { + case HIT_UPPER_LEFT: + ::OffsetRect(&rc, cxDelta, cyDelta); + break; + case HIT_UPPER_CENTER: + ::OffsetRect(&rc, 0, cyDelta); + break; + case HIT_UPPER_RIGHT: + ::OffsetRect(&rc, 0, cyDelta); + break; + case HIT_MIDDLE_LEFT: + ::OffsetRect(&rc, cxDelta, 0); + break; + case HIT_LOWER_LEFT: + ::OffsetRect(&rc, cxDelta, 0); + break; + default: + break; + } + ImageToCanvas(rc); + m_rcNew = rc; + Invalidate(TRUE); + return 0; } -LRESULT CCanvasWindow::OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +LRESULT CCanvasWindow::OnLRButtonUp(BOOL bLeftButton, UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { + POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + CanvasToImage(pt); + ::ReleaseCapture(); - if (m_whereHit == HIT_NONE) + if (m_drawing) + { + m_drawing = FALSE; + toolsModel.OnButtonUp(bLeftButton, pt.x, pt.y); + Invalidate(FALSE); + SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) ""); + return 0; + } + else if (m_hitSelection != HIT_NONE && bLeftButton) + { + EndSelectionDrag(pt); + return 0; + } + + if (m_whereHit == HIT_NONE || !bLeftButton) return 0; // Resize the image INT cxImage = imageModel.GetWidth(), cyImage = imageModel.GetHeight(); - INT cxDelta = UnZoomed(GET_X_LPARAM(lParam) - m_ptOrig.x); - INT cyDelta = UnZoomed(GET_Y_LPARAM(lParam) - m_ptOrig.y); + INT cxDelta = pt.x - m_ptOrig.x; + INT cyDelta = pt.y - m_ptOrig.y; switch (m_whereHit) { case HIT_UPPER_LEFT: @@ -285,23 +594,68 @@ LRESULT CCanvasWindow::OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL default: break; } + ::SetRectEmpty(&m_rcNew); - // Finish dragging m_whereHit = HIT_NONE; - toolsModel.resetTool(); // resets the point-buffer of the polygon and bezier functions + toolsModel.resetTool(); // resets the point-buffer of the polygon and bezier functions Update(NULL); Invalidate(TRUE); - return 0; } +LRESULT CCanvasWindow::OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + return OnLRButtonUp(TRUE, nMsg, wParam, lParam, bHandled); +} + +LRESULT CCanvasWindow::OnRButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + return OnLRButtonUp(FALSE, nMsg, wParam, lParam, bHandled); +} + LRESULT CCanvasWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { POINT pt; ::GetCursorPos(&pt); ScreenToClient(&pt); - if (!setCursorOnSizeBox(HitTest(pt))) + CANVAS_HITTEST hitSelection = SelectionHitTest(pt); + if (hitSelection != HIT_NONE) + { + if (!setCursorOnSizeBox(hitSelection)) + ::SetCursor(::LoadCursor(NULL, IDC_SIZEALL)); + return 0; + } + + CRect rcImage; + GetImageRect(rcImage); + ImageToCanvas(rcImage); + if (::PtInRect(&rcImage, pt)) + { + switch (toolsModel.GetActiveTool()) + { + case TOOL_FILL: + ::SetCursor(::LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_FILL))); + break; + case TOOL_COLOR: + ::SetCursor(::LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_COLOR))); + break; + case TOOL_ZOOM: + ::SetCursor(::LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_ZOOM))); + break; + case TOOL_PEN: + ::SetCursor(::LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_PEN))); + break; + case TOOL_AIRBRUSH: + ::SetCursor(::LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_AIRBRUSH))); + break; + default: + ::SetCursor(::LoadCursor(NULL, IDC_CROSS)); + } + return 0; + } + + if (selectionModel.m_bShow || !setCursorOnSizeBox(CanvasHitTest(pt))) ::SetCursor(::LoadCursor(NULL, IDC_ARROW)); return 0; @@ -354,3 +708,56 @@ LRESULT CCanvasWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH EndPaint(&ps); return 0; } + +VOID CCanvasWindow::cancelDrawing() +{ + selectionModel.ClearColor(); + selectionModel.ClearMask(); + m_hitSelection = HIT_NONE; + m_drawing = FALSE; + toolsModel.OnCancelDraw(); + Invalidate(FALSE); +} + +VOID CCanvasWindow::finishDrawing() +{ + toolsModel.OnFinishDraw(); + m_drawing = FALSE; + Invalidate(FALSE); +} + +CANVAS_HITTEST CCanvasWindow::SelectionHitTest(POINT ptZoomed) +{ + if (!selectionModel.m_bShow) + return HIT_NONE; + + RECT rcSelection = selectionModel.m_rc; + Zoomed(rcSelection); + ::OffsetRect(&rcSelection, GRIP_SIZE - GetScrollPos(SB_HORZ), GRIP_SIZE - GetScrollPos(SB_VERT)); + ::InflateRect(&rcSelection, GRIP_SIZE, GRIP_SIZE); + + return getSizeBoxHitTest(ptZoomed, &rcSelection); +} + +VOID CCanvasWindow::StartSelectionDrag(CANVAS_HITTEST hit, POINT ptUnZoomed) +{ + m_hitSelection = hit; + selectionModel.m_ptHit = ptUnZoomed; + selectionModel.TakeOff(); + + SetCapture(); + Invalidate(FALSE); +} + +VOID CCanvasWindow::SelectionDragging(POINT ptUnZoomed) +{ + selectionModel.Dragging(m_hitSelection, ptUnZoomed); + Invalidate(FALSE); +} + +VOID CCanvasWindow::EndSelectionDrag(POINT ptUnZoomed) +{ + selectionModel.Dragging(m_hitSelection, ptUnZoomed); + m_hitSelection = HIT_NONE; + Invalidate(FALSE); +} diff --git a/base/applications/mspaint/canvas.h b/base/applications/mspaint/canvas.h index fe2251ce05a..f932902b370 100644 --- a/base/applications/mspaint/canvas.h +++ b/base/applications/mspaint/canvas.h @@ -11,7 +11,7 @@ class CCanvasWindow : public CWindowImpl { public: - DECLARE_WND_CLASS_EX(_T("ReactOSPaintCanvas"), 0, COLOR_APPWORKSPACE) + DECLARE_WND_CLASS_EX(_T("ReactOSPaintCanvas"), CS_DBLCLKS, COLOR_APPWORKSPACE) BEGIN_MSG_MAP(CCanvasWindow) MESSAGE_HANDLER(WM_SIZE, OnSize) @@ -21,8 +21,12 @@ public: MESSAGE_HANDLER(WM_VSCROLL, OnVScroll) MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd) MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) + MESSAGE_HANDLER(WM_RBUTTONDOWN, OnRButtonDown) + MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDblClk) + MESSAGE_HANDLER(WM_RBUTTONDBLCLK, OnRButtonDblClk) MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown) MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp) + MESSAGE_HANDLER(WM_RBUTTONUP, OnRButtonUp) MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor) MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel) MESSAGE_HANDLER(WM_CANCELMODE, OnCancelMode) @@ -31,16 +35,34 @@ public: CCanvasWindow(); + BOOL m_drawing; + + VOID cancelDrawing(); + VOID finishDrawing(); VOID Update(HWND hwndFrom); + VOID ImageToCanvas(POINT& pt); + VOID ImageToCanvas(RECT& rc); + VOID CanvasToImage(POINT& pt, BOOL bZoomed = FALSE); + VOID CanvasToImage(RECT& rc, BOOL bZoomed = FALSE); + VOID GetImageRect(RECT& rc); + protected: + CANVAS_HITTEST m_hitSelection; CANVAS_HITTEST m_whereHit; POINT m_ptOrig; // The origin of drag start + CRect m_rcNew; - CANVAS_HITTEST HitTest(POINT pt); + CANVAS_HITTEST CanvasHitTest(POINT pt); RECT GetBaseRect(); VOID DoDraw(HDC hDC, RECT& rcClient, RECT& rcPaint); VOID OnHVScroll(WPARAM wParam, INT fnBar); + VOID drawZoomFrame(INT mouseX, INT mouseY); + + CANVAS_HITTEST SelectionHitTest(POINT ptZoomed); + VOID StartSelectionDrag(CANVAS_HITTEST hit, POINT ptUnZoomed); + VOID SelectionDragging(POINT ptUnZoomed); + VOID EndSelectionDrag(POINT ptUnZoomed); LRESULT OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnHScroll(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); @@ -48,11 +70,19 @@ protected: LRESULT OnEraseBkgnd(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnRButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnLButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnRButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnRButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnCancelMode(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnCaptureChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + + LRESULT OnLRButtonDown(BOOL bLeftButton, UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnLRButtonDblClk(BOOL bLeftButton, UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnLRButtonUp(BOOL bLeftButton, UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); }; diff --git a/base/applications/mspaint/drawing.cpp b/base/applications/mspaint/drawing.cpp index 86711c0f6f0..afcae889bc0 100644 --- a/base/applications/mspaint/drawing.cpp +++ b/base/applications/mspaint/drawing.cpp @@ -363,3 +363,14 @@ ColorKeyedMaskBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, return TRUE; } + +void DrawXorRect(HDC hdc, const RECT *prc) +{ + HGDIOBJ oldPen = ::SelectObject(hdc, ::CreatePen(PS_SOLID, 0, RGB(255, 255, 255))); + HGDIOBJ oldBrush = ::SelectObject(hdc, ::GetStockObject(NULL_BRUSH)); + INT oldRop2 = SetROP2(hdc, R2_XORPEN); + ::Rectangle(hdc, prc->left, prc->top, prc->right, prc->bottom); + ::SetROP2(hdc, oldRop2); + ::SelectObject(hdc, oldBrush); + ::DeleteObject(::SelectObject(hdc, oldPen)); +} diff --git a/base/applications/mspaint/drawing.h b/base/applications/mspaint/drawing.h index 8fb0f54c6a6..11c0bcd6516 100644 --- a/base/applications/mspaint/drawing.h +++ b/base/applications/mspaint/drawing.h @@ -38,3 +38,5 @@ BOOL ColorKeyedMaskBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, int nSrcWidth, int nSrcHeight, HBITMAP hbmMask, COLORREF keyColor); + +void DrawXorRect(HDC hdc, const RECT *prc); diff --git a/base/applications/mspaint/globalvar.h b/base/applications/mspaint/globalvar.h index 058117f9390..4ed2cfc6a12 100644 --- a/base/applications/mspaint/globalvar.h +++ b/base/applications/mspaint/globalvar.h @@ -52,5 +52,4 @@ extern CToolBox toolBoxContainer; extern CToolSettingsWindow toolSettingsWindow; extern CPaletteWindow paletteWindow; extern CCanvasWindow canvasWindow; -extern CImgAreaWindow imageArea; extern CTextEditWindow textEditWindow; diff --git a/base/applications/mspaint/history.cpp b/base/applications/mspaint/history.cpp index 0680865c2a6..5be421fdfa0 100644 --- a/base/applications/mspaint/history.cpp +++ b/base/applications/mspaint/history.cpp @@ -14,14 +14,14 @@ ImageModel imageModel; void ImageModel::NotifyDimensionsChanged() { - if (imageArea.IsWindow()) - imageArea.SendMessage(WM_IMAGEMODELDIMENSIONSCHANGED); + if (canvasWindow.IsWindow()) + canvasWindow.SendMessage(WM_IMAGEMODELDIMENSIONSCHANGED); } void ImageModel::NotifyImageChanged() { - if (imageArea.IsWindow()) - imageArea.SendMessage(WM_IMAGEMODELIMAGECHANGED); + if (canvasWindow.IsWindow()) + canvasWindow.SendMessage(WM_IMAGEMODELIMAGECHANGED); } ImageModel::ImageModel() diff --git a/base/applications/mspaint/imgarea.cpp b/base/applications/mspaint/imgarea.cpp deleted file mode 100644 index abae54c89a5..00000000000 --- a/base/applications/mspaint/imgarea.cpp +++ /dev/null @@ -1,480 +0,0 @@ -/* - * PROJECT: PAINT for ReactOS - * LICENSE: LGPL - * FILE: base/applications/mspaint/imgarea.cpp - * 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" - -CImgAreaWindow imageArea; - -/* FUNCTIONS ********************************************************/ - -LRESULT CImgAreaWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - m_hCurFill = LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_FILL)); - m_hCurColor = LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_COLOR)); - m_hCurZoom = LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_ZOOM)); - m_hCurPen = LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_PEN)); - m_hCurAirbrush = LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_AIRBRUSH)); - return 0; -} - -void CImgAreaWindow::drawZoomFrame(int mouseX, int mouseY) -{ - HDC hdc; - HPEN oldPen; - HBRUSH oldBrush; - LOGBRUSH logbrush; - int rop; - - RECT clientRectCanvas; - RECT clientRectImageArea; - int x, y, w, h; - canvasWindow.GetClientRect(&clientRectCanvas); - GetClientRect(&clientRectImageArea); - w = clientRectImageArea.right * 2; - h = clientRectImageArea.bottom * 2; - if (!w || !h) - { - return; - } - w = clientRectImageArea.right * clientRectCanvas.right / w; - h = clientRectImageArea.bottom * clientRectCanvas.bottom / h; - x = max(0, min(clientRectImageArea.right - w, mouseX - w / 2)); - y = max(0, min(clientRectImageArea.bottom - h, mouseY - h / 2)); - - hdc = GetDC(); - oldPen = (HPEN) SelectObject(hdc, CreatePen(PS_SOLID, 0, 0)); - logbrush.lbStyle = BS_HOLLOW; - oldBrush = (HBRUSH) SelectObject(hdc, CreateBrushIndirect(&logbrush)); - rop = SetROP2(hdc, R2_NOT); - Rectangle(hdc, x, y, x + w, y + h); - SetROP2(hdc, rop); - DeleteObject(SelectObject(hdc, oldBrush)); - DeleteObject(SelectObject(hdc, oldPen)); - ReleaseDC(hdc); -} - -LRESULT CImgAreaWindow::OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - if (!IsWindow()) - return 0; - canvasWindow.Update(NULL); - return 0; -} - -LRESULT CImgAreaWindow::OnEraseBkGnd(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - return TRUE; // Don't fill background -} - -LRESULT CImgAreaWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - RECT rcClient; - GetClientRect(&rcClient); - - PAINTSTRUCT ps; - HDC hdc = BeginPaint(&ps); - - // We use a memory bitmap to reduce flickering - HDC hdcMem = ::CreateCompatibleDC(hdc); - HBITMAP hbm = ::CreateCompatibleBitmap(hdc, rcClient.right, rcClient.bottom); - HGDIOBJ hbmOld = ::SelectObject(hdcMem, hbm); - - // Draw the image - SIZE size = { imageModel.GetWidth(), imageModel.GetHeight() }; - StretchBlt(hdcMem, 0, 0, ::Zoomed(size.cx), ::Zoomed(size.cy), - imageModel.GetDC(), 0, 0, size.cx, size.cy, SRCCOPY); - - // Draw the grid - if (showGrid && (toolsModel.GetZoom() >= 4000)) - { - HPEN oldPen = (HPEN) SelectObject(hdcMem, CreatePen(PS_SOLID, 1, 0x00a0a0a0)); - for (int counter = 0; counter <= size.cy; counter++) - { - ::MoveToEx(hdcMem, 0, ::Zoomed(counter), NULL); - ::LineTo(hdcMem, ::Zoomed(size.cx), ::Zoomed(counter)); - } - for (int counter = 0; counter <= size.cx; counter++) - { - ::MoveToEx(hdcMem, ::Zoomed(counter), 0, NULL); - ::LineTo(hdcMem, ::Zoomed(counter), ::Zoomed(size.cy)); - } - ::DeleteObject(::SelectObject(hdcMem, oldPen)); - } - - // Draw selection - if (selectionModel.m_bShow) - { - RECT rc = selectionModel.m_rc; - Zoomed(rc); - ::InflateRect(&rc, GRIP_SIZE, GRIP_SIZE); - drawSizeBoxes(hdcMem, &rc, TRUE, &ps.rcPaint); - ::InflateRect(&rc, -GRIP_SIZE, -GRIP_SIZE); - selectionModel.DrawSelection(hdcMem, &rc, paletteModel.GetBgColor(), - toolsModel.IsBackgroundTransparent()); - } - - // Transfer bits - ::BitBlt(hdc, 0, 0, rcClient.right, rcClient.bottom, hdcMem, 0, 0, SRCCOPY); - ::SelectObject(hdcMem, hbmOld); - EndPaint(&ps); - - if (miniature.IsWindow()) - miniature.Invalidate(FALSE); - if (textEditWindow.IsWindow()) - textEditWindow.Invalidate(FALSE); - return 0; -} - -CANVAS_HITTEST CImgAreaWindow::SelectionHitTest(POINT ptZoomed) -{ - if (!selectionModel.m_bShow) - return HIT_NONE; - - RECT rcSelection = selectionModel.m_rc; - Zoomed(rcSelection); - ::InflateRect(&rcSelection, GRIP_SIZE, GRIP_SIZE); - - return getSizeBoxHitTest(ptZoomed, &rcSelection); -} - -void CImgAreaWindow::StartSelectionDrag(CANVAS_HITTEST hit, POINT ptUnZoomed) -{ - m_hitSelection = hit; - selectionModel.m_ptHit = ptUnZoomed; - selectionModel.TakeOff(); - - SetCapture(); - Invalidate(FALSE); -} - -void CImgAreaWindow::SelectionDragging(POINT ptUnZoomed) -{ - selectionModel.Dragging(m_hitSelection, ptUnZoomed); - Invalidate(FALSE); -} - -void CImgAreaWindow::EndSelectionDrag(POINT ptUnZoomed) -{ - selectionModel.Dragging(m_hitSelection, ptUnZoomed); - m_hitSelection = HIT_NONE; - Invalidate(FALSE); -} - -LRESULT CImgAreaWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - POINT pt; - ::GetCursorPos(&pt); - ScreenToClient(&pt); - - CANVAS_HITTEST hit = SelectionHitTest(pt); - if (hit != HIT_NONE) - { - if (!setCursorOnSizeBox(hit)) - ::SetCursor(::LoadCursor(NULL, IDC_SIZEALL)); - return 0; - } - - UnZoomed(pt); - - switch (toolsModel.GetActiveTool()) - { - case TOOL_FILL: - ::SetCursor(m_hCurFill); - break; - case TOOL_COLOR: - ::SetCursor(m_hCurColor); - break; - case TOOL_ZOOM: - ::SetCursor(m_hCurZoom); - break; - case TOOL_PEN: - ::SetCursor(m_hCurPen); - break; - case TOOL_AIRBRUSH: - ::SetCursor(m_hCurAirbrush); - break; - default: - ::SetCursor(::LoadCursor(NULL, IDC_CROSS)); - } - return 0; -} - -LRESULT CImgAreaWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - - CANVAS_HITTEST hit = SelectionHitTest(pt); - if (hit != HIT_NONE) - { - UnZoomed(pt); - StartSelectionDrag(hit, pt); - return 0; - } - - UnZoomed(pt); - drawing = TRUE; - SetCapture(); - toolsModel.OnButtonDown(TRUE, pt.x, pt.y, FALSE); - Invalidate(FALSE); - return 0; -} - -LRESULT CImgAreaWindow::OnLButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - UnZoomed(pt); - drawing = FALSE; - ReleaseCapture(); - toolsModel.OnButtonDown(TRUE, pt.x, pt.y, TRUE); - toolsModel.resetTool(); - Invalidate(FALSE); - return 0; -} - -LRESULT CImgAreaWindow::OnRButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - UnZoomed(pt); - drawing = TRUE; - SetCapture(); - toolsModel.OnButtonDown(FALSE, pt.x, pt.y, FALSE); - Invalidate(FALSE); - return 0; -} - -LRESULT CImgAreaWindow::OnRButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - UnZoomed(pt); - drawing = FALSE; - ReleaseCapture(); - toolsModel.OnButtonDown(FALSE, pt.x, pt.y, TRUE); - toolsModel.resetTool(); - Invalidate(FALSE); - return 0; -} - -LRESULT CImgAreaWindow::OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - UnZoomed(pt); - if (drawing) - { - drawing = FALSE; - toolsModel.OnButtonUp(TRUE, pt.x, pt.y); - Invalidate(FALSE); - SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) ""); - } - else if (m_hitSelection != HIT_NONE) - { - EndSelectionDrag(pt); - } - ReleaseCapture(); - return 0; -} - -void CImgAreaWindow::cancelDrawing() -{ - selectionModel.ClearColor(); - selectionModel.ClearMask(); - m_hitSelection = HIT_NONE; - drawing = FALSE; - toolsModel.OnCancelDraw(); - Invalidate(FALSE); -} - -LRESULT CImgAreaWindow::OnCaptureChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - if (drawing) - cancelDrawing(); - return 0; -} - -LRESULT CImgAreaWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - if (wParam == VK_ESCAPE) - { - if (GetCapture() == m_hWnd) - { - ReleaseCapture(); - } - else - { - if (drawing || ToolBase::pointSP != 0 || selectionModel.m_bShow) - cancelDrawing(); - } - } - return 0; -} - -LRESULT CImgAreaWindow::OnRButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - UnZoomed(pt); - if (drawing) - { - drawing = FALSE; - toolsModel.OnButtonUp(FALSE, pt.x, pt.y); - Invalidate(FALSE); - SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) ""); - } - else if (m_hitSelection != HIT_NONE) - { - EndSelectionDrag(pt); - } - ReleaseCapture(); - return 0; -} - -LRESULT CImgAreaWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; - UnZoomed(pt); - - if (m_hitSelection != HIT_NONE) - { - SelectionDragging(pt); - return 0; - } - - if ((!drawing) || (toolsModel.GetActiveTool() <= TOOL_AIRBRUSH)) - { - TRACKMOUSEEVENT tme; - - if (toolsModel.GetActiveTool() == TOOL_ZOOM) - { - Invalidate(FALSE); - UpdateWindow(); - drawZoomFrame(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); - } - - tme.cbSize = sizeof(TRACKMOUSEEVENT); - tme.dwFlags = TME_LEAVE; - tme.hwndTrack = m_hWnd; - tme.dwHoverTime = 0; - TrackMouseEvent(&tme); - - if (!drawing) - { - CString strCoord; - strCoord.Format(_T("%ld, %ld"), pt.x, pt.y); - SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) (LPCTSTR) strCoord); - } - } - if (drawing) - { - /* values displayed in statusbar */ - LONG xRel = pt.x - start.x; - LONG yRel = pt.y - start.y; - /* freesel, rectsel and text tools always show numbers limited to fit into image area */ - if ((toolsModel.GetActiveTool() == TOOL_FREESEL) || (toolsModel.GetActiveTool() == TOOL_RECTSEL) || (toolsModel.GetActiveTool() == TOOL_TEXT)) - { - if (xRel < 0) - xRel = (pt.x < 0) ? -start.x : xRel; - else if (pt.x > imageModel.GetWidth()) - xRel = imageModel.GetWidth() - start.x; - if (yRel < 0) - yRel = (pt.y < 0) ? -start.y : yRel; - else if (pt.y > imageModel.GetHeight()) - yRel = imageModel.GetHeight() - start.y; - } - /* rectsel and shape tools always show non-negative numbers when drawing */ - if ((toolsModel.GetActiveTool() == TOOL_RECTSEL) || (toolsModel.GetActiveTool() == TOOL_SHAPE)) - { - if (xRel < 0) - xRel = -xRel; - if (yRel < 0) - yRel = -yRel; - } - /* while drawing, update cursor coordinates only for tools 3, 7, 8, 9, 14 */ - switch(toolsModel.GetActiveTool()) - { - case TOOL_RUBBER: - case TOOL_PEN: - case TOOL_BRUSH: - case TOOL_AIRBRUSH: - case TOOL_SHAPE: - { - CString strCoord; - strCoord.Format(_T("%ld, %ld"), pt.x, pt.y); - SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) (LPCTSTR) strCoord); - break; - } - default: - break; - } - if (wParam & MK_LBUTTON) - { - toolsModel.OnMouseMove(TRUE, pt.x, pt.y); - Invalidate(FALSE); - if ((toolsModel.GetActiveTool() >= TOOL_TEXT) || (toolsModel.GetActiveTool() == TOOL_RECTSEL) || (toolsModel.GetActiveTool() == TOOL_FREESEL)) - { - CString strSize; - if ((toolsModel.GetActiveTool() >= TOOL_LINE) && (GetAsyncKeyState(VK_SHIFT) < 0)) - yRel = xRel; - strSize.Format(_T("%ld x %ld"), xRel, yRel); - SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) (LPCTSTR) strSize); - } - } - if (wParam & MK_RBUTTON) - { - toolsModel.OnMouseMove(FALSE, pt.x, pt.y); - Invalidate(FALSE); - if (toolsModel.GetActiveTool() >= TOOL_TEXT) - { - CString strSize; - if ((toolsModel.GetActiveTool() >= TOOL_LINE) && (GetAsyncKeyState(VK_SHIFT) < 0)) - yRel = xRel; - strSize.Format(_T("%ld x %ld"), xRel, yRel); - SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) (LPCTSTR) strSize); - } - } - } - return 0; -} - -LRESULT CImgAreaWindow::OnMouseLeave(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) _T("")); - if (toolsModel.GetActiveTool() == TOOL_ZOOM) - Invalidate(FALSE); - return 0; -} - -LRESULT CImgAreaWindow::OnImageModelDimensionsChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - canvasWindow.Update(NULL); - return 0; -} - -LRESULT CImgAreaWindow::OnImageModelImageChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - Invalidate(FALSE); - return 0; -} - -LRESULT CImgAreaWindow::OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - return ::SendMessage(GetParent(), nMsg, wParam, lParam); -} - -LRESULT CImgAreaWindow::OnCtlColorEdit(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - HDC hdc = (HDC)wParam; - 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 deleted file mode 100644 index 941424d0af9..00000000000 --- a/base/applications/mspaint/imgarea.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * PROJECT: PAINT for ReactOS - * LICENSE: LGPL - * FILE: base/applications/mspaint/imgarea.h - * PURPOSE: Window procedure of the main window and all children apart from - * hPalWin, hToolSettings and hSelection - * PROGRAMMERS: Benedikt Freisen - * Katayama Hirofumi MZ - */ - -#pragma once - -class CImgAreaWindow : public CWindowImpl -{ -public: - CImgAreaWindow() - : drawing(FALSE) - , m_hitSelection(HIT_NONE) - { - } - - BOOL drawing; - CANVAS_HITTEST m_hitSelection; - - void cancelDrawing(); - void finishDrawing(); - - DECLARE_WND_CLASS_EX(_T("ImgAreaWindow"), CS_DBLCLKS, COLOR_BTNFACE) - - BEGIN_MSG_MAP(CImgAreaWindow) - MESSAGE_HANDLER(WM_SIZE, OnSize) - MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkGnd) - MESSAGE_HANDLER(WM_PAINT, OnPaint) - MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor) - MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) - MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDblClk) - MESSAGE_HANDLER(WM_RBUTTONDOWN, OnRButtonDown) - MESSAGE_HANDLER(WM_RBUTTONDBLCLK, OnRButtonDblClk) - MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp) - MESSAGE_HANDLER(WM_RBUTTONUP, OnRButtonUp) - MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove) - MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel) - MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseLeave) - MESSAGE_HANDLER(WM_IMAGEMODELDIMENSIONSCHANGED, OnImageModelDimensionsChanged) - MESSAGE_HANDLER(WM_IMAGEMODELIMAGECHANGED, OnImageModelImageChanged) - MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged) - MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown) - MESSAGE_HANDLER(WM_CTLCOLOREDIT, OnCtlColorEdit) - MESSAGE_HANDLER(WM_CREATE, OnCreate) - END_MSG_MAP() - -private: - HCURSOR m_hCurFill; - HCURSOR m_hCurColor; - HCURSOR m_hCurZoom; - HCURSOR m_hCurPen; - HCURSOR m_hCurAirbrush; - - LRESULT OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnSize(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); - LRESULT OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnLButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnRButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnRButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnRButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnMouseLeave(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnImageModelDimensionsChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnImageModelImageChanged(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 OnCtlColorEdit(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - - void drawZoomFrame(int mouseX, int mouseY); - CANVAS_HITTEST SelectionHitTest(POINT ptZoomed); - void StartSelectionDrag(CANVAS_HITTEST hit, POINT ptUnZoomed); - void SelectionDragging(POINT ptUnZoomed); - void EndSelectionDrag(POINT ptUnZoomed); -}; diff --git a/base/applications/mspaint/mouse.cpp b/base/applications/mspaint/mouse.cpp index 5d1c4fcefea..a412219e0bb 100644 --- a/base/applications/mspaint/mouse.cpp +++ b/base/applications/mspaint/mouse.cpp @@ -151,14 +151,14 @@ struct FreeSelTool : ToolBase selectionModel.ResetPtStack(); selectionModel.m_bShow = FALSE; } - imageArea.Invalidate(FALSE); + canvasWindow.Invalidate(FALSE); } } void OnFinishDraw() { if (m_bLeftButton) - imageArea.Invalidate(FALSE); + canvasWindow.Invalidate(FALSE); m_bLeftButton = FALSE; ToolBase::OnFinishDraw(); @@ -214,14 +214,14 @@ struct RectSelTool : ToolBase if (start.x == x && start.y == y) imageModel.Undo(TRUE); selectionModel.m_bShow = !selectionModel.m_rc.IsRectEmpty(); - imageArea.Invalidate(FALSE); + canvasWindow.Invalidate(FALSE); } } void OnFinishDraw() { if (m_bLeftButton) - imageArea.Invalidate(FALSE); + canvasWindow.Invalidate(FALSE); m_bLeftButton = FALSE; ToolBase::OnFinishDraw(); @@ -417,7 +417,7 @@ struct TextTool : ToolBase void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) { if (!textEditWindow.IsWindow()) - textEditWindow.Create(imageArea); + textEditWindow.Create(canvasWindow); imageModel.CopyPrevious(); UpdatePoint(x, y); @@ -484,7 +484,7 @@ struct TextTool : ToolBase } if (!textEditWindow.IsWindow()) - textEditWindow.Create(imageArea); + textEditWindow.Create(canvasWindow); textEditWindow.SetWindowText(NULL); textEditWindow.ValidateEditRect(&rc); diff --git a/base/applications/mspaint/palettemodel.cpp b/base/applications/mspaint/palettemodel.cpp index cf920bc43e0..8d18449fbee 100644 --- a/base/applications/mspaint/palettemodel.cpp +++ b/base/applications/mspaint/palettemodel.cpp @@ -97,8 +97,8 @@ void PaletteModel::NotifyColorChanged() { if (paletteWindow.IsWindow()) paletteWindow.SendMessage(WM_PALETTEMODELCOLORCHANGED); - if (imageArea.IsWindow()) - imageArea.SendMessage(WM_PALETTEMODELCOLORCHANGED); + if (canvasWindow.IsWindow()) + canvasWindow.SendMessage(WM_PALETTEMODELCOLORCHANGED); if (textEditWindow.IsWindow()) textEditWindow.SendMessage(WM_PALETTEMODELCOLORCHANGED); } diff --git a/base/applications/mspaint/precomp.h b/base/applications/mspaint/precomp.h index ae4e584e229..368ce304461 100644 --- a/base/applications/mspaint/precomp.h +++ b/base/applications/mspaint/precomp.h @@ -38,7 +38,6 @@ #include "dib.h" #include "fullscreen.h" #include "history.h" -#include "imgarea.h" #include "miniature.h" #include "palette.h" #include "palettemodel.h" diff --git a/base/applications/mspaint/selectionmodel.cpp b/base/applications/mspaint/selectionmodel.cpp index f7c61d16c28..3609632f63b 100644 --- a/base/applications/mspaint/selectionmodel.cpp +++ b/base/applications/mspaint/selectionmodel.cpp @@ -179,7 +179,7 @@ BOOL SelectionModel::TakeOff() DrawBackgroundRect(hDCImage, paletteModel.GetBgColor()); } - imageArea.Invalidate(FALSE); + canvasWindow.Invalidate(FALSE); return TRUE; } @@ -417,7 +417,7 @@ void SelectionModel::Dragging(CANVAS_HITTEST hit, POINT pt) void SelectionModel::NotifyRefreshNeeded() { - imageArea.Invalidate(FALSE); + canvasWindow.Invalidate(FALSE); } void SelectionModel::ClearMask() @@ -448,5 +448,5 @@ void SelectionModel::CancelSelection() imageModel.Undo(TRUE); m_bShow = FALSE; - imageArea.Invalidate(FALSE); + canvasWindow.Invalidate(FALSE); } diff --git a/base/applications/mspaint/textedit.cpp b/base/applications/mspaint/textedit.cpp index 6a05cebff90..3b679c61272 100644 --- a/base/applications/mspaint/textedit.cpp +++ b/base/applications/mspaint/textedit.cpp @@ -293,11 +293,8 @@ void CTextEditWindow::InvalidateEditRect() ::InvalidateRect(m_hwndParent, &rc, TRUE); GetClientRect(&rc); - MapWindowPoints(imageArea, (LPPOINT)&rc, 2); - rc.left = UnZoomed(rc.left); - rc.top = UnZoomed(rc.top); - rc.right = UnZoomed(rc.right); - rc.bottom = UnZoomed(rc.bottom); + MapWindowPoints(canvasWindow, (LPPOINT)&rc, 2); + canvasWindow.CanvasToImage(rc); m_rc = rc; } @@ -394,27 +391,30 @@ void CTextEditWindow::ValidateEditRect(LPCRECT prc OPTIONAL) { if (prc) m_rc = *prc; - INT x0 = Zoomed(m_rc.left), y0 = Zoomed(m_rc.top); - INT x1 = Zoomed(m_rc.right), y1 = Zoomed(m_rc.bottom); + + CRect rc = m_rc; + canvasWindow.ImageToCanvas(rc); ++m_nAppIsMovingOrSizing; - MoveWindow(x0, y0, x1 - x0, y1 - y0, TRUE); + MoveWindow(rc.left, rc.top, rc.Width(), rc.Height(), TRUE); --m_nAppIsMovingOrSizing; } void CTextEditWindow::Reposition() { - RECT rc, rcImage; + CRect rc; GetWindowRect(&rc); + ::MapWindowPoints(NULL, canvasWindow, (LPPOINT)&rc, 2); + canvasWindow.CanvasToImage(rc); - ::MapWindowPoints(NULL, imageArea, (LPPOINT)&rc, 2); - imageArea.GetClientRect(&rcImage); + CRect rcImage; + canvasWindow.GetImageRect(rcImage); if (rc.bottom > rcImage.bottom) - ::OffsetRect(&rc, 0, rcImage.bottom - rc.bottom); + ::OffsetRect(&rc, 0, rcImage.Height()); if (rc.right > rcImage.right) - ::OffsetRect(&rc, rcImage.right - rc.right, 0); + ::OffsetRect(&rc, rcImage.Width(), 0); if (rc.left < 0) ::OffsetRect(&rc, -rc.left, 0); @@ -422,8 +422,10 @@ void CTextEditWindow::Reposition() if (rc.top < 0) ::OffsetRect(&rc, 0, -rc.top); + canvasWindow.ImageToCanvas(rc); + ++m_nAppIsMovingOrSizing; - MoveWindow(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE); + MoveWindow(rc.left, rc.top, rc.Width(), rc.Height(), TRUE); --m_nAppIsMovingOrSizing; } diff --git a/base/applications/mspaint/toolsmodel.cpp b/base/applications/mspaint/toolsmodel.cpp index 5f07ddf6132..bebb8687284 100644 --- a/base/applications/mspaint/toolsmodel.cpp +++ b/base/applications/mspaint/toolsmodel.cpp @@ -141,8 +141,8 @@ void ToolsModel::SetBackgroundTransparent(BOOL bTransparent) { m_transpBg = bTransparent; NotifyToolSettingsChanged(); - if (imageArea.IsWindow()) - imageArea.Invalidate(FALSE); + if (canvasWindow.IsWindow()) + canvasWindow.Invalidate(FALSE); } int ToolsModel::GetZoom() const @@ -182,8 +182,8 @@ void ToolsModel::NotifyZoomChanged() toolSettingsWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED); if (textEditWindow.IsWindow()) textEditWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED); - if (imageArea.IsWindow()) - imageArea.SendMessage(WM_TOOLSMODELZOOMCHANGED); + if (canvasWindow.IsWindow()) + canvasWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED); } void ToolsModel::OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) diff --git a/base/applications/mspaint/winproc.cpp b/base/applications/mspaint/winproc.cpp index c709750b2e3..09fc9e4b139 100644 --- a/base/applications/mspaint/winproc.cpp +++ b/base/applications/mspaint/winproc.cpp @@ -45,11 +45,14 @@ static HWND DoHtmlHelpW(HWND hwndCaller, LPCWSTR pszFile, UINT uCommand, DWORD_P BOOL zoomTo(int newZoom, int mouseX, int mouseY) { - RECT clientRectScrollbox; - RECT clientRectImageArea; int x, y, w, h; + RECT clientRectScrollbox; canvasWindow.GetClientRect(&clientRectScrollbox); - imageArea.GetClientRect(&clientRectImageArea); + + RECT clientRectImageArea; + ::SetRect(&clientRectImageArea, 0, 0, imageModel.GetWidth(), imageModel.GetHeight()); + Zoomed(clientRectImageArea); + w = clientRectImageArea.right * newZoom / toolsModel.GetZoom(); h = clientRectImageArea.bottom * newZoom / toolsModel.GetZoom(); if (!w || !h) @@ -63,9 +66,7 @@ zoomTo(int newZoom, int mouseX, int mouseY) toolsModel.SetZoom(newZoom); - imageArea.MoveWindow(GRIP_SIZE, GRIP_SIZE, Zoomed(imageModel.GetWidth()), Zoomed(imageModel.GetHeight()), FALSE); canvasWindow.Invalidate(TRUE); - imageArea.Invalidate(FALSE); canvasWindow.SendMessage(WM_HSCROLL, MAKEWPARAM(SB_THUMBPOSITION, x), 0); canvasWindow.SendMessage(WM_VSCROLL, MAKEWPARAM(SB_THUMBPOSITION, y), 0); @@ -139,7 +140,7 @@ void CMainWindow::alignChildrenToMainWindow() void CMainWindow::saveImage(BOOL overwrite) { - imageArea.finishDrawing(); + canvasWindow.finishDrawing(); if (isAFile && overwrite) { @@ -206,7 +207,7 @@ void CMainWindow::InsertSelectionFromHBITMAP(HBITMAP bitmap, HWND window) imageModel.CopyPrevious(); selectionModel.InsertFromHBITMAP(bitmap, 0, 0); selectionModel.m_bShow = TRUE; - imageArea.Invalidate(FALSE); + canvasWindow.Invalidate(FALSE); } LRESULT CMainWindow::OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) @@ -296,9 +297,6 @@ LRESULT CMainWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHa style = WS_CHILD | WS_GROUP | WS_HSCROLL | WS_VSCROLL | WS_VISIBLE; canvasWindow.Create(m_hWnd, rcEmpty, NULL, style, WS_EX_CLIENTEDGE); - // Creating the window inside the canvas - imageArea.Create(canvasWindow, rcEmpty, NULL, WS_CHILD | WS_VISIBLE); - // Create and show the miniature if necessary if (registrySettings.ShowThumbnail) { @@ -340,7 +338,7 @@ LRESULT CMainWindow::OnDestroy(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH BOOL CMainWindow::ConfirmSave() { - imageArea.finishDrawing(); + canvasWindow.finishDrawing(); if (imageModel.IsImageSaved()) return TRUE; @@ -501,16 +499,11 @@ LRESULT CMainWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH if (hwndCapture) { if (canvasWindow.m_hWnd == hwndCapture || - imageArea.m_hWnd == hwndCapture || fullscreenWindow.m_hWnd == hwndCapture) { SendMessage(hwndCapture, nMsg, wParam, lParam); } } - else - { - imageArea.SendMessage(nMsg, wParam, lParam); - } } return 0; } @@ -526,7 +519,7 @@ 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()) + if (canvasWindow.m_drawing && ::GetCapture()) { ATLTRACE("locking!\n"); return 0; @@ -631,28 +624,28 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH if (toolsModel.GetActiveTool() == TOOL_RECTSEL || toolsModel.GetActiveTool() == TOOL_FREESEL) { - imageArea.cancelDrawing(); + canvasWindow.cancelDrawing(); break; } } if (ToolBase::pointSP != 0) // drawing something? { - imageArea.cancelDrawing(); + canvasWindow.cancelDrawing(); break; } imageModel.Undo(); - imageArea.Invalidate(FALSE); + canvasWindow.Invalidate(FALSE); break; case IDM_EDITREDO: if (toolsModel.GetActiveTool() == TOOL_TEXT && ::IsWindowVisible(textEditWindow)) break; if (ToolBase::pointSP != 0) // drawing something? { - imageArea.finishDrawing(); + canvasWindow.finishDrawing(); break; } imageModel.Redo(); - imageArea.Invalidate(FALSE); + canvasWindow.Invalidate(FALSE); break; case IDM_EDITCOPY: OpenClipboard(); @@ -684,7 +677,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH break; case TOOL_TEXT: - imageArea.cancelDrawing(); + canvasWindow.cancelDrawing(); break; default: break; @@ -701,7 +694,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH HWND hToolbar = FindWindowEx(toolBoxContainer.m_hWnd, NULL, TOOLBARCLASSNAME, NULL); SendMessage(hToolbar, TB_CHECKBUTTON, ID_RECTSEL, MAKELPARAM(TRUE, 0)); toolsModel.selectAll(); - imageArea.Invalidate(TRUE); + canvasWindow.Invalidate(TRUE); break; } case IDM_EDITCOPYTO: @@ -746,7 +739,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH case IDM_IMAGEDELETEIMAGE: imageModel.CopyPrevious(); Rect(imageModel.GetDC(), 0, 0, imageModel.GetWidth(), imageModel.GetHeight(), paletteModel.GetBgColor(), paletteModel.GetBgColor(), 0, TRUE); - imageArea.Invalidate(FALSE); + canvasWindow.Invalidate(FALSE); break; case IDM_IMAGEROTATEMIRROR: switch (mirrorRotateDialog.DoModal(mainWindow.m_hWnd)) @@ -844,7 +837,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH break; case IDM_VIEWSHOWGRID: showGrid = !showGrid; - imageArea.Invalidate(FALSE); + canvasWindow.Invalidate(FALSE); break; case IDM_VIEWSHOWMINIATURE: registrySettings.ShowThumbnail = !::IsWindowVisible(miniature);