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 POINT start; 16 POINT last; 17 18 ToolsModel toolsModel; 19 20 SelectionModel selectionModel; 21 22 LOGFONT lfTextFont; 23 HFONT hfontTextFont; 24 HWND hwndEditCtl; 25 LPTSTR textToolText = NULL; 26 int textToolTextMaxLen = 0; 27 28 PaletteModel paletteModel; 29 30 RegistrySettings registrySettings; 31 32 ImageModel imageModel; 33 BOOL askBeforeEnlarging = FALSE; // TODO: initialize from registry 34 35 HWND hStatusBar; 36 CHOOSECOLOR choosecolor; 37 OPENFILENAME ofn; 38 OPENFILENAME sfn; 39 HICON hNontranspIcon; 40 HICON hTranspIcon; 41 42 HCURSOR hCurFill; 43 HCURSOR hCurColor; 44 HCURSOR hCurZoom; 45 HCURSOR hCurPen; 46 HCURSOR hCurAirbrush; 47 48 HWND hToolBtn[16]; 49 50 HINSTANCE hProgInstance; 51 52 TCHAR filepathname[1000]; 53 BOOL isAFile = FALSE; 54 int fileSize; 55 int fileHPPM = 2834; 56 int fileVPPM = 2834; 57 SYSTEMTIME fileTime; 58 59 BOOL showGrid = FALSE; 60 BOOL showMiniature = FALSE; 61 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; 81 82 // get file name extension from filter string 83 static BOOL 84 FileExtFromFilter(LPTSTR pExt, LPCTSTR pTitle, OPENFILENAME *pOFN) 85 { 86 LPTSTR pchExt = pExt; 87 *pchExt = 0; 88 89 DWORD nIndex = 1; 90 for (LPCTSTR pch = pOFN->lpstrFilter; *pch; ++nIndex) 91 { 92 pch += lstrlen(pch) + 1; 93 if (pOFN->nFilterIndex == nIndex) 94 { 95 for (++pch; *pch && *pch != _T(';'); ++pch) 96 { 97 *pchExt++ = *pch; 98 } 99 *pchExt = 0; 100 CharLower(pExt); 101 return TRUE; 102 } 103 pch += lstrlen(pch) + 1; 104 } 105 return FALSE; 106 } 107 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) 111 { 112 HWND hParent; 113 OFNOTIFY *pon; 114 switch (uMsg) 115 { 116 case WM_NOTIFY: 117 pon = (OFNOTIFY *)lParam; 118 if (pon->hdr.code == CDN_TYPECHANGE) 119 { 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('/')); 126 127 LPTSTR pch = _tcsrchr((pchTitle ? pchTitle : Path), _T('.')); 128 if (pch && pchTitle) 129 { 130 pchTitle++; 131 *pch = 0; 132 FileExtFromFilter(pch, pchTitle, pon->lpOFN); 133 SendMessage(hParent, CDM_SETCONTROLTEXT, 0x047c, (LPARAM)pchTitle); 134 lstrcpyn(pon->lpOFN->lpstrFile, Path, SIZEOF(pon->lpOFN->lpstrFile)); 135 } 136 } 137 break; 138 } 139 return 0; 140 } 141 142 /* entry point */ 143 144 int WINAPI 145 _tWinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPTSTR lpszArgument, int nFunsterStil) 146 { 147 HWND hwnd; /* This is the handle for our window */ 148 MSG messages; /* Here messages to the application are saved */ 149 150 HMENU menu; 151 HACCEL haccel; 152 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 160 }; 161 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); 178 179 hProgInstance = hThisInstance; 180 181 /* initialize common controls library */ 182 InitCommonControls(); 183 184 LoadString(hThisInstance, IDS_DEFAULTFILENAME, filepathname, SIZEOF(filepathname)); 185 CPath pathFileName(filepathname); 186 pathFileName.StripPath(); 187 CString strTitle; 188 strTitle.Format(IDS_WINDOWTITLE, (LPCTSTR)pathFileName); 189 LoadString(hThisInstance, IDS_MINIATURETITLE, miniaturetitle, SIZEOF(miniaturetitle)); 190 191 /* load settings from registry */ 192 registrySettings.Load(); 193 showMiniature = registrySettings.ShowThumbnail; 194 imageModel.Crop(registrySettings.BMPWidth, registrySettings.BMPHeight); 195 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); 199 200 RECT fullscreenWindowPos = {0, 0, 100, 100}; 201 fullscreenWindow.Create(HWND_DESKTOP, fullscreenWindowPos, NULL, WS_POPUPWINDOW | WS_MAXIMIZE); 202 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); 209 210 /* loading and setting the window menu from resource */ 211 menu = LoadMenu(hThisInstance, MAKEINTRESOURCE(ID_MENU)); 212 SetMenu(hwnd, menu); 213 haccel = LoadAccelerators(hThisInstance, MAKEINTRESOURCE(800)); 214 215 /* preloading the draw transparent/nontransparent icons for later use */ 216 hNontranspIcon = 217 (HICON) LoadImage(hThisInstance, MAKEINTRESOURCE(IDI_NONTRANSPARENT), IMAGE_ICON, 40, 30, LR_DEFAULTCOLOR); 218 hTranspIcon = 219 (HICON) LoadImage(hThisInstance, MAKEINTRESOURCE(IDI_TRANSPARENT), IMAGE_ICON, 40, 30, LR_DEFAULTCOLOR); 220 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)); 226 227 CreateWindowEx(0, _T("STATIC"), NULL, WS_CHILD | WS_VISIBLE | SS_ETCHEDHORZ, 0, 0, 5000, 2, hwnd, NULL, 228 hThisInstance, NULL); 229 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); 235 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); 239 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); 244 245 /* creating the status bar */ 246 hStatusBar = 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); 250 251 RECT scrlClientWindowPos = {0, 0, 0 + 500, 0 + 500}; 252 scrlClientWindow.Create(scrollboxWindow.m_hWnd, scrlClientWindowPos, NULL, WS_CHILD | WS_VISIBLE); 253 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); 257 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); 261 262 if (__argc >= 2) 263 { 264 WIN32_FIND_DATAW find; 265 HANDLE hFind = FindFirstFileW(__targv[1], &find); 266 if (hFind != INVALID_HANDLE_VALUE) 267 { 268 FindClose(hFind); 269 270 // check the file size 271 if (find.nFileSizeHigh || find.nFileSizeLow) 272 { 273 // load it now 274 HBITMAP bmNew = NULL; 275 LoadDIBFromFile(&bmNew, __targv[1], &fileTime, &fileSize, &fileHPPM, &fileVPPM); 276 if (bmNew) 277 { 278 // valid bitmap file 279 GetFullPathName(__targv[1], SIZEOF(filepathname), filepathname, NULL); 280 imageModel.Insert(bmNew); 281 CPath pathFileName(filepathname); 282 pathFileName.StripPath(); 283 284 CString strTitle; 285 strTitle.Format(IDS_WINDOWTITLE, (LPCTSTR)pathFileName); 286 mainWindow.SetWindowText(strTitle); 287 288 imageModel.ClearHistory(); 289 290 isAFile = TRUE; 291 registrySettings.SetMostRecentFile(filepathname); 292 } 293 else 294 { 295 // cannot open and not empty 296 CStringW strText; 297 strText.Format(IDS_LOADERRORTEXT, __targv[1]); 298 MessageBoxW(NULL, strText, NULL, MB_ICONERROR); 299 } 300 } 301 else 302 { 303 // open the empty file 304 GetFullPathName(__targv[1], SIZEOF(filepathname), filepathname, NULL); 305 CPath pathFileName(filepathname); 306 pathFileName.StripPath(); 307 308 CString strTitle; 309 strTitle.Format(IDS_WINDOWTITLE, (LPCTSTR)pathFileName); 310 mainWindow.SetWindowText(strTitle); 311 312 imageModel.ClearHistory(); 313 314 isAFile = TRUE; 315 registrySettings.SetMostRecentFile(filepathname); 316 } 317 } 318 else 319 { 320 // does not exist 321 CStringW strText; 322 strText.Format(IDS_LOADERRORTEXT, __targv[1]); 323 MessageBoxW(NULL, strText, NULL, MB_ICONERROR); 324 } 325 } 326 327 /* initializing the CHOOSECOLOR structure for use with ChooseColor */ 328 choosecolor.lStructSize = sizeof(CHOOSECOLOR); 329 choosecolor.hwndOwner = hwnd; 330 choosecolor.hInstance = NULL; 331 choosecolor.rgbResult = 0x00ffffff; 332 choosecolor.lpCustColors = (COLORREF*) &custColors; 333 choosecolor.Flags = 0; 334 choosecolor.lCustData = 0; 335 choosecolor.lpfnHook = NULL; 336 choosecolor.lpTemplateName = NULL; 337 338 /* initializing the OPENFILENAME structure for use with GetOpenFileName and GetSaveFileName */ 339 CopyMemory(ofnFilename, filepathname, sizeof(filepathname)); 340 CString strImporters; 341 CSimpleArray<GUID> aguidFileTypesI; 342 CString strAllPictureFiles; 343 strAllPictureFiles.LoadString(hThisInstance, IDS_ALLPICTUREFILES); 344 CImage::GetImporterFilterString(strImporters, aguidFileTypesI, strAllPictureFiles, CImage::excludeDefaultLoad, _T('\0')); 345 // CAtlStringW strAllFiles; 346 // strAllFiles.LoadString(hThisInstance, IDS_ALLFILES); 347 // strImporters = strAllFiles + CAtlStringW(_T("|*.*|")).Replace('|', '\0') + strImporters; 348 ZeroMemory(&ofn, sizeof(OPENFILENAME)); 349 ofn.lStructSize = sizeof(OPENFILENAME); 350 ofn.hwndOwner = hwnd; 351 ofn.hInstance = hThisInstance; 352 ofn.lpstrFilter = strImporters; 353 ofn.lpstrFile = ofnFilename; 354 ofn.nMaxFile = SIZEOF(ofnFilename); 355 ofn.lpstrFileTitle = ofnFiletitle; 356 ofn.nMaxFileTitle = SIZEOF(ofnFiletitle); 357 ofn.Flags = OFN_HIDEREADONLY; 358 359 CopyMemory(sfnFilename, filepathname, sizeof(filepathname)); 360 CString strExporters; 361 CSimpleArray<GUID> aguidFileTypesE; 362 CImage::GetExporterFilterString(strExporters, aguidFileTypesE, NULL, CImage::excludeDefaultSave, _T('\0')); 363 ZeroMemory(&sfn, sizeof(OPENFILENAME)); 364 sfn.lStructSize = sizeof(OPENFILENAME); 365 sfn.hwndOwner = hwnd; 366 sfn.hInstance = hThisInstance; 367 sfn.lpstrFilter = strExporters; 368 sfn.lpstrFile = sfnFilename; 369 sfn.nMaxFile = SIZEOF(sfnFilename); 370 sfn.lpstrFileTitle = sfnFiletitle; 371 sfn.nMaxFileTitle = SIZEOF(sfnFiletitle); 372 sfn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_EXPLORER | OFN_ENABLEHOOK; 373 sfn.lpfnHook = OFNHookProc; 374 375 /* creating the size boxes */ 376 RECT sizeboxPos = {0, 0, 0 + 3, 0 + 3}; 377 sizeboxLeftTop.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); 378 sizeboxCenterTop.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); 379 sizeboxRightTop.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); 380 sizeboxLeftCenter.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); 381 sizeboxRightCenter.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); 382 sizeboxLeftBottom.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); 383 sizeboxCenterBottom.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); 384 sizeboxRightBottom.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); 385 /* placing the size boxes around the image */ 386 imageArea.SendMessage(WM_SIZE, 0, 0); 387 388 /* by moving the window, the things in WM_SIZE are done */ 389 mainWindow.SetWindowPlacement(&(registrySettings.WindowPlacement)); 390 391 /* creating the text editor window for the text tool */ 392 RECT textEditWindowPos = {300, 0, 300 + 300, 0 + 200}; 393 textEditWindow.Create(hwnd, textEditWindowPos, NULL, WS_OVERLAPPEDWINDOW); 394 395 /* Make the window visible on the screen */ 396 ShowWindow (hwnd, nFunsterStil); 397 398 /* inform the system, that the main window accepts dropped files */ 399 DragAcceptFiles(hwnd, TRUE); 400 401 /* Run the message loop. It will run until GetMessage() returns 0 */ 402 while (GetMessage(&messages, NULL, 0, 0)) 403 { 404 TranslateAccelerator(hwnd, haccel, &messages); 405 406 /* Translate virtual-key messages into character messages */ 407 TranslateMessage(&messages); 408 /* Send message to WindowProcedure */ 409 DispatchMessage(&messages); 410 } 411 412 /* write back settings to registry */ 413 registrySettings.ShowThumbnail = showMiniature; 414 registrySettings.BMPWidth = imageModel.GetWidth(); 415 registrySettings.BMPHeight = imageModel.GetHeight(); 416 registrySettings.Store(); 417 418 /* The program return-value is 0 - The value that PostQuitMessage() gave */ 419 return messages.wParam; 420 } 421