[MSPAINT] Polymorphism on tools (#4210)

- Introduce polymorphism on tools and mouse actions.
- Implement double-clicking on TOOL_SHAPE.
- Fix some bugs about mouse handling.
CORE-17931
This commit is contained in:
Katayama Hirofumi MZ 2022-01-01 22:02:36 +09:00 committed by GitHub
parent e0a47b7b5f
commit ee132a05ba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 790 additions and 635 deletions

View file

@ -30,6 +30,9 @@
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);
static inline int Zoomed(int xy)
{

View file

@ -106,5 +106,3 @@ extern CStretchSkewDialog stretchSkewDialog;
/* VARIABLES declared in mouse.cpp **********************************/
extern POINT pointStack[256];
extern short pointSP;

View file

@ -159,41 +159,43 @@ LRESULT CImgAreaWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOO
LRESULT CImgAreaWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if ((!drawing) || (toolsModel.GetActiveTool() == TOOL_COLOR))
{
SetCapture();
drawing = TRUE;
startPaintingL(imageModel.GetDC(), UnZoomed(GET_X_LPARAM(lParam)), UnZoomed(GET_Y_LPARAM(lParam)),
paletteModel.GetFgColor(), paletteModel.GetBgColor());
}
else
{
SendMessage(WM_LBUTTONUP, wParam, lParam);
imageModel.Undo();
}
drawing = TRUE;
SetCapture();
INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam);
toolsModel.OnButtonDown(TRUE, UnZoomed(x), UnZoomed(y), FALSE);
Invalidate(FALSE);
return 0;
}
LRESULT CImgAreaWindow::OnLButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
drawing = FALSE;
ReleaseCapture();
INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam);
toolsModel.OnButtonDown(TRUE, UnZoomed(x), UnZoomed(y), TRUE);
toolsModel.resetTool();
Invalidate(FALSE);
if ((toolsModel.GetActiveTool() == TOOL_ZOOM) && (toolsModel.GetZoom() < MAX_ZOOM))
zoomTo(toolsModel.GetZoom() * 2, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
return 0;
}
LRESULT CImgAreaWindow::OnRButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if ((!drawing) || (toolsModel.GetActiveTool() == TOOL_COLOR))
{
SetCapture();
drawing = TRUE;
startPaintingR(imageModel.GetDC(), UnZoomed(GET_X_LPARAM(lParam)), UnZoomed(GET_Y_LPARAM(lParam)),
paletteModel.GetFgColor(), paletteModel.GetBgColor());
}
else
{
SendMessage(WM_RBUTTONUP, wParam, lParam);
imageModel.Undo();
}
drawing = TRUE;
SetCapture();
INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam);
toolsModel.OnButtonDown(FALSE, UnZoomed(x), UnZoomed(y), FALSE);
Invalidate(FALSE);
return 0;
}
LRESULT CImgAreaWindow::OnRButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
drawing = FALSE;
ReleaseCapture();
INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam);
toolsModel.OnButtonDown(FALSE, UnZoomed(x), UnZoomed(y), TRUE);
toolsModel.resetTool();
Invalidate(FALSE);
if ((toolsModel.GetActiveTool() == TOOL_ZOOM) && (toolsModel.GetZoom() > MIN_ZOOM))
zoomTo(toolsModel.GetZoom() / 2, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
return 0;
}
@ -201,62 +203,27 @@ LRESULT CImgAreaWindow::OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOO
{
if (drawing)
{
endPaintingL(imageModel.GetDC(), UnZoomed(GET_X_LPARAM(lParam)), UnZoomed(GET_Y_LPARAM(lParam)), paletteModel.GetFgColor(),
paletteModel.GetBgColor());
drawing = FALSE;
INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam);
toolsModel.OnButtonUp(TRUE, UnZoomed(x), UnZoomed(y));
Invalidate(FALSE);
if (toolsModel.GetActiveTool() == TOOL_COLOR)
{
COLORREF tempColor =
GetPixel(imageModel.GetDC(), UnZoomed(GET_X_LPARAM(lParam)), UnZoomed(GET_Y_LPARAM(lParam)));
if (tempColor != CLR_INVALID)
paletteModel.SetFgColor(tempColor);
}
SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) "");
}
drawing = FALSE;
ReleaseCapture();
return 0;
}
void CImgAreaWindow::cancelDrawing()
{
POINT pt;
switch (toolsModel.GetActiveTool())
{
case TOOL_FREESEL: case TOOL_RECTSEL:
case TOOL_TEXT: case TOOL_ZOOM: case TOOL_SHAPE:
imageModel.ResetToPrevious();
selectionModel.ResetPtStack();
pointSP = 0;
Invalidate(FALSE);
break;
default:
GetCursorPos(&pt);
ScreenToClient(&pt);
// FIXME: dirty hack
if (GetKeyState(VK_LBUTTON) < 0)
{
endPaintingL(imageModel.GetDC(), UnZoomed(pt.x), UnZoomed(pt.y), paletteModel.GetFgColor(),
paletteModel.GetBgColor());
}
else if (GetKeyState(VK_RBUTTON) < 0)
{
endPaintingR(imageModel.GetDC(), UnZoomed(pt.x), UnZoomed(pt.y), paletteModel.GetFgColor(),
paletteModel.GetBgColor());
}
imageModel.Undo();
pointSP = 0;
selectionModel.ResetPtStack();
}
drawing = FALSE;
toolsModel.OnCancelDraw();
Invalidate(FALSE);
}
LRESULT CImgAreaWindow::OnCaptureChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (drawing)
{
cancelDrawing();
drawing = FALSE;
}
return 0;
}
@ -270,14 +237,8 @@ LRESULT CImgAreaWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
}
else
{
switch (toolsModel.GetActiveTool())
{
case TOOL_SHAPE: case TOOL_BEZIER:
cancelDrawing();
break;
default:
break;
}
if (drawing || ToolBase::pointSP != 0)
cancelDrawing();
}
}
return 0;
@ -287,19 +248,12 @@ LRESULT CImgAreaWindow::OnRButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOO
{
if (drawing)
{
endPaintingR(imageModel.GetDC(), UnZoomed(GET_X_LPARAM(lParam)), UnZoomed(GET_Y_LPARAM(lParam)), paletteModel.GetFgColor(),
paletteModel.GetBgColor());
drawing = FALSE;
INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam);
toolsModel.OnButtonUp(FALSE, UnZoomed(x), UnZoomed(y));
Invalidate(FALSE);
if (toolsModel.GetActiveTool() == TOOL_COLOR)
{
COLORREF tempColor =
GetPixel(imageModel.GetDC(), UnZoomed(GET_X_LPARAM(lParam)), UnZoomed(GET_Y_LPARAM(lParam)));
if (tempColor != CLR_INVALID)
paletteModel.SetBgColor(tempColor);
}
SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) "");
}
drawing = FALSE;
ReleaseCapture();
return 0;
}
@ -374,9 +328,9 @@ LRESULT CImgAreaWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOO
default:
break;
}
if ((wParam & MK_LBUTTON) != 0)
if (wParam & MK_LBUTTON)
{
whilePaintingL(imageModel.GetDC(), xNow, yNow, paletteModel.GetFgColor(), paletteModel.GetBgColor());
toolsModel.OnMouseMove(TRUE, xNow, yNow);
Invalidate(FALSE);
if ((toolsModel.GetActiveTool() >= TOOL_TEXT) || (toolsModel.GetActiveTool() == TOOL_RECTSEL) || (toolsModel.GetActiveTool() == TOOL_FREESEL))
{
@ -387,9 +341,9 @@ LRESULT CImgAreaWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOO
SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) (LPCTSTR) strSize);
}
}
if ((wParam & MK_RBUTTON) != 0)
if (wParam & MK_RBUTTON)
{
whilePaintingR(imageModel.GetDC(), xNow, yNow, paletteModel.GetFgColor(), paletteModel.GetBgColor());
toolsModel.OnMouseMove(FALSE, xNow, yNow);
Invalidate(FALSE);
if (toolsModel.GetActiveTool() >= TOOL_TEXT)
{

View file

@ -13,6 +13,10 @@
class CImgAreaWindow : public CWindowImpl<CMainWindow>
{
public:
CImgAreaWindow() : drawing(FALSE)
{
}
DECLARE_WND_CLASS_EX(_T("ImgAreaWindow"), CS_DBLCLKS, COLOR_BTNFACE)
BEGIN_MSG_MAP(CImgAreaWindow)
@ -20,7 +24,9 @@ public:
MESSAGE_HANDLER(WM_PAINT, OnPaint)
MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor)
MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDblClk)
MESSAGE_HANDLER(WM_RBUTTONDOWN, OnRButtonDown)
MESSAGE_HANDLER(WM_RBUTTONDBLCLK, OnRButtonDblClk)
MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
MESSAGE_HANDLER(WM_RBUTTONUP, OnRButtonUp)
MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
@ -39,7 +45,9 @@ private:
LRESULT OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnLButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnRButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnRButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnRButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

File diff suppressed because it is too large Load diff

View file

@ -1,23 +0,0 @@
/*
* PROJECT: PAINT for ReactOS
* LICENSE: LGPL
* FILE: base/applications/mspaint/mouse.h
* PURPOSE: Things which should not be in the mouse event handler itself
* PROGRAMMERS: Benedikt Freisen
*/
#pragma once
void placeSelWin(void);
void startPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg);
void whilePaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg);
void endPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg);
void startPaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg);
void whilePaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg);
void endPaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg);

View file

@ -38,7 +38,6 @@
#include "history.h"
#include "imgarea.h"
#include "miniature.h"
#include "mouse.h"
#include "palette.h"
#include "palettemodel.h"
#include "registry.h"

View file

@ -176,7 +176,23 @@ LRESULT CScrollboxWindow::OnVScroll(UINT nMsg, WPARAM wParam, LPARAM lParam, BOO
LRESULT CScrollboxWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
selectionWindow.ShowWindow(SW_HIDE);
pointSP = 0; // resets the point-buffer of the polygon and bezier functions
switch (toolsModel.GetActiveTool())
{
case TOOL_BEZIER:
case TOOL_SHAPE:
if (ToolBase::pointSP != 0)
{
toolsModel.OnCancelDraw();
imageArea.Invalidate();
}
break;
default:
break;
}
toolsModel.resetTool(); // resets the point-buffer of the polygon and bezier functions
return 0;
}

View file

@ -71,58 +71,42 @@ LRESULT CToolBox::OnSysColorChange(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL
return 0;
}
struct COMMAND_TO_TOOL
{
UINT id;
TOOLTYPE tool;
};
static const COMMAND_TO_TOOL CommandToToolMapping[] =
{
{ ID_FREESEL, TOOL_FREESEL },
{ ID_RECTSEL, TOOL_RECTSEL },
{ ID_RUBBER, TOOL_RUBBER },
{ ID_FILL, TOOL_FILL },
{ ID_COLOR, TOOL_COLOR },
{ ID_ZOOM, TOOL_ZOOM },
{ ID_PEN, TOOL_PEN },
{ ID_BRUSH, TOOL_BRUSH },
{ ID_AIRBRUSH, TOOL_AIRBRUSH },
{ ID_TEXT, TOOL_TEXT },
{ ID_LINE, TOOL_LINE },
{ ID_BEZIER, TOOL_BEZIER },
{ ID_RECT, TOOL_RECT },
{ ID_SHAPE, TOOL_SHAPE },
{ ID_ELLIPSE, TOOL_ELLIPSE },
{ ID_RRECT, TOOL_RRECT },
};
LRESULT CToolBox::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
switch (LOWORD(wParam))
UINT id = LOWORD(wParam);
for (size_t i = 0; i < _countof(CommandToToolMapping); ++i)
{
case ID_FREESEL:
toolsModel.SetActiveTool(TOOL_FREESEL);
break;
case ID_RECTSEL:
toolsModel.SetActiveTool(TOOL_RECTSEL);
break;
case ID_RUBBER:
toolsModel.SetActiveTool(TOOL_RUBBER);
break;
case ID_FILL:
toolsModel.SetActiveTool(TOOL_FILL);
break;
case ID_COLOR:
toolsModel.SetActiveTool(TOOL_COLOR);
break;
case ID_ZOOM:
toolsModel.SetActiveTool(TOOL_ZOOM);
break;
case ID_PEN:
toolsModel.SetActiveTool(TOOL_PEN);
break;
case ID_BRUSH:
toolsModel.SetActiveTool(TOOL_BRUSH);
break;
case ID_AIRBRUSH:
toolsModel.SetActiveTool(TOOL_AIRBRUSH);
break;
case ID_TEXT:
toolsModel.SetActiveTool(TOOL_TEXT);
break;
case ID_LINE:
toolsModel.SetActiveTool(TOOL_LINE);
break;
case ID_BEZIER:
toolsModel.SetActiveTool(TOOL_BEZIER);
break;
case ID_RECT:
toolsModel.SetActiveTool(TOOL_RECT);
break;
case ID_SHAPE:
toolsModel.SetActiveTool(TOOL_SHAPE);
break;
case ID_ELLIPSE:
toolsModel.SetActiveTool(TOOL_ELLIPSE);
break;
case ID_RRECT:
toolsModel.SetActiveTool(TOOL_RRECT);
if (CommandToToolMapping[i].id == id)
{
toolsModel.SetActiveTool(CommandToToolMapping[i].tool);
break;
}
}
return 0;
}
@ -130,6 +114,18 @@ 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);
pointSP = 0; // resets the point-buffer of the polygon and bezier functions
toolsModel.resetTool(); // resets the point-buffer of the polygon and bezier functions
// Check the toolbar button
TOOLTYPE tool = toolsModel.GetActiveTool();
for (size_t i = 0; i < _countof(CommandToToolMapping); ++i)
{
if (CommandToToolMapping[i].tool == tool)
{
toolbar.SendMessage(TB_CHECKBUTTON, CommandToToolMapping[i].id, TRUE);
break;
}
}
return 0;
}

