[MSPAINT][ATL] Encapsulation: mainWindow (#5178)
authorKatayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
Tue, 28 Mar 2023 13:31:26 +0000 (22:31 +0900)
committerGitHub <noreply@github.com>
Tue, 28 Mar 2023 13:31:26 +0000 (22:31 +0900)
- 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

29 files changed:
base/applications/mspaint/atlimagedx.h [new file with mode: 0644]
base/applications/mspaint/canvas.cpp
base/applications/mspaint/common.h
base/applications/mspaint/dialogs.cpp
base/applications/mspaint/dib.cpp
base/applications/mspaint/dib.h
base/applications/mspaint/fullscreen.cpp
base/applications/mspaint/fullscreen.h
base/applications/mspaint/globalvar.h
base/applications/mspaint/history.cpp
base/applications/mspaint/imgarea.cpp
base/applications/mspaint/imgarea.h
base/applications/mspaint/main.cpp
base/applications/mspaint/miniature.cpp
base/applications/mspaint/miniature.h
base/applications/mspaint/palette.cpp
base/applications/mspaint/palettemodel.cpp
base/applications/mspaint/precomp.h
base/applications/mspaint/registry.cpp
base/applications/mspaint/selection.cpp
base/applications/mspaint/selectionmodel.cpp
base/applications/mspaint/textedit.cpp
base/applications/mspaint/toolbox.cpp
base/applications/mspaint/toolsettings.cpp
base/applications/mspaint/toolsmodel.cpp
base/applications/mspaint/toolsmodel.h
base/applications/mspaint/winproc.cpp
base/applications/mspaint/winproc.h
sdk/lib/atl/atlimage.h

diff --git a/base/applications/mspaint/atlimagedx.h b/base/applications/mspaint/atlimagedx.h
new file mode 100644 (file)
index 0000000..98ecb86
--- /dev/null
@@ -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;
+};
index 591d1ba..d538925 100644 (file)
@@ -6,10 +6,10 @@
  * PROGRAMMERS: Benedikt Freisen
  */
 
-/* INCLUDES *********************************************************/
-
 #include "precomp.h"
 
+CCanvasWindow canvasWindow;
+
 /* FUNCTIONS ********************************************************/
 
 CCanvasWindow::CCanvasWindow()
index af55873..619133f 100644 (file)
 #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)
 
 /* 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();
-}
index 2b0798f..b593058 100644 (file)
@@ -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))
         {
index 529d7c9..96218a8 100644 (file)
@@ -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)
index e0f8d14..82ccde6 100644 (file)
@@ -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);
index 4ea0409..610062c 100644 (file)
@@ -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)));
index 64f3ce0..4466b11 100644 (file)
@@ -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);
index 3a366c0..fe9e47f 100644 (file)
 
 /* 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 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 TCHAR filepathname[MAX_LONG_PATH];
 extern BOOL isAFile;
 extern BOOL imageSaved;
-extern int fileSize;
-extern int fileHPPM;
-extern int fileVPPM;
-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;
+
+/* 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;
+extern SelectionModel selectionModel;
+extern PaletteModel paletteModel;
+
+extern HWND hStatusBar;
+extern float g_xDpi;
+extern float g_yDpi;
+extern INT fileSize;
+extern SYSTEMTIME fileTime;
+
 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;
index f0a3691..847e6c6 100644 (file)
@@ -6,10 +6,10 @@
  * PROGRAMMERS: Benedikt Freisen
  */
 
-/* INCLUDES *********************************************************/
-
 #include "precomp.h"
 
+ImageModel imageModel;
+
 /* FUNCTIONS ********************************************************/
 
 void ImageModel::NotifyDimensionsChanged()
index aa116dc..dfb9345 100644 (file)
@@ -10,6 +10,8 @@
 
 #include "precomp.h"
 
+CImgAreaWindow imageArea;
+
 /* FUNCTIONS ********************************************************/
 
 LRESULT CImgAreaWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
index d7b44e5..daef656 100644 (file)
@@ -13,9 +13,7 @@
 class CImgAreaWindow : public CWindowImpl<CImgAreaWindow>
 {
 public:
-    CImgAreaWindow() : drawing(FALSE)
-    {
-    }
+    CImgAreaWindow() : drawing(FALSE) { }
 
     BOOL drawing;
     void cancelDrawing();
index 170610c..971bfbb 100644 (file)
@@ -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 */
+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(hProgInstance, 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   = 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;
 
-int WINAPI
-_tWinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPTSTR lpszArgument, INT nCmdShow)
+    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)
 {
-    HWND hwnd;               /* This is the handle for our window */
-    MSG messages;            /* Here messages to the application are saved */
-
-    HMENU menu;
-    HACCEL haccel;
-
-    TCHAR sfnFilename[1000];
-    TCHAR sfnFiletitle[256];
-    TCHAR ofnFilename[1000];
-    TCHAR ofnFiletitle[256];
-    TCHAR miniaturetitle[100];
-    static COLORREF custColors[16] = {
+    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;
-
-    /* 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";
-
-    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)
-    {
-        if (aguidFileTypesE[i] == Gdiplus::ImageFormatPNG)
-        {
-            sfn.nFilterIndex = i + 1;
-            break;
-        }
-    }
+    // Make the window visible on the screen
+    mainWindow.ShowWindow(registrySettings.WindowPlacement.showCmd);
 
-    /* placing the size boxes around the image */
-    imageArea.SendMessage(WM_SIZE, 0, 0);
+    // Load the access keys
+    HACCEL hAccel = ::LoadAccelerators(hInstance, MAKEINTRESOURCE(800));
 
-    /* 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))
+    // The message loop
+    MSG msg;
+    while (::GetMessage(&msg, 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;
 }
index b9efd88..c048d0d 100644 (file)
@@ -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;
 }
 
index 57fe955..b68d03a 100644 (file)
@@ -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);
index 7795b97..161d056 100644 (file)
@@ -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;
 }
index c91899b..b4ae440 100644 (file)
@@ -7,10 +7,10 @@
  *              Katayama Hirofumi MZ
  */
 
-/* INCLUDES *********************************************************/
-
 #include "precomp.h"
 
+PaletteModel paletteModel;
+
 /* FUNCTIONS ********************************************************/
 
 PaletteModel::PaletteModel()
index c73cd80..5dda7a9 100644 (file)
@@ -6,8 +6,6 @@
     #undef _DEBUG
 #endif
 
-#include <stdarg.h>
-
 #include <windef.h>
 #include <winbase.h>
 #include <winuser.h>
 #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 */
index bb97301..fbf659f 100644 (file)
@@ -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;
index 4a328b0..1426e08 100644 (file)
@@ -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 */
index 3cd41e1..2079f7a 100644 (file)
@@ -7,10 +7,10 @@
  *              Katayama Hirofumi MZ
  */
 
-/* INCLUDES *********************************************************/
-
 #include "precomp.h"
 
+SelectionModel selectionModel;
+
 /* FUNCTIONS ********************************************************/
 
 SelectionModel::SelectionModel()
index 881a00b..6a05ceb 100644 (file)
@@ -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)
index 793c62b..6ba2337 100644 (file)
@@ -7,10 +7,10 @@
  * PROGRAMMERS: Benedikt Freisen
  */
 
-/* INCLUDES *********************************************************/
-
 #include "precomp.h"
 
+CToolBox toolBoxContainer;
+
 /* FUNCTIONS ********************************************************/
 
 BOOL CToolBox::DoCreate(HWND hwndParent)
index c8b3978..d70a3dd 100644 (file)
 
 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,
index 5d5c7fe..3434163 100644 (file)
@@ -6,10 +6,10 @@
  * PROGRAMMERS: Benedikt Freisen
  */
 
-/* INCLUDES *********************************************************/
-
 #include "precomp.h"
 
+ToolsModel toolsModel;
+
 /* FUNCTIONS ********************************************************/
 
 ToolsModel::ToolsModel()
index 9d3a053..c7fc230 100644 (file)
@@ -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();
+}
index 5208e37..ee09d6f 100644 (file)
@@ -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;
     }
index 71db5e7..5ec12f2 100644 (file)
@@ -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);
index f84d8cb..5d8eed0 100644 (file)
@@ -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;