📄 draw.c
字号:
* In win98 BF_FLAT rectangles have an inner border same color as the
* middle (COLOR_BTNFACE). I believe it's the same for win95 but since
* I don't know I go with Bertho and just sets it for win98 until proven
* otherwise.
* Dennis Björklund, 10 June, 99
*/
if( LTInnerI != -1 )
LTInnerI = RBInnerI = COLOR_BTNFACE;
}
else if(uFlags & BF_SOFT)
{
LTInnerI = LTInnerSoft[uType & (BDR_INNER|BDR_OUTER)];
LTOuterI = LTOuterSoft[uType & (BDR_INNER|BDR_OUTER)];
RBInnerI = RBInnerSoft[uType & (BDR_INNER|BDR_OUTER)];
RBOuterI = RBOuterSoft[uType & (BDR_INNER|BDR_OUTER)];
}
else
{
LTInnerI = LTInnerNormal[uType & (BDR_INNER|BDR_OUTER)];
LTOuterI = LTOuterNormal[uType & (BDR_INNER|BDR_OUTER)];
RBInnerI = RBInnerNormal[uType & (BDR_INNER|BDR_OUTER)];
RBOuterI = RBOuterNormal[uType & (BDR_INNER|BDR_OUTER)];
}
if((uFlags & BF_BOTTOMLEFT) == BF_BOTTOMLEFT) LBpenplus = 1;
if((uFlags & BF_TOPRIGHT) == BF_TOPRIGHT) RTpenplus = 1;
if((uFlags & BF_BOTTOMRIGHT) == BF_BOTTOMRIGHT) RBpenplus = 1;
if((uFlags & BF_TOPLEFT) == BF_TOPLEFT) LTpenplus = 1;
if(LTInnerI != -1) LTInnerPen = GetSysColorPen(LTInnerI);
if(LTOuterI != -1) LTOuterPen = GetSysColorPen(LTOuterI);
if(RBInnerI != -1) RBInnerPen = GetSysColorPen(RBInnerI);
if(RBOuterI != -1) RBOuterPen = GetSysColorPen(RBOuterI);
if((uFlags & BF_MIDDLE) && retval)
{
FillRect(hdc, &InnerRect, GetSysColorBrush(uFlags & BF_MONO ?
COLOR_WINDOW : COLOR_BTNFACE));
}
MoveToEx(hdc, 0, 0, &SavePoint);
/* Draw the outer edge */
SelectObject(hdc, LTOuterPen);
if(uFlags & BF_TOP)
{
MoveToEx(hdc, InnerRect.left, InnerRect.top, NULL);
LineTo(hdc, InnerRect.right, InnerRect.top);
}
if(uFlags & BF_LEFT)
{
MoveToEx(hdc, InnerRect.left, InnerRect.top, NULL);
LineTo(hdc, InnerRect.left, InnerRect.bottom);
}
SelectObject(hdc, RBOuterPen);
if(uFlags & BF_BOTTOM)
{
MoveToEx(hdc, InnerRect.left, InnerRect.bottom-1, NULL);
LineTo(hdc, InnerRect.right, InnerRect.bottom-1);
}
if(uFlags & BF_RIGHT)
{
MoveToEx(hdc, InnerRect.right-1, InnerRect.top, NULL);
LineTo(hdc, InnerRect.right-1, InnerRect.bottom);
}
/* Draw the inner edge */
SelectObject(hdc, LTInnerPen);
if(uFlags & BF_TOP)
{
MoveToEx(hdc, InnerRect.left+LTpenplus, InnerRect.top+1, NULL);
LineTo(hdc, InnerRect.right-RTpenplus, InnerRect.top+1);
}
if(uFlags & BF_LEFT)
{
MoveToEx(hdc, InnerRect.left+1, InnerRect.top+LTpenplus, NULL);
LineTo(hdc, InnerRect.left+1, InnerRect.bottom-LBpenplus);
}
SelectObject(hdc, RBInnerPen);
if(uFlags & BF_BOTTOM)
{
MoveToEx(hdc, InnerRect.left+LBpenplus, InnerRect.bottom-2, NULL);
LineTo(hdc, InnerRect.right-RBpenplus, InnerRect.bottom-2);
}
if(uFlags & BF_RIGHT)
{
MoveToEx(hdc, InnerRect.right-2, InnerRect.top+RTpenplus, NULL);
LineTo(hdc, InnerRect.right-2, InnerRect.bottom-RBpenplus);
}
if( ((uFlags & BF_MIDDLE) && retval) || (uFlags & BF_ADJUST) )
{
int add = (LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0)
+ (LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0);
if(uFlags & BF_LEFT) InnerRect.left += add;
if(uFlags & BF_RIGHT) InnerRect.right -= add;
if(uFlags & BF_TOP) InnerRect.top += add;
if(uFlags & BF_BOTTOM) InnerRect.bottom -= add;
if(uFlags & BF_ADJUST)
*rc = InnerRect;
}
/* Cleanup */
SelectObject(hdc, SavePen);
MoveToEx(hdc, SavePoint.x, SavePoint.y, NULL);
return retval;
}
/* Ported from WINE20020904 */
/* Utility to create a square rectangle and returning the width */
static int UITOOLS_MakeSquareRect(LPRECT src, LPRECT dst)
{
int Width = src->right - src->left;
int Height = src->bottom - src->top;
int SmallDiam = Width > Height ? Height : Width;
*dst = *src;
/* Make it a square box */
if(Width < Height) /* SmallDiam == Width */
{
dst->top += (Height-Width)/2;
dst->bottom = dst->top + SmallDiam;
}
else if(Width > Height) /* SmallDiam == Height */
{
dst->left += (Width-Height)/2;
dst->right = dst->left + SmallDiam;
}
return SmallDiam;
}
/* Ported from WINE20020904 */
static void UITOOLS_DrawCheckedRect( HDC dc, LPRECT rect )
{
if(GetSysColor(COLOR_BTNHIGHLIGHT) == RGB(255, 255, 255))
{
HBITMAP hbm = CreateBitmap(8, 8, 1, 1, wPattern_AA55);
HBRUSH hbsave;
HBRUSH hb = CreatePatternBrush(hbm);
COLORREF bg;
FillRect(dc, rect, GetSysColorBrush(COLOR_BTNFACE));
bg = SetBkColor(dc, RGB(255, 255, 255));
hbsave = (HBRUSH)SelectObject(dc, hb);
PatBlt(dc, rect->left, rect->top, rect->right-rect->left, rect->bottom-rect->top, 0x00FA0089);
SelectObject(dc, hbsave);
SetBkColor(dc, bg);
DeleteObject(hb);
DeleteObject(hbm);
}
else
{
FillRect(dc, rect, GetSysColorBrush(COLOR_BTNHIGHLIGHT));
}
}
/* Ported from WINE20020904 */
/* Draw a push button coming from DrawFrameControl()
*
* Does a pretty good job in emulating MS behavior. Some quirks are
* however there because MS uses a TrueType font (Marlett) to draw
* the buttons.
*/
static BOOL UITOOLS95_DFC_ButtonPush(HDC dc, LPRECT r, UINT uFlags)
{
UINT edge;
RECT myr = *r;
if(uFlags & (DFCS_PUSHED | DFCS_CHECKED | DFCS_FLAT))
edge = EDGE_SUNKEN;
else
edge = EDGE_RAISED;
if(uFlags & DFCS_CHECKED)
{
if(uFlags & DFCS_MONO)
IntDrawRectEdge(dc, &myr, edge, BF_MONO|BF_RECT|BF_ADJUST);
else
IntDrawRectEdge(dc, &myr, edge, (uFlags&DFCS_FLAT)|BF_RECT|BF_SOFT|BF_ADJUST);
UITOOLS_DrawCheckedRect( dc, &myr );
}
else
{
if(uFlags & DFCS_MONO)
{
IntDrawRectEdge(dc, &myr, edge, BF_MONO|BF_RECT|BF_ADJUST);
FillRect(dc, &myr, GetSysColorBrush(COLOR_BTNFACE));
}
else
{
IntDrawRectEdge(dc, r, edge, (uFlags&DFCS_FLAT) | BF_MIDDLE | BF_RECT | BF_SOFT);
}
}
/* Adjust rectangle if asked */
if(uFlags & DFCS_ADJUSTRECT)
{
r->left += 2;
r->right -= 2;
r->top += 2;
r->bottom -= 2;
}
return TRUE;
}
/* Ported from WINE20020904 */
/* Draw a check/3state button coming from DrawFrameControl()
*
* Does a pretty good job in emulating MS behavior. Some quirks are
* however there because MS uses a TrueType font (Marlett) to draw
* the buttons.
*/
static BOOL UITOOLS95_DFC_ButtonCheck(HDC dc, LPRECT r, UINT uFlags)
{
RECT myr, bar;
UINT flags = BF_RECT | BF_ADJUST;
UITOOLS_MakeSquareRect(r, &myr);
if(uFlags & DFCS_FLAT) flags |= BF_FLAT;
else if(uFlags & DFCS_MONO) flags |= BF_MONO;
IntDrawRectEdge( dc, &myr, EDGE_SUNKEN, flags );
if(uFlags & (DFCS_INACTIVE|DFCS_PUSHED))
FillRect(dc, &myr, GetSysColorBrush(COLOR_BTNFACE));
else if( (uFlags & DFCS_BUTTON3STATE) && (uFlags & DFCS_CHECKED) )
UITOOLS_DrawCheckedRect( dc, &myr );
else
{
FillRect(dc, &myr, GetSysColorBrush(COLOR_WINDOW));
}
if(uFlags & DFCS_CHECKED)
{
int i, k;
i = (uFlags & DFCS_INACTIVE) || (uFlags & 0xff) == DFCS_BUTTON3STATE ?
COLOR_BTNSHADOW : COLOR_WINDOWTEXT;
/* draw 7 bars, with h=3w to form the check */
bar.left = myr.left;
bar.top = myr.top + 2;
for (k = 0; k < 7; k++) {
bar.left = bar.left + 1;
bar.top = (k < 3) ? bar.top + 1 : bar.top - 1;
bar.bottom = bar.top + 3;
bar.right = bar.left + 1;
FillRect(dc, &bar, GetSysColorBrush(i));
}
}
return TRUE;
}
static BOOL UITOOLS95_DFC_ButtonRadio(HDC dc, LPRECT r, UINT uFlags)
{
RECT rc;
LOGFONT lf;
HFONT hFont, hOldFont;
int SmallDiam, i;
LPCTSTR OutRight = TEXT("j"); // Outer right
LPCTSTR OutLeft = TEXT("k"); // Outer left
LPCTSTR InRight = TEXT("l"); // inner right
LPCTSTR InLeft = TEXT("m"); // inner left
LPCTSTR Center = TEXT("n"); // center
SmallDiam = UITOOLS_MakeSquareRect(r, &rc);
ZeroMemory(&lf, sizeof(LOGFONT));
lf.lfHeight = SmallDiam;
lf.lfWidth = 0;
lf.lfWeight = FW_NORMAL;
lf.lfCharSet = DEFAULT_CHARSET;
lstrcpy(lf.lfFaceName, TEXT("Marlett"));
hFont = CreateFontIndirect(&lf);
hOldFont = SelectObject(dc, hFont);
if((uFlags & 0xff) == DFCS_BUTTONRADIOMASK)
{
SetBkMode(dc, OPAQUE);
SetTextColor(dc, GetSysColor(COLOR_WINDOWFRAME));
TextOut(dc, rc.left, rc.top, Center, 1);
SetBkMode(dc, TRANSPARENT);
SetTextColor(dc, GetSysColor(COLOR_WINDOWFRAME));
TextOut(dc, rc.left, rc.top, OutRight, 1);
SetTextColor(dc, GetSysColor(COLOR_WINDOWFRAME));
TextOut(dc, rc.left, rc.top, OutLeft, 1);
}
else
{
SetBkMode(dc, TRANSPARENT);
/* Center section, white for active, grey for inactive */
i= !(uFlags & (DFCS_INACTIVE|DFCS_PUSHED)) ? COLOR_WINDOW : COLOR_BTNFACE;
SetTextColor(dc, GetSysColor(i));
TextOut(dc, rc.left, rc.top, Center, 1);
if(uFlags & (DFCS_FLAT | DFCS_MONO))
{
SetTextColor(dc, GetSysColor(COLOR_WINDOWFRAME));
TextOut(dc, rc.left, rc.top, OutRight, 1);
TextOut(dc, rc.left, rc.top, OutLeft, 1);
TextOut(dc, rc.left, rc.top, InRight, 1);
TextOut(dc, rc.left, rc.top, InLeft, 1);
}
else
{
SetTextColor(dc, GetSysColor(COLOR_BTNSHADOW));
TextOut(dc, rc.left, rc.top, OutRight, 1);
SetTextColor(dc, GetSysColor(COLOR_BTNHIGHLIGHT));
TextOut(dc, rc.left, rc.top, OutLeft, 1);
SetTextColor(dc, GetSysColor(COLOR_3DDKSHADOW));
TextOut(dc, rc.left, rc.top, InRight, 1);
SetTextColor(dc, GetSysColor(COLOR_3DLIGHT));
TextOut(dc, rc.left, rc.top, InLeft, 1);
}
}
if(uFlags & DFCS_CHECKED)
{
LPCTSTR Check = TEXT("i");
SetTextColor(dc, GetSysColor(COLOR_WINDOWTEXT));
TextOut(dc, rc.left, rc.top, Check, 1);
}
SetTextColor(dc, GetSysColor(COLOR_WINDOWTEXT));
SelectObject(dc, hOldFont);
return TRUE;
}
/* Ported from WINE20020904 */
static BOOL UITOOLS95_DrawFrameButton(HDC hdc, LPRECT rc, UINT uState)
{
switch(uState & 0xff)
{
case DFCS_BUTTONPUSH:
return UITOOLS95_DFC_ButtonPush(hdc, rc, uState);
case DFCS_BUTTONCHECK:
case DFCS_BUTTON3STATE:
return UITOOLS95_DFC_ButtonCheck(hdc, rc, uState);
case DFCS_BUTTONRADIOIMAGE:
case DFCS_BUTTONRADIOMASK:
case DFCS_BUTTONRADIO:
return UITOOLS95_DFC_ButtonRadio(hdc, rc, uState);
/*
default:
DbgPrint("Invalid button state=0x%04x\n", uState);
*/
}
return FALSE;
}
/* Ported from WINE20020904 */
/* Draw caption buttons (win95), coming from DrawFrameControl() */
static BOOL UITOOLS95_DrawFrameCaption(HDC dc, LPRECT r, UINT uFlags)
{
POINT Line1[10];
POINT Line2[10];
int Line1N;
int Line2N;
RECT myr;
int SmallDiam = UITOOLS_MakeSquareRect(r, &myr)-2;
int i;
HBRUSH hbsave;
HPEN hpsave;
HFONT hfsave, hf;
int colorIdx = uFlags & DFCS_INACTIVE ? COLOR_BTNSHADOW : COLOR_BTNTEXT;
int xc = (myr.left+myr.right)/2;
int yc = (myr.top+myr.bottom)/2;
int edge, move;
char str[2] = "?";
UINT alignsave;
int bksave;
COLORREF clrsave;
SIZE size;
if(uFlags & DFCS_PUSHED)
IntDrawRectEdge(dc,r,EDGE_SUNKEN, BF_RECT | BF_MIDDLE | BF_SOFT);
else
IntDrawRectEdge(dc,r,BDR_RAISEDINNER | BDR_RAISEDOUTER, BF_RECT |
BF_SOFT | BF_MIDDLE);
switch(uFlags & 0xff)
{
case DFCS_CAPTIONCLOSE:
{
/* The "X" is made by drawing a series of lines.
* The number of lines drawn depends on the size
* of the bounding rect. e.g. For a 6x5 inside rect,
* two lines are drawn from top-left to bottom-right,
* and two lines from top-right to bottom-left.
*
* 0 1 2 3 4 5 0 1 2 3 4 5
* 1 * * * *
* 2 * * * *
* 3 * * * *
* 4 * * * *
*
* Drawing one line for every 6 pixels in width
* seems to provide the best proportions.
*/
POINT start, oldPos;
INT width = myr.right - (++myr.left) - 5;
INT height = (--myr.bottom) - myr.top - 6;
INT numLines = (width / 6) + 1;
hpsave = (HPEN)SelectObject(dc, GetSysColorPen(colorIdx));
start.x = myr.left + 2;
start.y = myr.top + 2;
if (width < 6)
height = width;
else
start.y++;
if (uFlags & DFCS_PUSHED)
{
start.x++;
start.y++;
}
/* now use the width of each line */
width -= numLines - 1;
for (i = 0; i < numLines; i++)
{
MoveToEx(dc, start.x + i, start.y, &oldPos);
LineTo(dc, start.x + i + width, start.y + height);
MoveToEx(dc, start.x + i, start.y + height - 1, &oldPos);
LineTo(dc, start.x + i + width, start.y - 1);
}
SelectObject(dc, hpsave);
return TRUE;
}
case DFCS_CAPTIONHELP:
/* This one breaks the flow */
/* FIXME: We need the Marlett font in order to get this right. */
hf = CreateFontA(-SmallDiam, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY, FIXED_PITCH|FF_DONTCARE, "System");
alignsave = SetTextAlign(dc, TA_TOP|TA_LEFT);
bksave = SetBkMode(dc, TRANSPARENT);
clrsave = GetTextColor(dc);
hfsave = (HFONT)SelectObject(dc, hf);
GetTextExtentPoint32A(dc, str, 1, &size);
if(uFlags & DFCS_INACTIVE)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -