2 * PROJECT: PAINT for ReactOS
4 * FILE: base/applications/mspaint/main.cpp
5 * PURPOSE: Initializing everything
6 * PROGRAMMERS: Benedikt Freisen
9 /* INCLUDES *********************************************************/
13 /* FUNCTIONS ********************************************************/
18 ToolsModel toolsModel
;
20 SelectionModel selectionModel
;
25 LPTSTR textToolText
= NULL
;
26 int textToolTextMaxLen
= 0;
28 PaletteModel paletteModel
;
30 RegistrySettings registrySettings
;
32 ImageModel imageModel
;
33 BOOL askBeforeEnlarging
= FALSE
; // TODO: initialize from registry
36 CHOOSECOLOR choosecolor
;
50 HINSTANCE hProgInstance
;
52 TCHAR filepathname
[1000];
59 BOOL showGrid
= FALSE
;
60 BOOL showMiniature
= FALSE
;
62 CMainWindow mainWindow
;
63 CFullscreenWindow fullscreenWindow
;
64 CMiniatureWindow miniature
;
65 CToolBox toolBoxContainer
;
66 CToolSettingsWindow toolSettingsWindow
;
67 CPaletteWindow paletteWindow
;
68 CScrollboxWindow scrollboxWindow
;
69 CScrollboxWindow scrlClientWindow
;
70 CSelectionWindow selectionWindow
;
71 CImgAreaWindow imageArea
;
72 CSizeboxWindow sizeboxLeftTop
;
73 CSizeboxWindow sizeboxCenterTop
;
74 CSizeboxWindow sizeboxRightTop
;
75 CSizeboxWindow sizeboxLeftCenter
;
76 CSizeboxWindow sizeboxRightCenter
;
77 CSizeboxWindow sizeboxLeftBottom
;
78 CSizeboxWindow sizeboxCenterBottom
;
79 CSizeboxWindow sizeboxRightBottom
;
80 CTextEditWindow textEditWindow
;
82 // get file name extension from filter string
84 FileExtFromFilter(LPTSTR pExt
, LPCTSTR pTitle
, OPENFILENAME
*pOFN
)
90 for (LPCTSTR pch
= pOFN
->lpstrFilter
; *pch
; ++nIndex
)
92 pch
+= lstrlen(pch
) + 1;
93 if (pOFN
->nFilterIndex
== nIndex
)
95 for (++pch
; *pch
&& *pch
!= _T(';'); ++pch
)
103 pch
+= lstrlen(pch
) + 1;
108 // Hook procedure for OPENFILENAME to change the file name extension
109 static UINT_PTR APIENTRY
110 OFNHookProc(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
117 pon
= (OFNOTIFY
*)lParam
;
118 if (pon
->hdr
.code
== CDN_TYPECHANGE
)
120 hParent
= GetParent(hwnd
);
121 TCHAR Path
[MAX_PATH
];
122 SendMessage(hParent
, CDM_GETFILEPATH
, SIZEOF(Path
), (LPARAM
)Path
);
123 LPTSTR pchTitle
= _tcsrchr(Path
, _T('\\'));
124 if (pchTitle
== NULL
)
125 pchTitle
= _tcsrchr(Path
, _T('/'));
127 LPTSTR pch
= _tcsrchr((pchTitle
? pchTitle
: Path
), _T('.'));
132 FileExtFromFilter(pch
, pchTitle
, pon
->lpOFN
);
133 SendMessage(hParent
, CDM_SETCONTROLTEXT
, 0x047c, (LPARAM
)pchTitle
);
134 lstrcpyn(pon
->lpOFN
->lpstrFile
, Path
, SIZEOF(pon
->lpOFN
->lpstrFile
));
145 _tWinMain (HINSTANCE hThisInstance
, HINSTANCE hPrevInstance
, LPTSTR lpszArgument
, int nFunsterStil
)
147 HWND hwnd
; /* This is the handle for our window */
148 MSG messages
; /* Here messages to the application are saved */
153 TCHAR sfnFilename
[1000];
154 TCHAR sfnFiletitle
[256];
155 TCHAR ofnFilename
[1000];
156 TCHAR ofnFiletitle
[256];
157 TCHAR miniaturetitle
[100];
158 static int custColors
[16] = { 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
159 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff
162 /* init font for text tool */
163 lfTextFont
.lfHeight
= 0;
164 lfTextFont
.lfWidth
= 0;
165 lfTextFont
.lfEscapement
= 0;
166 lfTextFont
.lfOrientation
= 0;
167 lfTextFont
.lfWeight
= FW_NORMAL
;
168 lfTextFont
.lfItalic
= FALSE
;
169 lfTextFont
.lfUnderline
= FALSE
;
170 lfTextFont
.lfStrikeOut
= FALSE
;
171 lfTextFont
.lfCharSet
= DEFAULT_CHARSET
;
172 lfTextFont
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
173 lfTextFont
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
174 lfTextFont
.lfQuality
= DEFAULT_QUALITY
;
175 lfTextFont
.lfPitchAndFamily
= DEFAULT_PITCH
| FF_DONTCARE
;
176 lstrcpy(lfTextFont
.lfFaceName
, _T(""));
177 hfontTextFont
= CreateFontIndirect(&lfTextFont
);
179 hProgInstance
= hThisInstance
;
181 /* initialize common controls library */
182 InitCommonControls();
184 LoadString(hThisInstance
, IDS_DEFAULTFILENAME
, filepathname
, SIZEOF(filepathname
));
185 CPath
pathFileName(filepathname
);
186 pathFileName
.StripPath();
188 strTitle
.Format(IDS_WINDOWTITLE
, (LPCTSTR
)pathFileName
);
189 LoadString(hThisInstance
, IDS_MINIATURETITLE
, miniaturetitle
, SIZEOF(miniaturetitle
));
191 /* load settings from registry */
192 registrySettings
.Load();
193 showMiniature
= registrySettings
.ShowThumbnail
;
194 imageModel
.Crop(registrySettings
.BMPWidth
, registrySettings
.BMPHeight
);
196 /* create main window */
197 RECT mainWindowPos
= {0, 0, 544, 375}; // FIXME: use equivalent of CW_USEDEFAULT for position
198 hwnd
= mainWindow
.Create(HWND_DESKTOP
, mainWindowPos
, strTitle
, WS_OVERLAPPEDWINDOW
);
200 RECT fullscreenWindowPos
= {0, 0, 100, 100};
201 fullscreenWindow
.Create(HWND_DESKTOP
, fullscreenWindowPos
, NULL
, WS_POPUPWINDOW
| WS_MAXIMIZE
);
203 RECT miniaturePos
= {(LONG
) registrySettings
.ThumbXPos
, (LONG
) registrySettings
.ThumbYPos
,
204 (LONG
) registrySettings
.ThumbXPos
+ (LONG
) registrySettings
.ThumbWidth
,
205 (LONG
) registrySettings
.ThumbYPos
+ (LONG
) registrySettings
.ThumbHeight
};
206 miniature
.Create(hwnd
, miniaturePos
, miniaturetitle
,
207 WS_OVERLAPPED
| WS_CAPTION
| WS_SYSMENU
| WS_THICKFRAME
, WS_EX_PALETTEWINDOW
);
208 miniature
.ShowWindow(showMiniature
? SW_SHOW
: SW_HIDE
);
210 /* loading and setting the window menu from resource */
211 menu
= LoadMenu(hThisInstance
, MAKEINTRESOURCE(ID_MENU
));
213 haccel
= LoadAccelerators(hThisInstance
, MAKEINTRESOURCE(800));
215 /* preloading the draw transparent/nontransparent icons for later use */
217 (HICON
) LoadImage(hThisInstance
, MAKEINTRESOURCE(IDI_NONTRANSPARENT
), IMAGE_ICON
, 40, 30, LR_DEFAULTCOLOR
);
219 (HICON
) LoadImage(hThisInstance
, MAKEINTRESOURCE(IDI_TRANSPARENT
), IMAGE_ICON
, 40, 30, LR_DEFAULTCOLOR
);
221 hCurFill
= LoadIcon(hThisInstance
, MAKEINTRESOURCE(IDC_FILL
));
222 hCurColor
= LoadIcon(hThisInstance
, MAKEINTRESOURCE(IDC_COLOR
));
223 hCurZoom
= LoadIcon(hThisInstance
, MAKEINTRESOURCE(IDC_ZOOM
));
224 hCurPen
= LoadIcon(hThisInstance
, MAKEINTRESOURCE(IDC_PEN
));
225 hCurAirbrush
= LoadIcon(hThisInstance
, MAKEINTRESOURCE(IDC_AIRBRUSH
));
227 CreateWindowEx(0, _T("STATIC"), NULL
, WS_CHILD
| WS_VISIBLE
| SS_ETCHEDHORZ
, 0, 0, 5000, 2, hwnd
, NULL
,
228 hThisInstance
, NULL
);
230 RECT toolBoxContainerPos
= {2, 2, 2 + 52, 2 + 350};
231 toolBoxContainer
.Create(hwnd
, toolBoxContainerPos
, NULL
, WS_CHILD
| WS_VISIBLE
);
232 /* creating the tool settings child window */
233 RECT toolSettingsWindowPos
= {5, 208, 5 + 42, 208 + 140};
234 toolSettingsWindow
.Create(toolBoxContainer
.m_hWnd
, toolSettingsWindowPos
, NULL
, WS_CHILD
| WS_VISIBLE
);
236 /* creating the palette child window */
237 RECT paletteWindowPos
= {56, 9, 56 + 255, 9 + 32};
238 paletteWindow
.Create(hwnd
, paletteWindowPos
, NULL
, WS_CHILD
| WS_VISIBLE
);
240 /* creating the scroll box */
241 RECT scrollboxWindowPos
= {56, 49, 56 + 472, 49 + 248};
242 scrollboxWindow
.Create(hwnd
, scrollboxWindowPos
, NULL
,
243 WS_CHILD
| WS_GROUP
| WS_HSCROLL
| WS_VSCROLL
| WS_VISIBLE
, WS_EX_CLIENTEDGE
);
245 /* creating the status bar */
247 CreateWindowEx(0, STATUSCLASSNAME
, NULL
, SBARS_SIZEGRIP
| WS_CHILD
| WS_VISIBLE
, 0, 0, 0, 0, hwnd
,
248 NULL
, hThisInstance
, NULL
);
249 SendMessage(hStatusBar
, SB_SETMINHEIGHT
, 21, 0);
251 RECT scrlClientWindowPos
= {0, 0, 0 + 500, 0 + 500};
252 scrlClientWindow
.Create(scrollboxWindow
.m_hWnd
, scrlClientWindowPos
, NULL
, WS_CHILD
| WS_VISIBLE
);
254 /* create selection window (initially hidden) */
255 RECT selectionWindowPos
= {350, 0, 350 + 100, 0 + 100};
256 selectionWindow
.Create(scrlClientWindow
.m_hWnd
, selectionWindowPos
, NULL
, WS_CHILD
| BS_OWNERDRAW
);
258 /* creating the window inside the scroll box, on which the image in hDrawingDC's bitmap is drawn */
259 RECT imageAreaPos
= {3, 3, 3 + imageModel
.GetWidth(), 3 + imageModel
.GetHeight()};
260 imageArea
.Create(scrlClientWindow
.m_hWnd
, imageAreaPos
, NULL
, WS_CHILD
| WS_VISIBLE
);
264 HBITMAP bmNew
= NULL
;
265 LoadDIBFromFile(&bmNew
, __targv
[1], &fileTime
, &fileSize
, &fileHPPM
, &fileVPPM
);
269 imageModel
.Insert(bmNew
);
270 GetFullPathName(__targv
[1], SIZEOF(filepathname
), filepathname
, &temp
);
271 CPath
pathFileName(filepathname
);
272 pathFileName
.StripPath();
274 strTitle
.Format(IDS_WINDOWTITLE
, (LPCTSTR
)pathFileName
);
275 mainWindow
.SetWindowText(strTitle
);
276 imageModel
.ClearHistory();
285 /* initializing the CHOOSECOLOR structure for use with ChooseColor */
286 choosecolor
.lStructSize
= sizeof(CHOOSECOLOR
);
287 choosecolor
.hwndOwner
= hwnd
;
288 choosecolor
.hInstance
= NULL
;
289 choosecolor
.rgbResult
= 0x00ffffff;
290 choosecolor
.lpCustColors
= (COLORREF
*) &custColors
;
291 choosecolor
.Flags
= 0;
292 choosecolor
.lCustData
= 0;
293 choosecolor
.lpfnHook
= NULL
;
294 choosecolor
.lpTemplateName
= NULL
;
296 /* initializing the OPENFILENAME structure for use with GetOpenFileName and GetSaveFileName */
297 CopyMemory(ofnFilename
, filepathname
, sizeof(filepathname
));
298 CString strImporters
;
299 CSimpleArray
<GUID
> aguidFileTypesI
;
300 CString strAllPictureFiles
;
301 strAllPictureFiles
.LoadString(hThisInstance
, IDS_ALLPICTUREFILES
);
302 CImage::GetImporterFilterString(strImporters
, aguidFileTypesI
, strAllPictureFiles
, CImage::excludeDefaultLoad
, _T('\0'));
303 // CAtlStringW strAllFiles;
304 // strAllFiles.LoadString(hThisInstance, IDS_ALLFILES);
305 // strImporters = strAllFiles + CAtlStringW(_T("|*.*|")).Replace('|', '\0') + strImporters;
306 ZeroMemory(&ofn
, sizeof(OPENFILENAME
));
307 ofn
.lStructSize
= sizeof(OPENFILENAME
);
308 ofn
.hwndOwner
= hwnd
;
309 ofn
.hInstance
= hThisInstance
;
310 ofn
.lpstrFilter
= strImporters
;
311 ofn
.lpstrFile
= ofnFilename
;
312 ofn
.nMaxFile
= SIZEOF(ofnFilename
);
313 ofn
.lpstrFileTitle
= ofnFiletitle
;
314 ofn
.nMaxFileTitle
= SIZEOF(ofnFiletitle
);
315 ofn
.Flags
= OFN_HIDEREADONLY
;
317 CopyMemory(sfnFilename
, filepathname
, sizeof(filepathname
));
318 CString strExporters
;
319 CSimpleArray
<GUID
> aguidFileTypesE
;
320 CImage::GetExporterFilterString(strExporters
, aguidFileTypesE
, NULL
, CImage::excludeDefaultSave
, _T('\0'));
321 ZeroMemory(&sfn
, sizeof(OPENFILENAME
));
322 sfn
.lStructSize
= sizeof(OPENFILENAME
);
323 sfn
.hwndOwner
= hwnd
;
324 sfn
.hInstance
= hThisInstance
;
325 sfn
.lpstrFilter
= strExporters
;
326 sfn
.lpstrFile
= sfnFilename
;
327 sfn
.nMaxFile
= SIZEOF(sfnFilename
);
328 sfn
.lpstrFileTitle
= sfnFiletitle
;
329 sfn
.nMaxFileTitle
= SIZEOF(sfnFiletitle
);
330 sfn
.Flags
= OFN_OVERWRITEPROMPT
| OFN_HIDEREADONLY
| OFN_EXPLORER
| OFN_ENABLEHOOK
;
331 sfn
.lpfnHook
= OFNHookProc
;
333 /* creating the size boxes */
334 RECT sizeboxPos
= {0, 0, 0 + 3, 0 + 3};
335 sizeboxLeftTop
.Create(scrlClientWindow
.m_hWnd
, sizeboxPos
, NULL
, WS_CHILD
| WS_VISIBLE
);
336 sizeboxCenterTop
.Create(scrlClientWindow
.m_hWnd
, sizeboxPos
, NULL
, WS_CHILD
| WS_VISIBLE
);
337 sizeboxRightTop
.Create(scrlClientWindow
.m_hWnd
, sizeboxPos
, NULL
, WS_CHILD
| WS_VISIBLE
);
338 sizeboxLeftCenter
.Create(scrlClientWindow
.m_hWnd
, sizeboxPos
, NULL
, WS_CHILD
| WS_VISIBLE
);
339 sizeboxRightCenter
.Create(scrlClientWindow
.m_hWnd
, sizeboxPos
, NULL
, WS_CHILD
| WS_VISIBLE
);
340 sizeboxLeftBottom
.Create(scrlClientWindow
.m_hWnd
, sizeboxPos
, NULL
, WS_CHILD
| WS_VISIBLE
);
341 sizeboxCenterBottom
.Create(scrlClientWindow
.m_hWnd
, sizeboxPos
, NULL
, WS_CHILD
| WS_VISIBLE
);
342 sizeboxRightBottom
.Create(scrlClientWindow
.m_hWnd
, sizeboxPos
, NULL
, WS_CHILD
| WS_VISIBLE
);
343 /* placing the size boxes around the image */
344 imageArea
.SendMessage(WM_SIZE
, 0, 0);
346 /* by moving the window, the things in WM_SIZE are done */
347 mainWindow
.SetWindowPlacement(&(registrySettings
.WindowPlacement
));
349 /* creating the text editor window for the text tool */
350 RECT textEditWindowPos
= {300, 0, 300 + 300, 0 + 200};
351 textEditWindow
.Create(hwnd
, textEditWindowPos
, NULL
, WS_OVERLAPPEDWINDOW
);
353 /* Make the window visible on the screen */
354 ShowWindow (hwnd
, nFunsterStil
);
356 /* inform the system, that the main window accepts dropped files */
357 DragAcceptFiles(hwnd
, TRUE
);
359 /* Run the message loop. It will run until GetMessage() returns 0 */
360 while (GetMessage(&messages
, NULL
, 0, 0))
362 TranslateAccelerator(hwnd
, haccel
, &messages
);
364 /* Translate virtual-key messages into character messages */
365 TranslateMessage(&messages
);
366 /* Send message to WindowProcedure */
367 DispatchMessage(&messages
);
370 /* write back settings to registry */
371 registrySettings
.ShowThumbnail
= showMiniature
;
372 registrySettings
.BMPWidth
= imageModel
.GetWidth();
373 registrySettings
.BMPHeight
= imageModel
.GetHeight();
374 registrySettings
.Store();
376 /* The program return-value is 0 - The value that PostQuitMessage() gave */
377 return messages
.wParam
;