- strmini.h: Include windef.h so CDECL gets defined for msvc version of DEFINE_GUIDEX...
[reactos.git] / reactos / base / applications / paint / main.c
1 /*
2 * PROJECT: PAINT for ReactOS
3 * LICENSE: LGPL
4 * FILE: main.c
5 * PURPOSE: Initializing everything
6 * PROGRAMMERS: Benedikt Freisen
7 */
8
9 /* INCLUDES *********************************************************/
10
11 #include <windows.h>
12 #include <windowsx.h>
13 #include <commctrl.h>
14 #include <stdio.h>
15 #include <tchar.h>
16 #include "definitions.h"
17
18 #include "drawing.h"
19 #include "dib.h"
20
21 #include "globalvar.h"
22 #include "history.h"
23 #include "mouse.h"
24
25 #include "winproc.h"
26 #include "palette.h"
27 #include "toolsettings.h"
28 #include "selection.h"
29 #include "sizebox.h"
30
31 /* FUNCTIONS ********************************************************/
32
33 HDC hDrawingDC;
34 HDC hSelDC;
35 int *bmAddress;
36 BITMAPINFO bitmapinfo;
37 int imgXRes = 400;
38 int imgYRes = 300;
39
40 HBITMAP hBms[4];
41 int currInd = 0;
42 int undoSteps = 0;
43 int redoSteps = 0;
44
45 // global status variables
46
47 short startX;
48 short startY;
49 short lastX;
50 short lastY;
51 int lineWidth = 1;
52 int shapeStyle = 0;
53 int brushStyle = 0;
54 int activeTool = 7;
55 int airBrushWidth = 5;
56 int rubberRadius = 4;
57 int transpBg = 0;
58 int zoom = 1000;
59 int rectSel_src[4];
60 int rectSel_dest[4];
61 HWND hSelection;
62 HWND hImageArea;
63 HBITMAP hSelBm;
64
65
66 // global declarations and WinMain
67
68
69 // initial palette colors; may be changed by the user during execution
70 int palColors[28] =
71 {0x000000, 0x464646, 0x787878, 0x300099, 0x241ced, 0x0078ff, 0x0ec2ff,
72 0x00f2ff, 0x1de6a8, 0x4cb122, 0xefb700, 0xf36d4d, 0x99362f, 0x98316f,
73 0xffffff, 0xdcdcdc, 0xb4b4b4, 0x3c5a9c, 0xb1a3ff, 0x7aaae5, 0x9ce4f5,
74 0xbdf9ff, 0xbcf9d3, 0x61bb9d, 0xead999, 0xd19a70, 0x8e6d54, 0xd5a5b5};
75 // foreground and background colors with initial value
76 int fgColor = 0x00000000;
77 int bgColor = 0x00ffffff;
78 // the current zoom in percent*10
79 HWND hStatusBar;
80 HWND hScrollbox;
81 HWND hMainWnd;
82 HWND hPalWin;
83 HWND hToolSettings;
84 CHOOSECOLOR choosecolor;
85 OPENFILENAME ofn;
86 OPENFILENAME sfn;
87 HICON hNontranspIcon;
88 HICON hTranspIcon;
89
90 HCURSOR hCurFill;
91 HCURSOR hCurColor;
92 HCURSOR hCurZoom;
93 HCURSOR hCurPen;
94 HCURSOR hCurAirbrush;
95
96 HWND hScrlClient;
97
98 HWND hToolBtn[16];
99
100 HINSTANCE hProgInstance;
101
102 TCHAR filename[256];
103 TCHAR filepathname[1000];
104 BOOL isAFile = FALSE;
105
106 BOOL showGrid = FALSE;
107 BOOL showMiniature = FALSE;
108
109 HWND hwndMiniature;
110
111 HWND hSizeboxLeftTop;
112 HWND hSizeboxCenterTop;
113 HWND hSizeboxRightTop;
114 HWND hSizeboxLeftCenter;
115 HWND hSizeboxRightCenter;
116 HWND hSizeboxLeftBottom;
117 HWND hSizeboxCenterBottom;
118 HWND hSizeboxRightBottom;
119
120 int WINAPI _tWinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPTSTR lpszArgument, int nFunsterStil)
121 {
122 HWND hwnd; /* This is the handle for our window */
123 MSG messages; /* Here messages to the application are saved */
124 WNDCLASSEX wclScroll;
125 WNDCLASSEX wincl;
126 WNDCLASSEX wclPal;
127 WNDCLASSEX wclSettings;
128 WNDCLASSEX wclSelection;
129 TCHAR progtitle[1000];
130 TCHAR resstr[100];
131 HMENU menu;
132 HWND hToolbar;
133 HIMAGELIST hImageList;
134 HANDLE haccel;
135 HBITMAP tempBm;
136 int i;
137 TCHAR tooltips[16][30];
138 TCHAR *c;
139 TCHAR sfnFilename[1000];
140 TCHAR sfnFiletitle[256];
141 TCHAR sfnFilter[1000];
142 TCHAR ofnFilename[1000];
143 TCHAR ofnFiletitle[256];
144 TCHAR ofnFilter[1000];
145 TCHAR miniaturetitle[100];
146 int custColors[16] =
147 {0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
148 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff};
149
150 hProgInstance = hThisInstance;
151
152 /* Necessary */
153 InitCommonControls();
154
155 /* initializing and registering the window class used for the main window */
156 wincl.hInstance = hThisInstance;
157 wincl.lpszClassName = _T("WindowsApp");
158 wincl.lpfnWndProc = WindowProcedure;
159 wincl.style = CS_DBLCLKS;
160 wincl.cbSize = sizeof (WNDCLASSEX);
161 wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
162 wincl.hIconSm = LoadIcon (hThisInstance, MAKEINTRESOURCE(500));
163 wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
164 wincl.lpszMenuName = NULL;
165 wincl.cbClsExtra = 0;
166 wincl.cbWndExtra = 0;
167 wincl.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
168 RegisterClassEx (&wincl);
169
170 /* initializing and registering the window class used for the scroll box */
171 wclScroll.hInstance = hThisInstance;
172 wclScroll.lpszClassName = _T("Scrollbox");
173 wclScroll.lpfnWndProc = WindowProcedure;
174 wclScroll.style = 0;
175 wclScroll.cbSize = sizeof (WNDCLASSEX);
176 wclScroll.hIcon = NULL;
177 wclScroll.hIconSm = NULL;
178 wclScroll.hCursor = LoadCursor (NULL, IDC_ARROW);
179 wclScroll.lpszMenuName = NULL;
180 wclScroll.cbClsExtra = 0;
181 wclScroll.cbWndExtra = 0;
182 wclScroll.hbrBackground = GetSysColorBrush(COLOR_APPWORKSPACE);
183 RegisterClassEx (&wclScroll);
184
185 /* initializing and registering the window class used for the palette window */
186 wclPal.hInstance = hThisInstance;
187 wclPal.lpszClassName = _T("Palette");
188 wclPal.lpfnWndProc = PalWinProc;
189 wclPal.style = CS_DBLCLKS;
190 wclPal.cbSize = sizeof (WNDCLASSEX);
191 wclPal.hIcon = NULL;
192 wclPal.hIconSm = NULL;
193 wclPal.hCursor = LoadCursor (NULL, IDC_ARROW);
194 wclPal.lpszMenuName = NULL;
195 wclPal.cbClsExtra = 0;
196 wclPal.cbWndExtra = 0;
197 wclPal.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
198 RegisterClassEx (&wclPal);
199
200 /* initializing and registering the window class for the settings window */
201 wclSettings.hInstance = hThisInstance;
202 wclSettings.lpszClassName = _T("ToolSettings");
203 wclSettings.lpfnWndProc = SettingsWinProc;
204 wclSettings.style = CS_DBLCLKS;
205 wclSettings.cbSize = sizeof (WNDCLASSEX);
206 wclSettings.hIcon = NULL;
207 wclSettings.hIconSm = NULL;
208 wclSettings.hCursor = LoadCursor (NULL, IDC_ARROW);
209 wclSettings.lpszMenuName = NULL;
210 wclSettings.cbClsExtra = 0;
211 wclSettings.cbWndExtra = 0;
212 wclSettings.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
213 RegisterClassEx (&wclSettings);
214
215 /* initializing and registering the window class for the selection frame */
216 wclSelection.hInstance = hThisInstance;
217 wclSelection.lpszClassName = _T("Selection");
218 wclSelection.lpfnWndProc = SelectionWinProc;
219 wclSelection.style = CS_DBLCLKS;
220 wclSelection.cbSize = sizeof (WNDCLASSEX);
221 wclSelection.hIcon = NULL;
222 wclSelection.hIconSm = NULL;
223 wclSelection.hCursor = LoadCursor (NULL, IDC_SIZEALL);
224 wclSelection.lpszMenuName = NULL;
225 wclSelection.cbClsExtra = 0;
226 wclSelection.cbWndExtra = 0;
227 wclSelection.hbrBackground = NULL;//GetSysColorBrush(COLOR_BTNFACE);
228 RegisterClassEx (&wclSelection);
229
230 /* initializing and registering the window class for the size boxes */
231 wclSettings.hInstance = hThisInstance;
232 wclSettings.lpszClassName = _T("Sizebox");
233 wclSettings.lpfnWndProc = SizeboxWinProc;
234 wclSettings.style = CS_DBLCLKS;
235 wclSettings.cbSize = sizeof (WNDCLASSEX);
236 wclSettings.hIcon = NULL;
237 wclSettings.hIconSm = NULL;
238 wclSettings.hCursor = LoadCursor (NULL, IDC_ARROW);
239 wclSettings.lpszMenuName = NULL;
240 wclSettings.cbClsExtra = 0;
241 wclSettings.cbWndExtra = 0;
242 wclSettings.hbrBackground = GetSysColorBrush(COLOR_HIGHLIGHT);
243 RegisterClassEx (&wclSettings);
244
245 LoadString(hThisInstance, IDS_DEFAULTFILENAME, filename, SIZEOF(filename));
246 LoadString(hThisInstance, IDS_WINDOWTITLE, resstr, SIZEOF(resstr));
247 _stprintf(progtitle, resstr, filename);
248 LoadString(hThisInstance, IDS_MINIATURETITLE, miniaturetitle, SIZEOF(miniaturetitle));
249
250 /* create main window */
251 hwnd = CreateWindowEx (0, _T("WindowsApp"), progtitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 544, 375, HWND_DESKTOP, NULL, hThisInstance, NULL);
252
253 hMainWnd = hwnd;
254 hwndMiniature = CreateWindowEx(WS_EX_PALETTEWINDOW, _T("WindowsApp"), miniaturetitle, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME, 180, 200, 120, 100, hwnd, NULL, hThisInstance, NULL);
255
256 /* loading and setting the window menu from resource */
257 menu = LoadMenu(hThisInstance, MAKEINTRESOURCE(ID_MENU));
258 SetMenu(hwnd, menu);
259 haccel = LoadAccelerators(hThisInstance, MAKEINTRESOURCE(800));
260
261 /* preloading the draw transparent/nontransparent icons for later use */
262 hNontranspIcon = LoadImage(hThisInstance, MAKEINTRESOURCE(IDI_NONTRANSPARENT), IMAGE_ICON, 40, 30, LR_DEFAULTCOLOR);
263 hTranspIcon = LoadImage(hThisInstance, MAKEINTRESOURCE(IDI_TRANSPARENT), IMAGE_ICON, 40, 30, LR_DEFAULTCOLOR);
264
265 hCurFill = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_FILL));
266 hCurColor = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_COLOR));
267 hCurZoom = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_ZOOM));
268 hCurPen = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_PEN));
269 hCurAirbrush = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_AIRBRUSH));
270
271 CreateWindowEx (0, _T("STATIC"), _T(""), WS_CHILD | WS_VISIBLE | SS_ETCHEDHORZ, 0, 0, 5000, 2, hwnd, NULL, hThisInstance, NULL);
272
273 /* creating the 16 bitmap radio buttons and setting the bitmap */
274
275
276 /* FIXME: Unintentionally there is a line above the tool bar. To prevent cropping of the buttons height has been increased from 200 to 205 */
277 hToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | CCS_NOPARENTALIGN | CCS_VERT | CCS_NORESIZE | TBSTYLE_TOOLTIPS, 3, 3, 50, 205, hwnd, NULL, hThisInstance, NULL);
278 hImageList = ImageList_Create(16, 16, ILC_COLOR24 | ILC_MASK, 16, 0);
279 SendMessage(hToolbar, TB_SETIMAGELIST, 0, (LPARAM)hImageList);
280 tempBm = LoadImage(hThisInstance, MAKEINTRESOURCE(IDB_TOOLBARICONS), IMAGE_BITMAP, 256, 16, 0);
281 ImageList_AddMasked(hImageList, tempBm, 0xff00ff);
282 DeleteObject(tempBm);
283 SendMessage(hToolbar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
284 for (i=0; i<16; i++)
285 {
286 TBBUTTON tbbutton;
287 int wrapnow = 0;
288
289 if (i % 2 == 1) wrapnow = TBSTATE_WRAP;
290 LoadString(hThisInstance, IDS_TOOLTIP1 + i, tooltips[i], 30);
291 ZeroMemory(&tbbutton, sizeof(TBBUTTON));
292 tbbutton.iString = (INT_PTR)tooltips[i];
293 tbbutton.fsStyle = TBSTYLE_CHECKGROUP;
294 tbbutton.fsState = TBSTATE_ENABLED | wrapnow;
295 tbbutton.idCommand = ID_FREESEL + i;
296 tbbutton.iBitmap = i;
297 SendMessage(hToolbar, TB_ADDBUTTONS, 1, (LPARAM)&tbbutton);
298 }
299 /* SendMessage(hToolbar, TB_SETROWS, MAKEWPARAM(8, FALSE), (LPARAM)NULL); */
300 SendMessage(hToolbar, TB_CHECKBUTTON, ID_PEN, MAKELONG(TRUE, 0));
301 SendMessage(hToolbar, TB_SETMAXTEXTROWS, 0, 0);
302
303 SendMessage(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(25, 25));
304 /* SendMessage(hToolbar, TB_AUTOSIZE, 0, 0); */
305
306 /* creating the tool settings child window */
307 hToolSettings = CreateWindowEx(0, _T("ToolSettings"), _T(""), WS_CHILD | WS_VISIBLE, 7, 210, 42, 140, hwnd, NULL, hThisInstance, NULL);
308
309 /* creating the palette child window */
310 hPalWin = CreateWindowEx(0, _T("Palette"), _T(""), WS_CHILD | WS_VISIBLE, 56, 9, 255, 32, hwnd, NULL, hThisInstance, NULL);
311
312 /* creating the scroll box */
313 hScrollbox = CreateWindowEx (WS_EX_CLIENTEDGE, _T("Scrollbox"), _T(""), WS_CHILD | WS_GROUP | WS_HSCROLL | WS_VSCROLL | WS_VISIBLE, 56, 49, 472, 248, hwnd, NULL, hThisInstance, NULL);
314
315 /* creating the status bar */
316 hStatusBar = CreateWindowEx (0, STATUSCLASSNAME, _T(""), SBARS_SIZEGRIP | WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hwnd, NULL, hThisInstance, NULL);
317 SendMessage(hStatusBar, SB_SETMINHEIGHT, 21, 0);
318
319 hScrlClient = CreateWindowEx(0, _T("Scrollbox"), _T(""), WS_CHILD | WS_VISIBLE, 0, 0, 500, 500, hScrollbox, NULL, hThisInstance, NULL);
320
321 /* create selection window (initially hidden) */
322 hSelection = CreateWindowEx(WS_EX_TRANSPARENT, _T("Selection"), _T(""), WS_CHILD | BS_OWNERDRAW, 350, 0, 100, 100, hScrlClient, NULL, hThisInstance, NULL);
323
324 /* creating the window inside the scroll box, on which the image in hDrawingDC's bitmap is drawn */
325 hImageArea = CreateWindowEx (0, _T("Scrollbox"), _T(""), WS_CHILD | WS_VISIBLE, 3, 3, imgXRes, imgYRes, hScrlClient, NULL, hThisInstance, NULL);
326
327 hDrawingDC = CreateCompatibleDC(GetDC(hImageArea));
328 hSelDC = CreateCompatibleDC(GetDC(hImageArea));
329 SelectObject(hDrawingDC, CreatePen(PS_SOLID, 0, fgColor));
330 SelectObject(hDrawingDC, CreateSolidBrush(bgColor));
331
332 hBms[0] = CreateDIBWithProperties(imgXRes, imgYRes);
333 SelectObject(hDrawingDC, hBms[0]);
334 Rectangle(hDrawingDC, 0-1, 0-1, imgXRes+1, imgYRes+1);
335
336 /* initializing the CHOOSECOLOR structure for use with ChooseColor */
337 choosecolor.lStructSize = sizeof(CHOOSECOLOR);
338 choosecolor.hwndOwner = hwnd;
339 choosecolor.hInstance = NULL;
340 choosecolor.rgbResult = 0x00ffffff;
341 choosecolor.lpCustColors = (COLORREF*)&custColors;
342 choosecolor.Flags = 0;
343 choosecolor.lCustData = 0;
344 choosecolor.lpfnHook = NULL;
345 choosecolor.lpTemplateName = NULL;
346
347 /* initializing the OPENFILENAME structure for use with GetOpenFileName and GetSaveFileName */
348 CopyMemory(ofnFilename, filename, sizeof(filename));
349 LoadString(hThisInstance, IDS_OPENFILTER, ofnFilter, SIZEOF(ofnFilter));
350 for (c = ofnFilter; *c; c++) if (*c == '\1') *c = '\0';
351 ZeroMemory(&ofn, sizeof(OPENFILENAME));
352 ofn.lStructSize = sizeof (OPENFILENAME);
353 ofn.hwndOwner = hwnd;
354 ofn.hInstance = hThisInstance;
355 ofn.lpstrFilter = ofnFilter;
356 ofn.lpstrFile = ofnFilename;
357 ofn.nMaxFile = SIZEOF(ofnFilename);
358 ofn.lpstrFileTitle = ofnFiletitle;
359 ofn.nMaxFileTitle = SIZEOF(ofnFiletitle);
360 ofn.Flags = OFN_HIDEREADONLY;
361
362 CopyMemory(sfnFilename, filename, sizeof(filename));
363 LoadString(hThisInstance, IDS_SAVEFILTER, sfnFilter, SIZEOF(sfnFilter));
364 for (c = sfnFilter; *c; c++) if (*c == '\1') *c = '\0';
365 ZeroMemory(&sfn, sizeof(OPENFILENAME));
366 sfn.lStructSize = sizeof (OPENFILENAME);
367 sfn.hwndOwner = hwnd;
368 sfn.hInstance = hThisInstance;
369 sfn.lpstrFilter = sfnFilter;
370 sfn.lpstrFile = sfnFilename;
371 sfn.nMaxFile = SIZEOF(sfnFilename);
372 sfn.lpstrFileTitle = sfnFiletitle;
373 sfn.nMaxFileTitle = SIZEOF(sfnFiletitle);
374 sfn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
375
376 hSizeboxLeftTop = CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD | WS_VISIBLE, 0, 0, 3, 3, hScrlClient, NULL, hThisInstance, NULL);
377 hSizeboxCenterTop = CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD | WS_VISIBLE, 0, 0, 3, 3, hScrlClient, NULL, hThisInstance, NULL);
378 hSizeboxRightTop = CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD | WS_VISIBLE, 0, 0, 3, 3, hScrlClient, NULL, hThisInstance, NULL);
379 hSizeboxLeftCenter = CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD | WS_VISIBLE, 0, 0, 3, 3, hScrlClient, NULL, hThisInstance, NULL);
380 hSizeboxRightCenter = CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD | WS_VISIBLE, 0, 0, 3, 3, hScrlClient, NULL, hThisInstance, NULL);
381 hSizeboxLeftBottom = CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD | WS_VISIBLE, 0, 0, 3, 3, hScrlClient, NULL, hThisInstance, NULL);
382 hSizeboxCenterBottom= CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD | WS_VISIBLE, 0, 0, 3, 3, hScrlClient, NULL, hThisInstance, NULL);
383 hSizeboxRightBottom = CreateWindowEx(0, _T("Sizebox"), _T(""), WS_CHILD | WS_VISIBLE, 0, 0, 3, 3, hScrlClient, NULL, hThisInstance, NULL);
384 SendMessage(hImageArea, WM_SIZE, 0, 0);
385
386 /* by moving the window, the things in WM_SIZE are done */
387 MoveWindow(hwnd, 100, 100, 600, 450, TRUE);
388
389 /* Make the window visible on the screen */
390 ShowWindow (hwnd, nFunsterStil);
391
392 /* Run the message loop. It will run until GetMessage() returns 0 */
393 while (GetMessage (&messages, NULL, 0, 0))
394 {
395 TranslateAccelerator(hwnd, haccel, &messages);
396
397 /* Translate virtual-key messages into character messages */
398 TranslateMessage(&messages);
399 /* Send message to WindowProcedure */
400 DispatchMessage(&messages);
401 }
402
403 /* The program return-value is 0 - The value that PostQuitMessage() gave */
404 return messages.wParam;
405 }