2 * PROJECT: PAINT for ReactOS
4 * FILE: base/applications/paint/main.c
5 * PURPOSE: Initializing everything
6 * PROGRAMMERS: Benedikt Freisen
9 /* INCLUDES *********************************************************/
15 #include "toolsettings.h"
16 #include "selection.h"
19 /* FUNCTIONS ********************************************************/
24 BITMAPINFO bitmapinfo
;
31 STRETCHSKEW stretchSkew
;
33 HBITMAP hBms
[HISTORYSIZE
];
37 BOOL imageSaved
= TRUE
;
44 int activeTool
= TOOL_PEN
;
45 int airBrushWidth
= 5;
56 /* array holding palette colors; may be changed by the user during execution */
60 int modernPalColors
[28] = { 0x000000, 0x464646, 0x787878, 0x300099, 0x241ced, 0x0078ff, 0x0ec2ff,
61 0x00f2ff, 0x1de6a8, 0x4cb122, 0xefb700, 0xf36d4d, 0x99362f, 0x98316f,
62 0xffffff, 0xdcdcdc, 0xb4b4b4, 0x3c5a9c, 0xb1a3ff, 0x7aaae5, 0x9ce4f5,
63 0xbdf9ff, 0xbcf9d3, 0x61bb9d, 0xead999, 0xd19a70, 0x8e6d54, 0xd5a5b5
66 /* older palette containing VGA colors */
67 int oldPalColors
[28] = { 0x000000, 0x808080, 0x000080, 0x008080, 0x008000, 0x808000, 0x800000,
68 0x800080, 0x408080, 0x404000, 0xff8000, 0x804000, 0xff0040, 0x004080,
69 0xffffff, 0xc0c0c0, 0x0000ff, 0x00ffff, 0x00ff00, 0xffff00, 0xff0000,
70 0xff00ff, 0x80ffff, 0x80ff00, 0xffff80, 0xff8080, 0x8000ff, 0x4080ff
73 /* palette currently in use (1: modern, 2: old) */
76 /* foreground and background colors with initial value */
77 int fgColor
= 0x00000000;
78 int bgColor
= 0x00ffffff;
84 HWND hToolBoxContainer
;
87 CHOOSECOLOR choosecolor
;
103 HINSTANCE hProgInstance
;
106 TCHAR filepathname
[1000];
107 BOOL isAFile
= FALSE
;
113 BOOL showGrid
= FALSE
;
114 BOOL showMiniature
= FALSE
;
118 HWND hSizeboxLeftTop
;
119 HWND hSizeboxCenterTop
;
120 HWND hSizeboxRightTop
;
121 HWND hSizeboxLeftCenter
;
122 HWND hSizeboxRightCenter
;
123 HWND hSizeboxLeftBottom
;
124 HWND hSizeboxCenterBottom
;
125 HWND hSizeboxRightBottom
;
130 _tWinMain (HINSTANCE hThisInstance
, HINSTANCE hPrevInstance
, LPTSTR lpszArgument
, int nFunsterStil
)
132 HWND hwnd
; /* This is the handle for our window */
133 MSG messages
; /* Here messages to the application are saved */
135 WNDCLASSEX wclScroll
;
138 WNDCLASSEX wclSettings
;
139 WNDCLASSEX wclSelection
;
141 TCHAR progtitle
[1000];
145 HIMAGELIST hImageList
;
149 TCHAR tooltips
[16][30];
153 TCHAR sfnFilename
[1000];
154 TCHAR sfnFiletitle
[256];
155 TCHAR sfnFilter
[1000];
156 TCHAR ofnFilename
[1000];
157 TCHAR ofnFiletitle
[256];
158 TCHAR ofnFilter
[1000];
159 TCHAR miniaturetitle
[100];
160 static int custColors
[16] = { 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
161 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff
166 CopyMemory(palColors
, modernPalColors
, sizeof(palColors
));
168 hProgInstance
= hThisInstance
;
171 InitCommonControls();
173 /* initializing and registering the window class used for the main window */
174 wincl
.hInstance
= hThisInstance
;
175 wincl
.lpszClassName
= _T("WindowsApp");
176 wincl
.lpfnWndProc
= WindowProcedure
;
177 wincl
.style
= CS_DBLCLKS
;
178 wincl
.cbSize
= sizeof(WNDCLASSEX
);
179 wincl
.hIcon
= LoadIcon(hThisInstance
, MAKEINTRESOURCE(IDI_APPICON
));
180 wincl
.hIconSm
= LoadIcon(hThisInstance
, MAKEINTRESOURCE(IDI_APPICON
));
181 wincl
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
182 wincl
.lpszMenuName
= NULL
;
183 wincl
.cbClsExtra
= 0;
184 wincl
.cbWndExtra
= 0;
185 wincl
.hbrBackground
= GetSysColorBrush(COLOR_BTNFACE
);
186 RegisterClassEx (&wincl
);
188 /* initializing and registering the window class used for the scroll box */
189 wclScroll
.hInstance
= hThisInstance
;
190 wclScroll
.lpszClassName
= _T("Scrollbox");
191 wclScroll
.lpfnWndProc
= WindowProcedure
;
193 wclScroll
.cbSize
= sizeof(WNDCLASSEX
);
194 wclScroll
.hIcon
= NULL
;
195 wclScroll
.hIconSm
= NULL
;
196 wclScroll
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
197 wclScroll
.lpszMenuName
= NULL
;
198 wclScroll
.cbClsExtra
= 0;
199 wclScroll
.cbWndExtra
= 0;
200 wclScroll
.hbrBackground
= GetSysColorBrush(COLOR_APPWORKSPACE
);
201 RegisterClassEx (&wclScroll
);
203 /* initializing and registering the window class used for the palette window */
204 wclPal
.hInstance
= hThisInstance
;
205 wclPal
.lpszClassName
= _T("Palette");
206 wclPal
.lpfnWndProc
= PalWinProc
;
207 wclPal
.style
= CS_DBLCLKS
;
208 wclPal
.cbSize
= sizeof(WNDCLASSEX
);
210 wclPal
.hIconSm
= NULL
;
211 wclPal
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
212 wclPal
.lpszMenuName
= NULL
;
213 wclPal
.cbClsExtra
= 0;
214 wclPal
.cbWndExtra
= 0;
215 wclPal
.hbrBackground
= GetSysColorBrush(COLOR_BTNFACE
);
216 RegisterClassEx (&wclPal
);
218 /* initializing and registering the window class for the settings window */
219 wclSettings
.hInstance
= hThisInstance
;
220 wclSettings
.lpszClassName
= _T("ToolSettings");
221 wclSettings
.lpfnWndProc
= SettingsWinProc
;
222 wclSettings
.style
= CS_DBLCLKS
;
223 wclSettings
.cbSize
= sizeof(WNDCLASSEX
);
224 wclSettings
.hIcon
= NULL
;
225 wclSettings
.hIconSm
= NULL
;
226 wclSettings
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
227 wclSettings
.lpszMenuName
= NULL
;
228 wclSettings
.cbClsExtra
= 0;
229 wclSettings
.cbWndExtra
= 0;
230 wclSettings
.hbrBackground
= GetSysColorBrush(COLOR_BTNFACE
);
231 RegisterClassEx (&wclSettings
);
233 /* initializing and registering the window class for the selection frame */
234 wclSelection
.hInstance
= hThisInstance
;
235 wclSelection
.lpszClassName
= _T("Selection");
236 wclSelection
.lpfnWndProc
= SelectionWinProc
;
237 wclSelection
.style
= CS_DBLCLKS
;
238 wclSelection
.cbSize
= sizeof(WNDCLASSEX
);
239 wclSelection
.hIcon
= NULL
;
240 wclSelection
.hIconSm
= NULL
;
241 wclSelection
.hCursor
= LoadCursor(NULL
, IDC_SIZEALL
);
242 wclSelection
.lpszMenuName
= NULL
;
243 wclSelection
.cbClsExtra
= 0;
244 wclSelection
.cbWndExtra
= 0;
245 wclSelection
.hbrBackground
= NULL
;
246 RegisterClassEx (&wclSelection
);
248 /* initializing and registering the window class for the size boxes */
249 wclSettings
.hInstance
= hThisInstance
;
250 wclSettings
.lpszClassName
= _T("Sizebox");
251 wclSettings
.lpfnWndProc
= SizeboxWinProc
;
252 wclSettings
.style
= CS_DBLCLKS
;
253 wclSettings
.cbSize
= sizeof(WNDCLASSEX
);
254 wclSettings
.hIcon
= NULL
;
255 wclSettings
.hIconSm
= NULL
;
256 wclSettings
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
257 wclSettings
.lpszMenuName
= NULL
;
258 wclSettings
.cbClsExtra
= 0;
259 wclSettings
.cbWndExtra
= 0;
260 wclSettings
.hbrBackground
= GetSysColorBrush(COLOR_HIGHLIGHT
);
261 RegisterClassEx (&wclSettings
);
263 LoadString(hThisInstance
, IDS_DEFAULTFILENAME
, filename
, SIZEOF(filename
));
264 LoadString(hThisInstance
, IDS_WINDOWTITLE
, resstr
, SIZEOF(resstr
));
265 _stprintf(progtitle
, resstr
, filename
);
266 LoadString(hThisInstance
, IDS_MINIATURETITLE
, miniaturetitle
, SIZEOF(miniaturetitle
));
268 /* create main window */
270 CreateWindowEx(0, _T("WindowsApp"), progtitle
, WS_OVERLAPPEDWINDOW
, CW_USEDEFAULT
, CW_USEDEFAULT
, 544,
271 375, HWND_DESKTOP
, NULL
, hThisInstance
, NULL
);
275 CreateWindowEx(WS_EX_PALETTEWINDOW
, _T("WindowsApp"), miniaturetitle
,
276 WS_OVERLAPPED
| WS_CAPTION
| WS_SYSMENU
| WS_THICKFRAME
, 180, 200, 120, 100, hwnd
,
277 NULL
, hThisInstance
, NULL
);
279 /* loading and setting the window menu from resource */
280 menu
= LoadMenu(hThisInstance
, MAKEINTRESOURCE(ID_MENU
));
282 haccel
= LoadAccelerators(hThisInstance
, MAKEINTRESOURCE(800));
284 /* preloading the draw transparent/nontransparent icons for later use */
286 LoadImage(hThisInstance
, MAKEINTRESOURCE(IDI_NONTRANSPARENT
), IMAGE_ICON
, 40, 30, LR_DEFAULTCOLOR
);
288 LoadImage(hThisInstance
, MAKEINTRESOURCE(IDI_TRANSPARENT
), IMAGE_ICON
, 40, 30, LR_DEFAULTCOLOR
);
290 hCurFill
= LoadIcon(hThisInstance
, MAKEINTRESOURCE(IDC_FILL
));
291 hCurColor
= LoadIcon(hThisInstance
, MAKEINTRESOURCE(IDC_COLOR
));
292 hCurZoom
= LoadIcon(hThisInstance
, MAKEINTRESOURCE(IDC_ZOOM
));
293 hCurPen
= LoadIcon(hThisInstance
, MAKEINTRESOURCE(IDC_PEN
));
294 hCurAirbrush
= LoadIcon(hThisInstance
, MAKEINTRESOURCE(IDC_AIRBRUSH
));
296 CreateWindowEx(0, _T("STATIC"), _T(""), WS_CHILD
| WS_VISIBLE
| SS_ETCHEDHORZ
, 0, 0, 5000, 2, hwnd
, NULL
,
297 hThisInstance
, NULL
);
300 CreateWindowEx(0, _T("WindowsApp"), _T(""), WS_CHILD
| WS_VISIBLE
, 2, 2, 52, 350, hwnd
, NULL
,
301 hThisInstance
, NULL
);
302 /* creating the 16 bitmap radio buttons and setting the bitmap */
306 * FIXME: Unintentionally there is a line above the tool bar (hidden by y-offset).
307 * To prevent cropping of the buttons height has been increased from 200 to 205
310 CreateWindowEx(0, TOOLBARCLASSNAME
, NULL
,
311 WS_CHILD
| WS_VISIBLE
| CCS_NOPARENTALIGN
| CCS_VERT
| CCS_NORESIZE
| TBSTYLE_TOOLTIPS
,
312 1, -2, 50, 205, hToolBoxContainer
, NULL
, hThisInstance
, NULL
);
313 hImageList
= ImageList_Create(16, 16, ILC_COLOR24
| ILC_MASK
, 16, 0);
314 SendMessage(hToolbar
, TB_SETIMAGELIST
, 0, (LPARAM
) hImageList
);
315 tempBm
= LoadImage(hThisInstance
, MAKEINTRESOURCE(IDB_TOOLBARICONS
), IMAGE_BITMAP
, 256, 16, 0);
316 ImageList_AddMasked(hImageList
, tempBm
, 0xff00ff);
317 DeleteObject(tempBm
);
318 SendMessage(hToolbar
, TB_BUTTONSTRUCTSIZE
, sizeof(TBBUTTON
), 0);
320 for(i
= 0; i
< 16; i
++)
326 wrapnow
= TBSTATE_WRAP
;
328 LoadString(hThisInstance
, IDS_TOOLTIP1
+ i
, tooltips
[i
], 30);
329 ZeroMemory(&tbbutton
, sizeof(TBBUTTON
));
330 tbbutton
.iString
= (INT_PTR
) tooltips
[i
];
331 tbbutton
.fsStyle
= TBSTYLE_CHECKGROUP
;
332 tbbutton
.fsState
= TBSTATE_ENABLED
| wrapnow
;
333 tbbutton
.idCommand
= ID_FREESEL
+ i
;
334 tbbutton
.iBitmap
= i
;
335 SendMessage(hToolbar
, TB_ADDBUTTONS
, 1, (LPARAM
) &tbbutton
);
338 SendMessage(hToolbar
, TB_CHECKBUTTON
, ID_PEN
, MAKELONG(TRUE
, 0));
339 SendMessage(hToolbar
, TB_SETMAXTEXTROWS
, 0, 0);
340 SendMessage(hToolbar
, TB_SETBUTTONSIZE
, 0, MAKELONG(25, 25));
342 /* creating the tool settings child window */
344 CreateWindowEx(0, _T("ToolSettings"), _T(""), WS_CHILD
| WS_VISIBLE
, 5, 208, 42, 140,
345 hToolBoxContainer
, NULL
, hThisInstance
, NULL
);
347 CreateWindowEx(0, TRACKBAR_CLASS
, _T(""), WS_CHILD
| TBS_VERT
| TBS_AUTOTICKS
, 1, 1, 40, 64,
348 hToolSettings
, NULL
, hThisInstance
, NULL
);
349 SendMessage(hTrackbarZoom
, TBM_SETRANGE
, (WPARAM
) TRUE
, (LPARAM
) MAKELONG(0, 6));
350 SendMessage(hTrackbarZoom
, TBM_SETPOS
, (WPARAM
) TRUE
, (LPARAM
) 3);
352 /* creating the palette child window */
354 CreateWindowEx(0, _T("Palette"), _T(""), WS_CHILD
| WS_VISIBLE
, 56, 9, 255, 32, hwnd
, NULL
,
355 hThisInstance
, NULL
);
357 /* creating the scroll box */
359 CreateWindowEx(WS_EX_CLIENTEDGE
, _T("Scrollbox"), _T(""),
360 WS_CHILD
| WS_GROUP
| WS_HSCROLL
| WS_VSCROLL
| WS_VISIBLE
, 56, 49, 472, 248, hwnd
,
361 NULL
, hThisInstance
, NULL
);
363 /* creating the status bar */
365 CreateWindowEx(0, STATUSCLASSNAME
, _T(""), SBARS_SIZEGRIP
| WS_CHILD
| WS_VISIBLE
, 0, 0, 0, 0, hwnd
,
366 NULL
, hThisInstance
, NULL
);
367 SendMessage(hStatusBar
, SB_SETMINHEIGHT
, 21, 0);
370 CreateWindowEx(0, _T("Scrollbox"), _T(""), WS_CHILD
| WS_VISIBLE
, 0, 0, 500, 500, hScrollbox
, NULL
,
371 hThisInstance
, NULL
);
373 /* create selection window (initially hidden) */
375 CreateWindowEx(WS_EX_TRANSPARENT
, _T("Selection"), _T(""), WS_CHILD
| BS_OWNERDRAW
, 350, 0, 100, 100,
376 hScrlClient
, NULL
, hThisInstance
, NULL
);
378 /* creating the window inside the scroll box, on which the image in hDrawingDC's bitmap is drawn */
380 CreateWindowEx(0, _T("Scrollbox"), _T(""), WS_CHILD
| WS_VISIBLE
, 3, 3, imgXRes
, imgYRes
, hScrlClient
,
381 NULL
, hThisInstance
, NULL
);
383 hDC
= GetDC(hImageArea
);
384 hDrawingDC
= CreateCompatibleDC(hDC
);
385 hSelDC
= CreateCompatibleDC(hDC
);
386 ReleaseDC(hImageArea
, hDC
);
387 SelectObject(hDrawingDC
, CreatePen(PS_SOLID
, 0, fgColor
));
388 SelectObject(hDrawingDC
, CreateSolidBrush(bgColor
));
390 hBms
[0] = CreateDIBWithProperties(imgXRes
, imgYRes
);
391 SelectObject(hDrawingDC
, hBms
[0]);
392 Rectangle(hDrawingDC
, 0 - 1, 0 - 1, imgXRes
+ 1, imgYRes
+ 1);
394 if (lpszArgument
[0] != 0)
396 HBITMAP bmNew
= NULL
;
397 LoadDIBFromFile(&bmNew
, lpszArgument
, &fileTime
, &fileSize
, &fileHPPM
, &fileVPPM
);
403 insertReversible(bmNew
);
404 GetFullPathName(lpszArgument
, SIZEOF(filepathname
), filepathname
, &temp
);
405 _tcscpy(filename
, temp
);
406 LoadString(hProgInstance
, IDS_WINDOWTITLE
, resstr
, SIZEOF(resstr
));
407 _stprintf(tempstr
, resstr
, filename
);
408 SetWindowText(hMainWnd
, tempstr
);
418 /* initializing the CHOOSECOLOR structure for use with ChooseColor */
419 choosecolor
.lStructSize
= sizeof(CHOOSECOLOR
);
420 choosecolor
.hwndOwner
= hwnd
;
421 choosecolor
.hInstance
= NULL
;
422 choosecolor
.rgbResult
= 0x00ffffff;
423 choosecolor
.lpCustColors
= (COLORREF
*) &custColors
;
424 choosecolor
.Flags
= 0;
425 choosecolor
.lCustData
= 0;
426 choosecolor
.lpfnHook
= NULL
;
427 choosecolor
.lpTemplateName
= NULL
;
429 /* initializing the OPENFILENAME structure for use with GetOpenFileName and GetSaveFileName */
430 CopyMemory(ofnFilename
, filename
, sizeof(filename
));
431 LoadString(hThisInstance
, IDS_OPENFILTER
, ofnFilter
, SIZEOF(ofnFilter
));
432 for(c
= ofnFilter
; *c
; c
++)
435 ZeroMemory(&ofn
, sizeof(OPENFILENAME
));
436 ofn
.lStructSize
= sizeof(OPENFILENAME
);
437 ofn
.hwndOwner
= hwnd
;
438 ofn
.hInstance
= hThisInstance
;
439 ofn
.lpstrFilter
= ofnFilter
;
440 ofn
.lpstrFile
= ofnFilename
;
441 ofn
.nMaxFile
= SIZEOF(ofnFilename
);
442 ofn
.lpstrFileTitle
= ofnFiletitle
;
443 ofn
.nMaxFileTitle
= SIZEOF(ofnFiletitle
);
444 ofn
.Flags
= OFN_HIDEREADONLY
;
446 CopyMemory(sfnFilename
, filename
, sizeof(filename
));
447 LoadString(hThisInstance
, IDS_SAVEFILTER
, sfnFilter
, SIZEOF(sfnFilter
));
448 for(c
= sfnFilter
; *c
; c
++)
451 ZeroMemory(&sfn
, sizeof(OPENFILENAME
));
452 sfn
.lStructSize
= sizeof(OPENFILENAME
);
453 sfn
.hwndOwner
= hwnd
;
454 sfn
.hInstance
= hThisInstance
;
455 sfn
.lpstrFilter
= sfnFilter
;
456 sfn
.lpstrFile
= sfnFilename
;
457 sfn
.nMaxFile
= SIZEOF(sfnFilename
);
458 sfn
.lpstrFileTitle
= sfnFiletitle
;
459 sfn
.nMaxFileTitle
= SIZEOF(sfnFiletitle
);
460 sfn
.Flags
= OFN_OVERWRITEPROMPT
| OFN_HIDEREADONLY
;
462 /* creating the size boxes */
464 CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD
| WS_VISIBLE
, 0, 0, 3, 3, hScrlClient
, NULL
,
465 hThisInstance
, NULL
);
467 CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD
| WS_VISIBLE
, 0, 0, 3, 3, hScrlClient
, NULL
,
468 hThisInstance
, NULL
);
470 CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD
| WS_VISIBLE
, 0, 0, 3, 3, hScrlClient
, NULL
,
471 hThisInstance
, NULL
);
473 CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD
| WS_VISIBLE
, 0, 0, 3, 3, hScrlClient
, NULL
,
474 hThisInstance
, NULL
);
475 hSizeboxRightCenter
=
476 CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD
| WS_VISIBLE
, 0, 0, 3, 3, hScrlClient
, NULL
,
477 hThisInstance
, NULL
);
479 CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD
| WS_VISIBLE
, 0, 0, 3, 3, hScrlClient
, NULL
,
480 hThisInstance
, NULL
);
481 hSizeboxCenterBottom
=
482 CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD
| WS_VISIBLE
, 0, 0, 3, 3, hScrlClient
, NULL
,
483 hThisInstance
, NULL
);
484 hSizeboxRightBottom
=
485 CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD
| WS_VISIBLE
, 0, 0, 3, 3, hScrlClient
, NULL
,
486 hThisInstance
, NULL
);
487 /* placing the size boxes around the image */
488 SendMessage(hImageArea
, WM_SIZE
, 0, 0);
490 /* by moving the window, the things in WM_SIZE are done */
491 MoveWindow(hwnd
, 100, 100, 600, 450, TRUE
);
493 /* Make the window visible on the screen */
494 ShowWindow (hwnd
, nFunsterStil
);
496 /* inform the system, that the main window accepts dropped files */
497 DragAcceptFiles(hwnd
, TRUE
);
499 /* Run the message loop. It will run until GetMessage() returns 0 */
500 while (GetMessage(&messages
, NULL
, 0, 0))
502 TranslateAccelerator(hwnd
, haccel
, &messages
);
504 /* Translate virtual-key messages into character messages */
505 TranslateMessage(&messages
);
506 /* Send message to WindowProcedure */
507 DispatchMessage(&messages
);
510 /* The program return-value is 0 - The value that PostQuitMessage() gave */
511 return messages
.wParam
;