https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9f56e67bc2f25b21ce7870...
commit 9f56e67bc2f25b21ce7870f922855945acb8895a Author: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com AuthorDate: Sun Jun 18 19:48:20 2023 +0900 Commit: GitHub noreply@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;