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