View file

@ -17,11 +17,27 @@ ToolsModel::ToolsModel()
m_lineWidth = 1;
m_shapeStyle = 0;
m_brushStyle = 0;
m_activeTool = TOOL_PEN;
m_oldActiveTool = m_activeTool = TOOL_PEN;
m_airBrushWidth = 5;
m_rubberRadius = 4;
m_transpBg = FALSE;
m_zoom = 1000;
ZeroMemory(&m_tools, sizeof(m_tools));
m_pToolObject = GetOrCreateTool(m_activeTool);
}
ToolsModel::~ToolsModel()
{
for (size_t i = 0; i < TOOL_MAX + 1; ++i)
delete m_tools[i];
}
ToolBase *ToolsModel::GetOrCreateTool(TOOLTYPE nTool)
{
if (!m_tools[nTool])
m_tools[nTool] = ToolBase::createToolObject(nTool);
return m_tools[nTool];
}
int ToolsModel::GetLineWidth() const
@ -62,9 +78,29 @@ TOOLTYPE ToolsModel::GetActiveTool() const
return m_activeTool;
}
TOOLTYPE ToolsModel::GetOldActiveTool() const
{
return m_oldActiveTool;
}
void ToolsModel::SetActiveTool(TOOLTYPE nActiveTool)
{
switch (m_activeTool)
{
case TOOL_FREESEL:
case TOOL_RECTSEL:
case TOOL_RUBBER:
case TOOL_COLOR:
case TOOL_ZOOM:
case TOOL_TEXT:
break;
default:
m_oldActiveTool = m_activeTool;
break;
}
m_activeTool = nActiveTool;
m_pToolObject = GetOrCreateTool(m_activeTool);
NotifyToolChanged();
}
@ -129,3 +165,47 @@ void ToolsModel::NotifyZoomChanged()
{
toolSettingsWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED);
}
void ToolsModel::OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
{
m_pToolObject->beginEvent();
updateStartAndLast(x, y);
m_pToolObject->OnButtonDown(bLeftButton, x, y, bDoubleClick);
m_pToolObject->endEvent();
}
void ToolsModel::OnMouseMove(BOOL bLeftButton, LONG x, LONG y)
{
m_pToolObject->beginEvent();
m_pToolObject->OnMouseMove(bLeftButton, x, y);
updateLast(x, y);
m_pToolObject->endEvent();
}
void ToolsModel::OnButtonUp(BOOL bLeftButton, LONG x, LONG y)
{
m_pToolObject->beginEvent();
m_pToolObject->OnButtonUp(bLeftButton, x, y);
updateLast(x, y);
m_pToolObject->endEvent();
}
void ToolsModel::OnCancelDraw()
{
m_pToolObject->beginEvent();
m_pToolObject->OnCancelDraw();
m_pToolObject->endEvent();
}
void ToolsModel::resetTool()
{
m_pToolObject->reset();
}
void ToolsModel::selectAll()
{
SetActiveTool(TOOL_RECTSEL);
OnButtonDown(TRUE, 0, 0, FALSE);
OnMouseMove(TRUE, imageModel.GetWidth(), imageModel.GetHeight());
OnButtonUp(TRUE, imageModel.GetWidth(), imageModel.GetHeight());
}

