📄 draw.c
字号:
{
if (unicode)
success = TextOutW(MemDC, 0, 0, (WCHAR*) lpData, nCount);
else
success = TextOutA(MemDC, 0, 0, (CHAR*) lpData, nCount);
if (! success) goto cleanup;
PatBlt(MemDC, 0, 0, nWidth, nHeight, PATCOPY);
// This is how WINE does it: (but we should have our own graying brush already)
// hbsave = (HBRUSH)SelectObject(memdc, CACHE_GetPattern55AABrush());
// PatBlt(memdc, 0, 0, cx, cy, 0x000A0329);
// SelectObject(memdc, hbsave);
}
if (! BitBlt(hDC, X, Y, nWidth, nHeight, MemDC, 0, 0, SRCCOPY)) goto cleanup;
cleanup :
SetTextColor(hDC, ForeColor);
SetBkColor(hDC, BackColor);
if (MemDC)
{
if (OldFont) SelectObject(MemDC, OldFont);
if (OldBrush) SelectObject(MemDC, OldBrush);
if (OldBMP) SelectObject(MemDC, OldBMP);
if (MemBMP) DeleteObject(MemBMP);
DeleteDC(MemDC);
}
return success;
}
/**********************************************************************
* PAINTING_DrawStateJam
*
* Jams in the requested type in the dc
*/
static BOOL PAINTING_DrawStateJam(HDC hdc, UINT opcode,
DRAWSTATEPROC func, LPARAM lp, WPARAM wp,
LPRECT rc, UINT dtflags, BOOL unicode )
{
HDC memdc;
HBITMAP hbmsave;
BOOL retval;
INT cx = rc->right - rc->left;
INT cy = rc->bottom - rc->top;
switch(opcode)
{
case DST_TEXT:
case DST_PREFIXTEXT:
if(unicode)
return DrawTextW(hdc, (LPWSTR)lp, (INT)wp, rc, dtflags);
else
return DrawTextA(hdc, (LPSTR)lp, (INT)wp, rc, dtflags);
case DST_ICON:
return DrawIconEx(hdc, rc->left, rc->top, (HICON)lp, cx, cy, 0, NULL, DI_NORMAL);
case DST_BITMAP:
memdc = CreateCompatibleDC(hdc);
if(!memdc) return FALSE;
hbmsave = (HBITMAP)SelectObject(memdc, (HBITMAP)lp);
if(!hbmsave)
{
DeleteDC(memdc);
return FALSE;
}
retval = BitBlt(hdc, rc->left, rc->top, cx, cy, memdc, 0, 0, SRCCOPY);
SelectObject(memdc, hbmsave);
DeleteDC(memdc);
return retval;
case DST_COMPLEX:
if(func) {
BOOL bRet;
/* DRAWSTATEPROC assumes that it draws at the center of coordinates */
OffsetViewportOrgEx(hdc, rc->left, rc->top, NULL);
bRet = func(hdc, lp, wp, cx, cy);
/* Restore origin */
OffsetViewportOrgEx(hdc, -rc->left, -rc->top, NULL);
return bRet;
} else
return FALSE;
}
return FALSE;
}
static BOOL
IntDrawState(HDC hdc, HBRUSH hbr, DRAWSTATEPROC func, LPARAM lp, WPARAM wp,
INT x, INT y, INT cx, INT cy, UINT flags, BOOL unicode)
{
HBITMAP hbm, hbmsave;
HFONT hfsave;
HBRUSH hbsave, hbrtmp = 0;
HDC memdc;
RECT rc;
UINT dtflags = DT_NOCLIP;
COLORREF fg, bg;
UINT opcode = flags & 0xf;
INT len = wp;
BOOL retval, tmp;
if((opcode == DST_TEXT || opcode == DST_PREFIXTEXT) && !len) /* The string is '\0' terminated */
{
if(unicode)
len = lstrlenW((LPWSTR)lp);
else
len = lstrlenA((LPSTR)lp);
}
/* Find out what size the image has if not given by caller */
if(!cx || !cy)
{
SIZE s;
ICONINFO ici;
BITMAP bm;
switch(opcode)
{
case DST_TEXT:
case DST_PREFIXTEXT:
if(unicode)
retval = GetTextExtentPoint32W(hdc, (LPWSTR)lp, len, &s);
else
retval = GetTextExtentPoint32A(hdc, (LPSTR)lp, len, &s);
if(!retval) return FALSE;
break;
case DST_ICON:
if(!GetIconInfo((HICON)lp, &ici))
return FALSE;
if(!GetObjectW(ici.hbmColor, sizeof(bm), &bm))
return FALSE;
s.cx = bm.bmWidth;
s.cy = bm.bmHeight;
break;
case DST_BITMAP:
if(!GetObjectW((HBITMAP)lp, sizeof(bm), &bm))
return FALSE;
s.cx = bm.bmWidth;
s.cy = bm.bmHeight;
break;
case DST_COMPLEX: /* cx and cy must be set in this mode */
return FALSE;
}
if(!cx) cx = s.cx;
if(!cy) cy = s.cy;
}
rc.left = x;
rc.top = y;
rc.right = x + cx;
rc.bottom = y + cy;
if(flags & DSS_RIGHT) /* This one is not documented in the win32.hlp file */
dtflags |= DT_RIGHT;
if(opcode == DST_TEXT)
dtflags |= DT_NOPREFIX;
/* For DSS_NORMAL we just jam in the image and return */
if((flags & 0x7ff0) == DSS_NORMAL)
{
return PAINTING_DrawStateJam(hdc, opcode, func, lp, len, &rc, dtflags, unicode);
}
/* For all other states we need to convert the image to B/W in a local bitmap */
/* before it is displayed */
fg = SetTextColor(hdc, RGB(0, 0, 0));
bg = SetBkColor(hdc, RGB(255, 255, 255));
hbm = NULL; hbmsave = NULL;
memdc = NULL; hbsave = NULL;
retval = FALSE; /* assume failure */
/* From here on we must use "goto cleanup" when something goes wrong */
hbm = CreateBitmap(cx, cy, 1, 1, NULL);
if(!hbm) goto cleanup;
memdc = CreateCompatibleDC(hdc);
if(!memdc) goto cleanup;
hbmsave = (HBITMAP)SelectObject(memdc, hbm);
if(!hbmsave) goto cleanup;
rc.left = rc.top = 0;
rc.right = cx;
rc.bottom = cy;
if(!FillRect(memdc, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH))) goto cleanup;
SetBkColor(memdc, RGB(255, 255, 255));
SetTextColor(memdc, RGB(0, 0, 0));
hfsave = (HFONT)SelectObject(memdc, GetCurrentObject(hdc, OBJ_FONT));
/* DST_COMPLEX may draw text as well,
* so we must be sure that correct font is selected
*/
if(!hfsave && (opcode <= DST_PREFIXTEXT)) goto cleanup;
tmp = PAINTING_DrawStateJam(memdc, opcode, func, lp, len, &rc, dtflags, unicode);
if(hfsave) SelectObject(memdc, hfsave);
if(!tmp) goto cleanup;
/* This state cause the image to be dithered */
if(flags & DSS_UNION)
{
#if 0
hbsave = (HBRUSH)SelectObject(memdc, CACHE_GetPattern55AABrush());
if(!hbsave) goto cleanup;
tmp = PatBlt(memdc, 0, 0, cx, cy, 0x00FA0089);
SelectObject(memdc, hbsave);
if(!tmp) goto cleanup;
#else
UNIMPLEMENTED;
#endif
}
if (flags & DSS_DISABLED)
hbrtmp = CreateSolidBrush(GetSysColor(COLOR_3DHILIGHT));
else if (flags & DSS_DEFAULT)
hbrtmp = CreateSolidBrush(GetSysColor(COLOR_3DSHADOW));
/* Draw light or dark shadow */
if (flags & (DSS_DISABLED|DSS_DEFAULT))
{
if(!hbrtmp) goto cleanup;
hbsave = (HBRUSH)SelectObject(hdc, hbrtmp);
if(!hbsave) goto cleanup;
if(!BitBlt(hdc, x+1, y+1, cx, cy, memdc, 0, 0, 0x00B8074A)) goto cleanup;
SelectObject(hdc, hbsave);
DeleteObject(hbrtmp);
hbrtmp = 0;
}
if (flags & DSS_DISABLED)
{
hbr = hbrtmp = CreateSolidBrush(GetSysColor(COLOR_3DSHADOW));
if(!hbrtmp) goto cleanup;
}
else if (!hbr)
{
hbr = (HBRUSH)GetStockObject(BLACK_BRUSH);
}
hbsave = (HBRUSH)SelectObject(hdc, hbr);
if(!BitBlt(hdc, x, y, cx, cy, memdc, 0, 0, 0x00B8074A)) goto cleanup;
retval = TRUE; /* We succeeded */
cleanup:
SetTextColor(hdc, fg);
SetBkColor(hdc, bg);
if(hbsave) SelectObject(hdc, hbsave);
if(hbmsave) SelectObject(memdc, hbmsave);
if(hbrtmp) DeleteObject(hbrtmp);
if(hbm) DeleteObject(hbm);
if(memdc) DeleteDC(memdc);
return retval;
}
/*
* @implemented
*/
BOOL STDCALL
DrawFrameControl(HDC hDC, LPRECT rc, UINT uType, UINT uState)
{
if (GetMapMode(hDC) != MM_TEXT)
return FALSE;
switch(uType)
{
case DFC_BUTTON:
return UITOOLS95_DrawFrameButton(hDC, rc, uState);
case DFC_CAPTION:
return UITOOLS95_DrawFrameCaption(hDC, rc, uState);
case DFC_MENU:
return UITOOLS95_DrawFrameMenu(hDC, rc, uState);
#if 0
case DFC_POPUPMENU:
UNIMPLEMENTED;
break;
#endif
case DFC_SCROLL:
return UITOOLS95_DrawFrameScroll(hDC, rc, uState);
}
return FALSE;
}
/*
* @implemented
*/
BOOL STDCALL
DrawEdge(HDC hDC, LPRECT rc, UINT edge, UINT flags)
{
if (flags & BF_DIAGONAL)
return IntDrawDiagEdge(hDC, rc, edge, flags);
else
return IntDrawRectEdge(hDC, rc, edge, flags);
}
/*
* @implemented
*/
BOOL STDCALL
GrayStringA(HDC hDC, HBRUSH hBrush, GRAYSTRINGPROC lpOutputFunc, LPARAM lpData,
int nCount, int X, int Y, int nWidth, int nHeight)
{
return IntGrayString(hDC, hBrush, lpOutputFunc, lpData, nCount, X, Y, nWidth, nHeight, FALSE);
}
/*
* @implemented
*/
BOOL STDCALL
GrayStringW(HDC hDC, HBRUSH hBrush, GRAYSTRINGPROC lpOutputFunc, LPARAM lpData,
int nCount, int X, int Y, int nWidth, int nHeight)
{
return IntGrayString(hDC, hBrush, lpOutputFunc, lpData, nCount, X, Y, nWidth, nHeight, TRUE);
}
/*
* @implemented
*/
BOOL STDCALL
InvertRect(HDC hDC, CONST RECT *lprc)
{
return PatBlt(hDC, lprc->left, lprc->top, lprc->right - lprc->left,
lprc->bottom - lprc->top, DSTINVERT);
}
/*
* @implemented
*/
INT STDCALL
FrameRect(HDC hDC, CONST RECT *lprc, HBRUSH hbr)
{
HBRUSH oldbrush;
RECT r = *lprc;
if ((r.right <= r.left) || (r.bottom <= r.top)) return 0;
if (!(oldbrush = SelectObject(hDC, hbr))) return 0;
PatBlt(hDC, r.left, r.top, 1, r.bottom - r.top, PATCOPY);
PatBlt(hDC, r.right - 1, r.top, 1, r.bottom - r.top, PATCOPY);
PatBlt(hDC, r.left, r.top, r.right - r.left, 1, PATCOPY);
PatBlt(hDC, r.left, r.bottom - 1, r.right - r.left, 1, PATCOPY);
SelectObject(hDC, oldbrush);
return TRUE;
}
/*
* @unimplemented
*/
BOOL STDCALL
FlashWindow(HWND hWnd, BOOL bInvert)
{
UNIMPLEMENTED;
return FALSE;
}
/*
* @unimplemented
*/
BOOL STDCALL
FlashWindowEx(PFLASHWINFO pfwi)
{
UNIMPLEMENTED;
return FALSE;
}
/*
* @implemented
*/
INT STDCALL
FillRect(HDC hDC, CONST RECT *lprc, HBRUSH hbr)
{
HBRUSH prevhbr;
if (hbr <= (HBRUSH)(COLOR_MENUBAR + 1))
{
hbr = GetSysColorBrush((int)hbr - 1);
}
if ((prevhbr = NtGdiSelectObject(hDC, hbr)) == NULL)
{
return FALSE;
}
NtGdiPatBlt(hDC, lprc->left, lprc->top, lprc->right - lprc->left,
lprc->bottom - lprc->top, PATCOPY);
NtGdiSelectObject(hDC, prevhbr);
return TRUE;
}
/*
* @unimplemented
*/
BOOL STDCALL
DrawAnimatedRects(HWND hWnd, int idAni, CONST RECT *lprcFrom,
CONST RECT *lprcTo)
{
UNIMPLEMENTED;
return FALSE;
}
/*
* @implemented
*/
BOOL STDCALL
DrawFocusRect(HDC hdc, CONST RECT *rect)
{
static HBRUSH hFocusRectBrush = NULL;
HGDIOBJ OldObj;
UINT cx, cy;
if(!hFocusRectBrush)
{
static HBITMAP hFocusPattern = NULL;
const DWORD Pattern[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA};
hFocusPattern = CreateBitmap(8, 8, 1, 1, Pattern);
hFocusRectBrush = CreatePatternBrush(hFocusPattern);
}
NtUserSystemParametersInfo(SPI_GETFOCUSBORDERWIDTH, 0, &cx, 0);
NtUserSystemParametersInfo(SPI_GETFOCUSBORDERHEIGHT, 0, &cy, 0);
OldObj = SelectObject(hdc, hFocusRectBrush);
/* top */
PatBlt(hdc, rect->left, rect->top, rect->right - rect->left, cy, PATINVERT);
/* bottom */
PatBlt(hdc, rect->left, rect->bottom - cy, rect->right - rect->left, cy, PATINVERT);
/* left */
PatBlt(hdc, rect->left, rect->top + cy, cx, rect->bottom - rect->top - (2 * cy), PATINVERT);
/* right */
PatBlt(hdc, rect->right - cx, rect->top + cy, cx, rect->bottom - rect->top - (2 * cy), PATINVERT);
SelectObject(hdc, OldObj);
return TRUE;
}
/*
* @implemented
*/
BOOL STDCALL
DrawStateA(HDC hDC, HBRUSH hBrush, DRAWSTATEPROC lpOutputFunc, LPARAM lData,
WPARAM wData, int x, int y, int cx, int cy, UINT fuFlags)
{
return IntDrawState(hDC, hBrush, lpOutputFunc, lData, wData, x, y, cx, cy, fuFlags, FALSE);
}
/*
* @implemented
*/
BOOL STDCALL
DrawStateW(HDC hDC, HBRUSH hBrush, DRAWSTATEPROC lpOutputFunc, LPARAM lData,
WPARAM wData, int x, int y, int cx, int cy, UINT fuFlags)
{
return IntDrawState(hDC, hBrush, lpOutputFunc, lData, wData, x, y, cx, cy, fuFlags, TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -