reactos/base/applications/mspaint/main.cpp
Stanislav Motylkov 8f1f1c7a5a [MSPAINT] Update copyright headers
Use LGPL-2.0-or-later as the first available LGPL version on SPDX
taking into account 530512f17e commit message.

CORE-18867
2023-06-23 20:49:28 +03:00

246 lines
7.1 KiB
C++

/*
* PROJECT: PAINT for ReactOS
* LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
* PURPOSE: Initializing everything
* COPYRIGHT: Copyright 2009 Benedikt Freisen <b.freisen@gmx.net>
*/
#include "precomp.h"
POINT g_ptStart, g_ptEnd;
BOOL g_askBeforeEnlarging = FALSE; // TODO: initialize from registry
HINSTANCE g_hinstExe = NULL;
TCHAR g_szFileName[MAX_LONG_PATH] = { 0 };
BOOL g_isAFile = FALSE;
BOOL g_imageSaved = FALSE;
BOOL g_showGrid = FALSE;
CMainWindow mainWindow;
/* FUNCTIONS ********************************************************/
// get file name extension from filter string
static BOOL
FileExtFromFilter(LPTSTR pExt, OPENFILENAME *pOFN)
{
LPTSTR pchExt = pExt;
*pchExt = 0;
DWORD nIndex = 1;
for (LPCTSTR pch = pOFN->lpstrFilter; *pch; ++nIndex)
{
pch += lstrlen(pch) + 1;
if (pOFN->nFilterIndex == nIndex)
{
for (++pch; *pch && *pch != _T(';'); ++pch)
{
*pchExt++ = *pch;
}
*pchExt = 0;
CharLower(pExt);
return TRUE;
}
pch += lstrlen(pch) + 1;
}
return FALSE;
}
// Hook procedure for OPENFILENAME to change the file name extension
static UINT_PTR APIENTRY
OFNHookProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HWND hParent;
OFNOTIFY *pon;
switch (uMsg)
{
case WM_NOTIFY:
pon = (OFNOTIFY *)lParam;
if (pon->hdr.code == CDN_TYPECHANGE)
{
hParent = GetParent(hwnd);
TCHAR Path[MAX_PATH];
SendMessage(hParent, CDM_GETFILEPATH, _countof(Path), (LPARAM)Path);
FileExtFromFilter(PathFindExtension(Path), pon->lpOFN);
SendMessage(hParent, CDM_SETCONTROLTEXT, 0x047c, (LPARAM)PathFindFileName(Path));
lstrcpyn(pon->lpOFN->lpstrFile, Path, pon->lpOFN->nMaxFile);
}
break;
}
return 0;
}
BOOL CMainWindow::GetOpenFileName(IN OUT LPTSTR pszFile, INT cchMaxFile)
{
static OPENFILENAME ofn = { 0 };
static CString strFilter;
if (ofn.lStructSize == 0)
{
// The "All Files" item text
CString strAllPictureFiles;
strAllPictureFiles.LoadString(g_hinstExe, IDS_ALLPICTUREFILES);
// Get the import filter
CSimpleArray<GUID> aguidFileTypesI;
CImage::GetImporterFilterString(strFilter, aguidFileTypesI, strAllPictureFiles,
CImage::excludeDefaultLoad, _T('\0'));
// Initializing the OPENFILENAME structure for GetOpenFileName
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = m_hWnd;
ofn.hInstance = g_hinstExe;
ofn.lpstrFilter = strFilter;
ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY;
ofn.lpstrDefExt = L"png";
}
ofn.lpstrFile = pszFile;
ofn.nMaxFile = cchMaxFile;
return ::GetOpenFileName(&ofn);
}
BOOL CMainWindow::GetSaveFileName(IN OUT LPTSTR pszFile, INT cchMaxFile)
{
static OPENFILENAME sfn = { 0 };
static CString strFilter;
if (sfn.lStructSize == 0)
{
// Get the export filter
CSimpleArray<GUID> aguidFileTypesE;
CImage::GetExporterFilterString(strFilter, aguidFileTypesE, NULL,
CImage::excludeDefaultSave, _T('\0'));
// Initializing the OPENFILENAME structure for GetSaveFileName
ZeroMemory(&sfn, sizeof(sfn));
sfn.lStructSize = sizeof(sfn);
sfn.hwndOwner = m_hWnd;
sfn.hInstance = g_hinstExe;
sfn.lpstrFilter = strFilter;
sfn.Flags = OFN_EXPLORER | OFN_OVERWRITEPROMPT | OFN_ENABLEHOOK;
sfn.lpfnHook = OFNHookProc;
sfn.lpstrDefExt = L"png";
LPWSTR pchDotExt = PathFindExtensionW(pszFile);
if (*pchDotExt == UNICODE_NULL)
{
// Choose PNG
wcscat(pszFile, L".png");
for (INT i = 0; i < aguidFileTypesE.GetSize(); ++i)
{
if (aguidFileTypesE[i] == Gdiplus::ImageFormatPNG)
{
sfn.nFilterIndex = i + 1;
break;
}
}
}
}
sfn.lpstrFile = pszFile;
sfn.nMaxFile = cchMaxFile;
return ::GetSaveFileName(&sfn);
}
BOOL CMainWindow::ChooseColor(IN OUT COLORREF *prgbColor)
{
static CHOOSECOLOR choosecolor = { 0 };
static COLORREF custColors[16] =
{
0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff
};
if (choosecolor.lStructSize == 0)
{
// Initializing the CHOOSECOLOR structure for ChooseColor
ZeroMemory(&choosecolor, sizeof(choosecolor));
choosecolor.lStructSize = sizeof(choosecolor);
choosecolor.hwndOwner = m_hWnd;
choosecolor.lpCustColors = custColors;
}
choosecolor.Flags = CC_RGBINIT;
choosecolor.rgbResult = *prgbColor;
if (!::ChooseColor(&choosecolor))
return FALSE;
*prgbColor = choosecolor.rgbResult;
return TRUE;
}
HWND CMainWindow::DoCreate()
{
::LoadString(g_hinstExe, IDS_DEFAULTFILENAME, g_szFileName, _countof(g_szFileName));
CString strTitle;
strTitle.Format(IDS_WINDOWTITLE, PathFindFileName(g_szFileName));
RECT& rc = registrySettings.WindowPlacement.rcNormalPosition;
return Create(HWND_DESKTOP, rc, strTitle, WS_OVERLAPPEDWINDOW, WS_EX_ACCEPTFILES);
}
// entry point
INT WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, INT nCmdShow)
{
#ifdef _DEBUG
// Report any memory leaks on exit
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
g_hinstExe = hInstance;
// Initialize common controls library
INITCOMMONCONTROLSEX iccx;
iccx.dwSize = sizeof(iccx);
iccx.dwICC = ICC_STANDARD_CLASSES | ICC_USEREX_CLASSES | ICC_BAR_CLASSES;
InitCommonControlsEx(&iccx);
// Load settings from registry
registrySettings.Load(nCmdShow);
// Create the main window
if (!mainWindow.DoCreate())
{
MessageBox(NULL, TEXT("Failed to create main window."), NULL, MB_ICONERROR);
return 1;
}
// Initialize imageModel
imageModel.Crop(registrySettings.BMPWidth, registrySettings.BMPHeight);
if (__argc >= 2)
DoLoadImageFile(mainWindow, __targv[1], TRUE);
imageModel.ClearHistory();
// Make the window visible on the screen
mainWindow.ShowWindow(registrySettings.WindowPlacement.showCmd);
// Load the access keys
HACCEL hAccel = ::LoadAccelerators(hInstance, MAKEINTRESOURCE(800));
// The message loop
MSG msg;
while (::GetMessage(&msg, NULL, 0, 0))
{
if (fontsDialog.IsWindow() && fontsDialog.IsDialogMessage(&msg))
continue;
if (::TranslateAccelerator(mainWindow, hAccel, &msg))
continue;
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
// Unload the access keys
::DestroyAcceleratorTable(hAccel);
// Write back settings to registry
registrySettings.Store();
// Return the value that PostQuitMessage() gave
return (INT)msg.wParam;
}