View file

@ -26,10 +26,48 @@ enum TOOLTYPE
TOOL_SHAPE = 14,
TOOL_ELLIPSE = 15,
TOOL_RRECT = 16,
TOOL_MAX = TOOL_RRECT,
};
/* CLASSES **********************************************************/
struct ToolBase
{
TOOLTYPE m_tool;
HDC m_hdc;
COLORREF m_fg, m_bg;
static INT pointSP;
static POINT pointStack[256];
ToolBase(TOOLTYPE tool) : m_tool(tool), m_hdc(NULL)
{
}
virtual ~ToolBase()
{
}
virtual void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
{
}
virtual void OnMouseMove(BOOL bLeftButton, LONG x, LONG y)
{
}
virtual void OnButtonUp(BOOL bLeftButton, LONG x, LONG y)
{
}
virtual void OnCancelDraw();
void beginEvent();
void endEvent();
void reset();
static ToolBase* createToolObject(TOOLTYPE type);
};
class ToolsModel
{
private:
@ -37,10 +75,15 @@ private:
int m_shapeStyle;
int m_brushStyle;
TOOLTYPE m_activeTool;
TOOLTYPE m_oldActiveTool;
int m_airBrushWidth;
int m_rubberRadius;
BOOL m_transpBg;
int m_zoom;
ToolBase* m_tools[TOOL_MAX + 1];
ToolBase *m_pToolObject;
ToolBase *GetOrCreateTool(TOOLTYPE nTool);
void NotifyToolChanged();
void NotifyToolSettingsChanged();
@ -48,6 +91,7 @@ private:
public:
ToolsModel();
~ToolsModel();
int GetLineWidth() const;
void SetLineWidth(int nLineWidth);
int GetShapeStyle() const;
@ -55,6 +99,7 @@ public:
int GetBrushStyle() const;
void SetBrushStyle(int nBrushStyle);
TOOLTYPE GetActiveTool() const;
TOOLTYPE GetOldActiveTool() const;
void SetActiveTool(TOOLTYPE nActiveTool);
int GetAirBrushWidth() const;
void SetAirBrushWidth(int nAirBrushWidth);
@ -64,4 +109,12 @@ public:
void SetBackgroundTransparent(BOOL bTransparent);
int GetZoom() const;
void SetZoom(int nZoom);
void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick);
void OnMouseMove(BOOL bLeftButton, LONG x, LONG y);
void OnButtonUp(BOOL bLeftButton, LONG x, LONG y);
void OnCancelDraw();
void resetTool();
void selectAll();
};

View file

@ -559,11 +559,8 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
{
HWND hToolbar = FindWindowEx(toolBoxContainer.m_hWnd, NULL, TOOLBARCLASSNAME, NULL);
SendMessage(hToolbar, TB_CHECKBUTTON, ID_RECTSEL, MAKELPARAM(TRUE, 0));
toolBoxContainer.SendMessage(WM_COMMAND, ID_RECTSEL);
//TODO: do this properly
startPaintingL(imageModel.GetDC(), 0, 0, paletteModel.GetFgColor(), paletteModel.GetBgColor());
whilePaintingL(imageModel.GetDC(), imageModel.GetWidth(), imageModel.GetHeight(), paletteModel.GetFgColor(), paletteModel.GetBgColor());
endPaintingL(imageModel.GetDC(), imageModel.GetWidth(), imageModel.GetHeight(), paletteModel.GetFgColor(), paletteModel.GetBgColor());
toolsModel.selectAll();
imageArea.Invalidate(TRUE);
break;
}
case IDM_EDITCOPYTO: