diff --git a/reactos/lib/uxtheme/nostyle/button.c b/reactos/lib/uxtheme/nostyle/button.c index a337c91eb34..82bf4b367d8 100644 --- a/reactos/lib/uxtheme/nostyle/button.c +++ b/reactos/lib/uxtheme/nostyle/button.c @@ -4,29 +4,61 @@ /* Functions */ STDAPI Button_DrawBackground ( - struct UXTHEME_DATA_ * pData, - HDC hdc, - int iPartId, - int iStateId, - const RECT * pRect, - const RECT * pClipRect + IN OUT struct UXTHEME_DATA_ * pData, + IN HDC hdc, + IN int iPartId, + IN int iStateId, + IN const RECT * pRect, + IN const RECT * pClipRect +); + +STDAPI Button_DrawText +( + IN OUT struct UXTHEME_DATA_ * pData, + IN HDC hdc, + IN int iPartId, + IN int iStateId, + IN LPCWSTR pszText, + IN int iCharCount, + IN DWORD dwTextFlags, + IN DWORD dwTextFlags2, + IN const RECT * pRect +); + +STDAPI Button_GetBackgroundContentRect +( + IN OUT struct UXTHEME_DATA_ * pData, + IN HDC hdc, + IN int iPartId, + IN int iStateId, + IN const RECT * pBoundingRect, + OUT RECT * pContentRect ); STDAPI_(BOOL) Button_IsPartDefined ( - struct UXTHEME_DATA_ * pData, - int iPartId, - int iStateId + IN OUT struct UXTHEME_DATA_ * pData, + IN int iPartId, + IN int iStateId ); const UXTHEME_VTABLE Button_Vt = { - (void *)Button_DrawBackground /* why (void *)? because GCC is stupid */ + (void *)Button_DrawBackground, /* why (void *)? because GCC is stupid */ + (void *)Button_DrawText, + (void *)Button_GetBackgroundContentRect }; +/* + * + * DrawThemeBackground + * + */ + /* BP_PUSHBUTTON */ static const UINT Button_PushButton_State[] = { + DFCS_BUTTONPUSH, /* */ DFCS_BUTTONPUSH, /* PBS_NORMAL */ DFCS_BUTTONPUSH | DFCS_HOT, /* PBS_HOT */ DFCS_BUTTONPUSH | DFCS_PUSHED, /* PBS_PRESSED */ @@ -37,6 +69,7 @@ static const UINT Button_PushButton_State[] = /* BP_RADIOBUTTON */ static const UINT Button_RadioButton_State[] = { + DFCS_BUTTONRADIO, /* */ DFCS_BUTTONRADIO, /* RBS_UNCHECKEDNORMAL */ DFCS_BUTTONRADIO | DFCS_HOT, /* RBS_UNCHECKEDHOT */ DFCS_BUTTONRADIO | DFCS_PUSHED, /* RBS_UNCHECKEDPRESSED */ @@ -50,6 +83,7 @@ static const UINT Button_RadioButton_State[] = /* BP_CHECKBOX */ static const UINT Button_CheckBox_State[] = { + DFCS_BUTTONCHECK, /* */ DFCS_BUTTONCHECK, /* CBS_UNCHECKEDNORMAL */ DFCS_BUTTONCHECK | DFCS_HOT, /* CBS_UNCHECKEDHOT */ DFCS_BUTTONCHECK | DFCS_PUSHED, /* CBS_UNCHECKEDPRESSED */ @@ -62,10 +96,11 @@ static const UINT Button_CheckBox_State[] = DFCS_BUTTON3STATE | DFCS_CHECKED | DFCS_HOT, /* CBS_MIXEDHOT */ DFCS_BUTTON3STATE | DFCS_CHECKED | DFCS_PUSHED, /* CBS_MIXEDPRESSED */ DFCS_BUTTON3STATE | DFCS_CHECKED | DFCS_INACTIVE /* CBS_MIXEDDISABLED */ -}; +}; static UINT const * Button_Part_State[] = { + NULL, Button_PushButton_State, Button_RadioButton_State, Button_CheckBox_State @@ -122,8 +157,6 @@ STDAPI Button_DrawBackground HRGN hrgnSave; HRESULT hres = S_OK; - /*UxTheme_Trace(("[ Button_DrawBackground"));*/ - for(;;) { if(!Button_IsPartDefined(pData, iPartId, iStateId)) @@ -132,7 +165,7 @@ STDAPI Button_DrawBackground break; } - uState = Button_Part_State[iPartId - 1][iStateId - 1]; + uState = Button_Part_State[iPartId][iStateId]; if(pClipRect && FAILED(hres = UxTheme_ClipDc(hdc, pClipRect, &hrgnSave))) break; @@ -151,11 +184,290 @@ STDAPI Button_DrawBackground break; } - /*UxTheme_Trace(("] Button_DrawBackground (status %X)", hres));*/ + return hres; +} + +/* + * + * DrawThemeText + * + */ +STDAPI_(BOOL) Button_TextGrayed +( + IN OUT struct UXTHEME_DATA_ * pData, + IN HDC hdc, + IN int iPartId, + IN int iStateId, + IN DWORD dwTextFlags2 +) +{ + if(dwTextFlags2 & DTT_GRAYED == DTT_GRAYED) return TRUE; + + switch(iPartId) + { + case BP_PUSHBUTTON: + switch(iStateId) + { + case PBS_DISABLED: + return TRUE; + } + + break; + + case BP_RADIOBUTTON: + switch(iStateId) + { + case RBS_UNCHECKEDDISABLED: + case RBS_CHECKEDDISABLED: + return TRUE; + } + + break; + + case BP_CHECKBOX: + switch(iStateId) + { + case CBS_UNCHECKEDDISABLED: + case CBS_CHECKEDDISABLED: + case CBS_MIXEDDISABLED: + return TRUE; + } + + break; + + case BP_GROUPBOX: + switch(iStateId) + { + case GBS_DISABLED: + return TRUE; + } + + break; + + case BP_USERBUTTON: + case 0: + default: + break; + } + + return FALSE; +} + +struct Button_DrawTextString +{ + LPCWSTR pszText; + int iCharCount; +}; + +BOOL CALLBACK Button_DrawTextStateProc +( + HDC hdc, + LPARAM lData, + WPARAM wData, + int cx, + int cy +) +{ + RECT rc; + + rc.left = 0; + rc.top = 0; + rc.right = cx; + rc.bottom = cy; + + return DrawTextW + ( + hdc, + ((struct Button_DrawTextString *)lData)->pszText, + ((struct Button_DrawTextString *)lData)->iCharCount, + &rc, + (UINT)wData + ); +} + +STDAPI Button_DrawText +( + IN OUT struct UXTHEME_DATA_ * pData, + IN HDC hdc, + IN int iPartId, + IN int iStateId, + IN LPCWSTR pszText, + IN int iCharCount, + IN DWORD dwTextFlags, + IN DWORD dwTextFlags2, + IN const RECT * pRect +) +{ + BOOL bRet; + int nBkMode; + COLORREF clrOld; + struct Button_DrawTextString dtsString; + DWORD dwDSFlags = DST_COMPLEX; + HRESULT hres = S_OK; + + for(;;) + { + /* check if the part is supported */ + if(!Button_IsPartDefined(pData, iPartId, iStateId)) + { + hres = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + break; + } + + nBkMode = SetBkMode(hdc, TRANSPARENT); + clrOld = SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT)); + + if(Button_TextGrayed(pData, hdc, iPartId, iStateId, dwTextFlags2)) + dwDSFlags |= DSS_DISABLED; + + dtsString.pszText = pszText; + dtsString.iCharCount = iCharCount; + + bRet = DrawStateW + ( + hdc, + NULL, + Button_DrawTextStateProc, + (LPARAM)&dtsString, + (WPARAM)dwTextFlags, + pRect->left, + pRect->top, + pRect->right - pRect->left, + pRect->bottom - pRect->top, + dwDSFlags + ); + + if(!bRet) hres = HRESULT_FROM_WIN32(GetLastError()); + + SetTextColor(hdc, clrOld); + SetBkMode(hdc, nBkMode); + + break; + } return hres; } +/* + * + * GetThemeBackgroundContentRect + * + */ +STDAPI Button_GetBackgroundContentRectSpecial +( + IN OUT struct UXTHEME_DATA_ * pData, + IN HDC hdc, + IN int iPartId, + IN int iStateId, + IN const RECT * pBoundingRect, + OUT RECT * pContentRect +) +{ + HRESULT hres = S_FALSE; + + if(iPartId == BP_GROUPBOX) + { + RECT rc = *pBoundingRect; + + if(!DrawEdge(hdc, &rc, EDGE_ETCHED, BF_RECT | BF_ADJUST)) + hres = HRESULT_FROM_WIN32(GetLastError()); + + *pContentRect = rc; + hres = S_OK; + } + else if(iPartId == BP_PUSHBUTTON && iStateId == PBS_DEFAULTED) + { + RECT rc = *pBoundingRect; + + InflateRect(&rc, -1, -1); + + if(!DrawFrameControl(hdc, &rc, DFC_BUTTON, DFCS_BUTTONPUSH | DFCS_ADJUSTRECT)) + hres = HRESULT_FROM_WIN32(GetLastError()); + else + { + *pContentRect = rc; + hres = S_OK; + } + } + + return hres; +} + +STDAPI Button_GetBackgroundContentRect +( + IN OUT struct UXTHEME_DATA_ * pData, + IN HDC hdc, + IN int iPartId, + IN int iStateId, + IN const RECT * pBoundingRect, + OUT RECT * pContentRect +) +{ + RECT rc; + HDC hdcCompat = NULL; + BOOL bRet; + HRESULT hres = S_OK; + + for(;;) + { + if(!Button_IsPartDefined(pData, iPartId, iStateId)) + { + hres = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + break; + } + + hdcCompat = CreateCompatibleDC(hdc); + + if(hdcCompat == NULL) + { + hres = HRESULT_FROM_WIN32(GetLastError()); + break; + } + + hres = Button_GetBackgroundContentRectSpecial + ( + pData, + hdcCompat, + iPartId, + iStateId, + pBoundingRect, + pContentRect + ); + + if(hres != S_FALSE) break; + + hres = S_OK; + rc = *pBoundingRect; + + bRet = DrawFrameControl + ( + hdcCompat, + &rc, + DFC_BUTTON, + Button_Part_State[iPartId][iStateId] | DFCS_ADJUSTRECT + ); + + if(!bRet) + { + hres = HRESULT_FROM_WIN32(GetLastError()); + break; + } + + *pContentRect = rc; + + break; + } + + DeleteDC(hdcCompat); + + return hres; +} + +/* + * + * IsThemePartDefined + * + */ STDAPI_(BOOL) Button_IsPartDefined ( struct UXTHEME_DATA_ * pData, @@ -168,6 +480,7 @@ STDAPI_(BOOL) Button_IsPartDefined case BP_PUSHBUTTON: switch(iStateId) { + case 0: case PBS_NORMAL: case PBS_HOT: case PBS_PRESSED: @@ -184,6 +497,7 @@ STDAPI_(BOOL) Button_IsPartDefined case BP_RADIOBUTTON: switch(iStateId) { + case 0: case RBS_UNCHECKEDNORMAL: case RBS_UNCHECKEDHOT: case RBS_UNCHECKEDPRESSED: @@ -203,6 +517,7 @@ STDAPI_(BOOL) Button_IsPartDefined case BP_CHECKBOX: switch(iStateId) { + case 0: case CBS_UNCHECKEDNORMAL: case CBS_UNCHECKEDHOT: case CBS_UNCHECKEDPRESSED: @@ -224,9 +539,21 @@ STDAPI_(BOOL) Button_IsPartDefined break; case BP_GROUPBOX: + switch(iStateId) + { + case 0: + case GBS_DISABLED: + case GBS_NORMAL: + break; + + default: + return FALSE; + } + break; - + case BP_USERBUTTON: + case 0: default: return FALSE; } diff --git a/reactos/lib/uxtheme/uxtheme.def b/reactos/lib/uxtheme/uxtheme.def index 6c5d85d77ad..d1a172bb6b8 100644 --- a/reactos/lib/uxtheme/uxtheme.def +++ b/reactos/lib/uxtheme/uxtheme.def @@ -40,7 +40,7 @@ DrawThemeBackground @6 ; @36 ;DrawThemeIcon @37 DrawThemeParentBackground @38 -;DrawThemeText @39 +DrawThemeText @39 ;EnableThemeDialogTexture @40 ;EnableTheming @41 ;GetCurrentThemeName @42 @@ -51,7 +51,7 @@ DrawThemeParentBackground @38 ; @47 ; @48 ;GetThemeAppProperties @49 -;GetThemeBackgroundContentRect @50 +GetThemeBackgroundContentRect @50 ;GetThemeBackgroundExtent @51 ;GetThemeBackgroundRegion @52 ;GetThemeBool @53 diff --git a/reactos/lib/uxtheme/uxthemedll.c b/reactos/lib/uxtheme/uxthemedll.c index e42f78d825c..9f74a792b6c 100644 --- a/reactos/lib/uxtheme/uxthemedll.c +++ b/reactos/lib/uxtheme/uxthemedll.c @@ -151,6 +151,58 @@ THEMEAPI DrawThemeParentBackground return E_FAIL; } +THEMEAPI DrawThemeText +( + IN HTHEME hTheme, + IN HDC hdc, + IN int iPartId, + IN int iStateId, + IN LPCWSTR pszText, + IN int iCharCount, + IN DWORD dwTextFlags, + IN DWORD dwTextFlags2, + IN const RECT * pRect +) +{ + PUXTHEME_DATA pUxTheme = HTHEME_TO_UXTHEME_(hTheme); + + return pUxTheme->pvt->p_DrawText + ( + pUxTheme, + hdc, + iPartId, + iStateId, + pszText, + iCharCount, + dwTextFlags, + dwTextFlags2, + pRect + ); +} + +THEMEAPI GetThemeBackgroundContentRect +( + IN HTHEME hTheme, + IN HDC hdc, + IN int iPartId, + IN int iStateId, + IN const RECT * pBoundingRect, + OUT RECT * pContentRect +) +{ + PUXTHEME_DATA pUxTheme = HTHEME_TO_UXTHEME_(hTheme); + + return pUxTheme->pvt->p_GetBackgroundContentRect + ( + pUxTheme, + hdc, + iPartId, + iStateId, + pBoundingRect, + pContentRect + ); +} + THEMEAPI_(BOOL) IsThemeBackgroundPartiallyTransparent ( HTHEME hTheme, diff --git a/reactos/lib/uxtheme/uxthemedll.h b/reactos/lib/uxtheme/uxthemedll.h index 771bca0d245..30ef8f79451 100644 --- a/reactos/lib/uxtheme/uxthemedll.h +++ b/reactos/lib/uxtheme/uxthemedll.h @@ -19,12 +19,35 @@ struct UXTHEME_VTABLE_ { HRESULT STDAPICALLTYPE (* p_DrawBackground) ( - struct UXTHEME_DATA_ * pData, - HDC hdc, - int iPartId, - int iStateId, - const RECT * pRect, - const RECT * pClipRect + IN OUT struct UXTHEME_DATA_ * pData, + IN HDC hdc, + IN int iPartId, + IN int iStateId, + IN const RECT * pRect, + IN const RECT * pClipRect + ); + + HRESULT STDAPICALLTYPE (* p_DrawText) + ( + IN OUT struct UXTHEME_DATA_ * pData, + IN HDC hdc, + IN int iPartId, + IN int iStateId, + IN LPCWSTR pszText, + IN int iCharCount, + IN DWORD dwTextFlags, + IN DWORD dwTextFlags2, + IN const RECT * pRect + ); + + HRESULT STDAPICALLTYPE (* p_GetBackgroundContentRect) + ( + IN OUT struct UXTHEME_DATA_ * pData, + IN HDC hdc, + IN int iPartId, + IN int iStateId, + IN const RECT * pBoundingRect, + OUT RECT * pContentRect ); };