Commit 3701cb2f authored by Frank Richter's avatar Frank Richter Committed by Alexandre Julliard

Implementation for GetThemePartSize() (not entirely equivalent to

native uxtheme, but sensibly useable).
parent c93da092
......@@ -371,46 +371,33 @@ static HRESULT UXTHEME_DrawGlyph(HTHEME hTheme, HDC hdc, int iPartId,
}
/***********************************************************************
* UXTHEME_DrawImageBackground
* get_image_part_size
*
* Draw an imagefile background
* Used by GetThemePartSize and UXTHEME_DrawImageBackground
*/
static HRESULT UXTHEME_DrawImageBackground(HTHEME hTheme, HDC hdc, int iPartId,
int iStateId, RECT *pRect,
const DTBGOPTS *pOptions)
static HRESULT get_image_part_size (HTHEME hTheme, HDC hdc, int iPartId,
int iStateId, RECT *prc, THEMESIZE eSize,
POINT *psz)
{
HRESULT hr = S_OK;
HBITMAP bmpSrc;
HGDIOBJ oldSrc;
HDC hdcSrc;
RECT rcSrc;
hr = UXTHEME_LoadImage(hTheme, hdc, iPartId, iStateId, prc, FALSE, &bmpSrc, &rcSrc);
if (FAILED(hr)) return hr;
switch (eSize)
{
case TS_DRAW:
if (prc != NULL)
{
RECT rcDst;
POINT dstSize;
POINT srcSize;
int sizingtype = ST_TRUESIZE;
int sizingtype = ST_STRETCH;
BOOL uniformsizing = FALSE;
BOOL transparent = FALSE;
COLORREF transparentcolor = 0;
hr = UXTHEME_LoadImage(hTheme, hdc, iPartId, iStateId, pRect, FALSE, &bmpSrc, &rcSrc);
if(FAILED(hr)) return hr;
hdcSrc = CreateCompatibleDC(hdc);
if(!hdcSrc) {
hr = HRESULT_FROM_WIN32(GetLastError());
DeleteObject(bmpSrc);
return hr;
}
oldSrc = SelectObject(hdcSrc, bmpSrc);
CopyRect(&rcDst, pRect);
GetThemeBool(hTheme, iPartId, iStateId, TMT_TRANSPARENT, &transparent);
if(transparent) {
if(FAILED(GetThemeColor(hTheme, iPartId, iStateId, TMT_TRANSPARENTCOLOR, &transparentcolor))) {
/* If image is transparent, but no color was specified, get the color of the upper left corner */
transparentcolor = GetPixel(hdcSrc, 0, 0);
}
}
CopyRect(&rcDst, prc);
dstSize.x = rcDst.right-rcDst.left;
dstSize.y = rcDst.bottom-rcDst.top;
......@@ -455,21 +442,88 @@ static HRESULT UXTHEME_DrawImageBackground(HTHEME hTheme, HDC hdc, int iPartId,
if(dstSize.x < 0 || dstSize.y < 0 ||
MulDiv(srcSize.x, 100, dstSize.x) > truesizestretchmark ||
MulDiv(srcSize.y, 100, dstSize.y) > truesizestretchmark) {
if(!UXTHEME_StretchBlt(hdc, rcDst.left, rcDst.top, dstSize.x, dstSize.y,
hdcSrc, rcSrc.left, rcSrc.top, srcSize.x, srcSize.y,
transparent, transparentcolor))
hr = HRESULT_FROM_WIN32(GetLastError());
memcpy (psz, &dstSize, sizeof (SIZE));
}
else {
rcDst.left += (dstSize.x/2)-(srcSize.x/2);
rcDst.top += (dstSize.y/2)-(srcSize.y/2);
rcDst.right = rcDst.left + srcSize.x;
rcDst.bottom = rcDst.top + srcSize.y;
if(!UXTHEME_Blt(hdc, rcDst.left, rcDst.top, srcSize.x, srcSize.y,
hdcSrc, rcSrc.left, rcSrc.top,
transparent, transparentcolor))
memcpy (psz, &srcSize, sizeof (SIZE));
}
}
else
{
psz->x = abs(dstSize.x);
psz->y = abs(dstSize.y);
}
break;
}
/* else fall through */
case TS_MIN:
/* FIXME: couldn't figure how native uxtheme computes min size */
case TS_TRUE:
psz->x = rcSrc.right - rcSrc.left;
psz->y = rcSrc.bottom - rcSrc.top;
break;
}
return hr;
}
/***********************************************************************
* UXTHEME_DrawImageBackground
*
* Draw an imagefile background
*/
static HRESULT UXTHEME_DrawImageBackground(HTHEME hTheme, HDC hdc, int iPartId,
int iStateId, RECT *pRect,
const DTBGOPTS *pOptions)
{
HRESULT hr = S_OK;
HBITMAP bmpSrc;
HGDIOBJ oldSrc;
HDC hdcSrc;
RECT rcSrc;
RECT rcDst;
POINT dstSize;
POINT srcSize;
POINT drawSize;
int sizingtype = ST_STRETCH;
BOOL transparent = FALSE;
COLORREF transparentcolor = 0;
hr = UXTHEME_LoadImage(hTheme, hdc, iPartId, iStateId, pRect, FALSE, &bmpSrc, &rcSrc);
if(FAILED(hr)) return hr;
hdcSrc = CreateCompatibleDC(hdc);
if(!hdcSrc) {
hr = HRESULT_FROM_WIN32(GetLastError());
DeleteObject(bmpSrc);
return hr;
}
oldSrc = SelectObject(hdcSrc, bmpSrc);
CopyRect(&rcDst, pRect);
GetThemeBool(hTheme, iPartId, iStateId, TMT_TRANSPARENT, &transparent);
if(transparent) {
if(FAILED(GetThemeColor(hTheme, iPartId, iStateId, TMT_TRANSPARENTCOLOR, &transparentcolor))) {
/* If image is transparent, but no color was specified, get the color of the upper left corner */
transparentcolor = GetPixel(hdcSrc, 0, 0);
}
}
dstSize.x = rcDst.right-rcDst.left;
dstSize.y = rcDst.bottom-rcDst.top;
srcSize.x = rcSrc.right-rcSrc.left;
srcSize.y = rcSrc.bottom-rcSrc.top;
GetThemeEnumValue(hTheme, iPartId, iStateId, TMT_SIZINGTYPE, &sizingtype);
if(sizingtype == ST_TRUESIZE) {
get_image_part_size (hTheme, hdc, iPartId, iStateId, pRect, TS_DRAW, &drawSize);
rcDst.left += (dstSize.x/2)-(drawSize.x/2);
rcDst.top += (dstSize.y/2)-(drawSize.y/2);
rcDst.right = rcDst.left + drawSize.x;
rcDst.bottom = rcDst.top + drawSize.y;
if(!UXTHEME_StretchBlt(hdc, rcDst.left, rcDst.top, drawSize.x, drawSize.y,
hdcSrc, rcSrc.left, rcSrc.top, srcSize.x, srcSize.y,
transparent, transparentcolor))
hr = HRESULT_FROM_WIN32(GetLastError());
}
else {
HDC hdcDst = NULL;
......@@ -976,6 +1030,26 @@ HRESULT WINAPI GetThemeBackgroundRegion(HTHEME hTheme, HDC hdc, int iPartId,
return hr;
}
/* compute part size for "borderfill" backgrounds */
HRESULT get_border_background_size (HTHEME hTheme, int iPartId,
int iStateId, THEMESIZE eSize, POINT* psz)
{
HRESULT hr = S_OK;
int bordersize = 1;
if (SUCCEEDED (hr = GetThemeInt(hTheme, iPartId, iStateId, TMT_BORDERSIZE,
&bordersize)))
{
psz->x = psz->y = 2*bordersize;
if (eSize != TS_MIN)
{
psz->x++;
psz->y++;
}
}
return hr;
}
/***********************************************************************
* GetThemePartSize (UXTHEME.@)
*/
......@@ -983,10 +1057,26 @@ HRESULT WINAPI GetThemePartSize(HTHEME hTheme, HDC hdc, int iPartId,
int iStateId, RECT *prc, THEMESIZE eSize,
SIZE *psz)
{
FIXME("%d %d %d: stub\n", iPartId, iStateId, eSize);
int bgtype = BT_BORDERFILL;
HRESULT hr = S_OK;
POINT size = {1, 1};
if(!hTheme)
return E_HANDLE;
return ERROR_CALL_NOT_IMPLEMENTED;
GetThemeEnumValue(hTheme, iPartId, iStateId, TMT_BGTYPE, &bgtype);
if(bgtype == BT_IMAGEFILE)
hr = get_image_part_size (hTheme, hdc, iPartId, iStateId, prc, eSize, &size);
else if(bgtype == BT_BORDERFILL)
hr = get_border_background_size (hTheme, iPartId, iStateId, eSize, &size);
else {
FIXME("Unknown background type\n");
/* This should never happen, and hence I don't know what to return */
hr = E_FAIL;
}
psz->cx = size.x;
psz->cy = size.y;
return hr;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment