From 3116acb259277f12807046f55031ecdf9d30d23f Mon Sep 17 00:00:00 2001 From: Benedikt Freisen Date: Thu, 9 Jul 2015 09:48:01 +0000 Subject: [PATCH] [MSPAINT_NEW] refactoring: move selection management to a dedicated SelectionModel (WIP) svn path=/trunk/; revision=68382 --- .../applications/mspaint_new/CMakeLists.txt | 1 + .../base/applications/mspaint_new/globalvar.h | 10 +- .../base/applications/mspaint_new/main.cpp | 9 +- .../base/applications/mspaint_new/mouse.cpp | 167 +++------ .../base/applications/mspaint_new/precomp.h | 1 + .../applications/mspaint_new/selection.cpp | 209 +++-------- .../base/applications/mspaint_new/selection.h | 11 + .../mspaint_new/selectionmodel.cpp | 328 ++++++++++++++++++ .../applications/mspaint_new/selectionmodel.h | 65 ++++ .../base/applications/mspaint_new/winproc.cpp | 62 +--- 10 files changed, 528 insertions(+), 335 deletions(-) create mode 100644 reactos/base/applications/mspaint_new/selectionmodel.cpp create mode 100644 reactos/base/applications/mspaint_new/selectionmodel.h diff --git a/reactos/base/applications/mspaint_new/CMakeLists.txt b/reactos/base/applications/mspaint_new/CMakeLists.txt index 377f70d0c9c..63229439e51 100644 --- a/reactos/base/applications/mspaint_new/CMakeLists.txt +++ b/reactos/base/applications/mspaint_new/CMakeLists.txt @@ -18,6 +18,7 @@ list(APPEND SOURCE registry.cpp scrollbox.cpp selection.cpp + selectionmodel.cpp sizebox.cpp textedit.cpp toolbox.cpp diff --git a/reactos/base/applications/mspaint_new/globalvar.h b/reactos/base/applications/mspaint_new/globalvar.h index 270a3e556a6..7fcc21132cc 100644 --- a/reactos/base/applications/mspaint_new/globalvar.h +++ b/reactos/base/applications/mspaint_new/globalvar.h @@ -21,7 +21,6 @@ typedef struct tagSTRETCHSKEW { /* VARIABLES declared in main.c *************************************/ extern HDC hDrawingDC; -extern HDC hSelDC; extern int *bmAddress; extern BITMAPINFO bitmapinfo; @@ -39,10 +38,9 @@ extern POINT last; class ToolsModel; extern ToolsModel toolsModel; -extern RECT rectSel_src; -extern RECT rectSel_dest; -extern HBITMAP hSelBm; -extern HBITMAP hSelMask; +class SelectionModel; +extern SelectionModel selectionModel; + extern HWND hwndEditCtl; extern LOGFONT lfTextFont; extern HFONT hfontTextFont; @@ -114,5 +112,3 @@ extern CTextEditWindow textEditWindow; extern POINT pointStack[256]; extern short pointSP; -extern POINT *ptStack; -extern int ptSP; diff --git a/reactos/base/applications/mspaint_new/main.cpp b/reactos/base/applications/mspaint_new/main.cpp index 363c6353105..abdfb6b5942 100644 --- a/reactos/base/applications/mspaint_new/main.cpp +++ b/reactos/base/applications/mspaint_new/main.cpp @@ -13,7 +13,6 @@ /* FUNCTIONS ********************************************************/ HDC hDrawingDC; -HDC hSelDC; int *bmAddress; BITMAPINFO bitmapinfo; int imgXRes = 400; @@ -31,10 +30,8 @@ POINT last; ToolsModel toolsModel; -RECT rectSel_src; -RECT rectSel_dest; -HBITMAP hSelBm; -HBITMAP hSelMask; +SelectionModel selectionModel; + LOGFONT lfTextFont; HFONT hfontTextFont; HWND hwndEditCtl; @@ -205,7 +202,7 @@ _tWinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPTSTR lpszArgument hDC = imageArea.GetDC(); hDrawingDC = CreateCompatibleDC(hDC); - hSelDC = CreateCompatibleDC(hDC); + selectionModel.SetDC(CreateCompatibleDC(hDC)); imageArea.ReleaseDC(hDC); SelectObject(hDrawingDC, CreatePen(PS_SOLID, 0, paletteModel.GetFgColor())); SelectObject(hDrawingDC, CreateSolidBrush(paletteModel.GetBgColor())); diff --git a/reactos/base/applications/mspaint_new/mouse.cpp b/reactos/base/applications/mspaint_new/mouse.cpp index 10f446ed5ce..a4eaf6b52d2 100644 --- a/reactos/base/applications/mspaint_new/mouse.cpp +++ b/reactos/base/applications/mspaint_new/mouse.cpp @@ -15,44 +15,42 @@ void placeSelWin() { - selectionWindow.MoveWindow(rectSel_dest.left * toolsModel.GetZoom() / 1000, rectSel_dest.top * toolsModel.GetZoom() / 1000, - RECT_WIDTH(rectSel_dest) * toolsModel.GetZoom() / 1000 + 6, RECT_HEIGHT(rectSel_dest) * toolsModel.GetZoom() / 1000 + 6, TRUE); + selectionWindow.MoveWindow(selectionModel.GetDestRectLeft() * toolsModel.GetZoom() / 1000, selectionModel.GetDestRectTop() * toolsModel.GetZoom() / 1000, + selectionModel.GetDestRectWidth() * toolsModel.GetZoom() / 1000 + 6, selectionModel.GetDestRectHeight() * toolsModel.GetZoom() / 1000 + 6, TRUE); selectionWindow.BringWindowToTop(); imageArea.InvalidateRect(NULL, FALSE); } void -regularize(LONG x0, LONG y0, LONG *x1, LONG *y1) +regularize(LONG x0, LONG y0, LONG& x1, LONG& y1) { - if (abs(*x1 - x0) >= abs(*y1 - y0)) - *y1 = y0 + (*y1 > y0 ? abs(*x1 - x0) : -abs(*x1 - x0)); + if (abs(x1 - x0) >= abs(y1 - y0)) + y1 = y0 + (y1 > y0 ? abs(x1 - x0) : -abs(x1 - x0)); else - *x1 = x0 + (*x1 > x0 ? abs(*y1 - y0) : -abs(*y1 - y0)); + x1 = x0 + (x1 > x0 ? abs(y1 - y0) : -abs(y1 - y0)); } void -roundTo8Directions(LONG x0, LONG y0, LONG *x1, LONG *y1) +roundTo8Directions(LONG x0, LONG y0, LONG& x1, LONG& y1) { - if (abs(*x1 - x0) >= abs(*y1 - y0)) + if (abs(x1 - x0) >= abs(y1 - y0)) { - if (abs(*y1 - y0) * 5 < abs(*x1 - x0) * 2) - *y1 = y0; + if (abs(y1 - y0) * 5 < abs(x1 - x0) * 2) + y1 = y0; else - *y1 = y0 + (*y1 > y0 ? abs(*x1 - x0) : -abs(*x1 - x0)); + y1 = y0 + (y1 > y0 ? abs(x1 - x0) : -abs(x1 - x0)); } else { - if (abs(*x1 - x0) * 5 < abs(*y1 - y0) * 2) - *x1 = x0; + if (abs(x1 - x0) * 5 < abs(y1 - y0) * 2) + x1 = x0; else - *x1 = x0 + (*x1 > x0 ? abs(*y1 - y0) : -abs(*y1 - y0)); + x1 = x0 + (x1 > x0 ? abs(y1 - y0) : -abs(y1 - y0)); } } POINT pointStack[256]; short pointSP; -POINT *ptStack = NULL; -int ptSP = 0; void startPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) @@ -65,12 +63,8 @@ startPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) { case TOOL_FREESEL: selectionWindow.ShowWindow(SW_HIDE); - if (ptStack != NULL) - HeapFree(GetProcessHeap(), 0, ptStack); - ptStack = (POINT*) HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(POINT) * 1024); - ptSP = 0; - ptStack[0].x = x; - ptStack[0].y = y; + selectionModel.ResetPtStack(); + selectionModel.PushToPtStack(x, y); break; case TOOL_LINE: case TOOL_RECT: @@ -82,8 +76,7 @@ startPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) case TOOL_TEXT: imageModel.CopyPrevious(); selectionWindow.ShowWindow(SW_HIDE); - rectSel_src.right = rectSel_src.left; - rectSel_src.bottom = rectSel_src.top; + selectionModel.SetSrcRectSizeToZero(); break; case TOOL_RUBBER: imageModel.CopyPrevious(); @@ -134,15 +127,11 @@ whilePaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) switch (toolsModel.GetActiveTool()) { case TOOL_FREESEL: - if (ptSP == 0) + if (selectionModel.PtStackSize() == 1) imageModel.CopyPrevious(); - ptSP++; - if (ptSP % 1024 == 0) - ptStack = (POINT*) HeapReAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, ptStack, sizeof(POINT) * (ptSP + 1024)); - ptStack[ptSP].x = max(0, min(x, imageModel.GetWidth())); - ptStack[ptSP].y = max(0, min(y, imageModel.GetHeight())); + selectionModel.PushToPtStack(max(0, min(x, imageModel.GetWidth())), max(0, min(y, imageModel.GetHeight()))); imageModel.ResetToPrevious(); - Poly(hdc, ptStack, ptSP + 1, 0, 0, 2, 0, FALSE, TRUE); /* draw the freehand selection inverted/xored */ + selectionModel.DrawFramePoly(hdc); break; case TOOL_RECTSEL: case TOOL_TEXT: @@ -151,10 +140,7 @@ whilePaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) imageModel.ResetToPrevious(); temp.x = max(0, min(x, imageModel.GetWidth())); temp.y = max(0, min(y, imageModel.GetHeight())); - rectSel_dest.left = rectSel_src.left = min(start.x, temp.x); - rectSel_dest.top = rectSel_src.top = min(start.y, temp.y); - rectSel_dest.right = rectSel_src.right = max(start.x, temp.x); - rectSel_dest.bottom = rectSel_src.bottom = max(start.y, temp.y); + selectionModel.SetSrcAndDestRectFromPoints(start, temp); RectSel(hdc, start.x, start.y, temp.x, temp.y); break; } @@ -173,7 +159,7 @@ whilePaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) case TOOL_LINE: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) - roundTo8Directions(start.x, start.y, &x, &y); + roundTo8Directions(start.x, start.y, x, y); Line(hdc, start.x, start.y, x, y, fg, toolsModel.GetLineWidth()); break; case TOOL_BEZIER: @@ -197,7 +183,7 @@ whilePaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) case TOOL_RECT: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) - regularize(start.x, start.y, &x, &y); + regularize(start.x, start.y, x, y); Rect(hdc, start.x, start.y, x, y, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle()); break; case TOOL_SHAPE: @@ -206,20 +192,20 @@ whilePaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) pointStack[pointSP].y = y; if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0)) roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y, - &pointStack[pointSP].x, &pointStack[pointSP].y); + pointStack[pointSP].x, pointStack[pointSP].y); if (pointSP + 1 >= 2) Poly(hdc, pointStack, pointSP + 1, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), FALSE, FALSE); break; case TOOL_ELLIPSE: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) - regularize(start.x, start.y, &x, &y); + regularize(start.x, start.y, x, y); Ellp(hdc, start.x, start.y, x, y, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle()); break; case TOOL_RRECT: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) - regularize(start.x, start.y, &x, &y); + regularize(start.x, start.y, x, y); RRect(hdc, start.x, start.y, x, y, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle()); break; } @@ -235,79 +221,30 @@ endPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) { case TOOL_FREESEL: { - POINT *ptStackCopy; - int i; - rectSel_src.left = rectSel_src.top = MAXLONG; - rectSel_src.right = rectSel_src.bottom = 0; - for (i = 0; i <= ptSP; i++) + selectionModel.CalculateBoundingBoxAndContents(hdc); + if (selectionModel.PtStackSize() > 1) { - if (ptStack[i].x < rectSel_src.left) - rectSel_src.left = ptStack[i].x; - if (ptStack[i].y < rectSel_src.top) - rectSel_src.top = ptStack[i].y; - if (ptStack[i].x > rectSel_src.right) - rectSel_src.right = ptStack[i].x; - if (ptStack[i].y > rectSel_src.bottom) - rectSel_src.bottom = ptStack[i].y; - } - rectSel_src.right += 1; - rectSel_src.bottom += 1; - rectSel_dest.left = rectSel_src.left; - rectSel_dest.top = rectSel_src.top; - rectSel_dest.right = rectSel_src.right; - rectSel_dest.bottom = rectSel_src.bottom; - if (ptSP != 0) - { - DeleteObject(hSelMask); - hSelMask = CreateBitmap(RECT_WIDTH(rectSel_src), RECT_HEIGHT(rectSel_src), 1, 1, NULL); - DeleteObject(SelectObject(hSelDC, hSelMask)); - ptStackCopy = (POINT*) HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(POINT) * (ptSP + 1)); - for (i = 0; i <= ptSP; i++) - { - ptStackCopy[i].x = ptStack[i].x - rectSel_src.left; - ptStackCopy[i].y = ptStack[i].y - rectSel_src.top; - } - Poly(hSelDC, ptStackCopy, ptSP + 1, 0x00ffffff, 0x00ffffff, 1, 2, TRUE, FALSE); - HeapFree(GetProcessHeap(), 0, ptStackCopy); - SelectObject(hSelDC, hSelBm = CreateDIBWithProperties(RECT_WIDTH(rectSel_src), RECT_HEIGHT(rectSel_src))); - imageModel.ResetToPrevious(); - MaskBlt(hSelDC, 0, 0, RECT_WIDTH(rectSel_src), RECT_HEIGHT(rectSel_src), hDrawingDC, rectSel_src.left, - rectSel_src.top, hSelMask, 0, 0, MAKEROP4(SRCCOPY, WHITENESS)); - Poly(hdc, ptStack, ptSP + 1, bg, bg, 1, 2, TRUE, FALSE); + selectionModel.DrawBackgroundPoly(hdc, bg); imageModel.CopyPrevious(); - MaskBlt(hDrawingDC, rectSel_src.left, rectSel_src.top, RECT_WIDTH(rectSel_src), RECT_HEIGHT(rectSel_src), hSelDC, 0, - 0, hSelMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND)); + selectionModel.DrawSelection(hdc); placeSelWin(); selectionWindow.ShowWindow(SW_SHOW); - /* force refresh of selection contents */ - selectionWindow.SendMessage(WM_LBUTTONDOWN, 0, 0); - selectionWindow.SendMessage(WM_MOUSEMOVE, 0, 0); - selectionWindow.SendMessage(WM_LBUTTONUP, 0, 0); + ForceRefreshSelectionContents(); } - HeapFree(GetProcessHeap(), 0, ptStack); - ptStack = NULL; + selectionModel.ResetPtStack(); break; } case TOOL_RECTSEL: imageModel.ResetToPrevious(); - if ((RECT_WIDTH(rectSel_src) != 0) && (RECT_HEIGHT(rectSel_src) != 0)) + if (selectionModel.IsSrcRectSizeNonzero()) { - DeleteObject(hSelMask); - hSelMask = CreateBitmap(RECT_WIDTH(rectSel_src), RECT_HEIGHT(rectSel_src), 1, 1, NULL); - DeleteObject(SelectObject(hSelDC, hSelMask)); - Rect(hSelDC, 0, 0, RECT_WIDTH(rectSel_src), RECT_HEIGHT(rectSel_src), 0x00ffffff, 0x00ffffff, 1, 2); - SelectObject(hSelDC, hSelBm = CreateDIBWithProperties(RECT_WIDTH(rectSel_src), RECT_HEIGHT(rectSel_src))); - imageModel.ResetToPrevious(); - BitBlt(hSelDC, 0, 0, RECT_WIDTH(rectSel_src), RECT_HEIGHT(rectSel_src), hDrawingDC, rectSel_src.left, - rectSel_src.top, SRCCOPY); - Rect(hdc, rectSel_src.left, rectSel_src.top, rectSel_src.right, - rectSel_src.bottom, bg, bg, 0, TRUE); + selectionModel.CalculateContents(hdc); + selectionModel.DrawBackgroundRect(hdc, bg); imageModel.CopyPrevious(); - BitBlt(hDrawingDC, rectSel_src.left, rectSel_src.top, RECT_WIDTH(rectSel_src), RECT_HEIGHT(rectSel_src), hSelDC, 0, - 0, SRCCOPY); + selectionModel.DrawSelection(hdc); placeSelWin(); selectionWindow.ShowWindow(SW_SHOW); @@ -316,7 +253,7 @@ endPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) break; case TOOL_TEXT: imageModel.ResetToPrevious(); - if ((RECT_WIDTH(rectSel_src) != 0) && (RECT_HEIGHT(rectSel_src) != 0)) + if (selectionModel.IsSrcRectSizeNonzero()) { imageModel.CopyPrevious(); @@ -335,7 +272,7 @@ endPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) case TOOL_LINE: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) - roundTo8Directions(start.x, start.y, &x, &y); + roundTo8Directions(start.x, start.y, x, y); Line(hdc, start.x, start.y, x, y, fg, toolsModel.GetLineWidth()); break; case TOOL_BEZIER: @@ -346,7 +283,7 @@ endPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) case TOOL_RECT: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) - regularize(start.x, start.y, &x, &y); + regularize(start.x, start.y, x, y); Rect(hdc, start.x, start.y, x, y, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle()); break; case TOOL_SHAPE: @@ -355,7 +292,7 @@ endPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) pointStack[pointSP].y = y; if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0)) roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y, - &pointStack[pointSP].x, &pointStack[pointSP].y); + pointStack[pointSP].x, pointStack[pointSP].y); pointSP++; if (pointSP >= 2) { @@ -376,13 +313,13 @@ endPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) case TOOL_ELLIPSE: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) - regularize(start.x, start.y, &x, &y); + regularize(start.x, start.y, x, y); Ellp(hdc, start.x, start.y, x, y, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle()); break; case TOOL_RRECT: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) - regularize(start.x, start.y, &x, &y); + regularize(start.x, start.y, x, y); RRect(hdc, start.x, start.y, x, y, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle()); break; } @@ -468,7 +405,7 @@ whilePaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) case TOOL_LINE: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) - roundTo8Directions(start.x, start.y, &x, &y); + roundTo8Directions(start.x, start.y, x, y); Line(hdc, start.x, start.y, x, y, bg, toolsModel.GetLineWidth()); break; case TOOL_BEZIER: @@ -492,7 +429,7 @@ whilePaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) case TOOL_RECT: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) - regularize(start.x, start.y, &x, &y); + regularize(start.x, start.y, x, y); Rect(hdc, start.x, start.y, x, y, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle()); break; case TOOL_SHAPE: @@ -501,20 +438,20 @@ whilePaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) pointStack[pointSP].y = y; if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0)) roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y, - &pointStack[pointSP].x, &pointStack[pointSP].y); + pointStack[pointSP].x, pointStack[pointSP].y); if (pointSP + 1 >= 2) Poly(hdc, pointStack, pointSP + 1, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), FALSE, FALSE); break; case TOOL_ELLIPSE: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) - regularize(start.x, start.y, &x, &y); + regularize(start.x, start.y, x, y); Ellp(hdc, start.x, start.y, x, y, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle()); break; case TOOL_RRECT: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) - regularize(start.x, start.y, &x, &y); + regularize(start.x, start.y, x, y); RRect(hdc, start.x, start.y, x, y, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle()); break; } @@ -538,7 +475,7 @@ endPaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) case TOOL_LINE: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) - roundTo8Directions(start.x, start.y, &x, &y); + roundTo8Directions(start.x, start.y, x, y); Line(hdc, start.x, start.y, x, y, bg, toolsModel.GetLineWidth()); break; case TOOL_BEZIER: @@ -549,7 +486,7 @@ endPaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) case TOOL_RECT: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) - regularize(start.x, start.y, &x, &y); + regularize(start.x, start.y, x, y); Rect(hdc, start.x, start.y, x, y, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle()); break; case TOOL_SHAPE: @@ -558,7 +495,7 @@ endPaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) pointStack[pointSP].y = y; if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0)) roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y, - &pointStack[pointSP].x, &pointStack[pointSP].y); + pointStack[pointSP].x, pointStack[pointSP].y); pointSP++; if (pointSP >= 2) { @@ -579,13 +516,13 @@ endPaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) case TOOL_ELLIPSE: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) - regularize(start.x, start.y, &x, &y); + regularize(start.x, start.y, x, y); Ellp(hdc, start.x, start.y, x, y, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle()); break; case TOOL_RRECT: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) - regularize(start.x, start.y, &x, &y); + regularize(start.x, start.y, x, y); RRect(hdc, start.x, start.y, x, y, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle()); break; } diff --git a/reactos/base/applications/mspaint_new/precomp.h b/reactos/base/applications/mspaint_new/precomp.h index 123ee89943f..960dfab6d61 100644 --- a/reactos/base/applications/mspaint_new/precomp.h +++ b/reactos/base/applications/mspaint_new/precomp.h @@ -30,6 +30,7 @@ #include "palettemodel.h" #include "scrollbox.h" #include "selection.h" +#include "selectionmodel.h" #include "sizebox.h" #include "textedit.h" #include "toolbox.h" diff --git a/reactos/base/applications/mspaint_new/selection.cpp b/reactos/base/applications/mspaint_new/selection.cpp index 3016dca64bc..cd3df620b7b 100644 --- a/reactos/base/applications/mspaint_new/selection.cpp +++ b/reactos/base/applications/mspaint_new/selection.cpp @@ -10,21 +10,9 @@ #include "precomp.h" -/* 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 - /* FUNCTIONS ********************************************************/ -LPCTSTR cursors[9] = { /* action to mouse cursor lookup table */ +const LPCTSTR CSelectionWindow::m_lpszCursorLUT[9] = { /* action to mouse cursor lookup table */ IDC_SIZEALL, IDC_SIZENWSE, IDC_SIZENS, IDC_SIZENESW, @@ -32,13 +20,6 @@ LPCTSTR cursors[9] = { /* action to mouse cursor lookup table */ IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE }; -BOOL moving = FALSE; -int action = ACTION_MOVE; -POINTS pos; -POINTS frac; -POINT delta; -DWORD system_selection_color; - 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) { @@ -81,32 +62,31 @@ ForceRefreshSelectionContents() } } -int -identifyCorner(short x, short y, short w, short h) +int CSelectionWindow::IdentifyCorner(int iXPos, int iYPos, int iWidth, int iHeight) { - if (y < 3) + if (iYPos < 3) { - if (x < 3) + if (iXPos < 3) return ACTION_RESIZE_TOP_LEFT; - if ((x < w / 2 + 2) && (x >= w / 2 - 1)) + if ((iXPos < iWidth / 2 + 2) && (iXPos >= iWidth / 2 - 1)) return ACTION_RESIZE_TOP; - if (x >= w - 3) + if (iXPos >= iWidth - 3) return ACTION_RESIZE_TOP_RIGHT; } - if ((y < h / 2 + 2) && (y >= h / 2 - 1)) + if ((iYPos < iHeight / 2 + 2) && (iYPos >= iHeight / 2 - 1)) { - if (x < 3) + if (iXPos < 3) return ACTION_RESIZE_LEFT; - if (x >= w - 3) + if (iXPos >= iWidth - 3) return ACTION_RESIZE_RIGHT; } - if (y >= h - 3) + if (iYPos >= iHeight - 3) { - if (x < 3) + if (iXPos < 3) return ACTION_RESIZE_BOTTOM_LEFT; - if ((x < w / 2 + 2) && (x >= w / 2 - 1)) + if ((iXPos < iWidth / 2 + 2) && (iXPos >= iWidth / 2 - 1)) return ACTION_RESIZE_BOTTOM; - if (x >= w - 3) + if (iXPos >= iWidth - 3) return ACTION_RESIZE_BOTTOM_RIGHT; } return 0; @@ -114,13 +94,13 @@ identifyCorner(short x, short y, short w, short h) LRESULT CSelectionWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { - if (!moving) + if (!m_bMoving) { HDC hDC = GetDC(); DefWindowProc(WM_PAINT, wParam, lParam); - SelectionFrame(hDC, 1, 1, RECT_WIDTH(rectSel_dest) * toolsModel.GetZoom() / 1000 + 5, - RECT_HEIGHT(rectSel_dest) * toolsModel.GetZoom() / 1000 + 5, - system_selection_color); + SelectionFrame(hDC, 1, 1, selectionModel.GetDestRectWidth() * toolsModel.GetZoom() / 1000 + 5, + selectionModel.GetDestRectHeight() * toolsModel.GetZoom() / 1000 + 5, + m_dwSystemSelectionColor); ReleaseDC(hDC); } return 0; @@ -134,8 +114,10 @@ LRESULT CSelectionWindow::OnEraseBkgnd(UINT nMsg, WPARAM wParam, LPARAM lParam, LRESULT CSelectionWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { + m_bMoving = FALSE; + m_iAction = ACTION_MOVE; /* update the system selection color */ - system_selection_color = GetSysColor(COLOR_HIGHLIGHT); + m_dwSystemSelectionColor = GetSysColor(COLOR_HIGHLIGHT); SendMessage(WM_PAINT, 0, MAKELPARAM(0, 0)); return 0; } @@ -143,7 +125,7 @@ LRESULT CSelectionWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL LRESULT CSelectionWindow::OnSysColorChange(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { /* update the system selection color */ - system_selection_color = GetSysColor(COLOR_HIGHLIGHT); + m_dwSystemSelectionColor = GetSysColor(COLOR_HIGHLIGHT); SendMessage(WM_PAINT, 0, MAKELPARAM(0, 0)); return 0; } @@ -156,14 +138,14 @@ LRESULT CSelectionWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, B LRESULT CSelectionWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { - pos.x = GET_X_LPARAM(lParam); - pos.y = GET_Y_LPARAM(lParam); - delta.x = 0; - delta.y = 0; + m_ptPos.x = GET_X_LPARAM(lParam); + m_ptPos.y = GET_Y_LPARAM(lParam); + m_ptDelta.x = 0; + m_ptDelta.y = 0; SetCapture(); - if (action != ACTION_MOVE) - SetCursor(LoadCursor(NULL, cursors[action])); - moving = TRUE; + if (m_iAction != ACTION_MOVE) + SetCursor(LoadCursor(NULL, m_lpszCursorLUT[m_iAction])); + m_bMoving = TRUE; scrlClientWindow.InvalidateRect(NULL, TRUE); imageArea.SendMessage(WM_PAINT, 0, 0); return 0; @@ -171,127 +153,66 @@ LRESULT CSelectionWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, LRESULT CSelectionWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { - if (moving) + if (m_bMoving) { TCHAR sizeStr[100]; - POINT deltaUsed; imageModel.ResetToPrevious(); - frac.x += GET_X_LPARAM(lParam) - pos.x; - frac.y += GET_Y_LPARAM(lParam) - pos.y; - delta.x += frac.x * 1000 / toolsModel.GetZoom(); - delta.y += frac.y * 1000 / toolsModel.GetZoom(); + m_ptFrac.x += GET_X_LPARAM(lParam) - m_ptPos.x; + m_ptFrac.y += GET_Y_LPARAM(lParam) - m_ptPos.y; + m_ptDelta.x += m_ptFrac.x * 1000 / toolsModel.GetZoom(); + m_ptDelta.y += m_ptFrac.y * 1000 / toolsModel.GetZoom(); if (toolsModel.GetZoom() < 1000) { - frac.x = 0; - frac.y = 0; + m_ptFrac.x = 0; + m_ptFrac.y = 0; } else { - frac.x -= (frac.x * 1000 / toolsModel.GetZoom()) * toolsModel.GetZoom() / 1000; - frac.y -= (frac.y * 1000 / toolsModel.GetZoom()) * toolsModel.GetZoom() / 1000; + m_ptFrac.x -= (m_ptFrac.x * 1000 / toolsModel.GetZoom()) * toolsModel.GetZoom() / 1000; + m_ptFrac.y -= (m_ptFrac.y * 1000 / toolsModel.GetZoom()) * toolsModel.GetZoom() / 1000; } - switch (action) - { - case ACTION_MOVE: /* move selection */ - deltaUsed.x = delta.x; - deltaUsed.y = delta.y; - OffsetRect(&rectSel_dest, deltaUsed.x, deltaUsed.y); - break; - case ACTION_RESIZE_TOP_LEFT: /* resize at upper left corner */ - deltaUsed.x = min(delta.x, RECT_WIDTH(rectSel_dest) - 1); - deltaUsed.y = min(delta.y, RECT_HEIGHT(rectSel_dest) - 1); - rectSel_dest.left += deltaUsed.x; - rectSel_dest.top += deltaUsed.y; - break; - case ACTION_RESIZE_TOP: /* resize at top edge */ - deltaUsed.x = delta.x; - deltaUsed.y = min(delta.y, RECT_HEIGHT(rectSel_dest) - 1); - rectSel_dest.top += deltaUsed.y; - break; - case ACTION_RESIZE_TOP_RIGHT: /* resize at upper right corner */ - deltaUsed.x = max(delta.x, -(RECT_WIDTH(rectSel_dest) - 1)); - deltaUsed.y = min(delta.y, RECT_HEIGHT(rectSel_dest) - 1); - rectSel_dest.top += deltaUsed.y; - rectSel_dest.right += deltaUsed.x; - break; - case ACTION_RESIZE_LEFT: /* resize at left edge */ - deltaUsed.x = min(delta.x, RECT_WIDTH(rectSel_dest) - 1); - deltaUsed.y = delta.y; - rectSel_dest.left += deltaUsed.x; - break; - case ACTION_RESIZE_RIGHT: /* resize at right edge */ - deltaUsed.x = max(delta.x, -(RECT_WIDTH(rectSel_dest) - 1)); - deltaUsed.y = delta.y; - rectSel_dest.right += deltaUsed.x; - break; - case ACTION_RESIZE_BOTTOM_LEFT: /* resize at lower left corner */ - deltaUsed.x = min(delta.x, RECT_WIDTH(rectSel_dest) - 1); - deltaUsed.y = max(delta.y, -(RECT_HEIGHT(rectSel_dest) - 1)); - rectSel_dest.left += deltaUsed.x; - rectSel_dest.bottom += deltaUsed.y; - break; - case ACTION_RESIZE_BOTTOM: /* resize at bottom edge */ - deltaUsed.x = delta.x; - deltaUsed.y = max(delta.y, -(RECT_HEIGHT(rectSel_dest) - 1)); - rectSel_dest.bottom += deltaUsed.y; - break; - case ACTION_RESIZE_BOTTOM_RIGHT: /* resize at lower right corner */ - deltaUsed.x = max(delta.x, -(RECT_WIDTH(rectSel_dest) - 1)); - deltaUsed.y = max(delta.y, -(RECT_HEIGHT(rectSel_dest) - 1)); - rectSel_dest.right += deltaUsed.x; - rectSel_dest.bottom += deltaUsed.y; - break; - } - delta.x -= deltaUsed.x; - delta.y -= deltaUsed.y; + selectionModel.ModifyDestRect(m_ptDelta, m_iAction); - _stprintf(sizeStr, _T("%d x %d"), RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest)); + _stprintf(sizeStr, _T("%d x %d"), selectionModel.GetDestRectWidth(), selectionModel.GetDestRectHeight()); SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) sizeStr); if (toolsModel.GetActiveTool() == TOOL_TEXT) { - Text(hDrawingDC, rectSel_dest.left, rectSel_dest.top, rectSel_dest.right, rectSel_dest.bottom, paletteModel.GetFgColor(), paletteModel.GetBgColor(), textToolText, hfontTextFont, toolsModel.IsBackgroundTransparent()); + selectionModel.DrawTextToolText(hDrawingDC, paletteModel.GetFgColor(), paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent()); } else { - if (action != ACTION_MOVE) - StretchBlt(hDrawingDC, rectSel_dest.left, rectSel_dest.top, RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), hSelDC, 0, 0, GetDIBWidth(hSelBm), GetDIBHeight(hSelBm), SRCCOPY); + if (m_iAction != ACTION_MOVE) + selectionModel.DrawSelectionStretched(hDrawingDC); else - if (toolsModel.IsBackgroundTransparent() == 0) - MaskBlt(hDrawingDC, rectSel_dest.left, rectSel_dest.top, RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), - hSelDC, 0, 0, hSelMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND)); - else - { - ColorKeyedMaskBlt(hDrawingDC, rectSel_dest.left, rectSel_dest.top, RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), - hSelDC, 0, 0, hSelMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND), paletteModel.GetBgColor()); - } + selectionModel.DrawSelection(hDrawingDC, paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent()); } imageArea.InvalidateRect(NULL, FALSE); imageArea.SendMessage(WM_PAINT, 0, 0); - pos.x = GET_X_LPARAM(lParam); - pos.y = GET_Y_LPARAM(lParam); + m_ptPos.x = GET_X_LPARAM(lParam); + m_ptPos.y = GET_Y_LPARAM(lParam); } else { - int w = RECT_WIDTH(rectSel_dest) * toolsModel.GetZoom() / 1000 + 6; - int h = RECT_HEIGHT(rectSel_dest) * toolsModel.GetZoom() / 1000 + 6; - pos.x = GET_X_LPARAM(lParam); - pos.y = GET_Y_LPARAM(lParam); + int w = selectionModel.GetDestRectWidth() * toolsModel.GetZoom() / 1000 + 6; + int h = selectionModel.GetDestRectHeight() * toolsModel.GetZoom() / 1000 + 6; + m_ptPos.x = GET_X_LPARAM(lParam); + m_ptPos.y = GET_Y_LPARAM(lParam); SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) NULL); - action = identifyCorner(pos.x, pos.y, w, h); - if (action != ACTION_MOVE) - SetCursor(LoadCursor(NULL, cursors[action])); + 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::OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { - if (moving) + if (m_bMoving) { - moving = FALSE; + m_bMoving = FALSE; ReleaseCapture(); - if (action != ACTION_MOVE) + if (m_iAction != ACTION_MOVE) { if (toolsModel.GetActiveTool() == TOOL_TEXT) { @@ -299,25 +220,7 @@ LRESULT CSelectionWindow::OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, B } else { - HDC hTempDC; - HBITMAP hTempBm; - hTempDC = CreateCompatibleDC(hSelDC); - hTempBm = CreateDIBWithProperties(RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest)); - SelectObject(hTempDC, hTempBm); - SelectObject(hSelDC, hSelBm); - StretchBlt(hTempDC, 0, 0, RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), hSelDC, 0, 0, - GetDIBWidth(hSelBm), GetDIBHeight(hSelBm), SRCCOPY); - DeleteObject(hSelBm); - hSelBm = hTempBm; - hTempBm = CreateBitmap(RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), 1, 1, NULL); - SelectObject(hTempDC, hTempBm); - SelectObject(hSelDC, hSelMask); - StretchBlt(hTempDC, 0, 0, RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), hSelDC, 0, 0, - GetDIBWidth(hSelMask), GetDIBHeight(hSelMask), SRCCOPY); - DeleteObject(hSelMask); - hSelMask = hTempBm; - SelectObject(hSelDC, hSelBm); - DeleteDC(hTempDC); + selectionModel.ScaleContentsToFit(); } } placeSelWin(); diff --git a/reactos/base/applications/mspaint_new/selection.h b/reactos/base/applications/mspaint_new/selection.h index 916a20a4f2c..bf42c0cad06 100644 --- a/reactos/base/applications/mspaint_new/selection.h +++ b/reactos/base/applications/mspaint_new/selection.h @@ -30,6 +30,17 @@ public: 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); + +private: + static const LPCTSTR m_lpszCursorLUT[9]; + BOOL m_bMoving; + int m_iAction; + POINT m_ptPos; + POINT m_ptFrac; + POINT m_ptDelta; + DWORD m_dwSystemSelectionColor; + + int IdentifyCorner(int iXPos, int iYPos, int iWidth, int iHeight); }; void ForceRefreshSelectionContents(); diff --git a/reactos/base/applications/mspaint_new/selectionmodel.cpp b/reactos/base/applications/mspaint_new/selectionmodel.cpp new file mode 100644 index 00000000000..4ed7b073597 --- /dev/null +++ b/reactos/base/applications/mspaint_new/selectionmodel.cpp @@ -0,0 +1,328 @@ +/* + * PROJECT: PAINT for ReactOS + * LICENSE: LGPL + * FILE: base/applications/mspaint_new/selectionmodel.cpp + * PURPOSE: Keep track of selection parameters, notify listeners + * PROGRAMMERS: Benedikt Freisen + */ + +/* INCLUDES *********************************************************/ + +#include "precomp.h" + +/* FUNCTIONS ********************************************************/ + +SelectionModel::SelectionModel() +{ + m_ptStack = NULL; + m_iPtSP = 0; +} + +void SelectionModel::SetDC(HDC hDC) +{ + m_hDC = hDC; +} + +void SelectionModel::ResetPtStack() +{ + if (m_ptStack != NULL) + HeapFree(GetProcessHeap(), 0, m_ptStack); + m_ptStack = NULL; + m_iPtSP = 0; +} + +void SelectionModel::PushToPtStack(LONG x, LONG y) +{ + if (m_iPtSP % 1024 == 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); + } + m_ptStack[m_iPtSP].x = x; + m_ptStack[m_iPtSP].y = y; + m_iPtSP++; +} + +void SelectionModel::CalculateBoundingBoxAndContents(HDC hDCImage) +{ + int i; + m_rcSrc.left = m_rcSrc.top = MAXLONG; + m_rcSrc.right = m_rcSrc.bottom = 0; + for (i = 0; i < m_iPtSP; i++) + { + 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; + } + 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) + { + 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++) + { + m_ptStackCopy[i].x = m_ptStack[i].x - m_rcSrc.left; + m_ptStackCopy[i].y = m_ptStack[i].y - m_rcSrc.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) +{ + 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); +} + +void SelectionModel::DrawBackgroundPoly(HDC hDCImage, COLORREF crBg) +{ + Poly(hDCImage, m_ptStack, m_iPtSP, crBg, crBg, 1, 2, TRUE, 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, TRUE); +} + +extern 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); + +void SelectionModel::DrawSelection(HDC hDCImage, COLORREF crBg, BOOL bBgTransparent) +{ + MaskBlt(hDCImage, m_rcSrc.left, m_rcSrc.top, RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc), m_hDC, 0, + 0, m_hMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND)); + 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); +} + +void SelectionModel::DrawSelectionStretched(HDC hDCImage) +{ + 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); +} + +void SelectionModel::ScaleContentsToFit() +{ + 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); +} + +void SelectionModel::InsertFromHBITMAP(HBITMAP hBm) +{ + HDC hTempDC; + HBITMAP hTempMask; + + DeleteObject(SelectObject(m_hDC, m_hBm = (HBITMAP) CopyImage(hBm, + IMAGE_BITMAP, 0, 0, + LR_COPYRETURNORG))); + + SetRectEmpty(&m_rcSrc); + m_rcDest.left = m_rcDest.top = 0; + 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, m_rcDest.left, m_rcDest.top, m_rcDest.right, m_rcDest.bottom, 0x00ffffff, 0x00ffffff, 1, 1); + DeleteObject(m_hMask); + m_hMask = hTempMask; + DeleteDC(hTempDC); +} + +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); +} + +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); +} + +void SelectionModel::RotateNTimes90Degrees(int iN) +{ + if (iN == 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); + } +} + +HBITMAP SelectionModel::GetBitmap() +{ + return m_hBm; +} + +int SelectionModel::PtStackSize() +{ + return m_iPtSP; +} + +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(POINT& ptFrom, 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; +} + +BOOL SelectionModel::IsSrcRectSizeNonzero() +{ + return (RECT_WIDTH(m_rcSrc) != 0) && (RECT_HEIGHT(m_rcSrc) != 0); +} + +void SelectionModel::ModifyDestRect(POINT& ptDelta, int iAction) +{ + POINT ptDeltaUsed; + + switch (iAction) + { + case ACTION_MOVE: /* move selection */ + ptDeltaUsed.x = ptDelta.x; + ptDeltaUsed.y = ptDelta.y; + OffsetRect(&m_rcDest, ptDeltaUsed.x, ptDeltaUsed.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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + break; + } + ptDelta.x -= ptDeltaUsed.x; + ptDelta.y -= ptDeltaUsed.y; +} + +LONG SelectionModel::GetDestRectWidth() +{ + return m_rcDest.right - m_rcDest.left; +} + +LONG SelectionModel::GetDestRectHeight() +{ + return m_rcDest.bottom - m_rcDest.top; +} + +LONG SelectionModel::GetDestRectLeft() +{ + return m_rcDest.left; +} + +LONG SelectionModel::GetDestRectTop() +{ + return m_rcDest.top; +} + +void SelectionModel::DrawTextToolText(HDC hDCImage, COLORREF crFg, COLORREF crBg, BOOL bBgTransparent) +{ + Text(hDCImage, m_rcDest.left, m_rcDest.top, m_rcDest.right, m_rcDest.bottom, crFg, crBg, textToolText, hfontTextFont, bBgTransparent); +} diff --git a/reactos/base/applications/mspaint_new/selectionmodel.h b/reactos/base/applications/mspaint_new/selectionmodel.h new file mode 100644 index 00000000000..a3de6dcecc2 --- /dev/null +++ b/reactos/base/applications/mspaint_new/selectionmodel.h @@ -0,0 +1,65 @@ +/* + * PROJECT: PAINT for ReactOS + * LICENSE: LGPL + * FILE: base/applications/mspaint_new/selectionmodel.h + * PURPOSE: Keep track of selection parameters, notify listeners + * PROGRAMMERS: Benedikt Freisen + */ + +/* 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; + POINT *m_ptStack; + int m_iPtSP; + +// void NotifySelectionChanging(); +// void NotifySelectionChanged(); + +public: + SelectionModel(); + void SetDC(HDC hDC); + void ResetPtStack(); + void PushToPtStack(LONG x, LONG y); + void CalculateBoundingBoxAndContents(HDC hDCImage); + void CalculateContents(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 InsertFromHBITMAP(HBITMAP hBm); + void FlipHorizontally(); + void FlipVertically(); + void RotateNTimes90Degrees(int iN); + HBITMAP GetBitmap(); + int PtStackSize(); + void DrawFramePoly(HDC hDCImage); + void SetSrcAndDestRectFromPoints(POINT& ptFrom, POINT& ptTo); + void SetSrcRectSizeToZero(); + BOOL IsSrcRectSizeNonzero(); + void ModifyDestRect(POINT& ptDelta, int iAction); + LONG GetDestRectWidth(); + LONG GetDestRectHeight(); + LONG GetDestRectLeft(); + LONG GetDestRectTop(); + void DrawTextToolText(HDC hDCImage, COLORREF crFg, COLORREF crBg, BOOL bBgTransparent = FALSE); +}; diff --git a/reactos/base/applications/mspaint_new/winproc.cpp b/reactos/base/applications/mspaint_new/winproc.cpp index 109296d9239..67571742cf0 100644 --- a/reactos/base/applications/mspaint_new/winproc.cpp +++ b/reactos/base/applications/mspaint_new/winproc.cpp @@ -107,29 +107,12 @@ void CMainWindow::UpdateApplicationProperties(HBITMAP bitmap, LPTSTR newfilename void CMainWindow::InsertSelectionFromHBITMAP(HBITMAP bitmap, HWND window) { - HDC hTempDC; - HBITMAP hTempMask; - HWND hToolbar = FindWindowEx(toolBoxContainer.m_hWnd, NULL, TOOLBARCLASSNAME, NULL); SendMessage(hToolbar, TB_CHECKBUTTON, ID_RECTSEL, MAKELPARAM(TRUE, 0)); toolBoxContainer.SendMessage(WM_COMMAND, ID_RECTSEL); - DeleteObject(SelectObject(hSelDC, hSelBm = (HBITMAP) CopyImage(bitmap, - IMAGE_BITMAP, 0, 0, - LR_COPYRETURNORG))); imageModel.CopyPrevious(); - SetRectEmpty(&rectSel_src); - rectSel_dest.left = rectSel_dest.top = 0; - rectSel_dest.right = rectSel_dest.left + GetDIBWidth(hSelBm); - rectSel_dest.bottom = rectSel_dest.top + GetDIBHeight(hSelBm); - - hTempDC = CreateCompatibleDC(hSelDC); - hTempMask = CreateBitmap(RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), 1, 1, NULL); - SelectObject(hTempDC, hTempMask); - Rect(hTempDC, rectSel_dest.left, rectSel_dest.top, rectSel_dest.right, rectSel_dest.bottom, 0x00ffffff, 0x00ffffff, 1, 1); - DeleteObject(hSelMask); - hSelMask = hTempMask; - DeleteDC(hTempDC); + selectionModel.InsertFromHBITMAP(bitmap); placeSelWin(); selectionWindow.ShowWindow(SW_SHOW); @@ -159,8 +142,6 @@ LRESULT CMainWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHa { SendMessage(WM_SETICON, ICON_BIG, (LPARAM) LoadIcon(hProgInstance, MAKEINTRESOURCE(IDI_APPICON))); SendMessage(WM_SETICON, ICON_SMALL, (LPARAM) LoadIcon(hProgInstance, MAKEINTRESOURCE(IDI_APPICON))); - ptStack = NULL; - ptSP = 0; return 0; } @@ -392,7 +373,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH case IDM_EDITCOPY: OpenClipboard(); EmptyClipboard(); - SetClipboardData(CF_BITMAP, CopyImage(hSelBm, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG)); + SetClipboardData(CF_BITMAP, CopyImage(selectionModel.GetBitmap(), IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG)); CloseClipboard(); break; case IDM_EDITCUT: @@ -411,20 +392,8 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH break; case IDM_EDITDELETESELECTION: { - /* remove selection window and already painted content using undo(), - paint Rect for rectangular selections and Poly for freeform selections */ + /* remove selection window and already painted content using undo */ imageModel.Undo(); - if (toolsModel.GetActiveTool() == TOOL_RECTSEL) - { - imageModel.CopyPrevious(); - Rect(hDrawingDC, rectSel_dest.left, rectSel_dest.top, rectSel_dest.right, - rectSel_dest.bottom, paletteModel.GetBgColor(), paletteModel.GetBgColor(), 0, TRUE); - } - if (toolsModel.GetActiveTool() == TOOL_FREESEL) - { - imageModel.CopyPrevious(); - Poly(hDrawingDC, ptStack, ptSP + 1, 0, 0, 2, 0, FALSE, TRUE); - } break; } case IDM_EDITSELECTALL: @@ -440,7 +409,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH } case IDM_EDITCOPYTO: if (GetSaveFileName(&ofn) != 0) - SaveDIBToFile(hSelBm, ofn.lpstrFile, hDrawingDC, NULL, NULL, fileHPPM, fileVPPM); + SaveDIBToFile(selectionModel.GetBitmap(), ofn.lpstrFile, hDrawingDC, NULL, NULL, fileHPPM, fileVPPM); break; case IDM_EDITPASTEFROM: if (GetOpenFileName(&ofn) != 0) @@ -480,12 +449,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH case 1: /* flip horizontally */ if (selectionWindow.IsWindowVisible()) { - SelectObject(hSelDC, hSelMask); - StretchBlt(hSelDC, RECT_WIDTH(rectSel_dest) - 1, 0, -RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), hSelDC, - 0, 0, RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), SRCCOPY); - SelectObject(hSelDC, hSelBm); - StretchBlt(hSelDC, RECT_WIDTH(rectSel_dest) - 1, 0, -RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), hSelDC, - 0, 0, RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), SRCCOPY); + selectionModel.FlipHorizontally(); ForceRefreshSelectionContents(); } else @@ -499,12 +463,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH case 2: /* flip vertically */ if (selectionWindow.IsWindowVisible()) { - SelectObject(hSelDC, hSelMask); - StretchBlt(hSelDC, 0, RECT_HEIGHT(rectSel_dest) - 1, RECT_WIDTH(rectSel_dest), -RECT_HEIGHT(rectSel_dest), hSelDC, - 0, 0, RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), SRCCOPY); - SelectObject(hSelDC, hSelBm); - StretchBlt(hSelDC, 0, RECT_HEIGHT(rectSel_dest) - 1, RECT_WIDTH(rectSel_dest), -RECT_HEIGHT(rectSel_dest), hSelDC, - 0, 0, RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), SRCCOPY); + selectionModel.FlipVertically(); ForceRefreshSelectionContents(); } else @@ -520,12 +479,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH case 4: /* rotate 180 degrees */ if (selectionWindow.IsWindowVisible()) { - SelectObject(hSelDC, hSelMask); - StretchBlt(hSelDC, RECT_WIDTH(rectSel_dest) - 1, RECT_HEIGHT(rectSel_dest) - 1, -RECT_WIDTH(rectSel_dest), -RECT_HEIGHT(rectSel_dest), hSelDC, - 0, 0, RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), SRCCOPY); - SelectObject(hSelDC, hSelBm); - StretchBlt(hSelDC, RECT_WIDTH(rectSel_dest) - 1, RECT_HEIGHT(rectSel_dest) - 1, -RECT_WIDTH(rectSel_dest), -RECT_HEIGHT(rectSel_dest), hSelDC, - 0, 0, RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), SRCCOPY); + selectionModel.RotateNTimes90Degrees(2); ForceRefreshSelectionContents(); } else @@ -561,7 +515,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH toolsModel.SetBackgroundTransparent(!toolsModel.IsBackgroundTransparent()); break; case IDM_IMAGECROP: - imageModel.Insert((HBITMAP) CopyImage(hSelBm, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG)); + imageModel.Insert((HBITMAP) CopyImage(selectionModel.GetBitmap(), IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG)); break; case IDM_VIEWTOOLBOX: