afd1f468ed2454d329c4f360d9ef67378c67a220
[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 /* FUNCTIONS ********************************************************/
14
15 HDC hDrawingDC;
16 HDC hSelDC;
17 int *bmAddress;
18 BITMAPINFO bitmapinfo;
19 int imgXRes = 400;
20 int imgYRes = 300;
21
22 int widthSetInDlg;
23 int heightSetInDlg;
24
25 STRETCHSKEW stretchSkew;
26
27 HBITMAP hBms[HISTORYSIZE];
28 int currInd = 0;
29 int undoSteps = 0;
30 int redoSteps = 0;
31 BOOL imageSaved = TRUE;
32
33 POINT start;
34 POINT last;
35
36 ToolsModel toolsModel;
37
38 RECT rectSel_src;
39 RECT rectSel_dest;
40 HBITMAP hSelBm;
41 HBITMAP hSelMask;
42 LOGFONT lfTextFont;
43 HFONT hfontTextFont;
44 HWND hwndEditCtl;
45 LPTSTR textToolText = NULL;
46 int textToolTextMaxLen = 0;
47
48 PaletteModel paletteModel;
49
50 HWND hStatusBar;
51 HWND hTrackbarZoom;
52 CHOOSECOLOR choosecolor;
53 OPENFILENAME ofn;
54 OPENFILENAME sfn;
55 HICON hNontranspIcon;
56 HICON hTranspIcon;
57
58 HCURSOR hCurFill;
59 HCURSOR hCurColor;
60 HCURSOR hCurZoom;
61 HCURSOR hCurPen;
62 HCURSOR hCurAirbrush;
63
64 HWND hToolBtn[16];
65
66 HINSTANCE hProgInstance;
67
68 TCHAR filename[256];
69 TCHAR filepathname[1000];
70 BOOL isAFile = FALSE;
71 int fileSize;
72 int fileHPPM = 2834;
73 int fileVPPM = 2834;
74 SYSTEMTIME fileTime;
75
76 BOOL showGrid = FALSE;
77 BOOL showMiniature = FALSE;
78
79 CMainWindow mainWindow;
80 CMiniatureWindow miniature;
81 CMainWindow toolBoxContainer;
82 CToolSettingsWindow toolSettingsWindow;
83 CPaletteWindow paletteWindow;
84 CScrollboxWindow scrollboxWindow;
85 CScrollboxWindow scrlClientWindow;
86 CSelectionWindow selectionWindow;
87 CImgAreaWindow imageArea;
88 CSizeboxWindow sizeboxLeftTop;
89 CSizeboxWindow sizeboxCenterTop;
90 CSizeboxWindow sizeboxRightTop;
91 CSizeboxWindow sizeboxLeftCenter;
92 CSizeboxWindow sizeboxRightCenter;
93 CSizeboxWindow sizeboxLeftBottom;
94 CSizeboxWindow sizeboxCenterBottom;
95 CSizeboxWindow sizeboxRightBottom;
96 CTextEditWindow textEditWindow;
97
98 /* entry point */
99
100 int WINAPI
101 _tWinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPTSTR lpszArgument, int nFunsterStil)
102 {
103 HWND hwnd; /* This is the handle for our window */
104 MSG messages; /* Here messages to the application are saved */
105
106 TCHAR progtitle[1000];
107 TCHAR resstr[100];
108 HMENU menu;
109 HWND hToolbar;
110 HIMAGELIST hImageList;
111 HANDLE haccel;
112 HBITMAP tempBm;
113 int i;
114 TCHAR tooltips[16][30];
115 HDC hDC;
116
117 TCHAR *c;
118 TCHAR sfnFilename[1000];
119 TCHAR sfnFiletitle[256];
120 TCHAR sfnFilter[1000];
121 TCHAR ofnFilename[1000];
122 TCHAR ofnFiletitle[256];
123 TCHAR ofnFilter[1000];
124 TCHAR miniaturetitle[100];
125 static int custColors[16] = { 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
126 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff
127 };
128
129 /* init font for text tool */
130 lfTextFont.lfHeight = 0;
131 lfTextFont.lfWidth = 0;
132 lfTextFont.lfEscapement = 0;
133 lfTextFont.lfOrientation = 0;
134 lfTextFont.lfWeight = FW_NORMAL;
135 lfTextFont.lfItalic = FALSE;
136 lfTextFont.lfUnderline = FALSE;
137 lfTextFont.lfStrikeOut = FALSE;
138 lfTextFont.lfCharSet = DEFAULT_CHARSET;
139 lfTextFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
140 lfTextFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
141 lfTextFont.lfQuality = DEFAULT_QUALITY;
142 lfTextFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
143 lstrcpy(lfTextFont.lfFaceName, _T(""));
144 hfontTextFont = CreateFontIndirect(&lfTextFont);
145
146 hProgInstance = hThisInstance;
147
148 /* initialize common controls library */
149 InitCommonControls();
150
151 LoadString(hThisInstance, IDS_DEFAULTFILENAME, filename, SIZEOF(filename));
152 LoadString(hThisInstance, IDS_WINDOWTITLE, resstr, SIZEOF(resstr));
153 _stprintf(progtitle, resstr, filename);
154 LoadString(hThisInstance, IDS_MINIATURETITLE, miniaturetitle, SIZEOF(miniaturetitle));
155
156 /* create main window */
157 RECT mainWindowPos = {0, 0, 544, 375}; // FIXME: use equivalent of CW_USEDEFAULT for position
158 hwnd = mainWindow.Create(HWND_DESKTOP, mainWindowPos, progtitle, WS_OVERLAPPEDWINDOW, 0, 0U, NULL);
159
160 RECT miniaturePos = {180, 200, 180 + 120, 200 + 100};
161 miniature.Create(hwnd, miniaturePos, miniaturetitle,
162 WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME, WS_EX_PALETTEWINDOW, 0U, NULL);
163
164 /* loading and setting the window menu from resource */
165 menu = LoadMenu(hThisInstance, MAKEINTRESOURCE(ID_MENU));
166 SetMenu(hwnd, menu);
167 haccel = LoadAccelerators(hThisInstance, MAKEINTRESOURCE(800));
168
169 /* preloading the draw transparent/nontransparent icons for later use */
170 hNontranspIcon =
171 (HICON) LoadImage(hThisInstance, MAKEINTRESOURCE(IDI_NONTRANSPARENT), IMAGE_ICON, 40, 30, LR_DEFAULTCOLOR);
172 hTranspIcon =
173 (HICON) LoadImage(hThisInstance, MAKEINTRESOURCE(IDI_TRANSPARENT), IMAGE_ICON, 40, 30, LR_DEFAULTCOLOR);
174
175 hCurFill = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_FILL));
176 hCurColor = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_COLOR));
177 hCurZoom = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_ZOOM));
178 hCurPen = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_PEN));
179 hCurAirbrush = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_AIRBRUSH));
180
181 CreateWindowEx(0, _T("STATIC"), _T(""), WS_CHILD | WS_VISIBLE | SS_ETCHEDHORZ, 0, 0, 5000, 2, hwnd, NULL,
182 hThisInstance, NULL);
183
184 RECT toolBoxContainerPos = {2, 2, 2 + 52, 2 + 350};
185 toolBoxContainer.Create(hwnd, toolBoxContainerPos, _T(""), WS_CHILD | WS_VISIBLE, 0, 0U, NULL);
186 /* creating the 16 bitmap radio buttons and setting the bitmap */
187
188
189 /*
190 * FIXME: Unintentionally there is a line above the tool bar (hidden by y-offset).
191 * To prevent cropping of the buttons height has been increased from 200 to 205
192 */
193 hToolbar =
194 CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
195 WS_CHILD | WS_VISIBLE | CCS_NOPARENTALIGN | CCS_VERT | CCS_NORESIZE | TBSTYLE_TOOLTIPS,
196 1, -2, 50, 205, toolBoxContainer.m_hWnd, NULL, hThisInstance, NULL);
197 hImageList = ImageList_Create(16, 16, ILC_COLOR24 | ILC_MASK, 16, 0);
198 SendMessage(hToolbar, TB_SETIMAGELIST, 0, (LPARAM) hImageList);
199 tempBm = (HBITMAP) LoadImage(hThisInstance, MAKEINTRESOURCE(IDB_TOOLBARICONS), IMAGE_BITMAP, 256, 16, 0);
200 ImageList_AddMasked(hImageList, tempBm, 0xff00ff);
201 DeleteObject(tempBm);
202 SendMessage(hToolbar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
203
204 for(i = 0; i < 16; i++)
205 {
206 TBBUTTON tbbutton;
207 int wrapnow = 0;
208
209 if (i % 2 == 1)
210 wrapnow = TBSTATE_WRAP;
211
212 LoadString(hThisInstance, IDS_TOOLTIP1 + i, tooltips[i], 30);
213 ZeroMemory(&tbbutton, sizeof(TBBUTTON));
214 tbbutton.iString = (INT_PTR) tooltips[i];
215 tbbutton.fsStyle = TBSTYLE_CHECKGROUP;
216 tbbutton.fsState = TBSTATE_ENABLED | wrapnow;
217 tbbutton.idCommand = ID_FREESEL + i;
218 tbbutton.iBitmap = i;
219 SendMessage(hToolbar, TB_ADDBUTTONS, 1, (LPARAM) &tbbutton);
220 }
221
222 SendMessage(hToolbar, TB_CHECKBUTTON, ID_PEN, MAKELONG(TRUE, 0));
223 SendMessage(hToolbar, TB_SETMAXTEXTROWS, 0, 0);
224 SendMessage(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(25, 25));
225
226 /* creating the tool settings child window */
227 RECT toolSettingsWindowPos = {5, 208, 5 + 42, 208 + 140};
228 toolSettingsWindow.Create(toolBoxContainer.m_hWnd, toolSettingsWindowPos, _T(""), WS_CHILD | WS_VISIBLE, 0, 0U, NULL);
229 hTrackbarZoom =
230 CreateWindowEx(0, TRACKBAR_CLASS, _T(""), WS_CHILD | TBS_VERT | TBS_AUTOTICKS, 1, 1, 40, 64,
231 toolSettingsWindow.m_hWnd, NULL, hThisInstance, NULL);
232 SendMessage(hTrackbarZoom, TBM_SETRANGE, (WPARAM) TRUE, (LPARAM) MAKELONG(0, 6));
233 SendMessage(hTrackbarZoom, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) 3);
234
235 /* creating the palette child window */
236 RECT paletteWindowPos = {56, 9, 56 + 255, 9 + 32};
237 paletteWindow.Create(hwnd, paletteWindowPos, _T(""), WS_CHILD | WS_VISIBLE, 0, 0U, NULL);
238
239 /* creating the scroll box */
240 RECT scrollboxWindowPos = {56, 49, 56 + 472, 49 + 248};
241 scrollboxWindow.Create(hwnd, scrollboxWindowPos, _T(""),
242 WS_CHILD | WS_GROUP | WS_HSCROLL | WS_VSCROLL | WS_VISIBLE, WS_EX_CLIENTEDGE, 0U, NULL);
243
244 /* creating the status bar */
245 hStatusBar =
246 CreateWindowEx(0, STATUSCLASSNAME, _T(""), SBARS_SIZEGRIP | WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hwnd,
247 NULL, hThisInstance, NULL);
248 SendMessage(hStatusBar, SB_SETMINHEIGHT, 21, 0);
249
250 RECT scrlClientWindowPos = {0, 0, 0 + 500, 0 + 500};
251 scrlClientWindow.Create(scrollboxWindow.m_hWnd, scrlClientWindowPos, _T(""), WS_CHILD | WS_VISIBLE, 0, 0U, NULL);
252
253 /* create selection window (initially hidden) */
254 RECT selectionWindowPos = {350, 0, 350 + 100, 0 + 100};
255 selectionWindow.Create(scrlClientWindow.m_hWnd, selectionWindowPos, _T(""), WS_CHILD | BS_OWNERDRAW, 0, 0U, NULL);
256
257 /* creating the window inside the scroll box, on which the image in hDrawingDC's bitmap is drawn */
258 RECT imageAreaPos = {3, 3, 3 + imgXRes, 3 + imgYRes};
259 imageArea.Create(scrlClientWindow.m_hWnd, imageAreaPos, _T(""), WS_CHILD | WS_VISIBLE, 0, 0U, NULL);
260
261 hDC = imageArea.GetDC();
262 hDrawingDC = CreateCompatibleDC(hDC);
263 hSelDC = CreateCompatibleDC(hDC);
264 imageArea.ReleaseDC(hDC);
265 SelectObject(hDrawingDC, CreatePen(PS_SOLID, 0, paletteModel.GetFgColor()));
266 SelectObject(hDrawingDC, CreateSolidBrush(paletteModel.GetBgColor()));
267
268 hBms[0] = CreateDIBWithProperties(imgXRes, imgYRes);
269 SelectObject(hDrawingDC, hBms[0]);
270 Rectangle(hDrawingDC, 0 - 1, 0 - 1, imgXRes + 1, imgYRes + 1);
271
272 if (lpszArgument[0] != 0)
273 {
274 HBITMAP bmNew = NULL;
275 LoadDIBFromFile(&bmNew, lpszArgument, &fileTime, &fileSize, &fileHPPM, &fileVPPM);
276 if (bmNew != NULL)
277 {
278 TCHAR tempstr[1000];
279 TCHAR resstr[100];
280 TCHAR *temp;
281 insertReversible(bmNew);
282 GetFullPathName(lpszArgument, SIZEOF(filepathname), filepathname, &temp);
283 _tcscpy(filename, temp);
284 LoadString(hProgInstance, IDS_WINDOWTITLE, resstr, SIZEOF(resstr));
285 _stprintf(tempstr, resstr, filename);
286 mainWindow.SetWindowText(tempstr);
287 clearHistory();
288 isAFile = TRUE;
289 }
290 else
291 {
292 exit(0);
293 }
294 }
295
296 /* initializing the CHOOSECOLOR structure for use with ChooseColor */
297 choosecolor.lStructSize = sizeof(CHOOSECOLOR);
298 choosecolor.hwndOwner = hwnd;
299 choosecolor.hInstance = NULL;
300 choosecolor.rgbResult = 0x00ffffff;
301 choosecolor.lpCustColors = (COLORREF*) &custColors;
302 choosecolor.Flags = 0;
303 choosecolor.lCustData = 0;
304 choosecolor.lpfnHook = NULL;
305 choosecolor.lpTemplateName = NULL;
306
307 /* initializing the OPENFILENAME structure for use with GetOpenFileName and GetSaveFileName */
308 CopyMemory(ofnFilename, filename, sizeof(filename));
309 LoadString(hThisInstance, IDS_OPENFILTER, ofnFilter, SIZEOF(ofnFilter));
310 for(c = ofnFilter; *c; c++)
311 if (*c == '\1')
312 *c = '\0';
313 ZeroMemory(&ofn, sizeof(OPENFILENAME));
314 ofn.lStructSize = sizeof(OPENFILENAME);
315 ofn.hwndOwner = hwnd;
316 ofn.hInstance = hThisInstance;
317 ofn.lpstrFilter = ofnFilter;
318 ofn.lpstrFile = ofnFilename;
319 ofn.nMaxFile = SIZEOF(ofnFilename);
320 ofn.lpstrFileTitle = ofnFiletitle;
321 ofn.nMaxFileTitle = SIZEOF(ofnFiletitle);
322 ofn.Flags = OFN_HIDEREADONLY;
323
324 CopyMemory(sfnFilename, filename, sizeof(filename));
325 LoadString(hThisInstance, IDS_SAVEFILTER, sfnFilter, SIZEOF(sfnFilter));
326 for(c = sfnFilter; *c; c++)
327 if (*c == '\1')
328 *c = '\0';
329 ZeroMemory(&sfn, sizeof(OPENFILENAME));
330 sfn.lStructSize = sizeof(OPENFILENAME);
331 sfn.hwndOwner = hwnd;
332 sfn.hInstance = hThisInstance;
333 sfn.lpstrFilter = sfnFilter;
334 sfn.lpstrFile = sfnFilename;
335 sfn.nMaxFile = SIZEOF(sfnFilename);
336 sfn.lpstrFileTitle = sfnFiletitle;
337 sfn.nMaxFileTitle = SIZEOF(sfnFiletitle);
338 sfn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
339
340 /* creating the size boxes */
341 RECT sizeboxPos = {0, 0, 0 + 3, 0 + 3};
342 sizeboxLeftTop.Create(scrlClientWindow.m_hWnd, sizeboxPos, _T(""), WS_CHILD | WS_VISIBLE, 0, 0U, NULL);
343 sizeboxCenterTop.Create(scrlClientWindow.m_hWnd, sizeboxPos, _T(""), WS_CHILD | WS_VISIBLE, 0, 0U, NULL);
344 sizeboxRightTop.Create(scrlClientWindow.m_hWnd, sizeboxPos, _T(""), WS_CHILD | WS_VISIBLE, 0, 0U, NULL);
345 sizeboxLeftCenter.Create(scrlClientWindow.m_hWnd, sizeboxPos, _T(""), WS_CHILD | WS_VISIBLE, 0, 0U, NULL);
346 sizeboxRightCenter.Create(scrlClientWindow.m_hWnd, sizeboxPos, _T(""), WS_CHILD | WS_VISIBLE, 0, 0U, NULL);
347 sizeboxLeftBottom.Create(scrlClientWindow.m_hWnd, sizeboxPos, _T(""), WS_CHILD | WS_VISIBLE, 0, 0U, NULL);
348 sizeboxCenterBottom.Create(scrlClientWindow.m_hWnd, sizeboxPos, _T(""), WS_CHILD | WS_VISIBLE, 0, 0U, NULL);
349 sizeboxRightBottom.Create(scrlClientWindow.m_hWnd, sizeboxPos, _T(""), WS_CHILD | WS_VISIBLE, 0, 0U, NULL);
350 /* placing the size boxes around the image */
351 imageArea.SendMessage(WM_SIZE, 0, 0);
352
353 /* by moving the window, the things in WM_SIZE are done */
354 MoveWindow(hwnd, 100, 100, 600, 450, TRUE);
355
356 /* creating the text editor window for the text tool */
357 RECT textEditWindowPos = {300, 0, 300 + 300, 0 + 200};
358 textEditWindow.Create(hwnd, textEditWindowPos, _T(""), WS_OVERLAPPEDWINDOW, 0, 0U, NULL);
359 /* creating the edit control within the editor window */
360 hwndEditCtl =
361 CreateWindowEx(WS_EX_CLIENTEDGE, _T("EDIT"), _T(""),
362 WS_CHILD | WS_VISIBLE | WS_BORDER | WS_HSCROLL | WS_VSCROLL | ES_MULTILINE | ES_NOHIDESEL | ES_AUTOHSCROLL | ES_AUTOVSCROLL,
363 0, 0, 100, 100, textEditWindow.m_hWnd, NULL, hThisInstance, NULL);
364
365 /* Make the window visible on the screen */
366 ShowWindow (hwnd, nFunsterStil);
367
368 /* inform the system, that the main window accepts dropped files */
369 DragAcceptFiles(hwnd, TRUE);
370
371 /* Run the message loop. It will run until GetMessage() returns 0 */
372 while (GetMessage(&messages, NULL, 0, 0))
373 {
374 TranslateAccelerator(hwnd, (HACCEL) haccel, &messages);
375
376 /* Translate virtual-key messages into character messages */
377 TranslateMessage(&messages);
378 /* Send message to WindowProcedure */
379 DispatchMessage(&messages);
380 }
381
382 /* The program return-value is 0 - The value that PostQuitMessage() gave */
383 return messages.wParam;
384 }