Hi. This is my first attempt to implement something in win32k. Please review and point out mistakes, if any. I commited testapps to trunk. From testcode I found that our current implementation has bugs and fixed them. You can see them on screenshot: http://i1.tinypic.com/20a9te1.jpg In windows: http://i1.tinypic.com/20a9thf.jpg With my patch: http://i1.tinypic.com/20a9to2.jpg
And now I'll ask some questions :) 1) Internal functions naming. Some functions have prefix like Int*, User*, co_* etc., some don't have any prefix. Is there any standart? 2) Is there any difference between shared and exclusive lock? When should I use shared lock, and when exlusive? In ntuser.h I saw this: #define UserEnterShared() UserEnterExclusive() I guess this is temporary hack, isn't it?
Index: subsystems/win32/win32k/ntuser/painting.c =================================================================== --- subsystems/win32/win32k/ntuser/painting.c (revision 23134) +++ subsystems/win32/win32k/ntuser/painting.c (working copy) @@ -32,7 +32,7 @@
#include <w32k.h>
-#define NDEBUG +#undef NDEBUG #include <debug.h>
/* PRIVATE FUNCTIONS **********************************************************/ @@ -1372,4 +1372,392 @@ END_CLEANUP; }
+/* Don't know where to put this */ +BOOL FASTCALL IntGdiGradientFill(DC *dc, PTRIVERTEX pVertex, ULONG uVertex, PVOID pMesh, ULONG uMesh, ULONG ulMode); +ULONG FASTCALL IntSystemParametersInfo(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni); +BOOL UserDrawIconEx(HDC hDc, INT xLeft, INT yTop, PCURICON_OBJECT pIcon, INT cxWidth, + INT cyHeight, UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags); +PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon); + +BOOL +IntDrawSysMenuButton( + PWINDOW_OBJECT pWnd, + HDC hDc, + LPRECT lpRc, + BOOL Down) +{ + HICON hIcon; + PCURICON_OBJECT pIcon; + + ASSERT(pWnd && lpRc); + + /* Get the icon to draw. We don't care about WM_GETICON here. */ + + hIcon = pWnd->Class->hIconSm; + + if(!hIcon) + { + DPRINT("Wnd class has no small icon.\n"); + hIcon = pWnd->Class->hIcon; + } + + if(!hIcon) + { + DPRINT("Wnd class hasn't any icon.\n"); + //FIXME: Draw "winlogo" icon. + return FALSE; + } + + if(!(pIcon = UserGetCurIconObject(hIcon))) + { + DPRINT1("UserGetCurIconObject() failed!\n"); + return FALSE; + } + + return UserDrawIconEx(hDc, lpRc->left, lpRc->top, pIcon, + UserGetSystemMetrics(SM_CXSMICON), + UserGetSystemMetrics(SM_CYSMICON), + 0, NULL, DI_NORMAL); +} + +BOOL +IntDrawCaptionText(HDC hDc, + const PUNICODE_STRING Text, + const LPRECT lpRc, + UINT uFlags) +{ + HFONT hOldFont = NULL, hFont = NULL; + COLORREF OldTextColor; + NONCLIENTMETRICS nclm; + NTSTATUS Status; + INT i; + + #ifndef NDEBUG + DPRINT("%s:", __FUNCTION__); + for(i = 0; i < Text->Length/sizeof(WCHAR); i++) + DbgPrint("%C", Text->Buffer[i]); + DbgPrint(", %d\n", Text->Length/sizeof(WCHAR)); + #endif + + nclm.cbSize = sizeof(nclm); + if(!IntSystemParametersInfo(SPI_GETNONCLIENTMETRICS, + sizeof(NONCLIENTMETRICS), &nclm, 0)) + { + DPRINT1("%s: IntSystemParametersInfo() failed!\n", __FUNCTION__); + return FALSE; + } + + NtGdiSetBkMode(hDc, TRANSPARENT); + + if(uFlags & DC_SMALLCAP) + Status = TextIntCreateFontIndirect(&nclm.lfSmCaptionFont, &hFont); + else Status = TextIntCreateFontIndirect(&nclm.lfCaptionFont, &hFont); + + if(!NT_SUCCESS(Status)) + { + DPRINT1("%s: TextIntCreateFontIndirect() failed! Status: 0x%x\n", + __FUNCTION__, Status); + return FALSE; + } + + hOldFont = NtGdiSelectObject(hDc, hFont); + if(!hOldFont) + { + DPRINT1("%s: SelectObject() failed!\n", __FUNCTION__); + NtGdiDeleteObject(hFont); + return FALSE; + } + + if(uFlags & DC_INBUTTON) + OldTextColor = NtGdiSetTextColor(hDc, IntGetSysColor(COLOR_BTNTEXT)); + else OldTextColor = NtGdiSetTextColor(hDc, IntGetSysColor(uFlags & DC_ACTIVE + ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT)); + + //FIXME: If string doesn't fit to rc, truncate it and add ellipsis. + + NtGdiTextOut(hDc, lpRc->left, + lpRc->top, Text->Buffer, + Text->Length/sizeof(WCHAR)); + + NtGdiSetTextColor(hDc, OldTextColor); + NtGdiSelectObject(hDc, hOldFont); + NtGdiDeleteObject(hFont); + + return TRUE; +} + +BOOL UserDrawCaption( + PWINDOW_OBJECT pWnd, + HDC hDc, + LPCRECT lpRc, + UINT uFlags) +{ + BOOL Ret = FALSE; + HBITMAP hMemBmp = NULL, hOldBmp = NULL; + HBRUSH hOldBrush = NULL; + HDC hMemDc = NULL; + ULONG Height; + UINT VCenter = 0, Padding = 0; + RECT r = *lpRc; + LONG ButtonWidth, IconWidth; + BOOL HasIcon; + + ASSERT(pWnd != NULL); + + hMemBmp = NtGdiCreateCompatibleBitmap(hDc, + lpRc->right - lpRc->left, + lpRc->bottom - lpRc->top); + + if(!hMemBmp) + { + DPRINT1("%s: NtGdiCreateCompatibleBitmap() failed!\n", __FUNCTION__); + return FALSE; + } + + hMemDc = NtGdiCreateCompatibleDC(hDc); + if(!hMemDc) + { + DPRINT1("%s: NtGdiCreateCompatibleDC() failed!\n", __FUNCTION__); + goto cleanup; + } + + hOldBmp = NtGdiSelectObject(hMemDc, hMemBmp); + if(!hOldBmp) + { + DPRINT1("%s: NtGdiSelectObject() failed!\n", __FUNCTION__); + goto cleanup; + } + + Height = UserGetSystemMetrics(SM_CYCAPTION) - 1; + VCenter = (lpRc->bottom - lpRc->top) / 2; + Padding = VCenter - (Height / 2); + HasIcon = (uFlags & DC_ICON) && (pWnd->Style & WS_SYSMENU) + && !(uFlags & DC_SMALLCAP); + IconWidth = UserGetSystemMetrics(SM_CXSIZE) + Padding; + + r.left = Padding; + r.right = r.left + (lpRc->right - lpRc->left); + r.top = Padding; + r.bottom = r.top + (Height / 2); + + // Draw the caption background + if(uFlags & DC_INBUTTON) + { + hOldBrush = NtGdiSelectObject(hMemDc, + IntGetSysColorBrush(uFlags & DC_ACTIVE ? + COLOR_BTNFACE : COLOR_BTNSHADOW)); + + if(!hOldBrush) + { + DPRINT1("%s: NtGdiSelectObject() failed!\n", __FUNCTION__); + goto cleanup; + } + + if(!NtGdiPatBlt(hMemDc, 0, 0, + lpRc->right - lpRc->left, + lpRc->bottom - lpRc->top, + PATCOPY)) + { + DPRINT1("%s: NtGdiPatBlt() failed!\n", __FUNCTION__); + goto cleanup; + } + + if(HasIcon) r.left+=IconWidth; + } + else + { + r.right = (lpRc->right - lpRc->left); + if(uFlags & DC_SMALLCAP) + ButtonWidth = UserGetSystemMetrics(SM_CXSMSIZE) - 2; + else ButtonWidth = UserGetSystemMetrics(SM_CXSIZE) - 2; + + hOldBrush = NtGdiSelectObject(hMemDc, + IntGetSysColorBrush(uFlags & DC_ACTIVE ? + COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION)); + + if(!hOldBrush) + { + DPRINT1("%s: NtGdiSelectObject() failed!\n", __FUNCTION__); + goto cleanup; + } + + if(HasIcon && (uFlags & DC_GRADIENT)) + { + NtGdiPatBlt(hMemDc, 0, 0, + IconWidth+1, + lpRc->bottom - lpRc->top, + PATCOPY); + r.left+=IconWidth; + } + else + { + NtGdiPatBlt(hMemDc, 0, 0, + lpRc->right - lpRc->left, + lpRc->bottom - lpRc->top, + PATCOPY); + } + + if(uFlags & DC_GRADIENT) + { + static GRADIENT_RECT gcap = {0, 1}; + TRIVERTEX vert[2]; + COLORREF Colors[2]; + PDC pMemDc; + + if(pWnd->Style & WS_SYSMENU) + { + r.right -= 3 + ButtonWidth; + if(!(uFlags & DC_SMALLCAP)) + { + if(pWnd->Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX)) + r.right -= 2 + 2 * ButtonWidth; + else r.right -= 2; + r.right -= 2; + } + + //Draw buttons background + if(!NtGdiSelectObject(hMemDc, + IntGetSysColorBrush(uFlags & DC_ACTIVE ? + COLOR_GRADIENTACTIVECAPTION:COLOR_GRADIENTINACTIVECAPTION))) + { + DPRINT1("%s: NtGdiSelectObject() failed!\n", __FUNCTION__); + goto cleanup; + } + + NtGdiPatBlt(hMemDc, + r.right, + 0, + lpRc->right - lpRc->left - r.right, + lpRc->bottom - lpRc->top, + PATCOPY); + } + + Colors[0] = IntGetSysColor((uFlags & DC_ACTIVE) ? + COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION); + + Colors[1] = IntGetSysColor((uFlags & DC_ACTIVE) ? + COLOR_GRADIENTACTIVECAPTION : COLOR_GRADIENTINACTIVECAPTION); + + vert[0].x = r.left; + vert[0].y = 0; + vert[0].Red = (WORD)Colors[0]<<8; + vert[0].Green = (WORD)Colors[0] & 0xFF00; + vert[0].Blue = (WORD)(Colors[0]>>8) & 0xFF00; + vert[0].Alpha = 0; + + vert[1].x = r.right; + vert[1].y = lpRc->bottom - lpRc->top; + vert[1].Red = (WORD)Colors[1]<<8; + vert[1].Green = (WORD)Colors[1] & 0xFF00; + vert[1].Blue = (WORD)(Colors[1]>>8) & 0xFF00; + vert[1].Alpha = 0; + + pMemDc = DC_LockDc(hMemDc); + if(!pMemDc) + { + DPRINT1("%s: Can't lock dc!\n", __FUNCTION__); + goto cleanup; + } + + if(!IntGdiGradientFill(pMemDc, vert, 2, &gcap, + 1, GRADIENT_FILL_RECT_H)) + { + DPRINT1("%s: IntGdiGradientFill() failed!\n", __FUNCTION__); + } + + DC_UnlockDc(pMemDc); + } //if(uFlags & DC_GRADIENT) + } + + if(HasIcon) + { + r.top ++; + r.left -= --IconWidth; + IntDrawSysMenuButton(pWnd, hMemDc, &r, FALSE); + r.left += IconWidth; + r.top --; + } + + r.top ++; + r.left += 2; + + r.bottom = r.top + Height; + + if((uFlags & DC_TEXT) && pWnd->WindowName.Length) + { + if(!(uFlags & DC_GRADIENT)) + { + r.right = (lpRc->right - lpRc->left); + + if(uFlags & DC_SMALLCAP) + ButtonWidth = UserGetSystemMetrics(SM_CXSMSIZE) - 2; + else ButtonWidth = UserGetSystemMetrics(SM_CXSIZE) - 2; + + if(pWnd->Style & WS_SYSMENU) + { + r.right -= 3 + ButtonWidth; + if(! (uFlags & DC_SMALLCAP)) + { + if(pWnd->Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX)) + r.right -= 2 + 2 * ButtonWidth; + else r.right -= 2; + r.right -= 2; + } + } + } + + IntDrawCaptionText(hMemDc, &pWnd->WindowName, &r, uFlags); + } + + if(!NtGdiBitBlt(hDc, lpRc->left, lpRc->top, + lpRc->right - lpRc->left, lpRc->bottom - lpRc->top, + hMemDc, 0, 0, SRCCOPY, 0, 0)) + { + DPRINT1("%s: NtGdiBitBlt() failed!\n", __FUNCTION__); + goto cleanup; + } + + Ret = TRUE; + +cleanup: + if (hOldBrush) NtGdiSelectObject(hMemDc, hOldBrush); + if (hOldBmp) NtGdiSelectObject(hMemDc, hOldBmp); + if (hMemBmp) NtGdiDeleteObject(hMemBmp); + if (hMemDc) NtGdiDeleteObjectApp(hMemDc); + + return Ret; +} + + +BOOL +STDCALL +NtUserDrawCaption(HWND hWnd, + HDC hDc, + LPCRECT lpRc, + UINT uFlags) +{ + PWINDOW_OBJECT pWnd; + RECT SafeRect; + BOOL Ret; + + if(!NT_SUCCESS(MmCopyFromCaller(&SafeRect, lpRc, sizeof(RECT)))) + { + DPRINT1("%s: MmCopyFromCaller failed!", __FUNCTION__); + return FALSE; + } + + UserEnterExclusive(); + + if(!(pWnd = UserGetWindowObject(hWnd))) + { + UserLeave(); + return FALSE; + } + + Ret = UserDrawCaption(pWnd, hDc, &SafeRect, uFlags); + + UserLeave(); + return Ret; +} + /* EOF */ Index: subsystems/win32/win32k/ntuser/cursoricon.c =================================================================== --- subsystems/win32/win32k/ntuser/cursoricon.c (revision 23134) +++ subsystems/win32/win32k/ntuser/cursoricon.c (working copy) @@ -72,7 +72,6 @@ }
-static PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon) { PCURICON_OBJECT CurIcon; @@ -1346,66 +1345,49 @@ (Rop3), 0) #endif /* STRETCH_CAN_SRCCOPY_ONLY */
-/* - * @implemented - */ -BOOL -STDCALL -NtUserDrawIconEx( - HDC hdc, - int xLeft, - int yTop, - HICON hIcon, - int cxWidth, - int cyHeight, +BOOL +UserDrawIconEx( + HDC hDc, + INT xLeft, + INT yTop, + PCURICON_OBJECT pIcon, + INT cxWidth, + INT cyHeight, UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, - UINT diFlags, - DWORD Unknown0, - DWORD Unknown1) + UINT diFlags) { - PCURICON_OBJECT CurIcon; - PWINSTATION_OBJECT WinSta; + BOOL Ret = FALSE; HBITMAP hbmMask, hbmColor; BITMAP bmpMask, bmpColor; + COLORREF oldFg, oldBg; BOOL DoFlickerFree; + INT nStretchMode; SIZE IconSize; - COLORREF oldFg, oldBg; - HDC hdcMem, hdcOff = (HDC)0; - HBITMAP hbmOff = (HBITMAP)0; - HGDIOBJ hOldOffBrush = 0, hOldOffBmp = 0, hOldMem; - BOOL Ret = FALSE; - INT nStretchMode; + + HDC hdcOff; + HGDIOBJ hOldOffBrush = 0; + HGDIOBJ hOldOffBmp = 0; + HBITMAP hbmOff = 0; + HDC hdcMem = 0; + HGDIOBJ hOldMem; + + hbmMask = pIcon->IconInfo.hbmMask; + hbmColor = pIcon->IconInfo.hbmColor;
- DECLARE_RETURN(BOOL); + if(istepIfAniCur) + DPRINT1("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
- DPRINT("Enter NtUserDrawIconEx\n"); - UserEnterExclusive(); - - WinSta = IntGetWinStaObj(); - if(WinSta == NULL) + if(!hbmMask || !IntGdiGetObject(hbmMask, sizeof(BITMAP), &bmpMask)) { - RETURN( FALSE); + return FALSE; }
- if (!(CurIcon = UserGetCurIconObject(hIcon))) + if(hbmColor && !IntGdiGetObject(hbmColor, sizeof(BITMAP), &bmpColor)) { - ObDereferenceObject(WinSta); - RETURN(FALSE); + return FALSE; }
- hbmMask = CurIcon->IconInfo.hbmMask; - hbmColor = CurIcon->IconInfo.hbmColor; - - if(istepIfAniCur) - DPRINT1("NtUserDrawIconEx: istepIfAniCur is not supported!\n"); - - if(!hbmMask || !IntGdiGetObject(hbmMask, sizeof(BITMAP), &bmpMask)) - goto done; - - if(hbmColor && !IntGdiGetObject(hbmColor, sizeof(BITMAP), &bmpColor)) - goto done; - if(hbmColor) { IconSize.cx = bmpColor.bmWidth; @@ -1421,11 +1403,15 @@ diFlags = DI_NORMAL;
if(!cxWidth) - cxWidth = ((diFlags & DI_DEFAULTSIZE) ? UserGetSystemMetrics(SM_CXICON) : IconSize.cx); + cxWidth = ((diFlags & DI_DEFAULTSIZE) ? + UserGetSystemMetrics(SM_CXICON) : IconSize.cx); + if(!cyHeight) - cyHeight = ((diFlags & DI_DEFAULTSIZE) ? UserGetSystemMetrics(SM_CYICON) : IconSize.cy); + cyHeight = ((diFlags & DI_DEFAULTSIZE) ? + UserGetSystemMetrics(SM_CYICON) : IconSize.cy);
- DoFlickerFree = (hbrFlickerFreeDraw && (NtGdiGetObjectType(hbrFlickerFreeDraw) == OBJ_BRUSH)); + DoFlickerFree = (hbrFlickerFreeDraw && + (NtGdiGetObjectType(hbrFlickerFreeDraw) == OBJ_BRUSH));
if(DoFlickerFree) { @@ -1433,29 +1419,45 @@ r.right = cxWidth; r.bottom = cyHeight;
- hdcOff = NtGdiCreateCompatibleDC(hdc); + hdcOff = NtGdiCreateCompatibleDC(hDc); if(!hdcOff) - goto done; + { + DPRINT1("NtGdiCreateCompatibleDC() failed!\n"); + return FALSE; + }
- hbmOff = NtGdiCreateCompatibleBitmap(hdc, cxWidth, cyHeight); + hbmOff = NtGdiCreateCompatibleBitmap(hDc, cxWidth, cyHeight); if(!hbmOff) { - NtGdiDeleteObjectApp(hdcOff); - goto done; + DPRINT1("NtGdiCreateCompatibleBitmap() failed!\n"); + goto cleanup; } + hOldOffBrush = NtGdiSelectObject(hdcOff, hbrFlickerFreeDraw); + if(!hOldOffBrush) + { + DPRINT1("NtGdiSelectObject() failed!\n"); + goto cleanup; + } + hOldOffBmp = NtGdiSelectObject(hdcOff, hbmOff); + if(!hOldOffBmp) + { + DPRINT1("NtGdiSelectObject() failed!\n"); + goto cleanup; + } + NtGdiPatBlt(hdcOff, 0, 0, r.right, r.bottom, PATCOPY); - NtGdiSelectObject(hdcOff, hbmOff); } - - hdcMem = NtGdiCreateCompatibleDC(hdc); + else hdcOff = hDc; + + hdcMem = NtGdiCreateCompatibleDC(hDc); if(!hdcMem) + { + DPRINT1("NtGdiCreateCompatibleDC() failed!\n"); goto cleanup; + }
- if(!DoFlickerFree) - hdcOff = hdc; - nStretchMode = NtGdiSetStretchBltMode(hdcOff, STRETCH_DELETESCANS);
oldFg = NtGdiSetTextColor(hdcOff, RGB(0, 0, 0)); @@ -1464,13 +1466,19 @@ if(diFlags & DI_MASK) { hOldMem = NtGdiSelectObject(hdcMem, hbmMask); + if(!hOldMem) + { + DPRINT("NtGdiSelectObject() failed!\n"); + goto cleanup; + }
DoStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft), (DoFlickerFree ? 0 : yTop), cxWidth, cyHeight, hdcMem, 0, 0, IconSize.cx, IconSize.cy, ((diFlags & DI_IMAGE) ? SRCAND : SRCCOPY), FALSE);
- if(!hbmColor && (bmpMask.bmHeight == 2 * bmpMask.bmWidth) && (diFlags & DI_IMAGE)) + if(!hbmColor && (bmpMask.bmHeight == 2 * bmpMask.bmWidth) + && (diFlags & DI_IMAGE)) { DoStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft), (DoFlickerFree ? 0 : yTop), cxWidth, cyHeight, hdcMem, @@ -1479,9 +1487,10 @@
diFlags &= ~DI_IMAGE; } + NtGdiSelectObject(hdcMem, hOldMem); } - + if(diFlags & DI_IMAGE) { hOldMem = NtGdiSelectObject(hdcMem, (hbmColor ? hbmColor : hbmMask)); @@ -1496,35 +1505,72 @@ }
if(DoFlickerFree) - NtGdiBitBlt(hdc, xLeft, yTop, cxWidth, cyHeight, hdcOff, 0, 0, SRCCOPY, 0, 0); - + { + NtGdiBitBlt(hDc, xLeft, yTop, cxWidth, + cyHeight, hdcOff, 0, 0, SRCCOPY, 0, 0); + } + NtGdiSetTextColor(hdcOff, oldFg); NtGdiSetBkColor(hdcOff, oldBg); - NtGdiSetStretchBltMode(hdcOff, nStretchMode); - + Ret = TRUE; - + cleanup: if(DoFlickerFree) {
- NtGdiSelectObject(hdcOff, hOldOffBmp); - NtGdiSelectObject(hdcOff, hOldOffBrush); - NtGdiDeleteObject(hbmOff); - NtGdiDeleteObjectApp(hdcOff); + if(hOldOffBmp) NtGdiSelectObject(hdcOff, hOldOffBmp); + if(hOldOffBrush) NtGdiSelectObject(hdcOff, hOldOffBrush); + if(hbmOff) NtGdiDeleteObject(hbmOff); + if(hdcOff) NtGdiDeleteObjectApp(hdcOff); } - if(hdcMem) - NtGdiDeleteObjectApp(hdcMem); + + if(hdcMem) NtGdiDeleteObjectApp(hdcMem); + return Ret; +}
-done: - ObDereferenceObject(WinSta); +/* + * @implemented + */ +BOOL +STDCALL +NtUserDrawIconEx( + HDC hdc, + int xLeft, + int yTop, + HICON hIcon, + int cxWidth, + int cyHeight, + UINT istepIfAniCur, + HBRUSH hbrFlickerFreeDraw, + UINT diFlags, + DWORD Unknown0, + DWORD Unknown1) +{ + PCURICON_OBJECT pIcon; + BOOL Ret;
- RETURN( Ret); + DPRINT("Enter NtUserDrawIconEx\n"); + UserEnterExclusive(); + + if(!(pIcon = UserGetCurIconObject(hIcon))) + { + DPRINT1("UserGetCurIconObject() failed!\n"); + UserLeave(); + return FALSE; + } + + Ret = UserDrawIconEx(hdc, + xLeft, + yTop, + pIcon, + cxWidth, + cyHeight, + istepIfAniCur, + hbrFlickerFreeDraw, + diFlags);
-CLEANUP: - DPRINT("Leave NtUserDrawIconEx, ret=%i\n",_ret_); UserLeave(); - END_CLEANUP; + return Ret; } - Index: subsystems/win32/win32k/ntuser/ntstubs.c =================================================================== --- subsystems/win32/win32k/ntuser/ntstubs.c (revision 23134) +++ subsystems/win32/win32k/ntuser/ntstubs.c (working copy) @@ -193,19 +193,6 @@
DWORD STDCALL -NtUserDrawCaption( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3) -{ - UNIMPLEMENTED - - return 0; -} - -DWORD -STDCALL NtUserDrawCaptionTemp( DWORD Unknown0, DWORD Unknown1, Index: subsystems/win32/win32k/include/intgdi.h =================================================================== --- subsystems/win32/win32k/include/intgdi.h (revision 23134) +++ subsystems/win32/win32k/include/intgdi.h (working copy) @@ -188,12 +188,18 @@ BOOL FASTCALL IntGetSysColorBrushes(HBRUSH *Brushes, UINT nBrushes);
+HGDIOBJ FASTCALL +IntGetSysColorBrush(INT Object); + BOOL FASTCALL IntGetSysColorPens(HPEN *Pens, UINT nPens);
BOOL FASTCALL IntGetSysColors(COLORREF *Colors, UINT nColors);
+DWORD FASTCALL +IntGetSysColor(INT nIndex); + /* Other Stuff */
INT FASTCALL Index: subsystems/win32/win32k/objects/stockobj.c =================================================================== --- subsystems/win32/win32k/objects/stockobj.c (revision 23134) +++ subsystems/win32/win32k/objects/stockobj.c (working copy) @@ -210,6 +210,12 @@ return nBrushes > 0; }
+HGDIOBJ FASTCALL +IntGetSysColorBrush(INT Object) +{ + return ((Object < 0) || (NUM_SYSCOLORS <= Object)) ? NULL : SysColorBrushes[Object]; +} + BOOL FASTCALL IntGetSysColorPens(HPEN *Pens, UINT nPens) { @@ -254,6 +260,12 @@ return nColors > 0; }
+DWORD FASTCALL +IntGetSysColor(INT nIndex) +{ + return ((nIndex < 0) || (NUM_SYSCOLORS <= nIndex)) ? 0 : SysColors[nIndex]; +} + VOID FASTCALL CreateSysColorObjects(VOID) { Index: include/reactos/win32k/ntuser.h =================================================================== --- include/reactos/win32k/ntuser.h (revision 23134) +++ include/reactos/win32k/ntuser.h (working copy) @@ -687,12 +687,11 @@ DWORD NTAPI NtUserDragObject( - HWND hwnd1, - HWND hwnd2, - UINT u1, - DWORD dw1, - HCURSOR hc1 - ); + HWND hwnd1, + HWND hwnd2, + UINT u1, + DWORD dw1, + HCURSOR hc1);
DWORD NTAPI @@ -702,24 +701,24 @@ DWORD Unknown2, DWORD Unknown3);
-DWORD +BOOL NTAPI NtUserDrawCaption( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3); + HWND hWnd, + HDC hDc, + LPCRECT lpRc, + UINT uFlags);
DWORD -NTAPI +STDCALL NtUserDrawCaptionTemp( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4, - DWORD Unknown5, - DWORD Unknown6); + DWORD Unknown0, + DWORD Unknown1, + DWORD Unknown2, + DWORD Unknown3, + DWORD Unknown4, + DWORD Unknown5, + DWORD Unknown6);
BOOL NTAPI Index: dll/win32/user32/windows/nonclient.c =================================================================== --- dll/win32/user32/windows/nonclient.c (revision 23134) +++ dll/win32/user32/windows/nonclient.c (working copy) @@ -1097,231 +1097,9 @@ BOOL WINAPI DrawCaption(HWND hWnd, HDC hDC, LPCRECT lprc, UINT uFlags) { - NONCLIENTMETRICSW nclm; - BOOL result = FALSE; - RECT r = *lprc; - UINT VCenter = 0, Padding = 0, Height; - ULONG Style; - WCHAR buffer[256]; - HFONT hFont = NULL; - HFONT hOldFont = NULL; - HBRUSH OldBrush = NULL; - HDC MemDC = NULL; - int ButtonWidth; - COLORREF OldTextColor; - -#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 - - Style = GetWindowLongW(hWnd, GWL_STYLE); - - /* Windows behaves like this */ - Height = GetSystemMetrics(SM_CYCAPTION) - 1; - - VCenter = (lprc->bottom - lprc->top) / 2; - Padding = VCenter - (Height / 2); - - r.left = Padding; - r.right = r.left + (lprc->right - lprc->left); - r.top = Padding; - r.bottom = r.top + (Height / 2); - - // Draw the caption background - if (uFlags & DC_INBUTTON) - { - OldBrush = SelectObject(MemDC, GetSysColorBrush(uFlags & DC_ACTIVE ? COLOR_BTNFACE : COLOR_BTNSHADOW) ); - if (! OldBrush) goto cleanup; - if (! PatBlt(MemDC, 0, 0, lprc->right - lprc->left, lprc->bottom - lprc->top, PATCOPY )) goto cleanup; - } - else - { - if (uFlags & DC_GRADIENT) - { - static GRADIENT_RECT gcap = {0, 1}; - TRIVERTEX vert[2]; - COLORREF Colors[2]; - LONG xx; - - r.right = (lprc->right - lprc->left); - if (uFlags & DC_SMALLCAP) - ButtonWidth = GetSystemMetrics(SM_CXSMSIZE) - 2; - else - ButtonWidth = GetSystemMetrics(SM_CXSIZE) - 2; - - //if (Style & WS_SYSMENU) - //{ - // r.right -= 3 + ButtonWidth; - // if (! (uFlags & DC_SMALLCAP)) - // { - // if(Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX)) - // r.right -= 2 + 2 * ButtonWidth; - // else - // r.right -= 2; - // r.right -= 2; - // } - //} - - Colors[0] = GetSysColor((uFlags & DC_ACTIVE) ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION); - Colors[1] = GetSysColor((uFlags & DC_ACTIVE) ? COLOR_GRADIENTACTIVECAPTION : COLOR_GRADIENTINACTIVECAPTION); - - vert[0].x = r.left; - vert[0].y = 0; - vert[0].Red = GetRValue(Colors[0]) << 8; - vert[0].Green = GetGValue(Colors[0]) << 8; - vert[0].Blue = GetBValue(Colors[0]) << 8; - vert[0].Alpha = 0; - - vert[1].x = r.right; - vert[1].y = lprc->bottom - lprc->top; - vert[1].Red = GetRValue(Colors[1]) << 8; - vert[1].Green = GetGValue(Colors[1]) << 8; - vert[1].Blue = GetBValue(Colors[1]) << 8; - vert[1].Alpha = 0; - - GdiGradientFill(MemDC, vert, 2, &gcap, 1, GRADIENT_FILL_RECT_V); - - if ((uFlags & DC_ICON) && (Style & WS_SYSMENU) && !(uFlags & DC_SMALLCAP)) - { - r.top --; - SetBkMode( MemDC, TRANSPARENT ); - xx = GetSystemMetrics(SM_CXSIZE) + Padding; - if (UserDrawSysMenuButton(hWnd, MemDC, &r, FALSE)) - r.left += xx; - r.top ++; - } - - if(OldBrush) - { - SelectObject(MemDC, OldBrush); - OldBrush = NULL; - } - //xx = lprc->right - lprc->left - r.right; - //if(xx > 0) - //{ - // OldBrush = SelectObject(MemDC, GetSysColorBrush(uFlags & DC_ACTIVE ? COLOR_GRADIENTACTIVECAPTION : COLOR_GRADIENTINACTIVECAPTION)); - // if (!OldBrush) goto cleanup; - // PatBlt(MemDC, r.right, 0, xx, lprc->bottom - lprc->top, PATCOPY); - //} - } - else - { - OldBrush = SelectObject(MemDC, GetSysColorBrush(uFlags & DC_ACTIVE ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION) ); - if (! OldBrush) goto cleanup; - if (! PatBlt(MemDC, 0, 0, lprc->right - lprc->left, lprc->bottom - lprc->top, PATCOPY )) goto cleanup; - } - } - - if ((uFlags & DC_ICON) && !(uFlags & DC_GRADIENT) && (Style & WS_SYSMENU) && !(uFlags & DC_SMALLCAP)) - { - /* For some reason the icon isn't centered correctly... */ - r.top --; - if (UserDrawSysMenuButton(hWnd, MemDC, &r, FALSE)) - r.left += GetSystemMetrics(SM_CXSIZE) + Padding; - r.top ++; - } - r.top ++; - r.left += 2; - - r.bottom = r.top + Height; - - if ((uFlags & DC_TEXT) && (NtUserInternalGetWindowText( hWnd, buffer, sizeof(buffer)/sizeof(buffer[0]) ))) - { - if(!(uFlags & DC_GRADIENT)) - { - r.right = (lprc->right - lprc->left); - if (uFlags & DC_SMALLCAP) - ButtonWidth = GetSystemMetrics(SM_CXSMSIZE) - 2; - else - ButtonWidth = GetSystemMetrics(SM_CXSIZE) - 2; - - if (Style & WS_SYSMENU) - { - r.right -= 3 + ButtonWidth; - if (! (uFlags & DC_SMALLCAP)) - { - if(Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX)) - r.right -= 2 + 2 * ButtonWidth; - else - r.right -= 2; - r.right -= 2; - } - } - } - - nclm.cbSize = sizeof(nclm); - if (! SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW), &nclm, 0)) goto cleanup; - - SetBkMode( MemDC, TRANSPARENT ); - if (uFlags & DC_SMALLCAP) - hFont = CreateFontIndirectW(&nclm.lfSmCaptionFont); - else - hFont = CreateFontIndirectW(&nclm.lfCaptionFont); - - if (! hFont) goto cleanup; - - hOldFont = SelectObject(MemDC, hFont); - if (! hOldFont) goto cleanup; - - if (uFlags & DC_INBUTTON) - OldTextColor = SetTextColor(MemDC, GetSysColor(uFlags & DC_ACTIVE ? COLOR_BTNTEXT : COLOR_GRAYTEXT)); - else - OldTextColor = SetTextColor(MemDC, GetSysColor(uFlags & DC_ACTIVE ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT)); - - DrawTextW(MemDC, buffer, wcslen(buffer), &r, DT_VCENTER | DT_END_ELLIPSIS); - - SetTextColor(MemDC, OldTextColor); - } - -#if 0 - 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); - } -#endif - -#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; + return NtUserDrawCaption(hWnd, hDC, lprc, uFlags); }
- /* * @unimplemented */