https://git.reactos.org/?p=reactos.git;a=commitdiff;h=afb132a90b24811dc9631…
commit afb132a90b24811dc9631cf1149b87c302186eb6
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sat Jan 6 17:44:57 2024 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Sat Jan 6 17:44:57 2024 +0900
[SDK] cicuif.h: Add CUIFBitmapDC (#6306)
Supporting TIPs...
JIRA issue: CORE-19360
- Add CUIFBitmapDC class.
- Add cicInitUIFUtil and
cicDoneUIFUtil functions.
- Add cicSetLayout, cicMirrorBitmap,
cicCreateDitherBrush,
cicCreateDisabledBitmap,
and cicCreateShadowMaskBmp
utility functions.
---
sdk/include/reactos/cicero/cicuif.h | 331 +++++++++++++++++++++++++++++++++---
1 file changed, 309 insertions(+), 22 deletions(-)
diff --git a/sdk/include/reactos/cicero/cicuif.h b/sdk/include/reactos/cicero/cicuif.h
index 5bbc133f4ef..9745484075d 100644
--- a/sdk/include/reactos/cicero/cicuif.h
+++ b/sdk/include/reactos/cicero/cicuif.h
@@ -13,6 +13,10 @@ struct CUIFTheme;
class CUIFObject;
class CUIFWindow;
class CUIFObjectArray;
+class CUIFColorTable;
+ class CUIFColorTableSys;
+ class CUIFColorTableOff10;
+class CUIFBitmapDC;
class CUIFScheme;
/////////////////////////////////////////////////////////////////////////////
@@ -84,6 +88,25 @@ struct CUIFTheme
STDMETHOD_(void, SetActiveTheme)(LPCWSTR pszClassList, INT iPartId, DWORD
dwUnknown2);
};
+// static members
+DECLSPEC_SELECTANY HINSTANCE CUIFTheme::s_hUXTHEME = NULL;
+DECLSPEC_SELECTANY FN_OpenThemeData CUIFTheme::s_fnOpenThemeData = NULL;
+DECLSPEC_SELECTANY FN_CloseThemeData CUIFTheme::s_fnCloseThemeData = NULL;
+DECLSPEC_SELECTANY FN_DrawThemeBackground CUIFTheme::s_fnDrawThemeBackground = NULL;
+DECLSPEC_SELECTANY FN_DrawThemeParentBackground CUIFTheme::s_fnDrawThemeParentBackground
= NULL;
+DECLSPEC_SELECTANY FN_DrawThemeText CUIFTheme::s_fnDrawThemeText = NULL;
+DECLSPEC_SELECTANY FN_DrawThemeIcon CUIFTheme::s_fnDrawThemeIcon = NULL;
+DECLSPEC_SELECTANY FN_GetThemeBackgroundExtent CUIFTheme::s_fnGetThemeBackgroundExtent =
NULL;
+DECLSPEC_SELECTANY FN_GetThemeBackgroundContentRect
CUIFTheme::s_fnGetThemeBackgroundContentRect = NULL;
+DECLSPEC_SELECTANY FN_GetThemeTextExtent CUIFTheme::s_fnGetThemeTextExtent = NULL;
+DECLSPEC_SELECTANY FN_GetThemePartSize CUIFTheme::s_fnGetThemePartSize = NULL;
+DECLSPEC_SELECTANY FN_DrawThemeEdge CUIFTheme::s_fnDrawThemeEdge = NULL;
+DECLSPEC_SELECTANY FN_GetThemeColor CUIFTheme::s_fnGetThemeColor = NULL;
+DECLSPEC_SELECTANY FN_GetThemeMargins CUIFTheme::s_fnGetThemeMargins = NULL;
+DECLSPEC_SELECTANY FN_GetThemeFont CUIFTheme::s_fnGetThemeFont = NULL;
+DECLSPEC_SELECTANY FN_GetThemeSysColor CUIFTheme::s_fnGetThemeSysColor = NULL;
+DECLSPEC_SELECTANY FN_GetThemeSysSize CUIFTheme::s_fnGetThemeSysSize = NULL;
+
/////////////////////////////////////////////////////////////////////////////
class CUIFObjectArray : public CicArray<CUIFObject*>
@@ -245,6 +268,55 @@ public:
/////////////////////////////////////////////////////////////////////////////
+class CUIFBitmapDC
+{
+protected:
+ HBITMAP m_hBitmap;
+ HGDIOBJ m_hOldBitmap;
+ HGDIOBJ m_hOldObject;
+ HDC m_hDC;
+
+public:
+ static BOOL s_fInitBitmapDCs;
+ static CUIFBitmapDC *s_phdcSrc;
+ static CUIFBitmapDC *s_phdcMask;
+ static CUIFBitmapDC *s_phdcDst;
+
+ CUIFBitmapDC(BOOL bMemory);
+ ~CUIFBitmapDC();
+ operator HDC() const { return m_hDC; }
+
+ void Uninit(BOOL bKeep);
+
+ BOOL SetBitmap(HBITMAP hBitmap);
+ BOOL SetBitmap(LONG cx, LONG cy, WORD cPlanes, WORD cBitCount);
+ BOOL SetDIB(LONG cx, LONG cy, WORD cPlanes, WORD cBitCount);
+
+ HBITMAP DetachBitmap()
+ {
+ HBITMAP hOldBitmap = m_hBitmap;
+ m_hBitmap = NULL;
+ return hOldBitmap;
+ }
+};
+
+DECLSPEC_SELECTANY BOOL CUIFBitmapDC::s_fInitBitmapDCs = FALSE;
+DECLSPEC_SELECTANY CUIFBitmapDC *CUIFBitmapDC::s_phdcSrc = NULL;
+DECLSPEC_SELECTANY CUIFBitmapDC *CUIFBitmapDC::s_phdcMask = NULL;
+DECLSPEC_SELECTANY CUIFBitmapDC *CUIFBitmapDC::s_phdcDst = NULL;
+
+void cicInitUIFUtil(void);
+void cicDoneUIFUtil(void);
+
+BOOL cicSetLayout(HDC hDC, BOOL bLayout);
+HBITMAP cicMirrorBitmap(HBITMAP hBitmap, HBRUSH hbrBack);
+HBRUSH cicCreateDitherBrush(VOID);
+HBITMAP cicCreateDisabledBitmap(LPCRECT prc, HBITMAP hbmMask, HBRUSH hbr1, HBRUSH hbr2,
+ BOOL bPressed);
+HBITMAP cicCreateShadowMaskBmp(LPRECT prc, HBITMAP hbm1, HBITMAP hbm2, HBRUSH hbr1,
HBRUSH hbr2);
+
+/////////////////////////////////////////////////////////////////////////////
+
class CUIFScheme
{
public:
@@ -268,27 +340,6 @@ class CUIFWindow : public CUIFObject
/////////////////////////////////////////////////////////////////////////////
-// static members
-DECLSPEC_SELECTANY HINSTANCE CUIFTheme::s_hUXTHEME = NULL;
-DECLSPEC_SELECTANY FN_OpenThemeData CUIFTheme::s_fnOpenThemeData = NULL;
-DECLSPEC_SELECTANY FN_CloseThemeData CUIFTheme::s_fnCloseThemeData = NULL;
-DECLSPEC_SELECTANY FN_DrawThemeBackground CUIFTheme::s_fnDrawThemeBackground = NULL;
-DECLSPEC_SELECTANY FN_DrawThemeParentBackground CUIFTheme::s_fnDrawThemeParentBackground
= NULL;
-DECLSPEC_SELECTANY FN_DrawThemeText CUIFTheme::s_fnDrawThemeText = NULL;
-DECLSPEC_SELECTANY FN_DrawThemeIcon CUIFTheme::s_fnDrawThemeIcon = NULL;
-DECLSPEC_SELECTANY FN_GetThemeBackgroundExtent CUIFTheme::s_fnGetThemeBackgroundExtent =
NULL;
-DECLSPEC_SELECTANY FN_GetThemeBackgroundContentRect
CUIFTheme::s_fnGetThemeBackgroundContentRect = NULL;
-DECLSPEC_SELECTANY FN_GetThemeTextExtent CUIFTheme::s_fnGetThemeTextExtent = NULL;
-DECLSPEC_SELECTANY FN_GetThemePartSize CUIFTheme::s_fnGetThemePartSize = NULL;
-DECLSPEC_SELECTANY FN_DrawThemeEdge CUIFTheme::s_fnDrawThemeEdge = NULL;
-DECLSPEC_SELECTANY FN_GetThemeColor CUIFTheme::s_fnGetThemeColor = NULL;
-DECLSPEC_SELECTANY FN_GetThemeMargins CUIFTheme::s_fnGetThemeMargins = NULL;
-DECLSPEC_SELECTANY FN_GetThemeFont CUIFTheme::s_fnGetThemeFont = NULL;
-DECLSPEC_SELECTANY FN_GetThemeSysColor CUIFTheme::s_fnGetThemeSysColor = NULL;
-DECLSPEC_SELECTANY FN_GetThemeSysSize CUIFTheme::s_fnGetThemeSysSize = NULL;
-
-/////////////////////////////////////////////////////////////////////////////
-
inline HRESULT CUIFTheme::InternalOpenThemeData(HWND hWnd)
{
if (!hWnd || !m_pszClassList)
@@ -526,7 +577,7 @@ inline STDMETHODIMP_(void) CUIFObject::OnUnknown(DWORD x1, DWORD x2,
DWORD x3)
inline STDMETHODIMP_(void) CUIFObject::GetRect(LPRECT prc)
{
- *prc = this->m_rc;
+ *prc = m_rc;
}
/// @unimplemented
@@ -840,3 +891,239 @@ inline void cicDoneUIFScheme(void)
CUIFScheme::s_pColorTableOff10 = NULL;
}
}
+
+/////////////////////////////////////////////////////////////////////////////
+
+inline CUIFBitmapDC::CUIFBitmapDC(BOOL bMemory)
+{
+ m_hBitmap = NULL;
+ m_hOldBitmap = NULL;
+ m_hOldObject = NULL;
+ if (bMemory)
+ m_hDC = ::CreateCompatibleDC(NULL);
+ else
+ m_hDC = ::CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
+}
+
+inline CUIFBitmapDC::~CUIFBitmapDC()
+{
+ Uninit(FALSE);
+ ::DeleteDC(m_hDC);
+}
+
+inline void CUIFBitmapDC::Uninit(BOOL bKeep)
+{
+ if (m_hOldBitmap)
+ {
+ ::SelectObject(m_hDC, m_hOldBitmap);
+ m_hOldBitmap = NULL;
+ }
+ if (m_hOldObject)
+ {
+ ::SelectObject(m_hDC, m_hOldObject);
+ m_hOldObject = NULL;
+ }
+ if (!bKeep)
+ {
+ if (m_hBitmap)
+ {
+ ::DeleteObject(m_hBitmap);
+ m_hBitmap = NULL;
+ }
+ }
+}
+
+inline BOOL CUIFBitmapDC::SetBitmap(HBITMAP hBitmap)
+{
+ if (m_hDC)
+ m_hOldBitmap = ::SelectObject(m_hDC, hBitmap);
+ return TRUE;
+}
+
+inline BOOL CUIFBitmapDC::SetBitmap(LONG cx, LONG cy, WORD cPlanes, WORD cBitCount)
+{
+ m_hBitmap = ::CreateBitmap(cx, cy, cPlanes, cBitCount, 0);
+ m_hOldBitmap = ::SelectObject(m_hDC, m_hBitmap);
+ return TRUE;
+}
+
+inline BOOL CUIFBitmapDC::SetDIB(LONG cx, LONG cy, WORD cPlanes, WORD cBitCount)
+{
+ BITMAPINFO bmi;
+ ZeroMemory(&bmi, sizeof(bmi));
+ bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
+ bmi.bmiHeader.biWidth = cx;
+ bmi.bmiHeader.biHeight = cy;
+ bmi.bmiHeader.biPlanes = cPlanes;
+ bmi.bmiHeader.biBitCount = cBitCount;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ m_hBitmap = ::CreateDIBSection(m_hDC, &bmi, DIB_RGB_COLORS, NULL, NULL, 0);
+ m_hOldBitmap = ::SelectObject(m_hDC, m_hBitmap);
+ return TRUE;
+}
+
+inline void cicInitUIFUtil(void)
+{
+ if (!CUIFBitmapDC::s_phdcSrc)
+ CUIFBitmapDC::s_phdcSrc = new(cicNoThrow) CUIFBitmapDC(TRUE);
+
+ if (!CUIFBitmapDC::s_phdcMask)
+ CUIFBitmapDC::s_phdcMask = new(cicNoThrow) CUIFBitmapDC(TRUE);
+
+ if (!CUIFBitmapDC::s_phdcDst)
+ CUIFBitmapDC::s_phdcDst = new(cicNoThrow) CUIFBitmapDC(TRUE);
+
+ if (CUIFBitmapDC::s_phdcSrc && CUIFBitmapDC::s_phdcMask &&
CUIFBitmapDC::s_phdcDst)
+ CUIFBitmapDC::s_fInitBitmapDCs = TRUE;
+}
+
+inline void cicDoneUIFUtil(void)
+{
+ if (CUIFBitmapDC::s_phdcSrc)
+ {
+ delete CUIFBitmapDC::s_phdcSrc;
+ CUIFBitmapDC::s_phdcSrc = NULL;
+ }
+ if (CUIFBitmapDC::s_phdcMask)
+ {
+ delete CUIFBitmapDC::s_phdcMask;
+ CUIFBitmapDC::s_phdcMask = NULL;
+ }
+ if (CUIFBitmapDC::s_phdcDst)
+ {
+ delete CUIFBitmapDC::s_phdcDst;
+ CUIFBitmapDC::s_phdcDst = NULL;
+ }
+
+ CUIFBitmapDC::s_fInitBitmapDCs = FALSE;
+}
+
+inline BOOL cicSetLayout(HDC hDC, DWORD dwLayout)
+{
+ typedef BOOL (WINAPI *FN_SetLayout)(HDC hDC, DWORD dwLayout);
+ static HINSTANCE s_hGdi32 = NULL;
+ static FN_SetLayout s_fnSetLayout = NULL;
+
+ if (!cicGetFN(s_hGdi32, s_fnSetLayout, TEXT("gdi32.dll"),
"SetLayout"))
+ return FALSE;
+
+ return s_fnSetLayout(hDC, dwLayout);
+}
+
+inline HBITMAP cicMirrorBitmap(HBITMAP hBitmap, HBRUSH hbrBack)
+{
+ BITMAP bm;
+ if (!CUIFBitmapDC::s_fInitBitmapDCs || !::GetObject(hBitmap, sizeof(bm), &bm))
+ return NULL;
+
+ CUIFBitmapDC::s_phdcSrc->SetBitmap(hBitmap);
+ CUIFBitmapDC::s_phdcDst->SetDIB(bm.bmWidth, bm.bmHeight, 1, 32);
+ CUIFBitmapDC::s_phdcMask->SetDIB(bm.bmWidth, bm.bmHeight, 1, 32);
+
+ RECT rc;
+ ::SetRect(&rc, 0, 0, bm.bmWidth, bm.bmHeight);
+ FillRect(*CUIFBitmapDC::s_phdcDst, &rc, hbrBack);
+
+ cicSetLayout(*CUIFBitmapDC::s_phdcMask, LAYOUT_RTL);
+
+ ::BitBlt(*CUIFBitmapDC::s_phdcMask, 0, 0, bm.bmWidth, bm.bmHeight,
*CUIFBitmapDC::s_phdcSrc, 0, 0, SRCCOPY);
+
+ cicSetLayout(*CUIFBitmapDC::s_phdcMask, LAYOUT_LTR);
+
+ ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, bm.bmWidth, bm.bmHeight,
*CUIFBitmapDC::s_phdcMask, 1, 0, SRCCOPY);
+
+ CUIFBitmapDC::s_phdcSrc->Uninit(FALSE);
+ CUIFBitmapDC::s_phdcMask->Uninit(FALSE);
+ CUIFBitmapDC::s_phdcDst->Uninit(TRUE);
+ return CUIFBitmapDC::s_phdcDst->DetachBitmap();
+}
+
+inline HBRUSH cicCreateDitherBrush(VOID)
+{
+ BYTE Bits[16];
+ ZeroMemory(&Bits, sizeof(Bits));
+ Bits[0] = Bits[4] = Bits[8] = Bits[12] = 'U';
+ Bits[2] = Bits[6] = Bits[10] = Bits[14] = 0xAA;
+ HBITMAP hBitmap = ::CreateBitmap(8, 8, 1, 1, Bits);
+ if (!hBitmap)
+ return NULL;
+
+ LOGBRUSH lb;
+ lb.lbHatch = (ULONG_PTR)hBitmap;
+ lb.lbStyle = BS_PATTERN;
+ HBRUSH hbr = ::CreateBrushIndirect(&lb);
+ ::DeleteObject(hBitmap);
+ return hbr;
+}
+
+inline HBITMAP
+cicCreateDisabledBitmap(LPCRECT prc, HBITMAP hbmMask, HBRUSH hbr1, HBRUSH hbr2, BOOL
bPressed)
+{
+ if (!CUIFBitmapDC::s_fInitBitmapDCs)
+ return NULL;
+
+ LONG width = prc->right - prc->left, height = prc->bottom - prc->top;
+
+ CUIFBitmapDC::s_phdcDst->SetDIB(width, height, 1, 32);
+ CUIFBitmapDC::s_phdcMask->SetBitmap(hbmMask);
+ CUIFBitmapDC::s_phdcSrc->SetDIB(width, height, 1, 32);
+
+ RECT rc;
+ ::SetRect(&rc, 0, 0, width, height);
+ ::FillRect(*CUIFBitmapDC::s_phdcDst, &rc, hbr1);
+
+ HBRUSH hbrWhite = (HBRUSH)GetStockObject(WHITE_BRUSH);
+ ::FillRect(*CUIFBitmapDC::s_phdcSrc, &rc, hbrWhite);
+
+ ::BitBlt(*CUIFBitmapDC::s_phdcSrc, 0, 0, width, height, *CUIFBitmapDC::s_phdcMask, 0,
0, SRCINVERT);
+ if (bPressed)
+ BitBlt(*CUIFBitmapDC::s_phdcDst, 1, 1, width, height, *CUIFBitmapDC::s_phdcSrc,
0, 0, SRCPAINT);
+ else
+ BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, *CUIFBitmapDC::s_phdcSrc,
0, 0, SRCPAINT);
+
+ ::FillRect(*CUIFBitmapDC::s_phdcSrc, &rc, hbr2);
+
+ ::BitBlt(*CUIFBitmapDC::s_phdcSrc, 0, 0, width, height, *CUIFBitmapDC::s_phdcMask, 0,
0, SRCPAINT);
+ ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, *CUIFBitmapDC::s_phdcSrc, 0,
0, SRCAND);
+
+ CUIFBitmapDC::s_phdcSrc->Uninit(FALSE);
+ CUIFBitmapDC::s_phdcMask->Uninit(FALSE);
+ CUIFBitmapDC::s_phdcDst->Uninit(TRUE);
+ return CUIFBitmapDC::s_phdcDst->DetachBitmap();
+}
+
+inline HBITMAP
+cicCreateShadowMaskBmp(LPRECT prc, HBITMAP hbm1, HBITMAP hbm2, HBRUSH hbr1, HBRUSH hbr2)
+{
+ if (!CUIFBitmapDC::s_fInitBitmapDCs)
+ return NULL;
+
+ --prc->left;
+ --prc->top;
+
+ LONG width = prc->right - prc->left;
+ LONG height = prc->bottom - prc->top;
+
+ CUIFBitmapDC bitmapDC(TRUE);
+
+ CUIFBitmapDC::s_phdcDst->SetDIB(width, height, 1, 32);
+ CUIFBitmapDC::s_phdcSrc->SetBitmap(hbm1);
+ CUIFBitmapDC::s_phdcMask->SetBitmap(hbm2);
+ bitmapDC.SetDIB(width, height, 1, 32);
+
+ RECT rc;
+ ::SetRect(&rc, 0, 0, width, height);
+
+ ::FillRect(*CUIFBitmapDC::s_phdcDst, &rc, hbr1);
+ ::FillRect(bitmapDC, &rc, hbr2);
+
+ ::BitBlt(bitmapDC, 0, 0, width, height, *CUIFBitmapDC::s_phdcMask, 0, 0, SRCPAINT);
+ ::BitBlt(*CUIFBitmapDC::s_phdcDst, 2, 2, width, height, bitmapDC, 0, 0, SRCAND);
+ ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, *CUIFBitmapDC::s_phdcMask, 0,
0, SRCAND);
+ ::BitBlt(*CUIFBitmapDC::s_phdcDst, 0, 0, width, height, *CUIFBitmapDC::s_phdcSrc, 0,
0, SRCINVERT);
+
+ CUIFBitmapDC::s_phdcSrc->Uninit(FALSE);
+ CUIFBitmapDC::s_phdcMask->Uninit(FALSE);
+ CUIFBitmapDC::s_phdcDst->Uninit(TRUE);
+ return CUIFBitmapDC::s_phdcDst->DetachBitmap();
+}