mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[MSPAINT][ATL] Encapsulation: mainWindow (#5178)
- Add DoCreate methods to CFullscreenWindow, CMiniatureWindow, and CMainWindow classes. - Do encapsulation around mainWindow and _tWinMain. - Add GetOpenFileName, GetSaveFileName, and ChooseColor helper methods to CMainWindow class. - Move some code in WinMain into CMainWindow::OnCreate. - Delay creation of CFullscreenWindow and CMiniatureWindow. - Extend ATL CImage class as CImageDx in newly-created atlimagedx.h of mspaint. CORE-18867
This commit is contained in:
parent
0569bbd4a7
commit
29e147beca
29 changed files with 549 additions and 360 deletions
141
base/applications/mspaint/atlimagedx.h
Normal file
141
base/applications/mspaint/atlimagedx.h
Normal file
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* PROJECT: PAINT for ReactOS
|
||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||
* PURPOSE: Loading/Saving an image file with getting/setting resolution
|
||||
* COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
class CImageDx : public CImage
|
||||
{
|
||||
public:
|
||||
CImageDx() : CImage()
|
||||
{
|
||||
GetImageHorizontalResolution = NULL;
|
||||
GetImageVerticalResolution = NULL;
|
||||
BitmapSetResolution = NULL;
|
||||
}
|
||||
|
||||
BOOL GetResolution(Gdiplus::GpImage *pImage, float *pxDpi, float *pyDpi)
|
||||
{
|
||||
*pxDpi = 96;
|
||||
*pyDpi = 96;
|
||||
|
||||
if (GetImageHorizontalResolution == NULL || GetImageVerticalResolution == NULL)
|
||||
{
|
||||
GetImageHorizontalResolution =
|
||||
AddrOf<GETIMAGEHORIZONTALRESOLUTION>("GdipGetImageHorizontalResolution");
|
||||
GetImageVerticalResolution =
|
||||
AddrOf<GETIMAGEVERTICALRESOLUTION>("GdipGetImageVerticalResolution");
|
||||
}
|
||||
|
||||
if (GetImageHorizontalResolution == NULL || GetImageVerticalResolution == NULL)
|
||||
return FALSE;
|
||||
|
||||
GetImageHorizontalResolution(pImage, pxDpi);
|
||||
GetImageVerticalResolution(pImage, pyDpi);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL SetResolution(Gdiplus::GpBitmap *pBitmap, float xDpi, float yDpi) const
|
||||
{
|
||||
if (BitmapSetResolution == NULL)
|
||||
BitmapSetResolution = AddrOf<BITMAPSETRESOLUTION>("GdipBitmapSetResolution");
|
||||
|
||||
if (BitmapSetResolution == NULL)
|
||||
return FALSE;
|
||||
|
||||
BitmapSetResolution(pBitmap, xDpi, yDpi);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HRESULT LoadDx(LPCTSTR pszFileName, float *pxDpi, float *pyDpi) throw()
|
||||
{
|
||||
// convert the file name string into Unicode
|
||||
CStringW pszNameW(pszFileName);
|
||||
|
||||
// create a GpBitmap object from file
|
||||
using namespace Gdiplus;
|
||||
GpBitmap *pBitmap = NULL;
|
||||
if (GetCommon().CreateBitmapFromFile(pszNameW, &pBitmap) != Ok)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// get bitmap handle
|
||||
HBITMAP hbm = NULL;
|
||||
Color color(0xFF, 0xFF, 0xFF);
|
||||
Gdiplus::Status status;
|
||||
status = GetCommon().CreateHBITMAPFromBitmap(pBitmap, &hbm, color.GetValue());
|
||||
|
||||
// get the resolution
|
||||
GetResolution((Gdiplus::GpImage*)pBitmap, pxDpi, pyDpi);
|
||||
|
||||
// delete GpBitmap
|
||||
GetCommon().DisposeImage(pBitmap);
|
||||
|
||||
// attach it
|
||||
if (status == Ok)
|
||||
Attach(hbm);
|
||||
return (status == Ok ? S_OK : E_FAIL);
|
||||
}
|
||||
|
||||
HRESULT SaveDx(LPCTSTR pszFileName, REFGUID guidFileType = GUID_NULL,
|
||||
float xDpi = 0, float yDpi = 0) const throw()
|
||||
{
|
||||
using namespace Gdiplus;
|
||||
ATLASSERT(m_hbm);
|
||||
|
||||
// TODO & FIXME: set parameters (m_rgbTransColor etc.)
|
||||
|
||||
// convert the file name string into Unicode
|
||||
CStringW pszNameW(pszFileName);
|
||||
|
||||
// if the file type is null, get the file type from extension
|
||||
const GUID *FileType = &guidFileType;
|
||||
if (IsGuidEqual(guidFileType, GUID_NULL))
|
||||
{
|
||||
LPCWSTR pszExt = GetFileExtension(pszNameW);
|
||||
FileType = FileTypeFromExtension(pszExt);
|
||||
}
|
||||
|
||||
// get CLSID from file type
|
||||
CLSID clsid;
|
||||
if (!GetClsidFromFileType(&clsid, FileType))
|
||||
return E_FAIL;
|
||||
|
||||
// create a GpBitmap from HBITMAP
|
||||
GpBitmap *pBitmap = NULL;
|
||||
GetCommon().CreateBitmapFromHBITMAP(m_hbm, NULL, &pBitmap);
|
||||
|
||||
// set the resolution
|
||||
SetResolution(pBitmap, xDpi, yDpi);
|
||||
|
||||
// save to file
|
||||
Status status;
|
||||
status = GetCommon().SaveImageToFile(pBitmap, pszNameW, &clsid, NULL);
|
||||
|
||||
// destroy GpBitmap
|
||||
GetCommon().DisposeImage(pBitmap);
|
||||
|
||||
return (status == Ok ? S_OK : E_FAIL);
|
||||
}
|
||||
|
||||
protected:
|
||||
// get procedure address of the DLL
|
||||
template <typename TYPE>
|
||||
TYPE AddrOf(const char *name) const
|
||||
{
|
||||
FARPROC proc = ::GetProcAddress(GetCommon().hinstGdiPlus, name);
|
||||
return reinterpret_cast<TYPE>(proc);
|
||||
}
|
||||
|
||||
typedef St (WINGDIPAPI *GETIMAGEHORIZONTALRESOLUTION)(Im *, float*);
|
||||
typedef St (WINGDIPAPI *GETIMAGEVERTICALRESOLUTION)(Im *, float*);
|
||||
typedef St (WINGDIPAPI *BITMAPSETRESOLUTION)(Bm *, float, float);
|
||||
|
||||
GETIMAGEHORIZONTALRESOLUTION GetImageHorizontalResolution;
|
||||
GETIMAGEVERTICALRESOLUTION GetImageVerticalResolution;
|
||||
mutable BITMAPSETRESOLUTION BitmapSetResolution;
|
||||
};
|
|
@ -6,10 +6,10 @@
|
|||
* PROGRAMMERS: Benedikt Freisen
|
||||
*/
|
||||
|
||||
/* INCLUDES *********************************************************/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
CCanvasWindow canvasWindow;
|
||||
|
||||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
CCanvasWindow::CCanvasWindow()
|
||||
|
|
|
@ -14,6 +14,17 @@
|
|||
#define MIN_ZOOM 125
|
||||
#define MAX_ZOOM 8000
|
||||
|
||||
#define MAX_LONG_PATH 512
|
||||
|
||||
#define WM_TOOLSMODELTOOLCHANGED (WM_APP + 0)
|
||||
#define WM_TOOLSMODELSETTINGSCHANGED (WM_APP + 1)
|
||||
#define WM_TOOLSMODELZOOMCHANGED (WM_APP + 2)
|
||||
#define WM_PALETTEMODELCOLORCHANGED (WM_APP + 3)
|
||||
#define WM_PALETTEMODELPALETTECHANGED (WM_APP + 4)
|
||||
#define WM_IMAGEMODELDIMENSIONSCHANGED (WM_APP + 5)
|
||||
#define WM_IMAGEMODELIMAGECHANGED (WM_APP + 6)
|
||||
#define WM_SELECTIONMODELREFRESHNEEDED (WM_APP + 7)
|
||||
|
||||
/* width of the rectangle defined by a RECT structure */
|
||||
#define RECT_WIDTH(a) ((a).right - (a).left)
|
||||
|
||||
|
@ -26,6 +37,21 @@
|
|||
/* this simplifies enabling or graying menu items */
|
||||
#define ENABLED_IF(a) ((a) ? (MF_ENABLED | MF_BYCOMMAND) : (MF_GRAYED | MF_BYCOMMAND))
|
||||
|
||||
enum CANVAS_HITTEST // hit
|
||||
{
|
||||
HIT_NONE = 0, // Nothing hit or outside
|
||||
HIT_UPPER_LEFT,
|
||||
HIT_UPPER_CENTER,
|
||||
HIT_UPPER_RIGHT,
|
||||
HIT_MIDDLE_LEFT,
|
||||
HIT_MIDDLE_RIGHT,
|
||||
HIT_LOWER_LEFT,
|
||||
HIT_LOWER_CENTER,
|
||||
HIT_LOWER_RIGHT,
|
||||
HIT_BORDER,
|
||||
HIT_INNER,
|
||||
};
|
||||
|
||||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
BOOL zoomTo(int newZoom, int mouseX, int mouseY);
|
||||
|
@ -33,13 +59,3 @@ BOOL nearlyEqualPoints(INT x0, INT y0, INT x1, INT y1);
|
|||
void placeSelWin(void);
|
||||
void updateStartAndLast(LONG x, LONG y);
|
||||
void updateLast(LONG x, LONG y);
|
||||
|
||||
static inline int Zoomed(int xy)
|
||||
{
|
||||
return xy * toolsModel.GetZoom() / 1000;
|
||||
}
|
||||
|
||||
static inline int UnZoomed(int xy)
|
||||
{
|
||||
return xy * 1000 / toolsModel.GetZoom();
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ LRESULT CAttributesDialog::OnInitDialog(UINT nMsg, WPARAM wParam, LPARAM lParam,
|
|||
SetDlgItemText(IDD_ATTRIBUTESTEXT7, strSize);
|
||||
}
|
||||
CString strRes;
|
||||
strRes.Format(IDS_PRINTRES, fileHPPM, fileVPPM);
|
||||
strRes.Format(IDS_PRINTRES, (INT)PpmFromDpi(g_xDpi), (INT)PpmFromDpi(g_yDpi));
|
||||
SetDlgItemText(IDD_ATTRIBUTESTEXT8, strRes);
|
||||
return 0;
|
||||
}
|
||||
|
@ -136,9 +136,9 @@ LRESULT CAttributesDialog::OnDefault(WORD wNotifyCode, WORD wID, HWND hWndCtl, B
|
|||
LRESULT CAttributesDialog::OnRadioButton1(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
|
||||
{
|
||||
CString strNum;
|
||||
strNum.Format(_T("%.3lf"), newWidth / (0.0254 * fileHPPM));
|
||||
strNum.Format(_T("%.3lf"), newWidth / g_xDpi);
|
||||
SetDlgItemText(IDD_ATTRIBUTESEDIT1, strNum);
|
||||
strNum.Format(_T("%.3lf"), newHeight / (0.0254 * fileVPPM));
|
||||
strNum.Format(_T("%.3lf"), newHeight / g_yDpi);
|
||||
SetDlgItemText(IDD_ATTRIBUTESEDIT2, strNum);
|
||||
return 0;
|
||||
}
|
||||
|
@ -146,9 +146,9 @@ LRESULT CAttributesDialog::OnRadioButton1(WORD wNotifyCode, WORD wID, HWND hWndC
|
|||
LRESULT CAttributesDialog::OnRadioButton2(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
|
||||
{
|
||||
CString strNum;
|
||||
strNum.Format(_T("%.3lf"), newWidth * 100.0 / fileHPPM);
|
||||
strNum.Format(_T("%.3lf"), newWidth * 100 / PpmFromDpi(g_xDpi));
|
||||
SetDlgItemText(IDD_ATTRIBUTESEDIT1, strNum);
|
||||
strNum.Format(_T("%.3lf"), newHeight * 100.0 / fileVPPM);
|
||||
strNum.Format(_T("%.3lf"), newHeight * 100 / PpmFromDpi(g_yDpi));
|
||||
SetDlgItemText(IDD_ATTRIBUTESEDIT2, strNum);
|
||||
return 0;
|
||||
}
|
||||
|
@ -168,12 +168,12 @@ LRESULT CAttributesDialog::OnEdit1(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOO
|
|||
if (IsDlgButtonChecked(IDD_ATTRIBUTESRB1))
|
||||
{
|
||||
GetDlgItemText(IDD_ATTRIBUTESEDIT1, tempS, _countof(tempS));
|
||||
newWidth = max(1, (int) (_tcstod(tempS, NULL) * fileHPPM * 0.0254));
|
||||
newWidth = max(1, (int) (_tcstod(tempS, NULL) * g_xDpi));
|
||||
}
|
||||
else if (IsDlgButtonChecked(IDD_ATTRIBUTESRB2))
|
||||
{
|
||||
GetDlgItemText(IDD_ATTRIBUTESEDIT1, tempS, _countof(tempS));
|
||||
newWidth = max(1, (int) (_tcstod(tempS, NULL) * fileHPPM / 100));
|
||||
newWidth = max(1, (int) (_tcstod(tempS, NULL) * PpmFromDpi(g_xDpi) / 100));
|
||||
}
|
||||
else if (IsDlgButtonChecked(IDD_ATTRIBUTESRB3))
|
||||
{
|
||||
|
@ -193,12 +193,12 @@ LRESULT CAttributesDialog::OnEdit2(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOO
|
|||
if (IsDlgButtonChecked(IDD_ATTRIBUTESRB1))
|
||||
{
|
||||
GetDlgItemText(IDD_ATTRIBUTESEDIT2, tempS, _countof(tempS));
|
||||
newHeight = max(1, (int) (_tcstod(tempS, NULL) * fileVPPM * 0.0254));
|
||||
newHeight = max(1, (int) (_tcstod(tempS, NULL) * g_yDpi));
|
||||
}
|
||||
else if (IsDlgButtonChecked(IDD_ATTRIBUTESRB2))
|
||||
{
|
||||
GetDlgItemText(IDD_ATTRIBUTESEDIT2, tempS, _countof(tempS));
|
||||
newHeight = max(1, (int) (_tcstod(tempS, NULL) * fileVPPM / 100));
|
||||
newHeight = max(1, (int) (_tcstod(tempS, NULL) * PpmFromDpi(g_yDpi) / 100));
|
||||
}
|
||||
else if (IsDlgButtonChecked(IDD_ATTRIBUTESRB3))
|
||||
{
|
||||
|
|
|
@ -6,13 +6,22 @@
|
|||
* PROGRAMMERS: Benedikt Freisen
|
||||
*/
|
||||
|
||||
/* INCLUDES *********************************************************/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <math.h>
|
||||
|
||||
INT fileSize = 0;
|
||||
float g_xDpi = 96;
|
||||
float g_yDpi = 96;
|
||||
SYSTEMTIME fileTime;
|
||||
|
||||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
// Convert DPI (dots per inch) into PPM (pixels per meter)
|
||||
float PpmFromDpi(float dpi)
|
||||
{
|
||||
return dpi / 0.0254; // 1 DPI is 0.0254 meter.
|
||||
}
|
||||
|
||||
HBITMAP
|
||||
CreateDIBWithProperties(int width, int height)
|
||||
{
|
||||
|
@ -68,9 +77,9 @@ GetDIBHeight(HBITMAP hBitmap)
|
|||
|
||||
BOOL SaveDIBToFile(HBITMAP hBitmap, LPTSTR FileName, HDC hDC)
|
||||
{
|
||||
CImage img;
|
||||
CImageDx img;
|
||||
img.Attach(hBitmap);
|
||||
img.Save(FileName); // TODO: error handling
|
||||
img.SaveDx(FileName, GUID_NULL, g_xDpi, g_yDpi); // TODO: error handling
|
||||
img.Detach();
|
||||
|
||||
WIN32_FIND_DATA find;
|
||||
|
@ -116,16 +125,12 @@ HBITMAP SetBitmapAndInfo(HBITMAP hBitmap, LPCTSTR name, DWORD dwFileSize, BOOL i
|
|||
if (hBitmap == NULL)
|
||||
return FALSE;
|
||||
|
||||
fileHPPM = fileVPPM = 2834;
|
||||
ZeroMemory(&fileTime, sizeof(fileTime));
|
||||
}
|
||||
else
|
||||
{
|
||||
// update PPMs
|
||||
HDC hScreenDC = GetDC(NULL);
|
||||
fileHPPM = (int)(GetDeviceCaps(hScreenDC, LOGPIXELSX) * 1000 / 25.4);
|
||||
fileVPPM = (int)(GetDeviceCaps(hScreenDC, LOGPIXELSY) * 1000 / 25.4);
|
||||
g_xDpi = GetDeviceCaps(hScreenDC, LOGPIXELSX);
|
||||
g_yDpi = GetDeviceCaps(hScreenDC, LOGPIXELSY);
|
||||
ReleaseDC(NULL, hScreenDC);
|
||||
|
||||
ZeroMemory(&fileTime, sizeof(fileTime));
|
||||
}
|
||||
|
||||
// update image
|
||||
|
@ -185,8 +190,14 @@ HBITMAP DoLoadImageFile(HWND hwnd, LPCTSTR name, BOOL fIsMainFile)
|
|||
}
|
||||
|
||||
// load the image
|
||||
CImage img;
|
||||
img.Load(name);
|
||||
CImageDx img;
|
||||
img.LoadDx(name, &g_xDpi, &g_yDpi);
|
||||
|
||||
if (g_xDpi <= 0)
|
||||
g_xDpi = 96;
|
||||
if (g_yDpi <= 0)
|
||||
g_yDpi = 96;
|
||||
|
||||
HBITMAP hBitmap = img.Detach();
|
||||
|
||||
if (hBitmap == NULL)
|
||||
|
|
|
@ -31,3 +31,5 @@ HBITMAP SetBitmapAndInfo(HBITMAP hBitmap, LPCTSTR name, DWORD dwFileSize, BOOL i
|
|||
HBITMAP Rotate90DegreeBlt(HDC hDC1, INT cx, INT cy, BOOL bRight);
|
||||
|
||||
HBITMAP SkewDIB(HDC hDC1, HBITMAP hbm, INT nDegree, BOOL bVertical);
|
||||
|
||||
float PpmFromDpi(float dpi);
|
||||
|
|
|
@ -6,12 +6,21 @@
|
|||
* PROGRAMMERS: Benedikt Freisen
|
||||
*/
|
||||
|
||||
/* INCLUDES *********************************************************/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
CFullscreenWindow fullscreenWindow;
|
||||
|
||||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
HWND CFullscreenWindow::DoCreate()
|
||||
{
|
||||
if (m_hWnd)
|
||||
return m_hWnd;
|
||||
|
||||
RECT rc = {0, 0, 0, 0}; // Rely on SW_SHOWMAXIMIZED
|
||||
return Create(HWND_DESKTOP, rc, NULL, WS_POPUPWINDOW, WS_EX_TOPMOST);
|
||||
}
|
||||
|
||||
LRESULT CFullscreenWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
SendMessage(WM_SETICON, ICON_BIG, (LPARAM) LoadIcon(hProgInstance, MAKEINTRESOURCE(IDI_APPICON)));
|
||||
|
|
|
@ -23,6 +23,9 @@ public:
|
|||
MESSAGE_HANDLER(WM_GETTEXT, OnGetText)
|
||||
END_MSG_MAP()
|
||||
|
||||
HWND DoCreate();
|
||||
|
||||
private:
|
||||
LRESULT OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnCloseOrKeyDownOrLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
|
|
|
@ -10,58 +10,42 @@
|
|||
|
||||
/* VARIABLES declared in main.cpp ***********************************/
|
||||
|
||||
class RegistrySettings;
|
||||
extern RegistrySettings registrySettings;
|
||||
|
||||
class ImageModel;
|
||||
extern ImageModel imageModel;
|
||||
extern BOOL askBeforeEnlarging;
|
||||
|
||||
extern POINT start;
|
||||
extern POINT last;
|
||||
|
||||
class ToolsModel;
|
||||
extern HINSTANCE hProgInstance;
|
||||
|
||||
extern TCHAR filepathname[MAX_LONG_PATH];
|
||||
extern BOOL isAFile;
|
||||
extern BOOL imageSaved;
|
||||
|
||||
extern BOOL showGrid;
|
||||
|
||||
extern CMainWindow mainWindow;
|
||||
|
||||
/* VARIABLES declared in dialogs.cpp ********************************/
|
||||
|
||||
extern CMirrorRotateDialog mirrorRotateDialog;
|
||||
extern CAttributesDialog attributesDialog;
|
||||
extern CStretchSkewDialog stretchSkewDialog;
|
||||
extern CFontsDialog fontsDialog;
|
||||
|
||||
/* VARIABLES declared in the other places ***************************/
|
||||
|
||||
extern RegistrySettings registrySettings;
|
||||
extern ImageModel imageModel;
|
||||
extern ToolsModel toolsModel;
|
||||
|
||||
class SelectionModel;
|
||||
extern SelectionModel selectionModel;
|
||||
|
||||
class PaletteModel;
|
||||
extern PaletteModel paletteModel;
|
||||
|
||||
extern HWND hStatusBar;
|
||||
extern CHOOSECOLOR choosecolor;
|
||||
extern OPENFILENAME ofn;
|
||||
extern OPENFILENAME sfn;
|
||||
extern HICON hNontranspIcon;
|
||||
extern HICON hTranspIcon;
|
||||
|
||||
extern HINSTANCE hProgInstance;
|
||||
|
||||
extern TCHAR filepathname[1000];
|
||||
extern BOOL isAFile;
|
||||
extern BOOL imageSaved;
|
||||
extern int fileSize;
|
||||
extern int fileHPPM;
|
||||
extern int fileVPPM;
|
||||
extern float g_xDpi;
|
||||
extern float g_yDpi;
|
||||
extern INT fileSize;
|
||||
extern SYSTEMTIME fileTime;
|
||||
|
||||
extern BOOL showGrid;
|
||||
extern BOOL showMiniature;
|
||||
|
||||
class CMainWindow;
|
||||
class CFullscreenWindow;
|
||||
class CMiniatureWindow;
|
||||
class CToolBox;
|
||||
class CToolSettingsWindow;
|
||||
class CPaletteWindow;
|
||||
class CCanvasWindow;
|
||||
class CSelectionWindow;
|
||||
class CImgAreaWindow;
|
||||
class CSizeboxWindow;
|
||||
class CTextEditWindow;
|
||||
|
||||
extern CMainWindow mainWindow;
|
||||
extern CFullscreenWindow fullscreenWindow;
|
||||
extern CMiniatureWindow miniature;
|
||||
extern CToolBox toolBoxContainer;
|
||||
|
@ -71,15 +55,3 @@ extern CCanvasWindow canvasWindow;
|
|||
extern CSelectionWindow selectionWindow;
|
||||
extern CImgAreaWindow imageArea;
|
||||
extern CTextEditWindow textEditWindow;
|
||||
|
||||
/* VARIABLES declared in dialogs.cpp ********************************/
|
||||
|
||||
class CMirrorRotateDialog;
|
||||
class CAttributesDialog;
|
||||
class CStretchSkewDialog;
|
||||
class CFontsDialog;
|
||||
|
||||
extern CMirrorRotateDialog mirrorRotateDialog;
|
||||
extern CAttributesDialog attributesDialog;
|
||||
extern CStretchSkewDialog stretchSkewDialog;
|
||||
extern CFontsDialog fontsDialog;
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
* PROGRAMMERS: Benedikt Freisen
|
||||
*/
|
||||
|
||||
/* INCLUDES *********************************************************/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
ImageModel imageModel;
|
||||
|
||||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
void ImageModel::NotifyDimensionsChanged()
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
#include "precomp.h"
|
||||
|
||||
CImgAreaWindow imageArea;
|
||||
|
||||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
LRESULT CImgAreaWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
|
|
|
@ -13,9 +13,7 @@
|
|||
class CImgAreaWindow : public CWindowImpl<CImgAreaWindow>
|
||||
{
|
||||
public:
|
||||
CImgAreaWindow() : drawing(FALSE)
|
||||
{
|
||||
}
|
||||
CImgAreaWindow() : drawing(FALSE) { }
|
||||
|
||||
BOOL drawing;
|
||||
void cancelDrawing();
|
||||
|
|
|
@ -8,52 +8,19 @@
|
|||
|
||||
#include "precomp.h"
|
||||
|
||||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
POINT start;
|
||||
POINT last;
|
||||
|
||||
ToolsModel toolsModel;
|
||||
|
||||
SelectionModel selectionModel;
|
||||
|
||||
PaletteModel paletteModel;
|
||||
|
||||
RegistrySettings registrySettings;
|
||||
|
||||
ImageModel imageModel;
|
||||
BOOL askBeforeEnlarging = FALSE; // TODO: initialize from registry
|
||||
|
||||
HWND hStatusBar;
|
||||
CHOOSECOLOR choosecolor;
|
||||
OPENFILENAME ofn;
|
||||
OPENFILENAME sfn;
|
||||
HICON hNontranspIcon;
|
||||
HICON hTranspIcon;
|
||||
|
||||
HINSTANCE hProgInstance;
|
||||
|
||||
TCHAR filepathname[1000];
|
||||
HINSTANCE hProgInstance = NULL;
|
||||
TCHAR filepathname[MAX_LONG_PATH] = { 0 };
|
||||
BOOL isAFile = FALSE;
|
||||
BOOL imageSaved = FALSE;
|
||||
int fileSize;
|
||||
int fileHPPM = 2834;
|
||||
int fileVPPM = 2834;
|
||||
SYSTEMTIME fileTime;
|
||||
|
||||
BOOL showGrid = FALSE;
|
||||
BOOL showMiniature = FALSE;
|
||||
|
||||
CMainWindow mainWindow;
|
||||
CFullscreenWindow fullscreenWindow;
|
||||
CMiniatureWindow miniature;
|
||||
CToolBox toolBoxContainer;
|
||||
CToolSettingsWindow toolSettingsWindow;
|
||||
CPaletteWindow paletteWindow;
|
||||
CCanvasWindow canvasWindow;
|
||||
CSelectionWindow selectionWindow;
|
||||
CImgAreaWindow imageArea;
|
||||
CTextEditWindow textEditWindow;
|
||||
|
||||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
// get file name extension from filter string
|
||||
static BOOL
|
||||
|
@ -105,193 +72,171 @@ OFNHookProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* entry point */
|
||||
|
||||
int WINAPI
|
||||
_tWinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPTSTR lpszArgument, INT nCmdShow)
|
||||
BOOL CMainWindow::GetOpenFileName(IN OUT LPTSTR pszFile, INT cchMaxFile)
|
||||
{
|
||||
HWND hwnd; /* This is the handle for our window */
|
||||
MSG messages; /* Here messages to the application are saved */
|
||||
static OPENFILENAME ofn = { 0 };
|
||||
static CString strFilter;
|
||||
|
||||
HMENU menu;
|
||||
HACCEL haccel;
|
||||
if (ofn.lStructSize == 0)
|
||||
{
|
||||
// The "All Files" item text
|
||||
CString strAllPictureFiles;
|
||||
strAllPictureFiles.LoadString(hProgInstance, IDS_ALLPICTUREFILES);
|
||||
|
||||
TCHAR sfnFilename[1000];
|
||||
TCHAR sfnFiletitle[256];
|
||||
TCHAR ofnFilename[1000];
|
||||
TCHAR ofnFiletitle[256];
|
||||
TCHAR miniaturetitle[100];
|
||||
static COLORREF custColors[16] = {
|
||||
// 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 = hProgInstance;
|
||||
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 = hProgInstance;
|
||||
sfn.lpstrFilter = strFilter;
|
||||
sfn.Flags = OFN_EXPLORER | OFN_OVERWRITEPROMPT | OFN_ENABLEHOOK;
|
||||
sfn.lpfnHook = OFNHookProc;
|
||||
sfn.lpstrDefExt = L"png";
|
||||
|
||||
// Choose 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.rgbResult = *prgbColor;
|
||||
if (!::ChooseColor(&choosecolor))
|
||||
return FALSE;
|
||||
|
||||
*prgbColor = choosecolor.rgbResult;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HWND CMainWindow::DoCreate()
|
||||
{
|
||||
::LoadString(hProgInstance, IDS_DEFAULTFILENAME, filepathname, _countof(filepathname));
|
||||
|
||||
CString strTitle;
|
||||
strTitle.Format(IDS_WINDOWTITLE, PathFindFileName(filepathname));
|
||||
|
||||
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 */
|
||||
// Report any memory leaks on exit
|
||||
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
|
||||
#endif
|
||||
|
||||
hProgInstance = hThisInstance;
|
||||
hProgInstance = hInstance;
|
||||
|
||||
/* initialize common controls library */
|
||||
// Initialize common controls library
|
||||
INITCOMMONCONTROLSEX iccx;
|
||||
iccx.dwSize = sizeof(iccx);
|
||||
iccx.dwICC = ICC_STANDARD_CLASSES | ICC_USEREX_CLASSES | ICC_BAR_CLASSES;
|
||||
InitCommonControlsEx(&iccx);
|
||||
|
||||
LoadString(hThisInstance, IDS_DEFAULTFILENAME, filepathname, _countof(filepathname));
|
||||
CPath pathFileName(filepathname);
|
||||
pathFileName.StripPath();
|
||||
CString strTitle;
|
||||
strTitle.Format(IDS_WINDOWTITLE, (LPCTSTR)pathFileName);
|
||||
LoadString(hThisInstance, IDS_MINIATURETITLE, miniaturetitle, _countof(miniaturetitle));
|
||||
|
||||
/* load settings from registry */
|
||||
// Load settings from registry
|
||||
registrySettings.Load(nCmdShow);
|
||||
showMiniature = registrySettings.ShowThumbnail;
|
||||
imageModel.Crop(registrySettings.BMPWidth, registrySettings.BMPHeight);
|
||||
|
||||
/* create main window */
|
||||
RECT mainWindowPos = registrySettings.WindowPlacement.rcNormalPosition;
|
||||
hwnd = mainWindow.Create(HWND_DESKTOP, mainWindowPos, strTitle, WS_OVERLAPPEDWINDOW);
|
||||
|
||||
RECT fullscreenWindowPos = {0, 0, 100, 100};
|
||||
fullscreenWindow.Create(HWND_DESKTOP, fullscreenWindowPos, NULL, WS_POPUPWINDOW | WS_MAXIMIZE);
|
||||
|
||||
RECT miniaturePos = {(LONG) registrySettings.ThumbXPos, (LONG) registrySettings.ThumbYPos,
|
||||
(LONG) registrySettings.ThumbXPos + (LONG) registrySettings.ThumbWidth,
|
||||
(LONG) registrySettings.ThumbYPos + (LONG) registrySettings.ThumbHeight};
|
||||
miniature.Create(hwnd, miniaturePos, miniaturetitle,
|
||||
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME, WS_EX_PALETTEWINDOW);
|
||||
miniature.ShowWindow(showMiniature ? SW_SHOW : SW_HIDE);
|
||||
|
||||
/* loading and setting the window menu from resource */
|
||||
menu = LoadMenu(hThisInstance, MAKEINTRESOURCE(ID_MENU));
|
||||
SetMenu(hwnd, menu);
|
||||
haccel = LoadAccelerators(hThisInstance, MAKEINTRESOURCE(800));
|
||||
|
||||
/* Create ToolBox */
|
||||
toolBoxContainer.DoCreate(hwnd);
|
||||
|
||||
/* creating the palette child window */
|
||||
RECT paletteWindowPos = {56, 9, 56 + 255, 9 + 32};
|
||||
paletteWindow.Create(hwnd, paletteWindowPos, NULL, WS_CHILD, WS_EX_STATICEDGE);
|
||||
if (registrySettings.ShowPalette)
|
||||
paletteWindow.ShowWindow(SW_SHOWNOACTIVATE);
|
||||
|
||||
// creating the canvas
|
||||
RECT canvasWindowPos = {0, 0, 0 + 500, 0 + 500};
|
||||
canvasWindow.Create(hwnd, canvasWindowPos, NULL,
|
||||
WS_CHILD | WS_GROUP | WS_HSCROLL | WS_VSCROLL | WS_VISIBLE, WS_EX_CLIENTEDGE);
|
||||
|
||||
/* creating the status bar */
|
||||
hStatusBar =
|
||||
CreateWindowEx(0, STATUSCLASSNAME, NULL, SBARS_SIZEGRIP | WS_CHILD, 0, 0, 0, 0, hwnd,
|
||||
NULL, hThisInstance, NULL);
|
||||
SendMessage(hStatusBar, SB_SETMINHEIGHT, 21, 0);
|
||||
if (registrySettings.ShowStatusBar)
|
||||
ShowWindow(hStatusBar, SW_SHOWNOACTIVATE);
|
||||
|
||||
// Creating the window inside the canvas
|
||||
RECT imageAreaPos = {GRIP_SIZE, GRIP_SIZE, GRIP_SIZE + imageModel.GetWidth(), GRIP_SIZE + imageModel.GetHeight()};
|
||||
imageArea.Create(canvasWindow.m_hWnd, imageAreaPos, NULL, WS_CHILD | WS_VISIBLE);
|
||||
|
||||
/* create selection window (initially hidden) */
|
||||
RECT selectionWindowPos = {350, 0, 350 + 100, 0 + 100};
|
||||
selectionWindow.Create(imageArea.m_hWnd, selectionWindowPos, NULL, WS_CHILD | BS_OWNERDRAW);
|
||||
|
||||
if (__argc >= 2)
|
||||
// Create the main window
|
||||
if (!mainWindow.DoCreate())
|
||||
{
|
||||
DoLoadImageFile(mainWindow, __targv[1], TRUE);
|
||||
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();
|
||||
|
||||
/* initializing the CHOOSECOLOR structure for use with ChooseColor */
|
||||
ZeroMemory(&choosecolor, sizeof(choosecolor));
|
||||
choosecolor.lStructSize = sizeof(CHOOSECOLOR);
|
||||
choosecolor.hwndOwner = hwnd;
|
||||
choosecolor.rgbResult = 0x00ffffff;
|
||||
choosecolor.lpCustColors = custColors;
|
||||
// Make the window visible on the screen
|
||||
mainWindow.ShowWindow(registrySettings.WindowPlacement.showCmd);
|
||||
|
||||
/* initializing the OPENFILENAME structure for use with GetOpenFileName and GetSaveFileName */
|
||||
ofnFilename[0] = 0;
|
||||
CString strImporters;
|
||||
CSimpleArray<GUID> aguidFileTypesI;
|
||||
CString strAllPictureFiles;
|
||||
strAllPictureFiles.LoadString(hThisInstance, IDS_ALLPICTUREFILES);
|
||||
CImage::GetImporterFilterString(strImporters, aguidFileTypesI, strAllPictureFiles, CImage::excludeDefaultLoad, _T('\0'));
|
||||
// CAtlStringW strAllFiles;
|
||||
// strAllFiles.LoadString(hThisInstance, IDS_ALLFILES);
|
||||
// strImporters = strAllFiles + CAtlStringW(_T("|*.*|")).Replace('|', '\0') + strImporters;
|
||||
ZeroMemory(&ofn, sizeof(OPENFILENAME));
|
||||
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||
ofn.hwndOwner = hwnd;
|
||||
ofn.hInstance = hThisInstance;
|
||||
ofn.lpstrFilter = strImporters;
|
||||
ofn.lpstrFile = ofnFilename;
|
||||
ofn.nMaxFile = _countof(ofnFilename);
|
||||
ofn.lpstrFileTitle = ofnFiletitle;
|
||||
ofn.nMaxFileTitle = _countof(ofnFiletitle);
|
||||
ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY;
|
||||
ofn.lpstrDefExt = L"png";
|
||||
// Load the access keys
|
||||
HACCEL hAccel = ::LoadAccelerators(hInstance, MAKEINTRESOURCE(800));
|
||||
|
||||
CopyMemory(sfnFilename, filepathname, sizeof(filepathname));
|
||||
CString strExporters;
|
||||
CSimpleArray<GUID> aguidFileTypesE;
|
||||
CImage::GetExporterFilterString(strExporters, aguidFileTypesE, NULL, CImage::excludeDefaultSave, _T('\0'));
|
||||
ZeroMemory(&sfn, sizeof(OPENFILENAME));
|
||||
sfn.lStructSize = sizeof(OPENFILENAME);
|
||||
sfn.hwndOwner = hwnd;
|
||||
sfn.hInstance = hThisInstance;
|
||||
sfn.lpstrFilter = strExporters;
|
||||
sfn.lpstrFile = sfnFilename;
|
||||
sfn.nMaxFile = _countof(sfnFilename);
|
||||
sfn.lpstrFileTitle = sfnFiletitle;
|
||||
sfn.nMaxFileTitle = _countof(sfnFiletitle);
|
||||
sfn.Flags = OFN_EXPLORER | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_EXPLORER | OFN_ENABLEHOOK;
|
||||
sfn.lpfnHook = OFNHookProc;
|
||||
sfn.lpstrDefExt = L"png";
|
||||
// Choose PNG
|
||||
for (INT i = 0; i < aguidFileTypesE.GetSize(); ++i)
|
||||
// The message loop
|
||||
MSG msg;
|
||||
while (::GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
if (aguidFileTypesE[i] == Gdiplus::ImageFormatPNG)
|
||||
{
|
||||
sfn.nFilterIndex = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* placing the size boxes around the image */
|
||||
imageArea.SendMessage(WM_SIZE, 0, 0);
|
||||
|
||||
/* Make the window visible on the screen */
|
||||
ShowWindow(hwnd, registrySettings.WindowPlacement.showCmd);
|
||||
|
||||
/* inform the system, that the main window accepts dropped files */
|
||||
DragAcceptFiles(hwnd, TRUE);
|
||||
|
||||
/* Run the message loop. It will run until GetMessage() returns 0 */
|
||||
while (GetMessage(&messages, NULL, 0, 0))
|
||||
{
|
||||
if (fontsDialog.IsWindow() && IsDialogMessage(fontsDialog, &messages))
|
||||
if (fontsDialog.IsWindow() && fontsDialog.IsDialogMessage(&msg))
|
||||
continue;
|
||||
|
||||
if (TranslateAccelerator(hwnd, haccel, &messages))
|
||||
if (::TranslateAccelerator(mainWindow, hAccel, &msg))
|
||||
continue;
|
||||
|
||||
/* Translate virtual-key messages into character messages */
|
||||
TranslateMessage(&messages);
|
||||
/* Send message to WindowProcedure */
|
||||
DispatchMessage(&messages);
|
||||
::TranslateMessage(&msg);
|
||||
::DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
/* write back settings to registry */
|
||||
registrySettings.ShowThumbnail = showMiniature;
|
||||
registrySettings.BMPWidth = imageModel.GetWidth();
|
||||
registrySettings.BMPHeight = imageModel.GetHeight();
|
||||
// Unload the access keys
|
||||
::DestroyAcceleratorTable(hAccel);
|
||||
|
||||
// Write back settings to registry
|
||||
registrySettings.Store();
|
||||
|
||||
/* The program return-value is 0 - The value that PostQuitMessage() gave */
|
||||
return messages.wParam;
|
||||
// Return the value that PostQuitMessage() gave
|
||||
return (INT)msg.wParam;
|
||||
}
|
||||
|
|
|
@ -7,16 +7,35 @@
|
|||
* PROGRAMMERS: Benedikt Freisen
|
||||
*/
|
||||
|
||||
/* INCLUDES *********************************************************/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
CMiniatureWindow miniature;
|
||||
|
||||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
HWND CMiniatureWindow::DoCreate(HWND hwndParent)
|
||||
{
|
||||
if (m_hWnd)
|
||||
return m_hWnd;
|
||||
|
||||
RECT rc =
|
||||
{
|
||||
(LONG)registrySettings.ThumbXPos, (LONG)registrySettings.ThumbYPos,
|
||||
(LONG)(registrySettings.ThumbXPos + registrySettings.ThumbWidth),
|
||||
(LONG)(registrySettings.ThumbYPos + registrySettings.ThumbHeight)
|
||||
};
|
||||
|
||||
TCHAR strTitle[100];
|
||||
::LoadString(hProgInstance, IDS_MINIATURETITLE, strTitle, _countof(strTitle));
|
||||
|
||||
DWORD style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME;
|
||||
return Create(hwndParent, rc, strTitle, style, WS_EX_PALETTEWINDOW);
|
||||
}
|
||||
|
||||
LRESULT CMiniatureWindow::OnClose(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
miniature.ShowWindow(SW_HIDE);
|
||||
showMiniature = FALSE;
|
||||
ShowWindow(SW_HIDE);
|
||||
registrySettings.ShowThumbnail = FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,9 @@ public:
|
|||
MESSAGE_HANDLER(WM_PAINT, OnPaint)
|
||||
END_MSG_MAP()
|
||||
|
||||
HWND DoCreate(HWND hwndParent);
|
||||
|
||||
private:
|
||||
LRESULT OnClose(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#define COLOR_COUNT 28
|
||||
#define HALF_COLOR_COUNT (COLOR_COUNT / 2)
|
||||
|
||||
CPaletteWindow paletteWindow;
|
||||
|
||||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
static VOID drawColorBox(HDC hDC, LPCRECT prc, COLORREF rgbColor, UINT nBorder)
|
||||
|
@ -144,10 +146,11 @@ LRESULT CPaletteWindow::OnRButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, B
|
|||
LRESULT CPaletteWindow::OnLButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
INT iColor = DoHitTest(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
if (iColor != -1 && ChooseColor(&choosecolor))
|
||||
COLORREF rgbColor = paletteModel.GetFgColor();
|
||||
if (iColor != -1 && mainWindow.ChooseColor(&rgbColor))
|
||||
{
|
||||
paletteModel.SetColor(iColor, choosecolor.rgbResult);
|
||||
paletteModel.SetFgColor(choosecolor.rgbResult);
|
||||
paletteModel.SetColor(iColor, rgbColor);
|
||||
paletteModel.SetFgColor(rgbColor);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -155,10 +158,11 @@ LRESULT CPaletteWindow::OnLButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam,
|
|||
LRESULT CPaletteWindow::OnRButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
INT iColor = DoHitTest(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||||
if (iColor != -1 && ChooseColor(&choosecolor))
|
||||
COLORREF rgbColor = paletteModel.GetBgColor();
|
||||
if (iColor != -1 && mainWindow.ChooseColor(&rgbColor))
|
||||
{
|
||||
paletteModel.SetColor(iColor, choosecolor.rgbResult);
|
||||
paletteModel.SetBgColor(choosecolor.rgbResult);
|
||||
paletteModel.SetColor(iColor, rgbColor);
|
||||
paletteModel.SetBgColor(rgbColor);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
* Katayama Hirofumi MZ
|
||||
*/
|
||||
|
||||
/* INCLUDES *********************************************************/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
PaletteModel paletteModel;
|
||||
|
||||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
PaletteModel::PaletteModel()
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
#undef _DEBUG
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
#include <winuser.h>
|
||||
|
@ -26,43 +24,19 @@
|
|||
#include <stdlib.h>
|
||||
#include <shellapi.h>
|
||||
#include <htmlhelp.h>
|
||||
#include "atlimagedx.h"
|
||||
#ifdef _DEBUG
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#define WM_TOOLSMODELTOOLCHANGED (WM_APP + 0)
|
||||
#define WM_TOOLSMODELSETTINGSCHANGED (WM_APP + 1)
|
||||
#define WM_TOOLSMODELZOOMCHANGED (WM_APP + 2)
|
||||
#define WM_PALETTEMODELCOLORCHANGED (WM_APP + 3)
|
||||
#define WM_PALETTEMODELPALETTECHANGED (WM_APP + 4)
|
||||
#define WM_IMAGEMODELDIMENSIONSCHANGED (WM_APP + 5)
|
||||
#define WM_IMAGEMODELIMAGECHANGED (WM_APP + 6)
|
||||
#define WM_SELECTIONMODELREFRESHNEEDED (WM_APP + 7)
|
||||
|
||||
enum CANVAS_HITTEST // hit
|
||||
{
|
||||
HIT_NONE = 0, // Nothing hit or outside
|
||||
HIT_UPPER_LEFT,
|
||||
HIT_UPPER_CENTER,
|
||||
HIT_UPPER_RIGHT,
|
||||
HIT_MIDDLE_LEFT,
|
||||
HIT_MIDDLE_RIGHT,
|
||||
HIT_LOWER_LEFT,
|
||||
HIT_LOWER_CENTER,
|
||||
HIT_LOWER_RIGHT,
|
||||
HIT_BORDER,
|
||||
HIT_INNER,
|
||||
};
|
||||
|
||||
#include "resource.h"
|
||||
#include "common.h"
|
||||
#include "drawing.h"
|
||||
#include "dib.h"
|
||||
#include "fullscreen.h"
|
||||
#include "globalvar.h"
|
||||
#include "history.h"
|
||||
#include "imgarea.h"
|
||||
#include "miniature.h"
|
||||
|
@ -79,6 +53,6 @@ enum CANVAS_HITTEST // hit
|
|||
#include "toolsmodel.h"
|
||||
#include "winproc.h"
|
||||
#include "dialogs.h"
|
||||
#include "common.h"
|
||||
#include "globalvar.h"
|
||||
|
||||
#endif /* _MSPAINT_H */
|
||||
|
|
|
@ -7,14 +7,15 @@
|
|||
* Katayama Hirofumi MZ
|
||||
*/
|
||||
|
||||
/* INCLUDES *********************************************************/
|
||||
|
||||
#include "precomp.h"
|
||||
#include <winreg.h>
|
||||
#include <wincon.h>
|
||||
#include <shlobj.h>
|
||||
|
||||
RegistrySettings registrySettings;
|
||||
|
||||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
static void ReadDWORD(CRegKey &key, LPCTSTR lpName, DWORD &dwValue)
|
||||
{
|
||||
DWORD dwTemp;
|
||||
|
@ -161,6 +162,9 @@ void RegistrySettings::Load(INT nCmdShow)
|
|||
|
||||
void RegistrySettings::Store()
|
||||
{
|
||||
BMPWidth = imageModel.GetWidth();
|
||||
BMPHeight = imageModel.GetHeight();
|
||||
|
||||
CRegKey paint;
|
||||
if (paint.Create(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Paint")) != ERROR_SUCCESS)
|
||||
return;
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
* Katayama Hirofumi MZ
|
||||
*/
|
||||
|
||||
/* INCLUDES *********************************************************/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
CSelectionWindow selectionWindow;
|
||||
|
||||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
const LPCTSTR CSelectionWindow::m_lpszCursorLUT[9] = { /* action to mouse cursor lookup table */
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
* Katayama Hirofumi MZ
|
||||
*/
|
||||
|
||||
/* INCLUDES *********************************************************/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
SelectionModel selectionModel;
|
||||
|
||||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
SelectionModel::SelectionModel()
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
* PROGRAMMERS: Benedikt Freisen
|
||||
*/
|
||||
|
||||
/* INCLUDES *********************************************************/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
#define CXY_GRIP 3
|
||||
|
||||
CTextEditWindow textEditWindow;
|
||||
|
||||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
CTextEditWindow::CTextEditWindow() : m_hFont(NULL), m_hFontZoomed(NULL), m_nAppIsMovingOrSizing(0)
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
* PROGRAMMERS: Benedikt Freisen
|
||||
*/
|
||||
|
||||
/* INCLUDES *********************************************************/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
CToolBox toolBoxContainer;
|
||||
|
||||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
BOOL CToolBox::DoCreate(HWND hwndParent)
|
||||
|
|
|
@ -24,11 +24,12 @@
|
|||
|
||||
static const BYTE s_AirRadius[4] = { 5, 8, 3, 12 };
|
||||
|
||||
CToolSettingsWindow toolSettingsWindow;
|
||||
|
||||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
BOOL CToolSettingsWindow::DoCreate(HWND hwndParent)
|
||||
{
|
||||
/* creating the tool settings child window */
|
||||
RECT toolSettingsWindowPos =
|
||||
{
|
||||
X_TOOLSETTINGS, Y_TOOLSETTINGS,
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
* PROGRAMMERS: Benedikt Freisen
|
||||
*/
|
||||
|
||||
/* INCLUDES *********************************************************/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
ToolsModel toolsModel;
|
||||
|
||||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
ToolsModel::ToolsModel()
|
||||
|
|
|
@ -120,3 +120,15 @@ public:
|
|||
void NotifyToolSettingsChanged();
|
||||
void NotifyZoomChanged();
|
||||
};
|
||||
|
||||
extern ToolsModel toolsModel;
|
||||
|
||||
static inline int Zoomed(int xy)
|
||||
{
|
||||
return xy * toolsModel.GetZoom() / 1000;
|
||||
}
|
||||
|
||||
static inline int UnZoomed(int xy)
|
||||
{
|
||||
return xy * 1000 / toolsModel.GetZoom();
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@ typedef HWND (WINAPI *FN_HtmlHelpW)(HWND, LPCWSTR, UINT, DWORD_PTR);
|
|||
static HINSTANCE s_hHHCTRL_OCX = NULL; // HtmlHelpW needs "hhctrl.ocx"
|
||||
static FN_HtmlHelpW s_pHtmlHelpW = NULL;
|
||||
|
||||
HWND hStatusBar = NULL;
|
||||
|
||||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
// A wrapper function for HtmlHelpW
|
||||
|
@ -121,12 +123,12 @@ void CMainWindow::saveImage(BOOL overwrite)
|
|||
{
|
||||
imageModel.SaveImage(filepathname);
|
||||
}
|
||||
else if (GetSaveFileName(&sfn) != 0)
|
||||
else if (GetSaveFileName(filepathname, _countof(filepathname)))
|
||||
{
|
||||
imageModel.SaveImage(sfn.lpstrFile);
|
||||
_tcsncpy(filepathname, sfn.lpstrFile, _countof(filepathname));
|
||||
imageModel.SaveImage(filepathname);
|
||||
|
||||
CString strTitle;
|
||||
strTitle.Format(IDS_WINDOWTITLE, (LPCTSTR)sfn.lpstrFileTitle);
|
||||
strTitle.Format(IDS_WINDOWTITLE, PathFindFileName(filepathname));
|
||||
SetWindowText(strTitle);
|
||||
isAFile = TRUE;
|
||||
}
|
||||
|
@ -252,8 +254,45 @@ LRESULT CMainWindow::OnDropFiles(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
|
|||
|
||||
LRESULT CMainWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
// Loading and setting the window menu from resource
|
||||
m_hMenu = ::LoadMenu(hProgInstance, MAKEINTRESOURCE(ID_MENU));
|
||||
SetMenu(m_hMenu);
|
||||
|
||||
// Create the status bar
|
||||
DWORD style = SBARS_SIZEGRIP | WS_CHILD | (registrySettings.ShowStatusBar ? WS_VISIBLE : 0);
|
||||
hStatusBar = ::CreateWindowEx(0, STATUSCLASSNAME, NULL, style, 0, 0, 0, 0, m_hWnd,
|
||||
NULL, hProgInstance, NULL);
|
||||
::SendMessage(hStatusBar, SB_SETMINHEIGHT, 21, 0);
|
||||
|
||||
// Create the tool box
|
||||
toolBoxContainer.DoCreate(m_hWnd);
|
||||
|
||||
// Create the palette window
|
||||
RECT rcEmpty = { 0, 0, 0, 0 }; // Rely on WM_SIZE
|
||||
style = WS_CHILD | (registrySettings.ShowPalette ? WS_VISIBLE : 0);
|
||||
paletteWindow.Create(m_hWnd, rcEmpty, NULL, style, WS_EX_STATICEDGE);
|
||||
|
||||
// Create the canvas
|
||||
style = WS_CHILD | WS_GROUP | WS_HSCROLL | WS_VSCROLL | WS_VISIBLE;
|
||||
canvasWindow.Create(m_hWnd, rcEmpty, NULL, style, WS_EX_CLIENTEDGE);
|
||||
|
||||
// Creating the window inside the canvas
|
||||
imageArea.Create(canvasWindow, rcEmpty, NULL, WS_CHILD | WS_VISIBLE);
|
||||
|
||||
// Create selection window (initially hidden)
|
||||
selectionWindow.Create(imageArea, rcEmpty, NULL, WS_CHILD | BS_OWNERDRAW);
|
||||
|
||||
// Create and show the miniature if necessary
|
||||
if (registrySettings.ShowThumbnail)
|
||||
{
|
||||
miniature.DoCreate(m_hWnd);
|
||||
miniature.ShowWindow(SW_SHOWNOACTIVATE);
|
||||
}
|
||||
|
||||
// Set icon
|
||||
SendMessage(WM_SETICON, ICON_BIG, (LPARAM) LoadIcon(hProgInstance, MAKEINTRESOURCE(IDI_APPICON)));
|
||||
SendMessage(WM_SETICON, ICON_SMALL, (LPARAM) LoadIcon(hProgInstance, MAKEINTRESOURCE(IDI_APPICON)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -271,6 +310,13 @@ LRESULT CMainWindow::OnDestroy(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
|
|||
s_pHtmlHelpW = NULL;
|
||||
}
|
||||
|
||||
SetMenu(NULL);
|
||||
if (m_hMenu)
|
||||
{
|
||||
::DestroyMenu(m_hMenu);
|
||||
m_hMenu = NULL;
|
||||
}
|
||||
|
||||
PostQuitMessage(0); /* send a WM_QUIT to the message queue */
|
||||
return 0;
|
||||
}
|
||||
|
@ -359,7 +405,7 @@ void CMainWindow::ProcessFileMenu(HMENU hPopupMenu)
|
|||
|
||||
LRESULT CMainWindow::OnInitMenuPopup(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
HMENU menu = GetMenu();
|
||||
HMENU menu = (HMENU)wParam;
|
||||
BOOL trueSelection =
|
||||
(::IsWindowVisible(selectionWindow) &&
|
||||
((toolsModel.GetActiveTool() == TOOL_FREESEL) || (toolsModel.GetActiveTool() == TOOL_RECTSEL)));
|
||||
|
@ -389,7 +435,7 @@ LRESULT CMainWindow::OnInitMenuPopup(UINT nMsg, WPARAM wParam, LPARAM lParam, BO
|
|||
EnableMenuItem(menu, IDM_FORMATICONBAR, ENABLED_IF(toolsModel.GetActiveTool() == TOOL_TEXT));
|
||||
|
||||
CheckMenuItem(menu, IDM_VIEWSHOWGRID, CHECKED_IF(showGrid));
|
||||
CheckMenuItem(menu, IDM_VIEWSHOWMINIATURE, CHECKED_IF(showMiniature));
|
||||
CheckMenuItem(menu, IDM_VIEWSHOWMINIATURE, CHECKED_IF(registrySettings.ShowThumbnail));
|
||||
break;
|
||||
case 3: /* Image menu */
|
||||
EnableMenuItem(menu, IDM_IMAGECROP, ENABLED_IF(::IsWindowVisible(selectionWindow)));
|
||||
|
@ -496,11 +542,14 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
|
|||
}
|
||||
break;
|
||||
case IDM_FILEOPEN:
|
||||
if (ConfirmSave() && GetOpenFileName(&ofn))
|
||||
{
|
||||
DoLoadImageFile(m_hWnd, ofn.lpstrFile, TRUE);
|
||||
TCHAR szFileName[MAX_LONG_PATH] = _T("");
|
||||
if (ConfirmSave() && GetOpenFileName(szFileName, _countof(szFileName)))
|
||||
{
|
||||
DoLoadImageFile(m_hWnd, szFileName, TRUE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case IDM_FILESAVE:
|
||||
saveImage(TRUE);
|
||||
break;
|
||||
|
@ -640,13 +689,18 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
|
|||
break;
|
||||
}
|
||||
case IDM_EDITCOPYTO:
|
||||
if (GetSaveFileName(&ofn))
|
||||
SaveDIBToFile(selectionModel.GetBitmap(), ofn.lpstrFile, imageModel.GetDC());
|
||||
{
|
||||
TCHAR szFileName[MAX_LONG_PATH] = _T("");
|
||||
if (GetSaveFileName(szFileName, _countof(szFileName)))
|
||||
SaveDIBToFile(selectionModel.GetBitmap(), szFileName, imageModel.GetDC());
|
||||
break;
|
||||
}
|
||||
case IDM_EDITPASTEFROM:
|
||||
if (GetOpenFileName(&ofn))
|
||||
{
|
||||
TCHAR szFileName[MAX_LONG_PATH] = _T("");
|
||||
if (GetOpenFileName(szFileName, _countof(szFileName)))
|
||||
{
|
||||
HBITMAP hbmNew = DoLoadImageFile(m_hWnd, ofn.lpstrFile, FALSE);
|
||||
HBITMAP hbmNew = DoLoadImageFile(m_hWnd, szFileName, FALSE);
|
||||
if (hbmNew)
|
||||
{
|
||||
InsertSelectionFromHBITMAP(hbmNew, m_hWnd);
|
||||
|
@ -654,10 +708,14 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
|
|||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IDM_COLORSEDITPALETTE:
|
||||
if (ChooseColor(&choosecolor))
|
||||
paletteModel.SetFgColor(choosecolor.rgbResult);
|
||||
{
|
||||
COLORREF rgbColor = paletteModel.GetFgColor();
|
||||
if (ChooseColor(&rgbColor))
|
||||
paletteModel.SetFgColor(rgbColor);
|
||||
break;
|
||||
}
|
||||
case IDM_COLORSMODERNPALETTE:
|
||||
paletteModel.SelectPalette(PAL_MODERN);
|
||||
break;
|
||||
|
@ -773,8 +831,9 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
|
|||
imageArea.Invalidate(FALSE);
|
||||
break;
|
||||
case IDM_VIEWSHOWMINIATURE:
|
||||
showMiniature = !showMiniature;
|
||||
miniature.ShowWindow(showMiniature ? SW_SHOW : SW_HIDE);
|
||||
registrySettings.ShowThumbnail = !::IsWindowVisible(miniature);
|
||||
miniature.DoCreate(m_hWnd);
|
||||
miniature.ShowWindow(registrySettings.ShowThumbnail ? SW_SHOWNOACTIVATE : SW_HIDE);
|
||||
break;
|
||||
|
||||
case IDM_VIEWZOOM125:
|
||||
|
@ -800,7 +859,9 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
|
|||
break;
|
||||
|
||||
case IDM_VIEWFULLSCREEN:
|
||||
fullscreenWindow.ShowWindow(SW_SHOW);
|
||||
// Create and show the fullscreen window
|
||||
fullscreenWindow.DoCreate();
|
||||
fullscreenWindow.ShowWindow(SW_SHOWMAXIMIZED);
|
||||
ShowWindow(SW_HIDE);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,16 @@ public:
|
|||
MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel)
|
||||
END_MSG_MAP()
|
||||
|
||||
CMainWindow() : m_hMenu(NULL) { }
|
||||
|
||||
HWND DoCreate();
|
||||
BOOL GetOpenFileName(IN OUT LPTSTR pszFile, INT cchMaxFile);
|
||||
BOOL GetSaveFileName(IN OUT LPTSTR pszFile, INT cchMaxFile);
|
||||
BOOL ChooseColor(IN OUT COLORREF *prgbColor);
|
||||
|
||||
private:
|
||||
HMENU m_hMenu;
|
||||
|
||||
LRESULT OnDropFiles(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnDestroy(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
|
|
|
@ -543,6 +543,7 @@ public:
|
|||
|
||||
return (status == Ok ? S_OK : E_FAIL);
|
||||
}
|
||||
|
||||
HRESULT Save(LPCTSTR pszFileName,
|
||||
REFGUID guidFileType = GUID_NULL) const throw()
|
||||
{
|
||||
|
@ -828,15 +829,17 @@ protected:
|
|||
}
|
||||
};
|
||||
|
||||
// abbreviations of GDI+ basic types
|
||||
typedef Gdiplus::GpStatus St;
|
||||
typedef Gdiplus::GpBitmap Bm;
|
||||
typedef Gdiplus::GpImage Im;
|
||||
|
||||
// The common data of atlimage
|
||||
struct COMMON
|
||||
{
|
||||
// abbreviations of GDI+ basic types
|
||||
typedef Gdiplus::GpStatus St;
|
||||
typedef Gdiplus::ImageCodecInfo ICI;
|
||||
typedef Gdiplus::GpBitmap Bm;
|
||||
typedef Gdiplus::EncoderParameters EncParams;
|
||||
typedef Gdiplus::GpImage Im;
|
||||
typedef Gdiplus::ARGB ARGB;
|
||||
typedef HBITMAP HBM;
|
||||
typedef Gdiplus::GdiplusStartupInput GSI;
|
||||
|
|
Loading…
Reference in a new issue