From aac89519ec9270ffe0935cad267a4a87faccc92f Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Sat, 1 Apr 2023 22:01:04 +0900 Subject: [PATCH] [MSPAINT] Make selection window-less (#5208) - Delete selection.cpp and selection.h and selectionWindow. - Extend ColorKeyedMaskBlt function. - Implement selection resizing. CORE-18867 --- base/applications/mspaint/CMakeLists.txt | 1 - base/applications/mspaint/canvas.cpp | 23 +- base/applications/mspaint/common.h | 1 - base/applications/mspaint/dib.cpp | 8 +- base/applications/mspaint/dib.h | 2 +- base/applications/mspaint/drawing.cpp | 97 +++- base/applications/mspaint/drawing.h | 6 +- base/applications/mspaint/globalvar.h | 1 - base/applications/mspaint/history.cpp | 28 +- base/applications/mspaint/history.h | 1 - base/applications/mspaint/imgarea.cpp | 205 +++++-- base/applications/mspaint/imgarea.h | 12 +- base/applications/mspaint/mouse.cpp | 129 ++--- base/applications/mspaint/palettemodel.cpp | 4 +- base/applications/mspaint/precomp.h | 1 - base/applications/mspaint/selection.cpp | 237 -------- base/applications/mspaint/selection.h | 75 --- base/applications/mspaint/selectionmodel.cpp | 544 ++++++++++--------- base/applications/mspaint/selectionmodel.h | 72 +-- base/applications/mspaint/toolbox.cpp | 2 +- base/applications/mspaint/toolsmodel.cpp | 10 +- base/applications/mspaint/toolsmodel.h | 28 + base/applications/mspaint/winproc.cpp | 30 +- 23 files changed, 695 insertions(+), 822 deletions(-) delete mode 100644 base/applications/mspaint/selection.cpp delete mode 100644 base/applications/mspaint/selection.h diff --git a/base/applications/mspaint/CMakeLists.txt b/base/applications/mspaint/CMakeLists.txt index 2d6e24dc46d..57532cba22d 100644 --- a/base/applications/mspaint/CMakeLists.txt +++ b/base/applications/mspaint/CMakeLists.txt @@ -20,7 +20,6 @@ list(APPEND SOURCE palette.cpp palettemodel.cpp registry.cpp - selection.cpp selectionmodel.cpp sizebox.cpp textedit.cpp diff --git a/base/applications/mspaint/canvas.cpp b/base/applications/mspaint/canvas.cpp index d538925f39d..c0fc4ad9210 100644 --- a/base/applications/mspaint/canvas.cpp +++ b/base/applications/mspaint/canvas.cpp @@ -150,14 +150,25 @@ LRESULT CCanvasWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BO if (hit == HIT_NONE || hit == HIT_BORDER) { - if (toolsModel.GetActiveTool() == TOOL_BEZIER || - toolsModel.GetActiveTool() == TOOL_SHAPE) + switch (toolsModel.GetActiveTool()) { - if (ToolBase::pointSP != 0) - { - toolsModel.OnCancelDraw(); + case TOOL_BEZIER: + case TOOL_SHAPE: + if (ToolBase::pointSP != 0) + { + toolsModel.OnCancelDraw(); + imageArea.Invalidate(); + } + break; + + case TOOL_FREESEL: + case TOOL_RECTSEL: + toolsModel.OnFinishDraw(); imageArea.Invalidate(); - } + break; + + default: + break; } toolsModel.resetTool(); // resets the point-buffer of the polygon and bezier functions diff --git a/base/applications/mspaint/common.h b/base/applications/mspaint/common.h index 619133fc550..0b9890d27f9 100644 --- a/base/applications/mspaint/common.h +++ b/base/applications/mspaint/common.h @@ -56,6 +56,5 @@ enum CANVAS_HITTEST // hit BOOL zoomTo(int newZoom, int mouseX, int mouseY); BOOL nearlyEqualPoints(INT x0, INT y0, INT x1, INT y1); -void placeSelWin(void); void updateStartAndLast(LONG x, LONG y); void updateLast(LONG x, LONG y); diff --git a/base/applications/mspaint/dib.cpp b/base/applications/mspaint/dib.cpp index 96218a824a3..f46ef419934 100644 --- a/base/applications/mspaint/dib.cpp +++ b/base/applications/mspaint/dib.cpp @@ -220,9 +220,13 @@ HBITMAP DoLoadImageFile(HWND hwnd, LPCTSTR name, BOOL fIsMainFile) return hBitmap; } -HBITMAP Rotate90DegreeBlt(HDC hDC1, INT cx, INT cy, BOOL bRight) +HBITMAP Rotate90DegreeBlt(HDC hDC1, INT cx, INT cy, BOOL bRight, BOOL bMono) { - HBITMAP hbm2 = CreateDIBWithProperties(cy, cx); + HBITMAP hbm2; + if (bMono) + hbm2 = ::CreateBitmap(cy, cx, 1, 1, NULL); + else + hbm2 = CreateDIBWithProperties(cy, cx); if (!hbm2) return NULL; diff --git a/base/applications/mspaint/dib.h b/base/applications/mspaint/dib.h index 82ccde6e9ed..f9eb7d37384 100644 --- a/base/applications/mspaint/dib.h +++ b/base/applications/mspaint/dib.h @@ -28,7 +28,7 @@ void ShowFileLoadError(LPCTSTR name); HBITMAP SetBitmapAndInfo(HBITMAP hBitmap, LPCTSTR name, DWORD dwFileSize, BOOL isFile); -HBITMAP Rotate90DegreeBlt(HDC hDC1, INT cx, INT cy, BOOL bRight); +HBITMAP Rotate90DegreeBlt(HDC hDC1, INT cx, INT cy, BOOL bRight, BOOL bMono); HBITMAP SkewDIB(HDC hDC1, HBITMAP hbm, INT nDegree, BOOL bVertical); diff --git a/base/applications/mspaint/drawing.cpp b/base/applications/mspaint/drawing.cpp index f94da436eca..86711c0f6f0 100644 --- a/base/applications/mspaint/drawing.cpp +++ b/base/applications/mspaint/drawing.cpp @@ -290,33 +290,76 @@ Text(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF fg, COLORREF bg, LPCT BOOL ColorKeyedMaskBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, - HDC hdcSrc, int nXSrc, int nYSrc, HBITMAP hbmMask, int xMask, int yMask, - DWORD dwRop, COLORREF keyColor) + HDC hdcSrc, int nXSrc, int nYSrc, int nSrcWidth, int nSrcHeight, + HBITMAP hbmMask, COLORREF keyColor) { - HDC hTempDC; - HDC hTempDC2; - HBITMAP hTempBm; - HBRUSH hTempBrush; - HBITMAP hTempMask; - - hTempDC = CreateCompatibleDC(hdcSrc); - hTempDC2 = CreateCompatibleDC(hdcSrc); - hTempBm = CreateCompatibleBitmap(hTempDC, nWidth, nHeight); - SelectObject(hTempDC, hTempBm); - hTempBrush = CreateSolidBrush(keyColor); - SelectObject(hTempDC, hTempBrush); - BitBlt(hTempDC, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, SRCCOPY); - PatBlt(hTempDC, 0, 0, nWidth, nHeight, PATINVERT); - hTempMask = CreateBitmap(nWidth, nHeight, 1, 1, NULL); - SelectObject(hTempDC2, hTempMask); - BitBlt(hTempDC2, 0, 0, nWidth, nHeight, hTempDC, 0, 0, SRCCOPY); - SelectObject(hTempDC, hbmMask); - BitBlt(hTempDC2, 0, 0, nWidth, nHeight, hTempDC, xMask, yMask, SRCAND); - MaskBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, hTempMask, xMask, yMask, dwRop); - DeleteDC(hTempDC); - DeleteDC(hTempDC2); - DeleteObject(hTempBm); - DeleteObject(hTempBrush); - DeleteObject(hTempMask); + HDC hTempDC1, hTempDC2; + HBITMAP hbmTempColor, hbmTempMask; + HGDIOBJ hbmOld1, hbmOld2; + + if (hbmMask == NULL) + { + if (keyColor == CLR_INVALID) + { + ::StretchBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, + hdcSrc, nXSrc, nYSrc, nSrcWidth, nSrcHeight, SRCCOPY); + } + else + { + ::GdiTransparentBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, + hdcSrc, nXSrc, nYSrc, nSrcWidth, nSrcHeight, keyColor); + } + return TRUE; + } + else if (nWidth == nSrcWidth && nHeight == nSrcHeight && keyColor == CLR_INVALID) + { + ::MaskBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, + hdcSrc, nXSrc, nYSrc, hbmMask, 0, 0, MAKEROP4(SRCCOPY, 0xAA0029)); + return TRUE; + } + + hTempDC1 = ::CreateCompatibleDC(hdcDest); + hTempDC2 = ::CreateCompatibleDC(hdcDest); + hbmTempMask = ::CreateBitmap(nWidth, nHeight, 1, 1, NULL); + hbmTempColor = CreateColorDIB(nWidth, nHeight, RGB(255, 255, 255)); + + // hbmTempMask <-- hbmMask (stretched) + hbmOld1 = ::SelectObject(hTempDC1, hbmMask); + hbmOld2 = ::SelectObject(hTempDC2, hbmTempMask); + ::StretchBlt(hTempDC2, 0, 0, nWidth, nHeight, hTempDC1, 0, 0, nSrcWidth, nSrcHeight, SRCCOPY); + ::SelectObject(hTempDC2, hbmOld2); + ::SelectObject(hTempDC1, hbmOld1); + + hbmOld1 = ::SelectObject(hTempDC1, hbmTempColor); + if (keyColor == CLR_INVALID) + { + // hbmTempColor <-- hdcSrc (stretched) + ::StretchBlt(hTempDC1, 0, 0, nWidth, nHeight, + hdcSrc, nXSrc, nYSrc, nSrcWidth, nSrcHeight, SRCCOPY); + + // hdcDest <-- hbmTempColor (masked) + ::MaskBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hTempDC1, 0, 0, + hbmTempMask, 0, 0, MAKEROP4(SRCCOPY, 0xAA0029)); + } + else + { + // hbmTempColor <-- hdcDest + ::BitBlt(hTempDC1, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, SRCCOPY); + + // hbmTempColor <-- hdcSrc (color key) + ::GdiTransparentBlt(hTempDC1, 0, 0, nWidth, nHeight, + hdcSrc, nXSrc, nYSrc, nSrcWidth, nSrcHeight, keyColor); + + // hdcDest <-- hbmTempColor (masked) + ::MaskBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hTempDC1, 0, 0, + hbmTempMask, 0, 0, MAKEROP4(SRCCOPY, 0xAA0029)); + } + ::SelectObject(hTempDC1, hbmOld1); + + ::DeleteObject(hbmTempColor); + ::DeleteObject(hbmTempMask); + ::DeleteDC(hTempDC2); + ::DeleteDC(hTempDC1); + return TRUE; } diff --git a/base/applications/mspaint/drawing.h b/base/applications/mspaint/drawing.h index 5401168f92c..8fb0f54c6a6 100644 --- a/base/applications/mspaint/drawing.h +++ b/base/applications/mspaint/drawing.h @@ -34,7 +34,7 @@ void RectSel(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2); void Text(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF fg, COLORREF bg, LPCTSTR lpchText, HFONT font, LONG style); -extern BOOL +BOOL ColorKeyedMaskBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, - HDC hdcSrc, int nXSrc, int nYSrc, HBITMAP hbmMask, int xMask, int yMask, - DWORD dwRop, COLORREF keyColor); + HDC hdcSrc, int nXSrc, int nYSrc, int nSrcWidth, int nSrcHeight, + HBITMAP hbmMask, COLORREF keyColor); diff --git a/base/applications/mspaint/globalvar.h b/base/applications/mspaint/globalvar.h index fe9e47f5f0b..058117f9390 100644 --- a/base/applications/mspaint/globalvar.h +++ b/base/applications/mspaint/globalvar.h @@ -52,6 +52,5 @@ extern CToolBox toolBoxContainer; extern CToolSettingsWindow toolSettingsWindow; extern CPaletteWindow paletteWindow; extern CCanvasWindow canvasWindow; -extern CSelectionWindow selectionWindow; extern CImgAreaWindow imageArea; extern CTextEditWindow textEditWindow; diff --git a/base/applications/mspaint/history.cpp b/base/applications/mspaint/history.cpp index 847e6c6db81..0680865c2a6 100644 --- a/base/applications/mspaint/history.cpp +++ b/base/applications/mspaint/history.cpp @@ -64,7 +64,7 @@ void ImageModel::Undo(BOOL bClearRedo) { int oldWidth = GetWidth(); int oldHeight = GetHeight(); - selectionWindow.ShowWindow(SW_HIDE); + selectionModel.m_bShow = FALSE; currInd = (currInd + HISTORYSIZE - 1) % HISTORYSIZE; SelectObject(hDrawingDC, hBms[currInd]); undoSteps--; @@ -85,7 +85,7 @@ void ImageModel::Redo() { int oldWidth = GetWidth(); int oldHeight = GetHeight(); - selectionWindow.ShowWindow(SW_HIDE); + selectionModel.m_bShow = FALSE; currInd = (currInd + 1) % HISTORYSIZE; SelectObject(hDrawingDC, hBms[currInd]); redoSteps--; @@ -264,7 +264,7 @@ void ImageModel::RotateNTimes90Degrees(int iN) case 1: case 3: DeleteObject(hBms[(currInd + 1) % HISTORYSIZE]); - hBms[(currInd + 1) % HISTORYSIZE] = Rotate90DegreeBlt(hDrawingDC, GetWidth(), GetHeight(), iN == 1); + hBms[(currInd + 1) % HISTORYSIZE] = Rotate90DegreeBlt(hDrawingDC, GetWidth(), GetHeight(), iN == 1, FALSE); currInd = (currInd + 1) % HISTORYSIZE; if (undoSteps < HISTORYSIZE - 1) undoSteps++; @@ -282,23 +282,15 @@ void ImageModel::RotateNTimes90Degrees(int iN) NotifyImageChanged(); } -void ImageModel::DrawSelectionBackground(COLORREF rgbBG) -{ - if (toolsModel.GetActiveTool() == TOOL_FREESEL) - selectionModel.DrawBackgroundPoly(hDrawingDC, rgbBG); - else - selectionModel.DrawBackgroundRect(hDrawingDC, rgbBG); -} - void ImageModel::DeleteSelection() { - if (selectionWindow.IsWindowVisible()) - ResetToPrevious(); - CopyPrevious(); - if (selectionWindow.IsWindowVisible()) - Undo(TRUE); - DrawSelectionBackground(paletteModel.GetBgColor()); - selectionWindow.ShowWindow(SW_HIDE); + if (!selectionModel.m_bShow) + return; + + selectionModel.TakeOff(); + selectionModel.m_bShow = FALSE; + selectionModel.ClearColor(); + selectionModel.ClearMask(); NotifyImageChanged(); } diff --git a/base/applications/mspaint/history.h b/base/applications/mspaint/history.h index 17ef43b9e48..40792f8d661 100644 --- a/base/applications/mspaint/history.h +++ b/base/applications/mspaint/history.h @@ -45,7 +45,6 @@ public: void FlipHorizontally(); void FlipVertically(); void RotateNTimes90Degrees(int iN); - void DrawSelectionBackground(COLORREF rgbBG); void DeleteSelection(); void Bound(POINT& pt); }; diff --git a/base/applications/mspaint/imgarea.cpp b/base/applications/mspaint/imgarea.cpp index dfb93455b43..abae54c89a5 100644 --- a/base/applications/mspaint/imgarea.cpp +++ b/base/applications/mspaint/imgarea.cpp @@ -21,7 +21,6 @@ LRESULT CImgAreaWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& m_hCurZoom = LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_ZOOM)); m_hCurPen = LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_PEN)); m_hCurAirbrush = LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_AIRBRUSH)); - return 0; } @@ -71,49 +70,61 @@ LRESULT CImgAreaWindow::OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH LRESULT CImgAreaWindow::OnEraseBkGnd(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { - HDC hdc = (HDC)wParam; - - if (toolsModel.GetActiveTool() == TOOL_TEXT && !toolsModel.IsBackgroundTransparent() && - ::IsWindowVisible(textEditWindow)) - { - // Do clipping - HWND hChild = textEditWindow; - RECT rcChild; - ::GetWindowRect(hChild, &rcChild); - ::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rcChild, 2); - ExcludeClipRect(hdc, rcChild.left, rcChild.top, rcChild.right, rcChild.bottom); - } - - return DefWindowProc(nMsg, wParam, lParam); + 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); - int imgXRes = imageModel.GetWidth(); - int imgYRes = imageModel.GetHeight(); - StretchBlt(hdc, 0, 0, Zoomed(imgXRes), Zoomed(imgYRes), imageModel.GetDC(), 0, 0, imgXRes, - imgYRes, SRCCOPY); + + // 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(hdc, CreatePen(PS_SOLID, 1, 0x00a0a0a0)); - int counter; - for(counter = 0; counter <= imgYRes; counter++) + HPEN oldPen = (HPEN) SelectObject(hdcMem, CreatePen(PS_SOLID, 1, 0x00a0a0a0)); + for (int counter = 0; counter <= size.cy; counter++) { - MoveToEx(hdc, 0, Zoomed(counter), NULL); - LineTo(hdc, Zoomed(imgXRes), Zoomed(counter)); + ::MoveToEx(hdcMem, 0, ::Zoomed(counter), NULL); + ::LineTo(hdcMem, ::Zoomed(size.cx), ::Zoomed(counter)); } - for(counter = 0; counter <= imgXRes; counter++) + for (int counter = 0; counter <= size.cx; counter++) { - MoveToEx(hdc, Zoomed(counter), 0, NULL); - LineTo(hdc, Zoomed(counter), Zoomed(imgYRes)); + ::MoveToEx(hdcMem, ::Zoomed(counter), 0, NULL); + ::LineTo(hdcMem, ::Zoomed(counter), ::Zoomed(size.cy)); } - DeleteObject(SelectObject(hdc, oldPen)); + ::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 (selectionWindow.IsWindow()) - selectionWindow.Invalidate(FALSE); + if (miniature.IsWindow()) miniature.Invalidate(FALSE); if (textEditWindow.IsWindow()) @@ -121,8 +132,57 @@ LRESULT CImgAreaWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& b 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: @@ -148,20 +208,31 @@ LRESULT CImgAreaWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOO 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(); - INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam); - toolsModel.OnButtonDown(TRUE, UnZoomed(x), UnZoomed(y), FALSE); + 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(); - INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam); - toolsModel.OnButtonDown(TRUE, UnZoomed(x), UnZoomed(y), TRUE); + toolsModel.OnButtonDown(TRUE, pt.x, pt.y, TRUE); toolsModel.resetTool(); Invalidate(FALSE); return 0; @@ -169,20 +240,22 @@ LRESULT CImgAreaWindow::OnLButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, 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(); - INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam); - toolsModel.OnButtonDown(FALSE, UnZoomed(x), UnZoomed(y), FALSE); + 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(); - INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam); - toolsModel.OnButtonDown(FALSE, UnZoomed(x), UnZoomed(y), TRUE); + toolsModel.OnButtonDown(FALSE, pt.x, pt.y, TRUE); toolsModel.resetTool(); Invalidate(FALSE); return 0; @@ -190,20 +263,28 @@ LRESULT CImgAreaWindow::OnRButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, 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; - INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam); - toolsModel.OnButtonUp(TRUE, UnZoomed(x), UnZoomed(y)); + 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); @@ -226,7 +307,7 @@ LRESULT CImgAreaWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& } else { - if (drawing || ToolBase::pointSP != 0 || selectionWindow.IsWindowVisible()) + if (drawing || ToolBase::pointSP != 0 || selectionModel.m_bShow) cancelDrawing(); } } @@ -235,22 +316,34 @@ LRESULT CImgAreaWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& 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; - INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam); - toolsModel.OnButtonUp(FALSE, UnZoomed(x), UnZoomed(y)); + 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) { - LONG xNow = UnZoomed(GET_X_LPARAM(lParam)); - LONG yNow = UnZoomed(GET_Y_LPARAM(lParam)); + 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; @@ -271,26 +364,26 @@ LRESULT CImgAreaWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOO if (!drawing) { CString strCoord; - strCoord.Format(_T("%ld, %ld"), xNow, yNow); + 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 = xNow - start.x; - LONG yRel = yNow - start.y; + 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 = (xNow < 0) ? -start.x : xRel; - else if (xNow > imageModel.GetWidth()) + xRel = (pt.x < 0) ? -start.x : xRel; + else if (pt.x > imageModel.GetWidth()) xRel = imageModel.GetWidth() - start.x; if (yRel < 0) - yRel = (yNow < 0) ? -start.y : yRel; - else if (yNow > imageModel.GetHeight()) - yRel = imageModel.GetHeight() - start.y; + 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)) @@ -310,7 +403,7 @@ LRESULT CImgAreaWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOO case TOOL_SHAPE: { CString strCoord; - strCoord.Format(_T("%ld, %ld"), xNow, yNow); + strCoord.Format(_T("%ld, %ld"), pt.x, pt.y); SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) (LPCTSTR) strCoord); break; } @@ -319,7 +412,7 @@ LRESULT CImgAreaWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOO } if (wParam & MK_LBUTTON) { - toolsModel.OnMouseMove(TRUE, xNow, yNow); + toolsModel.OnMouseMove(TRUE, pt.x, pt.y); Invalidate(FALSE); if ((toolsModel.GetActiveTool() >= TOOL_TEXT) || (toolsModel.GetActiveTool() == TOOL_RECTSEL) || (toolsModel.GetActiveTool() == TOOL_FREESEL)) { @@ -332,7 +425,7 @@ LRESULT CImgAreaWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOO } if (wParam & MK_RBUTTON) { - toolsModel.OnMouseMove(FALSE, xNow, yNow); + toolsModel.OnMouseMove(FALSE, pt.x, pt.y); Invalidate(FALSE); if (toolsModel.GetActiveTool() >= TOOL_TEXT) { diff --git a/base/applications/mspaint/imgarea.h b/base/applications/mspaint/imgarea.h index daef656590a..941424d0af9 100644 --- a/base/applications/mspaint/imgarea.h +++ b/base/applications/mspaint/imgarea.h @@ -13,9 +13,15 @@ class CImgAreaWindow : public CWindowImpl { public: - CImgAreaWindow() : drawing(FALSE) { } + CImgAreaWindow() + : drawing(FALSE) + , m_hitSelection(HIT_NONE) + { + } BOOL drawing; + CANVAS_HITTEST m_hitSelection; + void cancelDrawing(); void finishDrawing(); @@ -71,4 +77,8 @@ private: 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 57f289487c6..5d1c4fcefea 100644 --- a/base/applications/mspaint/mouse.cpp +++ b/base/applications/mspaint/mouse.cpp @@ -16,20 +16,6 @@ POINT ToolBase::pointStack[256] = { { 0 } }; /* FUNCTIONS ********************************************************/ -void -placeSelWin() -{ - 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); -} - void regularize(LONG x0, LONG y0, LONG& x1, LONG& y1) { @@ -82,8 +68,11 @@ void ToolBase::reset() pointSP = 0; start.x = start.y = last.x = last.y = -1; selectionModel.ResetPtStack(); - if (selectionWindow.IsWindow()) - selectionWindow.ShowWindow(SW_HIDE); + if (selectionModel.m_bShow) + { + selectionModel.Landing(); + selectionModel.m_bShow = FALSE; + } } void ToolBase::OnCancelDraw() @@ -121,12 +110,14 @@ struct FreeSelTool : ToolBase void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) { + selectionModel.Landing(); if (bLeftButton) { imageModel.CopyPrevious(); - selectionWindow.ShowWindow(SW_HIDE); + selectionModel.m_bShow = FALSE; selectionModel.ResetPtStack(); - selectionModel.PushToPtStack(x, y); + POINT pt = { x, y }; + selectionModel.PushToPtStack(pt); } m_bLeftButton = bLeftButton; } @@ -137,7 +128,7 @@ struct FreeSelTool : ToolBase { POINT pt = { x, y }; imageModel.Bound(pt); - selectionModel.PushToPtStack(pt.x, pt.y); + selectionModel.PushToPtStack(pt); imageModel.ResetToPrevious(); selectionModel.DrawFramePoly(m_hdc); } @@ -150,28 +141,25 @@ struct FreeSelTool : ToolBase imageModel.ResetToPrevious(); if (selectionModel.PtStackSize() > 2) { - selectionModel.CalculateBoundingBoxAndContents(m_hdc); - placeSelWin(); - selectionWindow.IsMoved(FALSE); - selectionWindow.ShowWindow(SW_SHOWNOACTIVATE); + selectionModel.BuildMaskFromPtStack(); + selectionModel.TakeOff(); + selectionModel.m_bShow = TRUE; } else { imageModel.Undo(TRUE); - selectionWindow.IsMoved(FALSE); selectionModel.ResetPtStack(); - selectionWindow.ShowWindow(SW_HIDE); + selectionModel.m_bShow = FALSE; } + imageArea.Invalidate(FALSE); } } void OnFinishDraw() { if (m_bLeftButton) - { - selectionWindow.IsMoved(FALSE); - selectionWindow.ForceRefreshSelectionContents(); - } + imageArea.Invalidate(FALSE); + m_bLeftButton = FALSE; ToolBase::OnFinishDraw(); } @@ -181,7 +169,6 @@ struct FreeSelTool : ToolBase if (m_bLeftButton) imageModel.Undo(TRUE); m_bLeftButton = FALSE; - selectionWindow.IsMoved(FALSE); ToolBase::OnCancelDraw(); } }; @@ -197,11 +184,12 @@ struct RectSelTool : ToolBase void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) { + selectionModel.Landing(); if (bLeftButton) { imageModel.CopyPrevious(); - selectionWindow.ShowWindow(SW_HIDE); - selectionModel.SetSrcRectSizeToZero(); + selectionModel.m_bShow = FALSE; + ::SetRectEmpty(&selectionModel.m_rc); } m_bLeftButton = bLeftButton; } @@ -213,7 +201,7 @@ struct RectSelTool : ToolBase imageModel.ResetToPrevious(); POINT pt = { x, y }; imageModel.Bound(pt); - selectionModel.SetSrcAndDestRectFromPoints(start, pt); + selectionModel.SetRectFromPoints(start, pt); RectSel(m_hdc, start.x, start.y, pt.x, pt.y); } } @@ -225,23 +213,16 @@ struct RectSelTool : ToolBase imageModel.ResetToPrevious(); if (start.x == x && start.y == y) imageModel.Undo(TRUE); - selectionModel.CalculateContents(m_hdc); - placeSelWin(); - selectionWindow.IsMoved(FALSE); - if (selectionModel.IsSrcRectSizeNonzero()) - selectionWindow.ShowWindow(SW_SHOWNOACTIVATE); - else - selectionWindow.ShowWindow(SW_HIDE); + selectionModel.m_bShow = !selectionModel.m_rc.IsRectEmpty(); + imageArea.Invalidate(FALSE); } } void OnFinishDraw() { if (m_bLeftButton) - { - selectionWindow.IsMoved(FALSE); - selectionWindow.ForceRefreshSelectionContents(); - } + imageArea.Invalidate(FALSE); + m_bLeftButton = FALSE; ToolBase::OnFinishDraw(); } @@ -251,7 +232,6 @@ struct RectSelTool : ToolBase if (m_bLeftButton) imageModel.Undo(TRUE); m_bLeftButton = FALSE; - selectionWindow.IsMoved(FALSE); ToolBase::OnCancelDraw(); } }; @@ -430,7 +410,7 @@ struct TextTool : ToolBase imageModel.ResetToPrevious(); POINT pt = { x, y }; imageModel.Bound(pt); - selectionModel.SetSrcAndDestRectFromPoints(start, pt); + selectionModel.SetRectFromPoints(start, pt); RectSel(m_hdc, start.x, start.y, pt.x, pt.y); } @@ -452,6 +432,10 @@ struct TextTool : ToolBase { imageModel.Undo(TRUE); + POINT pt = { x, y }; + imageModel.Bound(pt); + selectionModel.SetRectFromPoints(start, pt); + BOOL bTextBoxShown = ::IsWindowVisible(textEditWindow); if (bTextBoxShown && textEditWindow.GetWindowTextLength() > 0) { @@ -466,6 +450,13 @@ struct TextTool : ToolBase imageModel.CopyPrevious(); Text(m_hdc, rc.left, rc.top, rc.right, rc.bottom, m_fg, m_bg, szText, textEditWindow.GetFont(), style); + + if (selectionModel.m_rc.IsRectEmpty()) + { + textEditWindow.ShowWindow(SW_HIDE); + textEditWindow.SetWindowText(NULL); + return; + } } if (registrySettings.ShowTextTool) @@ -476,45 +467,35 @@ struct TextTool : ToolBase fontsDialog.ShowWindow(SW_SHOWNOACTIVATE); } - if (!bTextBoxShown || selectionModel.IsSrcRectSizeNonzero()) - { - RECT rc; - selectionModel.GetRect(&rc); + RECT rc = selectionModel.m_rc; - // Enlarge if tool small - INT cxMin = CX_MINTEXTEDIT, cyMin = CY_MINTEXTEDIT; - if (selectionModel.IsSrcRectSizeNonzero()) - { - if (rc.right - rc.left < cxMin) - rc.right = rc.left + cxMin; - if (rc.bottom - rc.top < cyMin) - rc.bottom = rc.top + cyMin; - } - else - { - SetRect(&rc, x, y, x + cxMin, y + cyMin); - } - - if (!textEditWindow.IsWindow()) - textEditWindow.Create(imageArea); - - textEditWindow.SetWindowText(NULL); - textEditWindow.ValidateEditRect(&rc); - textEditWindow.ShowWindow(SW_SHOWNOACTIVATE); - textEditWindow.SetFocus(); + // Enlarge if tool small + INT cxMin = CX_MINTEXTEDIT, cyMin = CY_MINTEXTEDIT; + if (selectionModel.m_rc.IsRectEmpty()) + { + SetRect(&rc, x, y, x + cxMin, y + cyMin); } else { - textEditWindow.ShowWindow(SW_HIDE); - textEditWindow.SetWindowText(NULL); + if (rc.right - rc.left < cxMin) + rc.right = rc.left + cxMin; + if (rc.bottom - rc.top < cyMin) + rc.bottom = rc.top + cyMin; } + + if (!textEditWindow.IsWindow()) + textEditWindow.Create(imageArea); + + textEditWindow.SetWindowText(NULL); + textEditWindow.ValidateEditRect(&rc); + textEditWindow.ShowWindow(SW_SHOWNOACTIVATE); + textEditWindow.SetFocus(); } void OnFinishDraw() { toolsModel.OnButtonDown(TRUE, -1, -1, TRUE); toolsModel.OnButtonUp(TRUE, -1, -1); - selectionWindow.IsMoved(FALSE); ToolBase::OnFinishDraw(); } }; diff --git a/base/applications/mspaint/palettemodel.cpp b/base/applications/mspaint/palettemodel.cpp index b4ae440658f..cf920bc43e0 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 (selectionWindow.IsWindow()) - selectionWindow.SendMessage(WM_PALETTEMODELCOLORCHANGED); + if (imageArea.IsWindow()) + imageArea.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 5dda7a9c682..ae4e584e229 100644 --- a/base/applications/mspaint/precomp.h +++ b/base/applications/mspaint/precomp.h @@ -43,7 +43,6 @@ #include "palette.h" #include "palettemodel.h" #include "registry.h" -#include "selection.h" #include "selectionmodel.h" #include "sizebox.h" #include "canvas.h" diff --git a/base/applications/mspaint/selection.cpp b/base/applications/mspaint/selection.cpp deleted file mode 100644 index 1426e086d59..00000000000 --- a/base/applications/mspaint/selection.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/* - * PROJECT: PAINT for ReactOS - * LICENSE: LGPL - * FILE: base/applications/mspaint/selection.cpp - * PURPOSE: Window procedure of the selection window - * PROGRAMMERS: Benedikt Freisen - * Katayama Hirofumi MZ - */ - -#include "precomp.h" - -CSelectionWindow selectionWindow; - -/* FUNCTIONS ********************************************************/ - -const LPCTSTR CSelectionWindow::m_lpszCursorLUT[9] = { /* action to mouse cursor lookup table */ - IDC_SIZEALL, - - IDC_SIZENWSE, IDC_SIZENS, IDC_SIZENESW, - IDC_SIZEWE, IDC_SIZEWE, - IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE -}; - -void CSelectionWindow::ForceRefreshSelectionContents() -{ - if (::IsWindowVisible(selectionWindow)) - { - imageModel.ResetToPrevious(); - imageModel.DrawSelectionBackground(m_rgbBack); - selectionModel.DrawSelection(imageModel.GetDC(), paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent()); - } -} - -int CSelectionWindow::IdentifyCorner(int iXPos, int iYPos, int iWidth, int iHeight) -{ - return 0; -} - -LRESULT CSelectionWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - PAINTSTRUCT ps; - HDC hDC = BeginPaint(&ps); - if (!m_bMoving) - { - RECT rcClient; - GetClientRect(&rcClient); - drawSizeBoxes(hDC, &rcClient, TRUE, &ps.rcPaint); - } - EndPaint(&ps); - return 0; -} - -LRESULT CSelectionWindow::OnEraseBkgnd(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - // do nothing => transparent background - return TRUE; -} - -LRESULT CSelectionWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - m_bMoving = FALSE; - m_iAction = ACTION_MOVE; - /* update the system selection color */ - Invalidate(); - return 0; -} - -LRESULT CSelectionWindow::OnSysColorChange(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - /* update the system selection color */ - Invalidate(); - return 0; -} - -LRESULT CSelectionWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - RECT rcClient; - GetClientRect(&rcClient); - - POINT pt; - ::GetCursorPos(&pt); - ScreenToClient(&pt); - - if (!setCursorOnSizeBox(getSizeBoxHitTest(pt, &rcClient))) - ::SetCursor(::LoadCursor(NULL, IDC_SIZEALL)); - - return 0; -} - -LRESULT CSelectionWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - m_ptPos.x = GET_X_LPARAM(lParam); - m_ptPos.y = GET_Y_LPARAM(lParam); - m_ptDelta.x = 0; - m_ptDelta.y = 0; - SetCapture(); - if (m_iAction != ACTION_MOVE) - SetCursor(LoadCursor(NULL, m_lpszCursorLUT[m_iAction])); - m_bMoving = TRUE; - imageArea.InvalidateRect(NULL, FALSE); - imageArea.SendMessage(WM_PAINT, 0, 0); - m_rgbBack = paletteModel.GetBgColor(); - return 0; -} - -LRESULT CSelectionWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - if (m_bMoving) - { - imageModel.ResetToPrevious(); - imageModel.DrawSelectionBackground(m_rgbBack); - m_ptFrac.x += GET_X_LPARAM(lParam) - m_ptPos.x; - m_ptFrac.y += GET_Y_LPARAM(lParam) - m_ptPos.y; - m_ptDelta.x += UnZoomed(m_ptFrac.x); - m_ptDelta.y += UnZoomed(m_ptFrac.y); - if (toolsModel.GetZoom() < 1000) - { - m_ptFrac.x = 0; - m_ptFrac.y = 0; - } - else - { - m_ptFrac.x -= Zoomed(UnZoomed(m_ptFrac.x)); - m_ptFrac.y -= Zoomed(UnZoomed(m_ptFrac.y)); - } - selectionModel.ModifyDestRect(m_ptDelta, m_iAction); - - CString strSize; - strSize.Format(_T("%ld x %ld"), selectionModel.GetDestRectWidth(), selectionModel.GetDestRectHeight()); - SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) (LPCTSTR) strSize); - - if (m_iAction != ACTION_MOVE) - selectionModel.DrawSelectionStretched(imageModel.GetDC()); - else - selectionModel.DrawSelection(imageModel.GetDC(), paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent()); - imageArea.InvalidateRect(NULL, FALSE); - imageArea.SendMessage(WM_PAINT, 0, 0); - m_ptPos.x = GET_X_LPARAM(lParam); - m_ptPos.y = GET_Y_LPARAM(lParam); - } - else - { - int w = Zoomed(selectionModel.GetDestRectWidth()) + 2 * GRIP_SIZE; - int h = Zoomed(selectionModel.GetDestRectHeight()) + 2 * GRIP_SIZE; - m_ptPos.x = GET_X_LPARAM(lParam); - m_ptPos.y = GET_Y_LPARAM(lParam); - SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) NULL); - m_iAction = IdentifyCorner(m_ptPos.x, m_ptPos.y, w, h); - if (m_iAction != ACTION_MOVE) - SetCursor(LoadCursor(NULL, m_lpszCursorLUT[m_iAction])); - } - return 0; -} - -LRESULT CSelectionWindow::OnMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - m_bMoved = TRUE; - return 0; -} - -LRESULT CSelectionWindow::OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - if (m_bMoving) - { - m_bMoving = FALSE; - ReleaseCapture(); - if (m_iAction != ACTION_MOVE && toolsModel.GetActiveTool() != TOOL_TEXT) - { - imageModel.Undo(); - imageModel.DrawSelectionBackground(m_rgbBack); - selectionModel.ScaleContentsToFit(); - imageModel.CopyPrevious(); - } - placeSelWin(); - } - return 0; -} - -LRESULT CSelectionWindow::OnCaptureChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - if (m_bMoving) - { - m_bMoving = FALSE; - if (m_iAction == ACTION_MOVE) - { - if (toolsModel.GetActiveTool() == TOOL_RECTSEL) - imageArea.cancelDrawing(); - else - placeSelWin(); - } - else - { - m_iAction = ACTION_MOVE; - } - ShowWindow(SW_HIDE); - } - return 0; -} - -LRESULT CSelectionWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - if (wParam == VK_ESCAPE) - { - if (GetCapture() == m_hWnd) - { - ReleaseCapture(); - } - } - return 0; -} - -LRESULT CSelectionWindow::OnPaletteModelColorChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - return 0; -} - -LRESULT CSelectionWindow::OnToolsModelSettingsChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - return 0; -} - -LRESULT CSelectionWindow::OnSelectionModelRefreshNeeded(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - ForceRefreshSelectionContents(); - return 0; -} - -LRESULT CSelectionWindow::OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - return ::SendMessage(GetParent(), nMsg, wParam, lParam); -} - -LRESULT CSelectionWindow::OnToolsModelZoomChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) -{ - placeSelWin(); - return 0; -} diff --git a/base/applications/mspaint/selection.h b/base/applications/mspaint/selection.h deleted file mode 100644 index 8e61b77d9ef..00000000000 --- a/base/applications/mspaint/selection.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * PROJECT: PAINT for ReactOS - * LICENSE: LGPL - * FILE: base/applications/mspaint/selection.h - * PURPOSE: Window procedure of the selection window - * PROGRAMMERS: Benedikt Freisen - * Katayama Hirofumi MZ - */ - -#pragma once - -class CSelectionWindow : public CWindowImpl -{ -public: - CSelectionWindow() : m_bMoved(FALSE) - { - } - - BOOL IsMoved() const { return m_bMoved; } - void IsMoved(BOOL bMoved) { m_bMoved = bMoved; } - - void ForceRefreshSelectionContents(); - - DECLARE_WND_CLASS_EX(_T("Selection"), CS_DBLCLKS, COLOR_BTNFACE) - - BEGIN_MSG_MAP(CSelectionWindow) - MESSAGE_HANDLER(WM_PAINT, OnPaint) - MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd) - MESSAGE_HANDLER(WM_CREATE, OnCreate) - MESSAGE_HANDLER(WM_SYSCOLORCHANGE, OnSysColorChange) - MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor) - MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) - MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove) - MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel) - MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp) - MESSAGE_HANDLER(WM_MOVE, OnMove) - MESSAGE_HANDLER(WM_PALETTEMODELCOLORCHANGED, OnPaletteModelColorChanged) - MESSAGE_HANDLER(WM_TOOLSMODELSETTINGSCHANGED, OnToolsModelSettingsChanged) - MESSAGE_HANDLER(WM_TOOLSMODELZOOMCHANGED, OnToolsModelZoomChanged) - MESSAGE_HANDLER(WM_SELECTIONMODELREFRESHNEEDED, OnSelectionModelRefreshNeeded) - MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged) - MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown) - END_MSG_MAP() - - LRESULT OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnEraseBkgnd(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnSysColorChange(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 OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnPaletteModelColorChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnToolsModelSettingsChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnToolsModelZoomChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnSelectionModelRefreshNeeded(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 OnMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - -private: - static const LPCTSTR m_lpszCursorLUT[9]; - BOOL m_bMoved; - BOOL m_bMoving; - int m_iAction; - POINT m_ptPos; - POINT m_ptFrac; - POINT m_ptDelta; - COLORREF m_rgbBack; - - int IdentifyCorner(int iXPos, int iYPos, int iWidth, int iHeight); -}; - -void ForceRefreshSelectionContents(); diff --git a/base/applications/mspaint/selectionmodel.cpp b/base/applications/mspaint/selectionmodel.cpp index 2079f7afd9b..f7c61d16c28 100644 --- a/base/applications/mspaint/selectionmodel.cpp +++ b/base/applications/mspaint/selectionmodel.cpp @@ -14,225 +14,295 @@ SelectionModel selectionModel; /* FUNCTIONS ********************************************************/ SelectionModel::SelectionModel() - : m_hDC(CreateCompatibleDC(NULL)) - , m_hBm(NULL) - , m_hMask(NULL) + : m_hbmColor(NULL) + , m_hbmMask(NULL) , m_ptStack(NULL) , m_iPtSP(0) + , m_bShow(FALSE) { - SetRectEmpty(&m_rcSrc); - SetRectEmpty(&m_rcDest); + ::SetRectEmpty(&m_rc); + m_ptHit.x = m_ptHit.y = -1; } SelectionModel::~SelectionModel() { - DeleteDC(m_hDC); + ClearColor(); + ClearMask(); ResetPtStack(); - if (m_hBm) - { - DeleteObject(m_hBm); - } - if (m_hMask) - { - DeleteObject(m_hMask); - } } void SelectionModel::ResetPtStack() { - if (m_ptStack != NULL) - HeapFree(GetProcessHeap(), 0, m_ptStack); - m_ptStack = NULL; + if (m_ptStack) + { + free(m_ptStack); + m_ptStack = NULL; + } m_iPtSP = 0; } -void SelectionModel::PushToPtStack(LONG x, LONG y) +void SelectionModel::PushToPtStack(POINT pt) { - if (m_iPtSP % 1024 == 0) +#define GROW_COUNT 256 + if (m_iPtSP % GROW_COUNT == 0) { - if (m_ptStack) - m_ptStack = (POINT*) HeapReAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, m_ptStack, sizeof(POINT) * (m_iPtSP + 1024)); - else - m_ptStack = (POINT*) HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(POINT) * 1024); + INT nNewCount = m_iPtSP + GROW_COUNT; + LPPOINT pptNew = (LPPOINT)realloc(m_ptStack, sizeof(POINT) * nNewCount); + if (pptNew == NULL) + return; + m_ptStack = pptNew; } - m_ptStack[m_iPtSP].x = x; - m_ptStack[m_iPtSP].y = y; + m_ptStack[m_iPtSP] = pt; m_iPtSP++; +#undef GROW_COUNT } -void SelectionModel::CalculateBoundingBoxAndContents(HDC hDCImage) +void SelectionModel::ShiftPtStack(BOOL bPlus) { - int i; - m_rcSrc.left = m_rcSrc.top = MAXLONG; - m_rcSrc.right = m_rcSrc.bottom = 0; - for (i = 0; i < m_iPtSP; i++) + if (bPlus) { - if (m_ptStack[i].x < m_rcSrc.left) - m_rcSrc.left = m_ptStack[i].x; - if (m_ptStack[i].y < m_rcSrc.top) - m_rcSrc.top = m_ptStack[i].y; - if (m_ptStack[i].x > m_rcSrc.right) - m_rcSrc.right = m_ptStack[i].x; - if (m_ptStack[i].y > m_rcSrc.bottom) - m_rcSrc.bottom = m_ptStack[i].y; + for (INT i = 0; i < m_iPtSP; ++i) + { + POINT& pt = m_ptStack[i]; + pt.x += m_rc.left; + pt.y += m_rc.top; + } } - m_rcSrc.right += 1; - m_rcSrc.bottom += 1; - m_rcDest.left = m_rcSrc.left; - m_rcDest.top = m_rcSrc.top; - m_rcDest.right = m_rcSrc.right; - m_rcDest.bottom = m_rcSrc.bottom; - - if (m_iPtSP > 1) + else { - DeleteObject(m_hMask); - m_hMask = CreateBitmap(RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc), 1, 1, NULL); - DeleteObject(SelectObject(m_hDC, m_hMask)); - POINT *m_ptStackCopy = (POINT*) HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(POINT) * m_iPtSP); - for (i = 0; i < m_iPtSP; i++) + for (INT i = 0; i < m_iPtSP; ++i) { - m_ptStackCopy[i].x = m_ptStack[i].x - m_rcSrc.left; - m_ptStackCopy[i].y = m_ptStack[i].y - m_rcSrc.top; + POINT& pt = m_ptStack[i]; + pt.x -= m_rc.left; + pt.y -= m_rc.top; } - Poly(m_hDC, m_ptStackCopy, m_iPtSP, 0x00ffffff, 0x00ffffff, 1, 2, TRUE, FALSE); - HeapFree(GetProcessHeap(), 0, m_ptStackCopy); - SelectObject(m_hDC, m_hBm = CreateDIBWithProperties(RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc))); - imageModel.ResetToPrevious(); - MaskBlt(m_hDC, 0, 0, RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc), hDCImage, m_rcSrc.left, - m_rcSrc.top, m_hMask, 0, 0, MAKEROP4(SRCCOPY, WHITENESS)); } } -void SelectionModel::CalculateContents(HDC hDCImage) +void SelectionModel::BuildMaskFromPtStack() { - DeleteObject(m_hMask); - m_hMask = CreateBitmap(RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc), 1, 1, NULL); - DeleteObject(SelectObject(m_hDC, m_hMask)); - Rect(m_hDC, 0, 0, RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc), 0x00ffffff, 0x00ffffff, 1, 2); - SelectObject(m_hDC, m_hBm = CreateDIBWithProperties(RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc))); - BitBlt(m_hDC, 0, 0, RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc), hDCImage, m_rcSrc.left, - m_rcSrc.top, SRCCOPY); + CRect rc = { MAXLONG, MAXLONG, 0, 0 }; + for (INT i = 0; i < m_iPtSP; ++i) + { + POINT& pt = m_ptStack[i]; + rc.left = min(pt.x, rc.left); + rc.top = min(pt.y, rc.top); + rc.right = max(pt.x, rc.right); + rc.bottom = max(pt.y, rc.bottom); + } + rc.right += 1; + rc.bottom += 1; + + m_rc = rc; + + ShiftPtStack(FALSE); + + ClearMask(); + + HDC hdcMem = ::CreateCompatibleDC(NULL); + m_hbmMask = ::CreateBitmap(rc.Width(), rc.Height(), 1, 1, NULL); + HGDIOBJ hbmOld = ::SelectObject(hdcMem, m_hbmMask); + FillRect(hdcMem, &rc, (HBRUSH)::GetStockObject(BLACK_BRUSH)); + HGDIOBJ hPenOld = ::SelectObject(hdcMem, GetStockObject(NULL_PEN)); + HGDIOBJ hbrOld = ::SelectObject(hdcMem, GetStockObject(WHITE_BRUSH)); + ::Polygon(hdcMem, m_ptStack, m_iPtSP); + ::SelectObject(hdcMem, hbrOld); + ::SelectObject(hdcMem, hPenOld); + ::SelectObject(hdcMem, hbmOld); + ::DeleteDC(hdcMem); } void SelectionModel::DrawBackgroundPoly(HDC hDCImage, COLORREF crBg) { - Poly(hDCImage, m_ptStack, m_iPtSP, crBg, crBg, 1, 2, TRUE, FALSE); + ShiftPtStack(TRUE); + + HGDIOBJ hPenOld = ::SelectObject(hDCImage, ::GetStockObject(NULL_PEN)); + HGDIOBJ hbrOld = ::SelectObject(hDCImage, ::CreateSolidBrush(crBg)); + ::Polygon(hDCImage, m_ptStack, m_iPtSP); + ::DeleteObject(::SelectObject(hDCImage, hbrOld)); + ::SelectObject(hDCImage, hPenOld); + + ShiftPtStack(FALSE); } void SelectionModel::DrawBackgroundRect(HDC hDCImage, COLORREF crBg) { - Rect(hDCImage, m_rcSrc.left, m_rcSrc.top, m_rcSrc.right, m_rcSrc.bottom, crBg, crBg, 0, 1); + Rect(hDCImage, m_rc.left, m_rc.top, m_rc.right, m_rc.bottom, crBg, crBg, 0, 1); } -void SelectionModel::DrawSelection(HDC hDCImage, COLORREF crBg, BOOL bBgTransparent) +void SelectionModel::DrawSelection(HDC hDCImage, LPCRECT prc, COLORREF crBg, BOOL bBgTransparent) { - if (!bBgTransparent) - MaskBlt(hDCImage, m_rcDest.left, m_rcDest.top, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), - m_hDC, 0, 0, m_hMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND)); - else - ColorKeyedMaskBlt(hDCImage, m_rcDest.left, m_rcDest.top, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), - m_hDC, 0, 0, m_hMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND), crBg); + CRect rc = *prc; + if (::IsRectEmpty(&rc)) + return; + + BITMAP bm; + GetObject(m_hbmColor, sizeof(BITMAP), &bm); + + COLORREF keyColor = (bBgTransparent ? crBg : CLR_INVALID); + + HDC hMemDC = CreateCompatibleDC(hDCImage); + HGDIOBJ hbmOld = SelectObject(hMemDC, m_hbmColor); + ColorKeyedMaskBlt(hDCImage, rc.left, rc.top, rc.Width(), rc.Height(), + hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, m_hbmMask, keyColor); + SelectObject(hMemDC, hbmOld); + DeleteDC(hMemDC); +} + +void SelectionModel::GetSelectionContents(HDC hDCImage) +{ + ClearColor(); + + HDC hMemDC = ::CreateCompatibleDC(NULL); + m_hbmColor = CreateColorDIB(m_rc.Width(), m_rc.Height(), RGB(255, 255, 255)); + HGDIOBJ hbmOld = ::SelectObject(hMemDC, m_hbmColor); + ::BitBlt(hMemDC, 0, 0, m_rc.Width(), m_rc.Height(), hDCImage, m_rc.left, m_rc.top, SRCCOPY); + ::SelectObject(hMemDC, hbmOld); + ::DeleteDC(hMemDC); } -void SelectionModel::DrawSelectionStretched(HDC hDCImage) +BOOL SelectionModel::TakeOff() { - StretchBlt(hDCImage, m_rcDest.left, m_rcDest.top, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), m_hDC, 0, 0, GetDIBWidth(m_hBm), GetDIBHeight(m_hBm), SRCCOPY); + if (m_hbmColor || ::IsRectEmpty(&m_rc)) + return FALSE; + + HDC hDCImage = imageModel.GetDC(); + GetSelectionContents(hDCImage); + + if (toolsModel.GetActiveTool() == TOOL_FREESEL) + { + DrawBackgroundPoly(hDCImage, paletteModel.GetBgColor()); + } + else + { + ClearMask(); + DrawBackgroundRect(hDCImage, paletteModel.GetBgColor()); + } + + imageArea.Invalidate(FALSE); + return TRUE; } -void SelectionModel::ScaleContentsToFit() +void SelectionModel::Landing() { - HDC hTempDC; - HBITMAP hTempBm; - hTempDC = CreateCompatibleDC(m_hDC); - hTempBm = CreateDIBWithProperties(RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest)); - SelectObject(hTempDC, hTempBm); - SelectObject(m_hDC, m_hBm); - StretchBlt(hTempDC, 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), m_hDC, 0, 0, - GetDIBWidth(m_hBm), GetDIBHeight(m_hBm), SRCCOPY); - DeleteObject(m_hBm); - m_hBm = hTempBm; - hTempBm = CreateBitmap(RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), 1, 1, NULL); - SelectObject(hTempDC, hTempBm); - SelectObject(m_hDC, m_hMask); - StretchBlt(hTempDC, 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), m_hDC, 0, 0, - GetDIBWidth(m_hMask), GetDIBHeight(m_hMask), SRCCOPY); - DeleteObject(m_hMask); - m_hMask = hTempBm; - SelectObject(m_hDC, m_hBm); - DeleteDC(hTempDC); + if (!m_hbmColor) + return; + + DrawSelection(imageModel.GetDC(), &m_rc, paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent()); + + ::SetRectEmpty(&m_rc); + ClearMask(); + ClearColor(); + + imageModel.CopyPrevious(); } void SelectionModel::InsertFromHBITMAP(HBITMAP hBm, INT x, INT y) { - HDC hTempDC; - HBITMAP hTempMask; - - m_hBm = CopyDIBImage(hBm); - DeleteObject(SelectObject(m_hDC, m_hBm)); - - SetRectEmpty(&m_rcSrc); - m_rcDest.left = x; - m_rcDest.top = y; - m_rcDest.right = m_rcDest.left + GetDIBWidth(m_hBm); - m_rcDest.bottom = m_rcDest.top + GetDIBHeight(m_hBm); - - hTempDC = CreateCompatibleDC(m_hDC); - hTempMask = CreateBitmap(RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), 1, 1, NULL); - SelectObject(hTempDC, hTempMask); - Rect(hTempDC, 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), 0x00ffffff, 0x00ffffff, 1, 1); - DeleteObject(m_hMask); - m_hMask = hTempMask; - DeleteDC(hTempDC); + m_hbmColor = CopyDIBImage(hBm); + ::DeleteObject(m_hbmColor); + + m_rc.left = x; + m_rc.top = y; + m_rc.right = m_rc.left + GetDIBWidth(hBm); + m_rc.bottom = m_rc.top + GetDIBHeight(hBm); + + ClearMask(); } void SelectionModel::FlipHorizontally() { - SelectObject(m_hDC, m_hMask); - StretchBlt(m_hDC, RECT_WIDTH(m_rcDest) - 1, 0, -RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), m_hDC, - 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), SRCCOPY); - SelectObject(m_hDC, m_hBm); - StretchBlt(m_hDC, RECT_WIDTH(m_rcDest) - 1, 0, -RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), m_hDC, - 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), SRCCOPY); + TakeOff(); + + HDC hdcMem = ::CreateCompatibleDC(NULL); + if (m_hbmMask) + { + ::SelectObject(hdcMem, m_hbmMask); + ::StretchBlt(hdcMem, m_rc.Width() - 1, 0, -m_rc.Width(), m_rc.Height(), + hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY); + } + if (m_hbmColor) + { + ::SelectObject(hdcMem, m_hbmColor); + ::StretchBlt(hdcMem, m_rc.Width() - 1, 0, -m_rc.Width(), m_rc.Height(), + hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY); + } + ::DeleteDC(hdcMem); + NotifyRefreshNeeded(); } void SelectionModel::FlipVertically() { - SelectObject(m_hDC, m_hMask); - StretchBlt(m_hDC, 0, RECT_HEIGHT(m_rcDest) - 1, RECT_WIDTH(m_rcDest), -RECT_HEIGHT(m_rcDest), m_hDC, - 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), SRCCOPY); - SelectObject(m_hDC, m_hBm); - StretchBlt(m_hDC, 0, RECT_HEIGHT(m_rcDest) - 1, RECT_WIDTH(m_rcDest), -RECT_HEIGHT(m_rcDest), m_hDC, - 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), SRCCOPY); + TakeOff(); + + HDC hdcMem = ::CreateCompatibleDC(NULL); + if (m_hbmMask) + { + ::SelectObject(hdcMem, m_hbmMask); + ::StretchBlt(hdcMem, 0, m_rc.Height() - 1, m_rc.Width(), -m_rc.Height(), + hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY); + } + if (m_hbmColor) + { + ::SelectObject(hdcMem, m_hbmColor); + ::StretchBlt(hdcMem, 0, m_rc.Height() - 1, m_rc.Width(), -m_rc.Height(), + hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY); + } + ::DeleteDC(hdcMem); + NotifyRefreshNeeded(); } void SelectionModel::RotateNTimes90Degrees(int iN) { HBITMAP hbm; + HGDIOBJ hbmOld; + HDC hdcMem = ::CreateCompatibleDC(NULL); + switch (iN) { - case 1: - case 3: - imageModel.DeleteSelection(); - imageModel.CopyPrevious(); - SelectObject(m_hDC, m_hBm); - hbm = Rotate90DegreeBlt(m_hDC, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), iN == 1); - InsertFromHBITMAP(hbm, m_rcDest.left, m_rcDest.top); - DeleteObject(hbm); - selectionWindow.ShowWindow(SW_SHOWNOACTIVATE); - selectionWindow.ForceRefreshSelectionContents(); - placeSelWin(); - break; - case 2: - SelectObject(m_hDC, m_hMask); - StretchBlt(m_hDC, RECT_WIDTH(m_rcDest) - 1, RECT_HEIGHT(m_rcDest) - 1, -RECT_WIDTH(m_rcDest), -RECT_HEIGHT(m_rcDest), m_hDC, - 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), SRCCOPY); - SelectObject(m_hDC, m_hBm); - StretchBlt(m_hDC, RECT_WIDTH(m_rcDest) - 1, RECT_HEIGHT(m_rcDest) - 1, -RECT_WIDTH(m_rcDest), -RECT_HEIGHT(m_rcDest), m_hDC, - 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), SRCCOPY); - break; + case 1: + case 3: + TakeOff(); + if (m_hbmColor) + { + hbmOld = ::SelectObject(hdcMem, m_hbmColor); + hbm = Rotate90DegreeBlt(hdcMem, m_rc.Width(), m_rc.Height(), iN == 1, FALSE); + ::SelectObject(hdcMem, hbmOld); + ::DeleteObject(m_hbmColor); + m_hbmColor = hbm; + } + if (m_hbmMask) + { + hbmOld = ::SelectObject(hdcMem, m_hbmMask); + hbm = Rotate90DegreeBlt(hdcMem, m_rc.Width(), m_rc.Height(), iN == 1, TRUE); + ::SelectObject(hdcMem, hbmOld); + ::DeleteObject(m_hbmMask); + m_hbmMask = hbm; + } + break; + + case 2: + TakeOff(); + if (m_hbmColor) + { + hbmOld = ::SelectObject(hdcMem, m_hbmColor); + ::StretchBlt(hdcMem, m_rc.Width() - 1, m_rc.Height() - 1, -m_rc.Width(), -m_rc.Height(), + hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY); + ::SelectObject(hdcMem, hbmOld); + } + if (m_hbmMask) + { + hbmOld = ::SelectObject(hdcMem, m_hbmMask); + ::StretchBlt(hdcMem, m_rc.Width() - 1, m_rc.Height() - 1, -m_rc.Width(), -m_rc.Height(), + hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY); + ::SelectObject(hdcMem, hbmOld); + } + break; } + + ::DeleteDC(hdcMem); NotifyRefreshNeeded(); } @@ -241,47 +311,47 @@ void SelectionModel::StretchSkew(int nStretchPercentX, int nStretchPercentY, int if (nStretchPercentX == 100 && nStretchPercentY == 100 && nSkewDegX == 0 && nSkewDegY == 0) return; - imageModel.DeleteSelection(); - imageModel.CopyPrevious(); + TakeOff(); - INT oldWidth = RECT_WIDTH(m_rcDest); - INT oldHeight = RECT_HEIGHT(m_rcDest); + INT oldWidth = m_rc.Width(); + INT oldHeight = m_rc.Height(); INT newWidth = oldWidth * nStretchPercentX / 100; INT newHeight = oldHeight * nStretchPercentY / 100; if (oldWidth != newWidth || oldHeight != newHeight) { - SelectObject(m_hDC, m_hBm); - HBITMAP hbm0 = CopyDIBImage(m_hBm, newWidth, newHeight); - InsertFromHBITMAP(hbm0, m_rcDest.left, m_rcDest.top); - DeleteObject(hbm0); + HBITMAP hbm0 = CopyDIBImage(m_hbmColor, newWidth, newHeight); + InsertFromHBITMAP(hbm0, m_rc.left, m_rc.top); + ::DeleteObject(hbm0); } + HDC hDC = ::CreateCompatibleDC(NULL); + if (nSkewDegX) { - SelectObject(m_hDC, m_hBm); - HBITMAP hbm1 = SkewDIB(m_hDC, m_hBm, nSkewDegX, FALSE); - InsertFromHBITMAP(hbm1, m_rcDest.left, m_rcDest.top); - DeleteObject(hbm1); + ::SelectObject(hDC, m_hbmColor); + HBITMAP hbm1 = SkewDIB(hDC, m_hbmColor, nSkewDegX, FALSE); + InsertFromHBITMAP(hbm1, m_rc.left, m_rc.top); + ::DeleteObject(hbm1); } if (nSkewDegY) { - SelectObject(m_hDC, m_hBm); - HBITMAP hbm2 = SkewDIB(m_hDC, m_hBm, nSkewDegY, TRUE); - InsertFromHBITMAP(hbm2, m_rcDest.left, m_rcDest.top); - DeleteObject(hbm2); + ::SelectObject(hDC, m_hbmColor); + HBITMAP hbm2 = SkewDIB(hDC, m_hbmColor, nSkewDegY, TRUE); + InsertFromHBITMAP(hbm2, m_rc.left, m_rc.top); + ::DeleteObject(hbm2); } - selectionWindow.ShowWindow(SW_SHOWNOACTIVATE); - selectionWindow.ForceRefreshSelectionContents(); - placeSelWin(); + ::DeleteDC(hDC); + + m_bShow = TRUE; NotifyRefreshNeeded(); } HBITMAP SelectionModel::GetBitmap() const { - return m_hBm; + return m_hbmColor; } int SelectionModel::PtStackSize() const @@ -291,114 +361,92 @@ int SelectionModel::PtStackSize() const void SelectionModel::DrawFramePoly(HDC hDCImage) { - Poly(hDCImage, m_ptStack, m_iPtSP, 0, 0, 2, 0, FALSE, TRUE); /* draw the freehand selection inverted/xored */ -} - -void SelectionModel::SetSrcAndDestRectFromPoints(const POINT& ptFrom, const POINT& ptTo) -{ - m_rcDest.left = m_rcSrc.left = min(ptFrom.x, ptTo.x); - m_rcDest.top = m_rcSrc.top = min(ptFrom.y, ptTo.y); - m_rcDest.right = m_rcSrc.right = max(ptFrom.x, ptTo.x); - m_rcDest.bottom = m_rcSrc.bottom = max(ptFrom.y, ptTo.y); -} - -void SelectionModel::SetSrcRectSizeToZero() -{ - m_rcSrc.right = m_rcSrc.left; - m_rcSrc.bottom = m_rcSrc.top; + /* draw the freehand selection inverted/xored */ + Poly(hDCImage, m_ptStack, m_iPtSP, 0, 0, 2, 0, FALSE, TRUE); } -BOOL SelectionModel::IsSrcRectSizeNonzero() const +void SelectionModel::SetRectFromPoints(const POINT& ptFrom, const POINT& ptTo) { - return (RECT_WIDTH(m_rcSrc) != 0) && (RECT_HEIGHT(m_rcSrc) != 0); + m_rc.left = min(ptFrom.x, ptTo.x); + m_rc.top = min(ptFrom.y, ptTo.y); + m_rc.right = max(ptFrom.x, ptTo.x); + m_rc.bottom = max(ptFrom.y, ptTo.y); } -void SelectionModel::ModifyDestRect(POINT& ptDelta, int iAction) +void SelectionModel::Dragging(CANVAS_HITTEST hit, POINT pt) { - POINT ptDeltaUsed; - - switch (iAction) + switch (hit) { - case ACTION_MOVE: /* move selection */ - ptDeltaUsed.x = ptDelta.x; - ptDeltaUsed.y = ptDelta.y; - OffsetRect(&m_rcDest, ptDeltaUsed.x, ptDeltaUsed.y); + case HIT_NONE: + break; + case HIT_UPPER_LEFT: + m_rc.left += pt.x - m_ptHit.x; + m_rc.top += pt.y - m_ptHit.y; break; - case ACTION_RESIZE_TOP_LEFT: /* resize at upper left corner */ - ptDeltaUsed.x = min(ptDelta.x, RECT_WIDTH(m_rcDest) - 1); - ptDeltaUsed.y = min(ptDelta.y, RECT_HEIGHT(m_rcDest) - 1); - m_rcDest.left += ptDeltaUsed.x; - m_rcDest.top += ptDeltaUsed.y; + case HIT_UPPER_CENTER: + m_rc.top += pt.y - m_ptHit.y; break; - case ACTION_RESIZE_TOP: /* resize at top edge */ - ptDeltaUsed.x = ptDelta.x; - ptDeltaUsed.y = min(ptDelta.y, RECT_HEIGHT(m_rcDest) - 1); - m_rcDest.top += ptDeltaUsed.y; + case HIT_UPPER_RIGHT: + m_rc.right += pt.x - m_ptHit.x; + m_rc.top += pt.y - m_ptHit.y; break; - case ACTION_RESIZE_TOP_RIGHT: /* resize at upper right corner */ - ptDeltaUsed.x = max(ptDelta.x, -(RECT_WIDTH(m_rcDest) - 1)); - ptDeltaUsed.y = min(ptDelta.y, RECT_HEIGHT(m_rcDest) - 1); - m_rcDest.top += ptDeltaUsed.y; - m_rcDest.right += ptDeltaUsed.x; + case HIT_MIDDLE_LEFT: + m_rc.left += pt.x - m_ptHit.x; break; - case ACTION_RESIZE_LEFT: /* resize at left edge */ - ptDeltaUsed.x = min(ptDelta.x, RECT_WIDTH(m_rcDest) - 1); - ptDeltaUsed.y = ptDelta.y; - m_rcDest.left += ptDeltaUsed.x; + case HIT_MIDDLE_RIGHT: + m_rc.right += pt.x - m_ptHit.x; break; - case ACTION_RESIZE_RIGHT: /* resize at right edge */ - ptDeltaUsed.x = max(ptDelta.x, -(RECT_WIDTH(m_rcDest) - 1)); - ptDeltaUsed.y = ptDelta.y; - m_rcDest.right += ptDeltaUsed.x; + case HIT_LOWER_LEFT: + m_rc.left += pt.x - m_ptHit.x; + m_rc.bottom += pt.y - m_ptHit.y; break; - case ACTION_RESIZE_BOTTOM_LEFT: /* resize at lower left corner */ - ptDeltaUsed.x = min(ptDelta.x, RECT_WIDTH(m_rcDest) - 1); - ptDeltaUsed.y = max(ptDelta.y, -(RECT_HEIGHT(m_rcDest) - 1)); - m_rcDest.left += ptDeltaUsed.x; - m_rcDest.bottom += ptDeltaUsed.y; + case HIT_LOWER_CENTER: + m_rc.bottom += pt.y - m_ptHit.y; break; - case ACTION_RESIZE_BOTTOM: /* resize at bottom edge */ - ptDeltaUsed.x = ptDelta.x; - ptDeltaUsed.y = max(ptDelta.y, -(RECT_HEIGHT(m_rcDest) - 1)); - m_rcDest.bottom += ptDeltaUsed.y; + case HIT_LOWER_RIGHT: + m_rc.right += pt.x - m_ptHit.x; + m_rc.bottom += pt.y - m_ptHit.y; break; - case ACTION_RESIZE_BOTTOM_RIGHT: /* resize at lower right corner */ - ptDeltaUsed.x = max(ptDelta.x, -(RECT_WIDTH(m_rcDest) - 1)); - ptDeltaUsed.y = max(ptDelta.y, -(RECT_HEIGHT(m_rcDest) - 1)); - m_rcDest.right += ptDeltaUsed.x; - m_rcDest.bottom += ptDeltaUsed.y; + case HIT_BORDER: + case HIT_INNER: + OffsetRect(&m_rc, pt.x - m_ptHit.x, pt.y - m_ptHit.y); break; } - ptDelta.x -= ptDeltaUsed.x; - ptDelta.y -= ptDeltaUsed.y; + m_ptHit = pt; } -LONG SelectionModel::GetDestRectWidth() const +void SelectionModel::NotifyRefreshNeeded() { - return m_rcDest.right - m_rcDest.left; + imageArea.Invalidate(FALSE); } -LONG SelectionModel::GetDestRectHeight() const +void SelectionModel::ClearMask() { - return m_rcDest.bottom - m_rcDest.top; + if (m_hbmMask) + { + ::DeleteObject(m_hbmMask); + m_hbmMask = NULL; + } } -LONG SelectionModel::GetDestRectLeft() const +void SelectionModel::ClearColor() { - return m_rcDest.left; + if (m_hbmColor) + { + ::DeleteObject(m_hbmColor); + m_hbmColor = NULL; + } } -LONG SelectionModel::GetDestRectTop() const +void SelectionModel::CancelSelection() { - return m_rcDest.top; -} + if (!m_bShow) + return; -void SelectionModel::NotifyRefreshNeeded() -{ - selectionWindow.SendMessage(WM_SELECTIONMODELREFRESHNEEDED); -} + imageModel.CopyPrevious(); + if (m_bShow) + imageModel.Undo(TRUE); -void SelectionModel::GetRect(LPRECT prc) const -{ - *prc = m_rcDest; + m_bShow = FALSE; + imageArea.Invalidate(FALSE); } diff --git a/base/applications/mspaint/selectionmodel.h b/base/applications/mspaint/selectionmodel.h index fbb208fed4b..fc1420de7fd 100644 --- a/base/applications/mspaint/selectionmodel.h +++ b/base/applications/mspaint/selectionmodel.h @@ -9,66 +9,54 @@ #pragma once -/* DEFINES **********************************************************/ - -#define ACTION_MOVE 0 -#define ACTION_RESIZE_TOP_LEFT 1 -#define ACTION_RESIZE_TOP 2 -#define ACTION_RESIZE_TOP_RIGHT 3 -#define ACTION_RESIZE_LEFT 4 -#define ACTION_RESIZE_RIGHT 5 -#define ACTION_RESIZE_BOTTOM_LEFT 6 -#define ACTION_RESIZE_BOTTOM 7 -#define ACTION_RESIZE_BOTTOM_RIGHT 8 - -/* CLASSES **********************************************************/ - class SelectionModel { private: - HDC m_hDC; - RECT m_rcSrc; - RECT m_rcDest; - HBITMAP m_hBm; - HBITMAP m_hMask; + HBITMAP m_hbmColor; + HBITMAP m_hbmMask; POINT *m_ptStack; int m_iPtSP; -// void NotifySelectionChanging(); -// void NotifySelectionChanged(); - void NotifyRefreshNeeded(); - public: + BOOL m_bShow; + CRect m_rc; // in image pixel coordinates + POINT m_ptHit; // in image pixel coordinates + SelectionModel(); ~SelectionModel(); + void ResetPtStack(); - void PushToPtStack(LONG x, LONG y); - void CalculateBoundingBoxAndContents(HDC hDCImage); - void CalculateContents(HDC hDCImage); + void PushToPtStack(POINT pt); + int PtStackSize() const; + void SetRectFromPoints(const POINT& ptFrom, const POINT& ptTo); + void BuildMaskFromPtStack(); + + BOOL TakeOff(); + void Landing(); + + HBITMAP GetBitmap() const; + void GetSelectionContents(HDC hDCImage); + void DrawFramePoly(HDC hDCImage); void DrawBackgroundPoly(HDC hDCImage, COLORREF crBg); void DrawBackgroundRect(HDC hDCImage, COLORREF crBg); - void DrawSelection(HDC hDCImage, COLORREF crBg = 0, BOOL bBgTransparent = FALSE); - void DrawSelectionStretched(HDC hDCImage); - void ScaleContentsToFit(); + void DrawSelection(HDC hDCImage, LPCRECT prc, COLORREF crBg = 0, BOOL bBgTransparent = FALSE); void InsertFromHBITMAP(HBITMAP hBm, INT x = 0, INT y = 0); + + // operation void FlipHorizontally(); void FlipVertically(); void RotateNTimes90Degrees(int iN); - void StretchSkew(int nStretchPercentX, int nStretchPercentY, int nSkewDegX = 0, int nSkewDegY = 0); - HBITMAP GetBitmap() const; - int PtStackSize() const; - void DrawFramePoly(HDC hDCImage); - void SetSrcAndDestRectFromPoints(const POINT& ptFrom, const POINT& ptTo); - void SetSrcRectSizeToZero(); - BOOL IsSrcRectSizeNonzero() const; - void ModifyDestRect(POINT& ptDelta, int iAction); - LONG GetDestRectWidth() const; - LONG GetDestRectHeight() const; - LONG GetDestRectLeft() const; - LONG GetDestRectTop() const; - void GetRect(LPRECT prc) const; + 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(); private: SelectionModel(const SelectionModel&); SelectionModel& operator=(const SelectionModel&); + + void ShiftPtStack(BOOL bPlus); }; diff --git a/base/applications/mspaint/toolbox.cpp b/base/applications/mspaint/toolbox.cpp index 6ba23375ebb..64f90f9c807 100644 --- a/base/applications/mspaint/toolbox.cpp +++ b/base/applications/mspaint/toolbox.cpp @@ -114,7 +114,7 @@ LRESULT CToolBox::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHand LRESULT CToolBox::OnToolsModelToolChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { - selectionWindow.ShowWindow(SW_HIDE); + selectionModel.m_bShow = FALSE; toolsModel.resetTool(); // resets the point-buffer of the polygon and bezier functions // Check the toolbar button diff --git a/base/applications/mspaint/toolsmodel.cpp b/base/applications/mspaint/toolsmodel.cpp index 34341635554..5f07ddf6132 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 (selectionWindow.IsWindow()) - selectionWindow.ForceRefreshSelectionContents(); + if (imageArea.IsWindow()) + imageArea.Invalidate(FALSE); } int ToolsModel::GetZoom() const @@ -172,8 +172,6 @@ void ToolsModel::NotifyToolSettingsChanged() { if (toolSettingsWindow.IsWindow()) toolSettingsWindow.SendMessage(WM_TOOLSMODELSETTINGSCHANGED); - if (selectionWindow.IsWindow()) - selectionWindow.SendMessage(WM_TOOLSMODELSETTINGSCHANGED); if (textEditWindow.IsWindow()) textEditWindow.SendMessage(WM_TOOLSMODELSETTINGSCHANGED); } @@ -184,8 +182,8 @@ void ToolsModel::NotifyZoomChanged() toolSettingsWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED); if (textEditWindow.IsWindow()) textEditWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED); - if (selectionWindow.IsWindow()) - selectionWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED); + if (imageArea.IsWindow()) + imageArea.SendMessage(WM_TOOLSMODELZOOMCHANGED); } void ToolsModel::OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) diff --git a/base/applications/mspaint/toolsmodel.h b/base/applications/mspaint/toolsmodel.h index c7fc2302415..da0e06cfa2f 100644 --- a/base/applications/mspaint/toolsmodel.h +++ b/base/applications/mspaint/toolsmodel.h @@ -132,3 +132,31 @@ static inline int UnZoomed(int xy) { return xy * 1000 / toolsModel.GetZoom(); } + +static inline void Zoomed(POINT& pt) +{ + pt.x = Zoomed(pt.x); + pt.y = Zoomed(pt.y); +} + +static inline void Zoomed(RECT& rc) +{ + rc.left = Zoomed(rc.left); + rc.top = Zoomed(rc.top); + rc.right = Zoomed(rc.right); + rc.bottom = Zoomed(rc.bottom); +} + +static inline void UnZoomed(POINT& pt) +{ + pt.x = UnZoomed(pt.x); + pt.y = UnZoomed(pt.y); +} + +static inline void UnZoomed(RECT& rc) +{ + rc.left = UnZoomed(rc.left); + rc.top = UnZoomed(rc.top); + rc.right = UnZoomed(rc.right); + rc.bottom = UnZoomed(rc.bottom); +} diff --git a/base/applications/mspaint/winproc.cpp b/base/applications/mspaint/winproc.cpp index ee09d6fba99..b44534a8043 100644 --- a/base/applications/mspaint/winproc.cpp +++ b/base/applications/mspaint/winproc.cpp @@ -182,11 +182,9 @@ void CMainWindow::InsertSelectionFromHBITMAP(HBITMAP bitmap, HWND window) toolBoxContainer.SendMessage(WM_COMMAND, ID_RECTSEL); imageModel.CopyPrevious(); - selectionModel.InsertFromHBITMAP(bitmap); - - placeSelWin(); - selectionWindow.ShowWindow(SW_SHOW); - selectionWindow.ForceRefreshSelectionContents(); + selectionModel.InsertFromHBITMAP(bitmap, 0, 0); + selectionModel.m_bShow = TRUE; + imageArea.Invalidate(FALSE); } LRESULT CMainWindow::OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) @@ -279,9 +277,6 @@ LRESULT CMainWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHa // Creating the window inside the canvas imageArea.Create(canvasWindow, rcEmpty, NULL, WS_CHILD | WS_VISIBLE); - // Create selection window (initially hidden) - selectionWindow.Create(imageArea, rcEmpty, NULL, WS_CHILD | BS_OWNERDRAW); - // Create and show the miniature if necessary if (registrySettings.ShowThumbnail) { @@ -407,7 +402,7 @@ LRESULT CMainWindow::OnInitMenuPopup(UINT nMsg, WPARAM wParam, LPARAM lParam, BO { HMENU menu = (HMENU)wParam; BOOL trueSelection = - (::IsWindowVisible(selectionWindow) && + (selectionModel.m_bShow && ((toolsModel.GetActiveTool() == TOOL_FREESEL) || (toolsModel.GetActiveTool() == TOOL_RECTSEL))); switch (lParam) @@ -438,7 +433,7 @@ LRESULT CMainWindow::OnInitMenuPopup(UINT nMsg, WPARAM wParam, LPARAM lParam, BO CheckMenuItem(menu, IDM_VIEWSHOWMINIATURE, CHECKED_IF(registrySettings.ShowThumbnail)); break; case 3: /* Image menu */ - EnableMenuItem(menu, IDM_IMAGECROP, ENABLED_IF(::IsWindowVisible(selectionWindow))); + EnableMenuItem(menu, IDM_IMAGECROP, ENABLED_IF(selectionModel.m_bShow)); CheckMenuItem(menu, IDM_IMAGEDRAWOPAQUE, CHECKED_IF(!toolsModel.IsBackgroundTransparent())); break; } @@ -484,7 +479,6 @@ LRESULT CMainWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH if (hwndCapture) { if (canvasWindow.m_hWnd == hwndCapture || - selectionWindow.m_hWnd == hwndCapture || imageArea.m_hWnd == hwndCapture || fullscreenWindow.m_hWnd == hwndCapture) { @@ -610,7 +604,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH case IDM_EDITUNDO: if (toolsModel.GetActiveTool() == TOOL_TEXT && ::IsWindowVisible(textEditWindow)) break; - if (selectionWindow.IsWindowVisible()) + if (selectionModel.m_bShow) { if (toolsModel.GetActiveTool() == TOOL_RECTSEL || toolsModel.GetActiveTool() == TOOL_FREESEL) @@ -736,31 +730,31 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH switch (mirrorRotateDialog.DoModal(mainWindow.m_hWnd)) { case 1: /* flip horizontally */ - if (::IsWindowVisible(selectionWindow)) + if (selectionModel.m_bShow) selectionModel.FlipHorizontally(); else imageModel.FlipHorizontally(); break; case 2: /* flip vertically */ - if (::IsWindowVisible(selectionWindow)) + if (selectionModel.m_bShow) selectionModel.FlipVertically(); else imageModel.FlipVertically(); break; case 3: /* rotate 90 degrees */ - if (::IsWindowVisible(selectionWindow)) + if (selectionModel.m_bShow) selectionModel.RotateNTimes90Degrees(1); else imageModel.RotateNTimes90Degrees(1); break; case 4: /* rotate 180 degrees */ - if (::IsWindowVisible(selectionWindow)) + if (selectionModel.m_bShow) selectionModel.RotateNTimes90Degrees(2); else imageModel.RotateNTimes90Degrees(2); break; case 5: /* rotate 270 degrees */ - if (::IsWindowVisible(selectionWindow)) + if (selectionModel.m_bShow) selectionModel.RotateNTimes90Degrees(3); else imageModel.RotateNTimes90Degrees(3); @@ -779,7 +773,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH { if (stretchSkewDialog.DoModal(mainWindow.m_hWnd)) { - if (::IsWindowVisible(selectionWindow)) + if (selectionModel.m_bShow) { selectionModel.StretchSkew(stretchSkewDialog.percentage.x, stretchSkewDialog.percentage.y, stretchSkewDialog.angle.x, stretchSkewDialog.angle.y); -- 2.17.1