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 // get file name extension from filter string 88 static BOOL 89 FileExtFromFilter(LPTSTR pExt, LPCTSTR pTitle, OPENFILENAME *pOFN) 90 { 91 LPTSTR pchExt = pExt; 92 *pchExt = 0; 93 94 DWORD nIndex = 1; 95 for (LPCTSTR pch = pOFN->lpstrFilter; *pch; ++nIndex) 96 { 97 pch += lstrlen(pch) + 1; 98 if (pOFN->nFilterIndex == nIndex) 99 { 100 for (++pch; *pch && *pch != _T(';'); ++pch) 101 { 102 *pchExt++ = *pch; 103 } 104 *pchExt = 0; 105 CharLower(pExt); 106 return TRUE; 107 } 108 pch += lstrlen(pch) + 1; 109 } 110 return FALSE; 111 } 112 113 // Hook procedure for OPENFILENAME to change the file name extension 114 static UINT_PTR APIENTRY 115 OFNHookProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 116 { 117 HWND hParent; 118 OFNOTIFY *pon; 119 switch (uMsg) 120 { 121 case WM_NOTIFY: 122 pon = (OFNOTIFY *)lParam; 123 if (pon->hdr.code == CDN_TYPECHANGE) 124 { 125 hParent = GetParent(hwnd); 126 TCHAR Path[MAX_PATH]; 127 SendMessage(hParent, CDM_GETFILEPATH, SIZEOF(Path), (LPARAM)Path); 128 LPTSTR pchTitle = _tcsrchr(Path, _T('\\')); 129 if (pchTitle == NULL) 130 pchTitle = _tcsrchr(Path, _T('/')); 131 132 LPTSTR pch = _tcsrchr((pchTitle ? pchTitle : Path), _T('.')); 133 if (pch && pchTitle) 134 { 135 pchTitle++; 136 *pch = 0; 137 FileExtFromFilter(pch, pchTitle, pon->lpOFN); 138 SendMessage(hParent, CDM_SETCONTROLTEXT, 0x047c, (LPARAM)pchTitle); 139 lstrcpyn(pon->lpOFN->lpstrFile, Path, SIZEOF(pon->lpOFN->lpstrFile)); 140 } 141 } 142 break; 143 } 144 return 0; 145 } 146 147 /* entry point */ 148 149 int WINAPI 150 _tWinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPTSTR lpszArgument, int nFunsterStil) 151 { 152 HWND hwnd; /* This is the handle for our window */ 153 MSG messages; /* Here messages to the application are saved */ 154 155 HMENU menu; 156 HACCEL haccel; 157 158 TCHAR sfnFilename[1000]; 159 TCHAR sfnFiletitle[256]; 160 TCHAR ofnFilename[1000]; 161 TCHAR ofnFiletitle[256]; 162 TCHAR miniaturetitle[100]; 163 static int custColors[16] = { 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 164 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff 165 }; 166 167 /* init font for text tool */ 168 lfTextFont.lfHeight = 0; 169 lfTextFont.lfWidth = 0; 170 lfTextFont.lfEscapement = 0; 171 lfTextFont.lfOrientation = 0; 172 lfTextFont.lfWeight = FW_NORMAL; 173 lfTextFont.lfItalic = FALSE; 174 lfTextFont.lfUnderline = FALSE; 175 lfTextFont.lfStrikeOut = FALSE; 176 lfTextFont.lfCharSet = DEFAULT_CHARSET; 177 lfTextFont.lfOutPrecision = OUT_DEFAULT_PRECIS; 178 lfTextFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; 179 lfTextFont.lfQuality = DEFAULT_QUALITY; 180 lfTextFont.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; 181 lstrcpy(lfTextFont.lfFaceName, _T("")); 182 hfontTextFont = CreateFontIndirect(&lfTextFont); 183 184 hProgInstance = hThisInstance; 185 186 /* initialize common controls library */ 187 InitCommonControls(); 188 189 LoadString(hThisInstance, IDS_DEFAULTFILENAME, filepathname, SIZEOF(filepathname)); 190 CPath pathFileName(filepathname); 191 pathFileName.StripPath(); 192 CString strTitle; 193 strTitle.Format(IDS_WINDOWTITLE, (LPCTSTR)pathFileName); 194 LoadString(hThisInstance, IDS_MINIATURETITLE, miniaturetitle, SIZEOF(miniaturetitle)); 195 196 /* load settings from registry */ 197 registrySettings.Load(); 198 showMiniature = registrySettings.ShowThumbnail; 199 imageModel.Crop(registrySettings.BMPWidth, registrySettings.BMPHeight); 200 201 /* create main window */ 202 RECT mainWindowPos = {0, 0, 544, 375}; // FIXME: use equivalent of CW_USEDEFAULT for position 203 hwnd = mainWindow.Create(HWND_DESKTOP, mainWindowPos, strTitle, WS_OVERLAPPEDWINDOW); 204 205 RECT fullscreenWindowPos = {0, 0, 100, 100}; 206 fullscreenWindow.Create(HWND_DESKTOP, fullscreenWindowPos, NULL, WS_POPUPWINDOW | WS_MAXIMIZE); 207 208 RECT miniaturePos = {(LONG) registrySettings.ThumbXPos, (LONG) registrySettings.ThumbYPos, 209 (LONG) registrySettings.ThumbXPos + (LONG) registrySettings.ThumbWidth, 210 (LONG) registrySettings.ThumbYPos + (LONG) registrySettings.ThumbHeight}; 211 miniature.Create(hwnd, miniaturePos, miniaturetitle, 212 WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME, WS_EX_PALETTEWINDOW); 213 miniature.ShowWindow(showMiniature ? SW_SHOW : SW_HIDE); 214 215 /* loading and setting the window menu from resource */ 216 menu = LoadMenu(hThisInstance, MAKEINTRESOURCE(ID_MENU)); 217 SetMenu(hwnd, menu); 218 haccel = LoadAccelerators(hThisInstance, MAKEINTRESOURCE(800)); 219 220 /* preloading the draw transparent/nontransparent icons for later use */ 221 hNontranspIcon = 222 (HICON) LoadImage(hThisInstance, MAKEINTRESOURCE(IDI_NONTRANSPARENT), IMAGE_ICON, 40, 30, LR_DEFAULTCOLOR); 223 hTranspIcon = 224 (HICON) LoadImage(hThisInstance, MAKEINTRESOURCE(IDI_TRANSPARENT), IMAGE_ICON, 40, 30, LR_DEFAULTCOLOR); 225 226 hCurFill = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_FILL)); 227 hCurColor = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_COLOR)); 228 hCurZoom = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_ZOOM)); 229 hCurPen = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_PEN)); 230 hCurAirbrush = LoadIcon(hThisInstance, MAKEINTRESOURCE(IDC_AIRBRUSH)); 231 232 CreateWindowEx(0, _T("STATIC"), NULL, WS_CHILD | WS_VISIBLE | SS_ETCHEDHORZ, 0, 0, 5000, 2, hwnd, NULL, 233 hThisInstance, NULL); 234 235 RECT toolBoxContainerPos = {2, 2, 2 + 52, 2 + 350}; 236 toolBoxContainer.Create(hwnd, toolBoxContainerPos, NULL, WS_CHILD | WS_VISIBLE); 237 /* creating the tool settings child window */ 238 RECT toolSettingsWindowPos = {5, 208, 5 + 42, 208 + 140}; 239 toolSettingsWindow.Create(toolBoxContainer.m_hWnd, toolSettingsWindowPos, NULL, WS_CHILD | WS_VISIBLE); 240 241 /* creating the palette child window */ 242 RECT paletteWindowPos = {56, 9, 56 + 255, 9 + 32}; 243 paletteWindow.Create(hwnd, paletteWindowPos, NULL, WS_CHILD | WS_VISIBLE); 244 245 /* creating the scroll box */ 246 RECT scrollboxWindowPos = {56, 49, 56 + 472, 49 + 248}; 247 scrollboxWindow.Create(hwnd, scrollboxWindowPos, NULL, 248 WS_CHILD | WS_GROUP | WS_HSCROLL | WS_VSCROLL | WS_VISIBLE, WS_EX_CLIENTEDGE); 249 250 /* creating the status bar */ 251 hStatusBar = 252 CreateWindowEx(0, STATUSCLASSNAME, NULL, SBARS_SIZEGRIP | WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hwnd, 253 NULL, hThisInstance, NULL); 254 SendMessage(hStatusBar, SB_SETMINHEIGHT, 21, 0); 255 256 RECT scrlClientWindowPos = {0, 0, 0 + 500, 0 + 500}; 257 scrlClientWindow.Create(scrollboxWindow.m_hWnd, scrlClientWindowPos, NULL, WS_CHILD | WS_VISIBLE); 258 259 /* create selection window (initially hidden) */ 260 RECT selectionWindowPos = {350, 0, 350 + 100, 0 + 100}; 261 selectionWindow.Create(scrlClientWindow.m_hWnd, selectionWindowPos, NULL, WS_CHILD | BS_OWNERDRAW); 262 263 /* creating the window inside the scroll box, on which the image in hDrawingDC's bitmap is drawn */ 264 RECT imageAreaPos = {3, 3, 3 + imageModel.GetWidth(), 3 + imageModel.GetHeight()}; 265 imageArea.Create(scrlClientWindow.m_hWnd, imageAreaPos, NULL, WS_CHILD | WS_VISIBLE); 266 267 if (lpszArgument[0] != 0) 268 { 269 HBITMAP bmNew = NULL; 270 LoadDIBFromFile(&bmNew, lpszArgument, &fileTime, &fileSize, &fileHPPM, &fileVPPM); 271 if (bmNew != NULL) 272 { 273 TCHAR *temp; 274 imageModel.Insert(bmNew); 275 GetFullPathName(lpszArgument, SIZEOF(filepathname), filepathname, &temp); 276 CPath pathFileName(filepathname); 277 pathFileName.StripPath(); 278 CString strTitle; 279 strTitle.Format(IDS_WINDOWTITLE, (LPCTSTR)pathFileName); 280 mainWindow.SetWindowText(strTitle); 281 imageModel.ClearHistory(); 282 isAFile = TRUE; 283 } 284 else 285 { 286 exit(0); 287 } 288 } 289 290 /* initializing the CHOOSECOLOR structure for use with ChooseColor */ 291 choosecolor.lStructSize = sizeof(CHOOSECOLOR); 292 choosecolor.hwndOwner = hwnd; 293 choosecolor.hInstance = NULL; 294 choosecolor.rgbResult = 0x00ffffff; 295 choosecolor.lpCustColors = (COLORREF*) &custColors; 296 choosecolor.Flags = 0; 297 choosecolor.lCustData = 0; 298 choosecolor.lpfnHook = NULL; 299 choosecolor.lpTemplateName = NULL; 300 301 /* initializing the OPENFILENAME structure for use with GetOpenFileName and GetSaveFileName */ 302 CopyMemory(ofnFilename, filepathname, sizeof(filepathname)); 303 CString strImporters; 304 CSimpleArray<GUID> aguidFileTypesI; 305 CString strAllPictureFiles; 306 strAllPictureFiles.LoadString(hThisInstance, IDS_ALLPICTUREFILES); 307 CImage::GetImporterFilterString(strImporters, aguidFileTypesI, strAllPictureFiles, CImage::excludeDefaultLoad, _T('\0')); 308 // CAtlStringW strAllFiles; 309 // strAllFiles.LoadString(hThisInstance, IDS_ALLFILES); 310 // strImporters = strAllFiles + CAtlStringW(_T("|*.*|")).Replace('|', '\0') + strImporters; 311 ZeroMemory(&ofn, sizeof(OPENFILENAME)); 312 ofn.lStructSize = sizeof(OPENFILENAME); 313 ofn.hwndOwner = hwnd; 314 ofn.hInstance = hThisInstance; 315 ofn.lpstrFilter = strImporters; 316 ofn.lpstrFile = ofnFilename; 317 ofn.nMaxFile = SIZEOF(ofnFilename); 318 ofn.lpstrFileTitle = ofnFiletitle; 319 ofn.nMaxFileTitle = SIZEOF(ofnFiletitle); 320 ofn.Flags = OFN_HIDEREADONLY; 321 322 CopyMemory(sfnFilename, filepathname, sizeof(filepathname)); 323 CString strExporters; 324 CSimpleArray<GUID> aguidFileTypesE; 325 CImage::GetExporterFilterString(strExporters, aguidFileTypesE, NULL, CImage::excludeDefaultSave, _T('\0')); 326 ZeroMemory(&sfn, sizeof(OPENFILENAME)); 327 sfn.lStructSize = sizeof(OPENFILENAME); 328 sfn.hwndOwner = hwnd; 329 sfn.hInstance = hThisInstance; 330 sfn.lpstrFilter = strExporters; 331 sfn.lpstrFile = sfnFilename; 332 sfn.nMaxFile = SIZEOF(sfnFilename); 333 sfn.lpstrFileTitle = sfnFiletitle; 334 sfn.nMaxFileTitle = SIZEOF(sfnFiletitle); 335 sfn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_EXPLORER | OFN_ENABLEHOOK; 336 sfn.lpfnHook = OFNHookProc; 337 338 /* creating the size boxes */ 339 RECT sizeboxPos = {0, 0, 0 + 3, 0 + 3}; 340 sizeboxLeftTop.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); 341 sizeboxCenterTop.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); 342 sizeboxRightTop.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); 343 sizeboxLeftCenter.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); 344 sizeboxRightCenter.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); 345 sizeboxLeftBottom.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); 346 sizeboxCenterBottom.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); 347 sizeboxRightBottom.Create(scrlClientWindow.m_hWnd, sizeboxPos, NULL, WS_CHILD | WS_VISIBLE); 348 /* placing the size boxes around the image */ 349 imageArea.SendMessage(WM_SIZE, 0, 0); 350 351 /* by moving the window, the things in WM_SIZE are done */ 352 mainWindow.SetWindowPlacement(&(registrySettings.WindowPlacement)); 353 354 /* creating the text editor window for the text tool */ 355 RECT textEditWindowPos = {300, 0, 300 + 300, 0 + 200}; 356 textEditWindow.Create(hwnd, textEditWindowPos, NULL, WS_OVERLAPPEDWINDOW); 357 358 /* Make the window visible on the screen */ 359 ShowWindow (hwnd, nFunsterStil); 360 361 /* inform the system, that the main window accepts dropped files */ 362 DragAcceptFiles(hwnd, TRUE); 363 364 /* Run the message loop. It will run until GetMessage() returns 0 */ 365 while (GetMessage(&messages, NULL, 0, 0)) 366 { 367 TranslateAccelerator(hwnd, haccel, &messages); 368 369 /* Translate virtual-key messages into character messages */ 370 TranslateMessage(&messages); 371 /* Send message to WindowProcedure */ 372 DispatchMessage(&messages); 373 } 374 375 /* write back settings to registry */ 376 registrySettings.ShowThumbnail = showMiniature; 377 registrySettings.BMPWidth = imageModel.GetWidth(); 378 registrySettings.BMPHeight = imageModel.GetHeight(); 379 registrySettings.Store(); 380 381 /* The program return-value is 0 - The value that PostQuitMessage() gave */ 382 return messages.wParam; 383 } 384