From b68a3f329c2f9cb8daad63431ca1b92ce6ac4ab9 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Tue, 5 Sep 2023 09:03:32 +0900 Subject: [PATCH] [ATL][ATL_APITEST] Implement CImageDC class (#5643) - Use reference count for CImage::GetDC / CImage::ReleaseDC. - Add CImageDC class. - Delete modules/rostests/apitests/atl/CImage_WIP.txt. CORE-19008 --- modules/rostests/apitests/atl/CImage.cpp | 20 +++++ modules/rostests/apitests/atl/CImage_WIP.txt | 86 -------------------- sdk/lib/atl/atlimage.h | 65 +++++++++++---- 3 files changed, 70 insertions(+), 101 deletions(-) delete mode 100644 modules/rostests/apitests/atl/CImage_WIP.txt diff --git a/modules/rostests/apitests/atl/CImage.cpp b/modules/rostests/apitests/atl/CImage.cpp index 005cd4d9295..3ee98304da8 100644 --- a/modules/rostests/apitests/atl/CImage.cpp +++ b/modules/rostests/apitests/atl/CImage.cpp @@ -235,6 +235,26 @@ static void Test_LoadSaveImage(void) color = image1.GetPixel(5, 5); ok(color == RGB(255, 0,0), "Expected color to be 255, 0, 0; was: %i, %i, %i (for %i)\n", GetRValue(color), GetGValue(color), GetBValue(color), n); + { + CImageDC dc1(image1); + ::SetPixel(dc1, 5, 5, RGB(0, 255, 0)); + { + CImageDC dc2(image1); + ::SetPixel(dc2, 5, 5, RGB(0, 0, 255)); + } + } + + { + HDC hdcImage = image1.GetDC(); + color = ::GetPixel(hdcImage, 5, 5); + ok_long(color, RGB(0, 0, 255)); + + ::SetPixel(hdcImage, 5, 5, RGB(255, 0, 0)); + color = ::GetPixel(hdcImage, 5, 5); + ok_long(color, RGB(255, 0, 0)); + image1.ReleaseDC(); + } + bOK = DeleteFile(file); ok(bOK, "Expected bOK to be TRUE, was: %d (for %i)\n", bOK, n); } diff --git a/modules/rostests/apitests/atl/CImage_WIP.txt b/modules/rostests/apitests/atl/CImage_WIP.txt deleted file mode 100644 index 7cc02b77afe..00000000000 --- a/modules/rostests/apitests/atl/CImage_WIP.txt +++ /dev/null @@ -1,86 +0,0 @@ -Test files: - -atl_apitest: CImage class from reactos -CImage.exe : CImage class from microsoft - -================================================================================================================ -Windows Server 2003 SP2: -================================================================================================================ ->atl_apitest.exe CImage -R:\src\trunk\reactos\modules\rostests\apitests\atl\CImage.cpp(234): Test failed: Expected bpp to be 8, was: 32 -R:\src\trunk\reactos\modules\rostests\apitests\atl\CImage.cpp(265): Test failed: Expected bpp to be 8, was: 32 (for 0) -R:\src\trunk\reactos\modules\rostests\apitests\atl\CImage.cpp(265): Test failed: Expected bpp to be 8, was: 32 (for 1) -R:\src\trunk\reactos\modules\rostests\apitests\atl\CImage.cpp(265): Test failed: Expected bpp to be 8, was: 32 (for 2) -R:\src\trunk\reactos\modules\rostests\apitests\atl\CImage.cpp(260): Test failed: Expected bpp to be 24, was: 32 (for 3) -R:\src\trunk\reactos\modules\rostests\apitests\atl\CImage.cpp(265): Test failed: Expected bpp to be 8, was: 32 (for 4) - -CImage: 79 tests executed (0 marked as todo, 6 failures), 0 skipped. -================================================================================================================ ->CImage.exe -CImage: 79 tests executed (0 marked as todo, 0 failures), 0 skipped. -================================================================================================================ -================================================================================================================ -Windows 10: -================================================================================================================ ->atl_apitest.exe CImage -R:\src\trunk\reactos\modules\rostests\apitests\atl\CImage.cpp(234): Test failed: Expected bpp to be 8, was: 32 -R:\src\trunk\reactos\modules\rostests\apitests\atl\CImage.cpp(265): Test failed: Expected bpp to be 8, was: 32 (for 0) -R:\src\trunk\reactos\modules\rostests\apitests\atl\CImage.cpp(265): Test failed: Expected bpp to be 8, was: 32 (for 1) -R:\src\trunk\reactos\modules\rostests\apitests\atl\CImage.cpp(265): Test failed: Expected bpp to be 8, was: 32 (for 2) -R:\src\trunk\reactos\modules\rostests\apitests\atl\CImage.cpp(260): Test failed: Expected bpp to be 24, was: 32 (for 3) -R:\src\trunk\reactos\modules\rostests\apitests\atl\CImage.cpp(265): Test failed: Expected bpp to be 8, was: 32 (for 4) - -CImage: 79 tests executed (0 marked as todo, 6 failures), 0 skipped. -================================================================================================================ ->CImage.exe -CImage: 79 tests executed (0 marked as todo, 0 failures), 0 skipped. -================================================================================================================ -================================================================================================================ -ReactOS: -================================================================================================================ ->atl_apitest.exe CImage -CImage.cpp:234: Test failed: Expected bpp to be 8, was: 32 -CImage.cpp:265: Test failed: Expected bpp to be 8, was: 32 (for 0) -CImage.cpp:245: Test failed: Expected hr to be S_OK, was: 80004005 (for 1) -CImage.cpp:251: Test failed: Expected hr to be S_OK, was: 80004005 (for 1) -CImage.cpp:254: Test failed: Expected width to be 48, was: 0 (for 1) -CImage.cpp:256: Test failed: Expected height to be 48, was: 0 (for 1) -CImage.cpp:265: Test failed: Expected bpp to be 8, was: 0 (for 1) -CImage.cpp:148: Test failed: Expected status to be 0, was: 1 -CImage.cpp:149: Test failed: Expected a valid bitmap -CImage.cpp:245: Test failed: Expected hr to be S_OK, was: 80004005 (for 2) -CImage.cpp:251: Test failed: Expected hr to be S_OK, was: 80004005 (for 2) -CImage.cpp:254: Test failed: Expected width to be 48, was: 0 (for 2) -CImage.cpp:256: Test failed: Expected height to be 48, was: 0 (for 2) -CImage.cpp:265: Test failed: Expected bpp to be 8, was: 0 (for 2) -CImage.cpp:148: Test failed: Expected status to be 0, was: 1 -CImage.cpp:149: Test failed: Expected a valid bitmap -CImage.cpp:260: Test failed: Expected bpp to be 24, was: 32 (for 3) -CImage.cpp:154: Test failed: Expected PixelFormat to be 0x21808, was: 0x30803 -CImage.cpp:265: Test failed: Expected bpp to be 8, was: 32 (for 4) -CImage.cpp:154: Test failed: Expected PixelFormat to be 0x30803, was: 0x21808 - -CImage: 77 tests executed (0 marked as todo, 20 failures), 0 skipped. -================================================================================================================ ->CImage.exe -../CImage.cpp (245): Expected hr to be S_OK, was: 80004005 (for 1) -../CImage.cpp (251): Expected hr to be S_OK, was: 80004005 (for 1) -../CImage.cpp (254): Expected width to be 48, was: 0 (for 1) -../CImage.cpp (256): Expected height to be 48, was: 0 (for 1) -../CImage.cpp (265): Expected bpp to be 8, was: 0 (for 1) -../CImage.cpp (148): Expected status to be 0, was: 1 -../CImage.cpp (149): Expected a valid bitmap -../CImage.cpp (245): Expected hr to be S_OK, was: 80004005 (for 2) -../CImage.cpp (251): Expected hr to be S_OK, was: 80004005 (for 2) -../CImage.cpp (254): Expected width to be 48, was: 0 (for 2) -../CImage.cpp (256): Expected height to be 48, was: 0 (for 2) -../CImage.cpp (265): Expected bpp to be 8, was: 0 (for 2) -../CImage.cpp (148): Expected status to be 0, was: 1 -../CImage.cpp (149): Expected a valid bitmap -../CImage.cpp (260): Expected bpp to be 24, was: 8 (for 3) -../CImage.cpp (154): Expected PixelFormat to be 0x21808, was: 0x30803 -../CImage.cpp (265): Expected bpp to be 8, was: 24 (for 4) -../CImage.cpp (154): Expected PixelFormat to be 0x30803, was: 0x21808 -CImage: 77 tests executed (0 marked as todo, 18 failures), 0 skipped. -================================================================================================================ - diff --git a/sdk/lib/atl/atlimage.h b/sdk/lib/atl/atlimage.h index 31cceac8c76..c77c4dbc67b 100644 --- a/sdk/lib/atl/atlimage.h +++ b/sdk/lib/atl/atlimage.h @@ -6,12 +6,6 @@ #ifndef __ATLIMAGE_H__ #define __ATLIMAGE_H__ -// !!!! -// TODO: The backend (gdi+) that this class relies on is not yet complete! -// Before that is finished, this class will not be a perfect replacement. -// See rostest/apitests/atl/CImage_WIP.txt for test results. -// !!!! - #pragma once #include // for ATL Core @@ -93,28 +87,41 @@ public: HDC GetDC() const throw() { - if (m_hDC) - return m_hDC; + ATLASSERT(m_nDCRefCount >= 0); + if (::InterlockedIncrement(&m_nDCRefCount) == 1) + { + ATLASSERT(m_hDC == NULL); + ATLASSERT(m_hOldBitmap == NULL); + + m_hDC = ::CreateCompatibleDC(NULL); + ATLASSERT(m_hDC != NULL); + + m_hOldBitmap = (HBITMAP)::SelectObject(m_hDC, m_hBitmap); + ATLASSERT(m_hOldBitmap != NULL); + } - m_hDC = ::CreateCompatibleDC(NULL); - m_hOldBitmap = (HBITMAP)::SelectObject(m_hDC, m_hBitmap); return m_hDC; } void ReleaseDC() const throw() { - ATLASSERT(m_hDC); + ATLASSERT(m_nDCRefCount > 0); - if (m_hDC == NULL) + if (::InterlockedDecrement(&m_nDCRefCount) != 0) return; if (m_hOldBitmap) { + ATLASSERT(m_hDC != NULL); ::SelectObject(m_hDC, m_hOldBitmap); m_hOldBitmap = NULL; } - ::DeleteDC(m_hDC); - m_hDC = NULL; + + if (m_hDC) + { + ::DeleteDC(m_hDC); + m_hDC = NULL; + } } BOOL AlphaBlend(HDC hDestDC, @@ -1016,6 +1023,7 @@ private: HBITMAP m_hBitmap; mutable HBITMAP m_hOldBitmap; mutable HDC m_hDC; + mutable LONG m_nDCRefCount = 0; DIBOrientation m_eOrientation; bool m_bHasAlphaChannel; bool m_bIsDIBSection; @@ -1213,7 +1221,34 @@ private: DECLSPEC_SELECTANY CImage::CInitGDIPlus CImage::s_gdiplus; -} +class CImageDC +{ +private: + const CImage& m_image; + HDC m_hDC; + +public: + CImageDC(const CImage& image) + : m_image(image) + , m_hDC(image.GetDC()) + { + } + + virtual ~CImageDC() throw() + { + m_image.ReleaseDC(); + } + + operator HDC() const throw() + { + return m_hDC; + } + + CImageDC(const CImageDC&) = delete; + CImageDC& operator=(const CImageDC&) = delete; +}; + +} // namespace ATL #endif