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