[MSPAINT]
[reactos.git] / reactos / base / applications / mspaint / main.cpp
1 /*
2 * PROJECT: PAINT for ReactOS
3 * LICENSE: LGPL
4 * FILE: base/applications/mspaint/main.cpp
5 * PURPOSE: Initializing everything
6 * PROGRAMMERS: Benedikt Freisen
7 */
8
9 /* INCLUDES *********************************************************/
10
11 #include "precomp.h"
12
13 /* FUNCTIONS ********************************************************/
14
15 int widthSetInDlg;
16 int heightSetInDlg;
17
18 STRETCHSKEW stretchSkew;
19
20 POINT start;
21 POINT last;
22
23 ToolsModel toolsModel;
24
25 SelectionModel selectionModel;
26
27 LOGFONT lfTextFont;
28 HFONT hfontTextFont;
29 HWND hwndEditCtl;
30 LPTSTR textToolText = NULL;
31 int textToolTextMaxLen = 0;
32
33 PaletteModel paletteModel;
34
35 RegistrySettings registrySettings;
36
37 ImageModel imageModel;
38 BOOL askBeforeEnlarging = FALSE; // TODO: initialize from registry
39
40 HWND hStatusBar;
41 CHOOSECOLOR choosecolor;
42 OPENFILENAME ofn;
43 OPENFILENAME sfn;
44 HICON hNontranspIcon;
45 HICON hTranspIcon;
46
47 HCURSOR hCurFill;
48 HCURSOR hCurColor;
49 HCURSOR hCurZoom;
50 HCURSOR hCurPen;
51 HCURSOR hCurAirbrush;
52
53 HWND hToolBtn[16];
54
55 HINSTANCE hProgInstance;
56
57 TCHAR filepathname[1000];
58 BOOL isAFile = FALSE;
59 int fileSize;
60 int fileHPPM = 2834;
61 int fileVPPM = 2834;
62 SYSTEMTIME fileTime;
63
64 BOOL showGrid = FALSE;
65 BOOL showMiniature = FALSE;
66
67 CMainWindow mainWindow;
68 CFullscreenWindow fullscreenWindow;
69 CMiniatureWindow miniature;
70 CToolBox toolBoxContainer;
71 CToolSettingsWindow toolSettingsWindow;
72 CPaletteWindow paletteWindow;
73 CScrollboxWindow scrollboxWindow;
74 CScrollboxWindow scrlClientWindow;
75 CSelectionWindow selectionWindow;
76 CImgAreaWindow imageArea;
77 CSizeboxWindow sizeboxLeftTop;
78 CSizeboxWindow sizeboxCenterTop;
79 CSizeboxWindow sizeboxRightTop;
80 CSizeboxWindow sizeboxLeftCenter;
81 CSizeboxWindow sizeboxRightCenter;
82 CSizeboxWindow sizeboxLeftBottom;
83 CSizeboxWindow sizeboxCenterBottom;
84 CSizeboxWindow sizeboxRightBottom;
85 CTextEditWindow textEditWindow;
86
87 /* entry point */
88
89 int WINAPI
90 _tWinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPTSTR lpszArgument, int nFunsterStil)
91 {
92 HWND hwnd; /* This is the handle for our window */
93 MSG messages; /* Here messages to the application are saved */
94
95 HMENU menu;
96 HANDLE haccel;
97
98 TCHAR sfnFilename[1000];
99 TCHAR sfnFiletitle[256];
100 TCHAR ofnFilename[1000];
101 TCHAR ofnFiletitle[256];
102 TCHAR miniaturetitle[100];
103 static int custColors[16] = { 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
104 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff
105 };
106
107 /* init font for text tool */
108 lfTextFont.lfHeight = 0;
109 lfTextFont.lfWidth = 0;
110 lfTextFont.lfEscapement = 0;
111 lfTextFont.lfOrientation = 0;
112 lfTextFont.lfWeight = FW_NORMAL;
113 lfTextFont.lfItalic = FALSE;
114 lfTextFont.lfUnderline = FALSE;
115 lfTextFont.lfStrikeOut = FALSE;
116 lfTextFont.lfCharSet = DEFAULT_CHARSET;
117 lfTextFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
118 lfTextFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
119 lfTextFont.lfQuality = DEFAULT_QUALITY;
120 lfTextFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
121 lstrcpy(lfTextFont.lfFaceName, _T(""));
122 hfontTextFont = CreateFontIndirect(&lfTextFont);
123
124 hProgInstance = hThisInstance;
125
126 /* initialize common controls library */
127 InitCommonControls();
128
129 LoadString(hThisInstance, IDS_DEFAULTFILENAME, filepathname, SIZEOF(filepathname));
130 CPath pathFileName(filepathname);
131 pathFileName.StripPath();
132 CString strTitle;
133 strTitle.Format(IDS_WINDOWTITLE, (LPCTSTR)pathFileName);
134 LoadString(hThisInstance, IDS_MINIATURETITLE, miniaturetitle, SIZEOF(miniaturetitle));
135
136 /* load settings from registry */
137 registrySettings.Load();
138 showMiniature = registrySettings.ShowThumbnail;
139 imageModel.Crop(registrySettings.BMPWidth, registrySettings.BMPHeight);
140
141 /* create main window */
142 RECT mainWindowPos = {0, 0, 544, 375}; // FIXME: use equivalent of CW_USEDEFAULT for position
143 hwnd = mainWindow.Create(HWND_DESKTOP, mainWindowPos, strTitle, WS_OVERLAPPEDWINDOW);
144
145 RECT fullscreenWindowPos = {0, 0, 100, 100};
146 fullscreenWindow.Create(HWND_DESKTOP, fullscreenWindowPos, NULL, WS_POPUPWINDOW | WS_MAXIMIZE);
147
148 RECT miniaturePos = {(LONG) registrySettings.ThumbXPos, (LONG) registrySettings.ThumbYPos,
149 (LONG) registrySettings.ThumbXPos + (LONG) registrySettings.ThumbWidth,
150 (LONG) registrySettings.ThumbYPos + (LONG) registrySettings.ThumbHeight};
151 miniature.Create(hwnd, miniaturePos, miniaturetitle,
152 WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME, WS_EX_PALETTEWINDOW);
153 miniature.ShowWindow(showMiniature ? SW_SHOW : SW_HIDE);
154
155 /* loading and setting the window menu from resource */
156 menu = LoadMenu(hThisInstance, MAKEINTRESOURCE(ID_MENU));
157 SetMenu(hwnd, menu);
158 haccel = LoadAccelerators(hThisInstance, MAKEINTRESOURCE(800));
159
160 /* preloading the draw transparent/nontransparent icons for later use */
161 hNontranspIcon =
162 (HICON) LoadImage(hThisInstance, MAKEINTRESOURCE(IDI_NONTRANSPARENT), IMAGE_ICON, 40, 30, LR_DEFAULTCOLOR);
163 hTranspIcon =
164 (HICON) LoadImage(hThisInstance, MAKEINTRESOURCE(IDI_TRANSPARENT), IMAGE_ICON, 40, 30, LR_DEFAULTCOLOR);
165
166 hCurFill = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_FILL));
167 hCurColor = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_COLOR));
168 hCurZoom = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_ZOOM));
169 hCurPen = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_PEN));
170 hCurAirbrush = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_AIRBRUSH));
171
172 CreateWindowEx(0, _T("STATIC"), NULL, WS_CHILD | WS_VISIBLE | SS_ETCHEDHORZ, 0, 0, 5000, 2, hwnd, NULL,
173 hThisInstance, NULL);
174
175 RECT toolBoxContainerPos = {2, 2, 2 + 52, 2 + 350};
176 toolBoxContainer.Create(hwnd, toolBoxContainerPos, NULL, WS_CHILD | WS_VISIBLE);
177 /* creating the tool settings child window */
178 RECT toolSettingsWindowPos = {5, 208, 5 + 42, 208 + 140};
179 toolSettingsWindow.Create(toolBoxContainer.m_hWnd, toolSettingsWindowPos, NULL, WS_CHILD | WS_VISIBLE);
180
181 /* creating the palette child window */
182 RECT paletteWindowPos = {56, 9, 56 + 255, 9 + 32};
183 paletteWindow.Create(hwnd, paletteWindowPos, NULL, WS_CHILD | WS_VISIBLE);
184
185 /* creating the scroll box */
186 RECT scrollboxWindowPos = {56, 49, 56 + 472, 49 + 248};
187 scrollboxWindow.Create(hwnd, scrollboxWindowPos, NULL,
188 WS_CHILD | WS_GROUP | WS_HSCROLL | WS_VSCROLL | WS_VISIBLE, WS_EX_CLIENTEDGE);
189
190 /* creating the status bar */
191 hStatusBar =
192 CreateWindowEx(0, STATUSCLASSNAME, NULL, SBARS_SIZEGRIP | WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hwnd,
193 NULL, hThisInstance, NULL);
194 SendMessage(hStatusBar, SB_SETMINHEIGHT, 21, 0);
195
196 RECT scrlClientWindowPos = {0, 0, 0 + 500, 0 + 500};
197 scrlClientWindow.Create(scrollboxWindow.m_hWnd, scrlClientWindowPos, NULL, WS_CHILD | WS_VISIBLE);
198
199 /* create selection window (initially hidden) */
200 RECT selectionWindowPos = {350, 0, 350 + 100, 0 + 100};
201 selectionWindow.Create(scrlClientWindow.m_hWnd, selectionWindowPos, NULL, WS_CHILD | BS_OWNERDRAW);
202
203 /* creating the window inside the scroll box, on which the image in hDrawingDC's bitmap is drawn */
204 RECT imageAreaPos = {3, 3, 3 + imageModel.GetWidth(), 3 + imageModel.GetHeight()};
205 imageArea.Create(scrlClientWindow.m_hWnd, imageAreaPos, NULL, WS_CHILD | WS_VISIBLE);
206
207 if (lpszArgument[0] != 0)
208 {
209 HBITMAP bmNew = NULL;
210 LoadDIBFromFile(&bmNew, lpszArgument, &fileTime, &fileSize, &fileHPPM, &fileVPPM);
211 if (bmNew != NULL)
212 {
213 TCHAR *temp;
214 imageModel.Insert(bmNew);
215 GetFullPathName(lpszArgument, SIZEOF(filepathname), filepathname, &temp);
216 CPath pathFileName(filepathname);
217 pathFileName.StripPath();
218 CString strTitle;
219 strTitle.Format(IDS_WINDOWTITLE, (LPCTSTR)pathFileName);
220 mainWindow.SetWindowText(strTitle);
221 imageModel.ClearHistory();
222 isAFile = TRUE;
223 }
224 else
225 {
226 exit(0);
227 }
228 }
229
230 /* initializing the CHOOSECOLOR structure for use with ChooseColor */
231 choosecolor.lStructSize = sizeof(CHOOSECOLOR);
232 choosecolor.hwndOwner = hwnd;
233 choosecolor.hInstance = NULL;
234 choosecolor.rgbResult = 0x00ffffff;
235 choosecolor.lpCustColors = (COLORREF*) &custColors;
236 choosecolor.Flags = 0;
237 choosecolor.lCustData = 0;
238 choosecolor.lpfnHook = NULL;
239 choosecolor.lpTemplateName = NULL;
240
241 /* initializing the OPENFILENAME structure for use with GetOpenFileName and GetSaveFileName */
242 CopyMemory(ofnFilename, filepathname, sizeof(filepathname));
243 CString strImporters;
244 CSimpleArray<GUID> aguidFileTypesI;
245 CString strAllPictureFiles;
246 strAllPictureFiles.LoadString(hThisInstance, IDS_ALLPICTUREFILES);
247 CImage::GetImporterFilterString(strImporters, aguidFileTypesI, strAllPictureFiles, CImage::excludeDefaultLoad, _T('\0'));
248 // CAtlStringW strAllFiles;
249 // strAllFiles.LoadString(hThisInstance, IDS_ALLFILES);
250 // strImporters = strAllFiles + CAtlStringW(_T("|*.*|")).Replace('|', '\0') + strImporters;
251 ZeroMemory(&ofn, sizeof(OPENFILENAME));
252 ofn.lStructSize = sizeof(OPENFILENAME);
253 ofn.hwndOwner = hwnd;
254 ofn.hInstance = hThisInstance;
255 ofn.lpstrFilter = strImporters;
256 ofn.lpstrFile = ofnFilename;
257 ofn.nMaxFile = SIZEOF(ofnFilename);
258 ofn.lpstrFileTitle = ofnFiletitle;
259 ofn.nMaxFileTitle = SIZEOF(ofnFiletitle);
260 ofn.Flags = OFN_HIDEREADONLY;
261
262 CopyMemory(sfnFilename, filepathname, sizeof(filepathname));
263 CString strExporters;
264 CSimpleArray<GUID> aguidFileTypesE;
265 CImage::GetExporterFilterString(strExporters, aguidFileTypesE, NULL, CImage::excludeDefaultSave, _T('\0'));
266 ZeroMemory(&sfn, sizeof(OPENFILENAME));
267 sfn.lStructSize = sizeof(OPENFILENAME);
268 sfn.hwndOwner = hwnd;
269 sfn.hInstance = hThisInstance;
270 sfn.lpstrFilter = strExporters;
271 sfn.lpstrFile = sfnFilename;
272 sfn.nMaxFile = SIZEOF(sfnFilename);
273 sfn.lpstrFileTitle = sfnFiletitle;
274 sfn.nMaxFileTitle = SIZEOF(sfnFiletitle);
275 sfn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
276
277 /* creating the size boxes */
278 RECT sizeboxPos = {0, 0, 0 + 3, 0 + 3};
279 sizeboxLeftTop.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE);
280 sizeboxCenterTop.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE);
281 sizeboxRightTop.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE);
282 sizeboxLeftCenter.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE);
283 sizeboxRightCenter.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE);
284 sizeboxLeftBottom.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE);
285 sizeboxCenterBottom.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE);
286 sizeboxRightBottom.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE);
287 /* placing the size boxes around the image */
288 imageArea.SendMessage(WM_SIZE, 0, 0);
289
290 /* by moving the window, the things in WM_SIZE are done */
291 mainWindow.SetWindowPlacement(&(registrySettings.WindowPlacement));
292
293 /* creating the text editor window for the text tool */
294 RECT textEditWindowPos = {300, 0, 300 + 300, 0 + 200};
295 textEditWindow.Create(hwnd, textEditWindowPos, NULL, WS_OVERLAPPEDWINDOW);
296
297 /* Make the window visible on the screen */
298 ShowWindow (hwnd, nFunsterStil);
299
300 /* inform the system, that the main window accepts dropped files */
301 DragAcceptFiles(hwnd, TRUE);
302
303 /* Run the message loop. It will run until GetMessage() returns 0 */
304 while (GetMessage(&messages, NULL, 0, 0))
305 {
306 TranslateAccelerator(hwnd, (HACCEL) haccel, &messages);
307
308 /* Translate virtual-key messages into character messages */
309 TranslateMessage(&messages);
310 /* Send message to WindowProcedure */
311 DispatchMessage(&messages);
312 }
313
314 /* write back settings to registry */
315 registrySettings.ShowThumbnail = showMiniature;
316 registrySettings.BMPWidth = imageModel.GetWidth();
317 registrySettings.BMPHeight = imageModel.GetHeight();
318 registrySettings.Store();
319
320 /* The program return-value is 0 - The value that PostQuitMessage() gave */
321 return messages.wParam;
322 }