DrawCaption() now works, and is called (unsurprisingly) for drawing the captions of windows!

* Implemented DrawCaption() in lib/user32/windows/defwnd.c (couldn't put it in draw.c due to the functions it relies upon being in defwnd.c)
* Changed a few metrics in subsys/win32k/ntuser/metric.c to match the Windows defaults
* Added DC_GRADIENT and DC_BUTTONS to include/defines.h
* Modified prototype for UserDrawSysMenuButton in lib/user32/include/window.h to return success/failure
* Modified lib/usr32/resources/obm_close.bmp slightly. It now looks more like the Windows version.

svn path=/trunk/; revision=5688
This commit is contained in:
Andrew Greenwood 2003-08-20 00:41:04 +00:00
parent 778113754c
commit 8eb1d07658
6 changed files with 207 additions and 77 deletions

View file

@ -850,8 +850,15 @@ extern "C" {
#define IDANI_CLOSE (2)
/* DrawCaption */
#define DC_ACTIVE (1)
#define DC_SMALLCAP (2)
#define DC_ACTIVE 1
#define DC_SMALLCAP 2
#define DC_ICON 4
#define DC_TEXT 8
#define DC_INBUTTON 16
#define DC_GRADIENT 32
#define DC_BUTTONS 64
#define DC_CAPTION (DC_ICON|DC_TEXT|DC_BUTTONS|DC_GRADIENT)
#define DC_NC (DC_CAPTION|DC_FRAME)
/* DrawEdge */
#define BDR_OUTER (3)

View file

@ -12,7 +12,7 @@
VOID
UserSetupInternalPos(VOID);
VOID UserDrawSysMenuButton( HWND hWnd, HDC hDC, BOOL down );
BOOL UserDrawSysMenuButton( HWND hWnd, HDC hDC, LPRECT, BOOL down );
PINTERNALPOS
UserGetInternalPos(HWND hWnd);
ULONG

Binary file not shown.

Before

Width:  |  Height:  |  Size: 246 B

After

Width:  |  Height:  |  Size: 246 B

View file

@ -1,4 +1,4 @@
/* $Id: defwnd.c,v 1.69 2003/08/16 20:16:50 gvg Exp $
/* $Id: defwnd.c,v 1.70 2003/08/20 00:41:04 silverblade Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS user32.dll
@ -39,7 +39,9 @@ static HBITMAP hbScrDwn;
static HBITMAP hbScrLeft;
static HBITMAP hbScrRight;
*/
static COLORREF SysColours[] =
static COLORREF SysColours[29] =
{
RGB(224, 224, 224) /* COLOR_SCROLLBAR */,
RGB(58, 110, 165) /* COLOR_BACKGROUND */,
@ -304,24 +306,34 @@ UserGetInsideRectNC( HWND hWnd, RECT *rect )
}
}
VOID
UserDrawSysMenuButton( HWND hWnd, HDC hDC, BOOL down )
WINBOOL
UserDrawSysMenuButton( HWND hWnd, HDC hDC, LPRECT Rect, BOOL down )
{
RECT Rect;
HDC hDcMem;
HBITMAP hSavedBitmap;
HDC hDcMem;
HBITMAP hSavedBitmap;
WINBOOL result = FALSE;
hbSysMenu = (HBITMAP)LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CLOSE));
UserGetInsideRectNC(hWnd, &Rect);
hDcMem = CreateCompatibleDC(hDC);
hSavedBitmap = SelectObject(hDcMem, hbSysMenu);
BitBlt(hDC, Rect.left + 2, Rect.top +
hbSysMenu = (HBITMAP)LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CLOSE));
hDcMem = CreateCompatibleDC(hDC);
if (! hDcMem) goto cleanup;
hSavedBitmap = SelectObject(hDcMem, hbSysMenu);
if (! hSavedBitmap) goto cleanup;
BitBlt(hDC, Rect->left + 2, Rect->top +
2, 16, 16, hDcMem,
(GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD) ?
GetSystemMetrics(SM_CXSIZE): 0, 0, SRCCOPY);
SelectObject(hDcMem, hSavedBitmap);
DeleteDC(hDcMem);
}
GetSystemMetrics(SM_CXSIZE): 0, 0, SRCCOPY);
result = TRUE;
cleanup:
if (hDcMem)
{
if(hSavedBitmap) SelectObject(hDcMem, hSavedBitmap);
DeleteDC(hDcMem);
}
return result;
}
/* FIXME: Cache bitmaps, then just bitblt instead of calling DFC() (and
wasting precious CPU cycles) every time */
@ -396,6 +408,136 @@ UserDrawCaptionButton( HWND hWnd, HDC hDC, BOOL bDown, ULONG Type )
}
}
// Enabling this will cause captions to draw smoother, but slower:
// #define DOUBLE_BUFFER_CAPTION
// NOTE: Double buffering appears to be broken for this at the moment
/*
* @implemented
*/
WINBOOL
STDCALL
DrawCaption(
HWND hWnd,
HDC hDC,
LPRECT lprc,
UINT uFlags)
{
NONCLIENTMETRICSW nclm;
BOOL result = FALSE;
RECT r = *lprc;
UINT VCenter = 0, Padding = 0;
WCHAR buffer[256];
HFONT hFont = NULL,
hOldFont = NULL;
HBRUSH OldBrush = NULL;
HDC MemDC = NULL;
#ifdef DOUBLE_BUFFER_CAPTION
HBITMAP MemBMP = NULL,
OldBMP = NULL;
MemDC = CreateCompatibleDC(hDC);
if (! MemDC) goto cleanup;
MemBMP = CreateCompatibleBitmap(hDC, lprc->right - lprc->left, lprc->bottom - lprc->top);
if (! MemBMP) goto cleanup;
OldBMP = SelectObject(MemDC, MemBMP);
if (! OldBMP) goto cleanup;
#else
MemDC = hDC;
OffsetViewportOrgEx(MemDC, lprc->left, lprc->top, NULL);
#endif
// If DC_GRADIENT is specified, a Win 98/2000 style caption gradient should
// be painted. For now, that flag is ignored.
// Draw the caption background
OldBrush = SelectObject(MemDC, GetSysColorBrush(uFlags & DC_ACTIVE ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION) );
if (! OldBrush) goto cleanup;
PatBlt(MemDC, 0, 0, lprc->right - lprc->left, lprc->bottom - lprc->top, PATCOPY );
VCenter = (lprc->bottom - lprc->top) / 2;
Padding = VCenter - (GetSystemMetrics(SM_CYCAPTION) / 2);
r.left = Padding;
r.right = r.left + (lprc->right - lprc->left);
r.top = Padding;
r.bottom = r.top + (GetSystemMetrics(SM_CYCAPTION) / 2);
if (uFlags & DC_ICON)
{
// For some reason the icon isn't centered correctly...
r.top --;
UserDrawSysMenuButton(hWnd, MemDC, &r, FALSE);
r.top ++;
}
r.top ++;
r.left += 2;
if ((uFlags & DC_TEXT) && (GetWindowTextW( hWnd, buffer, sizeof(buffer)/sizeof(buffer[0]) )))
{
r.left += GetSystemMetrics(SM_CXSIZE) + Padding;
r.right = (lprc->right - lprc->left) - r.left;
nclm.cbSize = sizeof(nclm);
if (! SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, 0, &nclm, 0)) goto cleanup;
SetTextColor(MemDC, SysColours[ uFlags & DC_ACTIVE ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT]);
SetBkMode( MemDC, TRANSPARENT );
if (GetWindowLongW(hWnd, GWL_STYLE) & WS_EX_TOOLWINDOW)
hFont = CreateFontIndirectW(&nclm.lfSmCaptionFont);
else
hFont = CreateFontIndirectW(&nclm.lfCaptionFont);
if (! hFont) goto cleanup;
hOldFont = SelectObject(MemDC, hFont);
if (! hOldFont) goto cleanup;
DrawTextW(MemDC, buffer, wcslen(buffer), &r, DT_VCENTER | DT_END_ELLIPSIS);
// Old method:
// TextOutW(hDC, r.left + (GetSystemMetrics(SM_CXDLGFRAME) * 2), lprc->top + (nclm.lfCaptionFont.lfHeight / 2), buffer, wcslen(buffer));
}
if (uFlags & DC_BUTTONS)
{
// Windows XP draws the caption buttons with DC_BUTTONS
// r.left += GetSystemMetrics(SM_CXSIZE) + 1;
// UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONCLOSE);
// r.right -= GetSystemMetrics(SM_CXSMSIZE) + 1;
// UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMIN);
// UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMAX);
}
#ifdef DOUBLE_BUFFER_CAPTION
if (! BitBlt(hDC, lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top,
MemDC, 0, 0, SRCCOPY)) goto cleanup;
#endif
result = TRUE;
cleanup :
if (MemDC)
{
if (OldBrush) SelectObject(MemDC, OldBrush);
if (hOldFont) SelectObject(MemDC, hOldFont);
if (hFont) DeleteObject(hFont);
#ifdef DOUBLE_BUFFER_CAPTION
if (OldBMP) SelectObject(MemDC, OldBMP);
if (MemBMP) DeleteObject(MemBMP);
DeleteDC(MemDC);
#else
OffsetViewportOrgEx(MemDC, -lprc->left, -lprc->top, NULL);
#endif
}
return result;
}
static void
UserDrawCaptionNC (
HDC hDC,
@ -405,40 +547,33 @@ UserDrawCaptionNC (
BOOL active )
{
RECT r = *rect;
WCHAR buffer[256];
/* FIXME: Implement and Use DrawCaption() */
SelectObject( hDC, GetSysColorBrush(active ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION) );
UINT capflags = 0;
PatBlt(hDC,rect->left + GetSystemMetrics(SM_CXFRAME), rect->top +
GetSystemMetrics(SM_CYFRAME), rect->right - (GetSystemMetrics(SM_CXFRAME) * 2), (rect->top +
GetSystemMetrics(SM_CYCAPTION)) - 1, PATCOPY );
capflags = DC_ICON | DC_TEXT;
capflags += active & DC_ACTIVE;
// Old code:
// PatBlt(hDC,rect->left + GetSystemMetrics(SM_CXFRAME), rect->top +
// GetSystemMetrics(SM_CYFRAME), rect->right - (GetSystemMetrics(SM_CXFRAME) * 2), (rect->top +
// GetSystemMetrics(SM_CYCAPTION)) - 1, PATCOPY );
r.left += GetSystemMetrics(SM_CXFRAME);
r.top += GetSystemMetrics(SM_CYFRAME);
r.right -= GetSystemMetrics(SM_CXFRAME);
r.bottom = r.top + GetSystemMetrics(SM_CYCAPTION);
// GetSystemMetrics(SM_CYCAPTION)) - 1, PATCOPY );
DrawCaption(hWnd, hDC, &r, capflags);
if (style & WS_SYSMENU)
{
UserDrawSysMenuButton( hWnd, hDC, FALSE);
// UserDrawSysMenuButton( hWnd, hDC, FALSE);
r.left += GetSystemMetrics(SM_CXSIZE) + 1;
UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONCLOSE);
r.right -= GetSystemMetrics(SM_CXSMSIZE) + 1;
UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMIN);
UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMAX);
}
if (GetWindowTextW( hWnd, buffer, sizeof(buffer)/sizeof(buffer[0]) ))
{
NONCLIENTMETRICSW nclm;
HFONT hFont, hOldFont;
nclm.cbSize = sizeof(nclm);
SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
SetTextColor(hDC, SysColours[ active ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT]);
SetBkMode( hDC, TRANSPARENT );
if (style & WS_EX_TOOLWINDOW)
hFont = CreateFontIndirectW(&nclm.lfSmCaptionFont);
else
hFont = CreateFontIndirectW(&nclm.lfCaptionFont);
hOldFont = SelectObject(hDC, hFont);
TextOutW(hDC, r.left + (GetSystemMetrics(SM_CXDLGFRAME) * 2), rect->top + (nclm.lfCaptionFont.lfHeight / 2), buffer, wcslen(buffer));
DeleteObject (SelectObject (hDC, hOldFont));
}
}
@ -736,7 +871,7 @@ DefWndHandleLButtonDownNC(HWND hWnd, WPARAM wParam, LPARAM lParam)
if (!(GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE))
{
HDC hDC = GetWindowDC(hWnd);
UserDrawSysMenuButton(hWnd, hDC, TRUE);
// UserDrawSysMenuButton(hWnd, hDC, TRUE);
ReleaseDC(hWnd, hDC);
}
SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU,

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: draw.c,v 1.24 2003/08/19 03:05:42 royce Exp $
/* $Id: draw.c,v 1.25 2003/08/20 00:41:04 silverblade Exp $
*
* PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/input.c
@ -34,6 +34,7 @@
// Needed for DrawState
#include <string.h>
#include <unicode.h>
#include <draw.h>
#define NDEBUG
#include <debug.h>
@ -1682,22 +1683,6 @@ DrawAnimatedRects(
}
/*
* @unimplemented
*/
WINBOOL
STDCALL
DrawCaption(
HWND hwnd,
HDC hdc,
LPRECT lprc,
UINT uFlags)
{
UNIMPLEMENTED;
return FALSE;
}
/*
* @unimplemented
*/
@ -1743,16 +1728,17 @@ WINBOOL INTERNAL_DrawStateDraw(HDC hdc, UINT type, DRAWSTATEPROC lpOutputFunc,
BOOL retval = FALSE;
INT cx = rc->right - rc->left;
INT cy = rc->bottom - rc->top;
if (((type == DST_TEXT) || (type == DST_PREFIXTEXT)) && (lpOutputFunc))
type = DST_COMPLEX;
// Is this supposed to happen?
// if (((type == DST_TEXT) || (type == DST_PREFIXTEXT)) && (lpOutputFunc))
// type = DST_COMPLEX;
switch(type)
{
case DST_TEXT :
case DST_PREFIXTEXT :
{
DbgPrint("DST_TEXT\n");
DbgPrint("Drawing DST_TEXT\n");
if (unicode)
return DrawTextW(hdc, (LPWSTR)lData, (INT)wData, rc, dtflags);
else
@ -1762,23 +1748,26 @@ WINBOOL INTERNAL_DrawStateDraw(HDC hdc, UINT type, DRAWSTATEPROC lpOutputFunc,
case DST_ICON :
{
// TODO
DbgPrint("Drawing DST_ICON\n");
return retval;
}
case DST_BITMAP :
{
// TODO
DbgPrint("Drawing DST_BITMAP\n");
return retval;
}
case DST_COMPLEX :
{
DbgPrint("DST_COMPLEX\n");
DbgPrint("Drawing DST_COMPLEX\n");
// Call lpOutputFunc, if necessary
if (lpOutputFunc)
{
// Something seems to be wrong with OffsetViewportOrgEx:
OffsetViewportOrgEx(hdc, rc->left, rc->top, NULL);
DbgPrint("Calling lpOutputFunc\n");
DbgPrint("Calling lpOutputFunc(0x%x, 0x%x, 0x%x, %d, %d)\n", hdc, lData, wData, cx, cy);
retval = lpOutputFunc(hdc, lData, wData, cx, cy);
OffsetViewportOrgEx(hdc, -rc->left, -rc->top, NULL);
return retval;
@ -1856,10 +1845,10 @@ WINBOOL INTERNAL_DrawState(
case DST_TEXT :
case DST_PREFIXTEXT :
{
DbgPrint("Calculating rect of DST_TEXT / DST_PREFIXTEXT\n");
BOOL success;
DbgPrint("DST_TEXT / DST_PREFIXTEXT\n");
if (unicode)
success = GetTextExtentPoint32W(hdc, (LPWSTR) lData, len, &s);
else
@ -1871,14 +1860,14 @@ WINBOOL INTERNAL_DrawState(
case DST_ICON :
{
DbgPrint("DST_ICON\n");
DbgPrint("Calculating rect of DST_ICON\n");
// TODO
break;
}
case DST_BITMAP :
{
DbgPrint("DST_BITMAP\n");
DbgPrint("Calculating rect of DST_BITMAP\n");
if (!GetObjectA((HBITMAP) lData, sizeof(bm), &bm))
return FALSE;
@ -1889,7 +1878,7 @@ WINBOOL INTERNAL_DrawState(
}
case DST_COMPLEX : // cx and cy must be set in this mode
DbgPrint("DST_COMPLEX\n");
DbgPrint("Calculating rect of DST_COMPLEX - Not allowed!\n");
return FALSE;
}
@ -1906,9 +1895,8 @@ WINBOOL INTERNAL_DrawState(
// No additional processing needed for DSS_NORMAL
if (state == DSS_NORMAL)
{
DbgPrint("DSS_NORMAL\n");
DbgPrint("DSS_NORMAL (no additional processing necessary)\n");
SetRect(&rect, x, y, x + cx, y + cy);
DbgPrint("L == %d R == %d T == %d B == %d\n", rect.left, rect.right, rect.top, rect.bottom);
return INTERNAL_DrawStateDraw(hdc, type, lpOutputFunc, lData, wData, &rect, dtflags, unicode);
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: metric.c,v 1.9 2003/08/19 11:48:49 weiden Exp $
/* $Id: metric.c,v 1.10 2003/08/20 00:41:04 silverblade Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -94,7 +94,7 @@ NtUserGetSystemMetrics(ULONG Index)
return(32);
case SM_CXICONSPACING:
case SM_CYICONSPACING:
return(75);
return(44);
case SM_CXMAXIMIZED:
return(NtUserGetSystemMetrics(SM_CXSCREEN) + 8); /* This seems to be 8
pixels greater than
@ -159,7 +159,7 @@ NtUserGetSystemMetrics(ULONG Index)
case SM_CYVSCROLL:
return(16);
case SM_CYCAPTION:
return(19);
return(18);
case SM_CYKANJIWINDOW:
return 0;
case SM_CYMENU: