From: Katayama Hirofumi MZ Date: Sun, 19 Mar 2023 01:42:10 +0000 (+0900) Subject: [MSPAINT] Make sizeboxes window-less (#5166) X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=6b6a045766c2b22a68139a9cb702f5510eed97e8 [MSPAINT] Make sizeboxes window-less (#5166) Reduce window controls and integrate to the canvas window. - The sizeboxes are absorbed by canvasWindow. - class CSizeboxWindow is deleted. - Add enum CANVAS_HITTEST. - Add getSizeBoxRect, getSizeBoxHitTest, and drawSizeBoxes helper functions in sizebox.cpp. CORE-18867 --- diff --git a/base/applications/mspaint/canvas.cpp b/base/applications/mspaint/canvas.cpp index 49249373ab8..591d1ba670b 100644 --- a/base/applications/mspaint/canvas.cpp +++ b/base/applications/mspaint/canvas.cpp @@ -9,88 +9,104 @@ /* INCLUDES *********************************************************/ #include "precomp.h" -#include /* FUNCTIONS ********************************************************/ +CCanvasWindow::CCanvasWindow() + : m_whereHit(HIT_NONE) + , m_ptOrig { 0, 0 } +{ +} + +RECT CCanvasWindow::GetBaseRect() +{ + CRect rcBase = { 0, 0, Zoomed(imageModel.GetWidth()), Zoomed(imageModel.GetHeight()) }; + ::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) +{ + RECT rcBase = GetBaseRect(); + return getSizeBoxHitTest(pt, &rcBase); +} + +VOID CCanvasWindow::DoDraw(HDC hDC, RECT& rcClient, RECT& rcPaint) +{ + // 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); + + // Fill the background + ::FillRect(hdcMem, &rcPaint, (HBRUSH)(COLOR_APPWORKSPACE + 1)); + + // Draw the sizeboxes + RECT rcBase = GetBaseRect(); + drawSizeBoxes(hdcMem, &rcBase, FALSE, &rcPaint); + + // Transfer the bits + ::BitBlt(hDC, + rcPaint.left, rcPaint.top, + rcPaint.right - rcPaint.left, rcPaint.bottom - rcPaint.top, + hdcMem, rcPaint.left, rcPaint.top, SRCCOPY); + + ::SelectObject(hdcMem, hbmOld); + ::DeleteDC(hdcMem); +} + VOID CCanvasWindow::Update(HWND hwndFrom) { - CRect tempRect; - GetClientRect(&tempRect); - CSize sizeScrollBox(tempRect.Width(), tempRect.Height()); + CRect rcClient; + GetClientRect(&rcClient); + CSize sizePage(rcClient.right, rcClient.bottom); CSize sizeZoomed = { Zoomed(imageModel.GetWidth()), Zoomed(imageModel.GetHeight()) }; CSize sizeWhole = { sizeZoomed.cx + (GRIP_SIZE * 2), sizeZoomed.cy + (GRIP_SIZE * 2) }; /* show/hide the scrollbars */ - ShowScrollBar(SB_HORZ, sizeScrollBox.cx < sizeWhole.cx); - ShowScrollBar(SB_VERT, sizeScrollBox.cy < sizeWhole.cy); + ShowScrollBar(SB_HORZ, sizePage.cx < sizeWhole.cx); + ShowScrollBar(SB_VERT, sizePage.cy < sizeWhole.cy); - if (sizeScrollBox.cx < sizeWhole.cx || sizeScrollBox.cy < sizeWhole.cy) + if (sizePage.cx < sizeWhole.cx || sizePage.cy < sizeWhole.cy) { - GetClientRect(&tempRect); - sizeScrollBox = CSize(tempRect.Width(), tempRect.Height()); + GetClientRect(&rcClient); // Scrollbars might change, get client rectangle again + sizePage = CSize(rcClient.right, rcClient.bottom); } SCROLLINFO si = { sizeof(si), SIF_PAGE | SIF_RANGE }; si.nMin = 0; si.nMax = sizeWhole.cx; - si.nPage = sizeScrollBox.cx; + si.nPage = sizePage.cx; SetScrollInfo(SB_HORZ, &si); si.nMax = sizeWhole.cy; - si.nPage = sizeScrollBox.cy; + si.nPage = sizePage.cy; SetScrollInfo(SB_VERT, &si); - INT dx = -GetScrollPos(SB_HORZ); - INT dy = -GetScrollPos(SB_VERT); - - if (sizeboxLeftTop.IsWindow()) - { - sizeboxLeftTop.MoveWindow(dx, dy, GRIP_SIZE, GRIP_SIZE, TRUE); - sizeboxCenterTop.MoveWindow(dx + GRIP_SIZE + (sizeZoomed.cx - GRIP_SIZE) / 2, - dy, - GRIP_SIZE, GRIP_SIZE, TRUE); - sizeboxRightTop.MoveWindow(dx + GRIP_SIZE + sizeZoomed.cx, - dy, - GRIP_SIZE, GRIP_SIZE, TRUE); - sizeboxLeftCenter.MoveWindow(dx, - dy + GRIP_SIZE + (sizeZoomed.cy - GRIP_SIZE) / 2, - GRIP_SIZE, GRIP_SIZE, TRUE); - sizeboxRightCenter.MoveWindow(dx + GRIP_SIZE + sizeZoomed.cx, - dy + GRIP_SIZE + (sizeZoomed.cy - GRIP_SIZE) / 2, - GRIP_SIZE, GRIP_SIZE, TRUE); - sizeboxLeftBottom.MoveWindow(dx, - dy + GRIP_SIZE + sizeZoomed.cy, - GRIP_SIZE, GRIP_SIZE, TRUE); - sizeboxCenterBottom.MoveWindow(dx + GRIP_SIZE + (sizeZoomed.cx - GRIP_SIZE) / 2, - dy + GRIP_SIZE + sizeZoomed.cy, - GRIP_SIZE, GRIP_SIZE, TRUE); - sizeboxRightBottom.MoveWindow(dx + GRIP_SIZE + sizeZoomed.cx, - dy + GRIP_SIZE + sizeZoomed.cy, - GRIP_SIZE, GRIP_SIZE, TRUE); - } - 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) { if (m_hWnd) - { Update(m_hWnd); - } + return 0; } -LRESULT CCanvasWindow::OnHScroll(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +VOID CCanvasWindow::OnHVScroll(WPARAM wParam, INT fnBar) { SCROLLINFO si; si.cbSize = sizeof(SCROLLINFO); si.fMask = SIF_ALL; - GetScrollInfo(SB_HORZ, &si); + GetScrollInfo(fnBar, &si); switch (LOWORD(wParam)) { case SB_THUMBTRACK: @@ -110,59 +126,193 @@ LRESULT CCanvasWindow::OnHScroll(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& si.nPos += si.nPage; break; } - SetScrollInfo(SB_HORZ, &si); + SetScrollInfo(fnBar, &si); Update(m_hWnd); + Invalidate(FALSE); // FIXME: Flicker +} + +LRESULT CCanvasWindow::OnHScroll(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + OnHVScroll(wParam, SB_HORZ); return 0; } LRESULT CCanvasWindow::OnVScroll(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { - SCROLLINFO si; - si.cbSize = sizeof(SCROLLINFO); - si.fMask = SIF_ALL; - GetScrollInfo(SB_VERT, &si); - switch (LOWORD(wParam)) - { - case SB_THUMBTRACK: - case SB_THUMBPOSITION: - si.nPos = HIWORD(wParam); - break; - case SB_LINEUP: - si.nPos -= 5; - break; - case SB_LINEDOWN: - si.nPos += 5; - break; - case SB_PAGEUP: - si.nPos -= si.nPage; - break; - case SB_PAGEDOWN: - si.nPos += si.nPage; - break; - } - SetScrollInfo(SB_VERT, &si); - Update(m_hWnd); + OnHVScroll(wParam, SB_VERT); return 0; } LRESULT CCanvasWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { - switch (toolsModel.GetActiveTool()) + POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + CANVAS_HITTEST hit = HitTest(pt); + + if (hit == HIT_NONE || hit == HIT_BORDER) { - case TOOL_BEZIER: - case TOOL_SHAPE: + if (toolsModel.GetActiveTool() == TOOL_BEZIER || + toolsModel.GetActiveTool() == TOOL_SHAPE) + { if (ToolBase::pointSP != 0) { toolsModel.OnCancelDraw(); imageArea.Invalidate(); } + } + + toolsModel.resetTool(); // resets the point-buffer of the polygon and bezier functions + return 0; + } + + if (hit == HIT_INNER) + { + // TODO: In the future, we handle the events of the window-less image area. + return 0; + } + + // Start dragging + m_whereHit = hit; + m_ptOrig = pt; + SetCapture(); + return 0; +} + +LRESULT CCanvasWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + 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); + switch (m_whereHit) + { + case HIT_UPPER_LEFT: + cxImage -= cxDelta; + cyImage -= cyDelta; + break; + case HIT_UPPER_CENTER: + cyImage -= cyDelta; + break; + case HIT_UPPER_RIGHT: + cxImage += cxDelta; + cyImage -= cyDelta; + break; + case HIT_MIDDLE_LEFT: + cxImage -= cxDelta; + break; + case HIT_MIDDLE_RIGHT: + cxImage += cxDelta; break; + case HIT_LOWER_LEFT: + cxImage -= cxDelta; + cyImage += cyDelta; + break; + case HIT_LOWER_CENTER: + cyImage += cyDelta; + break; + case HIT_LOWER_RIGHT: + cxImage += cxDelta; + cyImage += cyDelta; + break; + default: + return 0; + } + + // Limit bitmap size + cxImage = max(1, cxImage); + cyImage = max(1, cyImage); + cxImage = min(MAXWORD, cxImage); + cyImage = min(MAXWORD, cyImage); + + // Display new size + CString strSize; + strSize.Format(_T("%d x %d"), cxImage, cyImage); + SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) (LPCTSTR) strSize); + return 0; +} + +LRESULT CCanvasWindow::OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + ::ReleaseCapture(); + + if (m_whereHit == HIT_NONE) + 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); + switch (m_whereHit) + { + case HIT_UPPER_LEFT: + imageModel.Crop(cxImage - cxDelta, cyImage - cyDelta, cxDelta, cyDelta); + break; + case HIT_UPPER_CENTER: + imageModel.Crop(cxImage, cyImage - cyDelta, 0, cyDelta); + break; + case HIT_UPPER_RIGHT: + imageModel.Crop(cxImage + cxDelta, cyImage - cyDelta, 0, cyDelta); + break; + case HIT_MIDDLE_LEFT: + imageModel.Crop(cxImage - cxDelta, cyImage, cxDelta, 0); + break; + case HIT_MIDDLE_RIGHT: + imageModel.Crop(cxImage + cxDelta, cyImage, 0, 0); + break; + case HIT_LOWER_LEFT: + imageModel.Crop(cxImage - cxDelta, cyImage + cyDelta, cxDelta, 0); + break; + case HIT_LOWER_CENTER: + imageModel.Crop(cxImage, cyImage + cyDelta, 0, 0); + break; + case HIT_LOWER_RIGHT: + imageModel.Crop(cxImage + cxDelta, cyImage + cyDelta, 0, 0); + break; default: break; } + // Finish dragging + m_whereHit = HIT_NONE; toolsModel.resetTool(); // resets the point-buffer of the polygon and bezier functions + Update(NULL); + Invalidate(TRUE); + + return 0; +} + +LRESULT CCanvasWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + POINT pt; + ::GetCursorPos(&pt); + ScreenToClient(&pt); + + if (!setCursorOnSizeBox(HitTest(pt))) + ::SetCursor(::LoadCursor(NULL, IDC_ARROW)); + + return 0; +} + +LRESULT CCanvasWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + if (wParam == VK_ESCAPE && ::GetCapture() == m_hWnd) + { + // Cancel dragging + m_whereHit = HIT_NONE; + ::ReleaseCapture(); + } + + return 0; +} + +LRESULT CCanvasWindow::OnCancelMode(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + // Cancel dragging + m_whereHit = HIT_NONE; + Invalidate(TRUE); return 0; } @@ -170,3 +320,26 @@ LRESULT CCanvasWindow::OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, BOO { return ::SendMessage(GetParent(), nMsg, wParam, lParam); } + +LRESULT CCanvasWindow::OnCaptureChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM)_T("")); + return 0; +} + +LRESULT CCanvasWindow::OnEraseBkgnd(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + return TRUE; // do nothing => transparent background +} + +LRESULT CCanvasWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +{ + RECT rcClient; + GetClientRect(&rcClient); + + PAINTSTRUCT ps; + HDC hDC = BeginPaint(&ps); + DoDraw(hDC, rcClient, ps.rcPaint); + EndPaint(&ps); + return 0; +} diff --git a/base/applications/mspaint/canvas.h b/base/applications/mspaint/canvas.h index 22613518857..fe2251ce05a 100644 --- a/base/applications/mspaint/canvas.h +++ b/base/applications/mspaint/canvas.h @@ -15,18 +15,44 @@ public: BEGIN_MSG_MAP(CCanvasWindow) MESSAGE_HANDLER(WM_SIZE, OnSize) + MESSAGE_HANDLER(WM_PAINT, OnPaint) + MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove) MESSAGE_HANDLER(WM_HSCROLL, OnHScroll) MESSAGE_HANDLER(WM_VSCROLL, OnVScroll) + MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd) MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) + MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown) + MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp) + MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor) MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel) + MESSAGE_HANDLER(WM_CANCELMODE, OnCancelMode) + MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged) END_MSG_MAP() + CCanvasWindow(); + VOID Update(HWND hwndFrom); protected: + CANVAS_HITTEST m_whereHit; + POINT m_ptOrig; // The origin of drag start + + CANVAS_HITTEST HitTest(POINT pt); + RECT GetBaseRect(); + VOID DoDraw(HDC hDC, RECT& rcClient, RECT& rcPaint); + VOID OnHVScroll(WPARAM wParam, INT fnBar); + LRESULT OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnHScroll(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnVScroll(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 OnLButtonDown(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 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); }; diff --git a/base/applications/mspaint/drawing.cpp b/base/applications/mspaint/drawing.cpp index 490ff9a0a62..296a6f57a1e 100644 --- a/base/applications/mspaint/drawing.cpp +++ b/base/applications/mspaint/drawing.cpp @@ -245,34 +245,6 @@ RectSel(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2) SetROP2(hdc, oldRop); } -void -SelectionFrame(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF system_selection_color) -{ - HBRUSH oldBrush; - LOGBRUSH logbrush; - HPEN oldPen = (HPEN) SelectObject(hdc, CreatePen(PS_DOT, 1, system_selection_color)); - - logbrush.lbStyle = BS_HOLLOW; - logbrush.lbColor = 0; - logbrush.lbHatch = 0; - oldBrush = (HBRUSH) SelectObject(hdc, CreateBrushIndirect(&logbrush)); - Rectangle(hdc, x1, y1, x2, y2); /* SEL BOX FRAME */ - DeleteObject(SelectObject(hdc, oldBrush)); - DeleteObject(SelectObject(hdc, oldPen)); - oldPen = (HPEN) SelectObject(hdc, CreatePen(PS_SOLID, 1, system_selection_color)); - oldBrush = (HBRUSH) SelectObject(hdc, CreateSolidBrush(system_selection_color)); - Rectangle(hdc, x1 - 1, y1 - 1, x1 + 2, y1 + 2); - Rectangle(hdc, x2 - 2, y1 - 1, x2 + 2, y1 + 2); - Rectangle(hdc, x1 - 1, y2 - 2, x1 + 2, y2 + 1); - Rectangle(hdc, x2 - 2, y2 - 2, x2 + 2, y2 + 1); - Rectangle(hdc, (x1 + x2) / 2 - 1, y1 - 1, (x1 + x2) / 2 + 2, y1 + 2); - Rectangle(hdc, (x1 + x2) / 2 - 1, y2 - 2, (x1 + x2) / 2 + 2, y2 + 1); - Rectangle(hdc, x1 - 1, (y1 + y2) / 2 - 1, x1 + 2, (y1 + y2) / 2 + 2); - Rectangle(hdc, x2 - 2, (y1 + y2) / 2 - 1, x2 + 1, (y1 + y2) / 2 + 2); - DeleteObject(SelectObject(hdc, oldBrush)); - DeleteObject(SelectObject(hdc, oldPen)); -} - void Text(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF fg, COLORREF bg, LPCTSTR lpchText, HFONT font, LONG style) { diff --git a/base/applications/mspaint/drawing.h b/base/applications/mspaint/drawing.h index 26178a83395..5401168f92c 100644 --- a/base/applications/mspaint/drawing.h +++ b/base/applications/mspaint/drawing.h @@ -32,8 +32,6 @@ void Brush(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF color, LONG sty void RectSel(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2); -void SelectionFrame(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF system_selection_color); - void Text(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF fg, COLORREF bg, LPCTSTR lpchText, HFONT font, LONG style); extern BOOL diff --git a/base/applications/mspaint/globalvar.h b/base/applications/mspaint/globalvar.h index b0099e571f5..3a366c04220 100644 --- a/base/applications/mspaint/globalvar.h +++ b/base/applications/mspaint/globalvar.h @@ -70,14 +70,6 @@ extern CPaletteWindow paletteWindow; extern CCanvasWindow canvasWindow; extern CSelectionWindow selectionWindow; extern CImgAreaWindow imageArea; -extern CSizeboxWindow sizeboxLeftTop; -extern CSizeboxWindow sizeboxCenterTop; -extern CSizeboxWindow sizeboxRightTop; -extern CSizeboxWindow sizeboxLeftCenter; -extern CSizeboxWindow sizeboxRightCenter; -extern CSizeboxWindow sizeboxLeftBottom; -extern CSizeboxWindow sizeboxCenterBottom; -extern CSizeboxWindow sizeboxRightBottom; extern CTextEditWindow textEditWindow; /* VARIABLES declared in dialogs.cpp ********************************/ diff --git a/base/applications/mspaint/main.cpp b/base/applications/mspaint/main.cpp index 933ef86cf6e..82b70d9dba5 100644 --- a/base/applications/mspaint/main.cpp +++ b/base/applications/mspaint/main.cpp @@ -57,14 +57,6 @@ CPaletteWindow paletteWindow; CCanvasWindow canvasWindow; CSelectionWindow selectionWindow; CImgAreaWindow imageArea; -CSizeboxWindow sizeboxLeftTop; -CSizeboxWindow sizeboxCenterTop; -CSizeboxWindow sizeboxRightTop; -CSizeboxWindow sizeboxLeftCenter; -CSizeboxWindow sizeboxRightCenter; -CSizeboxWindow sizeboxLeftBottom; -CSizeboxWindow sizeboxCenterBottom; -CSizeboxWindow sizeboxRightBottom; CTextEditWindow textEditWindow; // get file name extension from filter string @@ -289,16 +281,6 @@ _tWinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPTSTR lpszArgument } } - /* creating the size boxes */ - RECT sizeboxPos = {0, 0, GRIP_SIZE, GRIP_SIZE}; - sizeboxLeftTop.Create(canvasWindow, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); - sizeboxCenterTop.Create(canvasWindow, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); - sizeboxRightTop.Create(canvasWindow, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); - sizeboxLeftCenter.Create(canvasWindow, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); - sizeboxRightCenter.Create(canvasWindow, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); - sizeboxLeftBottom.Create(canvasWindow, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); - sizeboxCenterBottom.Create(canvasWindow, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); - sizeboxRightBottom.Create(canvasWindow, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); /* placing the size boxes around the image */ imageArea.SendMessage(WM_SIZE, 0, 0); diff --git a/base/applications/mspaint/mouse.cpp b/base/applications/mspaint/mouse.cpp index fda0bc64a81..57f289487c6 100644 --- a/base/applications/mspaint/mouse.cpp +++ b/base/applications/mspaint/mouse.cpp @@ -19,9 +19,13 @@ POINT ToolBase::pointStack[256] = { { 0 } }; void placeSelWin() { - selectionWindow.MoveWindow(Zoomed(selectionModel.GetDestRectLeft()), Zoomed(selectionModel.GetDestRectTop()), - Zoomed(selectionModel.GetDestRectWidth()) + 2 * GRIP_SIZE, - Zoomed(selectionModel.GetDestRectHeight()) + 2 * GRIP_SIZE, TRUE); + CRect rc; + rc.left = Zoomed(selectionModel.GetDestRectLeft()); + rc.top = Zoomed(selectionModel.GetDestRectTop()); + rc.right = rc.left + Zoomed(selectionModel.GetDestRectWidth()); + rc.bottom = rc.top + Zoomed(selectionModel.GetDestRectHeight()); + ::InflateRect(&rc, GRIP_SIZE, GRIP_SIZE); + selectionWindow.MoveWindow(rc.left, rc.top, rc.Width(), rc.Height(), TRUE); selectionWindow.BringWindowToTop(); imageArea.InvalidateRect(NULL, FALSE); } @@ -712,11 +716,6 @@ struct ShapeTool : ToolBase imageModel.ResetToPrevious(); --pointSP; draw(m_bLeftButton, -1, -1, TRUE); - pointSP = 0; - } - else - { - imageModel.Undo(TRUE); } ToolBase::OnFinishDraw(); } diff --git a/base/applications/mspaint/precomp.h b/base/applications/mspaint/precomp.h index 7c1f23acebb..cd24f7f8379 100644 --- a/base/applications/mspaint/precomp.h +++ b/base/applications/mspaint/precomp.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -38,8 +39,22 @@ #define WM_IMAGEMODELIMAGECHANGED (WM_APP + 6) #define WM_SELECTIONMODELREFRESHNEEDED (WM_APP + 7) +enum CANVAS_HITTEST // hit +{ + HIT_NONE = 0, // Nothing hit or outside + HIT_UPPER_LEFT, + HIT_UPPER_CENTER, + HIT_UPPER_RIGHT, + HIT_MIDDLE_LEFT, + HIT_MIDDLE_RIGHT, + HIT_LOWER_LEFT, + HIT_LOWER_CENTER, + HIT_LOWER_RIGHT, + HIT_BORDER, + HIT_INNER, +}; + #include "resource.h" -#include "canvas.h" #include "drawing.h" #include "dib.h" #include "fullscreen.h" @@ -53,6 +68,7 @@ #include "selection.h" #include "selectionmodel.h" #include "sizebox.h" +#include "canvas.h" #include "textedit.h" #include "toolbox.h" #include "toolsettings.h" diff --git a/base/applications/mspaint/selection.cpp b/base/applications/mspaint/selection.cpp index 64d01538216..4a328b0ab1f 100644 --- a/base/applications/mspaint/selection.cpp +++ b/base/applications/mspaint/selection.cpp @@ -33,24 +33,6 @@ void CSelectionWindow::ForceRefreshSelectionContents() int CSelectionWindow::IdentifyCorner(int iXPos, int iYPos, int iWidth, int iHeight) { - POINT pt = { iXPos, iYPos }; - HWND hwndChild = ChildWindowFromPointEx(pt, CWP_SKIPINVISIBLE | CWP_SKIPDISABLED); - if (hwndChild == sizeboxLeftTop) - return ACTION_RESIZE_TOP_LEFT; - if (hwndChild == sizeboxCenterTop) - return ACTION_RESIZE_TOP; - if (hwndChild == sizeboxRightTop) - return ACTION_RESIZE_TOP_RIGHT; - if (hwndChild == sizeboxRightCenter) - return ACTION_RESIZE_RIGHT; - if (hwndChild == sizeboxLeftCenter) - return ACTION_RESIZE_LEFT; - if (hwndChild == sizeboxCenterBottom) - return ACTION_RESIZE_BOTTOM; - if (hwndChild == sizeboxRightBottom) - return ACTION_RESIZE_BOTTOM_RIGHT; - if (hwndChild == sizeboxLeftBottom) - return ACTION_RESIZE_BOTTOM_LEFT; return 0; } @@ -60,10 +42,9 @@ LRESULT CSelectionWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& HDC hDC = BeginPaint(&ps); if (!m_bMoving) { - SelectionFrame(hDC, 1, 1, - Zoomed(selectionModel.GetDestRectWidth()) + (GRIP_SIZE * 2) - 1, - Zoomed(selectionModel.GetDestRectHeight()) + (GRIP_SIZE * 2) - 1, - GetSysColor(COLOR_HIGHLIGHT)); + RECT rcClient; + GetClientRect(&rcClient); + drawSizeBoxes(hDC, &rcClient, TRUE, &ps.rcPaint); } EndPaint(&ps); return 0; @@ -93,7 +74,16 @@ LRESULT CSelectionWindow::OnSysColorChange(UINT nMsg, WPARAM wParam, LPARAM lPar LRESULT CSelectionWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { - SetCursor(LoadCursor(NULL, IDC_SIZEALL)); + RECT rcClient; + GetClientRect(&rcClient); + + POINT pt; + ::GetCursorPos(&pt); + ScreenToClient(&pt); + + if (!setCursorOnSizeBox(getSizeBoxHitTest(pt, &rcClient))) + ::SetCursor(::LoadCursor(NULL, IDC_SIZEALL)); + return 0; } diff --git a/base/applications/mspaint/sizebox.cpp b/base/applications/mspaint/sizebox.cpp index 2ebbbcc70a3..8f3c5022e6b 100644 --- a/base/applications/mspaint/sizebox.cpp +++ b/base/applications/mspaint/sizebox.cpp @@ -7,117 +7,125 @@ * Katayama Hirofumi MZ */ -/* INCLUDES *********************************************************/ - #include "precomp.h" -/* FUNCTIONS ********************************************************/ - -static BOOL resizing = FALSE; -static short xOrig; -static short yOrig; - -LRESULT CSizeboxWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +static LPCWSTR s_cursor_shapes[] = { - if ((m_hWnd == sizeboxLeftTop.m_hWnd) || (m_hWnd == sizeboxRightBottom.m_hWnd)) - SetCursor(LoadCursor(NULL, IDC_SIZENWSE)); - if ((m_hWnd == sizeboxLeftBottom.m_hWnd) || (m_hWnd == sizeboxRightTop.m_hWnd)) - SetCursor(LoadCursor(NULL, IDC_SIZENESW)); - if ((m_hWnd == sizeboxLeftCenter.m_hWnd) || (m_hWnd == sizeboxRightCenter.m_hWnd)) - SetCursor(LoadCursor(NULL, IDC_SIZEWE)); - if ((m_hWnd == sizeboxCenterTop.m_hWnd) || (m_hWnd == sizeboxCenterBottom.m_hWnd)) - SetCursor(LoadCursor(NULL, IDC_SIZENS)); - return 0; -} + IDC_SIZENWSE, IDC_SIZENS, IDC_SIZENESW, + IDC_SIZEWE, IDC_SIZEWE, + IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE, +}; -LRESULT CSizeboxWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - resizing = TRUE; - xOrig = GET_X_LPARAM(lParam); - yOrig = GET_Y_LPARAM(lParam); - SetCapture(); - return 0; -} +/* FUNCTIONS ********************************************************/ -LRESULT CSizeboxWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +BOOL setCursorOnSizeBox(CANVAS_HITTEST hit) { - if (resizing) + if (HIT_UPPER_LEFT <= hit && hit <= HIT_LOWER_RIGHT) { - CString strSize; - short xRel; - short yRel; - int imgXRes = imageModel.GetWidth(); - int imgYRes = imageModel.GetHeight(); - xRel = UnZoomed(GET_X_LPARAM(lParam) - xOrig); - yRel = UnZoomed(GET_Y_LPARAM(lParam) - yOrig); - if (m_hWnd == sizeboxLeftTop.m_hWnd) - strSize.Format(_T("%d x %d"), imgXRes - xRel, imgYRes - yRel); - if (m_hWnd == sizeboxCenterTop.m_hWnd) - strSize.Format(_T("%d x %d"), imgXRes, imgYRes - yRel); - if (m_hWnd == sizeboxRightTop.m_hWnd) - strSize.Format(_T("%d x %d"), imgXRes + xRel, imgYRes - yRel); - if (m_hWnd == sizeboxLeftCenter.m_hWnd) - strSize.Format(_T("%d x %d"), imgXRes - xRel, imgYRes); - if (m_hWnd == sizeboxRightCenter.m_hWnd) - strSize.Format(_T("%d x %d"), imgXRes + xRel, imgYRes); - if (m_hWnd == sizeboxLeftBottom.m_hWnd) - strSize.Format(_T("%d x %d"), imgXRes - xRel, imgYRes + yRel); - if (m_hWnd == sizeboxCenterBottom.m_hWnd) - strSize.Format(_T("%d x %d"), imgXRes, imgYRes + yRel); - if (m_hWnd == sizeboxRightBottom.m_hWnd) - strSize.Format(_T("%d x %d"), imgXRes + xRel, imgYRes + yRel); - SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) (LPCTSTR) strSize); + ::SetCursor(::LoadCursor(NULL, s_cursor_shapes[hit - HIT_UPPER_LEFT])); + return TRUE; } - return 0; + return FALSE; } -LRESULT CSizeboxWindow::OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +BOOL getSizeBoxRect(LPRECT prc, CANVAS_HITTEST hit, LPCRECT prcBase) { - if (resizing) + switch (hit) { - short xRel; - short yRel; - int imgXRes = imageModel.GetWidth(); - int imgYRes = imageModel.GetHeight(); - xRel = (GET_X_LPARAM(lParam) - xOrig) * 1000 / toolsModel.GetZoom(); - yRel = (GET_Y_LPARAM(lParam) - yOrig) * 1000 / toolsModel.GetZoom(); - if (m_hWnd == sizeboxLeftTop) - imageModel.Crop(imgXRes - xRel, imgYRes - yRel, xRel, yRel); - if (m_hWnd == sizeboxCenterTop.m_hWnd) - imageModel.Crop(imgXRes, imgYRes - yRel, 0, yRel); - if (m_hWnd == sizeboxRightTop.m_hWnd) - imageModel.Crop(imgXRes + xRel, imgYRes - yRel, 0, yRel); - if (m_hWnd == sizeboxLeftCenter.m_hWnd) - imageModel.Crop(imgXRes - xRel, imgYRes, xRel, 0); - if (m_hWnd == sizeboxRightCenter.m_hWnd) - imageModel.Crop(imgXRes + xRel, imgYRes, 0, 0); - if (m_hWnd == sizeboxLeftBottom.m_hWnd) - imageModel.Crop(imgXRes - xRel, imgYRes + yRel, xRel, 0); - if (m_hWnd == sizeboxCenterBottom.m_hWnd) - imageModel.Crop(imgXRes, imgYRes + yRel, 0, 0); - if (m_hWnd == sizeboxRightBottom.m_hWnd) - imageModel.Crop(imgXRes + xRel, imgYRes + yRel, 0, 0); - SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) _T("")); + case HIT_UPPER_LEFT: + prc->left = prcBase->left; + prc->top = prcBase->top; + break; + case HIT_UPPER_CENTER: + prc->left = (prcBase->left + prcBase->right - GRIP_SIZE) / 2; + prc->top = prcBase->top; + break; + case HIT_UPPER_RIGHT: + prc->left = prcBase->right - GRIP_SIZE; + prc->top = prcBase->top; + break; + case HIT_MIDDLE_LEFT: + prc->left = prcBase->left; + prc->top = (prcBase->top + prcBase->bottom - GRIP_SIZE) / 2; + break; + case HIT_MIDDLE_RIGHT: + prc->left = prcBase->right - GRIP_SIZE; + prc->top = (prcBase->top + prcBase->bottom - GRIP_SIZE) / 2; + break; + case HIT_LOWER_LEFT: + prc->left = prcBase->left; + prc->top = prcBase->bottom - GRIP_SIZE; + break; + case HIT_LOWER_CENTER: + prc->left = (prcBase->left + prcBase->right - GRIP_SIZE) / 2; + prc->top = prcBase->bottom - GRIP_SIZE; + break; + case HIT_LOWER_RIGHT: + prc->left = prcBase->right - GRIP_SIZE; + prc->top = prcBase->bottom - GRIP_SIZE; + break; + case HIT_INNER: + *prc = *prcBase; + ::InflateRect(prc, -GRIP_SIZE, -GRIP_SIZE); + return TRUE; + default: + ::SetRectEmpty(prc); + return FALSE; } - resizing = FALSE; - ReleaseCapture(); - return 0; + + prc->right = prc->left + GRIP_SIZE; + prc->bottom = prc->top + GRIP_SIZE; + return TRUE; } -LRESULT CSizeboxWindow::OnCaptureChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +CANVAS_HITTEST getSizeBoxHitTest(POINT pt, LPCRECT prcBase) { - resizing = FALSE; - return 0; + RECT rc; + + if (!::PtInRect(prcBase, pt)) + return HIT_NONE; + + rc = *prcBase; + ::InflateRect(&rc, -GRIP_SIZE, -GRIP_SIZE); + if (::PtInRect(&rc, pt)) + return HIT_INNER; + + for (INT i = HIT_UPPER_LEFT; i <= HIT_LOWER_RIGHT; ++i) + { + CANVAS_HITTEST hit = (CANVAS_HITTEST)i; + getSizeBoxRect(&rc, hit, prcBase); + if (::PtInRect(&rc, pt)) + return hit; + } + + return HIT_BORDER; } -LRESULT CSizeboxWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) +VOID drawSizeBoxes(HDC hdc, LPCRECT prcBase, BOOL bDrawFrame, LPCRECT prcPaint) { - if (wParam == VK_ESCAPE) + CRect rc, rcIntersect; + + if (prcPaint && !::IntersectRect(&rcIntersect, prcPaint, prcBase)) + return; + + if (bDrawFrame) + { + rc = *prcBase; + ::InflateRect(&rc, -GRIP_SIZE / 2, -GRIP_SIZE / 2); + + LOGBRUSH logBrush = { BS_HOLLOW, 0, 0 }; + COLORREF rgbHighlight = ::GetSysColor(COLOR_HIGHLIGHT); + HGDIOBJ oldPen = ::SelectObject(hdc, ::CreatePen(PS_DOT, 1, rgbHighlight)); + HGDIOBJ oldBrush = ::SelectObject(hdc, ::CreateBrushIndirect(&logBrush)); + ::Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom); + ::DeleteObject(::SelectObject(hdc, oldBrush)); + ::DeleteObject(::SelectObject(hdc, oldPen)); + } + + for (INT i = HIT_UPPER_LEFT; i <= HIT_LOWER_RIGHT; ++i) { - if (GetCapture() == m_hWnd) - { - ReleaseCapture(); - } + getSizeBoxRect(&rc, (CANVAS_HITTEST)i, prcBase); + if (!prcPaint || ::IntersectRect(&rcIntersect, &rc, prcPaint)) + ::FillRect(hdc, &rc, (HBRUSH)(COLOR_HIGHLIGHT + 1)); } - return 0; } diff --git a/base/applications/mspaint/sizebox.h b/base/applications/mspaint/sizebox.h index 551f0e6bfbc..9a6e4234418 100644 --- a/base/applications/mspaint/sizebox.h +++ b/base/applications/mspaint/sizebox.h @@ -9,24 +9,7 @@ #pragma once -class CSizeboxWindow : public CWindowImpl -{ -public: - DECLARE_WND_CLASS_EX(_T("Sizebox"), CS_DBLCLKS, COLOR_HIGHLIGHT) - - BEGIN_MSG_MAP(CSizeboxWindow) - MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor) - MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) - MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove) - MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp) - MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged) - MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown) - END_MSG_MAP() - - LRESULT OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnLButtonUp(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); -}; +BOOL setCursorOnSizeBox(CANVAS_HITTEST hit); +BOOL getSizeBoxRect(LPRECT prc, CANVAS_HITTEST hit, LPCRECT prcBase); +CANVAS_HITTEST getSizeBoxHitTest(POINT pt, LPCRECT prcBase); +VOID drawSizeBoxes(HDC hdc, LPCRECT prcBase, BOOL bDrawFrame = FALSE, LPCRECT prcPaint = NULL); diff --git a/base/applications/mspaint/winproc.cpp b/base/applications/mspaint/winproc.cpp index e121a4f53cf..ee4e9daa87a 100644 --- a/base/applications/mspaint/winproc.cpp +++ b/base/applications/mspaint/winproc.cpp @@ -437,17 +437,10 @@ LRESULT CMainWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH HWND hwndCapture = GetCapture(); if (hwndCapture) { - if (selectionWindow.m_hWnd == hwndCapture || + if (canvasWindow.m_hWnd == hwndCapture || + selectionWindow.m_hWnd == hwndCapture || imageArea.m_hWnd == hwndCapture || - fullscreenWindow.m_hWnd == hwndCapture || - sizeboxLeftTop.m_hWnd == hwndCapture || - sizeboxCenterTop.m_hWnd == hwndCapture || - sizeboxRightTop.m_hWnd == hwndCapture || - sizeboxLeftCenter.m_hWnd == hwndCapture || - sizeboxRightCenter.m_hWnd == hwndCapture || - sizeboxLeftBottom.m_hWnd == hwndCapture || - sizeboxCenterBottom.m_hWnd == hwndCapture || - sizeboxRightBottom.m_hWnd == hwndCapture) + fullscreenWindow.m_hWnd == hwndCapture) { SendMessage(hwndCapture, nMsg, wParam, lParam); }