https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3e23cdf9ee1268fe21916…
commit 3e23cdf9ee1268fe219168ebf8e8e0f544d6f0df
Author:     Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Wed Jul 5 12:06:22 2023 +0900
Commit:     GitHub <noreply(a)github.com>
CommitDate: Wed Jul 5 12:06:22 2023 +0900
    [MSPAINT] Some bug fixes on loading/saving files (#5385)
    - Display a correct error message on failing to save a file.
    - Don't confuse the main file info and the non-main file info.
    - Rename ShowFileLoadError as ShowError, and strengthen and move it to dialogs.cpp.
    - Add SetFileInfo and InitializeImage helper functions.
    - Add IDS_SAVEERROR resource string.
    - Modify SaveDIBToFile, SetBitmapAndInfo, and DoLoadImageFile functions.
    CORE-18867
---
 base/applications/mspaint/dialogs.cpp   |  16 ++++
 base/applications/mspaint/dialogs.h     |   2 +
 base/applications/mspaint/dib.cpp       | 164 ++++++++++++++++----------------
 base/applications/mspaint/dib.h         |  10 +-
 base/applications/mspaint/history.cpp   |   2 +-
 base/applications/mspaint/lang/bg-BG.rc |   1 +
 base/applications/mspaint/lang/cs-CZ.rc |   1 +
 base/applications/mspaint/lang/de-DE.rc |   1 +
 base/applications/mspaint/lang/en-GB.rc |   1 +
 base/applications/mspaint/lang/en-US.rc |   1 +
 base/applications/mspaint/lang/es-ES.rc |   1 +
 base/applications/mspaint/lang/et-EE.rc |   1 +
 base/applications/mspaint/lang/eu-ES.rc |   1 +
 base/applications/mspaint/lang/fr-FR.rc |   1 +
 base/applications/mspaint/lang/he-IL.rc |   1 +
 base/applications/mspaint/lang/hu-HU.rc |   1 +
 base/applications/mspaint/lang/id-ID.rc |   1 +
 base/applications/mspaint/lang/it-IT.rc |   1 +
 base/applications/mspaint/lang/ja-JP.rc |   1 +
 base/applications/mspaint/lang/nl-NL.rc |   1 +
 base/applications/mspaint/lang/no-NO.rc |   1 +
 base/applications/mspaint/lang/pl-PL.rc |   1 +
 base/applications/mspaint/lang/pt-BR.rc |   1 +
 base/applications/mspaint/lang/pt-PT.rc |   1 +
 base/applications/mspaint/lang/ro-RO.rc |   1 +
 base/applications/mspaint/lang/ru-RU.rc |   1 +
 base/applications/mspaint/lang/sk-SK.rc |   1 +
 base/applications/mspaint/lang/sq-AL.rc |   1 +
 base/applications/mspaint/lang/sv-SE.rc |   1 +
 base/applications/mspaint/lang/tr-TR.rc |   1 +
 base/applications/mspaint/lang/uk-UA.rc |   1 +
 base/applications/mspaint/lang/vi-VN.rc |   1 +
 base/applications/mspaint/lang/zh-CN.rc |   1 +
 base/applications/mspaint/lang/zh-HK.rc |   1 +
 base/applications/mspaint/lang/zh-TW.rc |   1 +
 base/applications/mspaint/main.cpp      |   6 +-
 base/applications/mspaint/resource.h    |   1 +
 base/applications/mspaint/winproc.cpp   |  26 +++--
 38 files changed, 149 insertions(+), 108 deletions(-)
diff --git a/base/applications/mspaint/dialogs.cpp b/base/applications/mspaint/dialogs.cpp
index 1d818616cd9..9c9fad3e567 100644
--- a/base/applications/mspaint/dialogs.cpp
+++ b/base/applications/mspaint/dialogs.cpp
@@ -22,6 +22,22 @@ CFontsDialog fontsDialog;
 /* FUNCTIONS ********************************************************/
+void ShowError(INT stringID, ...)
+{
+    va_list va;
+    va_start(va, stringID);
+
+    CStringW strFormat, strText;
+    strFormat.LoadString(stringID);
+    strText.FormatV(strFormat, va);
+
+    CStringW strProgramName;
+    strProgramName.LoadString(IDS_PROGRAMNAME);
+
+    mainWindow.MessageBox(strText, strProgramName, MB_ICONERROR);
+    va_end(va);
+}
+
 LRESULT CMirrorRotateDialog::OnInitDialog(UINT nMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled)
 {
     CheckDlgButton(IDD_MIRRORROTATERB1, BST_CHECKED);
diff --git a/base/applications/mspaint/dialogs.h b/base/applications/mspaint/dialogs.h
index b4c55c28adb..d760c59d556 100644
--- a/base/applications/mspaint/dialogs.h
+++ b/base/applications/mspaint/dialogs.h
@@ -7,6 +7,8 @@
 #pragma once
+void ShowError(INT stringID, ...);
+
 class CMirrorRotateDialog : public CDialogImpl<CMirrorRotateDialog>
 {
 public:
diff --git a/base/applications/mspaint/dib.cpp b/base/applications/mspaint/dib.cpp
index 4723b25f465..ea5ead7427a 100644
--- a/base/applications/mspaint/dib.cpp
+++ b/base/applications/mspaint/dib.cpp
@@ -142,76 +142,65 @@ GetDIBHeight(HBITMAP hBitmap)
     return bm.bmHeight;
 }
-BOOL SaveDIBToFile(HBITMAP hBitmap, LPCTSTR FileName, HDC hDC)
+BOOL SaveDIBToFile(HBITMAP hBitmap, LPCWSTR FileName, BOOL fIsMainFile)
 {
     CImageDx img;
     img.Attach(hBitmap);
-    img.SaveDx(FileName, GUID_NULL, g_xDpi, g_yDpi); // TODO: error handling
+    HRESULT hr = img.SaveDx(FileName, GUID_NULL, g_xDpi, g_yDpi);
     img.Detach();
-    WIN32_FIND_DATA find;
-    HANDLE hFind = FindFirstFile(FileName, &find);
-    if (hFind == INVALID_HANDLE_VALUE)
+    if (FAILED(hr))
     {
-        ShowFileLoadError(FileName);
+        ShowError(IDS_SAVEERROR, FileName);
         return FALSE;
     }
-    FindClose(hFind);
-    // update time and size
-    FILETIME ft;
-    FileTimeToLocalFileTime(&find.ftLastWriteTime, &ft);
-    FileTimeToSystemTime(&ft, &g_fileTime);
-    g_fileSize = find.nFileSizeLow;
+    if (!fIsMainFile)
+        return TRUE;
-    // TODO: update hRes and vRes
-
-    registrySettings.SetMostRecentFile(FileName);
+    WIN32_FIND_DATAW find;
+    HANDLE hFind = ::FindFirstFileW(FileName, &find);
+    if (hFind == INVALID_HANDLE_VALUE)
+    {
+        ShowError(IDS_SAVEERROR, FileName);
+        return FALSE;
+    }
+    ::FindClose(hFind);
-    g_isAFile = TRUE;
+    SetFileInfo(FileName, &find, TRUE);
     g_imageSaved = TRUE;
     return TRUE;
 }
-void ShowFileLoadError(LPCTSTR name)
+void SetFileInfo(LPCWSTR name, LPWIN32_FIND_DATAW pFound, BOOL isAFile)
 {
-    CString strText;
-    strText.Format(IDS_LOADERRORTEXT, (LPCTSTR) name);
-    CString strProgramName;
-    strProgramName.LoadString(IDS_PROGRAMNAME);
-    mainWindow.MessageBox(strText, strProgramName, MB_OK | MB_ICONEXCLAMATION);
-}
-
-HBITMAP SetBitmapAndInfo(HBITMAP hBitmap, LPCTSTR name, DWORD dwFileSize, BOOL isFile)
-{
-    if (hBitmap == NULL)
+    // update file time and size
+    if (pFound)
     {
-        COLORREF white = RGB(255, 255, 255);
-        hBitmap = CreateColorDIB(registrySettings.BMPWidth,
-                                 registrySettings.BMPHeight, white);
-        if (hBitmap == NULL)
-            return FALSE;
-
-        HDC hScreenDC = GetDC(NULL);
-        g_xDpi = GetDeviceCaps(hScreenDC, LOGPIXELSX);
-        g_yDpi = GetDeviceCaps(hScreenDC, LOGPIXELSY);
-        ReleaseDC(NULL, hScreenDC);
+        FILETIME ft;
+        ::FileTimeToLocalFileTime(&pFound->ftLastWriteTime, &ft);
+        ::FileTimeToSystemTime(&ft, &g_fileTime);
+        g_fileSize = pFound->nFileSizeLow;
+    }
+    else
+    {
         ZeroMemory(&g_fileTime, sizeof(g_fileTime));
+        g_fileSize = 0;
     }
-    // update image
-    imageModel.PushImageForUndo(hBitmap);
-    imageModel.ClearHistory();
-
-    // update g_fileSize
-    g_fileSize = dwFileSize;
-
     // update g_szFileName
     if (name && name[0])
-        GetFullPathName(name, _countof(g_szFileName), g_szFileName, NULL);
+    {
+        CStringW strName = name;
+        ::GetFullPathNameW(strName, _countof(g_szFileName), g_szFileName, NULL);
+        // The following code won't work correctly when (name == g_szFileName):
+        //   ::GetFullPathNameW(name, _countof(g_szFileName), g_szFileName, NULL);
+    }
     else
-        LoadString(g_hinstExe, IDS_DEFAULTFILENAME, g_szFileName,
_countof(g_szFileName));
+    {
+        ::LoadStringW(g_hinstExe, IDS_DEFAULTFILENAME, g_szFileName,
_countof(g_szFileName));
+    }
     // set title
     CString strTitle;
@@ -219,71 +208,80 @@ HBITMAP SetBitmapAndInfo(HBITMAP hBitmap, LPCTSTR name, DWORD
dwFileSize, BOOL i
     mainWindow.SetWindowText(strTitle);
     // update file info and recent
-    g_isAFile = isFile;
+    g_isAFile = isAFile;
     if (g_isAFile)
         registrySettings.SetMostRecentFile(g_szFileName);
     g_imageSaved = TRUE;
+}
+
+HBITMAP InitializeImage(LPCWSTR name, LPWIN32_FIND_DATAW pFound, BOOL isFile)
+{
+    COLORREF white = RGB(255, 255, 255);
+    HBITMAP hBitmap = CreateColorDIB(registrySettings.BMPWidth,
registrySettings.BMPHeight, white);
+    if (hBitmap == NULL)
+        return NULL;
+
+    HDC hScreenDC = ::GetDC(NULL);
+    g_xDpi = ::GetDeviceCaps(hScreenDC, LOGPIXELSX);
+    g_yDpi = ::GetDeviceCaps(hScreenDC, LOGPIXELSY);
+    ::ReleaseDC(NULL, hScreenDC);
+
+    return SetBitmapAndInfo(hBitmap, name, pFound, isFile);
+}
+HBITMAP SetBitmapAndInfo(HBITMAP hBitmap, LPCWSTR name, LPWIN32_FIND_DATAW pFound, BOOL
isFile)
+{
+    // update image
+    imageModel.PushImageForUndo(hBitmap);
+    imageModel.ClearHistory();
+
+    SetFileInfo(name, pFound, isFile);
+    g_imageSaved = TRUE;
     return hBitmap;
 }
-HBITMAP DoLoadImageFile(HWND hwnd, LPCTSTR name, BOOL fIsMainFile)
+HBITMAP DoLoadImageFile(HWND hwnd, LPCWSTR name, BOOL fIsMainFile)
 {
     // find the file
     WIN32_FIND_DATA find;
-    HANDLE hFind = FindFirstFile(name, &find);
-    if (hFind == INVALID_HANDLE_VALUE)
+    HANDLE hFind = ::FindFirstFileW(name, &find);
+    if (hFind == INVALID_HANDLE_VALUE) // does not exist
     {
-        // does not exist
-        CStringW strText;
-        strText.Format(IDS_LOADERRORTEXT, name);
-        MessageBoxW(hwnd, strText, NULL, MB_ICONERROR);
+        ShowError(IDS_LOADERRORTEXT, name);
         return NULL;
     }
-    DWORD dwFileSize = find.nFileSizeLow; // get file size
-    FindClose(hFind);
+    ::FindClose(hFind);
     // is file empty?
-    if (dwFileSize == 0)
+    if (find.nFileSizeLow == 0 && find.nFileSizeHigh == 0)
     {
         if (fIsMainFile)
-        {
-            FILETIME ft;
-            FileTimeToLocalFileTime(&find.ftLastWriteTime, &ft);
-            FileTimeToSystemTime(&ft, &g_fileTime);
-            return SetBitmapAndInfo(NULL, name, dwFileSize, TRUE);
-        }
+            return InitializeImage(name, &find, TRUE);
     }
     // load the image
     CImageDx img;
-    img.LoadDx(name, &g_xDpi, &g_yDpi);
+    float xDpi, yDpi;
+    HRESULT hr = img.LoadDx(name, &xDpi, &yDpi);
+    if (FAILED(hr))
+    {
+        ShowError(IDS_LOADERRORTEXT, name);
+        return NULL;
+    }
+
+    HBITMAP hBitmap = img.Detach();
+    if (!fIsMainFile)
+        return hBitmap;
+    g_xDpi = xDpi;
+    g_yDpi = yDpi;
     if (g_xDpi <= 0)
         g_xDpi = 96;
     if (g_yDpi <= 0)
         g_yDpi = 96;
-    HBITMAP hBitmap = img.Detach();
-
-    if (hBitmap == NULL)
-    {
-        // cannot open
-        CStringW strText;
-        strText.Format(IDS_LOADERRORTEXT, name);
-        MessageBoxW(hwnd, strText, NULL, MB_ICONERROR);
-        return NULL;
-    }
-
-    if (fIsMainFile)
-    {
-        FILETIME ft;
-        FileTimeToLocalFileTime(&find.ftLastWriteTime, &ft);
-        FileTimeToSystemTime(&ft, &g_fileTime);
-        SetBitmapAndInfo(hBitmap, name, dwFileSize, TRUE);
-    }
-
+    SetBitmapAndInfo(hBitmap, name, &find, TRUE);
     return hBitmap;
 }
diff --git a/base/applications/mspaint/dib.h b/base/applications/mspaint/dib.h
index 0ddb5067db5..9c1e5d4f09c 100644
--- a/base/applications/mspaint/dib.h
+++ b/base/applications/mspaint/dib.h
@@ -20,16 +20,16 @@ static inline HBITMAP CopyDIBImage(HBITMAP hbm, INT cx = 0, INT cy =
0)
 }
 int GetDIBWidth(HBITMAP hbm);
-
 int GetDIBHeight(HBITMAP hbm);
-BOOL SaveDIBToFile(HBITMAP hBitmap, LPCTSTR FileName, HDC hDC);
+BOOL SaveDIBToFile(HBITMAP hBitmap, LPCWSTR FileName, BOOL fIsMainFile);
-HBITMAP DoLoadImageFile(HWND hwnd, LPCTSTR name, BOOL fIsMainFile);
+HBITMAP DoLoadImageFile(HWND hwnd, LPCWSTR name, BOOL fIsMainFile);
-void ShowFileLoadError(LPCTSTR name);
+void SetFileInfo(LPCWSTR name, LPWIN32_FIND_DATAW pFound, BOOL isAFile);
-HBITMAP SetBitmapAndInfo(HBITMAP hBitmap, LPCTSTR name, DWORD dwFileSize, BOOL isFile);
+HBITMAP InitializeImage(LPCWSTR name, LPWIN32_FIND_DATAW pFound, BOOL isFile);
+HBITMAP SetBitmapAndInfo(HBITMAP hBitmap, LPCWSTR name, LPWIN32_FIND_DATAW pFound, BOOL
isFile);
 HBITMAP Rotate90DegreeBlt(HDC hDC1, INT cx, INT cy, BOOL bRight, BOOL bMono);
diff --git a/base/applications/mspaint/history.cpp b/base/applications/mspaint/history.cpp
index 3b861b1840c..3f1878ad3d3 100644
--- a/base/applications/mspaint/history.cpp
+++ b/base/applications/mspaint/history.cpp
@@ -159,7 +159,7 @@ void ImageModel::Crop(int nWidth, int nHeight, int nOffsetX, int
nOffsetY)
 void ImageModel::SaveImage(LPCTSTR lpFileName)
 {
-    SaveDIBToFile(m_hBms[m_currInd], lpFileName, m_hDrawingDC);
+    SaveDIBToFile(m_hBms[m_currInd], lpFileName, TRUE);
 }
 BOOL ImageModel::IsImageSaved() const
diff --git a/base/applications/mspaint/lang/bg-BG.rc
b/base/applications/mspaint/lang/bg-BG.rc
index bdb017608e6..31663fde2d3 100644
--- a/base/applications/mspaint/lang/bg-BG.rc
+++ b/base/applications/mspaint/lang/bg-BG.rc
@@ -262,4 +262,5 @@ BEGIN
     IDS_VERTICAL "Вертикален"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/cs-CZ.rc
b/base/applications/mspaint/lang/cs-CZ.rc
index f500d7ebc52..c1d67ce1682 100644
--- a/base/applications/mspaint/lang/cs-CZ.rc
+++ b/base/applications/mspaint/lang/cs-CZ.rc
@@ -262,4 +262,5 @@ BEGIN
     IDS_VERTICAL "Vertical"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/de-DE.rc
b/base/applications/mspaint/lang/de-DE.rc
index 086c5bb953c..fc46fe2f042 100644
--- a/base/applications/mspaint/lang/de-DE.rc
+++ b/base/applications/mspaint/lang/de-DE.rc
@@ -261,4 +261,5 @@ BEGIN
     IDS_VERTICAL "Vertical"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/en-GB.rc
b/base/applications/mspaint/lang/en-GB.rc
index 699fc815286..c653732c4d8 100644
--- a/base/applications/mspaint/lang/en-GB.rc
+++ b/base/applications/mspaint/lang/en-GB.rc
@@ -261,4 +261,5 @@ BEGIN
     IDS_VERTICAL "Vertical"
     IDS_PRINTRES "%d x %d dots per inch"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/en-US.rc
b/base/applications/mspaint/lang/en-US.rc
index b3d8f58be45..9de01a2499f 100644
--- a/base/applications/mspaint/lang/en-US.rc
+++ b/base/applications/mspaint/lang/en-US.rc
@@ -262,4 +262,5 @@ BEGIN
     IDS_VERTICAL "Vertical"
     IDS_PRINTRES "%d x %d dots per inch"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/es-ES.rc
b/base/applications/mspaint/lang/es-ES.rc
index 734938c6e7e..d30226ccaf7 100644
--- a/base/applications/mspaint/lang/es-ES.rc
+++ b/base/applications/mspaint/lang/es-ES.rc
@@ -264,4 +264,5 @@ BEGIN
     IDS_VERTICAL "Vertical"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/et-EE.rc
b/base/applications/mspaint/lang/et-EE.rc
index eb1f2eb2a11..0c2b543cbe6 100644
--- a/base/applications/mspaint/lang/et-EE.rc
+++ b/base/applications/mspaint/lang/et-EE.rc
@@ -261,4 +261,5 @@ BEGIN
     IDS_VERTICAL "Vertical"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/eu-ES.rc
b/base/applications/mspaint/lang/eu-ES.rc
index e06db967538..273f8c9f20a 100644
--- a/base/applications/mspaint/lang/eu-ES.rc
+++ b/base/applications/mspaint/lang/eu-ES.rc
@@ -262,4 +262,5 @@ BEGIN
     IDS_VERTICAL "Vertical"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/fr-FR.rc
b/base/applications/mspaint/lang/fr-FR.rc
index 38f365838e5..aee25ef236b 100644
--- a/base/applications/mspaint/lang/fr-FR.rc
+++ b/base/applications/mspaint/lang/fr-FR.rc
@@ -262,4 +262,5 @@ BEGIN
     IDS_VERTICAL "Vertical"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/he-IL.rc
b/base/applications/mspaint/lang/he-IL.rc
index eec4f332e19..e02fcea3758 100644
--- a/base/applications/mspaint/lang/he-IL.rc
+++ b/base/applications/mspaint/lang/he-IL.rc
@@ -264,4 +264,5 @@ BEGIN
     IDS_VERTICAL "Vertical"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/hu-HU.rc
b/base/applications/mspaint/lang/hu-HU.rc
index 195907b30dd..ff132eda6f9 100644
--- a/base/applications/mspaint/lang/hu-HU.rc
+++ b/base/applications/mspaint/lang/hu-HU.rc
@@ -262,4 +262,5 @@ BEGIN
     IDS_VERTICAL "Vertical"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/id-ID.rc
b/base/applications/mspaint/lang/id-ID.rc
index 888c1557ed9..ad2d99b362a 100644
--- a/base/applications/mspaint/lang/id-ID.rc
+++ b/base/applications/mspaint/lang/id-ID.rc
@@ -261,4 +261,5 @@ BEGIN
     IDS_VERTICAL "Vertical"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/it-IT.rc
b/base/applications/mspaint/lang/it-IT.rc
index 9470b433909..45ff4d842e9 100644
--- a/base/applications/mspaint/lang/it-IT.rc
+++ b/base/applications/mspaint/lang/it-IT.rc
@@ -262,4 +262,5 @@ BEGIN
     IDS_VERTICAL "Vertical"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/ja-JP.rc
b/base/applications/mspaint/lang/ja-JP.rc
index 17e48fbfe11..b44eb8b4b74 100644
--- a/base/applications/mspaint/lang/ja-JP.rc
+++ b/base/applications/mspaint/lang/ja-JP.rc
@@ -263,4 +263,5 @@ BEGIN
     IDS_VERTICAL "縦書き"
     IDS_PRINTRES "%d x %d ピクセル/cm"
     IDS_CANTPASTE "クリップボードからの貼り付けに失敗しました。データ形式が間違っているか、未対応です。"
+    IDS_SAVEERROR "次のファイルとして画像を保存するのに失敗しました:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/nl-NL.rc
b/base/applications/mspaint/lang/nl-NL.rc
index 2d348a9ab8d..62ae6c4e47a 100644
--- a/base/applications/mspaint/lang/nl-NL.rc
+++ b/base/applications/mspaint/lang/nl-NL.rc
@@ -261,4 +261,5 @@ BEGIN
     IDS_VERTICAL "Vertical"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/no-NO.rc
b/base/applications/mspaint/lang/no-NO.rc
index e400c5bc2bb..b6014ef58e0 100644
--- a/base/applications/mspaint/lang/no-NO.rc
+++ b/base/applications/mspaint/lang/no-NO.rc
@@ -261,4 +261,5 @@ BEGIN
     IDS_VERTICAL "Vertical"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/pl-PL.rc
b/base/applications/mspaint/lang/pl-PL.rc
index 80d75558f8e..0714c9ce3cb 100644
--- a/base/applications/mspaint/lang/pl-PL.rc
+++ b/base/applications/mspaint/lang/pl-PL.rc
@@ -264,4 +264,5 @@ BEGIN
     IDS_VERTICAL "Pionowe"
     IDS_PRINTRES "%d x %d piksel/cm"
     IDS_CANTPASTE "Nie można wkleić ze schowka. Format danych jest nieprawidłowy lub
nieobsługiwany."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/pt-BR.rc
b/base/applications/mspaint/lang/pt-BR.rc
index c3fc84f47a8..0c8442b4b35 100644
--- a/base/applications/mspaint/lang/pt-BR.rc
+++ b/base/applications/mspaint/lang/pt-BR.rc
@@ -262,4 +262,5 @@ BEGIN
     IDS_VERTICAL "Vertical"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/pt-PT.rc
b/base/applications/mspaint/lang/pt-PT.rc
index f1378126d93..e150cfa14a2 100644
--- a/base/applications/mspaint/lang/pt-PT.rc
+++ b/base/applications/mspaint/lang/pt-PT.rc
@@ -262,4 +262,5 @@ BEGIN
     IDS_VERTICAL "Vertical"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/ro-RO.rc
b/base/applications/mspaint/lang/ro-RO.rc
index 398201aec18..3fce7fbca19 100644
--- a/base/applications/mspaint/lang/ro-RO.rc
+++ b/base/applications/mspaint/lang/ro-RO.rc
@@ -263,4 +263,5 @@ BEGIN
     IDS_VERTICAL "Vertical"
     IDS_PRINTRES "%d x %d pixeli/cm"
     IDS_CANTPASTE "Nu a putut fi lipit din clipboard. Formatul de date este fie
incorect, fie nesuportat."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/ru-RU.rc
b/base/applications/mspaint/lang/ru-RU.rc
index 61e2a6f8382..ded8d919f0f 100644
--- a/base/applications/mspaint/lang/ru-RU.rc
+++ b/base/applications/mspaint/lang/ru-RU.rc
@@ -265,4 +265,5 @@ BEGIN
     IDS_VERTICAL "Вертикальный"
     IDS_PRINTRES "%d x %d точек/см"
     IDS_CANTPASTE "Не удалось вставить из буфера обмена. Формат данных либо
некорректный, либо не поддерживается."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/sk-SK.rc
b/base/applications/mspaint/lang/sk-SK.rc
index b85e192dd3d..1fb92dbb4f6 100644
--- a/base/applications/mspaint/lang/sk-SK.rc
+++ b/base/applications/mspaint/lang/sk-SK.rc
@@ -261,4 +261,5 @@ BEGIN
     IDS_VERTICAL "Vertical"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/sq-AL.rc
b/base/applications/mspaint/lang/sq-AL.rc
index 1488e35ede6..b2122a03273 100644
--- a/base/applications/mspaint/lang/sq-AL.rc
+++ b/base/applications/mspaint/lang/sq-AL.rc
@@ -261,4 +261,5 @@ BEGIN
     IDS_VERTICAL "Vertical"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/sv-SE.rc
b/base/applications/mspaint/lang/sv-SE.rc
index cf9ab447e42..3d92c35f6c6 100644
--- a/base/applications/mspaint/lang/sv-SE.rc
+++ b/base/applications/mspaint/lang/sv-SE.rc
@@ -262,4 +262,5 @@ BEGIN
     IDS_VERTICAL "Vertical"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/tr-TR.rc
b/base/applications/mspaint/lang/tr-TR.rc
index 3113476be88..a87fb699142 100644
--- a/base/applications/mspaint/lang/tr-TR.rc
+++ b/base/applications/mspaint/lang/tr-TR.rc
@@ -262,4 +262,5 @@ BEGIN
     IDS_VERTICAL "Düşey"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/uk-UA.rc
b/base/applications/mspaint/lang/uk-UA.rc
index 2858cfb2432..a998b99363a 100644
--- a/base/applications/mspaint/lang/uk-UA.rc
+++ b/base/applications/mspaint/lang/uk-UA.rc
@@ -263,4 +263,5 @@ BEGIN
     IDS_VERTICAL "Vertical"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/vi-VN.rc
b/base/applications/mspaint/lang/vi-VN.rc
index 3e1e85f1102..0db569f74f3 100644
--- a/base/applications/mspaint/lang/vi-VN.rc
+++ b/base/applications/mspaint/lang/vi-VN.rc
@@ -261,4 +261,5 @@ BEGIN
     IDS_VERTICAL "Vertical"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/zh-CN.rc
b/base/applications/mspaint/lang/zh-CN.rc
index 307a0cda341..d40e2390b77 100644
--- a/base/applications/mspaint/lang/zh-CN.rc
+++ b/base/applications/mspaint/lang/zh-CN.rc
@@ -264,4 +264,5 @@ BEGIN
     IDS_VERTICAL "垂直"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/zh-HK.rc
b/base/applications/mspaint/lang/zh-HK.rc
index ea6ca319c38..85dd5341843 100644
--- a/base/applications/mspaint/lang/zh-HK.rc
+++ b/base/applications/mspaint/lang/zh-HK.rc
@@ -262,4 +262,5 @@ BEGIN
     IDS_VERTICAL "垂直"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/lang/zh-TW.rc
b/base/applications/mspaint/lang/zh-TW.rc
index 4b90a8185ea..b044da06910 100644
--- a/base/applications/mspaint/lang/zh-TW.rc
+++ b/base/applications/mspaint/lang/zh-TW.rc
@@ -262,4 +262,5 @@ BEGIN
     IDS_VERTICAL "垂直"
     IDS_PRINTRES "%d x %d pixel/cm"
     IDS_CANTPASTE "Failed to paste from the clipboard. The data format is either
incorrect or not supported."
+    IDS_SAVEERROR "Failed to save an image as the following file:\n\n%s"
 END
diff --git a/base/applications/mspaint/main.cpp b/base/applications/mspaint/main.cpp
index ef0b5da6aa1..a4cbb54b5b0 100644
--- a/base/applications/mspaint/main.cpp
+++ b/base/applications/mspaint/main.cpp
@@ -209,10 +209,8 @@ _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR
lpCmdLine, INT nC
     }
     // Initialize imageModel
-    imageModel.Crop(registrySettings.BMPWidth, registrySettings.BMPHeight);
-    if (__argc >= 2)
-        DoLoadImageFile(mainWindow, __targv[1], TRUE);
-    imageModel.ClearHistory();
+    if (__argc < 2 || !DoLoadImageFile(mainWindow, __targv[1], TRUE))
+        InitializeImage(NULL, NULL, FALSE);
     // Make the window visible on the screen
     mainWindow.ShowWindow(registrySettings.WindowPlacement.showCmd);
diff --git a/base/applications/mspaint/resource.h b/base/applications/mspaint/resource.h
index 3b9f530a6e5..1e34232d3c1 100644
--- a/base/applications/mspaint/resource.h
+++ b/base/applications/mspaint/resource.h
@@ -220,3 +220,4 @@
 #define IDS_VERTICAL    938
 #define IDS_PRINTRES    939
 #define IDS_CANTPASTE   940
+#define IDS_SAVEERROR   941
diff --git a/base/applications/mspaint/winproc.cpp b/base/applications/mspaint/winproc.cpp
index 161a4926fe9..a15e6dd3d6b 100644
--- a/base/applications/mspaint/winproc.cpp
+++ b/base/applications/mspaint/winproc.cpp
@@ -148,11 +148,6 @@ void CMainWindow::saveImage(BOOL overwrite)
     else if (GetSaveFileName(g_szFileName, _countof(g_szFileName)))
     {
         imageModel.SaveImage(g_szFileName);
-
-        CString strTitle;
-        strTitle.Format(IDS_WINDOWTITLE, PathFindFileName(g_szFileName));
-        SetWindowText(strTitle);
-        g_isAFile = TRUE;
     }
 }
@@ -201,7 +196,6 @@ void CMainWindow::InsertSelectionFromHBITMAP(HBITMAP bitmap, HWND
window)
     toolsModel.SetActiveTool(TOOL_RECTSEL);
-    imageModel.PushImageForUndo();
     selectionModel.InsertFromHBITMAP(bitmap, 0, 0);
     selectionModel.m_bShow = TRUE;
     imageModel.NotifyImageChanged();
@@ -380,9 +374,10 @@ void CMainWindow::ProcessFileMenu(HMENU hPopupMenu)
         isBMP = TRUE;
     }
-    EnableMenuItem(hPopupMenu, IDM_FILEASWALLPAPERPLANE,     ENABLED_IF(g_isAFile
&& isBMP));
-    EnableMenuItem(hPopupMenu, IDM_FILEASWALLPAPERCENTERED,  ENABLED_IF(g_isAFile
&& isBMP));
-    EnableMenuItem(hPopupMenu, IDM_FILEASWALLPAPERSTRETCHED, ENABLED_IF(g_isAFile
&& isBMP));
+    UINT uWallpaperEnabled = ENABLED_IF(g_isAFile && isBMP && g_fileSize
> 0);
+    ::EnableMenuItem(hPopupMenu, IDM_FILEASWALLPAPERPLANE,     uWallpaperEnabled);
+    ::EnableMenuItem(hPopupMenu, IDM_FILEASWALLPAPERCENTERED,  uWallpaperEnabled);
+    ::EnableMenuItem(hPopupMenu, IDM_FILEASWALLPAPERSTRETCHED, uWallpaperEnabled);
     for (INT iItem = 0; iItem < MAX_RECENT_FILES; ++iItem)
         RemoveMenu(hPopupMenu, IDM_FILE1 + iItem, MF_BYCOMMAND);
@@ -612,7 +607,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bH
         case IDM_FILENEW:
             if (ConfirmSave())
             {
-                SetBitmapAndInfo(NULL, NULL, 0, FALSE);
+                InitializeImage(NULL, NULL, FALSE);
             }
             break;
         case IDM_FILEOPEN:
@@ -850,25 +845,26 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bH
         }
         case IDM_EDITCOPYTO:
         {
-            TCHAR szFileName[MAX_LONG_PATH] = _T("");
+            WCHAR szFileName[MAX_LONG_PATH] = L"*.png";
             if (GetSaveFileName(szFileName, _countof(szFileName)))
             {
                 HBITMAP hbm = selectionModel.CopyBitmap();
-                SaveDIBToFile(hbm, szFileName, imageModel.GetDC());
+                if (!SaveDIBToFile(hbm, szFileName, FALSE))
+                    ShowError(IDS_SAVEERROR, szFileName);
                 ::DeleteObject(hbm);
             }
             break;
         }
         case IDM_EDITPASTEFROM:
         {
-            TCHAR szFileName[MAX_LONG_PATH] = _T("");
+            WCHAR szFileName[MAX_LONG_PATH] = L"";
             if (GetOpenFileName(szFileName, _countof(szFileName)))
             {
                 HBITMAP hbmNew = DoLoadImageFile(m_hWnd, szFileName, FALSE);
                 if (hbmNew)
-                {
                     InsertSelectionFromHBITMAP(hbmNew, m_hWnd);
-                }
+                else
+                    ShowError(IDS_LOADERRORTEXT, szFileName);
             }
             break;
         }