From ee02c7995d6dcaf490f8f90b8d37ebc6b08f733e Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Sat, 25 Oct 2008 10:55:17 +0900 Subject: [PATCH] [1/19] paint: basic paint program --- .gitignore | 1 + configure.ac | 1 + programs/paint/En.rc | 292 +++++++++++ programs/paint/Makefile.in | 24 + programs/paint/bdiagon.cur | Bin 0 -> 326 bytes programs/paint/bitmap.c | 89 ++++ programs/paint/canvas.c | 940 ++++++++++++++++++++++++++++++++++++ programs/paint/cross2.cur | Bin 0 -> 326 bytes programs/paint/fdiagon.cur | Bin 0 -> 326 bytes programs/paint/horizon.cur | Bin 0 -> 326 bytes programs/paint/main.c | 1123 +++++++++++++++++++++++++++++++++++++++++++ programs/paint/main.h | 139 ++++++ programs/paint/paint.c | 616 ++++++++++++++++++++++++ programs/paint/paint.h | 71 +++ programs/paint/paint.ico | Bin 0 -> 15086 bytes programs/paint/paint.svg | 305 ++++++++++++ programs/paint/pencil.cur | Bin 0 -> 326 bytes programs/paint/resource.h | 168 +++++++ programs/paint/rsrc.rc | 78 +++ programs/paint/tools.bmp | Bin 0 -> 1692 bytes programs/paint/vertical.cur | Bin 0 -> 326 bytes programs/paint/vibeam.cur | Bin 0 -> 326 bytes tools/make_makefiles | 1 + 23 files changed, 3848 insertions(+), 0 deletions(-) create mode 100644 programs/paint/En.rc create mode 100644 programs/paint/Makefile.in create mode 100644 programs/paint/bdiagon.cur create mode 100644 programs/paint/bitmap.c create mode 100644 programs/paint/canvas.c create mode 100644 programs/paint/cross2.cur create mode 100644 programs/paint/fdiagon.cur create mode 100644 programs/paint/horizon.cur create mode 100644 programs/paint/main.c create mode 100644 programs/paint/main.h create mode 100644 programs/paint/paint.c create mode 100644 programs/paint/paint.h create mode 100644 programs/paint/paint.ico create mode 100644 programs/paint/paint.svg create mode 100644 programs/paint/pencil.cur create mode 100644 programs/paint/resource.h create mode 100644 programs/paint/rsrc.rc create mode 100644 programs/paint/tools.bmp create mode 100644 programs/paint/vertical.cur create mode 100644 programs/paint/vibeam.cur diff --git a/.gitignore b/.gitignore index 1caea1b..33fdbfe 100644 --- a/.gitignore +++ b/.gitignore @@ -233,6 +233,7 @@ programs/msiexec/msiexec programs/net/net programs/notepad/notepad programs/oleview/oleview +programs/paint/paint programs/progman/progman programs/reg/reg programs/regedit/regedit diff --git a/configure.ac b/configure.ac index dac47c6..aa4b7d6 100644 --- a/configure.ac +++ b/configure.ac @@ -2101,6 +2101,7 @@ WINE_CONFIG_MAKEFILE([programs/msiexec/Makefile],[programs/Makeprog.rules],[prog WINE_CONFIG_MAKEFILE([programs/net/Makefile],[programs/Makeprog.rules],[programs],[ALL_PROGRAM_DIRS,ALL_PROGRAM_INSTALL_DIRS]) WINE_CONFIG_MAKEFILE([programs/notepad/Makefile],[programs/Makeprog.rules],[programs],[ALL_PROGRAM_DIRS,ALL_PROGRAM_INSTALL_DIRS,ALL_PROGRAM_BIN_INSTALL_DIRS]) WINE_CONFIG_MAKEFILE([programs/oleview/Makefile],[programs/Makeprog.rules],[programs],[ALL_PROGRAM_DIRS,ALL_PROGRAM_INSTALL_DIRS]) +WINE_CONFIG_MAKEFILE([programs/paint/Makefile],[programs/Makeprog.rules],[programs],[ALL_PROGRAM_DIRS,ALL_PROGRAM_INSTALL_DIRS,ALL_PROGRAM_BIN_INSTALL_DIRS]) WINE_CONFIG_MAKEFILE([programs/progman/Makefile],[programs/Makeprog.rules],[programs],[ALL_PROGRAM_DIRS,ALL_PROGRAM_INSTALL_DIRS,ALL_PROGRAM_BIN_INSTALL_DIRS]) WINE_CONFIG_MAKEFILE([programs/reg/Makefile],[programs/Makeprog.rules],[programs],[ALL_PROGRAM_DIRS,ALL_PROGRAM_INSTALL_DIRS]) WINE_CONFIG_MAKEFILE([programs/regedit/Makefile],[programs/Makeprog.rules],[programs],[ALL_PROGRAM_DIRS,ALL_PROGRAM_INSTALL_DIRS,ALL_PROGRAM_BIN_INSTALL_DIRS]) diff --git a/programs/paint/En.rc b/programs/paint/En.rc new file mode 100644 index 0000000..01a44c5 --- /dev/null +++ b/programs/paint/En.rc @@ -0,0 +1,292 @@ +/* + * Paint (English resources) + * + * Copyright 2008 Katayama Hirofumi MZ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT + +MAIN_MENU MENU +{ + POPUP "&File" + { + MENUITEM "&New\tCtrl+N", CMD_NEW + MENUITEM "&Open...\tCtrl+O", CMD_OPEN + MENUITEM "&Save\tCtrl+S", CMD_SAVE + MENUITEM "Save &As...", CMD_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "Print Pre&view", CMD_PRINT_PREVIEW, GRAYED + MENUITEM "Page Set&up...", CMD_PAGE_SETUP, GRAYED + MENUITEM "&Print...\tCtrl+P", CMD_PRINT, GRAYED + MENUITEM SEPARATOR + MENUITEM "Set As &Wallpaper (Tiled)", CMD_WALLPAPAER_TILED, GRAYED + MENUITEM "Set As Wa&llpaper (Centered)", CMD_WALLPAPAER_CENTERED, GRAYED + MENUITEM SEPARATOR + MENUITEM "E&xit", CMD_EXIT + } + POPUP "&Edit" + { + MENUITEM "&Undo\tCtrl+Z", CMD_UNDO, GRAYED + MENUITEM "&Repeat\tCtrl+Y", CMD_REPEAT, GRAYED + MENUITEM SEPARATOR + MENUITEM "Cu&t\tCtrl+X", CMD_CUT + MENUITEM "&Copy\tCtrl+C", CMD_COPY + MENUITEM "&Paste\tCtrl+V", CMD_PASTE + MENUITEM "&Delete\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "Select &All\tCtrl+A", CMD_SELECT_ALL + MENUITEM SEPARATOR + MENUITEM "C&opy To...", CMD_COPY_TO + MENUITEM "Paste &From...", CMD_PASTE_FROM + } + POPUP "&View" + { + MENUITEM "&Tool Box\tCtrl+T", CMD_TOOL_BOX, CHECKED + MENUITEM "&Color Box\tCtrl+L", CMD_COLOR_BOX, CHECKED + MENUITEM "&Status Bar", CMD_STATUS_BAR, CHECKED + MENUITEM "&Text Tool", CMD_TEXT_TOOL, CHECKED, GRAYED + MENUITEM SEPARATOR + POPUP "&Zoom" + { + MENUITEM "&Normal Size\tCtrl+PgUp", CMD_ZOOM_NORMAL + MENUITEM "&Large Size\tCtrl+PgDn", CMD_ZOOM_LARGE + MENUITEM "C&ustom", CMD_ZOOM_CUSTOM + MENUITEM SEPARATOR + MENUITEM "Show &Grid\tCtrl+G", CMD_SHOW_GRID + MENUITEM "Show T&humbnail", CMD_SHOW_THUMBNAIL, GRAYED + } + MENUITEM "&View bitmap\tCtrl+F", CMD_VIEW_BITMAP, GRAYED + } + POPUP "&Image" + { + MENUITEM "Flip/Rotate...\tCtrl+R", CMD_FLIP_ROTATE + MENUITEM "Stretch/Skew...\tCtrl+W", CMD_STRETCH_SKEW + MENUITEM "Invert Colors\tCtrl+I", CMD_INVERT_COLORS + MENUITEM "Attributes...\tCtrl+E", CMD_ATTRIBUTES + MENUITEM "Clear Image\tCtrl+Shift+N", CMD_CLEAR_IMAGE + MENUITEM "Draw Opaque", CMD_DRAW_OPAQUE, CHECKED, GRAYED + } + POPUP "&Color" + { + MENUITEM "&Edit color...", CMD_EDIT_COLOR + MENUITEM "&Get Colors...", CMD_GET_COLORS, GRAYED + MENUITEM "&Save Colors...", CMD_SAVE_COLORS, GRAYED + } + POPUP "&Help" + { + MENUITEM "&Contents", CMD_HELP_CONTENTS + MENUITEM "&Help on help", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&About Paint", CMD_HELP_ABOUT_PAINT + } +} + +TEXT_MENU MENU +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +{ + POPUP "Text" + { + MENUITEM "Undo", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "Cut", CMD_CUT + MENUITEM "Copy", CMD_COPY + MENUITEM "Paste", CMD_PASTE + MENUITEM "Clear Selection", CMD_CLEAR_SELECTION + MENUITEM "Select All", CMD_SELECT_ALL + MENUITEM SEPARATOR + MENUITEM "Text Toolbar", CMD_TEXT_TOOL + } +} + +SELECTION_MENU MENU +{ + POPUP "Selection" + { + MENUITEM "Cu&t", CMD_CUT + MENUITEM "&Copy", CMD_COPY + MENUITEM "&Paste", CMD_PASTE + MENUITEM "C&lear Selection", CMD_CLEAR_SELECTION + MENUITEM "Select &All", CMD_SELECT_ALL + MENUITEM SEPARATOR + MENUITEM "C&opy To...", CMD_COPY_TO, GRAYED + MENUITEM "Paste &From...", CMD_PASTE_FROM + MENUITEM SEPARATOR + MENUITEM "Flip/&Rotate...", CMD_FLIP_ROTATE + MENUITEM "&Stretch/Skew...", CMD_STRETCH_SKEW + MENUITEM "&Invert Colors", CMD_INVERT_COLORS + } +} + +IDD_ZOOM DIALOG 0, 0, 200, 83 +STYLE DS_MODALFRAME | DS_CENTER | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Custom Zoom" +FONT 8, "MS Shell Dlg" +{ + LTEXT "Current zoom:", stc1, 13, 7, 47, 7 + RTEXT "", stc2, 61, 7, 49, 9 + GROUPBOX "Zoom to", grp1, 7, 20, 127, 57 + CONTROL "&100%", rad1, "BUTTON", BS_AUTORADIOBUTTON, 13, 38, 33, 10 + CONTROL "&200%", rad2, "BUTTON", BS_AUTORADIOBUTTON, 13, 57, 33, 10 + CONTROL "&400%", rad3, "BUTTON", BS_AUTORADIOBUTTON, 56, 38, 33, 10 + CONTROL "&600%", rad4, "BUTTON", BS_AUTORADIOBUTTON, 56, 57, 33, 10 + CONTROL "&800%", rad5, "BUTTON", BS_AUTORADIOBUTTON, 94, 38, 33, 10 + DEFPUSHBUTTON "OK", IDOK, 142, 7, 50, 14 + PUSHBUTTON "Cancel", IDCANCEL, 142, 24, 50, 14 +} + +IDD_STRETCH_SKEW DIALOG 18, 48, 232, 150 +STYLE DS_MODALFRAME | DS_CENTER | WS_CAPTION | WS_SYSMENU +CAPTION "Stretch and Skew" +FONT 9, "MS Shell Dlg" +{ + GROUPBOX "Stretch", IDC_STATIC, 7, 7, 160, 67 + ICON 100, ico1, 15, 20, 21, 22 + LTEXT "&Horizontal:", IDC_STATIC, 47, 27, 46, 8 + EDITTEXT edt1, 95, 26, 32, 12, ES_AUTOHSCROLL + LTEXT "%", IDC_STATIC, 130, 28, 8, 8 + ICON 101, ico2, 15, 45, 21, 22 + LTEXT "&Vertical:", IDC_STATIC, 47, 51, 46, 8 + EDITTEXT edt2, 95, 50, 32, 12, ES_AUTOHSCROLL + LTEXT "%", IDC_STATIC, 130, 52, 8, 8 + GROUPBOX "Skew", IDC_STATIC, 7, 77, 160, 67, WS_DISABLED + ICON 102, ico3, 15, 90, 21, 22, WS_DISABLED + LTEXT "H&orizontal:", IDC_STATIC, 47, 97, 46, 8, WS_DISABLED + EDITTEXT edt3, 95, 96, 32, 12, ES_AUTOHSCROLL | WS_DISABLED + LTEXT "Degree", IDC_STATIC, 130, 98, 28, 8, WS_DISABLED + ICON 103, ico4, 15, 115, 21, 22, WS_DISABLED + LTEXT "V&ertical:", IDC_STATIC, 47, 121, 46, 8, WS_DISABLED + EDITTEXT edt4, 95, 120, 32, 12, ES_AUTOHSCROLL | WS_DISABLED + LTEXT "Degree", IDC_STATIC, 130, 122, 28, 8, WS_DISABLED + DEFPUSHBUTTON "OK", IDOK, 175, 7, 50, 14 + PUSHBUTTON "Cancel", IDCANCEL, 175, 24, 50, 14 +} + +STRINGTABLE DISCARDABLE +{ + STRING_PAINT, "Paint" + STRING_UNTITLED, "Untitled" + STRING_ALL_FILES, "All Files (*.*)" + STRING_BMP_FILES_BMP, "Bitmap Files (*.bmp)" + STRING_DOESNOTEXIST, "File '%s' does not exist.\n\nDo you want to create a new file?" + STRING_SAVECHANGE, "Save changes to %s?" + STRING_NOTFOUND, "'%s' could not be found." + STRING_MONOCROME_BM, "Monochrome Bitmap (*.bmp)" + STRING_16COLOR_BM, "16 Color Bitmap (*.bmp)" + STRING_256COLOR_BM, "256 Color Bitmap (*.bmp)" + STRING_24BIT_BM, "24-bit Bitmap (*.bmp)" + STRING_JPEG_FILES, "JPEG (*.JPG;*.JPEG;*.JPE;*.JFIF)" + STRING_GIF_FILES, "GIF (*.GIF)" + STRING_TIFF_FILES, "TIFF (*.TIF;*.TIFF)" + STRING_PNG_FILES, "PNG (*.PNG)" + STRING_ICON_FILES, "Icon Files (*.ico)" + STRING_PCX_FILES, "PCX Files (*.pcx)" + STRING_ALL_PICTURE, "All Picture Files" + STRING_PALETTE, "Palette (*.pal)" +} + +STRINGTABLE DISCARDABLE +{ + STRING_POLYSELECT, "Selects a free-form part of the picture to move, copy, or edit." + STRING_BOXSELECT, "Selects a rectangular part of the picture to move, copy, or edit." + STRING_ERASER, "Erases a portion of the picture, using the selected eraser shape." + STRING_FLOODFILL, "Fills an area with the current drawing color." + STRING_SPOIT, "Picks up a color from the picture for drawing." + STRING_MAGNIFIER, "Changes the magnification." + STRING_PENCIL, "Draws a free-form line one pixel wide." + STRING_BRUSH, "Draws using a brush with the selected shape and size." + STRING_AIRBRUSH, "Draws using an airbrush of the selected size." + STRING_TEXT, "Inserts text into the picture." + STRING_LINE, "Draws a straight line with the selected line width." + STRING_CURVE, "Draws a curved line with the selected line width." + STRING_BOX, "Draws a rectangle with the selected fill style." + STRING_POLYGON, "Draws a polygon with the selected fill style." + STRING_ELLIPSE, "Draws an ellipse with the selected fill style." + STRING_ROUNDRECT, "Draws a rounded rectangle with the selected fill style." +} + +STRINGTABLE DISCARDABLE +{ + STRING_NEW, "Creates a new document." + STRING_OPEN, "Opens an existing document." + STRING_SAVE, "Saves the active document." + STRING_SAVE_AS, "Saves the active document with a new name." + STRING_PRINT_PREVIEW, "Displays full pages." + STRING_PAGE_SETUP, "Changes the page layout." + STRING_PRINT, "Prints the active document and sets printing options." + STRING_EXIT, "Quits Paint." + + STRING_WALLPAPAER_TILED, "Tiles this bitmap as the desktop wallpaper." + STRING_WALLPAPAER_CENTERED, "Centers this bitmap as the desktop wallpaper." + + STRING_UNDO, "Undoes the last action." + STRING_CUT, "Cuts the selection and puts it on the Clipboard." + STRING_COPY, "Copies the selection and puts it on the Clipboard." + STRING_PASTE, "Inserts the contents of the Clipboard." + STRING_DELETE, "Deletes the selection." + STRING_SELECT_ALL, "Selects everything." + STRING_REPEAT, "Repeats the last action." + STRING_COPY_TO, "Copies the selection to a file." + STRING_PASTE_FROM, "Pastes a file into the selection." + + STRING_TOOL_BOX, "Shows or hides the tool box." + STRING_COLOR_BOX, "Shows or hides the color box." + STRING_STATUS_BAR, "Shows or hides the status bar." + STRING_TEXT_TOOL, "Shows or hides the text toolbar." + STRING_ZOOM_NORMAL, "Zooms the picture to 100%." + STRING_ZOOM_LARGE, "Zooms the picture to 400%." + STRING_ZOOM_CUSTOM, "Zooms the picture." + STRING_SHOW_GRID, "Shows or hides the grid." + STRING_VIEW_BITMAP, "Displays the entire picture." + STRING_SHOW_THUMBNAIL, "Shows or hides the thumbnail." + + STRING_FLIP_ROTATE, "Flips or rotates the picture or a selection." + STRING_STRETCH_SKEW, "Stretches or skews the picture or a selection." + STRING_INVERT_COLORS, "Inverts the colors of the picture or a selection." + STRING_ATTRIBUTES, "Changes the attributes of the picture." + STRING_CLEAR_IMAGE, "Clears the picture or selection." + STRING_DRAW_OPAQUE, "Makes the current selection either opaque or transparent." + STRING_CLEAR_SELECTION, "Clears the picture or selection." + + STRING_EDIT_COLOR, "Creates a new color." + STRING_GET_COLORS, "Uses a previously saved palette of colors." + STRING_SAVE_COLORS, "Saves the current palette of colors to a file." + + STRING_HELP_CONTENTS, "Opens Paint Help." + STRING_HELP_ON_HELP, "Displays instructions about how to use Help." + STRING_HELP_ABOUT_PAINT, "Displays program information, version number, and copyright." +} + +STRINGTABLE DISCARDABLE +{ + STRING_SIZE, "Changes the window size." + STRING_MOVE, "Changes the window position." + STRING_MINIMIZE, "Reduces the window to an icon." + STRING_MAXIMIZE, "Enlarges the window to full size." + STRING_NEXTWINDOW, "Switches to the next document window." + STRING_PREVWINDOW, "Switches to the previous document window." + STRING_CLOSE, "Closes the active window and asks if you want to save changes." + STRING_RESTORE, "Restores the window to normal size." + STRING_TASKLIST, "Activates the task list." +} + +STRINGTABLE DISCARDABLE +{ + STRING_READY, "Ready" + STRING_POSITIVE_INT, "Please enter a positive integer." + STRING_INVALID_BM, "Invalid bitmap file" + STRING_LOSS_COLOR, "Saving into this format may cause some loss of color information.\nDo you want to continue?" +} diff --git a/programs/paint/Makefile.in b/programs/paint/Makefile.in new file mode 100644 index 0000000..52694cc --- /dev/null +++ b/programs/paint/Makefile.in @@ -0,0 +1,24 @@ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = paint.exe +APPMODE = -mwindows -mno-cygwin +IMPORTS = comdlg32 shell32 shlwapi user32 gdi32 advapi32 kernel32 +EXTRAINCL = -I$(TOPSRCDIR)/include/msvcrt +MODCFLAGS = @BUILTINFLAG@ +EXTRADEFS = -DNO_LIBWINE_PORT + +C_SRCS = \ + bitmap.c \ + canvas.c \ + main.c \ + paint.c + +RC_SRCS = rsrc.rc + +SVG_SRCS = paint.svg + +@MAKE_PROG_RULES@ + +@DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/programs/paint/bdiagon.cur b/programs/paint/bdiagon.cur new file mode 100644 index 0000000000000000000000000000000000000000..570cbbb571cc62fb2eca1f4fa2655338c06b5936 GIT binary patch literal 326 zcma)$F%E)26hvpy-j14t#?m98p`z9ca0L&bMhXg#VCgXl<6GE-66WXa>`Z<(D`g5Q z3hBU{f|N@-0+lKV%%o& literal 0 HcmV?d00001 diff --git a/programs/paint/bitmap.c b/programs/paint/bitmap.c new file mode 100644 index 0000000..bce020e --- /dev/null +++ b/programs/paint/bitmap.c @@ -0,0 +1,89 @@ +/* + * Paint (bitmap.c) + * + * Copyright 2008 Katayama Hirofumi MZ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define UNICODE + +#include +#include "resource.h" + +HBITMAP BM_Create(SIZE siz) +{ + BITMAPINFO bi; + VOID *pBits; + ZeroMemory(&bi.bmiHeader, sizeof(BITMAPINFOHEADER)); + bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bi.bmiHeader.biWidth = siz.cx; + bi.bmiHeader.biHeight = -siz.cy; + bi.bmiHeader.biPlanes = 1; + bi.bmiHeader.biBitCount = 24; + bi.bmiHeader.biCompression = BI_RGB; + return CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, &pBits, NULL, 0); +} + +HBITMAP BM_CreateResized(HWND hWnd, SIZE sizNew, HBITMAP hbm, SIZE siz) +{ + DWORD dwError; + HDC hDC, hdcMem1, hdcMem2; + HBITMAP hbmNew, hbmOld1, hbmOld2; + RECT rc; + + hbmNew = BM_Create(sizNew); + if (hbmNew != NULL) + { + dwError = 0; + hDC = GetDC(hWnd); + hdcMem1 = CreateCompatibleDC(hDC); + if (hdcMem1 != NULL) + { + hbmOld1 = SelectObject(hdcMem1, hbmNew); + + rc.left = rc.top = 0; + rc.right = sizNew.cx; + rc.bottom = sizNew.cy; + FillRect(hdcMem1, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); + + hdcMem2 = CreateCompatibleDC(hDC); + if (hdcMem2 != NULL) + { + hbmOld2 = SelectObject(hdcMem2, hbm); + BitBlt(hdcMem1, 0, 0, siz.cx, siz.cy, + hdcMem2, 0, 0, SRCCOPY); + SelectObject(hdcMem2, hbmOld2); + DeleteDC(hdcMem2); + } + else + dwError = GetLastError(); + SelectObject(hdcMem1, hbmOld1); + + DeleteDC(hdcMem1); + } + else + dwError = GetLastError(); + ReleaseDC(hWnd, hDC); + SetLastError(dwError); + } + + return hbmNew; +} + +HBITMAP BM_Copy(HBITMAP hbm) +{ + return (HBITMAP)CopyImage(hbm, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG); +} diff --git a/programs/paint/canvas.c b/programs/paint/canvas.c new file mode 100644 index 0000000..0adb108 --- /dev/null +++ b/programs/paint/canvas.c @@ -0,0 +1,940 @@ +/* + * Paint (canvas.c) + * + * Copyright 2008 Katayama Hirofumi MZ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define UNICODE + +#include +#include +#include + +#include "main.h" +#include "paint.h" +#include "resource.h" + +static const WCHAR empty[] = {0}; + +VOID CanvasToImage(POINT *ppt) +{ + ppt->x = (ppt->x + Globals.xScrollPos - 4) / Globals.nZoom; + ppt->y = (ppt->y + Globals.yScrollPos - 4) / Globals.nZoom; +} + +VOID ImageToCanvas(POINT *ppt) +{ + ppt->x = ppt->x * Globals.nZoom + 4 - Globals.xScrollPos; + ppt->y = ppt->y * Globals.nZoom + 4 - Globals.yScrollPos; +} + +VOID ImageToCanvas2(POINT *ppt) +{ + ppt->x = ppt->x * Globals.nZoom + 4; + ppt->y = ppt->y * Globals.nZoom + 4; +} + +VOID PrepareForUndo(VOID) +{ + Globals.fCanUndo = TRUE; + if (Globals.hbmImageUndo != NULL) + DeleteObject(Globals.hbmImageUndo); + Globals.hbmImageUndo = BM_Copy(Globals.hbmImage); + Globals.sizImageUndo = Globals.sizImage; +} + +VOID Canvas_DrawBuffer(HDC hDC) +{ +} + +VOID Canvas_OnPaint(HWND hWnd, HDC hDC) +{ + HBRUSH hbr; + HGDIOBJ hbmOld1, hbmOld2, hpenOld, hbrOld; + HDC hMemDC1, hMemDC2; + RECT rc; + INT x, y; + + SetWindowOrgEx(hDC, Globals.xScrollPos, Globals.yScrollPos, NULL); + + hMemDC1 = CreateCompatibleDC(hDC); + if (hMemDC1 != NULL) + { + hMemDC2 = CreateCompatibleDC(hDC); + if (hMemDC2 != NULL) + { + hbmOld1 = SelectObject(hMemDC1, Globals.hbmImage); + hbmOld2 = SelectObject(hMemDC2, Globals.hbmBuffer); + BitBlt(hMemDC2, 0, 0, Globals.sizImage.cx, Globals.sizImage.cy, + hMemDC1, 0, 0, SRCCOPY); + SelectObject(hMemDC1, hbmOld1); + Canvas_DrawBuffer(hMemDC2); + + /* FIXME: speed up by smaller buffer */ + hbmOld1 = SelectObject(hMemDC1, Globals.hbmZoomBuffer); + SetStretchBltMode(hDC, COLORONCOLOR); + StretchBlt(hMemDC1, 0, 0, Globals.sizImage.cx * Globals.nZoom, + Globals.sizImage.cy * Globals.nZoom, hMemDC2, + 0, 0, Globals.sizImage.cx, Globals.sizImage.cy, SRCCOPY); + SelectObject(hMemDC2, hbmOld2); + + if (Globals.fShowGrid && Globals.nZoom >= 3) + { + LOGBRUSH lb; + HPEN hPen1, hPen2; + hPen1 = CreatePen(PS_SOLID, 1, RGB(192, 192, 192)); + hpenOld = SelectObject(hMemDC1, hPen1); + for (x = 0; x < Globals.sizImage.cx; x++) + { + MoveToEx(hMemDC1, x * Globals.nZoom, 0, NULL); + LineTo(hMemDC1, x * Globals.nZoom, + Globals.sizImage.cy * Globals.nZoom); + } + for (y = 0; y < Globals.sizImage.cy; y++) + { + MoveToEx(hMemDC1, 0, y * Globals.nZoom, NULL); + LineTo(hMemDC1, Globals.sizImage.cx * Globals.nZoom, + y * Globals.nZoom); + } + lb.lbColor = RGB(128, 128, 128); + lb.lbStyle = BS_SOLID; + hPen2 = ExtCreatePen(PS_COSMETIC|PS_ALTERNATE|PS_ENDCAP_SQUARE|PS_JOIN_BEVEL, 1, &lb, 0, NULL); + SelectObject(hMemDC1, hPen2); + for (x = 0; x < Globals.sizImage.cx; x++) + { + MoveToEx(hMemDC1, x * Globals.nZoom, 0, NULL); + LineTo(hMemDC1, x * Globals.nZoom, + Globals.sizImage.cy * Globals.nZoom); + } + for (y = 0; y < Globals.sizImage.cy; y++) + { + MoveToEx(hMemDC1, 0, y * Globals.nZoom, NULL); + LineTo(hMemDC1, Globals.sizImage.cx * Globals.nZoom, + y * Globals.nZoom); + } + SelectObject(hMemDC1, hpenOld); + DeleteObject(hPen1); + DeleteObject(hPen2); + } + + if (GetSysColor(COLOR_3DFACE) == RGB(0, 0, 0)) + hbr = CreateSolidBrush(RGB(0, 0, 0)); + else + hbr = CreateSolidBrush(RGB(123, 125, 123)); + + hbmOld2 = SelectObject(hMemDC2, Globals.hbmCanvasBuffer); + GetClientRect(hWnd, &rc); + FillRect(hMemDC2, &rc, hbr); + DeleteObject(hbr); + BitBlt(hMemDC2, 4 - Globals.xScrollPos, 4 - Globals.yScrollPos, + Globals.sizImage.cx * Globals.nZoom, + Globals.sizImage.cy * Globals.nZoom, + hMemDC1, 0, 0, SRCCOPY); + SelectObject(hMemDC1, hbmOld1); + + if (Globals.fSelect && Globals.mode == MODE_NORMAL) + { + POINT pt0, pt1; + HPEN hPen = CreatePen(PS_DOT, 1, GetSysColor(COLOR_HIGHLIGHT)); + hbr = (HBRUSH)GetStockObject(NULL_BRUSH); + hbrOld = SelectObject(hMemDC2, hbr); + hpenOld = SelectObject(hMemDC2, hPen); + pt0 = Globals.pt0; + ImageToCanvas2(&pt0); + pt1 = Globals.pt1; + ImageToCanvas2(&pt1); + Rectangle(hMemDC2, + pt0.x - Globals.xScrollPos, pt0.y - Globals.yScrollPos, + pt1.x - Globals.xScrollPos, pt1.y - Globals.yScrollPos); + SelectObject(hMemDC2, hbrOld); + SelectObject(hMemDC2, hpenOld); + DeleteObject(hPen); + } + + BitBlt(hDC, Globals.xScrollPos, Globals.yScrollPos, + Globals.sizCanvas.cx, Globals.sizCanvas.cy, + hMemDC2, 0, 0, SRCCOPY); + SelectObject(hMemDC2, hbmOld2); + } + } + + if (!Globals.fSelect) + { + rc.left = 0; + rc.top = 0; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + FillRect(hDC, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); + rc.left = 4 + Globals.sizImage.cx * Globals.nZoom / 2 - 2; + rc.top = 0; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + FillRect(hDC, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); + rc.left = 0; + rc.top = 4 + Globals.sizImage.cy * Globals.nZoom / 2 - 2; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + FillRect(hDC, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); + rc.left = 0; + rc.top = 4 + Globals.sizImage.cy * Globals.nZoom + 1; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + FillRect(hDC, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); + rc.left = 4 + Globals.sizImage.cx * Globals.nZoom + 1; + rc.top = 0; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + FillRect(hDC, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); + + hbr = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT)); + rc.left = 4 + Globals.sizImage.cx * Globals.nZoom + 1; + rc.top = 4 + Globals.sizImage.cy * Globals.nZoom / 2 - 2; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + FillRect(hDC, &rc, hbr); + rc.left = 4 + Globals.sizImage.cx * Globals.nZoom / 2 - 2; + rc.top = 4 + Globals.sizImage.cy * Globals.nZoom + 1; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + FillRect(hDC, &rc, hbr); + rc.left = 4 + Globals.sizImage.cx * Globals.nZoom + 1; + rc.top = 4 + Globals.sizImage.cy * Globals.nZoom + 1; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + FillRect(hDC, &rc, hbr); + DeleteObject(hbr); + } +} + +VOID Canvas_OnButtonDown(HWND hWnd, INT x, INT y, BOOL fRight) +{ + POINT pt, pt0; + RECT rc; + HDC hDC, hMemDC; + HGDIOBJ hbmOld, hbrOld; + HBRUSH hbr; + pt.x = x; + pt.y = y; + + if (!fRight) + { + rc.left = 4 + Globals.sizImage.cx * Globals.nZoom + 1 - Globals.xScrollPos; + rc.top = 4 + Globals.sizImage.cy * Globals.nZoom / 2 - 2 - Globals.yScrollPos; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + if (PtInRect(&rc, pt)) + { + SetCursor(Globals.hcurHorizontal); + Globals.mode = MODE_RIGHT_EDGE; + SetCapture(hWnd); + Globals.pt0 = pt; + SetRectEmpty((RECT*)&Globals.pt0); + return; + } + + rc.left = 4 + Globals.sizImage.cx * Globals.nZoom / 2 - 2 - Globals.xScrollPos; + rc.top = 4 + Globals.sizImage.cy * Globals.nZoom + 1 - Globals.yScrollPos; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + if (PtInRect(&rc, pt)) + { + SetCursor(Globals.hcurVertical); + Globals.mode = MODE_DOWN_EDGE; + SetCapture(hWnd); + Globals.pt0 = pt; + SetRectEmpty((RECT*)&Globals.pt0); + return; + } + + rc.left = 4 + Globals.sizImage.cx * Globals.nZoom + 1 - Globals.xScrollPos; + rc.top = 4 + Globals.sizImage.cy * Globals.nZoom + 1 - Globals.yScrollPos; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + if (PtInRect(&rc, pt)) + { + SetCursor(Globals.hcurBDiagonal); + Globals.mode = MODE_LOWER_RIGHT_EDGE; + SetCapture(hWnd); + Globals.pt0 = pt; + SetRectEmpty((RECT*)&Globals.pt0); + return; + } + } + + rc.left = 4; + rc.top = 4; + rc.right = 4 + Globals.sizImage.cx * Globals.nZoom; + rc.bottom = 4 + Globals.sizImage.cy * Globals.nZoom; + + if (PtInRect(&rc, pt)) + { + switch (Globals.iToolSelect) + { + case TOOL_PENCIL: + SetCursor(Globals.hcurPencil); + Globals.mode = MODE_CANVAS; + SetCapture(hWnd); + CanvasToImage(&pt); + PrepareForUndo(); + hDC = GetDC(hWnd); + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + hbmOld = SelectObject(hMemDC, Globals.hbmImage); + SetPixelV(hMemDC, pt.x, pt.y, + fRight ? Globals.rgbBack : Globals.rgbFore); + SelectObject(hMemDC, hbmOld); + DeleteDC(hMemDC); + Globals.fModified = TRUE; + } + ReleaseDC(hWnd, hDC); + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + Globals.pt0 = pt; + break; + + default: + break; + } + } +} + +VOID ShowPos(POINT pt) +{ + WCHAR sz[64]; + static const WCHAR format[] = {'%','d',',','%','d',0}; + wsprintf(sz, format, pt.x, pt.y); + SendMessage(Globals.hStatusBar, SB_SETTEXT, 1 | 0, (LPARAM)sz); +} + +VOID ShowSize(INT cx, INT cy) +{ + WCHAR sz[64]; + static const WCHAR format[] = {'%','d','x','%','d',0}; + wsprintf(sz, format, cx, cy); + SendMessage(Globals.hStatusBar, SB_SETTEXT, 2 | 0, (LPARAM)sz); +} + +VOID ShowNoSize(VOID) +{ + SendMessage(Globals.hStatusBar, SB_SETTEXT, 2 | 0, (LPARAM)empty); +} + +VOID Canvas_OnMouseMove(HWND hWnd, INT x, INT y, BOOL fLeftDown, BOOL fRightDown) +{ + POINT pt; + RECT rc; + HDC hDC, hMemDC; + WCHAR sz[256]; + pt.x = x; + pt.y = y; + + LoadString(Globals.hInstance, STRING_READY, sz, 256); + SendMessage(Globals.hStatusBar, SB_SETTEXT, 0 | 0, (LPARAM)sz); + + if (fLeftDown) + { + rc.left = 4; + rc.top = 4; + Globals.fSwapColor = FALSE; + switch (Globals.mode) + { + case MODE_RIGHT_EDGE: + SetCursor(Globals.hcurHorizontal); + CanvasToImage(&pt); + ShowSize(pt.x, Globals.sizImage.cy); + ImageToCanvas(&pt); + rc.right = pt.x; + rc.bottom = Globals.sizImage.cy * Globals.nZoom + 4; + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + hDC = GetDC(hWnd); + if (hDC != NULL) + { + DrawFocusRect(hDC, &rc); + ReleaseDC(hWnd, hDC); + } + break; + + case MODE_DOWN_EDGE: + SetCursor(Globals.hcurVertical); + CanvasToImage(&pt); + ShowSize(Globals.sizImage.cx, pt.y); + ImageToCanvas(&pt); + rc.right = Globals.sizImage.cx * Globals.nZoom + 4; + rc.bottom = pt.y; + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + hDC = GetDC(hWnd); + if (hDC != NULL) + { + DrawFocusRect(hDC, &rc); + ReleaseDC(hWnd, hDC); + } + break; + + case MODE_LOWER_RIGHT_EDGE: + SetCursor(Globals.hcurBDiagonal); + CanvasToImage(&pt); + ShowSize(pt.x, pt.y); + ImageToCanvas(&pt); + rc.right = pt.x; + rc.bottom = pt.y; + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + hDC = GetDC(hWnd); + if (hDC != NULL) + { + DrawFocusRect(hDC, &rc); + ReleaseDC(hWnd, hDC); + } + break; + + case MODE_CANVAS: + switch (Globals.iToolSelect) + { + case TOOL_PENCIL: + SetCursor(Globals.hcurPencil); + CanvasToImage(&pt); + ShowPos(pt); + ShowNoSize(); + hDC = GetDC(hWnd); + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + HPEN hPen = CreatePen(PS_SOLID, 0, Globals.rgbFore); + HGDIOBJ hbmOld = SelectObject(hMemDC, Globals.hbmImage); + HGDIOBJ hpenOld = SelectObject(hMemDC, hPen); + MoveToEx(hMemDC, Globals.pt0.x, Globals.pt0.y, NULL); + LineTo(hMemDC, pt.x, pt.y); + SetPixelV(hMemDC, pt.x, pt.y, Globals.rgbFore); + SelectObject(hMemDC, hbmOld); + SelectObject(hMemDC, hpenOld); + DeleteObject(hPen); + DeleteDC(hMemDC); + Globals.fModified = TRUE; + } + ReleaseDC(hWnd, hDC); + Globals.pt0 = pt; + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + default: + break; + } + break; + + default: + break; + } + } + else if (fRightDown) + { + Globals.fSwapColor = TRUE; + if (Globals.mode == MODE_CANVAS) + { + switch (Globals.iToolSelect) + { + case TOOL_PENCIL: + SetCursor(Globals.hcurPencil); + CanvasToImage(&pt); + hDC = GetDC(hWnd); + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + HPEN hPen = CreatePen(PS_SOLID, 0, Globals.rgbBack); + HGDIOBJ hbmOld = SelectObject(hMemDC, Globals.hbmImage); + HGDIOBJ hpenOld = SelectObject(hMemDC, hPen); + MoveToEx(hMemDC, Globals.pt0.x, Globals.pt0.y, NULL); + LineTo(hMemDC, pt.x, pt.y); + SetPixelV(hMemDC, pt.x, pt.y, Globals.rgbBack); + SelectObject(hMemDC, hbmOld); + SelectObject(hMemDC, hpenOld); + DeleteObject(hPen); + DeleteDC(hMemDC); + Globals.fModified = TRUE; + } + ReleaseDC(hWnd, hDC); + Globals.pt0 = pt; + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + default: + break; + } + } + } + else + { + Globals.fSwapColor = FALSE; + Globals.mode = MODE_NORMAL; + ReleaseCapture(); + rc.left = 4 + Globals.sizImage.cx * Globals.nZoom + 1 - Globals.xScrollPos; + rc.top = 4 + Globals.sizImage.cy * Globals.nZoom / 2 - 2 - Globals.yScrollPos; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + if (PtInRect(&rc, pt)) + { + SetCursor(Globals.hcurHorizontal); + return; + } + + rc.left = 4 + Globals.sizImage.cx * Globals.nZoom / 2 - 2 - Globals.xScrollPos; + rc.top = 4 + Globals.sizImage.cy * Globals.nZoom + 1 - Globals.yScrollPos; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + if (PtInRect(&rc, pt)) + { + SetCursor(Globals.hcurVertical); + return; + } + + rc.left = 4 + Globals.sizImage.cx * Globals.nZoom + 1 - Globals.xScrollPos; + rc.top = 4 + Globals.sizImage.cy * Globals.nZoom + 1 - Globals.yScrollPos; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + if (PtInRect(&rc, pt)) + { + SetCursor(Globals.hcurBDiagonal); + return; + } + + rc.left = 4 + Globals.xScrollPos; + rc.top = 4 + Globals.yScrollPos; + rc.right = 4 + Globals.sizImage.cx * Globals.nZoom + Globals.xScrollPos; + rc.bottom = 4 + Globals.sizImage.cy * Globals.nZoom + Globals.yScrollPos; + + if (PtInRect(&rc, pt)) + { + switch (Globals.iToolSelect) + { + case TOOL_PENCIL: + SetCursor(Globals.hcurPencil); + CanvasToImage(&pt); + ShowPos(pt); + ShowNoSize(); + break; + + default: + SetCursor(Globals.hcurCross2); + CanvasToImage(&pt); + ShowPos(pt); + ShowNoSize(); + break; + } + } + else + { + SendMessage(Globals.hStatusBar, SB_SETTEXT, 1 | 0, (LPARAM)empty); + SetCursor(Globals.hcurArrow); + return; + } + } +} + +VOID Canvas_Resize(HWND hWnd, SIZE sizNew) +{ + HBITMAP hbmNew = BM_CreateResized(hWnd, sizNew, Globals.hbmImage, + Globals.sizImage); + if (hbmNew != NULL) + { + if (Globals.hbmImage != NULL) + DeleteObject(Globals.hbmImage); + Globals.hbmImage = hbmNew; + Globals.sizImage = sizNew; + + if (Globals.hbmBuffer != NULL) + DeleteObject(Globals.hbmBuffer); + Globals.hbmBuffer = BM_Copy(Globals.hbmImage); + if (Globals.hbmZoomBuffer != NULL) + DeleteObject(Globals.hbmZoomBuffer); + sizNew.cx *= Globals.nZoom; + sizNew.cy *= Globals.nZoom; + Globals.hbmZoomBuffer = BM_Create(sizNew); + Globals.fModified = TRUE; + Globals.xScrollPos = Globals.yScrollPos = 0; + PostMessage(hWnd, WM_SIZE, 0, 0); + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + } + else + ShowLastError(); +} + +VOID Canvas_OnButtonDblClk(HWND hWnd, INT x, INT y, BOOL fRight) +{ +} + +VOID Canvas_OnButtonUp(HWND hWnd, INT x, INT y, BOOL fRight) +{ + HDC hDC, hMemDC; + HGDIOBJ hbmOld; + POINT pt; + SIZE siz; + RECT rc; + pt.x = x; + pt.y = y; + + switch (Globals.mode) + { + case MODE_RIGHT_EDGE: + CanvasToImage(&pt); + PrepareForUndo(); + Globals.fModified = TRUE; + siz.cx = pt.x; + siz.cy = Globals.sizImage.cy; + if (siz.cx < 1) siz.cx = 1; + Canvas_Resize(hWnd, siz); + ReleaseCapture(); + Globals.mode = MODE_NORMAL; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + break; + + case MODE_DOWN_EDGE: + CanvasToImage(&pt); + PrepareForUndo(); + Globals.fModified = TRUE; + siz.cx = Globals.sizImage.cx; + siz.cy = pt.y; + if (siz.cy < 1) siz.cy = 1; + Canvas_Resize(hWnd, siz); + ReleaseCapture(); + Globals.mode = MODE_NORMAL; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + break; + + case MODE_LOWER_RIGHT_EDGE: + CanvasToImage(&pt); + PrepareForUndo(); + Globals.fModified = TRUE; + siz.cx = pt.x; + siz.cy = pt.y; + if (siz.cx < 1) siz.cx = 1; + if (siz.cy < 1) siz.cy = 1; + Canvas_Resize(hWnd, siz); + ReleaseCapture(); + Globals.mode = MODE_NORMAL; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + break; + + case MODE_CANVAS: + ReleaseCapture(); + Globals.mode = MODE_NORMAL; + switch (Globals.iToolSelect) + { + case TOOL_PENCIL: + CanvasToImage(&pt); + hDC = GetDC(hWnd); + if (hDC != NULL) + { + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + HPEN hPen; + HGDIOBJ hpenOld; + hbmOld = SelectObject(hMemDC, Globals.hbmImage); + hPen = CreatePen(PS_SOLID, 1, fRight ? Globals.rgbBack : + Globals.rgbFore); + hpenOld = SelectObject(hMemDC, hPen); + MoveToEx(hMemDC, Globals.pt0.x, Globals.pt0.y, NULL); + LineTo(hMemDC, pt.x, pt.y); + SetPixel(hMemDC, pt.x, pt.y, fRight ? + Globals.rgbBack : Globals.rgbFore); + SelectObject(hMemDC, hbmOld); + SelectObject(hMemDC, hpenOld); + DeleteObject(hPen); + DeleteDC(hMemDC); + Globals.fModified = TRUE; + } + ReleaseDC(hWnd, hDC); + } + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + default: + break; + } + break; + + default: + break; + } + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); +} + +VOID Canvas_OnSize(HWND hWnd) +{ + RECT rc; + SIZE siz; + + GetClientRect(hWnd, &rc); + siz.cx = rc.right - rc.left; + siz.cy = rc.bottom - rc.top; + if (siz.cx < Globals.sizImage.cx * Globals.nZoom + 8) + { + SCROLLINFO si; + EnableScrollBar(hWnd, SB_HORZ, ESB_ENABLE_BOTH); + si.cbSize = sizeof(si); + si.fMask = SIF_ALL; + si.nMin = 0; + si.nMax = Globals.sizImage.cx * Globals.nZoom + 8; + si.nPage = siz.cx; + si.nPos = Globals.xScrollPos; + SetScrollInfo(hWnd, SB_HORZ, &si, TRUE); + ShowScrollBar(hWnd, SB_HORZ, TRUE); + } + else + { + EnableScrollBar(hWnd, SB_HORZ, ESB_DISABLE_BOTH); + ShowScrollBar(hWnd, SB_HORZ, FALSE); + } + + if (siz.cy < Globals.sizImage.cy * Globals.nZoom + 8) + { + SCROLLINFO si; + EnableScrollBar(hWnd, SB_VERT, ESB_ENABLE_BOTH); + si.cbSize = sizeof(si); + si.fMask = SIF_ALL; + si.nMin = 0; + si.nMax = Globals.sizImage.cy * Globals.nZoom + 8; + si.nPage = siz.cy; + si.nPos = Globals.yScrollPos; + SetScrollInfo(hWnd, SB_VERT, &si, TRUE); + ShowScrollBar(hWnd, SB_VERT, TRUE); + } + else + { + EnableScrollBar(hWnd, SB_VERT, ESB_DISABLE_BOTH); + ShowScrollBar(hWnd, SB_VERT, FALSE); + } + + if (Globals.hbmCanvasBuffer == NULL || + siz.cx + 100 < Globals.sizCanvas.cx || + Globals.sizCanvas.cx < siz.cx || + siz.cy + 100 < Globals.sizCanvas.cy || + Globals.sizCanvas.cy < siz.cy) + { + if (Globals.hbmCanvasBuffer != NULL) + DeleteObject(Globals.hbmCanvasBuffer); + siz.cx += 50; + siz.cy += 50; + Globals.hbmCanvasBuffer = BM_Create(siz); + Globals.sizCanvas = siz; + } +} + +LRESULT CALLBACK CanvasWndProc(HWND hWnd, UINT uMsg, + WPARAM wParam, LPARAM lParam) +{ + INT c, c2; + RECT rc; + + switch (uMsg) + { + case WM_LBUTTONDOWN: + Canvas_OnButtonDown(hWnd, (INT)(SHORT)LOWORD(lParam), + (INT)(SHORT)HIWORD(lParam), FALSE); + break; + case WM_RBUTTONDOWN: + Canvas_OnButtonDown(hWnd, (INT)(SHORT)LOWORD(lParam), + (INT)(SHORT)HIWORD(lParam), TRUE); + break; + + case WM_LBUTTONDBLCLK: + Canvas_OnButtonDblClk(hWnd, (INT)(SHORT)LOWORD(lParam), + (INT)(SHORT)HIWORD(lParam), FALSE); + break; + + case WM_RBUTTONDBLCLK: + Canvas_OnButtonDblClk(hWnd, (INT)(SHORT)LOWORD(lParam), + (INT)(SHORT)HIWORD(lParam), TRUE); + break; + + case WM_LBUTTONUP: + Canvas_OnButtonUp(hWnd, (INT)(SHORT)LOWORD(lParam), + (INT)(SHORT)HIWORD(lParam), FALSE); + break; + + case WM_RBUTTONUP: + Canvas_OnButtonUp(hWnd, (INT)(SHORT)LOWORD(lParam), + (INT)(SHORT)HIWORD(lParam), TRUE); + break; + + case WM_MOUSEMOVE: + Canvas_OnMouseMove(hWnd, (INT)(SHORT)LOWORD(lParam), + (INT)(SHORT)HIWORD(lParam), wParam & MK_LBUTTON, + wParam & MK_RBUTTON); + break; + + case WM_KEYDOWN: + switch ((INT)wParam) + { + case VK_ESCAPE: + if (Globals.mode != MODE_NORMAL) + { + ReleaseCapture(); + Globals.mode = MODE_NORMAL; + Globals.ipt = 0; + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + } + } + break; + + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hDC = BeginPaint(hWnd, &ps); + if (hDC != NULL) + { + Canvas_OnPaint(hWnd, hDC); + EndPaint(hWnd, &ps); + } + break; + } + + case WM_ERASEBKGND: + break; + + case WM_SIZE: + Canvas_OnSize(hWnd); + break; + + case WM_HSCROLL: + switch (LOWORD(wParam)) + { + case SB_PAGELEFT: + GetClientRect(hWnd, &rc); + Globals.xScrollPos -= rc.right - rc.left; + if (Globals.xScrollPos < 0) + Globals.xScrollPos = 0; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + SetScrollPos(hWnd, SB_HORZ, Globals.xScrollPos, TRUE); + break; + + case SB_PAGERIGHT: + GetClientRect(hWnd, &rc); + c = rc.right - rc.left; + Globals.xScrollPos += c; + c2 = Globals.sizImage.cx * Globals.nZoom + 8 - c; + if (Globals.xScrollPos > c2) + Globals.xScrollPos = c2; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + SetScrollPos(hWnd, SB_HORZ, Globals.xScrollPos, TRUE); + break; + + case SB_LINELEFT: + Globals.xScrollPos -= Globals.nZoom; + if (Globals.xScrollPos < 0) + Globals.xScrollPos = 0; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + SetScrollPos(hWnd, SB_HORZ, Globals.xScrollPos, TRUE); + break; + + case SB_LINERIGHT: + GetClientRect(hWnd, &rc); + c = rc.right - rc.left; + Globals.xScrollPos += Globals.nZoom; + c2 = Globals.sizImage.cx * Globals.nZoom + 8 - c; + if (Globals.xScrollPos > c2) + Globals.xScrollPos = c2; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + SetScrollPos(hWnd, SB_HORZ, Globals.xScrollPos, TRUE); + break; + + case SB_THUMBPOSITION: + case SB_THUMBTRACK: + Globals.xScrollPos = (SHORT)HIWORD(wParam); + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + SetScrollPos(hWnd, SB_HORZ, (SHORT)HIWORD(wParam), TRUE); + break; + } + break; + + case WM_VSCROLL: + switch (LOWORD(wParam)) + { + case SB_PAGEUP: + GetClientRect(hWnd, &rc); + Globals.yScrollPos -= rc.bottom - rc.top; + if (Globals.yScrollPos < 0) + Globals.yScrollPos = 0; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + SetScrollPos(hWnd, SB_VERT, Globals.yScrollPos, TRUE); + break; + + case SB_PAGEDOWN: + GetClientRect(hWnd, &rc); + c = rc.bottom - rc.top; + Globals.yScrollPos += c; + c2 = Globals.sizImage.cy * Globals.nZoom + 8 - c; + if (Globals.yScrollPos > c2) + Globals.yScrollPos = c2; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + SetScrollPos(hWnd, SB_VERT, Globals.yScrollPos, TRUE); + break; + + case SB_LINEUP: + Globals.yScrollPos -= Globals.nZoom; + if (Globals.yScrollPos < 0) + Globals.yScrollPos = 0; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + SetScrollPos(hWnd, SB_VERT, Globals.yScrollPos, TRUE); + break; + + case SB_LINEDOWN: + GetClientRect(hWnd, &rc); + c = rc.bottom - rc.top; + Globals.yScrollPos += Globals.nZoom; + c2 = Globals.sizImage.cy * Globals.nZoom + 8 - c; + if (Globals.yScrollPos > c2) + Globals.yScrollPos = c2; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + SetScrollPos(hWnd, SB_VERT, Globals.yScrollPos, TRUE); + break; + + case SB_THUMBPOSITION: + case SB_THUMBTRACK: + Globals.yScrollPos = (SHORT)HIWORD(wParam); + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + SetScrollPos(hWnd, SB_VERT, (SHORT)HIWORD(wParam), TRUE); + break; + } + break; + + default: + return DefWindowProc(hWnd, uMsg, wParam, lParam); + } + return 0; +} diff --git a/programs/paint/cross2.cur b/programs/paint/cross2.cur new file mode 100644 index 0000000000000000000000000000000000000000..b5db12d01445e741394889540988cc8915d06702 GIT binary patch literal 326 zcmZQzU}9ioP*7lC5CB30Mg|5k1_lNVAO;FCH~=vt5P|`ef^ZPz|Ns9H9Ap-w15h&_ v3{=bfNB#i=Lj#ls3gA-@lEVRjZomZp?En8Kfd4QakcVMHYQgfDwtz(d@=SP5 literal 0 HcmV?d00001 diff --git a/programs/paint/fdiagon.cur b/programs/paint/fdiagon.cur new file mode 100644 index 0000000000000000000000000000000000000000..fd34a8420702798655e80234823a4ab1e9f0bdd8 GIT binary patch literal 326 zcma*hy$ypf5QgE;ED&g@ok&QCDwI@2DKbD73NQ{+fRs8T<#-K9l;*6*_hZYll*q|@ zDb+=HC*_h#Fwz5#wZ@*d=Ge{bXkt~{@i4AjyrDovU%x0uyb%tb81P3t_`|uFK4vSf U&zSIK_G>6I^auwbyB#SK3;ZL2Y5)KL literal 0 HcmV?d00001 diff --git a/programs/paint/horizon.cur b/programs/paint/horizon.cur new file mode 100644 index 0000000000000000000000000000000000000000..c460cae5ae217ada097742612752bf7d7aac1bc0 GIT binary patch literal 326 zcmb7;u?|2`3`Nhg5ebtRjYfaK=&#s}KFgn + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define UNICODE + +#include +#include + +#include "main.h" +#include "paint.h" +#include "resource.h" + +PAINT_GLOBALS Globals; + +COLORREF argbDefaultColor[] = +{ + RGB(0, 0, 0), RGB(255, 255, 255), + RGB(128, 128, 128), RGB(192, 192, 192), + RGB(128, 0, 0), RGB(255, 0, 0), + RGB(128, 128, 0), RGB(255, 255, 0), + RGB(0, 128, 0), RGB(0, 255, 0), + RGB(0, 128, 128), RGB(0, 255, 255), + RGB(0, 0, 128), RGB(0, 0, 255), + RGB(128, 0, 128), RGB(255, 0, 255), + RGB(128, 128, 64), RGB(255, 255, 128), + RGB(0, 64, 64), RGB(0, 255, 128), + RGB(0, 128, 255), RGB(128, 255, 255), + RGB(0, 64, 128), RGB(128, 128, 255), + RGB(64, 0, 128), RGB(255, 0, 128), + RGB(128, 64, 0), RGB(255, 128, 64), +}; + +COLORREF argbDefaultMono[] = +{ + RGB(0, 0, 0), RGB(255, 255, 255), + RGB(9, 9, 9), RGB(128, 128, 128), + RGB(18, 18, 18), RGB(137, 137, 137), + RGB(27, 27, 27), RGB(146, 146, 146), + RGB(37, 37, 37), RGB(155, 155, 155), + RGB(46, 46, 46), RGB(164, 164, 164), + RGB(55, 55, 55), RGB(173, 173, 173), + RGB(63, 63, 63), RGB(182, 182, 182), + RGB(73, 73, 73), RGB(191, 191, 191), + RGB(82, 82, 82), RGB(201, 201, 201), + RGB(92, 92, 92), RGB(212, 212, 212), + RGB(101, 101, 101), RGB(222, 222, 222), + RGB(110, 110, 110), RGB(231, 231, 231), + RGB(119, 119, 119), RGB(245, 245, 245) +}; + +COLORREF gargbColorTableMono[] = +{ + RGB(0, 0, 0), + RGB(255, 255, 255) +}; + +static const WCHAR paint_reg_key[] = { + 'S','o','f','t','w','a','r','e','\\', + 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\', + 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', + 'A','p','p','l','e','t','s','\\','P','a','i','n','t',0}; +static const WCHAR setting[] = {'S','e','t','t','i','n','g','s',0}; +static const WCHAR recent_file_list[] = {'R','e','c','e','n','t',' ', + 'F','i','l','e',' ','L','i','s','t',0 + }; +static const WCHAR text[] = {'T','e','x','t',0}; + +static const WCHAR canvasClassName[] = {'c','a','n','v','a','s',0}; +static const WCHAR colorBoxClassName[] = + {'c','o','l','o','r',' ','b','o','x',0}; +static const WCHAR toolBoxClassName[] = + {'t','o','o','l',' ','b','o','x',0}; + +VOID SetFileName(LPCWSTR szFileName) +{ + lstrcpy(Globals.szFileName, szFileName); + Globals.szFileTitle[0] = 0; + GetFileTitle(szFileName, Globals.szFileTitle, SIZEOF(Globals.szFileTitle)); +} + +VOID NotSupportedYet(VOID) +{ + static const WCHAR not_supported[] = {'N','o','t',' ','s','u','p','p','o', + 'r','t','e','d',' ','y','e','t',0}; + MessageBox(Globals.hMainWnd, not_supported, NULL, MB_ICONERROR | MB_OK); +} + +static VOID PAINT_SaveSettingToRegistry(void) +{ + HKEY hkey, hkey2; + DWORD disp; + static const WCHAR recent[] = {'R','e','c','e','n','t',' ', + 'F','i','l','e',' ','L','i','s','t',0 + }; + static const WCHAR text[] = {'T','e','x','t',0}; + static const WCHAR view[] = {'V','i','e','w',0}; + static const WCHAR placement[] = {'W','i','n','d','o','w', + 'P','l','a','c','e','m','e','n','t',0 + }; + static const WCHAR BMPHeight[] = {'B','M','P','H','e','i','g','h','t',0}; + static const WCHAR BMPWidth[] = {'B','M','P','W','i','d','t','h',0}; + + if (RegCreateKeyEx(HKEY_CURRENT_USER, paint_reg_key, 0, NULL, + REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &disp) == + ERROR_SUCCESS) + { + if (RegCreateKeyEx(hkey, recent, 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, NULL, &hkey2, &disp) == ERROR_SUCCESS) + { + /*FIXME: Load recent file list */ + RegCloseKey(hkey2); + } + + if (RegCreateKeyEx(hkey, text, 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, NULL, &hkey2, &disp) == ERROR_SUCCESS) + { + /*FIXME: Load text settings */ + RegCloseKey(hkey2); + } + + if (RegCreateKeyEx(hkey, view, 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, NULL, &hkey2, &disp) == ERROR_SUCCESS) + { + DWORD data; + WINDOWPLACEMENT wndpl; + GetWindowPlacement(Globals.hMainWnd, &wndpl); + RegSetValueEx(hkey2, placement, 0, REG_BINARY, (BYTE*)&wndpl, + sizeof(WINDOWPLACEMENT)); + /* FIXME: How do we save width and height? */ + if (Globals.szFileName[0] == '\0') + { + data = (DWORD)Globals.sizImage.cx; + RegSetValueEx(hkey2, BMPWidth, 0, REG_DWORD, (BYTE*)&data, sizeof(DWORD)); + data = (DWORD)Globals.sizImage.cy; + RegSetValueEx(hkey2, BMPHeight, 0, REG_DWORD, (BYTE*)&data, sizeof(DWORD)); + } + RegCloseKey(hkey2); + } + RegCloseKey(hkey); + } +} + +static VOID PAINT_LoadSettingFromRegistry(void) +{ + HKEY hkey, hkey2; + DWORD size; + static const WCHAR view[] = {'V','i','e','w',0}; + static const WCHAR placement[] = {'W','i','n','d','o','w', + 'P','l','a','c','e','m','e','n','t',0 + }; + static const WCHAR BMPHeight[] = {'B','M','P','H','e','i','g','h','t',0}; + static const WCHAR BMPWidth[] = {'B','M','P','W','i','d','t','h',0}; + if (RegOpenKey(HKEY_CURRENT_USER, paint_reg_key, &hkey) == ERROR_SUCCESS) + { + if (RegOpenKey(hkey, view, &hkey2) == ERROR_SUCCESS) + { + DWORD value; + WINDOWPLACEMENT wndpl; + size = sizeof(WINDOWPLACEMENT); + if (RegQueryValueEx(hkey2, placement, 0, NULL, (BYTE*)&wndpl, + &size) == ERROR_SUCCESS) + { + SetWindowPlacement(Globals.hMainWnd, &wndpl); + } + if (RegQueryValueEx(hkey2, BMPWidth, 0, NULL, (BYTE*)&value, + &size) == ERROR_SUCCESS) + { + Globals.sizImage.cx = (INT)value; + } + if (RegQueryValueEx(hkey2, BMPHeight, 0, NULL, (BYTE*)&value, + &size) == ERROR_SUCCESS) + { + Globals.sizImage.cy = (INT)value; + } + } + } +} + +static int PAINT_OnCommand(WPARAM wParam) +{ + switch (wParam) + { + case CMD_NEW: PAINT_FileNew(); break; + case CMD_OPEN: PAINT_FileOpen(); break; + case CMD_SAVE: PAINT_FileSave(); break; + case CMD_SAVE_AS: PAINT_FileSaveAs(); break; + case CMD_PRINT_PREVIEW: PAINT_FilePrintPreview(); break; + case CMD_PRINT: PAINT_FilePrint(); break; + case CMD_PAGE_SETUP: PAINT_FilePageSetup(); break; + case CMD_WALLPAPAER_TILED: PAINT_SetAsWallpaperTiled(); break; + case CMD_WALLPAPAER_CENTERED: PAINT_SetAsWallpaperCentered(); break; + case CMD_EXIT: PAINT_FileExit(); break; + + case CMD_UNDO: PAINT_EditUndo(); break; + case CMD_REPEAT: PAINT_EditRepeat(); break; + case CMD_CUT: PAINT_EditCut(); break; + case CMD_COPY: PAINT_EditCopy(); break; + case CMD_PASTE: PAINT_EditPaste(); break; + case CMD_DELETE: PAINT_EditDelete(); break; + case CMD_SELECT_ALL: PAINT_EditSelectAll(); break; + case CMD_COPY_TO: PAINT_CopyTo(); break; + case CMD_PASTE_FROM: PAINT_PasteFrom(); break; + + case CMD_TOOL_BOX: PAINT_ToolBox(); break; + case CMD_COLOR_BOX: PAINT_ColorBox(); break; + case CMD_STATUS_BAR: PAINT_StatusBar(); break; + case CMD_ZOOM_NORMAL: PAINT_Zoom(1); break; + case CMD_ZOOM_LARGE: PAINT_Zoom(4); break; + case CMD_SHOW_GRID: PAINT_ShowGrid(); break; + case CMD_ZOOM_CUSTOM: PAINT_ZoomCustom(); break; + + case CMD_FLIP_ROTATE: PAINT_FlipRotate(); break; + case CMD_STRETCH_SKEW: PAINT_StretchSkew(); break; + case CMD_INVERT_COLORS: PAINT_InvertColors(); break; + case CMD_ATTRIBUTES: PAINT_Attributes(); break; + case CMD_CLEAR_IMAGE: PAINT_ClearImage(); break; + case CMD_DRAW_OPAQUE: break; + case CMD_CLEAR_SELECTION: PAINT_ClearSelection(); break; + + case CMD_EDIT_COLOR: PAINT_EditColor(FALSE); break; + + case CMD_HELP_CONTENTS: PAINT_HelpContents(); break; + case CMD_HELP_ON_HELP: PAINT_HelpHelp(); break; + case CMD_HELP_ABOUT_PAINT: PAINT_HelpAboutPaint(); break; + } + return 0; +} + +static VOID PAINT_InitData(VOID) +{ + WCHAR sz[256]; + LPWSTR p = Globals.szFilter; + static const WCHAR bmp_files[] = { '*','.','b','m','p',0 }; + static const WCHAR all_files[] = { '*','.','*',0 }; + + LoadString(Globals.hInstance, STRING_BMP_FILES_BMP, p, MAX_STRING_LEN); + p += lstrlen(p) + 1; + lstrcpy(p, bmp_files); + p += lstrlen(p) + 1; + LoadString(Globals.hInstance, STRING_ALL_FILES, p, MAX_STRING_LEN); + p += lstrlen(p) + 1; + lstrcpy(p, all_files); + p += lstrlen(p) + 1; + *p = '\0'; + + Globals.cColors = 28; + CopyMemory(Globals.argbColors, argbDefaultColor, sizeof(Globals.argbColors)); + + Globals.iForeColor = 0; + Globals.iBackColor = 1; + Globals.rgbFore = RGB(0, 0, 0); + Globals.rgbBack = RGB(255, 255, 255); + Globals.iToolSelect = TOOL_PENCIL; + Globals.iToolClicking = -1; + + Globals.hbmImage = NULL; + Globals.hbmBuffer = NULL; + Globals.hbmZoomBuffer = NULL; + Globals.hbmCanvasBuffer = NULL; + + Globals.hbmSelect = NULL; + Globals.fSelect = FALSE; + Globals.fModified = FALSE; + Globals.sizImage.cx = 100; + Globals.sizImage.cy = 100; + Globals.sizCanvas.cx = 0; + Globals.sizCanvas.cy = 0; + + Globals.hcurArrow = LoadCursor(NULL, IDC_ARROW); + Globals.hcurHorizontal = LoadCursor(Globals.hInstance, MAKEINTRESOURCE(1)); + Globals.hcurVertical = LoadCursor(Globals.hInstance, MAKEINTRESOURCE(2)); + Globals.hcurBDiagonal = LoadCursor(Globals.hInstance, MAKEINTRESOURCE(3)); + Globals.hcurFDiagonal = LoadCursor(Globals.hInstance, MAKEINTRESOURCE(4)); + Globals.hcurPencil = LoadCursor(Globals.hInstance, MAKEINTRESOURCE(5)); + Globals.hcurCross2 = LoadCursor(Globals.hInstance, MAKEINTRESOURCE(12)); + + Globals.nLineWidth = 1; + + Globals.nZoom = 1; + Globals.fShowGrid = FALSE; + Globals.xScrollPos = Globals.yScrollPos = 0; + + LoadString(Globals.hInstance, STRING_READY, sz, 256); + SendMessage(Globals.hStatusBar, SB_SETTEXT, 0 | 0, (LPARAM)sz); +} + +static VOID PAINT_OnInitMenuPopup(HMENU hMenu, int index) +{ + CheckMenuItem(hMenu, CMD_TOOL_BOX, + IsWindowVisible(Globals.hToolBox) ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, CMD_COLOR_BOX, + IsWindowVisible(Globals.hColorBox) ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, CMD_STATUS_BAR, + IsWindowVisible(Globals.hStatusBar) ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, CMD_SHOW_GRID, + Globals.fShowGrid ? MF_CHECKED : MF_UNCHECKED); + EnableMenuItem(hMenu, CMD_SHOW_GRID, + Globals.nZoom >= 3 ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenu, CMD_ZOOM_NORMAL, + Globals.nZoom != 1 ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenu, CMD_ZOOM_LARGE, + Globals.nZoom != 4 ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenu, CMD_CLEAR_IMAGE, + Globals.fSelect ? MF_GRAYED : MF_ENABLED); + EnableMenuItem(hMenu, CMD_UNDO, + Globals.fCanUndo ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenu, CMD_REPEAT, + !Globals.fCanUndo && Globals.hbmImageUndo ? + MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenu, CMD_CUT, + Globals.fSelect ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenu, CMD_COPY, + Globals.fSelect ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenu, CMD_PASTE, + IsClipboardFormatAvailable(CF_DIB) ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenu, CMD_DELETE, + Globals.fSelect ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenu, CMD_COPY_TO, + Globals.fSelect ? MF_ENABLED : MF_GRAYED); +} + +VOID ColorBox_OnPaint(HWND hWnd, HDC hDC) +{ + INT i; + HBRUSH hbr; + RECT rc; + + rc.left = 10; + rc.top = 10; + rc.right = rc.left + 34; + rc.bottom = rc.top + 34; + DrawEdge(hDC, &rc, EDGE_SUNKEN, BF_ADJUST|BF_RECT); + FillRect(hDC, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); + + rc.left = 23; + rc.top = 23; + rc.right = rc.left + 16; + rc.bottom = rc.top + 16; + DrawEdge(hDC, &rc, EDGE_RAISED, BF_ADJUST|BF_RECT); + hbr = CreateSolidBrush(Globals.rgbBack); + FillRect(hDC, &rc, hbr); + DeleteObject(hbr); + + rc.left = 15; + rc.top = 15; + rc.right = rc.left + 16; + rc.bottom = rc.top + 16; + DrawEdge(hDC, &rc, EDGE_RAISED, BF_ADJUST|BF_RECT); + hbr = CreateSolidBrush(Globals.rgbFore); + FillRect(hDC, &rc, hbr); + DeleteObject(hbr); + + for (i = 0; i < SIZEOF(argbDefaultColor); i++) + { + rc.left = 60 + i / 2 * 17; + rc.top = 10 + (i % 2) * 17; + rc.right = rc.left + 16; + rc.bottom = rc.top + 16; + DrawEdge(hDC, &rc, EDGE_SUNKEN, BF_ADJUST|BF_RECT); + hbr = CreateSolidBrush(Globals.argbColors[i]); + FillRect(hDC, &rc, hbr); + DeleteObject(hbr); + } +} + +VOID ColorBox_OnButtonDown(HWND hWnd, INT x, INT y, BOOL fRight) +{ + INT i; + POINT pt; + RECT rc; + + pt.x = x; + pt.y = y; + + for (i = 0; i < SIZEOF(argbDefaultColor); i++) + { + rc.left = 60 + i / 2 * 17; + rc.top = 10 + (i % 2) * 17; + rc.right = rc.left + 16; + rc.bottom = rc.top + 16; + + if (PtInRect(&rc, pt)) + { + if (fRight) + { + Globals.rgbBack = Globals.argbColors[i]; + Globals.iBackColor = i; + } + else + { + Globals.rgbFore = Globals.argbColors[i]; + Globals.iForeColor = i; + } + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + break; + } + } +} + +VOID ColorBox_OnButtonDblClk(HWND hWnd, INT x, INT y, BOOL fRight) +{ + INT i; + POINT pt; + RECT rc; + + pt.x = x; + pt.y = y; + + for (i = 0; i < SIZEOF(argbDefaultColor); i++) + { + rc.left = 60 + i / 2 * 17; + rc.top = 10 + (i % 2) * 17; + rc.right = rc.left + 16; + rc.bottom = rc.top + 16; + + if (PtInRect(&rc, pt)) + { + PAINT_EditColor(fRight); + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + return; + } + } +} + +LRESULT CALLBACK ColorBoxWndProc(HWND hWnd, UINT uMsg, + WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_LBUTTONDOWN: + ColorBox_OnButtonDown(hWnd, (INT)(SHORT)LOWORD(lParam), + (INT)(SHORT)HIWORD(lParam), FALSE); + break; + + case WM_RBUTTONDOWN: + ColorBox_OnButtonDown(hWnd, (INT)(SHORT)LOWORD(lParam), + (INT)(SHORT)HIWORD(lParam), TRUE); + break; + + case WM_LBUTTONDBLCLK: + ColorBox_OnButtonDblClk(hWnd, (INT)(SHORT)LOWORD(lParam), + (INT)(SHORT)HIWORD(lParam), FALSE); + break; + + case WM_RBUTTONDBLCLK: + ColorBox_OnButtonDblClk(hWnd, (INT)(SHORT)LOWORD(lParam), + (INT)(SHORT)HIWORD(lParam), TRUE); + break; + + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hDC = BeginPaint(hWnd, &ps); + if (hDC != NULL) + { + ColorBox_OnPaint(hWnd, hDC); + EndPaint(hWnd, &ps); + } + break; + } + + default: + return DefWindowProc(hWnd, uMsg, wParam, lParam); + } + return 0; +} + +VOID ToolBox_OnPaint(HWND hWnd, HDC hDC) +{ + HBITMAP hbm, hbmOld; + INT i; + RECT rc; + POINT pt; + HDC hdcMem; + INT cMap; + COLORMAP aMap[] = + { + {RGB(255, 0, 0), 0}, + {RGB(0, 0, 0), RGB(255, 255, 255)}, + }; + + aMap[0].to = GetSysColor(COLOR_3DFACE); + if (GetSysColor(COLOR_3DFACE) == RGB(0, 0, 0)) + cMap = 2; + else + cMap = 1; + + hdcMem = CreateCompatibleDC(hDC); + if (hdcMem != NULL) + { + hbm = CreateMappedBitmap(Globals.hInstance, IDB_TOOLS, 0, + aMap, cMap); + hbmOld = SelectObject(hdcMem, hbm); + + for (i = 0; i < 16; i++) + { + rc.left = 3 + i % 2 * 25; + rc.top = 3 + i / 2 * 25; + rc.right = rc.left + 25; + rc.bottom = rc.top + 25; + + GetCursorPos(&pt); + ScreenToClient(hWnd, &pt); + if (Globals.iToolSelect == i || (Globals.iToolClicking == i && PtInRect(&rc, pt))) + { + DrawEdge(hDC, &rc, EDGE_SUNKEN, BF_RECT | BF_SOFT); + BitBlt(hDC, rc.left + 5, rc.top + 5, 16, 16, + hdcMem, i * 16, 0, SRCCOPY); + } + else + { + DrawEdge(hDC, &rc, EDGE_RAISED, BF_RECT | BF_SOFT); + BitBlt(hDC, rc.left + 4, rc.top + 4, 16, 16, + hdcMem, i * 16, 0, SRCCOPY); + } + } + + SelectObject(hdcMem, hbmOld); + DeleteObject(hbm); + + rc.left = 5; + rc.top = 210; + rc.right = 49; + rc.bottom = 290; + DrawEdge(hDC, &rc, EDGE_SUNKEN, BF_RECT|BF_ADJUST); + + DeleteDC(hdcMem); + } +} + +void ToolBox_OnLButton(HWND hWnd, int x, int y, BOOL fDown) +{ + RECT rc; + POINT pt; + INT i; + + pt.x = x; + pt.y = y; + for (i = 0; i < 16; i++) + { + rc.left = 3 + i % 2 * 25; + rc.top = 3 + i / 2 * 25; + rc.right = rc.left + 25; + rc.bottom = rc.top + 25; + if (PtInRect(&rc, pt)) + { + if (!fDown && Globals.iToolClicking == i) + { + Globals.iToolPrev = Globals.iToolSelect; + Globals.iToolSelect = i; + Globals.iToolClicking = -1; + Globals.ipt = 0; + SetRectEmpty((RECT*)&Globals.pt0); + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); + + switch (i) + { + case TOOL_SPOIT: + case TOOL_POLYSELECT: + case TOOL_BOXSELECT: + case TOOL_TEXT: + case TOOL_BRUSH: + case TOOL_AIRBRUSH: + case TOOL_FILL: + case TOOL_ERASER: + case TOOL_POLYGON: + case TOOL_MAGNIFIER: + case TOOL_CURVE: + case TOOL_BOX: + case TOOL_ELLIPSE: + case TOOL_ROUNDRECT: + case TOOL_LINE: + NotSupportedYet(); + break; + + default: + break; + } + } + else if (fDown) + { + Globals.iToolClicking = i; + SetCapture(hWnd); + } + InvalidateRect(Globals.hToolBox, NULL, TRUE); + UpdateWindow(Globals.hToolBox); + return; + } + } + + rc.left = 6; + rc.top = 210; + rc.right = 48; + rc.bottom = 290; + if (PtInRect(&rc, pt)) + { + MessageBeep(0xFFFFFFFF); + } +} + +void ToolBox_OnMouseMove(HWND hWnd, int x, int y, BOOL fDown) +{ + RECT rc; + POINT pt; + WCHAR sz[256]; + INT i; + pt.x = x; + pt.y = y; + + if (!fDown) + { + ReleaseCapture(); + Globals.iToolClicking = -1; + InvalidateRect(Globals.hToolBox, NULL, FALSE); + UpdateWindow(Globals.hToolBox); + } + else if (Globals.iToolClicking != -1) + { + rc.left = 3 + Globals.iToolClicking % 2 * 25; + rc.top = 3 + Globals.iToolClicking / 2 * 25; + rc.right = rc.left + 25; + rc.bottom = rc.top + 25; + InvalidateRect(Globals.hToolBox, NULL, FALSE); + UpdateWindow(Globals.hToolBox); + return; + } + + for (i = 0; i < 16; i++) + { + rc.left = 3 + i % 2 * 25; + rc.top = 3 + i / 2 * 25; + rc.right = rc.left + 25; + rc.bottom = rc.top + 25; + if (PtInRect(&rc, pt)) + { + LoadString(Globals.hInstance, i + STRING_POLYSELECT, sz, 256); + SendMessage(Globals.hStatusBar, SB_SETTEXT, 0 | 0, (LPARAM)sz); + return; + } + } + + LoadString(Globals.hInstance, STRING_READY, sz, 256); + SendMessage(Globals.hStatusBar, SB_SETTEXT, 0 | 0, (LPARAM)sz); +} + +static LRESULT CALLBACK ToolBoxWndProc(HWND hWnd, UINT uMsg, + WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_LBUTTONDOWN: + ToolBox_OnLButton(hWnd, LOWORD(lParam), HIWORD(lParam), TRUE); + break; + + case WM_LBUTTONUP: + ToolBox_OnLButton(hWnd, LOWORD(lParam), HIWORD(lParam), FALSE); + break; + + case WM_MOUSEMOVE: + ToolBox_OnMouseMove(hWnd, LOWORD(lParam), HIWORD(lParam), wParam & MK_LBUTTON); + break; + + case WM_CAPTURECHANGED: + Globals.iToolClicking = -1; + InvalidateRect(Globals.hToolBox, NULL, TRUE); + UpdateWindow(Globals.hToolBox); + break; + + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hDC = BeginPaint(hWnd, &ps); + if (hDC != NULL) + { + ToolBox_OnPaint(hWnd, hDC); + EndPaint(hWnd, &ps); + } + break; + } + + default: + return DefWindowProc(hWnd, uMsg, wParam, lParam); + } + return 0; +} + +VOID SetParts(HWND hWnd) +{ + INT aWidth[3]; + RECT rc; + + GetClientRect(hWnd, &rc); + if (rc.right - rc.left < 450) + { + aWidth[0] = 250; + aWidth[1] = 300; + aWidth[2] = 350; + } + else + { + aWidth[0] = rc.right - rc.left - 250; + aWidth[1] = rc.right - rc.left - 125; + aWidth[2] = rc.right - rc.left - 20; + } + SendMessage(Globals.hStatusBar, SB_SETPARTS, 3, (LPARAM)aWidth); +} + +VOID PAINT_OnDestroy(HWND hWnd) +{ + if (Globals.hbmImage != NULL) DeleteObject(Globals.hbmImage); + if (Globals.hbmBuffer != NULL) DeleteObject(Globals.hbmBuffer); + if (Globals.hbmZoomBuffer != NULL) DeleteObject(Globals.hbmZoomBuffer); + if (Globals.hbmCanvasBuffer != NULL) DeleteObject(Globals.hbmCanvasBuffer); + if (Globals.hbmImageUndo != NULL) DeleteObject(Globals.hbmImageUndo); + if (Globals.hbmSelect != NULL) DeleteObject(Globals.hbmSelect); + DestroyCursor(Globals.hcurArrow); + DestroyCursor(Globals.hcurBDiagonal); + DestroyCursor(Globals.hcurFDiagonal); + DestroyCursor(Globals.hcurHorizontal); + DestroyCursor(Globals.hcurVertical); + DestroyCursor(Globals.hcurPencil); + DestroyCursor(Globals.hcurCross2); + KillTimer(Globals.hCanvasWnd, Globals.idTimer); +} + +static LRESULT CALLBACK PaintWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, + LPARAM lParam) +{ + RECT rc; + WCHAR sz[MAX_STRING_LEN]; + WCHAR wszTitle[] = {0}; + + switch (uMsg) + { + case WM_CREATE: + GetClientRect(hWnd, &rc); + Globals.hCanvasWnd = CreateWindowEx(WS_EX_CLIENTEDGE, canvasClassName, + wszTitle, WS_CHILD|WS_VISIBLE, 0, 0, 0, 0, hWnd, + NULL, Globals.hInstance, NULL); + if (Globals.hCanvasWnd == NULL) + return -1; + Globals.hColorBox = CreateWindowEx(WS_EX_WINDOWEDGE, + colorBoxClassName, wszTitle, WS_CHILD|WS_VISIBLE, + 0, 0, 0, 0, hWnd, NULL, Globals.hInstance, NULL); + if (Globals.hColorBox == NULL) + return -1; + Globals.hStatusBar = CreateStatusWindow(WS_VISIBLE|WS_CHILD, + wszTitle, hWnd, 3); + if (Globals.hStatusBar == NULL) + return -1; + Globals.hToolBox = CreateWindowEx(WS_EX_WINDOWEDGE, toolBoxClassName, + wszTitle, WS_CHILD|WS_VISIBLE, 0, 0, 0, 0, hWnd, + NULL, Globals.hInstance, NULL); + if (Globals.hToolBox == NULL) + return -1; + + SetParts(hWnd); + break; + + case WM_KEYDOWN: + SendMessage(Globals.hCanvasWnd, uMsg, wParam, lParam); + break; + + case WM_COMMAND: + PAINT_OnCommand(LOWORD(wParam)); + break; + + case WM_MENUSELECT: + if ((HIWORD(wParam) & (MF_SYSMENU|MF_POPUP|MF_SEPARATOR)) == 0) + { + LoadString(Globals.hInstance, LOWORD(wParam) + 0x200, sz, MAX_STRING_LEN); + } + else if ((HIWORD(wParam) & (MF_SYSMENU|MF_POPUP|MF_SEPARATOR)) == MF_SYSMENU) + { + INT id; + switch(LOWORD(wParam)) + { + case SC_SIZE: id = STRING_SIZE; break; + case SC_MOVE: id = STRING_MOVE; break; + case SC_MINIMIZE: id = STRING_MINIMIZE; break; + case SC_MAXIMIZE: id = STRING_MAXIMIZE; break; + case SC_NEXTWINDOW: id = STRING_NEXTWINDOW; break; + case SC_PREVWINDOW: id = STRING_PREVWINDOW; break; + case SC_CLOSE: id = STRING_CLOSE; break; + case SC_RESTORE: id = STRING_RESTORE; break; + case SC_TASKLIST: id = STRING_TASKLIST; break; + default: id = STRING_READY; + } + LoadString(Globals.hInstance, id, sz, MAX_STRING_LEN); + } + else + { + sz[0] = '\0'; + } + SendMessage(Globals.hStatusBar, SB_SETTEXT, 0 | 0, (LPARAM)sz); + break; + + case WM_EXITMENULOOP: + LoadString(Globals.hInstance, STRING_READY, sz, 256); + SendMessage(Globals.hStatusBar, SB_SETTEXT, 0 | 0, (LPARAM)sz); + break; + + case WM_CLOSE: + if (DoCloseFile()) + { + DestroyWindow(hWnd); + } + break; + + case WM_GETMINMAXINFO: + { + MINMAXINFO *pmmi = (MINMAXINFO*)lParam; + pmmi->ptMinTrackSize.x = 330; + pmmi->ptMinTrackSize.y = 410; + break; + } + + case WM_SIZE: + { + RECT rc2; + INT leftSave; + HDWP hDwp; + + GetClientRect(hWnd, &rc); + + hDwp = BeginDeferWindowPos(1 + + !!IsWindowVisible(Globals.hStatusBar) + + !!IsWindowVisible(Globals.hColorBox) + + !!IsWindowVisible(Globals.hToolBox)); + if (IsWindowVisible(Globals.hStatusBar)) + { + PostMessage(Globals.hStatusBar, WM_SIZE, 0, 0); + GetWindowRect(Globals.hStatusBar, &rc2); + DeferWindowPos(hDwp, Globals.hStatusBar, NULL, + rc2.left, rc2.top, + rc2.right - rc2.left, rc2.bottom - rc2.top, + SWP_NOACTIVATE | SWP_NOREPOSITION | SWP_NOZORDER); + rc.bottom -= (rc2.bottom - rc2.top); + } + if (IsWindowVisible(Globals.hColorBox)) + { + rc.bottom -= 55; + } + leftSave = rc.left; + if (IsWindowVisible(Globals.hToolBox)) + { + LONG rightSave = rc.right; + rc.right = rc.left + 60; + DeferWindowPos(hDwp, Globals.hToolBox, NULL, + rc.left, rc.top, + rc.right - rc.left, rc.bottom - rc.top, + SWP_NOACTIVATE | SWP_NOREPOSITION | SWP_NOZORDER); + rc.left = rc.right; + rc.right = rightSave; + } + DeferWindowPos(hDwp, Globals.hCanvasWnd, NULL, + rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, + SWP_NOACTIVATE | SWP_NOREPOSITION | SWP_NOZORDER); + if (IsWindowVisible(Globals.hColorBox)) + { + rc.left = leftSave; + rc.top = rc.bottom; + rc.bottom = rc.top + 55; + DeferWindowPos(hDwp, Globals.hColorBox, NULL, rc.left, rc.top, + rc.right - rc.left, rc.bottom - rc.top, + SWP_NOACTIVATE | SWP_NOREPOSITION | SWP_NOZORDER); + } + EndDeferWindowPos(hDwp); + SetParts(hWnd); + PostMessage(Globals.hCanvasWnd, WM_SIZE, 0, 0); + break; + } + + case WM_QUERYENDSESSION: + if (DoCloseFile()) + return 1; + break; + + case WM_DESTROY: + PAINT_SaveSettingToRegistry(); + PAINT_OnDestroy(hWnd); + PostQuitMessage(0); + break; + + case WM_SETFOCUS: + break; + + case WM_DROPFILES: + { + WCHAR szFileName[MAX_PATH]; + HDROP hDrop = (HDROP)wParam; + + DragQueryFile(hDrop, 0, szFileName, SIZEOF(szFileName)); + DragFinish(hDrop); + DoOpenFile(szFileName); + break; + } + + case WM_INITMENUPOPUP: + PAINT_OnInitMenuPopup((HMENU)wParam, lParam); + break; + + default: + return DefWindowProc(hWnd, uMsg, wParam, lParam); + } + return 0; +} + +static int AlertFileDoesNotExist(LPCWSTR szFileName) +{ + int nResult; + WCHAR szMessage[MAX_STRING_LEN]; + WCHAR szResource[MAX_STRING_LEN]; + + LoadString(Globals.hInstance, STRING_DOESNOTEXIST, szResource, + SIZEOF(szResource)); + wsprintf(szMessage, szResource, szFileName); + + MessageBeep(MB_ICONEXCLAMATION); + nResult = MessageBox(Globals.hMainWnd, szMessage, NULL, + MB_ICONEXCLAMATION | MB_YESNO); + + return nResult; +} + +static void HandleCommandLine(LPWSTR cmdline) +{ + WCHAR delimiter; + int opt_print = 0; + + /* skip white space */ + while (*cmdline == ' ') cmdline++; + + /* skip executable name */ + delimiter = (*cmdline == '"' ? '"' : ' '); + + if (*cmdline == delimiter) cmdline++; + + while (*cmdline && *cmdline != delimiter) cmdline++; + + if (*cmdline == delimiter) cmdline++; + + while (*cmdline == ' ' || *cmdline == '-' || *cmdline == '/') + { + WCHAR option; + + if (*cmdline++ == ' ') continue; + + option = *cmdline; + if (option) cmdline++; + while (*cmdline == ' ') cmdline++; + + switch (option) + { + case 'p': + case 'P': + opt_print=1; + break; + } + } + + if (*cmdline) + { + LPCWSTR file_name; + BOOL file_exists; + WCHAR buf[MAX_PATH]; + + if (cmdline[0] == '"') + { + WCHAR* wc; + cmdline++; + wc = cmdline; + while (*wc && *wc != '"') wc++; + *wc = 0; + } + + if (FileExists(cmdline)) + { + file_exists = TRUE; + file_name = cmdline; + } + else + { + static const WCHAR txtW[] = { '.','b','m','p',0 }; + + /* try to find file with ".txt" extension */ + if (!lstrcmp(txtW, cmdline + lstrlen(cmdline) - lstrlen(txtW))) + { + file_exists = FALSE; + file_name = cmdline; + } + else + { + lstrcpyn(buf, cmdline, MAX_PATH - lstrlen(txtW) - 1); + lstrcat(buf, txtW); + file_name = buf; + file_exists = FileExists(buf); + } + } + + if (file_exists) + { + DoOpenFile(file_name); + InvalidateRect(Globals.hMainWnd, NULL, FALSE); + if (opt_print) + PAINT_FilePrint(); + } + else + { + switch (AlertFileDoesNotExist(file_name)) + { + case IDYES: + DoOpenFile(file_name); + break; + + case IDNO: + break; + } + } + } +} + +int WINAPI WinMain( + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR pszCmdLine, + int nCmdShow) +{ + MSG msg; + HACCEL hAccel; + WNDCLASSEX wcx; + + static const WCHAR className[] = {'P','a','i','n','t',0}; + static const WCHAR winName[] = {'P','a','i','n','t',0}; + + ZeroMemory(&Globals, sizeof(Globals)); + Globals.hInstance = hInstance; + + ZeroMemory(&wcx, sizeof(wcx)); + wcx.cbSize = sizeof(wcx); + wcx.lpfnWndProc = PaintWndProc; + wcx.hInstance = Globals.hInstance; + wcx.hIcon = LoadIcon(Globals.hInstance, MAKEINTRESOURCE(IDI_PAINT)); + wcx.hCursor = LoadCursor(0, IDC_ARROW); + wcx.hbrBackground = (HBRUSH)(COLOR_3DDKSHADOW + 1); + wcx.lpszMenuName = MAKEINTRESOURCE(MAIN_MENU); + wcx.lpszClassName = className; + + if (!RegisterClassEx(&wcx)) return FALSE; + + wcx.style = CS_DBLCLKS; + wcx.lpfnWndProc = CanvasWndProc; + wcx.hIcon = NULL; + wcx.hbrBackground = NULL; + wcx.lpszMenuName = NULL; + wcx.lpszClassName = canvasClassName; + + if (!RegisterClassEx(&wcx)) return FALSE; + + wcx.lpfnWndProc = ColorBoxWndProc; + wcx.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1); + wcx.lpszClassName = colorBoxClassName; + + if (!RegisterClassEx(&wcx)) return FALSE; + + wcx.style = 0; + wcx.lpfnWndProc = ToolBoxWndProc; + wcx.lpszClassName = toolBoxClassName; + + if (!RegisterClassEx(&wcx)) return FALSE; + + Globals.hMainWnd = CreateWindow(className, winName, + WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN, + CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, + Globals.hInstance, NULL); + if (Globals.hMainWnd == NULL) + { + ShowLastError(); + return 1; + } + + PAINT_InitData(); + PAINT_LoadSettingFromRegistry(); + PAINT_FileNew(); + + ShowWindow(Globals.hMainWnd, nCmdShow); + UpdateWindow(Globals.hMainWnd); + DragAcceptFiles(Globals.hMainWnd, TRUE); + + HandleCommandLine(GetCommandLine()); + + hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(ID_ACCEL)); + + while (GetMessage(&msg, 0, 0, 0)) + { + if (!TranslateAccelerator(Globals.hMainWnd, hAccel, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + return msg.wParam; +} diff --git a/programs/paint/main.h b/programs/paint/main.h new file mode 100644 index 0000000..c12bf48 --- /dev/null +++ b/programs/paint/main.h @@ -0,0 +1,139 @@ +/* + * Paint (main.h) + * + * Copyright 2008 Katayama Hirofumi MZ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define MAX_STRING_LEN 255 + +#define SIZEOF(a) sizeof(a)/sizeof((a)[0]) + +typedef enum +{ + MODE_NORMAL, + MODE_RIGHT_EDGE, + MODE_DOWN_EDGE, + MODE_LOWER_RIGHT_EDGE, + MODE_SELECTION, + MODE_CANVAS +} MODE; + +typedef enum +{ + TOOL_POLYSELECT, + TOOL_BOXSELECT, + TOOL_ERASER, + TOOL_FILL, + TOOL_SPOIT, + TOOL_MAGNIFIER, + TOOL_PENCIL, + TOOL_BRUSH, + TOOL_AIRBRUSH, + TOOL_TEXT, + TOOL_LINE, + TOOL_CURVE, + TOOL_BOX, + TOOL_POLYGON, + TOOL_ELLIPSE, + TOOL_ROUNDRECT +} TOOL; + +typedef struct +{ + HANDLE hInstance; + + HWND hMainWnd; + HWND hCanvasWnd; + HWND hToolBox; + HWND hColorBox; + HWND hStatusBar; + HWND hTextTool; + + SIZE sizImage; + SIZE sizCanvas; + HBITMAP hbmImage; + HBITMAP hbmBuffer; + HBITMAP hbmZoomBuffer; + HBITMAP hbmCanvasBuffer; + + BOOL fCanUndo; + HBITMAP hbmImageUndo; + SIZE sizImageUndo; + + BOOL fSelect; + HBITMAP hbmSelect; + + BOOL fModified; + + INT cColors; + COLORREF argbColors[28]; + INT iForeColor; + INT iBackColor; + COLORREF rgbFore; + COLORREF rgbBack; + + WCHAR szFileName[MAX_PATH]; + WCHAR szFileTitle[MAX_PATH]; + WCHAR szFilter[1024]; + + TOOL iToolSelect; + TOOL iToolClicking; + TOOL iToolPrev; + + HCURSOR hcurArrow; + HCURSOR hcurBDiagonal; + HCURSOR hcurFDiagonal; + HCURSOR hcurHorizontal; + HCURSOR hcurVertical; + HCURSOR hcurPencil; + HCURSOR hcurCross2; + + UINT idTimer; + + INT nZoom; + BOOL fShowGrid; + + INT nLineWidth; + + INT xScrollPos; + INT yScrollPos; + + MODE mode; + BOOL fSwapColor; + POINT pt0; + POINT pt1; + POINT pt2; + POINT pt3; + INT ipt; + COLORREF rgbPrev; +} PAINT_GLOBALS; + +extern PAINT_GLOBALS Globals; + +/* main.c */ +VOID SetFileName(LPCWSTR szFileName); +VOID NotSupportedYet(VOID); + +/* canvas.c */ +LRESULT CALLBACK CanvasWndProc(HWND hWnd, UINT uMsg, + WPARAM wParam, LPARAM lParam); +VOID Canvas_Resize(HWND hWnd, SIZE sizNew); + +/* bitmap.c */ +HBITMAP BM_Create(SIZE siz); +HBITMAP BM_CreateResized(HWND hWnd, SIZE sizNew, HBITMAP hbm, SIZE siz); +HBITMAP BM_Copy(HBITMAP hbm); diff --git a/programs/paint/paint.c b/programs/paint/paint.c new file mode 100644 index 0000000..4caa0a2 --- /dev/null +++ b/programs/paint/paint.c @@ -0,0 +1,616 @@ +/* + * Paint (paint.c) + * + * Copyright 2008 Katayama Hirofumi MZ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define UNICODE + +#include +#include +#include +#include + +#include "main.h" +#include "paint.h" +#include "resource.h" + +static const WCHAR helpfileW[] = + { 'p','a','i','n','t','.','h','l','p',0 }; + +static const WCHAR desktop_key[] = + {'C','o','n','t','r','o','l',' ', + 'P','a','n','e','l','\\', + 'D','e','s','k','t','o','p',0 + }; +static const WCHAR wallpaper_style[] = + {'W','a','l','l','p','a','p','e','r', + 'S','t','y','l','e',0 + }; +static const WCHAR tile_wallpaper[] = + {'T','i','l','e', + 'W','a','l','l','p','a','p','e','r',0 + }; + +COLORREF aCustColors[16] = +{ + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255) +}; + +VOID ShowLastError(void) +{ + WCHAR szMsg[MAX_STRING_LEN]; + LONG nError = GetLastError(); + if (nError != NO_ERROR) + { + if (nError > 0) + { + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, nError, 0, szMsg, MAX_STRING_LEN, NULL); + } + else + { + LoadString(Globals.hInstance, -nError, szMsg, MAX_STRING_LEN); + } + MessageBeep(MB_ICONERROR); + MessageBox(NULL, szMsg, NULL, MB_OK | MB_ICONERROR); + } +} + +static void UpdateWindowCaption(void) +{ + WCHAR szCaption[MAX_STRING_LEN]; + WCHAR szPaint[MAX_STRING_LEN]; + static const WCHAR hyphenW[] = { ' ','-',' ',0 }; + + if (Globals.szFileTitle[0] != '\0') + lstrcpy(szCaption, Globals.szFileTitle); + else + LoadString(Globals.hInstance, STRING_UNTITLED, szCaption, + MAX_STRING_LEN); + + LoadString(Globals.hInstance, STRING_PAINT, szPaint, MAX_STRING_LEN); + lstrcat(szCaption, hyphenW); + lstrcat(szCaption, szPaint); + + SetWindowText(Globals.hMainWnd, szCaption); +} + +int PAINT_StringMsgBox(HWND hParent, int formatId, LPCWSTR szString, + UINT uFlags) +{ + WCHAR szMessage[MAX_STRING_LEN]; + WCHAR szResource[MAX_STRING_LEN]; + + LoadString(Globals.hInstance, formatId, szResource, MAX_STRING_LEN); + wnsprintf(szMessage, MAX_STRING_LEN, szResource, szString); + + LoadString(Globals.hInstance, STRING_PAINT, szResource, MAX_STRING_LEN); + + if (hParent == NULL) + hParent = Globals.hMainWnd; + + MessageBeep(uFlags & MB_ICONMASK); + return MessageBox(hParent, szMessage, szResource, uFlags); +} + +static void AlertFileNotFound(LPCWSTR szFileName) +{ + PAINT_StringMsgBox(NULL, STRING_NOTFOUND, szFileName, + MB_ICONEXCLAMATION | MB_OK); +} + +static int AlertFileNotSaved(LPCWSTR szFileName) +{ + WCHAR szUntitled[MAX_STRING_LEN]; + + LoadString(Globals.hInstance, STRING_UNTITLED, szUntitled, MAX_STRING_LEN); + return PAINT_StringMsgBox(NULL, STRING_SAVECHANGE, + szFileName[0] ? szFileName : szUntitled, + MB_ICONWARNING | MB_YESNOCANCEL); +} + +BOOL FileExists(LPCWSTR szFileName) +{ + WIN32_FIND_DATA entry; + HANDLE hFile; + + hFile = FindFirstFile(szFileName, &entry); + FindClose(hFile); + + return (hFile != INVALID_HANDLE_VALUE); +} + +static VOID DoSaveFile(VOID) +{ +} + +/** + * Returns: + * TRUE - User agreed to close (both save/don't save) + * FALSE - User cancelled close by selecting "Cancel" + */ +BOOL DoCloseFile(void) +{ + int nResult; + static const WCHAR empty_strW[] = { 0 }; + + if (Globals.fModified) + { + nResult = AlertFileNotSaved(Globals.szFileName); + switch (nResult) + { + case IDYES: + if (!PAINT_FileSave()) + return FALSE; + break; + + case IDNO: + break; + + case IDCANCEL: + return FALSE; + + default: + return FALSE; + } + } + + SetFileName(empty_strW); + UpdateWindowCaption(); + return TRUE; +} + +void DoOpenFile(LPCWSTR pszFileName) +{ +} + +VOID PAINT_FileNew(VOID) +{ + HDC hDC, hdcMem; + HGDIOBJ hbmOld; + RECT rc; + SIZE sizZoom; + + if (DoCloseFile()) + { + hDC = GetDC(Globals.hCanvasWnd); + hdcMem = CreateCompatibleDC(hDC); + if (hdcMem != NULL) + { + if (Globals.hbmImage != NULL) + DeleteObject(Globals.hbmImage); + Globals.hbmImage = BM_Create(Globals.sizImage); + + hbmOld = SelectObject(hdcMem, Globals.hbmImage); + rc.left = rc.top = 0; + rc.right = Globals.sizImage.cx; + rc.bottom = Globals.sizImage.cy; + FillRect(hdcMem, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); + SelectObject(hdcMem, hbmOld); + + if (Globals.hbmBuffer != NULL) + DeleteObject(Globals.hbmBuffer); + Globals.hbmBuffer = BM_Copy(Globals.hbmImage); + + if (Globals.hbmZoomBuffer != NULL) + DeleteObject(Globals.hbmZoomBuffer); + sizZoom.cx = Globals.sizImage.cx * Globals.nZoom; + sizZoom.cy = Globals.sizImage.cy * Globals.nZoom; + Globals.hbmZoomBuffer = BM_Create(sizZoom); + DeleteDC(hdcMem); + } + ReleaseDC(Globals.hCanvasWnd, hDC); + } + + Globals.xScrollPos = Globals.yScrollPos = 0; + PostMessage(Globals.hCanvasWnd, WM_SIZE, 0, 0); +} + +VOID PAINT_FileOpen(VOID) +{ + NotSupportedYet(); +} + +BOOL PAINT_FileSave(VOID) +{ + NotSupportedYet(); + return TRUE; +} + +BOOL PAINT_FileSaveAs(VOID) +{ + NotSupportedYet(); + return FALSE; +} + +VOID PAINT_FilePrintPreview(VOID) +{ +} + +VOID PAINT_FilePrint(VOID) +{ +} + +VOID PAINT_FilePageSetup(VOID) +{ +} + +VOID PAINT_SetAsWallpaperTiled(VOID) +{ +} + +VOID PAINT_SetAsWallpaperCentered(VOID) +{ +} + +VOID PAINT_FileExit(VOID) +{ + PostMessage(Globals.hMainWnd, WM_CLOSE, 0, 0); +} + +VOID PAINT_EditUndo(VOID) +{ + HBITMAP hbm; + SIZE siz; + + if (Globals.fCanUndo) + { + hbm = Globals.hbmImage; + Globals.hbmImage = Globals.hbmImageUndo; + Globals.hbmImageUndo = hbm; + Globals.fCanUndo = FALSE; + siz = Globals.sizImage; + Globals.sizImage = Globals.sizImageUndo; + Globals.sizImageUndo = siz; + Globals.fSelect = FALSE; + if (Globals.hbmSelect != NULL) + { + DeleteObject(Globals.hbmSelect); + Globals.hbmSelect = NULL; + } + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); + Globals.fCanUndo = FALSE; + } +} + +VOID PAINT_EditRepeat(VOID) +{ + HBITMAP hbm; + SIZE siz; + + if (!Globals.fCanUndo && Globals.hbmImageUndo != NULL) + { + hbm = Globals.hbmImage; + Globals.hbmImage = Globals.hbmImageUndo; + Globals.hbmImageUndo = hbm; + Globals.fCanUndo = FALSE; + siz = Globals.sizImage; + Globals.sizImage = Globals.sizImageUndo; + Globals.sizImageUndo = siz; + Globals.fSelect = FALSE; + if (Globals.hbmSelect != NULL) + { + DeleteObject(Globals.hbmSelect); + Globals.hbmSelect = NULL; + } + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); + Globals.fCanUndo = TRUE; + } +} + +VOID PAINT_EditCut(VOID) +{ + NotSupportedYet(); +} + +VOID PAINT_EditCopy(VOID) +{ + NotSupportedYet(); +} + +VOID PAINT_EditPaste(VOID) +{ + NotSupportedYet(); +} + +VOID PAINT_EditDelete(VOID) +{ + PAINT_ClearSelection(); +} + +VOID PAINT_ClearSelection(VOID) +{ +} + +VOID PAINT_CopyTo(VOID) +{ + NotSupportedYet(); +} + +VOID PAINT_PasteFrom(VOID) +{ + NotSupportedYet(); +} + +VOID PAINT_EditSelectAll(VOID) +{ + NotSupportedYet(); +} + +VOID PAINT_HelpContents(VOID) +{ + WinHelp(Globals.hMainWnd, helpfileW, HELP_INDEX, 0); +} + +VOID PAINT_HelpHelp(VOID) +{ + WinHelp(Globals.hMainWnd, helpfileW, HELP_HELPONHELP, 0); +} + +VOID PAINT_HelpAboutPaint(VOID) +{ + static const WCHAR paintW[] = { 'P','a','i','n','t',0 }; + WCHAR szPaint[MAX_STRING_LEN]; + HICON icon = LoadImageW(Globals.hInstance, MAKEINTRESOURCE(IDI_PAINT), + IMAGE_ICON, 48, 48, LR_SHARED); + + LoadString(Globals.hInstance, STRING_PAINT, szPaint, SIZEOF(szPaint)); + ShellAbout(Globals.hMainWnd, szPaint, paintW, icon); +} + + +VOID PAINT_ToolBox(VOID) +{ + if (IsWindowVisible(Globals.hToolBox)) + ShowWindow(Globals.hToolBox, SW_HIDE); + else + ShowWindow(Globals.hToolBox, SW_SHOWNORMAL); + + PostMessage(Globals.hMainWnd, WM_SIZE, 0, 0); +} + +VOID PAINT_ColorBox(VOID) +{ + if (IsWindowVisible(Globals.hColorBox)) + ShowWindow(Globals.hColorBox, SW_HIDE); + else + ShowWindow(Globals.hColorBox, SW_SHOWNORMAL); + + PostMessage(Globals.hMainWnd, WM_SIZE, 0, 0); +} + +VOID PAINT_StatusBar(VOID) +{ + if (IsWindowVisible(Globals.hStatusBar)) + ShowWindow(Globals.hStatusBar, SW_HIDE); + else + ShowWindow(Globals.hStatusBar, SW_SHOWNORMAL); + + PostMessage(Globals.hMainWnd, WM_SIZE, 0, 0); +} + +VOID PAINT_Zoom(INT nZoom) +{ + SIZE siz; + Globals.nZoom = nZoom; + Globals.xScrollPos = Globals.yScrollPos = 0; + PostMessage(Globals.hCanvasWnd, WM_SIZE, 0, 0); + + if (Globals.hbmZoomBuffer != NULL) + DeleteObject(Globals.hbmZoomBuffer); + siz.cx = Globals.nZoom * Globals.sizImage.cx; + siz.cy = Globals.nZoom * Globals.sizImage.cy; + Globals.hbmZoomBuffer = BM_Create(siz); + + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); +} + +VOID PAINT_Zoom2(INT x, INT y, INT nZoom) +{ + SIZE siz; + Globals.nZoom = nZoom; + Globals.xScrollPos = x * nZoom; + Globals.yScrollPos = y * nZoom; + PostMessage(Globals.hCanvasWnd, WM_SIZE, 0, 0); + + if (Globals.hbmZoomBuffer != NULL) + DeleteObject(Globals.hbmZoomBuffer); + siz.cx = Globals.nZoom * Globals.sizImage.cx; + siz.cy = Globals.nZoom * Globals.sizImage.cy; + Globals.hbmZoomBuffer = BM_Create(siz); + + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); +} + +VOID PAINT_ShowGrid(VOID) +{ + Globals.fShowGrid = !Globals.fShowGrid; + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); +} + +VOID PAINT_InvertColors(VOID) +{ + HDC hDC, hdcMem; + HGDIOBJ hbmOld; + RECT rc; + hDC = GetDC(Globals.hCanvasWnd); + hdcMem = CreateCompatibleDC(hDC); + if (hdcMem != NULL) + { + hbmOld = SelectObject(hdcMem, Globals.hbmImage); + rc.left = rc.top = 0; + rc.right = Globals.sizImage.cx; + rc.bottom = Globals.sizImage.cy; + InvertRect(hdcMem, &rc); + SelectObject(hdcMem, hbmOld); + DeleteDC(hdcMem); + } + ReleaseDC(Globals.hCanvasWnd, hDC); + Globals.fModified = TRUE; + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); +} + +VOID PAINT_ClearImage(VOID) +{ + HDC hDC, hdcMem; + RECT rc; + hDC = GetDC(Globals.hCanvasWnd); + hdcMem = CreateCompatibleDC(hDC); + if (hdcMem != NULL) + { + HBRUSH hbr; + HGDIOBJ hbmOld = SelectObject(hdcMem, Globals.hbmImage); + rc.left = rc.top = 0; + rc.right = Globals.sizImage.cx; + rc.bottom = Globals.sizImage.cy; + hbr = CreateSolidBrush(Globals.rgbBack); + FillRect(hdcMem, &rc, hbr); + DeleteObject(hbr); + SelectObject(hdcMem, hbmOld); + DeleteDC(hdcMem); + } + ReleaseDC(Globals.hCanvasWnd, hDC); + Globals.fModified = TRUE; + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); +} + +BOOL CALLBACK ZoomDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + WCHAR sz[32]; + SIZE siz; + static const WCHAR format[] = {'%','d','0','0','%','%',0}; + + switch (uMsg) + { + case WM_INITDIALOG: + switch (Globals.nZoom) + { + case 1: CheckDlgButton(hDlg, rad1, 1); break; + case 2: CheckDlgButton(hDlg, rad2, 1); break; + case 4: CheckDlgButton(hDlg, rad3, 1); break; + case 6: CheckDlgButton(hDlg, rad4, 1); break; + case 8: CheckDlgButton(hDlg, rad5, 1); break; + } + wsprintf(sz, format, Globals.nZoom); + SetDlgItemText(hDlg, stc2, sz); + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + if (IsDlgButtonChecked(hDlg, rad1) & 1) Globals.nZoom = 1; + else if (IsDlgButtonChecked(hDlg, rad2) & 1) Globals.nZoom = 2; + else if (IsDlgButtonChecked(hDlg, rad3) & 1) Globals.nZoom = 4; + else if (IsDlgButtonChecked(hDlg, rad4) & 1) Globals.nZoom = 6; + else if (IsDlgButtonChecked(hDlg, rad5) & 1) Globals.nZoom = 8; + + siz.cx = Globals.nZoom * Globals.sizImage.cx; + siz.cy = Globals.nZoom * Globals.sizImage.cy; + if (Globals.hbmZoomBuffer != NULL) + DeleteObject(Globals.hbmZoomBuffer); + Globals.hbmZoomBuffer = BM_Create(siz); + EndDialog(hDlg, IDOK); + break; + + case IDCANCEL: + EndDialog(hDlg, IDCANCEL); + break; + } + } + return FALSE; +} + +VOID PAINT_ZoomCustom(VOID) +{ + if (DialogBox(Globals.hInstance, MAKEINTRESOURCE(IDD_ZOOM), + Globals.hMainWnd, ZoomDlgProc) == IDOK) + { + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); + } +} + +VOID PAINT_StretchSkew(VOID) +{ + NotSupportedYet(); +} + +VOID PAINT_Attributes(VOID) +{ + NotSupportedYet(); +} + +VOID PAINT_FlipRotate(VOID) +{ + NotSupportedYet(); +} + +VOID PAINT_EditColor(BOOL fBack) +{ + CHOOSECOLOR cc; + + ZeroMemory(&cc, sizeof(CHOOSECOLOR)); + cc.lStructSize = sizeof(CHOOSECOLOR); + cc.hwndOwner = Globals.hMainWnd; + if (fBack) + cc.rgbResult = Globals.rgbBack; + else + cc.rgbResult = Globals.rgbFore; + cc.lpCustColors = aCustColors; + cc.Flags = CC_RGBINIT; + + if (ChooseColor(&cc)) + { + if (fBack) + { + Globals.argbColors[Globals.iBackColor] = cc.rgbResult; + Globals.rgbBack = cc.rgbResult; + } + else + { + Globals.argbColors[Globals.iForeColor] = cc.rgbResult; + Globals.rgbFore = cc.rgbResult; + } + } + InvalidateRect(Globals.hColorBox, NULL, TRUE); + UpdateWindow(Globals.hColorBox); +} diff --git a/programs/paint/paint.h b/programs/paint/paint.h new file mode 100644 index 0000000..0f988a6 --- /dev/null +++ b/programs/paint/paint.h @@ -0,0 +1,71 @@ +/* + * Paint (paint.h) + * + * Copyright 2008 Katayama Hirofumi MZ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +VOID PAINT_FileNew(VOID); +VOID PAINT_FileOpen(VOID); +BOOL PAINT_FileSave(VOID); +BOOL PAINT_FileSaveAs(VOID); +VOID PAINT_FilePrintPreview(VOID); +VOID PAINT_FilePrint(VOID); +VOID PAINT_FilePageSetup(VOID); +VOID PAINT_FilePrinterSetup(VOID); +VOID PAINT_SetAsWallpaperTiled(VOID); +VOID PAINT_SetAsWallpaperCentered(VOID); +VOID PAINT_FileExit(VOID); + +VOID PAINT_EditUndo(VOID); +VOID PAINT_EditRepeat(VOID); +VOID PAINT_EditCut(VOID); +VOID PAINT_EditCopy(VOID); +VOID PAINT_EditPaste(VOID); +VOID PAINT_EditDelete(VOID); +VOID PAINT_EditSelectAll(VOID); +VOID PAINT_CopyTo(VOID); +VOID PAINT_PasteFrom(VOID); + +VOID PAINT_ClearSelection(VOID); + +VOID PAINT_HelpContents(VOID); +VOID PAINT_HelpHelp(VOID); +VOID PAINT_HelpAboutPaint(VOID); + +VOID PAINT_ToolBox(VOID); +VOID PAINT_ColorBox(VOID); +VOID PAINT_StatusBar(VOID); +VOID PAINT_Zoom(INT nZoom); +VOID PAINT_Zoom2(INT x, INT y, INT nZoom); +VOID PAINT_ShowGrid(VOID); +VOID PAINT_ZoomCustom(VOID); + +VOID PAINT_FlipRotate(VOID); +VOID PAINT_StretchSkew(VOID); +VOID PAINT_InvertColors(VOID); +VOID PAINT_Attributes(VOID); +VOID PAINT_ClearImage(VOID); + +VOID PAINT_EditColor(BOOL fBack); + +int PAINT_StringMsgBox(HWND hParent, int formatId, LPCWSTR szString, UINT uFlags); + +/* utility functions */ +VOID ShowLastError(void); +BOOL FileExists(LPCWSTR szFilename); +BOOL DoCloseFile(void); +void DoOpenFile(LPCWSTR szFileName); diff --git a/programs/paint/paint.ico b/programs/paint/paint.ico new file mode 100644 index 0000000000000000000000000000000000000000..545d4b3d55ecb7c99e67081a163d49d8388d7663 GIT binary patch literal 15086 zcmeI3dsJ0b9>@2&=Uy%k5i%@O7|pb#dgyPZmMHtUX;y%2c`Qu46KA;Nwg)*#69RorLR& z;7ZWZ7SGH6Z@&41Y}xVy^Uv{lX20!Yzp-COMs}>o$+?&L_W;BG%yxab?YhyW!{PX6 zQBjeM7%_rn3~%(X?&d-SGn$BRh;sDvNZ6d0nEzpLZo>nmdMh;^@wt4q!4~g(xzwFk zEY8FfrnA{_Zmm*xBW^yJ$Y+h}-(HAo@=^((vyEx41@-kX8uzon60nNTuCwQ{UmM{a zzYU+O^KU{tTBI_D3>hMZk%)Ycg0;+_Z_nd%9UGdrNz87&yoevJ94bK|wY9a#HwkQJ z{$(J{Ctt&@qenjpyJI=iF@H4kTk_INs9!_nwv->wZU~>hgZamU$m7S4TiNCG>C=oK z2wD{9WvNWJ3-sxEQBN6l{U{kUc#w4I+J*6K!)KCVNbo3Nm#3Tu*e2MuBS4!)V2QUo zz*nv%D6xj%y5<_Cs`rC(r7EicdT=?ZRB9>WnU~{C0=OD*e9}Ve&PsDNa1$Q<2L1(R z0*+~c$|cCaHq;U=l_>)Td?DSt7fE#VIF`YFb}2Ah%H;E`0{6}7ABAUs1pPr%vNbL3 zWx4IPqjLTAN5td#$SP+p5(m{k{oy^kzhSS7P(|3{`xJ0_DRRf=i4 zSxy?@nB}h+NcaMv?UvpFxORY+>ZkKiIzLTe)J}xU(d@W-e+BYP0Q}~Gh=Dm%zWVBv9654QKKS4# z>VF#qs(&f+Oag)GM;5jG=9_O8r_)K@7Hk7&`hLu73BOqmNUj0jdUs8xv_kt_@O5He7!RXPWW%cUSlAoV1$;rvoPydJd{TZ90knSir z3_PGUvQLFaiZgYRgw1|Q3|A;^7zxhQ4$#kBNK2o9z74Nc-_{s_JmSiIR_J%s`##^- z>u;$~L0<;Q0r!EqK(`@|34zM<=J*BTp0z>3=WQ3m9nP}&{>|0FS`1Z4lMU_xdEkDK z1yl(zK_Frn9Xm6LTnWkr~xbrsR8|)CX z%Y`f_70?EIecl0&2hXO0nP35U0MOrj65I+@HfYUwgf_4a-(ahR=RCu5b^z*!|KA|! zpPaWx0KWS|@G#)oX*DPW3hg7{`G5*ucV#crYmkTqe_=U<`iUi{$Bi2&yLRounvZ>s z-+l$)y5Mz=t@ z_d|EuG?tYQ`2KZkCLjHueDVp>u)lI$vk4Rf^*Nya=GMb_)U3oh;(Fm5lt_pCS6NmC zpnebF%w&7}y30d{4lx}t0ltZ$%5hKq=YiHp^Zl?1{dR*6et1w|;~FTX{y_VnW$Os% zfRVZ%I%597cjNmL2mTJ&_4!^GEW}t~sC1;Iem7{X=zbV_3){C^4yeBe^iSKfXOFMi zhWpTPJ%3R*X^Y(B8lH)k`W7$(ct9`E378;Q z!m_RhQ@}JZ1Iz;)gC7K(w^o8@KoQsiCIWwCC=y|9d;#`uJJjO(EARm*1NVSnNihnt z#&~~1)~CPnPHgObdcUhzueT*Oc7?U)MLnf}!$NC(G`oH$ZYqF3w!e;a+$Z4LfOD4b zIR>H{$rzWbBlgKYmXRZm%JAWpGIZ!M>C@*GZ&;XKpZpuCr-LLA$eu+bCAi@`tOxwY zzVAVQg8s*I;4)y@&a)KeYe5XY-@)YMbh-E5YRSl`ko5GUa_g;?lA8LiHz9#*NcAgN z0JvY+0klO}4{V#ofagpvgS!Fy2+wY4JLhoj(M14%1nWH|+1am3LBZF0&v5$mV>qw+ zQtun~@1M_i_zk3it3ViNi(q}L$BUm3&IPO&wiQDAdxAi}^; zS~hR~Ue>SwPM&?1d#6VwF78s={}dPkSVwIY)-m^h#sYp%+TT_gZ%S~9F;O0S>@mG>Us_r!AAb0u zR99ESPcrByaUA707!25UTO;QqQx#xca6VvJ!IFZQm>A4sv-Q6JYGmOljrkmj(Flmh$LO318Y?DuVx(45uucd2g) z7z+3f^gmh>)CKqbZbIHHggJm`6FeW_xe(7LE(7WiNNlN~0H39+sLtZdUg~wvT8};3 z7bRlRn__mqoVwlxw4I!3FYXAoHjyU__VZlDYCAk%;Q0p6cCfEn*Qe=EcLl)^_T`i2 zEz|YcQ)u31w4oi=`4i`#OhEfNel#~0(XWSX^g*n4W7R$PZfQ4vx5Trlen5{+Y?J=> zDR+`fBun4HAmqpK;IEHFP3%m4jh`_H%q`N=oa- z$-9u=>a(+O&AR8=lvVdUpW-{QpXl$&^5|Q%Rn9{JAM@-kWX?w22Y7xL%HMyPPU@mR z$9K36n7}SPWB&-lEYi_-o~2rSmglKF*Lwu;cWXS`V?XW;^c=}`Jl8bAkX0(I1Ny)^ zuRHGrJr0H6_k!1miK8yIA&x_|KNi^KV%)$_;21v{@Ethbu+J_64}xXj&)_M*cZdi2 zcV+Z-yW0zE!*x9JiaBzM*F9$w+E9r^-2bXLdkvwkPXX(S{lIq}#r4{$y7OGj<9e>; z*kx}wJkzD!Jm2FPTM|&)0QYYCf?&z(MqILl%)t38`#}CKao?CnU1T)42Jjv1It(J>bNSL@LEW#N!=HhuT zOL$%hbQ#q52=D;f9|tVCYt#*+tZi}~zW@IFSXYD~58D*m%__jUF9Ix2ua&qD$h8#b z_zm+vl?R>EqKI?Du;0vJUGz);ZsSW6yJd zbzcm&18x83D95rtP#+Olo0S_B>W=5fp>wuKM8RuPe}?=8a*D0elaiK}3R~%WvK{eUn{9{o_XYZVnf7yC-`4$06wx3YOFwmb#%X_)<7jy9X6l1q zsrQ&^|JA^%vxOO%8J5|N!V@P>;J46e;&8Z--ve^NJP^zC+4oTf+du8+7#vJl#(tpZ zV)%0r3tkmR-MXLbxPiN;|=WnWlFz(7fWK|g%Z(0 zuLm&a>9Hr+^-r7VYl?GNhJ@m`K>RI?>xvsuZw zgRJv;j-Ryu92OL0dCoX5K|*J2@P?rcxyR(w{x1RNVSWP-pj;dGhd6DnRp-sw&iJaT zDsS?|$!tHl$jkYQkZ_EnX3s0A`)`1Ht#K5Ws?jzfdlg1d+%Xyc)yhHE|phy zy&@%BOJw5<8)eO!HL~)_l@bvdQH%7`0qv*n&=s_&u$@TAxCh`*(~s1?&>aXZUnm-F zs3Z9O??9T0GxYD?*>`9^+kYfzZ~3bup$~r7xgBd;ZU0<^^rzW|>ik~^`msZ=Z$=<) z4B$Qx*9{)PdS+YXn9Dhrb~BECh!eE8#L=fPdvgxe_Af%nafkLZvjH(ag>q7YLjQ9G4 uC{)KYEL+U~8S_YCJQoRzg?3caV%Sy9Uw9#`h)3u_=z)a@e_y|hQR;tmespyJ literal 0 HcmV?d00001 diff --git a/programs/paint/paint.svg b/programs/paint/paint.svg new file mode 100644 index 0000000..faadc49 --- /dev/null +++ b/programs/paint/paint.svg @@ -0,0 +1,305 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/programs/paint/pencil.cur b/programs/paint/pencil.cur new file mode 100644 index 0000000000000000000000000000000000000000..a5f2c18d9e26c3bf44205c9c1ed1714b6ff7b8b8 GIT binary patch literal 326 zcmaLRy$!-J5QgE`35Z{b4$ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define MAIN_MENU 0x201 +#define TEXT_MENU 0x202 +#define SELECTION_MENU 0x203 +#define ID_ACCEL 0x204 +#define IDB_TOOLS 0x205 +#define IDD_ZOOM 0x207 +#define IDD_STRETCH_SKEW 0x208 +#define IDD_ATTRIBUTES 0x209 +#define IDD_FLIP_ROTATE 0x20A +#define IDI_PAINT 0x1 + +/* Commands */ +#define CMD_NEW 0x100 +#define CMD_OPEN 0x101 +#define CMD_SAVE 0x102 +#define CMD_SAVE_AS 0x103 +#define CMD_PRINT_PREVIEW 0x104 +#define CMD_PRINT 0x105 +#define CMD_PAGE_SETUP 0x106 +#define CMD_EXIT 0x107 +#define CMD_WALLPAPAER_TILED 0x108 +#define CMD_WALLPAPAER_CENTERED 0x109 +#define CMD_UNDO 0x10A +#define CMD_CUT 0x10B +#define CMD_COPY 0x10C +#define CMD_PASTE 0x10D +#define CMD_DELETE 0x10E +#define CMD_SELECT_ALL 0x10F +#define CMD_REPEAT 0x110 +#define CMD_COPY_TO 0x111 +#define CMD_PASTE_FROM 0x112 +#define CMD_TOOL_BOX 0x113 +#define CMD_COLOR_BOX 0x114 +#define CMD_STATUS_BAR 0x115 +#define CMD_TEXT_TOOL 0x116 +#define CMD_ZOOM_NORMAL 0x117 +#define CMD_ZOOM_LARGE 0x118 +#define CMD_ZOOM_CUSTOM 0x119 +#define CMD_SHOW_GRID 0x11A +#define CMD_VIEW_BITMAP 0x11B +#define CMD_SHOW_THUMBNAIL 0x11C +#define CMD_FLIP_ROTATE 0x11D +#define CMD_STRETCH_SKEW 0x11E +#define CMD_INVERT_COLORS 0x12F +#define CMD_ATTRIBUTES 0x120 +#define CMD_CLEAR_IMAGE 0x121 +#define CMD_DRAW_OPAQUE 0x122 +#define CMD_CLEAR_SELECTION 0x123 +#define CMD_EDIT_COLOR 0x124 +#define CMD_GET_COLORS 0x125 +#define CMD_SAVE_COLORS 0x126 +#define CMD_HELP_CONTENTS 0x127 +#define CMD_HELP_ON_HELP 0x128 +#define CMD_HELP_ABOUT_PAINT 0x129 + +#define IDC_STATIC -1 + +#define STRING_PAINT 0x170 +#define STRING_UNTITLED 0x174 +#define STRING_ALL_FILES 0x175 +#define STRING_BMP_FILES_BMP 0x176 +#define STRING_DOESNOTEXIST 0x179 +#define STRING_SAVECHANGE 0x17A +#define STRING_NOTFOUND 0x17B + +#define STRING_POLYSELECT 0x200 +#define STRING_BOXSELECT 0x201 +#define STRING_ERASER 0x202 +#define STRING_FLOODFILL 0x203 +#define STRING_SPOIT 0x204 +#define STRING_MAGNIFIER 0x205 +#define STRING_PENCIL 0x206 +#define STRING_BRUSH 0x207 +#define STRING_AIRBRUSH 0x208 +#define STRING_TEXT 0x209 +#define STRING_LINE 0x20A +#define STRING_CURVE 0x20B +#define STRING_BOX 0x20C +#define STRING_POLYGON 0x20D +#define STRING_ELLIPSE 0x20E +#define STRING_ROUNDRECT 0x20F +#define STRING_READY 0x210 +#define STRING_POSITIVE_INT 0x211 +#define STRING_INVALID_BM 0x212 +#define STRING_LOSS_COLOR 0x213 +#define STRING_MONOCROME_BM 0x215 +#define STRING_16COLOR_BM 0x216 +#define STRING_256COLOR_BM 0x217 +#define STRING_24BIT_BM 0x218 +#define STRING_JPEG_FILES 0x219 +#define STRING_GIF_FILES 0x21A +#define STRING_TIFF_FILES 0x21B +#define STRING_PNG_FILES 0x21C +#define STRING_ICON_FILES 0x21D +#define STRING_PCX_FILES 0x21E +#define STRING_ALL_PICTURE 0x21F +#define STRING_PALETTE 0x220 +#define STRING_NEW 0x300 +#define STRING_OPEN 0x301 +#define STRING_SAVE 0x302 +#define STRING_SAVE_AS 0x303 +#define STRING_PRINT_PREVIEW 0x304 +#define STRING_PAGE_SETUP 0x305 +#define STRING_PRINT 0x306 +#define STRING_EXIT 0x307 +#define STRING_WALLPAPAER_TILED 0x308 +#define STRING_WALLPAPAER_CENTERED 0x309 +#define STRING_UNDO 0x30A +#define STRING_CUT 0x30B +#define STRING_COPY 0x30C +#define STRING_PASTE 0x30D +#define STRING_DELETE 0x30E +#define STRING_SELECT_ALL 0x30F +#define STRING_REPEAT 0x310 +#define STRING_COPY_TO 0x311 +#define STRING_PASTE_FROM 0x312 +#define STRING_TOOL_BOX 0x313 +#define STRING_COLOR_BOX 0x314 +#define STRING_STATUS_BAR 0x315 +#define STRING_TEXT_TOOL 0x316 +#define STRING_ZOOM_NORMAL 0x317 +#define STRING_ZOOM_LARGE 0x318 +#define STRING_ZOOM_CUSTOM 0x319 +#define STRING_SHOW_GRID 0x31A +#define STRING_VIEW_BITMAP 0x31B +#define STRING_SHOW_THUMBNAIL 0x31C +#define STRING_FLIP_ROTATE 0x31D +#define STRING_STRETCH_SKEW 0x31E +#define STRING_INVERT_COLORS 0x32F +#define STRING_ATTRIBUTES 0x320 +#define STRING_CLEAR_IMAGE 0x321 +#define STRING_DRAW_OPAQUE 0x322 +#define STRING_CLEAR_SELECTION 0x323 +#define STRING_EDIT_COLOR 0x324 +#define STRING_GET_COLORS 0x325 +#define STRING_SAVE_COLORS 0x326 +#define STRING_HELP_CONTENTS 0x327 +#define STRING_HELP_ON_HELP 0x328 +#define STRING_HELP_ABOUT_PAINT 0x329 +#define STRING_SIZE 0x400 +#define STRING_MOVE 0x401 +#define STRING_MINIMIZE 0x402 +#define STRING_MAXIMIZE 0x403 +#define STRING_NEXTWINDOW 0x404 +#define STRING_PREVWINDOW 0x405 +#define STRING_CLOSE 0x406 +#define STRING_RESTORE 0x407 +#define STRING_TASKLIST 0x408 diff --git a/programs/paint/rsrc.rc b/programs/paint/rsrc.rc new file mode 100644 index 0000000..290133f --- /dev/null +++ b/programs/paint/rsrc.rc @@ -0,0 +1,78 @@ +/* + * Copyright 2008 Katayama Hirofumi MZ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "main.h" +#include "winnls.h" +#include "commctrl.h" +#include "dlgs.h" +#include "resource.h" + +ID_ACCEL ACCELERATORS +{ + "^N", CMD_CLEAR_IMAGE, ASCII, SHIFT + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^N", CMD_NEW + "^O", CMD_OPEN + "^P", CMD_PRINT + "^S", CMD_SAVE + "^X", CMD_CUT + "^C", CMD_COPY + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + "^Y", CMD_REPEAT + "^T", CMD_TOOL_BOX + "^L", CMD_COLOR_BOX + "^F", CMD_VIEW_BITMAP + "^G", CMD_SHOW_GRID + "^I", CMD_INVERT_COLORS + "^W", CMD_STRETCH_SKEW + "^R", CMD_FLIP_ROTATE + "^E", CMD_ATTRIBUTES + VK_DELETE, CMD_DELETE, VIRTKEY + VK_BACK, CMD_UNDO, VIRTKEY, ALT + VK_INSERT, CMD_COPY, VIRTKEY, CONTROL + VK_INSERT, CMD_PASTE, VIRTKEY, SHIFT + VK_PRIOR, CMD_ZOOM_NORMAL, VIRTKEY, CONTROL + VK_NEXT, CMD_ZOOM_LARGE, VIRTKEY, CONTROL +} + +/* @makedep: paint.ico */ +IDI_PAINT ICON "paint.ico" + +/* @makedep: tools.bmp */ +IDB_TOOLS BITMAP "tools.bmp" + +/* @makedep: horizon.cur */ +1 CURSOR "horizon.cur" +/* @makedep: vertical.cur */ +2 CURSOR "vertical.cur" +/* @makedep: bdiagon.cur */ +3 CURSOR "bdiagon.cur" +/* @makedep: fdiagon.cur */ +4 CURSOR "fdiagon.cur" +/* @makedep: pencil.cur */ +5 CURSOR "pencil.cur" +/* @makedep: cross2.cur */ +12 CURSOR "cross2.cur" + +#include "En.rc" diff --git a/programs/paint/tools.bmp b/programs/paint/tools.bmp new file mode 100644 index 0000000000000000000000000000000000000000..36bae5c8ff9cffc656b2e81d277799238f2a11b7 GIT binary patch literal 1692 zcmZ`(y=ogl5FV|Ez1z!i=ZIi}%M`(w6b5%8RS?K3l4nqLknRc*rLzh{N^c-A&-`7S2 zAK7fu4OcwMcDt3;YK4U^ex&R8gfHIw3l|N>eGKNtHgAHN;Old_3c~;81J=qQwh=4Z z9O7xcn8h7cFtuKr9d^n^j8=CNM7`7DTHM%q^G&#GI*Gev*oEA)(;*If-iAuvAq!$l zCmtVl##_nvF?Mc|r~cz&zV%`v_^kqVi3c*StDvNfeZaxGkpg)|T~;hjYl9WzY$*6o zWGvPN$2e+4lrBYEL`WqrcxfDxiS^xFN@k8KES@4}XLeLEFf>Uwkm&()7QtjCGA4Ao zX_u0>$XpNy45WnA0LP%oB=j??1UjUNK4}I@A!2)W9o9Mc;0|<+s`KZ_ zM6xZUqHhcC+q7HTE1ly+Xg&x{>ns9HzHw4ID6YRH1}^7qT1*BG<>3 zxE{E4=Xg2;-1aWPMirjDi26hvbXF!&{R>=FnoeQe3se^eXMn{411i0%sXd`Wg{@ji|BqIX~b7E$ZI->CJ!sElW4vERXx`;%&*XI2~0c~XZiciBBU)wIM<_3rU2 zXs+dM%dW5vUMHWSh-awBhbp*@{C)2YJqOPUpacI1YfwHGIM8;xE_IY>c0Zu{Th@3$ zh3a}&{*I`uFsdM9=6He0PUue&hQK&(b8}h+0pAEFDAu|Gm?GA d^D&OsW6TlbID5(ZE2apz?e%^_#tTlW(O=xwQ8@qr literal 0 HcmV?d00001 diff --git a/programs/paint/vertical.cur b/programs/paint/vertical.cur new file mode 100644 index 0000000000000000000000000000000000000000..9dad0950a01c08e7ab126c15ee984e4f25c11987 GIT binary patch literal 326 zcmaKmu?~YU5JO)O0~<^o+l(Fi2j$P`r}h&V87j=Vp#oI`pM1&LJ|$3*$QjzGM}iA* z4~9e^Oi^E~M;W#*X&a7i-mP9x_t0eMI=GHSv%aTw`_4IU@8E4##2?Nvhy59(=_!pj S>D?Au`{&Pd&UyRZKfwa#R)01C literal 0 HcmV?d00001 diff --git a/programs/paint/vibeam.cur b/programs/paint/vibeam.cur new file mode 100644 index 0000000000000000000000000000000000000000..534cf3bb79e21301806c30f4c7443f46864f9801 GIT binary patch literal 326 zcmZQzU}9ioP*7lC5MbbEFkob05My9q&;Vkf5Q75{GXfzPKq&|ZLH_^$AHgAo)c`aQ RhU@ 1, "notepad" => 1, "progman" => 1, + "paint" => 1, "regedit" => 1, "regsvr32" => 1, "uninstaller" => 1, -- 1.6.0.2