Sync to Wine-20050830:
Kevin Koltzau <kevin(a)plop.org>
- Fix 'cast to pointer from integer of different size' warnings in
64bit.
Frank Richter <frank.richter(a)gmail.com>
- Add support for the BT_NONE background type.
- Better computations to have uniformly sized parts scaled in both
directions.
- Implement GetThemeBackgroundExtent().
- Implement DrawThemeEdge().
- Implement support for the ST_TILE background stretching mode.
- Implementation for GetThemePartSize() (not entirely equivalent to
native uxtheme, but sensibly useable).
- Enhance uxtheme to store the themed system metrics in the registry and
also backup the old metrics. That way, themed system colors are set
even uxtheme was not loaded and initialized yet, and when a theme is
deactivated, the colors prior to the activation are restored as well.
- Also, not having to set the system colors in uxtheme startup works
around weird problems where SetSystemColors() ended up being called
from inside window creation and this seemingly led to some creation
message being sent twice.
- Make GetThemeMargins() return default values (0 margin) if the
function does not succeed.
- More elaborate IsThemeBackgroundPartiallyTransparent() implementation;
also returns TRUE for theme parts with 32bpp images.
- Since theme images are reused now it's not really a good idea to
delete them in drawing functions.
- Pass around what kind of transparency an image actually needs. Use
alpha-blending for 32bpp images.
- Set some default values for truesize sizing that seem closer to
Windows.
- If a MINSIZEn property is not present, fall back to actual size of nth
image to determine whether it is suitable.
- EnumThemeColors() and EnumThemeSizes() actually do not return a single
string with the color/size name, but rather a struct containing three
strings - name, display name and tooltip.
- The default image layout is HORIZONTAL, not VERTICAL.
- Take a common computation out of two if-branches in
UXTHEME_LoadImage().
- Compare result of RegQueryValueExW() with ERROR_SUCCESS.
- Another fix to use magenta as the default transparent color.
- Implement "manual" image sharing(as opposed to using LoadImage() with
LR_SHARED) by keeping the loaded images in a list. This is needed for
proper alpha support later on since once-per-image preparations will
be needed then.
- Add support for horizontal & vertical alignment when doing truesize
sizing.
- Whatever TrueSizeStretchMark is for - it's not what Wine uxtheme used
it for. Native uxtheme always stretches "truesize" parts when the
destination is smaller than the part image size, but
TrueSizeStretchMark doesn't seem to have an influence.
Deleted: trunk/reactos/lib/uxtheme/Makefile.in
Modified: trunk/reactos/lib/uxtheme/draw.c
Modified: trunk/reactos/lib/uxtheme/msstyles.c
Modified: trunk/reactos/lib/uxtheme/msstyles.h
Modified: trunk/reactos/lib/uxtheme/property.c
Modified: trunk/reactos/lib/uxtheme/system.c
Modified: trunk/reactos/lib/uxtheme/uxtheme.spec
Modified: trunk/reactos/lib/uxtheme/uxthemedll.h
_____
Deleted: trunk/reactos/lib/uxtheme/Makefile.in
--- trunk/reactos/lib/uxtheme/Makefile.in 2005-09-07 16:02:32 UTC
(rev 17718)
+++ trunk/reactos/lib/uxtheme/Makefile.in 2005-09-07 16:22:51 UTC
(rev 17719)
@@ -1,25 +0,0 @@
-TOPSRCDIR = @top_srcdir@
-TOPOBJDIR = ../..
-SRCDIR = @srcdir@
-VPATH = @srcdir@
-MODULE = uxtheme.dll
-IMPORTLIB = libuxtheme.$(IMPLIBEXT)
-IMPORTS = shlwapi user32 gdi32 advapi32 kernel32 ntdll
-DELAYIMPORTS = msimg32
-EXTRALIBS = $(LIBUNICODE)
-
-C_SRCS = \
- draw.c \
- main.c \
- metric.c \
- msstyles.c \
- property.c \
- stylemap.c \
- system.c \
- uxini.c
-
-RC_SRCS = version.rc
-
-@MAKE_DLL_RULES@
-
-### Dependencies:
_____
Modified: trunk/reactos/lib/uxtheme/draw.c
--- trunk/reactos/lib/uxtheme/draw.c 2005-09-07 16:02:32 UTC (rev
17718)
+++ trunk/reactos/lib/uxtheme/draw.c 2005-09-07 16:22:51 UTC (rev
17719)
@@ -187,12 +187,42 @@
POINT size = {pRect->right-pRect->left,
pRect->bottom-pRect->top};
POINT reqsize;
for(i=4; i>=0; i--) {
- if(SUCCEEDED(GetThemePosition(hTheme, iPartId, iStateId, i
+ TMT_MINSIZE1, &reqsize))) {
- if(reqsize.x >= size.x && reqsize.y >= size.y) {
- TRACE("Using image size %ldx%ld, image %d\n",
reqsize.x, reqsize.y, i + TMT_IMAGEFILE1);
- return MSSTYLES_FindProperty(hTheme, iPartId,
iStateId, TMT_FILENAME, i + TMT_IMAGEFILE1);
+ PTHEME_PROPERTY fileProp =
+ MSSTYLES_FindProperty(hTheme, iPartId, iStateId,
TMT_FILENAME, i + TMT_IMAGEFILE1);
+ if (!fileProp) continue;
+ if(FAILED(GetThemePosition(hTheme, iPartId, iStateId, i +
TMT_MINSIZE1, &reqsize))) {
+ /* fall back to size of Nth image */
+ WCHAR szPath[MAX_PATH];
+ int imagelayout = IL_HORIZONTAL;
+ int imagecount = 1;
+ int imagenum;
+ BITMAP bmp;
+ HBITMAP hBmp;
+ BOOL hasAlpha;
+
+ lstrcpynW(szPath, fileProp->lpValue,
+ min(fileProp->dwValueLen+1,
sizeof(szPath)/sizeof(szPath[0])));
+ hBmp = MSSTYLES_LoadBitmap(hTheme, szPath, &hasAlpha);
+ if(!hBmp) continue;
+
+ GetThemeEnumValue(hTheme, iPartId, iStateId,
TMT_IMAGELAYOUT, &imagelayout);
+ GetThemeInt(hTheme, iPartId, iStateId, TMT_IMAGECOUNT,
&imagecount);
+
+ imagenum = max (min (imagecount, iStateId), 1) - 1;
+ GetObjectW(hBmp, sizeof(bmp), &bmp);
+ if(imagelayout == IL_VERTICAL) {
+ reqsize.x = bmp.bmWidth;
+ reqsize.y = bmp.bmHeight/imagecount;
}
+ else {
+ reqsize.x = bmp.bmWidth/imagecount;
+ reqsize.y = bmp.bmHeight;
+ }
}
+ if(reqsize.x <= size.x && reqsize.y <= size.y) {
+ TRACE("Using image size %ldx%ld, image %d\n",
reqsize.x, reqsize.y, i + TMT_IMAGEFILE1);
+ return fileProp;
+ }
}
/* If an image couldnt be selected, choose the smallest one */
return MSSTYLES_FindProperty(hTheme, iPartId, iStateId,
TMT_FILENAME, TMT_IMAGEFILE1);
@@ -206,10 +236,11 @@
* Load image for part/state
*/
static HRESULT UXTHEME_LoadImage(HTHEME hTheme, HDC hdc, int iPartId,
int iStateId, const RECT *pRect, BOOL glyph,
- HBITMAP *hBmp, RECT *bmpRect)
+ HBITMAP *hBmp, RECT *bmpRect, BOOL*
hasImageAlpha)
{
- int imagelayout = IL_VERTICAL;
+ int imagelayout = IL_HORIZONTAL;
int imagecount = 1;
+ int imagenum;
BITMAP bmp;
WCHAR szPath[MAX_PATH];
PTHEME_PROPERTY tp = UXTHEME_SelectImage(hTheme, hdc, iPartId,
iStateId, pRect, glyph);
@@ -218,7 +249,7 @@
return E_PROP_ID_UNSUPPORTED;
}
lstrcpynW(szPath, tp->lpValue, min(tp->dwValueLen+1,
sizeof(szPath)/sizeof(szPath[0])));
- *hBmp = MSSTYLES_LoadBitmap(hdc, hTheme, szPath);
+ *hBmp = MSSTYLES_LoadBitmap(hTheme, szPath, hasImageAlpha);
if(!*hBmp) {
TRACE("Failed to load bitmap %s\n", debugstr_w(szPath));
return HRESULT_FROM_WIN32(GetLastError());
@@ -227,17 +258,18 @@
GetThemeEnumValue(hTheme, iPartId, iStateId, TMT_IMAGELAYOUT,
&imagelayout);
GetThemeInt(hTheme, iPartId, iStateId, TMT_IMAGECOUNT,
&imagecount);
+ imagenum = max (min (imagecount, iStateId), 1) - 1;
GetObjectW(*hBmp, sizeof(bmp), &bmp);
if(imagelayout == IL_VERTICAL) {
int height = bmp.bmHeight/imagecount;
bmpRect->left = 0;
bmpRect->right = bmp.bmWidth;
- bmpRect->top = (max(min(imagecount, iStateId), 1)-1) * height;
+ bmpRect->top = imagenum * height;
bmpRect->bottom = bmpRect->top + height;
}
else {
int width = bmp.bmWidth/imagecount;
- bmpRect->left = (max(min(imagecount, iStateId), 1)-1) * width;
+ bmpRect->left = imagenum * width;
bmpRect->right = bmpRect->left + width;
bmpRect->top = 0;
bmpRect->bottom = bmp.bmHeight;
@@ -248,22 +280,35 @@
/***********************************************************************
* UXTHEME_StretchBlt
*
- * Psudo TransparentBlt/StretchBlt
+ * Pseudo TransparentBlt/StretchBlt
*/
static inline BOOL UXTHEME_StretchBlt(HDC hdcDst, int nXOriginDst, int
nYOriginDst, int nWidthDst, int nHeightDst,
HDC hdcSrc, int nXOriginSrc, int
nYOriginSrc, int nWidthSrc, int nHeightSrc,
- BOOL transparent, COLORREF
transcolor)
+ INT transparent, COLORREF
transcolor)
{
- if(transparent) {
+ static const BLENDFUNCTION blendFunc =
+ {
+ AC_SRC_OVER, /* BlendOp */
+ 0, /* BlendFlag */
+ 255, /* SourceConstantAlpha */
+ AC_SRC_ALPHA /* AlphaFormat */
+ };
+ if (transparent == ALPHABLEND_BINARY) {
/* Ensure we don't pass any negative values to TransparentBlt
*/
return TransparentBlt(hdcDst, nXOriginDst, nYOriginDst,
abs(nWidthDst), abs(nHeightDst),
hdcSrc, nXOriginSrc, nYOriginSrc,
abs(nWidthSrc), abs(nHeightSrc),
transcolor);
}
- /* This should be using AlphaBlend */
- return StretchBlt(hdcDst, nXOriginDst, nYOriginDst, nWidthDst,
nHeightDst,
- hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc,
nHeightSrc,
- SRCCOPY);
+ if ((transparent == ALPHABLEND_NONE) ||
+ !AlphaBlend(hdcDst, nXOriginDst, nYOriginDst, nWidthDst,
nHeightDst,
+ hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc,
nHeightSrc,
+ blendFunc))
+ {
+ return StretchBlt(hdcDst, nXOriginDst, nYOriginDst, nWidthDst,
nHeightDst,
+ hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc,
nHeightSrc,
+ SRCCOPY);
+ }
+ return TRUE;
}
/***********************************************************************
@@ -273,14 +318,88 @@
*/
static inline BOOL UXTHEME_Blt(HDC hdcDest, int nXOriginDest, int
nYOriginDest, int nWidthDest, int nHeightDest,
HDC hdcSrc, int nXOriginSrc, int
nYOriginSrc,
- BOOL transparent, COLORREF transcolor)
+ INT transparent, COLORREF transcolor)
{
return UXTHEME_StretchBlt(hdcDest, nXOriginDest, nYOriginDest,
nWidthDest, nHeightDest,
hdcSrc, nXOriginSrc, nYOriginSrc,
nWidthDest, nHeightDest,
transparent, transcolor);
}
+/**********************************************************************
*
+ * UXTHEME_SizedBlt
+ *
+ * Stretches or tiles, depending on sizingtype.
+ */
+static inline BOOL UXTHEME_SizedBlt (HDC hdcDst, int nXOriginDst, int
nYOriginDst,
+ int nWidthDst, int nHeightDst,
+ HDC hdcSrc, int nXOriginSrc, int
nYOriginSrc,
+ int nWidthSrc, int nHeightSrc,
+ int sizingtype,
+ INT transparent, COLORREF
transcolor)
+{
+ if (sizingtype == ST_TILE)
+ {
+ int yOfs = nYOriginDst;
+ int yRemaining = nHeightDst;
+ while (yRemaining > 0)
+ {
+ int bltHeight = min (yRemaining, nHeightSrc);
+ int xOfs = nXOriginDst;
+ int xRemaining = nWidthDst;
+ while (xRemaining > 0)
+ {
+ int bltWidth = min (xRemaining, nWidthSrc);
+ if (!UXTHEME_Blt (hdcDst, xOfs, yOfs, bltWidth,
bltHeight,
+ hdcSrc, nXOriginSrc, nYOriginSrc,
+ transparent, transcolor))
+ return FALSE;
+ xOfs += nWidthSrc;
+ xRemaining -= nWidthSrc;
+ }
+ yOfs += nHeightSrc;
+ yRemaining -= nHeightSrc;
+ }
+ return TRUE;
+ }
+ else
+ {
+ return UXTHEME_StretchBlt (hdcDst, nXOriginDst, nYOriginDst,
nWidthDst, nHeightDst,
+ hdcSrc, nXOriginSrc, nYOriginSrc,
nWidthSrc, nHeightSrc,
+ transparent, transcolor);
+ }
+}
+/* Get transparency parameters passed to UXTHEME_StretchBlt() - the
parameters
+ * depend on whether the image has full alpha or whether it is
+ * color-transparent or just opaque. */
+static inline void get_transparency (HTHEME hTheme, int iPartId, int
iStateId,
+ BOOL hasImageAlpha, INT*
transparent,
+ COLORREF* transparentcolor, BOOL
glyph)
+{
+ if (hasImageAlpha)
+ {
+ *transparent = ALPHABLEND_FULL;
+ *transparentcolor = RGB (255, 0, 255);
+ }
+ else
+ {
+ BOOL trans = FALSE;
+ GetThemeBool(hTheme, iPartId, iStateId,
+ glyph ? TMT_GLYPHTRANSPARENT : TMT_TRANSPARENT, &trans);
+ if(trans) {
+ *transparent = ALPHABLEND_BINARY;
+ if(FAILED(GetThemeColor(hTheme, iPartId, iStateId,
+ glyph ? TMT_GLYPHTRANSPARENTCOLOR :
TMT_TRANSPARENTCOLOR,
+ transparentcolor))) {
+ /* If image is transparent, but no color was specified,
use magenta */
+ *transparentcolor = RGB(255, 0, 255);
+ }
+ }
+ else
+ *transparent = ALPHABLEND_NONE;
+ }
+}
+
/***********************************************************************
* UXTHEME_DrawImageGlyph
*
@@ -295,20 +414,21 @@
HDC hdcSrc = NULL;
HGDIOBJ oldSrc = NULL;
RECT rcSrc;
- BOOL transparent = FALSE;
- COLORREF transparentcolor = 0;
+ INT transparent = FALSE;
+ COLORREF transparentcolor;
int valign = VA_CENTER;
int halign = HA_CENTER;
POINT dstSize;
POINT srcSize;
POINT topleft;
+ BOOL hasAlpha;
- hr = UXTHEME_LoadImage(hTheme, hdc, iPartId, iStateId, pRect, TRUE,
&bmpSrc, &rcSrc);
+ hr = UXTHEME_LoadImage(hTheme, hdc, iPartId, iStateId, pRect, TRUE,
+ &bmpSrc, &rcSrc, &hasAlpha);
if(FAILED(hr)) return hr;
hdcSrc = CreateCompatibleDC(hdc);
if(!hdcSrc) {
hr = HRESULT_FROM_WIN32(GetLastError());
- DeleteObject(bmpSrc);
return hr;
}
oldSrc = SelectObject(hdcSrc, bmpSrc);
@@ -318,13 +438,8 @@
srcSize.x = rcSrc.right-rcSrc.left;
srcSize.y = rcSrc.bottom-rcSrc.top;
- GetThemeBool(hTheme, iPartId, iStateId, TMT_GLYPHTRANSPARENT,
&transparent);
- if(transparent) {
- if(FAILED(GetThemeColor(hTheme, iPartId, iStateId,
TMT_GLYPHTRANSPARENTCOLOR, &transparentcolor))) {
- /* If image is transparent, but no color was specified, use
magenta */
- transparentcolor = RGB(255, 0, 255);
- }
- }
+ get_transparency (hTheme, iPartId, iStateId, hasAlpha,
&transparent,
+ &transparentcolor, TRUE);
GetThemeEnumValue(hTheme, iPartId, iStateId, TMT_VALIGN, &valign);
GetThemeEnumValue(hTheme, iPartId, iStateId, TMT_HALIGN, &halign);
@@ -343,7 +458,6 @@
SelectObject(hdcSrc, oldSrc);
DeleteDC(hdcSrc);
- DeleteObject(bmpSrc);
return hr;
}
@@ -371,6 +485,110 @@
}
/***********************************************************************
+ * get_image_part_size
+ *
+ * Used by GetThemePartSize and UXTHEME_DrawImageBackground
+ */
+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;
+ RECT rcSrc;
+ BOOL hasAlpha;
+
+ hr = UXTHEME_LoadImage(hTheme, hdc, iPartId, iStateId, prc, FALSE,
+ &bmpSrc, &rcSrc, &hasAlpha);
+ if (FAILED(hr)) return hr;
+
+ switch (eSize)
+ {
+ case TS_DRAW:
+ if (prc != NULL)
+ {
+ RECT rcDst;
+ POINT dstSize;
+ POINT srcSize;
+ int sizingtype = ST_STRETCH;
+ BOOL uniformsizing = FALSE;
+
+ CopyRect(&rcDst, prc);
+
+ dstSize.x = rcDst.right-rcDst.left;
+ dstSize.y = rcDst.bottom-rcDst.top;
+ srcSize.x = rcSrc.right-rcSrc.left;
+ srcSize.y = rcSrc.bottom-rcSrc.top;
+
+ GetThemeBool(hTheme, iPartId, iStateId,
TMT_UNIFORMSIZING, &uniformsizing);
+ if(uniformsizing) {
+ /* Scale height and width equally */
+ if (dstSize.x*srcSize.y < dstSize.y*srcSize.x)
+ {
+ dstSize.y = MulDiv (srcSize.y, dstSize.x,
srcSize.x);
+ rcDst.bottom = rcDst.top + dstSize.y;
+ }
+ else
+ {
+ dstSize.x = MulDiv (srcSize.x, dstSize.y,
srcSize.y);
+ rcDst.right = rcDst.left + dstSize.x;
+ }
+ }
+
+ GetThemeEnumValue(hTheme, iPartId, iStateId,
TMT_SIZINGTYPE, &sizingtype);
+ if(sizingtype == ST_TRUESIZE) {
+ int truesizestretchmark = 100;
+
+ if(dstSize.x < 0 || dstSize.y < 0) {
+ BOOL mirrorimage = TRUE;
+ GetThemeBool(hTheme, iPartId, iStateId,
TMT_MIRRORIMAGE, &mirrorimage);
+ if(mirrorimage) {
+ if(dstSize.x < 0) {
+ rcDst.left += dstSize.x;
+ rcDst.right += dstSize.x;
+ }
+ if(dstSize.y < 0) {
+ rcDst.top += dstSize.y;
+ rcDst.bottom += dstSize.y;
+ }
+ }
+ }
+ /* Whatever TrueSizeStretchMark does - it does not
seem to
+ * be what's outlined below. It appears as if
native
+ * uxtheme always stretches if dest is smaller than
source
+ * (ie as if TrueSizeStretchMark==100 with the code
below) */
+#if 0
+ /* Only stretch when target exceeds source by
truesizestretchmark percent */
+ GetThemeInt(hTheme, iPartId, iStateId,
TMT_TRUESIZESTRETCHMARK, &truesizestretchmark);
+#endif
+ if(dstSize.x < 0 || dstSize.y < 0 ||
+ (MulDiv(srcSize.x, 100, dstSize.x) >
truesizestretchmark &&
+ MulDiv(srcSize.y, 100, dstSize.y) >
truesizestretchmark)) {
+ memcpy (psz, &dstSize, sizeof (SIZE));
+ }
+ else {
+ 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
@@ -387,143 +605,101 @@
RECT rcDst;
POINT dstSize;
POINT srcSize;
- int sizingtype = ST_TRUESIZE;
- BOOL uniformsizing = FALSE;
- BOOL transparent = FALSE;
+ POINT drawSize;
+ int sizingtype = ST_STRETCH;
+ INT transparent;
COLORREF transparentcolor = 0;
+ BOOL hasAlpha;
- hr = UXTHEME_LoadImage(hTheme, hdc, iPartId, iStateId, pRect,
FALSE, &bmpSrc, &rcSrc);
+ hr = UXTHEME_LoadImage(hTheme, hdc, iPartId, iStateId, pRect,
FALSE,
+ &bmpSrc, &rcSrc, &hasAlpha);
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);
- }
- }
+ get_transparency (hTheme, iPartId, iStateId, hasAlpha,
&transparent,
+ &transparentcolor, FALSE);
dstSize.x = rcDst.right-rcDst.left;
dstSize.y = rcDst.bottom-rcDst.top;
srcSize.x = rcSrc.right-rcSrc.left;
srcSize.y = rcSrc.bottom-rcSrc.top;
- GetThemeBool(hTheme, iPartId, iStateId, TMT_UNIFORMSIZING,
&uniformsizing);
- if(uniformsizing) {
- /* Scale height and width equally */
- int widthDiff = abs(srcSize.x-dstSize.x);
- int heightDiff = abs(srcSize.y-dstSize.x);
- if(widthDiff > heightDiff) {
- dstSize.y -= widthDiff-heightDiff;
- rcDst.bottom = rcDst.top + dstSize.y;
- }
- else if(heightDiff > widthDiff) {
- dstSize.x -= heightDiff-widthDiff;
- rcDst.right = rcDst.left + dstSize.x;
- }
- }
-
GetThemeEnumValue(hTheme, iPartId, iStateId, TMT_SIZINGTYPE,
&sizingtype);
if(sizingtype == ST_TRUESIZE) {
- int truesizestretchmark = 0;
+ int valign = VA_CENTER, halign = HA_CENTER;
- if(dstSize.x < 0 || dstSize.y < 0) {
- BOOL mirrorimage = TRUE;
- GetThemeBool(hTheme, iPartId, iStateId, TMT_MIRRORIMAGE,
&mirrorimage);
- if(mirrorimage) {
- if(dstSize.x < 0) {
- rcDst.left += dstSize.x;
- rcDst.right += dstSize.x;
- }
- if(dstSize.y < 0) {
- rcDst.top += dstSize.y;
- rcDst.bottom += dstSize.y;
- }
- }
- }
- /* Only stretch when target exceeds source by
truesizestretchmark percent */
- GetThemeInt(hTheme, iPartId, iStateId, TMT_TRUESIZESTRETCHMARK,
&truesizestretchmark);
- 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());
- }
- 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))
- hr = HRESULT_FROM_WIN32(GetLastError());
- }
+ get_image_part_size (hTheme, hdc, iPartId, iStateId, pRect,
TS_DRAW, &drawSize);
+ GetThemeEnumValue(hTheme, iPartId, iStateId, TMT_VALIGN,
&valign);
+ GetThemeEnumValue(hTheme, iPartId, iStateId, TMT_HALIGN,
&halign);
+
+ if (halign == HA_CENTER)
+ rcDst.left += (dstSize.x/2)-(drawSize.x/2);
+ else if (halign == HA_RIGHT)
+ rcDst.left = rcDst.right - drawSize.x;
+ if (valign == VA_CENTER)
+ rcDst.top += (dstSize.y/2)-(drawSize.y/2);
+ else if (valign == VA_BOTTOM)
+ rcDst.top = rcDst.bottom - drawSize.y;
+ 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;
- HBITMAP bmpDst = NULL;
- HGDIOBJ oldDst = NULL;
MARGINS sm;
+ POINT org;
dstSize.x = abs(dstSize.x);
dstSize.y = abs(dstSize.y);
GetThemeMargins(hTheme, hdc, iPartId, iStateId,
TMT_SIZINGMARGINS, NULL, &sm);
- hdcDst = CreateCompatibleDC(hdc);
- if(!hdcDst) {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto draw_error;
- }
- bmpDst = CreateCompatibleBitmap(hdc, dstSize.x, dstSize.y);
- if(!bmpDst) {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto draw_error;
- }
- oldDst = SelectObject(hdcDst, bmpDst);
+ hdcDst = hdc;
+ OffsetViewportOrgEx(hdcDst, rcDst.left, rcDst.top, &org);
/* Upper left corner */
- if(!BitBlt(hdcDst, 0, 0, sm.cxLeftWidth, sm.cyTopHeight,
- hdcSrc, rcSrc.left, rcSrc.top, SRCCOPY)) {
+ if(!UXTHEME_Blt(hdcDst, 0, 0, sm.cxLeftWidth, sm.cyTopHeight,
+ hdcSrc, rcSrc.left, rcSrc.top,
+ transparent, transparentcolor)) {
hr = HRESULT_FROM_WIN32(GetLastError());
goto draw_error;
}
/* Upper right corner */
- if(!BitBlt(hdcDst, dstSize.x-sm.cxRightWidth, 0,
sm.cxRightWidth, sm.cyTopHeight,
- hdcSrc, rcSrc.right-sm.cxRightWidth, rcSrc.top,
SRCCOPY)) {
+ if(!UXTHEME_Blt (hdcDst, dstSize.x-sm.cxRightWidth, 0,
+ sm.cxRightWidth, sm.cyTopHeight,
+ hdcSrc, rcSrc.right-sm.cxRightWidth,
rcSrc.top,
+ transparent, transparentcolor)) {
hr = HRESULT_FROM_WIN32(GetLastError());
goto draw_error;
}
/* Lower left corner */
- if(!BitBlt(hdcDst, 0, dstSize.y-sm.cyBottomHeight,
sm.cxLeftWidth, sm.cyBottomHeight,
- hdcSrc, rcSrc.left, rcSrc.bottom-sm.cyBottomHeight,
SRCCOPY)) {
+ if(!UXTHEME_Blt (hdcDst, 0, dstSize.y-sm.cyBottomHeight,
+ sm.cxLeftWidth, sm.cyBottomHeight,
+ hdcSrc, rcSrc.left,
rcSrc.bottom-sm.cyBottomHeight,
+ transparent, transparentcolor)) {
hr = HRESULT_FROM_WIN32(GetLastError());
goto draw_error;
}
/* Lower right corner */
- if(!BitBlt(hdcDst, dstSize.x-sm.cxRightWidth,
dstSize.y-sm.cyBottomHeight, sm.cxRightWidth, sm.cyBottomHeight,
- hdcSrc, rcSrc.right-sm.cxRightWidth,
rcSrc.bottom-sm.cyBottomHeight, SRCCOPY)) {
+ if(!UXTHEME_Blt (hdcDst, dstSize.x-sm.cxRightWidth,
dstSize.y-sm.cyBottomHeight,
+ sm.cxRightWidth, sm.cyBottomHeight,
+ hdcSrc, rcSrc.right-sm.cxRightWidth,
rcSrc.bottom-sm.cyBottomHeight,
+ transparent, transparentcolor)) {
hr = HRESULT_FROM_WIN32(GetLastError());
goto draw_error;
}
- if(sizingtype == ST_TILE) {
- FIXME("Tile\n");
- sizingtype = ST_STRETCH; /* Just use stretch for now */
- }
- if(sizingtype == ST_STRETCH) {
+ if ((sizingtype == ST_STRETCH) || (sizingtype == ST_TILE)) {
int destCenterWidth = dstSize.x - (sm.cxLeftWidth +
sm.cxRightWidth);
int srcCenterWidth = srcSize.x - (sm.cxLeftWidth +
sm.cxRightWidth);
int destCenterHeight = dstSize.y - (sm.cyTopHeight +
sm.cyBottomHeight);
@@ -531,28 +707,41 @@
if(destCenterWidth > 0) {
/* Center top */
- if(!StretchBlt(hdcDst, sm.cxLeftWidth, 0,
destCenterWidth, sm.cyTopHeight,
- hdcSrc, rcSrc.left+sm.cxLeftWidth,
rcSrc.top, srcCenterWidth, sm.cyTopHeight, SRCCOPY)) {
+ if(!UXTHEME_SizedBlt (hdcDst, sm.cxLeftWidth, 0,
+ destCenterWidth, sm.cyTopHeight,
+ hdcSrc,
rcSrc.left+sm.cxLeftWidth, rcSrc.top,
+ srcCenterWidth, sm.cyTopHeight,
+ sizingtype, transparent,
transparentcolor)) {
hr = HRESULT_FROM_WIN32(GetLastError());
goto draw_error;
}
/* Center bottom */
- if(!StretchBlt(hdcDst, sm.cxLeftWidth,
dstSize.y-sm.cyBottomHeight, destCenterWidth, sm.cyBottomHeight,
- hdcSrc, rcSrc.left+sm.cxLeftWidth,
rcSrc.bottom-sm.cyBottomHeight, srcCenterWidth, sm.cyTopHeight,
SRCCOPY)) {
+ if(!UXTHEME_SizedBlt (hdcDst, sm.cxLeftWidth,
dstSize.y-sm.cyBottomHeight,
+ destCenterWidth,
sm.cyBottomHeight,
+ hdcSrc,
rcSrc.left+sm.cxLeftWidth, rcSrc.bottom-sm.cyBottomHeight,
+ srcCenterWidth,
sm.cyBottomHeight,
+ sizingtype, transparent,
transparentcolor)) {
hr = HRESULT_FROM_WIN32(GetLastError());
goto draw_error;
}
}
if(destCenterHeight > 0) {
/* Left center */
- if(!StretchBlt(hdcDst, 0, sm.cyTopHeight,
sm.cxLeftWidth, destCenterHeight,
- hdcSrc, rcSrc.left,
rcSrc.top+sm.cyTopHeight, sm.cxLeftWidth, srcCenterHeight, SRCCOPY)) {
+ if(!UXTHEME_SizedBlt (hdcDst, 0, sm.cyTopHeight,
+ sm.cxLeftWidth, destCenterHeight,
+ hdcSrc, rcSrc.left,
rcSrc.top+sm.cyTopHeight,
+ sm.cxLeftWidth, srcCenterHeight,
+ sizingtype,
+ transparent, transparentcolor)) {
hr = HRESULT_FROM_WIN32(GetLastError());
goto draw_error;
}
/* Right center */
- if(!StretchBlt(hdcDst, dstSize.x-sm.cxRightWidth,
sm.cyTopHeight, sm.cxRightWidth, destCenterHeight,
- hdcSrc, rcSrc.right-sm.cxRightWidth,
rcSrc.top+sm.cyTopHeight, sm.cxRightWidth, srcCenterHeight, SRCCOPY)) {
+ if(!UXTHEME_SizedBlt (hdcDst,
dstSize.x-sm.cxRightWidth, sm.cyTopHeight,
+ sm.cxRightWidth,
destCenterHeight,
+ hdcSrc,
rcSrc.right-sm.cxRightWidth, rcSrc.top+sm.cyTopHeight,
+ sm.cxRightWidth, srcCenterHeight,
+ sizingtype, transparent,
transparentcolor)) {
hr = HRESULT_FROM_WIN32(GetLastError());
goto draw_error;
}
@@ -562,8 +751,11 @@
GetThemeBool(hTheme, iPartId, iStateId, TMT_BORDERONLY,
&borderonly);
if(!borderonly) {
/* Center */
- if(!StretchBlt(hdcDst, sm.cxLeftWidth,
sm.cyTopHeight, destCenterWidth, destCenterHeight,
- hdcSrc, rcSrc.left+sm.cxLeftWidth,
rcSrc.top+sm.cyTopHeight, srcCenterWidth, srcCenterHeight, SRCCOPY)) {
+ if(!UXTHEME_SizedBlt (hdcDst, sm.cxLeftWidth,
sm.cyTopHeight,
+ destCenterWidth,
destCenterHeight,
+ hdcSrc,
rcSrc.left+sm.cxLeftWidth, rcSrc.top+sm.cyTopHeight,
+ srcCenterWidth,
srcCenterHeight,
+ sizingtype, transparent,
transparentcolor)) {
hr = HRESULT_FROM_WIN32(GetLastError());
goto draw_error;
}
@@ -571,20 +763,10 @@
}
}
- if(!UXTHEME_Blt(hdc, rcDst.left, rcDst.top, dstSize.x,
dstSize.y,
- hdcDst, 0, 0,
- transparent, transparentcolor))
- hr = HRESULT_FROM_WIN32(GetLastError());
-
draw_error:
- if(hdcDst) {
- SelectObject(hdcDst, oldDst);
- DeleteDC(hdcDst);
- }
- if(bmpDst) DeleteObject(bmpDst);
+ SetViewportOrgEx (hdcDst, org.x, org.y, NULL);
}
SelectObject(hdcSrc, oldSrc);
- DeleteObject(bmpSrc);
DeleteDC(hdcSrc);
CopyRect(pRect, &rcDst);
return hr;
@@ -751,6 +933,9 @@
if(!hTheme)
return E_HANDLE;
+ GetThemeEnumValue(hTheme, iPartId, iStateId, TMT_BGTYPE, &bgtype);
+ if (bgtype == BT_NONE) return S_OK;
+
/* Ensure we have a DTBGOPTS structure available, simplifies some
of the code */
opts = pOptions;
if(!opts) opts = &defaultOpts;
@@ -765,7 +950,6 @@
}
CopyRect(&rt, pRect);
- GetThemeEnumValue(hTheme, iPartId, iStateId, TMT_BGTYPE, &bgtype);
if(bgtype == BT_IMAGEFILE)
hr = UXTHEME_DrawImageBackground(hTheme, hdc, iPartId,
iStateId, &rt, opts);
else if(bgtype == BT_BORDERFILL)
@@ -787,19 +971,557 @@
return hr;
}
+/*
+ * DrawThemeEdge() implementation
+ *
+ * Since it basically is DrawEdge() with different colors, I copied its
code
+ * from user32's uitools.c.
+ */
+
+enum
+{
+ EDGE_LIGHT,
+ EDGE_HIGHLIGHT,
+ EDGE_SHADOW,
+ EDGE_DARKSHADOW,
+ EDGE_FILL,
+
+ EDGE_WINDOW,
+ EDGE_WINDOWFRAME,
+
+ EDGE_NUMCOLORS
+};
+
+static const struct
+{
+ int themeProp;
+ int sysColor;
+} EdgeColorMap[EDGE_NUMCOLORS] = {
+ {TMT_EDGELIGHTCOLOR, COLOR_3DLIGHT},
+ {TMT_EDGEHIGHLIGHTCOLOR, COLOR_BTNHIGHLIGHT},
+ {TMT_EDGESHADOWCOLOR, COLOR_BTNSHADOW},
+ {TMT_EDGEDKSHADOWCOLOR, COLOR_3DDKSHADOW},
+ {TMT_EDGEFILLCOLOR, COLOR_BTNFACE},
+ {-1, COLOR_WINDOW},
+ {-1, COLOR_WINDOWFRAME}
+};
+
+static const signed char LTInnerNormal[] = {
+ -1, -1, -1, -1,
+ -1, EDGE_HIGHLIGHT, EDGE_HIGHLIGHT, -1,
+ -1, EDGE_DARKSHADOW, EDGE_DARKSHADOW, -1,
+ -1, -1, -1, -1
+};
+
+static const signed char LTOuterNormal[] = {
+ -1, EDGE_LIGHT, EDGE_SHADOW, -1,
+ EDGE_HIGHLIGHT, EDGE_LIGHT, EDGE_SHADOW, -1,
+ EDGE_DARKSHADOW, EDGE_LIGHT, EDGE_SHADOW, -1,
+ -1, EDGE_LIGHT, EDGE_SHADOW, -1
+};
+
+static const signed char RBInnerNormal[] = {
+ -1, -1, -1, -1,
+ -1, EDGE_SHADOW, EDGE_SHADOW, -1,
+ -1, EDGE_LIGHT, EDGE_LIGHT, -1,
+ -1, -1, -1, -1
+};
+
+static const signed char RBOuterNormal[] = {
+ -1, EDGE_DARKSHADOW, EDGE_HIGHLIGHT, -1,
+ EDGE_SHADOW, EDGE_DARKSHADOW, EDGE_HIGHLIGHT, -1,
+ EDGE_LIGHT, EDGE_DARKSHADOW, EDGE_HIGHLIGHT, -1,
+ -1, EDGE_DARKSHADOW, EDGE_HIGHLIGHT, -1
+};
+
+static const signed char LTInnerSoft[] = {
+ -1, -1, -1, -1,
+ -1, EDGE_LIGHT, EDGE_LIGHT, -1,
+ -1, EDGE_SHADOW, EDGE_SHADOW, -1,
+ -1, -1, -1, -1
+};
+
+static const signed char LTOuterSoft[] = {
+ -1, EDGE_HIGHLIGHT, EDGE_DARKSHADOW, -1,
+ EDGE_LIGHT, EDGE_HIGHLIGHT, EDGE_DARKSHADOW, -1,
+ EDGE_SHADOW, EDGE_HIGHLIGHT, EDGE_DARKSHADOW, -1,
+ -1, EDGE_HIGHLIGHT, EDGE_DARKSHADOW, -1
+};
+
+#define RBInnerSoft RBInnerNormal /* These are the same */
+#define RBOuterSoft RBOuterNormal
+
+static const signed char LTRBOuterMono[] = {
+ -1, EDGE_WINDOWFRAME, EDGE_WINDOWFRAME, EDGE_WINDOWFRAME,
+ EDGE_WINDOW, EDGE_WINDOWFRAME, EDGE_WINDOWFRAME, EDGE_WINDOWFRAME,
+ EDGE_WINDOW, EDGE_WINDOWFRAME, EDGE_WINDOWFRAME, EDGE_WINDOWFRAME,
+ EDGE_WINDOW, EDGE_WINDOWFRAME, EDGE_WINDOWFRAME, EDGE_WINDOWFRAME,
+};
+
+static const signed char LTRBInnerMono[] = {
+ -1, -1, -1, -1,
+ -1, EDGE_WINDOW, EDGE_WINDOW, EDGE_WINDOW,
+ -1, EDGE_WINDOW, EDGE_WINDOW, EDGE_WINDOW,
+ -1, EDGE_WINDOW, EDGE_WINDOW, EDGE_WINDOW,
+};
+
+static const signed char LTRBOuterFlat[] = {
+ -1, EDGE_SHADOW, EDGE_SHADOW, EDGE_SHADOW,
+ EDGE_FILL, EDGE_SHADOW, EDGE_SHADOW, EDGE_SHADOW,
+ EDGE_FILL, EDGE_SHADOW, EDGE_SHADOW, EDGE_SHADOW,
+ EDGE_FILL, EDGE_SHADOW, EDGE_SHADOW, EDGE_SHADOW,
+};
+
+static const signed char LTRBInnerFlat[] = {
+ -1, -1, -1, -1,
+ -1, EDGE_FILL, EDGE_FILL, EDGE_FILL,
+ -1, EDGE_FILL, EDGE_FILL, EDGE_FILL,
+ -1, EDGE_FILL, EDGE_FILL, EDGE_FILL,
+};
+
+static COLORREF get_edge_color (int edgeType, HTHEME theme, int part,
int state)
+{
+ COLORREF col;
+ if ((EdgeColorMap[edgeType].themeProp == -1)
+ || FAILED (GetThemeColor (theme, part, state,
+ EdgeColorMap[edgeType].themeProp, &col)))
+ col = GetSysColor (EdgeColorMap[edgeType].sysColor);
+ return col;
+}
+
+static inline HPEN get_edge_pen (int edgeType, HTHEME theme, int part,
int state)
+{
+ return CreatePen (PS_SOLID, 1, get_edge_color (edgeType, theme,
part, state));
+}
+
+static inline HBRUSH get_edge_brush (int edgeType, HTHEME theme, int
part, int state)
+{
+ return CreateSolidBrush (get_edge_color (edgeType, theme, part,
state));
+}
+
/***********************************************************************
+ * draw_diag_edge
+ *
+ * Same as DrawEdge invoked with BF_DIAGONAL
+ */
+static HRESULT draw_diag_edge (HDC hdc, HTHEME theme, int part, int
state,
+ const RECT* rc, UINT uType,
+ UINT uFlags, LPRECT contentsRect)
+{
+ POINT Points[4];
+ signed char InnerI, OuterI;
+ HPEN InnerPen, OuterPen;
+ POINT SavePoint;
+ HPEN SavePen;
+ int spx, spy;
+ int epx, epy;
+ int Width = rc->right - rc->left;
+ int Height= rc->bottom - rc->top;
+ int SmallDiam = Width > Height ? Height : Width;
+ HRESULT retval = (((uType & BDR_INNER) == BDR_INNER
+ || (uType & BDR_OUTER) == BDR_OUTER)
+ && !(uFlags & (BF_FLAT|BF_MONO)) ) ? E_FAIL :
S_OK;
+ int add = (LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 :
0)
+ + (LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 :
0);
+
+ /* Init some vars */
+ OuterPen = InnerPen = (HPEN)GetStockObject(NULL_PEN);
+ SavePen = (HPEN)SelectObject(hdc, InnerPen);
+ spx = spy = epx = epy = 0; /* Satisfy the compiler... */
+
+ /* Determine the colors of the edges */
+ if(uFlags & BF_MONO)
+ {
+ InnerI = LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)];
+ OuterI = LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)];
+ }
+ else if(uFlags & BF_FLAT)
+ {
+ InnerI = LTRBInnerFlat[uType & (BDR_INNER|BDR_OUTER)];
+ OuterI = LTRBOuterFlat[uType & (BDR_INNER|BDR_OUTER)];
+ }
+ else if(uFlags & BF_SOFT)
+ {
+ if(uFlags & BF_BOTTOM)
+ {
+ InnerI = RBInnerSoft[uType & (BDR_INNER|BDR_OUTER)];
+ OuterI = RBOuterSoft[uType & (BDR_INNER|BDR_OUTER)];
+ }
+ else
+ {
+ InnerI = LTInnerSoft[uType & (BDR_INNER|BDR_OUTER)];
+ OuterI = LTOuterSoft[uType & (BDR_INNER|BDR_OUTER)];
+ }
+ }
+ else
+ {
+ if(uFlags & BF_BOTTOM)
+ {
+ InnerI = RBInnerNormal[uType & (BDR_INNER|BDR_OUTER)];
+ OuterI = RBOuterNormal[uType & (BDR_INNER|BDR_OUTER)];
+ }
+ else
+ {
+ InnerI = LTInnerNormal[uType & (BDR_INNER|BDR_OUTER)];
+ OuterI = LTOuterNormal[uType & (BDR_INNER|BDR_OUTER)];
+ }
+ }
+
+ if(InnerI != -1) InnerPen = get_edge_pen (InnerI, theme, part,
state);
+ if(OuterI != -1) OuterPen = get_edge_pen (OuterI, theme, part,
state);
+
+ MoveToEx(hdc, 0, 0, &SavePoint);
+
+ /* Don't ask me why, but this is what is visible... */
+ /* This must be possible to do much simpler, but I fail to */
+ /* see the logic in the MS implementation (sigh...). */
+ /* So, this might look a bit brute force here (and it is), but */
+ /* it gets the job done;) */
+
+ switch(uFlags & BF_RECT)
+ {
+ case 0:
+ case BF_LEFT:
+ case BF_BOTTOM:
+ case BF_BOTTOMLEFT:
+ /* Left bottom endpoint */
+ epx = rc->left-1;
+ spx = epx + SmallDiam;
+ epy = rc->bottom;
+ spy = epy - SmallDiam;
+ break;
+
+ case BF_TOPLEFT:
+ case BF_BOTTOMRIGHT:
+ /* Left top endpoint */
+ epx = rc->left-1;
+ spx = epx + SmallDiam;
+ epy = rc->top-1;
+ spy = epy + SmallDiam;
+ break;
+
+ case BF_TOP:
+ case BF_RIGHT:
+ case BF_TOPRIGHT:
+ case BF_RIGHT|BF_LEFT:
+ case BF_RIGHT|BF_LEFT|BF_TOP:
+ case BF_BOTTOM|BF_TOP:
+ case BF_BOTTOM|BF_TOP|BF_LEFT:
+ case BF_BOTTOMRIGHT|BF_LEFT:
+ case BF_BOTTOMRIGHT|BF_TOP:
+ case BF_RECT:
+ /* Right top endpoint */
+ spx = rc->left;
+ epx = spx + SmallDiam;
+ spy = rc->bottom-1;
+ epy = spy - SmallDiam;
+ break;
+ }
+
+ MoveToEx(hdc, spx, spy, NULL);
+ SelectObject(hdc, OuterPen);
+ LineTo(hdc, epx, epy);
+
+ SelectObject(hdc, InnerPen);
+
+ switch(uFlags & (BF_RECT|BF_DIAGONAL))
+ {
+ case BF_DIAGONAL_ENDBOTTOMLEFT:
+ case (BF_DIAGONAL|BF_BOTTOM):
+ case BF_DIAGONAL:
+ case (BF_DIAGONAL|BF_LEFT):
+ MoveToEx(hdc, spx-1, spy, NULL);
+ LineTo(hdc, epx, epy-1);
+ Points[0].x = spx-add;
+ Points[0].y = spy;
+ Points[1].x = rc->left;
+ Points[1].y = rc->top;
+ Points[2].x = epx+1;
+ Points[2].y = epy-1-add;
+ Points[3] = Points[2];
+ break;
+
+ case BF_DIAGONAL_ENDBOTTOMRIGHT:
+ MoveToEx(hdc, spx-1, spy, NULL);
+ LineTo(hdc, epx, epy+1);
+ Points[0].x = spx-add;
+ Points[0].y = spy;
+ Points[1].x = rc->left;
+ Points[1].y = rc->bottom-1;
+ Points[2].x = epx+1;
+ Points[2].y = epy+1+add;
+ Points[3] = Points[2];
+ break;
+
+ case (BF_DIAGONAL|BF_BOTTOM|BF_RIGHT|BF_TOP):
[truncated at 1000 lines; 1215 more skipped]