https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b68a3f329c2f9cb8daad6…
commit b68a3f329c2f9cb8daad63431ca1b92ce6ac4ab9
Author:     Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Tue Sep 5 09:03:32 2023 +0900
Commit:     GitHub <noreply(a)github.com>
CommitDate: Tue Sep 5 09:03:32 2023 +0900
    [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(-)
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 <atlcore.h>        // 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