[MSPAINT_NEW] bootstrap mspaint_new from mspaint
[reactos.git] / reactos / base / applications / mspaint_new / main.cpp
1 /*
2 * PROJECT: PAINT for ReactOS
3 * LICENSE: LGPL
4 * FILE: base/applications/mspaint_new/main.cpp
5 * PURPOSE: Initializing everything
6 * PROGRAMMERS: Benedikt Freisen
7 */
8
9 /* INCLUDES *********************************************************/
10
11 #include "precomp.h"
12
13 #include "winproc.h"
14 #include "scrollbox.h"
15 #include "palette.h"
16 #include "toolsettings.h"
17 #include "selection.h"
18 #include "sizebox.h"
19 #include "textedit.h"
20
21 /* FUNCTIONS ********************************************************/
22
23 HDC hDrawingDC;
24 HDC hSelDC;
25 int *bmAddress;
26 BITMAPINFO bitmapinfo;
27 int imgXRes = 400;
28 int imgYRes = 300;
29
30 int widthSetInDlg;
31 int heightSetInDlg;
32
33 STRETCHSKEW stretchSkew;
34
35 HBITMAP hBms[HISTORYSIZE];
36 int currInd = 0;
37 int undoSteps = 0;
38 int redoSteps = 0;
39 BOOL imageSaved = TRUE;
40
41 POINT start;
42 POINT last;
43 int lineWidth = 1;
44 int shapeStyle = 0;
45 int brushStyle = 0;
46 int activeTool = TOOL_PEN;
47 int airBrushWidth = 5;
48 int rubberRadius = 4;
49 int transpBg = 0;
50 int zoom = 1000;
51 RECT rectSel_src;
52 RECT rectSel_dest;
53 HWND hSelection;
54 HWND hImageArea;
55 HBITMAP hSelBm;
56 HBITMAP hSelMask;
57 LOGFONT lfTextFont;
58 HFONT hfontTextFont;
59 HWND hwndTextEdit;
60 HWND hwndEditCtl;
61 LPTSTR textToolText = NULL;
62 int textToolTextMaxLen = 0;
63
64 /* array holding palette colors; may be changed by the user during execution */
65 int palColors[28];
66
67 /* modern palette */
68 int modernPalColors[28] = { 0x000000, 0x464646, 0x787878, 0x300099, 0x241ced, 0x0078ff, 0x0ec2ff,
69 0x00f2ff, 0x1de6a8, 0x4cb122, 0xefb700, 0xf36d4d, 0x99362f, 0x98316f,
70 0xffffff, 0xdcdcdc, 0xb4b4b4, 0x3c5a9c, 0xb1a3ff, 0x7aaae5, 0x9ce4f5,
71 0xbdf9ff, 0xbcf9d3, 0x61bb9d, 0xead999, 0xd19a70, 0x8e6d54, 0xd5a5b5
72 };
73
74 /* older palette containing VGA colors */
75 int oldPalColors[28] = { 0x000000, 0x808080, 0x000080, 0x008080, 0x008000, 0x808000, 0x800000,
76 0x800080, 0x408080, 0x404000, 0xff8000, 0x804000, 0xff0040, 0x004080,
77 0xffffff, 0xc0c0c0, 0x0000ff, 0x00ffff, 0x00ff00, 0xffff00, 0xff0000,
78 0xff00ff, 0x80ffff, 0x80ff00, 0xffff80, 0xff8080, 0x8000ff, 0x4080ff
79 };
80
81 /* palette currently in use (1: modern, 2: old) */
82 int selectedPalette;
83
84 /* foreground and background colors with initial value */
85 int fgColor = 0x00000000;
86 int bgColor = 0x00ffffff;
87
88 HWND hStatusBar;
89 HWND hScrollbox;
90 HWND hMainWnd;
91 HWND hPalWin;
92 HWND hToolBoxContainer;
93 HWND hToolSettings;
94 HWND hTrackbarZoom;
95 CHOOSECOLOR choosecolor;
96 OPENFILENAME ofn;
97 OPENFILENAME sfn;
98 HICON hNontranspIcon;
99 HICON hTranspIcon;
100
101 HCURSOR hCurFill;
102 HCURSOR hCurColor;
103 HCURSOR hCurZoom;
104 HCURSOR hCurPen;
105 HCURSOR hCurAirbrush;
106
107 HWND hScrlClient;
108
109 HWND hToolBtn[16];
110
111 HINSTANCE hProgInstance;
112
113 TCHAR filename[256];
114 TCHAR filepathname[1000];
115 BOOL isAFile = FALSE;
116 int fileSize;
117 int fileHPPM = 2834;
118 int fileVPPM = 2834;
119 SYSTEMTIME fileTime;
120
121 BOOL showGrid = FALSE;
122 BOOL showMiniature = FALSE;
123
124 HWND hwndMiniature;
125
126 HWND hSizeboxLeftTop;
127 HWND hSizeboxCenterTop;
128 HWND hSizeboxRightTop;
129 HWND hSizeboxLeftCenter;
130 HWND hSizeboxRightCenter;
131 HWND hSizeboxLeftBottom;
132 HWND hSizeboxCenterBottom;
133 HWND hSizeboxRightBottom;
134
135 /* entry point */
136
137 int WINAPI
138 _tWinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPTSTR lpszArgument, int nFunsterStil)
139 {
140 HWND hwnd; /* This is the handle for our window */
141 MSG messages; /* Here messages to the application are saved */
142
143 TCHAR progtitle[1000];
144 TCHAR resstr[100];
145 HMENU menu;
146 HWND hToolbar;
147 HIMAGELIST hImageList;
148 HANDLE haccel;
149 HBITMAP tempBm;
150 int i;
151 TCHAR tooltips[16][30];
152 HDC hDC;
153
154 TCHAR *c;
155 TCHAR sfnFilename[1000];
156 TCHAR sfnFiletitle[256];
157 TCHAR sfnFilter[1000];
158 TCHAR ofnFilename[1000];
159 TCHAR ofnFiletitle[256];
160 TCHAR ofnFilter[1000];
161 TCHAR miniaturetitle[100];
162 static int custColors[16] = { 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
163 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff
164 };
165
166 /* init font for text tool */
167 lfTextFont.lfHeight = 0;
168 lfTextFont.lfWidth = 0;
169 lfTextFont.lfEscapement = 0;
170 lfTextFont.lfOrientation = 0;
171 lfTextFont.lfWeight = FW_NORMAL;
172 lfTextFont.lfItalic = FALSE;
173 lfTextFont.lfUnderline = FALSE;
174 lfTextFont.lfStrikeOut = FALSE;
175 lfTextFont.lfCharSet = DEFAULT_CHARSET;
176 lfTextFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
177 lfTextFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
178 lfTextFont.lfQuality = DEFAULT_QUALITY;
179 lfTextFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
180 lstrcpy(lfTextFont.lfFaceName, _T(""));
181 hfontTextFont = CreateFontIndirect(&lfTextFont);
182
183 /* init palette */
184 selectedPalette = 1;
185 CopyMemory(palColors, modernPalColors, sizeof(palColors));
186
187 hProgInstance = hThisInstance;
188
189 /* initialize common controls library */
190 InitCommonControls();
191
192 /* register application defined window classes */
193 RegisterWclMain();
194 RegisterWclScrollbox();
195 RegisterWclPal();
196 RegisterWclSettings();
197 RegisterWclSelection();
198 RegisterWclSizebox();
199 RegisterWclTextEdit();
200
201 LoadString(hThisInstance, IDS_DEFAULTFILENAME, filename, SIZEOF(filename));
202 LoadString(hThisInstance, IDS_WINDOWTITLE, resstr, SIZEOF(resstr));
203 _stprintf(progtitle, resstr, filename);
204 LoadString(hThisInstance, IDS_MINIATURETITLE, miniaturetitle, SIZEOF(miniaturetitle));
205
206 /* create main window */
207 hwnd =
208 CreateWindowEx(0, _T("MainWindow"), progtitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 544,
209 375, HWND_DESKTOP, NULL, hThisInstance, NULL);
210 hMainWnd = hwnd;
211
212 hwndMiniature =
213 CreateWindowEx(WS_EX_PALETTEWINDOW, _T("MainWindow"), miniaturetitle,
214 WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME, 180, 200, 120, 100, hwnd,
215 NULL, hThisInstance, NULL);
216
217 /* loading and setting the window menu from resource */
218 menu = LoadMenu(hThisInstance, MAKEINTRESOURCE(ID_MENU));
219 SetMenu(hwnd, menu);
220 haccel = LoadAccelerators(hThisInstance, MAKEINTRESOURCE(800));
221
222 /* preloading the draw transparent/nontransparent icons for later use */
223 hNontranspIcon =
224 (HICON) LoadImage(hThisInstance, MAKEINTRESOURCE(IDI_NONTRANSPARENT), IMAGE_ICON, 40, 30, LR_DEFAULTCOLOR);
225 hTranspIcon =
226 (HICON) LoadImage(hThisInstance, MAKEINTRESOURCE(IDI_TRANSPARENT), IMAGE_ICON, 40, 30, LR_DEFAULTCOLOR);
227
228 hCurFill = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_FILL));
229 hCurColor = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_COLOR));
230 hCurZoom = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_ZOOM));
231 hCurPen = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_PEN));
232 hCurAirbrush = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_AIRBRUSH));
233
234 CreateWindowEx(0, _T("STATIC"), _T(""), WS_CHILD | WS_VISIBLE | SS_ETCHEDHORZ, 0, 0, 5000, 2, hwnd, NULL,
235 hThisInstance, NULL);
236
237 hToolBoxContainer =
238 CreateWindowEx(0, _T("MainWindow"), _T(""), WS_CHILD | WS_VISIBLE, 2, 2, 52, 350, hwnd, NULL,
239 hThisInstance, NULL);
240 /* creating the 16 bitmap radio buttons and setting the bitmap */
241
242
243 /*
244 * FIXME: Unintentionally there is a line above the tool bar (hidden by y-offset).
245 * To prevent cropping of the buttons height has been increased from 200 to 205
246 */
247 hToolbar =
248 CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
249 WS_CHILD | WS_VISIBLE | CCS_NOPARENTALIGN | CCS_VERT | CCS_NORESIZE | TBSTYLE_TOOLTIPS,
250 1, -2, 50, 205, hToolBoxContainer, NULL, hThisInstance, NULL);
251 hImageList = ImageList_Create(16, 16, ILC_COLOR24 | ILC_MASK, 16, 0);
252 SendMessage(hToolbar, TB_SETIMAGELIST, 0, (LPARAM) hImageList);
253 tempBm = (HBITMAP) LoadImage(hThisInstance, MAKEINTRESOURCE(IDB_TOOLBARICONS), IMAGE_BITMAP, 256, 16, 0);
254 ImageList_AddMasked(hImageList, tempBm, 0xff00ff);
255 DeleteObject(tempBm);
256 SendMessage(hToolbar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
257
258 for(i = 0; i < 16; i++)
259 {
260 TBBUTTON tbbutton;
261 int wrapnow = 0;
262
263 if (i % 2 == 1)
264 wrapnow = TBSTATE_WRAP;
265
266 LoadString(hThisInstance, IDS_TOOLTIP1 + i, tooltips[i], 30);
267 ZeroMemory(&tbbutton, sizeof(TBBUTTON));
268 tbbutton.iString = (INT_PTR) tooltips[i];
269 tbbutton.fsStyle = TBSTYLE_CHECKGROUP;
270 tbbutton.fsState = TBSTATE_ENABLED | wrapnow;
271 tbbutton.idCommand = ID_FREESEL + i;
272 tbbutton.iBitmap = i;
273 SendMessage(hToolbar, TB_ADDBUTTONS, 1, (LPARAM) &tbbutton);
274 }
275
276 SendMessage(hToolbar, TB_CHECKBUTTON, ID_PEN, MAKELONG(TRUE, 0));
277 SendMessage(hToolbar, TB_SETMAXTEXTROWS, 0, 0);
278 SendMessage(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(25, 25));
279
280 /* creating the tool settings child window */
281 hToolSettings =
282 CreateWindowEx(0, _T("ToolSettings"), _T(""), WS_CHILD | WS_VISIBLE, 5, 208, 42, 140,
283 hToolBoxContainer, NULL, hThisInstance, NULL);
284 hTrackbarZoom =
285 CreateWindowEx(0, TRACKBAR_CLASS, _T(""), WS_CHILD | TBS_VERT | TBS_AUTOTICKS, 1, 1, 40, 64,
286 hToolSettings, NULL, hThisInstance, NULL);
287 SendMessage(hTrackbarZoom, TBM_SETRANGE, (WPARAM) TRUE, (LPARAM) MAKELONG(0, 6));
288 SendMessage(hTrackbarZoom, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) 3);
289
290 /* creating the palette child window */
291 hPalWin =
292 CreateWindowEx(0, _T("Palette"), _T(""), WS_CHILD | WS_VISIBLE, 56, 9, 255, 32, hwnd, NULL,
293 hThisInstance, NULL);
294
295 /* creating the scroll box */
296 hScrollbox =
297 CreateWindowEx(WS_EX_CLIENTEDGE, _T("Scrollbox"), _T(""),
298 WS_CHILD | WS_GROUP | WS_HSCROLL | WS_VSCROLL | WS_VISIBLE, 56, 49, 472, 248, hwnd,
299 NULL, hThisInstance, NULL);
300
301 /* creating the status bar */
302 hStatusBar =
303 CreateWindowEx(0, STATUSCLASSNAME, _T(""), SBARS_SIZEGRIP | WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hwnd,
304 NULL, hThisInstance, NULL);
305 SendMessage(hStatusBar, SB_SETMINHEIGHT, 21, 0);
306
307 hScrlClient =
308 CreateWindowEx(0, _T("Scrollbox"), _T(""), WS_CHILD | WS_VISIBLE, 0, 0, 500, 500, hScrollbox, NULL,
309 hThisInstance, NULL);
310
311 /* create selection window (initially hidden) */
312 hSelection =
313 CreateWindowEx(WS_EX_TRANSPARENT, _T("Selection"), _T(""), WS_CHILD | BS_OWNERDRAW, 350, 0, 100, 100,
314 hScrlClient, NULL, hThisInstance, NULL);
315
316 /* creating the window inside the scroll box, on which the image in hDrawingDC's bitmap is drawn */
317 hImageArea =
318 CreateWindowEx(0, _T("MainWindow"), _T(""), WS_CHILD | WS_VISIBLE, 3, 3, imgXRes, imgYRes, hScrlClient,
319 NULL, hThisInstance, NULL);
320
321 hDC = GetDC(hImageArea);
322 hDrawingDC = CreateCompatibleDC(hDC);
323 hSelDC = CreateCompatibleDC(hDC);
324 ReleaseDC(hImageArea, hDC);
325 SelectObject(hDrawingDC, CreatePen(PS_SOLID, 0, fgColor));
326 SelectObject(hDrawingDC, CreateSolidBrush(bgColor));
327
328 hBms[0] = CreateDIBWithProperties(imgXRes, imgYRes);
329 SelectObject(hDrawingDC, hBms[0]);
330 Rectangle(hDrawingDC, 0 - 1, 0 - 1, imgXRes + 1, imgYRes + 1);
331
332 if (lpszArgument[0] != 0)
333 {
334 HBITMAP bmNew = NULL;
335 LoadDIBFromFile(&bmNew, lpszArgument, &fileTime, &fileSize, &fileHPPM, &fileVPPM);
336 if (bmNew != NULL)
337 {
338 TCHAR tempstr[1000];
339 TCHAR resstr[100];
340 TCHAR *temp;
341 insertReversible(bmNew);
342 GetFullPathName(lpszArgument, SIZEOF(filepathname), filepathname, &temp);
343 _tcscpy(filename, temp);
344 LoadString(hProgInstance, IDS_WINDOWTITLE, resstr, SIZEOF(resstr));
345 _stprintf(tempstr, resstr, filename);
346 SetWindowText(hMainWnd, tempstr);
347 clearHistory();
348 isAFile = TRUE;
349 }
350 else
351 {
352 exit(0);
353 }
354 }
355
356 /* initializing the CHOOSECOLOR structure for use with ChooseColor */
357 choosecolor.lStructSize = sizeof(CHOOSECOLOR);
358 choosecolor.hwndOwner = hwnd;
359 choosecolor.hInstance = NULL;
360 choosecolor.rgbResult = 0x00ffffff;
361 choosecolor.lpCustColors = (COLORREF*) &custColors;
362 choosecolor.Flags = 0;
363 choosecolor.lCustData = 0;
364 choosecolor.lpfnHook = NULL;
365 choosecolor.lpTemplateName = NULL;
366
367 /* initializing the OPENFILENAME structure for use with GetOpenFileName and GetSaveFileName */
368 CopyMemory(ofnFilename, filename, sizeof(filename));
369 LoadString(hThisInstance, IDS_OPENFILTER, ofnFilter, SIZEOF(ofnFilter));
370 for(c = ofnFilter; *c; c++)
371 if (*c == '\1')
372 *c = '\0';
373 ZeroMemory(&ofn, sizeof(OPENFILENAME));
374 ofn.lStructSize = sizeof(OPENFILENAME);
375 ofn.hwndOwner = hwnd;
376 ofn.hInstance = hThisInstance;
377 ofn.lpstrFilter = ofnFilter;
378 ofn.lpstrFile = ofnFilename;
379 ofn.nMaxFile = SIZEOF(ofnFilename);
380 ofn.lpstrFileTitle = ofnFiletitle;
381 ofn.nMaxFileTitle = SIZEOF(ofnFiletitle);
382 ofn.Flags = OFN_HIDEREADONLY;
383
384 CopyMemory(sfnFilename, filename, sizeof(filename));
385 LoadString(hThisInstance, IDS_SAVEFILTER, sfnFilter, SIZEOF(sfnFilter));
386 for(c = sfnFilter; *c; c++)
387 if (*c == '\1')
388 *c = '\0';
389 ZeroMemory(&sfn, sizeof(OPENFILENAME));
390 sfn.lStructSize = sizeof(OPENFILENAME);
391 sfn.hwndOwner = hwnd;
392 sfn.hInstance = hThisInstance;
393 sfn.lpstrFilter = sfnFilter;
394 sfn.lpstrFile = sfnFilename;
395 sfn.nMaxFile = SIZEOF(sfnFilename);
396 sfn.lpstrFileTitle = sfnFiletitle;
397 sfn.nMaxFileTitle = SIZEOF(sfnFiletitle);
398 sfn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
399
400 /* creating the size boxes */
401 hSizeboxLeftTop =
402 CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD | WS_VISIBLE, 0, 0, 3, 3, hScrlClient, NULL,
403 hThisInstance, NULL);
404 hSizeboxCenterTop =
405 CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD | WS_VISIBLE, 0, 0, 3, 3, hScrlClient, NULL,
406 hThisInstance, NULL);
407 hSizeboxRightTop =
408 CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD | WS_VISIBLE, 0, 0, 3, 3, hScrlClient, NULL,
409 hThisInstance, NULL);
410 hSizeboxLeftCenter =
411 CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD | WS_VISIBLE, 0, 0, 3, 3, hScrlClient, NULL,
412 hThisInstance, NULL);
413 hSizeboxRightCenter =
414 CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD | WS_VISIBLE, 0, 0, 3, 3, hScrlClient, NULL,
415 hThisInstance, NULL);
416 hSizeboxLeftBottom =
417 CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD | WS_VISIBLE, 0, 0, 3, 3, hScrlClient, NULL,
418 hThisInstance, NULL);
419 hSizeboxCenterBottom =
420 CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD | WS_VISIBLE, 0, 0, 3, 3, hScrlClient, NULL,
421 hThisInstance, NULL);
422 hSizeboxRightBottom =
423 CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD | WS_VISIBLE, 0, 0, 3, 3, hScrlClient, NULL,
424 hThisInstance, NULL);
425 /* placing the size boxes around the image */
426 SendMessage(hImageArea, WM_SIZE, 0, 0);
427
428 /* by moving the window, the things in WM_SIZE are done */
429 MoveWindow(hwnd, 100, 100, 600, 450, TRUE);
430
431 /* creating the text editor window for the text tool */
432 hwndTextEdit =
433 CreateWindowEx(0, _T("TextEdit"), _T(""), WS_OVERLAPPEDWINDOW, 300, 0, 300,
434 200, hwnd, NULL, hThisInstance, NULL);
435 /* creating the edit control within the editor window */
436 hwndEditCtl =
437 CreateWindowEx(WS_EX_CLIENTEDGE, _T("EDIT"), _T(""),
438 WS_CHILD | WS_VISIBLE | WS_BORDER | WS_HSCROLL | WS_VSCROLL | ES_MULTILINE | ES_NOHIDESEL | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
439 0, 0, 100, 100, hwndTextEdit, NULL, hThisInstance, NULL);
440
441 /* Make the window visible on the screen */
442 ShowWindow (hwnd, nFunsterStil);
443
444 /* inform the system, that the main window accepts dropped files */
445 DragAcceptFiles(hwnd, TRUE);
446
447 /* Run the message loop. It will run until GetMessage() returns 0 */
448 while (GetMessage(&messages, NULL, 0, 0))
449 {
450 TranslateAccelerator(hwnd, (HACCEL) haccel, &messages);
451
452 /* Translate virtual-key messages into character messages */
453 TranslateMessage(&messages);
454 /* Send message to WindowProcedure */
455 DispatchMessage(&messages);
456 }
457
458 /* The program return-value is 0 - The value that PostQuitMessage() gave */
459 return messages.wParam;
460 }