reactos/base/applications/mspaint/winproc.c
Amine Khaldi 527f2f9057 [SHELL/EXPERIMENTS]
* Create a branch for some evul shell experiments.

svn path=/branches/shell-experiments/; revision=61927
2014-02-02 19:37:27 +00:00

1165 lines
49 KiB
C

/*
* PROJECT: PAINT for ReactOS
* LICENSE: LGPL
* FILE: base/applications/paint/winproc.c
* PURPOSE: Window procedure of the main window and all children apart from
* hPalWin, hToolSettings and hSelection
* PROGRAMMERS: Benedikt Freisen
*/
/* INCLUDES *********************************************************/
#include "precomp.h"
#include "dialogs.h"
#include "registry.h"
/* FUNCTIONS ********************************************************/
void
selectTool(int tool)
{
ShowWindow(hSelection, SW_HIDE);
activeTool = tool;
pointSP = 0; // resets the point-buffer of the polygon and bezier functions
InvalidateRect(hToolSettings, NULL, TRUE);
ShowWindow(hTrackbarZoom, (tool == 6) ? SW_SHOW : SW_HIDE);
}
void
updateCanvasAndScrollbars()
{
ShowWindow(hSelection, SW_HIDE);
MoveWindow(hImageArea, 3, 3, imgXRes * zoom / 1000, imgYRes * zoom / 1000, FALSE);
InvalidateRect(hScrollbox, NULL, TRUE);
InvalidateRect(hImageArea, NULL, FALSE);
SetScrollPos(hScrollbox, SB_HORZ, 0, TRUE);
SetScrollPos(hScrollbox, SB_VERT, 0, TRUE);
}
void
zoomTo(int newZoom, int mouseX, int mouseY)
{
int tbPos = 0;
int tempZoom = newZoom;
long clientRectScrollbox[4];
long clientRectImageArea[4];
int x, y, w, h;
GetClientRect(hScrollbox, (LPRECT) &clientRectScrollbox);
GetClientRect(hImageArea, (LPRECT) &clientRectImageArea);
w = clientRectImageArea[2] * clientRectScrollbox[2] / (clientRectImageArea[2] * newZoom / zoom);
h = clientRectImageArea[3] * clientRectScrollbox[3] / (clientRectImageArea[3] * newZoom / zoom);
x = max(0, min(clientRectImageArea[2] - w, mouseX - w / 2)) * newZoom / zoom;
y = max(0, min(clientRectImageArea[3] - h, mouseY - h / 2)) * newZoom / zoom;
zoom = newZoom;
ShowWindow(hSelection, SW_HIDE);
MoveWindow(hImageArea, 3, 3, imgXRes * zoom / 1000, imgYRes * zoom / 1000, FALSE);
InvalidateRect(hScrollbox, NULL, TRUE);
InvalidateRect(hImageArea, NULL, FALSE);
SendMessage(hScrollbox, WM_HSCROLL, SB_THUMBPOSITION | (x << 16), 0);
SendMessage(hScrollbox, WM_VSCROLL, SB_THUMBPOSITION | (y << 16), 0);
while (tempZoom > 125)
{
tbPos++;
tempZoom = tempZoom >> 1;
}
SendMessage(hTrackbarZoom, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) tbPos);
}
void
drawZoomFrame(int mouseX, int mouseY)
{
HDC hdc;
HPEN oldPen;
HBRUSH oldBrush;
LOGBRUSH logbrush;
int rop;
long clientRectScrollbox[4];
long clientRectImageArea[4];
int x, y, w, h;
GetClientRect(hScrollbox, (LPRECT) &clientRectScrollbox);
GetClientRect(hImageArea, (LPRECT) &clientRectImageArea);
w = clientRectImageArea[2] * clientRectScrollbox[2] / (clientRectImageArea[2] * 2);
h = clientRectImageArea[3] * clientRectScrollbox[3] / (clientRectImageArea[3] * 2);
x = max(0, min(clientRectImageArea[2] - w, mouseX - w / 2));
y = max(0, min(clientRectImageArea[3] - h, mouseY - h / 2));
hdc = GetDC(hImageArea);
oldPen = SelectObject(hdc, CreatePen(PS_SOLID, 0, 0));
logbrush.lbStyle = BS_HOLLOW;
oldBrush = SelectObject(hdc, CreateBrushIndirect(&logbrush));
rop = SetROP2(hdc, R2_NOT);
Rectangle(hdc, x, y, x + w, y + h);
SetROP2(hdc, rop);
DeleteObject(SelectObject(hdc, oldBrush));
DeleteObject(SelectObject(hdc, oldPen));
ReleaseDC(hImageArea, hdc);
}
void
alignChildrenToMainWindow()
{
int x, y, w, h;
RECT clientRect;
GetClientRect(hMainWnd, &clientRect);
if (IsWindowVisible(hToolBoxContainer))
{
x = 56;
w = clientRect.right - 56;
}
else
{
x = 0;
w = clientRect.right;
}
if (IsWindowVisible(hPalWin))
{
y = 49;
h = clientRect.bottom - 49;
}
else
{
y = 3;
h = clientRect.bottom - 3;
}
MoveWindow(hScrollbox, x, y, w, IsWindowVisible(hStatusBar) ? h - 23 : h, TRUE);
MoveWindow(hPalWin, x, 9, 255, 32, TRUE);
}
void
saveImage(BOOL overwrite)
{
if (isAFile && overwrite)
{
SaveDIBToFile(hBms[currInd], filepathname, hDrawingDC, &fileTime, &fileSize, fileHPPM,
fileVPPM);
imageSaved = TRUE;
}
else if (GetSaveFileName(&sfn) != 0)
{
TCHAR tempstr[1000];
TCHAR resstr[100];
SaveDIBToFile(hBms[currInd], sfn.lpstrFile, hDrawingDC, &fileTime, &fileSize,
fileHPPM, fileVPPM);
CopyMemory(filename, sfn.lpstrFileTitle, sizeof(filename));
CopyMemory(filepathname, sfn.lpstrFile, sizeof(filepathname));
LoadString(hProgInstance, IDS_WINDOWTITLE, resstr, SIZEOF(resstr));
_stprintf(tempstr, resstr, filename);
SetWindowText(hMainWnd, tempstr);
isAFile = TRUE;
imageSaved = TRUE;
}
}
void
UpdateApplicationProperties(HBITMAP bitmap, LPTSTR newfilename, LPTSTR newfilepathname)
{
TCHAR tempstr[1000];
TCHAR resstr[100];
insertReversible(bitmap);
updateCanvasAndScrollbars();
CopyMemory(filename, newfilename, sizeof(filename));
CopyMemory(filepathname, newfilepathname, sizeof(filepathname));
LoadString(hProgInstance, IDS_WINDOWTITLE, resstr, SIZEOF(resstr));
_stprintf(tempstr, resstr, filename);
SetWindowText(hMainWnd, tempstr);
clearHistory();
isAFile = TRUE;
}
void
InsertSelectionFromHBITMAP(HBITMAP bitmap, HWND window)
{
HWND hToolbar = FindWindowEx(hToolBoxContainer, NULL, TOOLBARCLASSNAME, NULL);
SendMessage(hToolbar, TB_CHECKBUTTON, ID_RECTSEL, MAKELONG(TRUE, 0));
SendMessage(window, WM_COMMAND, ID_RECTSEL, 0);
DeleteObject(SelectObject(hSelDC, hSelBm = CopyImage(bitmap,
IMAGE_BITMAP, 0, 0,
LR_COPYRETURNORG)));
newReversible();
rectSel_src[0] = rectSel_src[1] = rectSel_src[2] = rectSel_src[3] = 0;
rectSel_dest[0] = rectSel_dest[1] = 0;
rectSel_dest[2] = GetDIBWidth(hSelBm);
rectSel_dest[3] = GetDIBHeight(hSelBm);
BitBlt(hDrawingDC, rectSel_dest[0], rectSel_dest[1], rectSel_dest[2], rectSel_dest[3],
hSelDC, 0, 0, SRCCOPY);
placeSelWin();
ShowWindow(hSelection, SW_SHOW);
}
BOOL drawing;
LRESULT CALLBACK
WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) /* handle the messages */
{
case WM_DROPFILES:
{
HDROP drophandle;
TCHAR droppedfile[MAX_PATH];
HBITMAP bmNew = NULL;
drophandle = (HDROP)wParam;
DragQueryFile(drophandle, 0, droppedfile, SIZEOF(droppedfile));
DragFinish(drophandle);
LoadDIBFromFile(&bmNew, droppedfile, &fileTime, &fileSize, &fileHPPM, &fileVPPM);
if (bmNew != NULL)
{
TCHAR *pathend;
pathend = _tcsrchr(droppedfile, '\\');
pathend++;
UpdateApplicationProperties(bmNew, pathend, pathend);
}
break;
}
case WM_CREATE:
ptStack = NULL;
ptSP = 0;
break;
case WM_DESTROY:
PostQuitMessage(0); /* send a WM_QUIT to the message queue */
break;
case WM_CLOSE:
if (hwnd == hwndMiniature)
{
ShowWindow(hwndMiniature, SW_HIDE);
showMiniature = FALSE;
break;
}
if (!imageSaved)
{
TCHAR programname[20];
TCHAR saveprompttext[100];
TCHAR temptext[500];
LoadString(hProgInstance, IDS_PROGRAMNAME, programname, SIZEOF(programname));
LoadString(hProgInstance, IDS_SAVEPROMPTTEXT, saveprompttext, SIZEOF(saveprompttext));
_stprintf(temptext, saveprompttext, filename);
switch (MessageBox(hwnd, temptext, programname, MB_YESNOCANCEL | MB_ICONQUESTION))
{
case IDNO:
DestroyWindow(hwnd);
break;
case IDYES:
saveImage(FALSE);
if (imageSaved)
DestroyWindow(hwnd);
break;
}
}
else
{
DestroyWindow(hwnd);
}
break;
case WM_INITMENUPOPUP:
switch (lParam)
{
case 0:
if (isAFile)
{
EnableMenuItem(GetMenu(hMainWnd), IDM_FILEASWALLPAPERPLANE,
MF_ENABLED | MF_BYCOMMAND);
EnableMenuItem(GetMenu(hMainWnd), IDM_FILEASWALLPAPERCENTERED,
MF_ENABLED | MF_BYCOMMAND);
EnableMenuItem(GetMenu(hMainWnd), IDM_FILEASWALLPAPERSTRETCHED,
MF_ENABLED | MF_BYCOMMAND);
}
else
{
EnableMenuItem(GetMenu(hMainWnd), IDM_FILEASWALLPAPERPLANE,
MF_GRAYED | MF_BYCOMMAND);
EnableMenuItem(GetMenu(hMainWnd), IDM_FILEASWALLPAPERCENTERED,
MF_GRAYED | MF_BYCOMMAND);
EnableMenuItem(GetMenu(hMainWnd), IDM_FILEASWALLPAPERSTRETCHED,
MF_GRAYED | MF_BYCOMMAND);
}
break;
case 1:
EnableMenuItem(GetMenu(hMainWnd), IDM_EDITUNDO,
(undoSteps > 0) ? (MF_ENABLED | MF_BYCOMMAND) : (MF_GRAYED | MF_BYCOMMAND));
EnableMenuItem(GetMenu(hMainWnd), IDM_EDITREDO,
(redoSteps > 0) ? (MF_ENABLED | MF_BYCOMMAND) : (MF_GRAYED | MF_BYCOMMAND));
if (IsWindowVisible(hSelection))
{
EnableMenuItem(GetMenu(hMainWnd), IDM_EDITCUT, MF_ENABLED | MF_BYCOMMAND);
EnableMenuItem(GetMenu(hMainWnd), IDM_EDITCOPY, MF_ENABLED | MF_BYCOMMAND);
EnableMenuItem(GetMenu(hMainWnd), IDM_EDITDELETESELECTION, MF_ENABLED | MF_BYCOMMAND);
EnableMenuItem(GetMenu(hMainWnd), IDM_EDITINVERTSELECTION, MF_ENABLED | MF_BYCOMMAND);
EnableMenuItem(GetMenu(hMainWnd), IDM_EDITCOPYTO, MF_ENABLED | MF_BYCOMMAND);
}
else
{
EnableMenuItem(GetMenu(hMainWnd), IDM_EDITCUT, MF_GRAYED | MF_BYCOMMAND);
EnableMenuItem(GetMenu(hMainWnd), IDM_EDITCOPY, MF_GRAYED | MF_BYCOMMAND);
EnableMenuItem(GetMenu(hMainWnd), IDM_EDITDELETESELECTION, MF_GRAYED | MF_BYCOMMAND);
EnableMenuItem(GetMenu(hMainWnd), IDM_EDITINVERTSELECTION, MF_GRAYED | MF_BYCOMMAND);
EnableMenuItem(GetMenu(hMainWnd), IDM_EDITCOPYTO, MF_GRAYED | MF_BYCOMMAND);
}
OpenClipboard(hMainWnd);
if (GetClipboardData(CF_BITMAP) != NULL)
EnableMenuItem(GetMenu(hMainWnd), IDM_EDITPASTE, MF_ENABLED | MF_BYCOMMAND);
else
EnableMenuItem(GetMenu(hMainWnd), IDM_EDITPASTE, MF_GRAYED | MF_BYCOMMAND);
CloseClipboard();
break;
case 3:
if (IsWindowVisible(hSelection))
EnableMenuItem(GetMenu(hMainWnd), IDM_IMAGECROP, MF_ENABLED | MF_BYCOMMAND);
else
EnableMenuItem(GetMenu(hMainWnd), IDM_IMAGECROP, MF_GRAYED | MF_BYCOMMAND);
CheckMenuItem(GetMenu(hMainWnd), IDM_IMAGEDRAWOPAQUE, (transpBg == 0) ?
(MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
break;
}
CheckMenuItem(GetMenu(hMainWnd), IDM_VIEWTOOLBOX,
IsWindowVisible(hToolBoxContainer) ?
(MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
CheckMenuItem(GetMenu(hMainWnd), IDM_VIEWCOLORPALETTE,
IsWindowVisible(hPalWin) ?
(MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
CheckMenuItem(GetMenu(hMainWnd), IDM_VIEWSTATUSBAR,
IsWindowVisible(hStatusBar) ?
(MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
CheckMenuItem(GetMenu(hMainWnd), IDM_VIEWSHOWGRID,
showGrid ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
CheckMenuItem(GetMenu(hMainWnd), IDM_VIEWSHOWMINIATURE,
showMiniature ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
CheckMenuItem(GetMenu(hMainWnd), IDM_VIEWZOOM125,
(zoom == 125) ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
CheckMenuItem(GetMenu(hMainWnd), IDM_VIEWZOOM25,
(zoom == 250) ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
CheckMenuItem(GetMenu(hMainWnd), IDM_VIEWZOOM50,
(zoom == 500) ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
CheckMenuItem(GetMenu(hMainWnd), IDM_VIEWZOOM100,
(zoom == 1000) ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
CheckMenuItem(GetMenu(hMainWnd), IDM_VIEWZOOM200,
(zoom == 2000) ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
CheckMenuItem(GetMenu(hMainWnd), IDM_VIEWZOOM400,
(zoom == 4000) ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
CheckMenuItem(GetMenu(hMainWnd), IDM_VIEWZOOM800,
(zoom == 8000) ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
CheckMenuItem(GetMenu(hMainWnd), IDM_COLORSMODERNPALETTE,
(selectedPalette == 1) ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
CheckMenuItem(GetMenu(hMainWnd), IDM_COLORSOLDPALETTE,
(selectedPalette == 2) ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND));
break;
case WM_SIZE:
if (hwnd == hMainWnd)
{
int test[] = { LOWORD(lParam) - 260, LOWORD(lParam) - 140, LOWORD(lParam) - 20 };
SendMessage(hStatusBar, WM_SIZE, wParam, lParam);
SendMessage(hStatusBar, SB_SETPARTS, 3, (LPARAM)&test);
alignChildrenToMainWindow();
InvalidateRect(hwnd, NULL, TRUE);
}
if (hwnd == hImageArea)
{
MoveWindow(hSizeboxLeftTop,
0,
0, 3, 3, TRUE);
MoveWindow(hSizeboxCenterTop,
imgXRes * zoom / 2000 + 3 * 3 / 4,
0, 3, 3, TRUE);
MoveWindow(hSizeboxRightTop,
imgXRes * zoom / 1000 + 3,
0, 3, 3, TRUE);
MoveWindow(hSizeboxLeftCenter,
0,
imgYRes * zoom / 2000 + 3 * 3 / 4, 3, 3, TRUE);
MoveWindow(hSizeboxRightCenter,
imgXRes * zoom / 1000 + 3,
imgYRes * zoom / 2000 + 3 * 3 / 4, 3, 3, TRUE);
MoveWindow(hSizeboxLeftBottom,
0,
imgYRes * zoom / 1000 + 3, 3, 3, TRUE);
MoveWindow(hSizeboxCenterBottom,
imgXRes * zoom / 2000 + 3 * 3 / 4,
imgYRes * zoom / 1000 + 3, 3, 3, TRUE);
MoveWindow(hSizeboxRightBottom,
imgXRes * zoom / 1000 + 3,
imgYRes * zoom / 1000 + 3, 3, 3, TRUE);
}
if ((hwnd == hImageArea) || (hwnd == hScrollbox))
{
long clientRectScrollbox[4];
long clientRectImageArea[4];
SCROLLINFO si;
GetClientRect(hScrollbox, (LPRECT) &clientRectScrollbox);
GetClientRect(hImageArea, (LPRECT) &clientRectImageArea);
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_PAGE | SIF_RANGE;
si.nMax = clientRectImageArea[2] + 6 - 1;
si.nMin = 0;
si.nPage = clientRectScrollbox[2];
SetScrollInfo(hScrollbox, SB_HORZ, &si, TRUE);
GetClientRect(hScrollbox, (LPRECT) clientRectScrollbox);
si.nMax = clientRectImageArea[3] + 6 - 1;
si.nPage = clientRectScrollbox[3];
SetScrollInfo(hScrollbox, SB_VERT, &si, TRUE);
MoveWindow(hScrlClient,
-GetScrollPos(hScrollbox, SB_HORZ), -GetScrollPos(hScrollbox, SB_VERT),
max(clientRectImageArea[2] + 6, clientRectScrollbox[2]),
max(clientRectImageArea[3] + 6, clientRectScrollbox[3]), TRUE);
}
break;
case WM_HSCROLL:
if (hwnd == hScrollbox)
{
SCROLLINFO si;
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_ALL;
GetScrollInfo(hScrollbox, SB_HORZ, &si);
switch (LOWORD(wParam))
{
case SB_THUMBTRACK:
case SB_THUMBPOSITION:
si.nPos = HIWORD(wParam);
break;
case SB_LINELEFT:
si.nPos -= 5;
break;
case SB_LINERIGHT:
si.nPos += 5;
break;
case SB_PAGELEFT:
si.nPos -= si.nPage;
break;
case SB_PAGERIGHT:
si.nPos += si.nPage;
break;
}
SetScrollInfo(hScrollbox, SB_HORZ, &si, TRUE);
MoveWindow(hScrlClient, -GetScrollPos(hScrollbox, SB_HORZ),
-GetScrollPos(hScrollbox, SB_VERT), imgXRes * zoom / 1000 + 6,
imgYRes * zoom / 1000 + 6, TRUE);
}
break;
case WM_VSCROLL:
if (hwnd == hScrollbox)
{
SCROLLINFO si;
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_ALL;
GetScrollInfo(hScrollbox, SB_VERT, &si);
switch (LOWORD(wParam))
{
case SB_THUMBTRACK:
case SB_THUMBPOSITION:
si.nPos = HIWORD(wParam);
break;
case SB_LINEUP:
si.nPos -= 5;
break;
case SB_LINEDOWN:
si.nPos += 5;
break;
case SB_PAGEUP:
si.nPos -= si.nPage;
break;
case SB_PAGEDOWN:
si.nPos += si.nPage;
break;
}
SetScrollInfo(hScrollbox, SB_VERT, &si, TRUE);
MoveWindow(hScrlClient, -GetScrollPos(hScrollbox, SB_HORZ),
-GetScrollPos(hScrollbox, SB_VERT), imgXRes * zoom / 1000 + 6,
imgYRes * zoom / 1000 + 6, TRUE);
}
break;
case WM_GETMINMAXINFO:
if (hwnd == hMainWnd)
{
MINMAXINFO *mm = (LPMINMAXINFO) lParam;
mm->ptMinTrackSize.x = 330;
mm->ptMinTrackSize.y = 430;
}
break;
case WM_PAINT:
DefWindowProc(hwnd, message, wParam, lParam);
if (hwnd == hImageArea)
{
HDC hdc = GetDC(hImageArea);
StretchBlt(hdc, 0, 0, imgXRes * zoom / 1000, imgYRes * zoom / 1000, hDrawingDC, 0, 0, imgXRes,
imgYRes, SRCCOPY);
if (showGrid && (zoom >= 4000))
{
HPEN oldPen = SelectObject(hdc, CreatePen(PS_SOLID, 1, 0x00a0a0a0));
int counter;
for(counter = 0; counter <= imgYRes; counter++)
{
MoveToEx(hdc, 0, counter * zoom / 1000, NULL);
LineTo(hdc, imgXRes * zoom / 1000, counter * zoom / 1000);
}
for(counter = 0; counter <= imgXRes; counter++)
{
MoveToEx(hdc, counter * zoom / 1000, 0, NULL);
LineTo(hdc, counter * zoom / 1000, imgYRes * zoom / 1000);
}
DeleteObject(SelectObject(hdc, oldPen));
}
ReleaseDC(hImageArea, hdc);
InvalidateRect(hSelection, NULL, FALSE);
InvalidateRect(hwndMiniature, NULL, FALSE);
}
else if (hwnd == hwndMiniature)
{
RECT mclient;
HDC hdc;
GetClientRect(hwndMiniature, &mclient);
hdc = GetDC(hwndMiniature);
StretchBlt(hdc, 0, 0, mclient.right, mclient.bottom, hDrawingDC, 0, 0, imgXRes, imgYRes, SRCCOPY);
ReleaseDC(hwndMiniature, hdc);
}
break;
// mouse events used for drawing
case WM_SETCURSOR:
if (hwnd == hImageArea)
{
switch (activeTool)
{
case TOOL_FILL:
SetCursor(hCurFill);
break;
case TOOL_COLOR:
SetCursor(hCurColor);
break;
case TOOL_ZOOM:
SetCursor(hCurZoom);
break;
case TOOL_PEN:
SetCursor(hCurPen);
break;
case TOOL_AIRBRUSH:
SetCursor(hCurAirbrush);
break;
default:
SetCursor(LoadCursor(NULL, IDC_CROSS));
}
}
else
DefWindowProc(hwnd, message, wParam, lParam);
break;
case WM_LBUTTONDOWN:
if (hwnd == hImageArea)
{
if ((!drawing) || (activeTool == TOOL_COLOR))
{
SetCapture(hImageArea);
drawing = TRUE;
startPaintingL(hDrawingDC, GET_X_LPARAM(lParam) * 1000 / zoom, GET_Y_LPARAM(lParam) * 1000 / zoom,
fgColor, bgColor);
}
else
{
SendMessage(hwnd, WM_LBUTTONUP, wParam, lParam);
undo();
}
InvalidateRect(hImageArea, NULL, FALSE);
if ((activeTool == TOOL_ZOOM) && (zoom < 8000))
zoomTo(zoom * 2, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
}
break;
case WM_RBUTTONDOWN:
if (hwnd == hImageArea)
{
if ((!drawing) || (activeTool == TOOL_COLOR))
{
SetCapture(hImageArea);
drawing = TRUE;
startPaintingR(hDrawingDC, GET_X_LPARAM(lParam) * 1000 / zoom, GET_Y_LPARAM(lParam) * 1000 / zoom,
fgColor, bgColor);
}
else
{
SendMessage(hwnd, WM_RBUTTONUP, wParam, lParam);
undo();
}
InvalidateRect(hImageArea, NULL, FALSE);
if ((activeTool == TOOL_ZOOM) && (zoom > 125))
zoomTo(zoom / 2, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
}
break;
case WM_LBUTTONUP:
if ((hwnd == hImageArea) && drawing)
{
ReleaseCapture();
drawing = FALSE;
endPaintingL(hDrawingDC, GET_X_LPARAM(lParam) * 1000 / zoom, GET_Y_LPARAM(lParam) * 1000 / zoom, fgColor,
bgColor);
InvalidateRect(hImageArea, NULL, FALSE);
if (activeTool == TOOL_COLOR)
{
int tempColor =
GetPixel(hDrawingDC, GET_X_LPARAM(lParam) * 1000 / zoom, GET_Y_LPARAM(lParam) * 1000 / zoom);
if (tempColor != CLR_INVALID)
fgColor = tempColor;
InvalidateRect(hPalWin, NULL, FALSE);
}
SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) "");
}
break;
case WM_RBUTTONUP:
if ((hwnd == hImageArea) && drawing)
{
ReleaseCapture();
drawing = FALSE;
endPaintingR(hDrawingDC, GET_X_LPARAM(lParam) * 1000 / zoom, GET_Y_LPARAM(lParam) * 1000 / zoom, fgColor,
bgColor);
InvalidateRect(hImageArea, NULL, FALSE);
if (activeTool == TOOL_COLOR)
{
int tempColor =
GetPixel(hDrawingDC, GET_X_LPARAM(lParam) * 1000 / zoom, GET_Y_LPARAM(lParam) * 1000 / zoom);
if (tempColor != CLR_INVALID)
bgColor = tempColor;
InvalidateRect(hPalWin, NULL, FALSE);
}
SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) "");
}
break;
case WM_KEYDOWN:
if (wParam == VK_ESCAPE)
{
if (!drawing)
{
/* Deselect */
if ((activeTool == TOOL_RECTSEL) || (activeTool == TOOL_FREESEL))
{
startPaintingL(hDrawingDC, 0, 0, fgColor, bgColor);
whilePaintingL(hDrawingDC, 0, 0, fgColor, bgColor);
endPaintingL(hDrawingDC, 0, 0, fgColor, bgColor);
ShowWindow(hSelection, SW_HIDE);
}
}
/* FIXME: also cancel current drawing underway */
}
break;
case WM_MOUSEMOVE:
if (hwnd == hImageArea)
{
LONG xNow = GET_X_LPARAM(lParam) * 1000 / zoom;
LONG yNow = GET_Y_LPARAM(lParam) * 1000 / zoom;
if ((!drawing) || (activeTool <= TOOL_AIRBRUSH))
{
TRACKMOUSEEVENT tme;
if (activeTool == TOOL_ZOOM)
{
InvalidateRect(hImageArea, NULL, FALSE);
UpdateWindow(hImageArea);
drawZoomFrame(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
}
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = hImageArea;
tme.dwHoverTime = 0;
TrackMouseEvent(&tme);
if (!drawing)
{
TCHAR coordStr[100];
_stprintf(coordStr, _T("%d, %d"), xNow, yNow);
SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) coordStr);
}
}
if (drawing)
{
/* values displayed in statusbar */
LONG xRel = xNow - start.x;
LONG yRel = yNow - start.y;
/* freesel, rectsel and text tools always show numbers limited to fit into image area */
if ((activeTool == TOOL_FREESEL) || (activeTool == TOOL_RECTSEL) || (activeTool == TOOL_TEXT))
{
if (xRel < 0)
xRel = (xNow < 0) ? -start.x : xRel;
else if (xNow > imgXRes)
xRel = imgXRes-start.x;
if (yRel < 0)
yRel = (yNow < 0) ? -start.y : yRel;
else if (yNow > imgYRes)
yRel = imgYRes-start.y;
}
/* rectsel and shape tools always show non-negative numbers when drawing */
if ((activeTool == TOOL_RECTSEL) || (activeTool == TOOL_SHAPE))
{
if (xRel < 0)
xRel = -xRel;
if (yRel < 0)
yRel = -yRel;
}
/* while drawing, update cursor coordinates only for tools 3, 7, 8, 9, 14 */
switch(activeTool)
{
case TOOL_RUBBER:
case TOOL_PEN:
case TOOL_BRUSH:
case TOOL_AIRBRUSH:
case TOOL_SHAPE:
{
TCHAR coordStr[100];
_stprintf(coordStr, _T("%d, %d"), xNow, yNow);
SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) coordStr);
break;
}
}
if ((wParam & MK_LBUTTON) != 0)
{
whilePaintingL(hDrawingDC, xNow, yNow, fgColor, bgColor);
InvalidateRect(hImageArea, NULL, FALSE);
if ((activeTool >= TOOL_TEXT) || (activeTool == TOOL_RECTSEL) || (activeTool == TOOL_FREESEL))
{
TCHAR sizeStr[100];
if ((activeTool >= TOOL_LINE) && (GetAsyncKeyState(VK_SHIFT) < 0))
yRel = xRel;
_stprintf(sizeStr, _T("%d x %d"), xRel, yRel);
SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) sizeStr);
}
}
if ((wParam & MK_RBUTTON) != 0)
{
whilePaintingR(hDrawingDC, xNow, yNow, fgColor, bgColor);
InvalidateRect(hImageArea, NULL, FALSE);
if (activeTool >= TOOL_TEXT)
{
TCHAR sizeStr[100];
if ((activeTool >= TOOL_LINE) && (GetAsyncKeyState(VK_SHIFT) < 0))
yRel = xRel;
_stprintf(sizeStr, _T("%d x %d"), xRel, yRel);
SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) sizeStr);
}
}
}
}
break;
case WM_MOUSELEAVE:
SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) _T(""));
if (activeTool == TOOL_ZOOM)
InvalidateRect(hImageArea, NULL, FALSE);
break;
// menu and button events
case WM_SYSCOLORCHANGE:
{
/* Redirect message to common controls */
HWND hToolbar = FindWindowEx(hToolBoxContainer, NULL, TOOLBARCLASSNAME, NULL);
SendMessage(hToolbar, WM_SYSCOLORCHANGE, 0, 0);
break;
}
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDM_HELPINFO:
{
HICON paintIcon = LoadIcon(hProgInstance, MAKEINTRESOURCE(IDI_APPICON));
TCHAR infotitle[100];
TCHAR infotext[200];
LoadString(hProgInstance, IDS_INFOTITLE, infotitle, SIZEOF(infotitle));
LoadString(hProgInstance, IDS_INFOTEXT, infotext, SIZEOF(infotext));
ShellAbout(hMainWnd, infotitle, infotext, paintIcon);
DeleteObject(paintIcon);
break;
}
case IDM_HELPHELPTOPICS:
//HtmlHelp(hMainWnd, "help\\Paint.chm", 0, 0);
break;
case IDM_FILEEXIT:
SendMessage(hwnd, WM_CLOSE, wParam, lParam);
break;
case IDM_FILENEW:
{
BOOL reset = TRUE;
if (!imageSaved)
{
TCHAR programname[20];
TCHAR saveprompttext[100];
TCHAR temptext[500];
LoadString(hProgInstance, IDS_PROGRAMNAME, programname, SIZEOF(programname));
LoadString(hProgInstance, IDS_SAVEPROMPTTEXT, saveprompttext, SIZEOF(saveprompttext));
_stprintf(temptext, saveprompttext, filename);
switch (MessageBox(hwnd, temptext, programname, MB_YESNOCANCEL | MB_ICONQUESTION))
{
case IDNO:
imageSaved = TRUE;
break;
case IDYES:
saveImage(FALSE);
break;
case IDCANCEL:
reset = FALSE;
break;
}
}
if (reset && imageSaved)
{
Rectangle(hDrawingDC, 0 - 1, 0 - 1, imgXRes + 1, imgYRes + 1);
InvalidateRect(hImageArea, NULL, FALSE);
updateCanvasAndScrollbars();
clearHistory();
}
break;
}
case IDM_FILEOPEN:
if (GetOpenFileName(&ofn) != 0)
{
HBITMAP bmNew = NULL;
LoadDIBFromFile(&bmNew, ofn.lpstrFile, &fileTime, &fileSize, &fileHPPM, &fileVPPM);
if (bmNew != NULL)
{
UpdateApplicationProperties(bmNew, ofn.lpstrFileTitle, ofn.lpstrFileTitle);
}
}
break;
case IDM_FILESAVE:
saveImage(TRUE);
break;
case IDM_FILESAVEAS:
saveImage(FALSE);
break;
case IDM_FILEASWALLPAPERPLANE:
SetWallpaper(filepathname, 1, 1);
break;
case IDM_FILEASWALLPAPERCENTERED:
SetWallpaper(filepathname, 1, 0);
break;
case IDM_FILEASWALLPAPERSTRETCHED:
SetWallpaper(filepathname, 2, 0);
break;
case IDM_EDITUNDO:
undo();
InvalidateRect(hImageArea, NULL, FALSE);
break;
case IDM_EDITREDO:
redo();
InvalidateRect(hImageArea, NULL, FALSE);
break;
case IDM_EDITCOPY:
OpenClipboard(hMainWnd);
EmptyClipboard();
SetClipboardData(CF_BITMAP, CopyImage(hSelBm, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG));
CloseClipboard();
break;
case IDM_EDITCUT:
/* Copy */
SendMessage(hwnd, WM_COMMAND, IDM_EDITCOPY, 0);
/* Delete selection */
SendMessage(hwnd, WM_COMMAND, IDM_EDITDELETESELECTION, 0);
break;
case IDM_EDITPASTE:
OpenClipboard(hMainWnd);
if (GetClipboardData(CF_BITMAP) != NULL)
{
InsertSelectionFromHBITMAP(GetClipboardData(CF_BITMAP), hwnd);
}
CloseClipboard();
break;
case IDM_EDITDELETESELECTION:
{
/* remove selection window and already painted content using undo(),
paint Rect for rectangular selections and Poly for freeform selections */
undo();
if (activeTool == TOOL_RECTSEL)
{
newReversible();
Rect(hDrawingDC, rectSel_dest[0], rectSel_dest[1], rectSel_dest[2] + rectSel_dest[0],
rectSel_dest[3] + rectSel_dest[1], bgColor, bgColor, 0, TRUE);
}
if (activeTool == TOOL_FREESEL)
{
newReversible();
Poly(hDrawingDC, ptStack, ptSP + 1, 0, 0, 2, 0, FALSE);
}
break;
}
case IDM_EDITSELECTALL:
{
HWND hToolbar = FindWindowEx(hToolBoxContainer, NULL, TOOLBARCLASSNAME, NULL);
SendMessage(hToolbar, TB_CHECKBUTTON, ID_RECTSEL, MAKELONG(TRUE, 0));
SendMessage(hwnd, WM_COMMAND, ID_RECTSEL, 0);
startPaintingL(hDrawingDC, 0, 0, fgColor, bgColor);
whilePaintingL(hDrawingDC, imgXRes, imgYRes, fgColor, bgColor);
endPaintingL(hDrawingDC, imgXRes, imgYRes, fgColor, bgColor);
break;
}
case IDM_EDITCOPYTO:
if (GetSaveFileName(&ofn) != 0)
SaveDIBToFile(hSelBm, ofn.lpstrFile, hDrawingDC, NULL, NULL, fileHPPM, fileVPPM);
break;
case IDM_EDITPASTEFROM:
if (GetOpenFileName(&ofn) != 0)
{
HBITMAP bmNew = NULL;
LoadDIBFromFile(&bmNew, ofn.lpstrFile, &fileTime, &fileSize, &fileHPPM, &fileVPPM);
if (bmNew != NULL)
{
InsertSelectionFromHBITMAP(bmNew, hwnd);
DeleteObject(bmNew);
}
}
break;
case IDM_COLORSEDITPALETTE:
if (ChooseColor(&choosecolor))
{
fgColor = choosecolor.rgbResult;
InvalidateRect(hPalWin, NULL, FALSE);
}
break;
case IDM_COLORSMODERNPALETTE:
selectedPalette = 1;
CopyMemory(palColors, modernPalColors, sizeof(palColors));
InvalidateRect(hPalWin, NULL, FALSE);
break;
case IDM_COLORSOLDPALETTE:
selectedPalette = 2;
CopyMemory(palColors, oldPalColors, sizeof(palColors));
InvalidateRect(hPalWin, NULL, FALSE);
break;
case IDM_IMAGEINVERTCOLORS:
{
RECT tempRect;
newReversible();
SetRect(&tempRect, 0, 0, imgXRes, imgYRes);
InvertRect(hDrawingDC, &tempRect);
InvalidateRect(hImageArea, NULL, FALSE);
break;
}
case IDM_IMAGEDELETEIMAGE:
newReversible();
Rect(hDrawingDC, 0, 0, imgXRes, imgYRes, bgColor, bgColor, 0, TRUE);
InvalidateRect(hImageArea, NULL, FALSE);
break;
case IDM_IMAGEROTATEMIRROR:
switch (mirrorRotateDlg())
{
case 1: /* flip horizontally */
if (IsWindowVisible(hSelection))
{
SelectObject(hSelDC, hSelMask);
StretchBlt(hSelDC, rectSel_dest[2] - 1, 0, -rectSel_dest[2], rectSel_dest[3], hSelDC,
0, 0, rectSel_dest[2], rectSel_dest[3], SRCCOPY);
SelectObject(hSelDC, hSelBm);
StretchBlt(hSelDC, rectSel_dest[2] - 1, 0, -rectSel_dest[2], rectSel_dest[3], hSelDC,
0, 0, rectSel_dest[2], rectSel_dest[3], SRCCOPY);
/* force refresh of selection contents, used also in case 2 and case 4 */
SendMessage(hSelection, WM_LBUTTONDOWN, 0, 0);
SendMessage(hSelection, WM_MOUSEMOVE, 0, 0);
SendMessage(hSelection, WM_LBUTTONUP, 0, 0);
}
else
{
newReversible();
StretchBlt(hDrawingDC, imgXRes - 1, 0, -imgXRes, imgYRes, hDrawingDC, 0, 0,
imgXRes, imgYRes, SRCCOPY);
InvalidateRect(hImageArea, NULL, FALSE);
}
break;
case 2: /* flip vertically */
if (IsWindowVisible(hSelection))
{
SelectObject(hSelDC, hSelMask);
StretchBlt(hSelDC, 0, rectSel_dest[3] - 1, rectSel_dest[2], -rectSel_dest[3], hSelDC,
0, 0, rectSel_dest[2], rectSel_dest[3], SRCCOPY);
SelectObject(hSelDC, hSelBm);
StretchBlt(hSelDC, 0, rectSel_dest[3] - 1, rectSel_dest[2], -rectSel_dest[3], hSelDC,
0, 0, rectSel_dest[2], rectSel_dest[3], SRCCOPY);
SendMessage(hSelection, WM_LBUTTONDOWN, 0, 0);
SendMessage(hSelection, WM_MOUSEMOVE, 0, 0);
SendMessage(hSelection, WM_LBUTTONUP, 0, 0);
}
else
{
newReversible();
StretchBlt(hDrawingDC, 0, imgYRes - 1, imgXRes, -imgYRes, hDrawingDC, 0, 0,
imgXRes, imgYRes, SRCCOPY);
InvalidateRect(hImageArea, NULL, FALSE);
}
break;
case 3: /* rotate 90 degrees */
break;
case 4: /* rotate 180 degrees */
if (IsWindowVisible(hSelection))
{
SelectObject(hSelDC, hSelMask);
StretchBlt(hSelDC, rectSel_dest[2] - 1, rectSel_dest[3] - 1, -rectSel_dest[2], -rectSel_dest[3], hSelDC,
0, 0, rectSel_dest[2], rectSel_dest[3], SRCCOPY);
SelectObject(hSelDC, hSelBm);
StretchBlt(hSelDC, rectSel_dest[2] - 1, rectSel_dest[3] - 1, -rectSel_dest[2], -rectSel_dest[3], hSelDC,
0, 0, rectSel_dest[2], rectSel_dest[3], SRCCOPY);
SendMessage(hSelection, WM_LBUTTONDOWN, 0, 0);
SendMessage(hSelection, WM_MOUSEMOVE, 0, 0);
SendMessage(hSelection, WM_LBUTTONUP, 0, 0);
}
else
{
newReversible();
StretchBlt(hDrawingDC, imgXRes - 1, imgYRes - 1, -imgXRes, -imgYRes, hDrawingDC,
0, 0, imgXRes, imgYRes, SRCCOPY);
InvalidateRect(hImageArea, NULL, FALSE);
}
break;
case 5: /* rotate 270 degrees */
break;
}
break;
case IDM_IMAGEATTRIBUTES:
{
if (attributesDlg())
{
cropReversible(widthSetInDlg, heightSetInDlg, 0, 0);
updateCanvasAndScrollbars();
}
break;
}
case IDM_IMAGESTRETCHSKEW:
{
if (changeSizeDlg())
{
insertReversible(CopyImage(hBms[currInd], IMAGE_BITMAP,
imgXRes * stretchSkew.percentage.x / 100,
imgYRes * stretchSkew.percentage.y / 100, 0));
updateCanvasAndScrollbars();
}
break;
}
case IDM_IMAGEDRAWOPAQUE:
transpBg = 1 - transpBg;
InvalidateRect(hToolSettings, NULL, TRUE);
break;
case IDM_IMAGECROP:
insertReversible(CopyImage(hSelBm, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG));
updateCanvasAndScrollbars();
break;
case IDM_VIEWTOOLBOX:
ShowWindow(hToolBoxContainer, IsWindowVisible(hToolBoxContainer) ? SW_HIDE : SW_SHOW);
alignChildrenToMainWindow();
break;
case IDM_VIEWCOLORPALETTE:
ShowWindow(hPalWin, IsWindowVisible(hPalWin) ? SW_HIDE : SW_SHOW);
alignChildrenToMainWindow();
break;
case IDM_VIEWSTATUSBAR:
ShowWindow(hStatusBar, IsWindowVisible(hStatusBar) ? SW_HIDE : SW_SHOW);
alignChildrenToMainWindow();
break;
case IDM_VIEWSHOWGRID:
showGrid = !showGrid;
InvalidateRect(hImageArea, NULL, FALSE);
break;
case IDM_VIEWSHOWMINIATURE:
showMiniature = !showMiniature;
ShowWindow(hwndMiniature, showMiniature ? SW_SHOW : SW_HIDE);
break;
case IDM_VIEWZOOM125:
zoomTo(125, 0, 0);
break;
case IDM_VIEWZOOM25:
zoomTo(250, 0, 0);
break;
case IDM_VIEWZOOM50:
zoomTo(500, 0, 0);
break;
case IDM_VIEWZOOM100:
zoomTo(1000, 0, 0);
break;
case IDM_VIEWZOOM200:
zoomTo(2000, 0, 0);
break;
case IDM_VIEWZOOM400:
zoomTo(4000, 0, 0);
break;
case IDM_VIEWZOOM800:
zoomTo(8000, 0, 0);
break;
case ID_FREESEL:
selectTool(1);
break;
case ID_RECTSEL:
selectTool(2);
break;
case ID_RUBBER:
selectTool(3);
break;
case ID_FILL:
selectTool(4);
break;
case ID_COLOR:
selectTool(5);
break;
case ID_ZOOM:
selectTool(6);
break;
case ID_PEN:
selectTool(7);
break;
case ID_BRUSH:
selectTool(8);
break;
case ID_AIRBRUSH:
selectTool(9);
break;
case ID_TEXT:
selectTool(10);
break;
case ID_LINE:
selectTool(11);
break;
case ID_BEZIER:
selectTool(12);
break;
case ID_RECT:
selectTool(13);
break;
case ID_SHAPE:
selectTool(14);
break;
case ID_ELLIPSE:
selectTool(15);
break;
case ID_RRECT:
selectTool(16);
break;
}
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}