diff --git a/reactos/include/defines.h b/reactos/include/defines.h index 8605c3caf49..cf101cf70a1 100644 --- a/reactos/include/defines.h +++ b/reactos/include/defines.h @@ -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) diff --git a/reactos/lib/user32/include/window.h b/reactos/lib/user32/include/window.h index 31145e6737a..66d657c14e5 100644 --- a/reactos/lib/user32/include/window.h +++ b/reactos/lib/user32/include/window.h @@ -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 diff --git a/reactos/lib/user32/resources/obm_close.bmp b/reactos/lib/user32/resources/obm_close.bmp index 58a0a34a2d8..b7c7fe7ea8e 100644 Binary files a/reactos/lib/user32/resources/obm_close.bmp and b/reactos/lib/user32/resources/obm_close.bmp differ diff --git a/reactos/lib/user32/windows/defwnd.c b/reactos/lib/user32/windows/defwnd.c index 3f33ac51444..7bc9ac20cef 100644 --- a/reactos/lib/user32/windows/defwnd.c +++ b/reactos/lib/user32/windows/defwnd.c @@ -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, diff --git a/reactos/lib/user32/windows/draw.c b/reactos/lib/user32/windows/draw.c index 3e4e420cb94..d4393dba244 100644 --- a/reactos/lib/user32/windows/draw.c +++ b/reactos/lib/user32/windows/draw.c @@ -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 #include +#include #define NDEBUG #include @@ -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); } diff --git a/reactos/subsys/win32k/ntuser/metric.c b/reactos/subsys/win32k/ntuser/metric.c index 1a7490fbee6..e6a5b08b1d4 100644 --- a/reactos/subsys/win32k/ntuser/metric.c +++ b/reactos/subsys/win32k/ntuser/metric.c @@ -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: