https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9f56e67bc2f25b21ce787…
commit 9f56e67bc2f25b21ce7870f922855945acb8895a
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sun Jun 18 19:48:20 2023 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Sun Jun 18 19:48:20 2023 +0900
[MSPAINT] Use CF_DIB instead of CF_BITMAP (#5349)
CF_BITMAP is not recommended format for copying. In fact, Win10 won't accept it.
- Use CF_DIB clipboard format instead of CF_BITMAP in copying.
- Use CF_ENHMETAFILE, CF_DIB, or CF_BITMAP in pasting.
- Add BitmapToClipboardDIB, BitmapFromClipboardDIB, and BitmapFromHEMF helper
functions to dib.cpp.
- Re-enable paste by fixing the bug that is embugged in the previous commit.
- Enable Cut, Copy, Paste, and Delete on text editing box by modifying
OnInitMenuPopup.
- Add IDS_CANTPASTE resource string to show message on paste failure.
CORE-18867
---
base/applications/mspaint/dib.cpp | 132 +++++++++++++++++++++++++
base/applications/mspaint/dib.h | 4 +
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/mouse.cpp | 9 +-
base/applications/mspaint/resource.h | 1 +
base/applications/mspaint/selectionmodel.cpp | 8 +-
base/applications/mspaint/textedit.cpp | 29 ++++--
base/applications/mspaint/textedit.h | 6 ++
base/applications/mspaint/winproc.cpp | 142 +++++++++++++++++++++------
38 files changed, 318 insertions(+), 43 deletions(-)
diff --git a/base/applications/mspaint/dib.cpp b/base/applications/mspaint/dib.cpp
index 85472994639..cb34859bd56 100644
--- a/base/applications/mspaint/dib.cpp
+++ b/base/applications/mspaint/dib.cpp
@@ -333,3 +333,135 @@ HBITMAP SkewDIB(HDC hDC1, HBITMAP hbm, INT nDegree, BOOL
bVertical)
DeleteDC(hDC2);
return hbmNew;
}
+
+struct BITMAPINFODX : BITMAPINFO
+{
+ RGBQUAD bmiColorsAdditional[256 - 1];
+};
+
+HGLOBAL BitmapToClipboardDIB(HBITMAP hBitmap)
+{
+ BITMAP bm;
+ if (!GetObject(hBitmap, sizeof(BITMAP), &bm))
+ return NULL;
+
+ BITMAPINFODX bmi;
+ ZeroMemory(&bmi, sizeof(bmi));
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = bm.bmWidth;
+ bmi.bmiHeader.biHeight = bm.bmHeight;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = bm.bmBitsPixel;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.bmiHeader.biSizeImage = bm.bmWidthBytes * bm.bmHeight;
+
+ INT cColors;
+ if (bm.bmBitsPixel < 16)
+ cColors = 1 << bm.bmBitsPixel;
+ else
+ cColors = 0;
+
+ HDC hDC = CreateCompatibleDC(NULL);
+
+ if (cColors)
+ {
+ HGDIOBJ hbmOld = SelectObject(hDC, hBitmap);
+ cColors = GetDIBColorTable(hDC, 0, cColors, bmi.bmiColors);
+ SelectObject(hDC, hbmOld);
+ }
+
+ DWORD cbColors = cColors * sizeof(RGBQUAD);
+ DWORD dwSize = sizeof(BITMAPINFOHEADER) + cbColors + bmi.bmiHeader.biSizeImage;
+ HGLOBAL hGlobal = GlobalAlloc(GHND | GMEM_SHARE, dwSize);
+ if (hGlobal)
+ {
+ LPBYTE pb = (LPBYTE)GlobalLock(hGlobal);
+ if (pb)
+ {
+ CopyMemory(pb, &bmi, sizeof(BITMAPINFOHEADER));
+ pb += sizeof(BITMAPINFOHEADER);
+
+ CopyMemory(pb, bmi.bmiColors, cbColors);
+ pb += cbColors;
+
+ GetDIBits(hDC, hBitmap, 0, bm.bmHeight, pb, &bmi, DIB_RGB_COLORS);
+
+ GlobalUnlock(hGlobal);
+ }
+ else
+ {
+ GlobalFree(hGlobal);
+ hGlobal = NULL;
+ }
+ }
+
+ DeleteDC(hDC);
+
+ return hGlobal;
+}
+
+HBITMAP BitmapFromClipboardDIB(HGLOBAL hGlobal)
+{
+ LPBYTE pb = (LPBYTE)GlobalLock(hGlobal);
+ if (!pb)
+ return NULL;
+
+ LPBITMAPINFO pbmi = (LPBITMAPINFO)pb;
+ pb += pbmi->bmiHeader.biSize;
+
+ INT cColors = 0, cbColors = 0;
+ if (pbmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+ {
+ LPBITMAPCOREINFO pbmci = (LPBITMAPCOREINFO)pbmi;
+ WORD BitCount = pbmci->bmciHeader.bcBitCount;
+ if (BitCount < 16)
+ {
+ cColors = (1 << BitCount);
+ cbColors = cColors * sizeof(RGBTRIPLE);
+ pb += cbColors;
+ }
+ }
+ else if (pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER))
+ {
+ WORD BitCount = pbmi->bmiHeader.biBitCount;
+ if (BitCount < 16)
+ {
+ cColors = (1 << BitCount);
+ cbColors = cColors * sizeof(RGBQUAD);
+ pb += cbColors;
+ }
+ }
+
+ HDC hDC = CreateCompatibleDC(NULL);
+ HBITMAP hBitmap = CreateDIBSection(hDC, pbmi, DIB_RGB_COLORS, NULL, NULL, 0);
+ if (hBitmap)
+ {
+ SetDIBits(hDC, hBitmap, 0, labs(pbmi->bmiHeader.biHeight), pb, pbmi,
DIB_RGB_COLORS);
+ }
+ DeleteDC(hDC);
+
+ GlobalUnlock(hGlobal);
+
+ return hBitmap;
+}
+
+HBITMAP BitmapFromHEMF(HENHMETAFILE hEMF)
+{
+ ENHMETAHEADER header;
+ if (!GetEnhMetaFileHeader(hEMF, sizeof(header), &header))
+ return NULL;
+
+ CRect rc = *(LPRECT)&header.rclBounds;
+ INT cx = rc.Width(), cy = rc.Height();
+ HBITMAP hbm = CreateColorDIB(cx, cy, RGB(255, 255, 255));
+ if (!hbm)
+ return NULL;
+
+ HDC hDC = CreateCompatibleDC(NULL);
+ HGDIOBJ hbmOld = SelectObject(hDC, hbm);
+ PlayEnhMetaFile(hDC, hEMF, &rc);
+ SelectObject(hDC, hbmOld);
+ DeleteDC(hDC);
+
+ return hbm;
+}
diff --git a/base/applications/mspaint/dib.h b/base/applications/mspaint/dib.h
index f4043d83ca3..4958f612673 100644
--- a/base/applications/mspaint/dib.h
+++ b/base/applications/mspaint/dib.h
@@ -36,3 +36,7 @@ HBITMAP SkewDIB(HDC hDC1, HBITMAP hbm, INT nDegree, BOOL bVertical);
float PpcmFromDpi(float dpi);
#define ROUND(x) (INT)((x) + 0.5)
+
+HGLOBAL BitmapToClipboardDIB(HBITMAP hBitmap);
+HBITMAP BitmapFromClipboardDIB(HGLOBAL hGlobal);
+HBITMAP BitmapFromHEMF(HENHMETAFILE hEMF);
diff --git a/base/applications/mspaint/lang/bg-BG.rc
b/base/applications/mspaint/lang/bg-BG.rc
index 5c0e13f0f1c..49fdda7a16b 100644
--- a/base/applications/mspaint/lang/bg-BG.rc
+++ b/base/applications/mspaint/lang/bg-BG.rc
@@ -242,4 +242,5 @@ BEGIN
IDS_UNDERLINE "Подчертан"
IDS_VERTICAL "Вертикален"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/cs-CZ.rc
b/base/applications/mspaint/lang/cs-CZ.rc
index 134b16d83e5..40d16e29cf5 100644
--- a/base/applications/mspaint/lang/cs-CZ.rc
+++ b/base/applications/mspaint/lang/cs-CZ.rc
@@ -242,4 +242,5 @@ BEGIN
IDS_UNDERLINE "Underline"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/de-DE.rc
b/base/applications/mspaint/lang/de-DE.rc
index b4479752bd2..6901a9ce68e 100644
--- a/base/applications/mspaint/lang/de-DE.rc
+++ b/base/applications/mspaint/lang/de-DE.rc
@@ -242,4 +242,5 @@ BEGIN
IDS_UNDERLINE "Underline"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/en-GB.rc
b/base/applications/mspaint/lang/en-GB.rc
index afe0dac8147..c2590081acb 100644
--- a/base/applications/mspaint/lang/en-GB.rc
+++ b/base/applications/mspaint/lang/en-GB.rc
@@ -242,4 +242,5 @@ BEGIN
IDS_UNDERLINE "Underline"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d dots per inch"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/en-US.rc
b/base/applications/mspaint/lang/en-US.rc
index 2f28cbe4bec..408a60bc505 100644
--- a/base/applications/mspaint/lang/en-US.rc
+++ b/base/applications/mspaint/lang/en-US.rc
@@ -242,4 +242,5 @@ BEGIN
IDS_UNDERLINE "Underline"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d dots per inch"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/es-ES.rc
b/base/applications/mspaint/lang/es-ES.rc
index 29eca278eca..782968cbd1b 100644
--- a/base/applications/mspaint/lang/es-ES.rc
+++ b/base/applications/mspaint/lang/es-ES.rc
@@ -244,4 +244,5 @@ BEGIN
IDS_UNDERLINE "Subrayado"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/et-EE.rc
b/base/applications/mspaint/lang/et-EE.rc
index 0320598596f..16a381596b8 100644
--- a/base/applications/mspaint/lang/et-EE.rc
+++ b/base/applications/mspaint/lang/et-EE.rc
@@ -242,4 +242,5 @@ BEGIN
IDS_UNDERLINE "Underline"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/eu-ES.rc
b/base/applications/mspaint/lang/eu-ES.rc
index 3078614dac8..066460512df 100644
--- a/base/applications/mspaint/lang/eu-ES.rc
+++ b/base/applications/mspaint/lang/eu-ES.rc
@@ -234,4 +234,5 @@ BEGIN
IDS_UNDERLINE "Underline"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/fr-FR.rc
b/base/applications/mspaint/lang/fr-FR.rc
index 92e2af66317..147b939fb58 100644
--- a/base/applications/mspaint/lang/fr-FR.rc
+++ b/base/applications/mspaint/lang/fr-FR.rc
@@ -234,4 +234,5 @@ BEGIN
IDS_UNDERLINE "Underline"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/he-IL.rc
b/base/applications/mspaint/lang/he-IL.rc
index 352f668177e..9a381bc4ff4 100644
--- a/base/applications/mspaint/lang/he-IL.rc
+++ b/base/applications/mspaint/lang/he-IL.rc
@@ -237,4 +237,5 @@ BEGIN
IDS_UNDERLINE "Underline"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/hu-HU.rc
b/base/applications/mspaint/lang/hu-HU.rc
index 8f193665862..ac16396730f 100644
--- a/base/applications/mspaint/lang/hu-HU.rc
+++ b/base/applications/mspaint/lang/hu-HU.rc
@@ -234,4 +234,5 @@ BEGIN
IDS_UNDERLINE "Underline"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/id-ID.rc
b/base/applications/mspaint/lang/id-ID.rc
index 0113573158a..6e082265cbf 100644
--- a/base/applications/mspaint/lang/id-ID.rc
+++ b/base/applications/mspaint/lang/id-ID.rc
@@ -242,4 +242,5 @@ BEGIN
IDS_UNDERLINE "Underline"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/it-IT.rc
b/base/applications/mspaint/lang/it-IT.rc
index 1e880516ac1..0ee7d4f8457 100644
--- a/base/applications/mspaint/lang/it-IT.rc
+++ b/base/applications/mspaint/lang/it-IT.rc
@@ -242,4 +242,5 @@ BEGIN
IDS_UNDERLINE "Underline"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/ja-JP.rc
b/base/applications/mspaint/lang/ja-JP.rc
index d771a81e70b..8e6bac2e22e 100644
--- a/base/applications/mspaint/lang/ja-JP.rc
+++ b/base/applications/mspaint/lang/ja-JP.rc
@@ -242,4 +242,5 @@ BEGIN
IDS_UNDERLINE "下線"
IDS_VERTICAL "縦書き"
IDS_PRINTRES "%d x %d ピクセル/cm"
+ IDS_CANTPASTE "申し訳ありませんが、このデータを貼り付けできません。データ形式が間違っているか、対応していません。"
END
diff --git a/base/applications/mspaint/lang/nl-NL.rc
b/base/applications/mspaint/lang/nl-NL.rc
index 3de457f22b6..5cb77b29837 100644
--- a/base/applications/mspaint/lang/nl-NL.rc
+++ b/base/applications/mspaint/lang/nl-NL.rc
@@ -242,4 +242,5 @@ BEGIN
IDS_UNDERLINE "Underline"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/no-NO.rc
b/base/applications/mspaint/lang/no-NO.rc
index 549d3ae938c..83434aa1a35 100644
--- a/base/applications/mspaint/lang/no-NO.rc
+++ b/base/applications/mspaint/lang/no-NO.rc
@@ -242,4 +242,5 @@ BEGIN
IDS_UNDERLINE "Underline"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/pl-PL.rc
b/base/applications/mspaint/lang/pl-PL.rc
index bd61c31ef89..86f1c53bef8 100644
--- a/base/applications/mspaint/lang/pl-PL.rc
+++ b/base/applications/mspaint/lang/pl-PL.rc
@@ -243,4 +243,5 @@ BEGIN
IDS_UNDERLINE "Underline"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/pt-BR.rc
b/base/applications/mspaint/lang/pt-BR.rc
index 075558c43d9..db0e4a0b2a0 100644
--- a/base/applications/mspaint/lang/pt-BR.rc
+++ b/base/applications/mspaint/lang/pt-BR.rc
@@ -242,4 +242,5 @@ BEGIN
IDS_UNDERLINE "Underline"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/pt-PT.rc
b/base/applications/mspaint/lang/pt-PT.rc
index ef8a793a3c1..638eabfe402 100644
--- a/base/applications/mspaint/lang/pt-PT.rc
+++ b/base/applications/mspaint/lang/pt-PT.rc
@@ -242,4 +242,5 @@ BEGIN
IDS_UNDERLINE "Sublinhado"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/ro-RO.rc
b/base/applications/mspaint/lang/ro-RO.rc
index a92ec1d6913..e6349714f3d 100644
--- a/base/applications/mspaint/lang/ro-RO.rc
+++ b/base/applications/mspaint/lang/ro-RO.rc
@@ -243,4 +243,5 @@ BEGIN
IDS_UNDERLINE "Subliniat"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/ru-RU.rc
b/base/applications/mspaint/lang/ru-RU.rc
index b241a712aa2..f65543435cb 100644
--- a/base/applications/mspaint/lang/ru-RU.rc
+++ b/base/applications/mspaint/lang/ru-RU.rc
@@ -234,4 +234,5 @@ BEGIN
IDS_UNDERLINE "Underline"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/sk-SK.rc
b/base/applications/mspaint/lang/sk-SK.rc
index e2acdc15642..1abab0cd683 100644
--- a/base/applications/mspaint/lang/sk-SK.rc
+++ b/base/applications/mspaint/lang/sk-SK.rc
@@ -243,4 +243,5 @@ BEGIN
IDS_UNDERLINE "Underline"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/sq-AL.rc
b/base/applications/mspaint/lang/sq-AL.rc
index 368a59c9369..d77521cae5e 100644
--- a/base/applications/mspaint/lang/sq-AL.rc
+++ b/base/applications/mspaint/lang/sq-AL.rc
@@ -242,4 +242,5 @@ BEGIN
IDS_UNDERLINE "Underline"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/sv-SE.rc
b/base/applications/mspaint/lang/sv-SE.rc
index 55ad9f1953c..8301fe01424 100644
--- a/base/applications/mspaint/lang/sv-SE.rc
+++ b/base/applications/mspaint/lang/sv-SE.rc
@@ -234,4 +234,5 @@ BEGIN
IDS_UNDERLINE "Underline"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/tr-TR.rc
b/base/applications/mspaint/lang/tr-TR.rc
index 532af08a2e5..227c35fe17b 100644
--- a/base/applications/mspaint/lang/tr-TR.rc
+++ b/base/applications/mspaint/lang/tr-TR.rc
@@ -242,4 +242,5 @@ BEGIN
IDS_UNDERLINE "Altı Çizgili"
IDS_VERTICAL "Düşey"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/uk-UA.rc
b/base/applications/mspaint/lang/uk-UA.rc
index 160830d6e6d..00a9e8ea90c 100644
--- a/base/applications/mspaint/lang/uk-UA.rc
+++ b/base/applications/mspaint/lang/uk-UA.rc
@@ -242,4 +242,5 @@ BEGIN
IDS_UNDERLINE "Underline"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/vi-VN.rc
b/base/applications/mspaint/lang/vi-VN.rc
index b5741ae9c96..b826a9270bd 100644
--- a/base/applications/mspaint/lang/vi-VN.rc
+++ b/base/applications/mspaint/lang/vi-VN.rc
@@ -242,4 +242,5 @@ BEGIN
IDS_UNDERLINE "Underline"
IDS_VERTICAL "Vertical"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/zh-CN.rc
b/base/applications/mspaint/lang/zh-CN.rc
index 2bc72542710..8aea3b4c409 100644
--- a/base/applications/mspaint/lang/zh-CN.rc
+++ b/base/applications/mspaint/lang/zh-CN.rc
@@ -244,4 +244,5 @@ BEGIN
IDS_UNDERLINE "下划线"
IDS_VERTICAL "垂直"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/zh-HK.rc
b/base/applications/mspaint/lang/zh-HK.rc
index 3f4cf0d1073..ca0db48b6d0 100644
--- a/base/applications/mspaint/lang/zh-HK.rc
+++ b/base/applications/mspaint/lang/zh-HK.rc
@@ -242,4 +242,5 @@ BEGIN
IDS_UNDERLINE "底線"
IDS_VERTICAL "垂直"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/lang/zh-TW.rc
b/base/applications/mspaint/lang/zh-TW.rc
index b404dec54c9..1ed27e4ec36 100644
--- a/base/applications/mspaint/lang/zh-TW.rc
+++ b/base/applications/mspaint/lang/zh-TW.rc
@@ -242,4 +242,5 @@ BEGIN
IDS_UNDERLINE "底線"
IDS_VERTICAL "垂直"
IDS_PRINTRES "%d x %d pixel/cm"
+ IDS_CANTPASTE "Sorry, this application cannot paste this data. The data format
is either incorrect or not supported."
END
diff --git a/base/applications/mspaint/mouse.cpp b/base/applications/mspaint/mouse.cpp
index 97359f0ce68..b16ae6190b8 100644
--- a/base/applications/mspaint/mouse.cpp
+++ b/base/applications/mspaint/mouse.cpp
@@ -547,7 +547,6 @@ struct TextTool : ToolBase
// Draw the text
INT style = (toolsModel.IsBackgroundTransparent() ? 0 : 1);
- imageModel.PushImageForUndo();
Text(hdc, rc.left, rc.top, rc.right, rc.bottom, m_fg, m_bg, szText,
textEditWindow.GetFont(), style);
}
@@ -568,12 +567,11 @@ struct TextTool : ToolBase
BOOL bTextBoxShown = ::IsWindowVisible(textEditWindow);
if (bTextBoxShown && textEditWindow.GetWindowTextLength() > 0)
{
+ imageModel.PushImageForUndo();
draw(m_hdc);
-
- if (selectionModel.m_rc.IsRectEmpty())
+ if (::IsRectEmpty(&selectionModel.m_rc))
{
- textEditWindow.ShowWindow(SW_HIDE);
- textEditWindow.SetWindowText(NULL);
+ quit();
return;
}
}
@@ -613,6 +611,7 @@ struct TextTool : ToolBase
void OnFinishDraw() override
{
+ imageModel.PushImageForUndo();
draw(m_hdc);
quit();
ToolBase::OnFinishDraw();
diff --git a/base/applications/mspaint/resource.h b/base/applications/mspaint/resource.h
index 3be802ced8c..53f17d4c715 100644
--- a/base/applications/mspaint/resource.h
+++ b/base/applications/mspaint/resource.h
@@ -219,3 +219,4 @@
#define IDS_UNDERLINE 937
#define IDS_VERTICAL 938
#define IDS_PRINTRES 939
+#define IDS_CANTPASTE 940
diff --git a/base/applications/mspaint/selectionmodel.cpp
b/base/applications/mspaint/selectionmodel.cpp
index 9497cef153f..bfa4501d5fc 100644
--- a/base/applications/mspaint/selectionmodel.cpp
+++ b/base/applications/mspaint/selectionmodel.cpp
@@ -205,8 +205,12 @@ void SelectionModel::InsertFromHBITMAP(HBITMAP hBm, INT x, INT y)
m_rc.left = x;
m_rc.top = y;
- m_rc.right = m_rc.left + GetDIBWidth(hBm);
- m_rc.bottom = m_rc.top + GetDIBHeight(hBm);
+ m_rc.right = x + GetDIBWidth(hBm);
+ m_rc.bottom = y + GetDIBHeight(hBm);
+
+ // If m_rc and m_rcOld were same, the image cannot be pasted to the canvas.
+ // See also SelectionModel::Landing
+ ::SetRect(&m_rcOld, -2, -2, -1, -1); // Outside of image
ClearMask();
}
diff --git a/base/applications/mspaint/textedit.cpp
b/base/applications/mspaint/textedit.cpp
index bf0ab2ce4fb..6d84a12c285 100644
--- a/base/applications/mspaint/textedit.cpp
+++ b/base/applications/mspaint/textedit.cpp
@@ -410,15 +410,9 @@ void CTextEditWindow::Reposition()
CRect rcImage;
canvasWindow.GetImageRect(rcImage);
- if (rc.bottom > rcImage.bottom)
- ::OffsetRect(&rc, 0, rcImage.Height());
-
- if (rc.right > rcImage.right)
- ::OffsetRect(&rc, rcImage.Width(), 0);
-
+ // FIXME: Smartly restrict the position and size by using WM_WINDOWPOSCHANGING
if (rc.left < 0)
::OffsetRect(&rc, -rc.left, 0);
-
if (rc.top < 0)
::OffsetRect(&rc, 0, -rc.top);
@@ -433,3 +427,24 @@ LRESULT CTextEditWindow::OnMouseWheel(UINT nMsg, WPARAM wParam,
LPARAM lParam, B
{
return ::SendMessage(GetParent(), nMsg, wParam, lParam);
}
+
+LRESULT CTextEditWindow::OnCut(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
+{
+ LRESULT ret = DefWindowProc(nMsg, wParam, lParam);
+ Invalidate(TRUE); // Redraw
+ return ret;
+}
+
+LRESULT CTextEditWindow::OnPaste(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
+{
+ LRESULT ret = DefWindowProc(nMsg, wParam, lParam);
+ FixEditPos(NULL);
+ return ret;
+}
+
+LRESULT CTextEditWindow::OnClear(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
+{
+ LRESULT ret = DefWindowProc(nMsg, wParam, lParam);
+ Invalidate(TRUE); // Redraw
+ return ret;
+}
diff --git a/base/applications/mspaint/textedit.h b/base/applications/mspaint/textedit.h
index a227ce25714..95fb3e6ca45 100644
--- a/base/applications/mspaint/textedit.h
+++ b/base/applications/mspaint/textedit.h
@@ -45,6 +45,9 @@ public:
MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown);
MESSAGE_HANDLER(EM_SETSEL, OnSetSel);
MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel);
+ MESSAGE_HANDLER(WM_CUT, OnCut);
+ MESSAGE_HANDLER(WM_PASTE, OnPaste);
+ MESSAGE_HANDLER(WM_CLEAR, OnClear);
END_MSG_MAP()
LRESULT OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
@@ -66,6 +69,9 @@ public:
LRESULT OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnSetSel(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT OnCut(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT OnPaste(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
+ LRESULT OnClear(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
protected:
HWND m_hwndParent;
diff --git a/base/applications/mspaint/winproc.cpp
b/base/applications/mspaint/winproc.cpp
index 29bc32b9327..ec714193b7c 100644
--- a/base/applications/mspaint/winproc.cpp
+++ b/base/applications/mspaint/winproc.cpp
@@ -200,9 +200,7 @@ void CMainWindow::InsertSelectionFromHBITMAP(HBITMAP bitmap, HWND
window)
}
}
- HWND hToolbar = FindWindowEx(toolBoxContainer.m_hWnd, NULL, TOOLBARCLASSNAME,
NULL);
- SendMessage(hToolbar, TB_CHECKBUTTON, ID_RECTSEL, MAKELPARAM(TRUE, 0));
- toolBoxContainer.SendMessage(WM_COMMAND, ID_RECTSEL);
+ toolsModel.SetActiveTool(TOOL_RECTSEL);
imageModel.PushImageForUndo();
selectionModel.InsertFromHBITMAP(bitmap, 0, 0);
@@ -424,6 +422,10 @@ LRESULT CMainWindow::OnInitMenuPopup(UINT nMsg, WPARAM wParam, LPARAM
lParam, BO
BOOL trueSelection =
(selectionModel.m_bShow &&
((toolsModel.GetActiveTool() == TOOL_FREESEL) || (toolsModel.GetActiveTool() ==
TOOL_RECTSEL)));
+ BOOL textShown = (toolsModel.GetActiveTool() == TOOL_TEXT &&
::IsWindowVisible(textEditWindow));
+ DWORD dwStart, dwEnd;
+ textEditWindow.SendMessage(EM_GETSEL, (WPARAM)&dwStart, (LPARAM)&dwEnd);
+ BOOL hasTextSel = (dwStart < dwEnd);
switch (lParam)
{
@@ -431,16 +433,20 @@ LRESULT CMainWindow::OnInitMenuPopup(UINT nMsg, WPARAM wParam,
LPARAM lParam, BO
ProcessFileMenu((HMENU)wParam);
break;
case 1: /* Edit menu */
- EnableMenuItem(menu, IDM_EDITUNDO, ENABLED_IF(imageModel.CanUndo()));
- EnableMenuItem(menu, IDM_EDITREDO, ENABLED_IF(imageModel.CanRedo()));
- EnableMenuItem(menu, IDM_EDITCUT, ENABLED_IF(trueSelection));
- EnableMenuItem(menu, IDM_EDITCOPY, ENABLED_IF(trueSelection));
- EnableMenuItem(menu, IDM_EDITDELETESELECTION, ENABLED_IF(trueSelection));
+ EnableMenuItem(menu, IDM_EDITUNDO,
+ ENABLED_IF(textShown ? textEditWindow.SendMessage(EM_CANUNDO) :
imageModel.CanUndo()));
+ EnableMenuItem(menu, IDM_EDITREDO, ENABLED_IF(textShown ? FALSE :
imageModel.CanRedo()));
+ EnableMenuItem(menu, IDM_EDITCUT, ENABLED_IF(textShown ? hasTextSel :
trueSelection));
+ EnableMenuItem(menu, IDM_EDITCOPY, ENABLED_IF(textShown ? hasTextSel :
trueSelection));
+ EnableMenuItem(menu, IDM_EDITDELETESELECTION,
+ ENABLED_IF(textShown ? hasTextSel : trueSelection));
EnableMenuItem(menu, IDM_EDITINVERTSELECTION, ENABLED_IF(trueSelection));
EnableMenuItem(menu, IDM_EDITCOPYTO, ENABLED_IF(trueSelection));
- OpenClipboard();
- EnableMenuItem(menu, IDM_EDITPASTE,
ENABLED_IF(IsClipboardFormatAvailable(CF_BITMAP)));
- CloseClipboard();
+ EnableMenuItem(menu, IDM_EDITPASTE,
+ ENABLED_IF(textShown ?
::IsClipboardFormatAvailable(CF_UNICODETEXT) :
+ ::IsClipboardFormatAvailable(CF_ENHMETAFILE) ||
+ ::IsClipboardFormatAvailable(CF_DIB) ||
+ ::IsClipboardFormatAvailable(CF_BITMAP)));
break;
case 2: /* View menu */
CheckMenuItem(menu, IDM_VIEWTOOLBOX,
CHECKED_IF(::IsWindowVisible(toolBoxContainer)));
@@ -503,7 +509,7 @@ LRESULT CMainWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bH
if (canvasWindow.m_hWnd == hwndCapture ||
fullscreenWindow.m_hWnd == hwndCapture)
{
- SendMessage(hwndCapture, nMsg, wParam, lParam);
+ ::SendMessage(hwndCapture, nMsg, wParam, lParam);
}
}
else if (selectionModel.m_bShow)
@@ -528,6 +534,8 @@ LRESULT CMainWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bH
case VK_DOWN:
canvasWindow.MoveSelection(0, +1);
break;
+ default:
+ break;
}
return 0;
}
@@ -549,6 +557,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bH
return 0;
}
+ BOOL textShown = (toolsModel.GetActiveTool() == TOOL_TEXT &&
::IsWindowVisible(textEditWindow));
switch (LOWORD(wParam))
{
case IDM_HELPINFO:
@@ -641,7 +650,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bH
break;
}
case IDM_EDITUNDO:
- if (toolsModel.GetActiveTool() == TOOL_TEXT &&
::IsWindowVisible(textEditWindow))
+ if (textShown)
{
textEditWindow.PostMessage(WM_UNDO, 0, 0);
break;
@@ -663,8 +672,11 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bH
imageModel.Undo();
break;
case IDM_EDITREDO:
- if (toolsModel.GetActiveTool() == TOOL_TEXT &&
::IsWindowVisible(textEditWindow))
+ if (textShown)
+ {
+ // There is no "WM_REDO". Do nothing
break;
+ }
if (ToolBase::pointSP != 0) // drawing something?
{
canvasWindow.finishDrawing();
@@ -673,38 +685,110 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bH
imageModel.Redo();
break;
case IDM_EDITCOPY:
- // FIXME: We should use CF_DIB in the future
- if (OpenClipboard())
+ if (textShown)
{
- EmptyClipboard();
- if (selectionModel.m_bShow)
- {
- selectionModel.TakeOff();
- SetClipboardData(CF_BITMAP, selectionModel.CopyBitmap());
- }
- else
+ textEditWindow.SendMessage(WM_COPY);
+ break;
+ }
+ if (!selectionModel.m_bShow || !OpenClipboard())
+ break;
+
+ EmptyClipboard();
+
+ selectionModel.TakeOff();
+
+ {
+ HBITMAP hbm = selectionModel.CopyBitmap();
+ if (hbm)
{
- SetClipboardData(CF_BITMAP, imageModel.CopyBitmap());
+ HGLOBAL hGlobal = BitmapToClipboardDIB(hbm);
+ if (hGlobal)
+ ::SetClipboardData(CF_DIB, hGlobal);
+ ::DeleteObject(hbm);
}
- CloseClipboard();
}
+
+ CloseClipboard();
break;
case IDM_EDITCUT:
+ if (textShown)
+ {
+ textEditWindow.SendMessage(WM_CUT);
+ break;
+ }
/* Copy */
SendMessage(WM_COMMAND, IDM_EDITCOPY, 0);
/* Delete selection */
SendMessage(WM_COMMAND, IDM_EDITDELETESELECTION, 0);
break;
case IDM_EDITPASTE:
- OpenClipboard();
- if (IsClipboardFormatAvailable(CF_BITMAP))
+ if (textShown)
{
- InsertSelectionFromHBITMAP((HBITMAP) GetClipboardData(CF_BITMAP),
m_hWnd);
+ textEditWindow.SendMessage(WM_PASTE);
+ break;
}
+
+ if (!OpenClipboard())
+ break;
+
+ // In many cases, CF_ENHMETAFILE provides a better image than CF_DIB
+ if (::IsClipboardFormatAvailable(CF_ENHMETAFILE))
+ {
+ HENHMETAFILE hEMF = (HENHMETAFILE)::GetClipboardData(CF_ENHMETAFILE);
+ if (hEMF)
+ {
+ HBITMAP hbm = BitmapFromHEMF(hEMF);
+ ::DeleteEnhMetaFile(hEMF);
+ if (hbm)
+ {
+ InsertSelectionFromHBITMAP(hbm, m_hWnd);
+ CloseClipboard();
+ break;
+ }
+ }
+ }
+
+ // In many cases, CF_DIB provides a better image than CF_BITMAP
+ if (::IsClipboardFormatAvailable(CF_DIB))
+ {
+ HBITMAP hbm = BitmapFromClipboardDIB(::GetClipboardData(CF_DIB));
+ if (hbm)
+ {
+ InsertSelectionFromHBITMAP(hbm, m_hWnd);
+ CloseClipboard();
+ break;
+ }
+ }
+
+ // The last resort
+ if (::IsClipboardFormatAvailable(CF_BITMAP))
+ {
+ HBITMAP hbm = (HBITMAP)::GetClipboardData(CF_BITMAP);
+ if (hbm)
+ {
+ InsertSelectionFromHBITMAP(hbm, m_hWnd);
+ CloseClipboard();
+ break;
+ }
+ }
+
+ // Failed to paste
+ {
+ CString strText, strTitle;
+ strText.LoadString(IDS_CANTPASTE);
+ strTitle.LoadString(IDS_PROGRAMNAME);
+ MessageBox(strText, strTitle, MB_ICONINFORMATION);
+ }
+
CloseClipboard();
break;
case IDM_EDITDELETESELECTION:
{
+ if (textShown)
+ {
+ textEditWindow.SendMessage(WM_CLEAR);
+ break;
+ }
switch (toolsModel.GetActiveTool())
{
case TOOL_FREESEL:
@@ -722,7 +806,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bH
}
case IDM_EDITSELECTALL:
{
- if (toolsModel.GetActiveTool() == TOOL_TEXT &&
::IsWindowVisible(textEditWindow))
+ if (textShown)
{
textEditWindow.SendMessage(EM_SETSEL, 0, -1);
break;