diff --git a/sdk/include/reactos/cicero/cicarray.h b/sdk/include/reactos/cicero/cicarray.h index 29c2e6e17ab..a9d4f4963ad 100644 --- a/sdk/include/reactos/cicero/cicarray.h +++ b/sdk/include/reactos/cicero/cicarray.h @@ -50,6 +50,16 @@ public: using CicArrayBase::Insert; using CicArrayBase::Remove; + + ssize_t Find(const T_ITEM& item) const + { + for (size_t iItem = 0; iItem < m_cItems; ++iItem) + { + if ((*this)[iItem] == item) + return iItem; + } + return -1; + } }; /******************************************************************************/ diff --git a/sdk/include/reactos/cicero/cicuif.h b/sdk/include/reactos/cicero/cicuif.h index 55854b57cba..bdbc451ddab 100644 --- a/sdk/include/reactos/cicero/cicuif.h +++ b/sdk/include/reactos/cicero/cicuif.h @@ -7,13 +7,21 @@ #pragma once -#include "cicbase.h" +#include "cicarray.h" + +struct CUIFTheme; + class CUIFObject; + class CUIFWindow; +class CUIFObjectArray; +class CUIFScheme; ///////////////////////////////////////////////////////////////////////////// #include // uxtheme.dll +using FN_OpenThemeData = decltype(&OpenThemeData); +using FN_CloseThemeData = decltype(&CloseThemeData); using FN_DrawThemeBackground = decltype(&DrawThemeBackground); using FN_DrawThemeParentBackground = decltype(&DrawThemeParentBackground); using FN_DrawThemeText = decltype(&DrawThemeText); @@ -33,12 +41,13 @@ using FN_GetThemeSysSize = decltype(&GetThemeSysSize); struct CUIFTheme { -protected: LPCWSTR m_pszClassList; INT m_iPartId; - DWORD m_dwUnknown2; + DWORD m_dwUnknown2; //FIXME: name and type HTHEME m_hTheme; static HINSTANCE s_hUXTHEME; + static FN_OpenThemeData s_fnOpenThemeData; + static FN_CloseThemeData s_fnCloseThemeData; static FN_DrawThemeBackground s_fnDrawThemeBackground; static FN_DrawThemeParentBackground s_fnDrawThemeParentBackground; static FN_DrawThemeText s_fnDrawThemeText; @@ -54,7 +63,10 @@ protected: static FN_GetThemeSysColor s_fnGetThemeSysColor; static FN_GetThemeSysSize s_fnGetThemeSysSize; -public: + HRESULT InternalOpenThemeData(HWND hWnd); + HRESULT EnsureThemeData(HWND hWnd); + HRESULT CloseThemeData(); + STDMETHOD(DrawThemeBackground)(HDC hDC, int iStateId, LPCRECT pRect, LPCRECT pClipRect); STDMETHOD(DrawThemeParentBackground)(HWND hwnd, HDC hDC, LPRECT prc); STDMETHOD(DrawThemeText)(HDC hDC, int iStateId, LPCWSTR pszText, int cchText, DWORD dwTextFlags, DWORD dwTextFlags2, LPCRECT pRect); @@ -74,8 +86,122 @@ public: ///////////////////////////////////////////////////////////////////////////// +class CUIFObjectArray : public CicArray +{ +public: + CUIFObjectArray() { } + + BOOL Add(CUIFObject *pObject) + { + if (!pObject || Find(pObject) >= 0) + return FALSE; + + CUIFObject **ppNew = Append(1); + if (!ppNew) + return FALSE; + + *ppNew = pObject; + return TRUE; + } + + BOOL Remove(CUIFObject *pObject) + { + if (!pObject) + return FALSE; + + ssize_t iItem = Find(pObject); + if (iItem < 0) + return FALSE; + + if (size_t(iItem) + 1 < size()) + MoveMemory(&data()[iItem], &data()[iItem + 1], + (size() - (iItem + 1)) * sizeof(CUIFObject*)); + + --m_cItems; + return TRUE; + } + + CUIFObject *GetLast() const + { + if (empty()) + return NULL; + return (*this)[size() - 1]; + } +}; + +///////////////////////////////////////////////////////////////////////////// + +class CUIFObject : public CUIFTheme +{ +protected: + CUIFObject *m_pParent; + CUIFWindow *m_pWindow; + CUIFScheme *m_pScheme; + CUIFObjectArray m_ObjectArray; + DWORD m_dwUnknown3; //FIXME: name and type + DWORD m_style; + RECT m_rc; + BOOL m_bEnable; + BOOL m_bVisible; + HFONT m_hFont; + BOOL m_bHasCustomFont; + LPWSTR m_pszToolTip; + DWORD m_dwUnknown4[2]; //FIXME: name and type + +public: + CUIFObject(CUIFObject *pParent, DWORD dwUnknown3, LPRECT prc, DWORD style); + virtual ~CUIFObject(); + + STDMETHOD_(void, Initialize)(); + STDMETHOD_(void, OnPaint)(HWND hWnd); + STDMETHOD_(void, OnHideToolTip)(); + STDMETHOD_(void, OnLButtonDown)(POINT pt); + STDMETHOD_(void, OnLButtonDblClk)(POINT pt); + STDMETHOD_(void, OnLButtonUp)(POINT pt); + STDMETHOD_(void, OnMButtonDown)(POINT pt); + STDMETHOD_(void, OnMButtonDblClk)(POINT pt); + STDMETHOD_(void, OnMButtonUp)(POINT pt); + STDMETHOD_(void, OnRButtonDown)(POINT pt); + STDMETHOD_(void, OnRButtonDblClk)(POINT pt); + STDMETHOD_(void, OnRButtonUp)(POINT pt); + STDMETHOD_(void, OnUnknown)(DWORD x1, DWORD x2, DWORD x3); //FIXME: name and type + STDMETHOD_(void, GetRect)(LPRECT prc); + STDMETHOD_(void, SetRect)(LPCRECT prc); + STDMETHOD_(BOOL, PtInObject)(POINT pt); + STDMETHOD_(void, PaintObject)(HWND hWnd, LPCRECT prc); + STDMETHOD_(void, CallOnPaint)(); + STDMETHOD_(void, Enable)(BOOL bEnable); + STDMETHOD_(void, Show)(BOOL bVisible); + STDMETHOD_(void, SetFontToThis)(HFONT hFont); + STDMETHOD_(void, SetFont)(HFONT hFont); + STDMETHOD_(void, SetStyle)(DWORD style); + STDMETHOD_(void, AddUIObj)(CUIFObject *pObject); + STDMETHOD_(void, RemoveUIObj)(CUIFObject *pObject); + STDMETHOD_(LRESULT, OnObjectNotify)(CUIFObject *pObject, WPARAM wParam, LPARAM lParam); + STDMETHOD_(void, SetToolTip)(LPCWSTR pszToolTip); + STDMETHOD_(LPCWSTR, GetToolTip)(); + STDMETHOD_(LRESULT, OnShowToolTip)(); + STDMETHOD_(void, OnHideToolTip2)(); + STDMETHOD_(void, DetachWndObj)(); + STDMETHOD_(void, ClearWndObj)(); + STDMETHOD_(LRESULT, OnPaintTheme)(HWND hWnd); + STDMETHOD_(void, OnSetFocus)(HWND hWnd); + STDMETHOD_(void, ClearTheme)(); +}; + +///////////////////////////////////////////////////////////////////////////// + +class CUIFWindow : public CUIFObject +{ + //FIXME +}; + +///////////////////////////////////////////////////////////////////////////// + // 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; @@ -93,6 +219,37 @@ DECLSPEC_SELECTANY FN_GetThemeSysSize CUIFTheme::s_fnGetThemeSysSize = NULL; ///////////////////////////////////////////////////////////////////////////// +inline HRESULT CUIFTheme::InternalOpenThemeData(HWND hWnd) +{ + if (!hWnd || !m_pszClassList) + return E_FAIL; + + if (!cicGetFN(s_hUXTHEME, s_fnOpenThemeData, TEXT("uxtheme.dll"), "OpenThemeData")) + return E_FAIL; + m_hTheme = s_fnOpenThemeData(hWnd, m_pszClassList); + return (m_hTheme ? S_OK : E_FAIL); +} + +inline HRESULT CUIFTheme::EnsureThemeData(HWND hWnd) +{ + if (m_hTheme) + return S_OK; + return InternalOpenThemeData(hWnd); +} + +inline HRESULT CUIFTheme::CloseThemeData() +{ + if (!m_hTheme) + return S_OK; + + if (!cicGetFN(s_hUXTHEME, s_fnCloseThemeData, TEXT("uxtheme.dll"), "CloseThemeData")) + return E_FAIL; + + HRESULT hr = s_fnCloseThemeData(m_hTheme); + m_hTheme = NULL; + return hr; +} + inline STDMETHODIMP CUIFTheme::DrawThemeBackground(HDC hDC, int iStateId, LPCRECT pRect, LPCRECT pClipRect) { @@ -209,6 +366,302 @@ inline STDMETHODIMP_(void) CUIFTheme::SetActiveTheme(LPCWSTR pszClassList, INT iPartId, DWORD dwUnknown2) { m_iPartId = iPartId; - m_dwUnknown2 = dwUnknown2; + m_dwUnknown2 = dwUnknown2; //FIXME: name and type m_pszClassList = pszClassList; } + +///////////////////////////////////////////////////////////////////////////// + +/// @unimplemented +inline +CUIFObject::CUIFObject(CUIFObject *pParent, DWORD dwUnknown3, LPRECT prc, DWORD style) +{ + m_pszClassList = NULL; + m_hTheme = NULL; + m_pParent = pParent; + m_dwUnknown3 = dwUnknown3; //FIXME: name and type + m_style = style; + + if (prc) + m_rc = *prc; + else + ::SetRect(&m_rc, 0, 0, 0, 0); + + if (m_pParent) + { + m_pWindow = m_pParent->m_pWindow; + m_pScheme = m_pParent->m_pScheme; + } + else + { + m_pWindow = NULL; + m_pScheme = NULL; + } + + m_bEnable = m_bVisible = TRUE; + + m_hFont = (HFONT)::GetStockObject(DEFAULT_GUI_FONT); + m_bHasCustomFont = FALSE; + + m_pszToolTip = NULL; + + m_dwUnknown4[0] = -1; //FIXME + m_dwUnknown4[1] = -1; //FIXME +} + +/// @unimplemented +inline +CUIFObject::~CUIFObject() +{ + if (m_pWindow) + { + //FIXME + } + + if (m_pszToolTip) + { + delete[] m_pszToolTip; + m_pszToolTip = NULL; + } + + for (;;) + { + CUIFObject *pLast = m_ObjectArray.GetLast(); + if (!pLast) + break; + + m_ObjectArray.Remove(pLast); + delete pLast; + } + + if (m_pWindow) + m_pWindow->RemoveUIObj(this); + + CloseThemeData(); +} + +inline STDMETHODIMP_(void) CUIFObject::Initialize() +{ +} + +inline STDMETHODIMP_(void) CUIFObject::OnPaint(HWND hWnd) +{ + if (!(m_pWindow->m_style & 0x80000000) || !OnPaintTheme(hWnd)) + OnSetFocus(hWnd); +} + +inline STDMETHODIMP_(void) CUIFObject::OnHideToolTip() +{ +} + +inline STDMETHODIMP_(void) CUIFObject::OnLButtonDown(POINT pt) +{ +} + +inline STDMETHODIMP_(void) CUIFObject::OnLButtonDblClk(POINT pt) +{ +} + +inline STDMETHODIMP_(void) CUIFObject::OnLButtonUp(POINT pt) +{ +} + +inline STDMETHODIMP_(void) CUIFObject::OnMButtonDown(POINT pt) +{ +} + +inline STDMETHODIMP_(void) CUIFObject::OnMButtonDblClk(POINT pt) +{ +} + +inline STDMETHODIMP_(void) CUIFObject::OnMButtonUp(POINT pt) +{ +} + +inline STDMETHODIMP_(void) CUIFObject::OnRButtonDown(POINT pt) +{ +} + +inline STDMETHODIMP_(void) CUIFObject::OnRButtonDblClk(POINT pt) +{ +} + +inline STDMETHODIMP_(void) CUIFObject::OnRButtonUp(POINT pt) +{ +} + +inline STDMETHODIMP_(void) CUIFObject::OnUnknown(DWORD x1, DWORD x2, DWORD x3) +{ +} + +inline STDMETHODIMP_(void) CUIFObject::GetRect(LPRECT prc) +{ + *prc = this->m_rc; +} + +/// @unimplemented +inline STDMETHODIMP_(void) CUIFObject::SetRect(LPCRECT prc) +{ + m_rc = *prc; + // FIXME + CallOnPaint(); +} + +inline STDMETHODIMP_(BOOL) CUIFObject::PtInObject(POINT pt) +{ + return m_bVisible && ::PtInRect(&m_rc, pt); +} + +inline STDMETHODIMP_(void) CUIFObject::PaintObject(HWND hWnd, LPCRECT prc) +{ + if (!m_bVisible) + return; + + if (!prc) + prc = &m_rc; + + OnPaint(hWnd); + + for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem) + { + CUIFObject *pObject = m_ObjectArray[iItem]; + RECT rc; + if (::IntersectRect(&rc, prc, &pObject->m_rc)) + pObject->PaintObject(hWnd, &rc); + } +} + +/// @unimplemented +inline STDMETHODIMP_(void) CUIFObject::CallOnPaint() +{ + //FIXME +} + +inline STDMETHODIMP_(void) CUIFObject::Enable(BOOL bEnable) +{ + if (m_bEnable == bEnable) + return; + + m_bEnable = bEnable; + for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem) + m_ObjectArray[iItem]->Enable(bEnable); + + CallOnPaint(); +} + +inline STDMETHODIMP_(void) CUIFObject::Show(BOOL bVisible) +{ + if (m_bVisible == bVisible) + return; + + m_bVisible = bVisible; + for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem) + m_ObjectArray[iItem]->Show(bVisible); + + if (m_bVisible || m_pParent) + m_pParent->CallOnPaint(); +} + +inline STDMETHODIMP_(void) CUIFObject::SetFontToThis(HFONT hFont) +{ + m_bHasCustomFont = !!hFont; + if (!hFont) + hFont = (HFONT)::GetStockObject(DEFAULT_GUI_FONT); + m_hFont = hFont; +} + +inline STDMETHODIMP_(void) CUIFObject::SetFont(HFONT hFont) +{ + SetFontToThis(hFont); + + for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem) + m_ObjectArray[iItem]->SetFont(hFont); + + CallOnPaint(); +} + +inline STDMETHODIMP_(void) CUIFObject::SetStyle(DWORD style) +{ + m_style = style; +} + +inline STDMETHODIMP_(void) CUIFObject::AddUIObj(CUIFObject *pObject) +{ + m_ObjectArray.Add(pObject); + CallOnPaint(); +} + +inline STDMETHODIMP_(void) CUIFObject::RemoveUIObj(CUIFObject *pObject) +{ + if (m_ObjectArray.Remove(pObject)) + CallOnPaint(); +} + +inline STDMETHODIMP_(LRESULT) CUIFObject::OnObjectNotify(CUIFObject *pObject, WPARAM wParam, LPARAM lParam) +{ + if (m_pParent) + return m_pParent->OnObjectNotify(pObject, wParam, lParam); + return 0; +} + +inline STDMETHODIMP_(void) CUIFObject::SetToolTip(LPCWSTR pszToolTip) +{ + if (m_pszToolTip) + { + delete[] m_pszToolTip; + m_pszToolTip = NULL; + } + + if (pszToolTip) + { + size_t cch = wcslen(pszToolTip); + m_pszToolTip = new(cicNoThrow) WCHAR[cch + 1]; + if (m_pszToolTip) + wcscpy(m_pszToolTip, pszToolTip); + } +} + +inline STDMETHODIMP_(LPCWSTR) CUIFObject::GetToolTip() +{ + return m_pszToolTip; +} + +inline STDMETHODIMP_(LRESULT) CUIFObject::OnShowToolTip() +{ + return 0; +} + +// FIXME: name +inline STDMETHODIMP_(void) CUIFObject::OnHideToolTip2() +{ +} + +/// @unimplemented +inline STDMETHODIMP_(void) CUIFObject::DetachWndObj() +{ + //FIXME + m_pWindow = NULL; +} + +inline STDMETHODIMP_(void) CUIFObject::ClearWndObj() +{ + m_pWindow = NULL; + for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem) + m_ObjectArray[iItem]->ClearWndObj(); +} + +inline STDMETHODIMP_(LRESULT) CUIFObject::OnPaintTheme(HWND hWnd) +{ + return 0; +} + +inline STDMETHODIMP_(void) CUIFObject::OnSetFocus(HWND hWnd) +{ +} + +inline STDMETHODIMP_(void) CUIFObject::ClearTheme() +{ + CloseThemeData(); + for (size_t iItem = 0; iItem < m_ObjectArray.size(); ++iItem) + m_ObjectArray[iItem]->ClearTheme(); +}