From 50382abaf98c2e0d147d0c40dbdbd39f5b2afaef Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Sat, 25 Oct 2003 22:57:34 +0000 Subject: [PATCH] - Better implementation of window non-client area functions. - Fixed GetWindowLong and SetWindowLong. - Other small bug fixes. svn path=/trunk/; revision=6436 --- reactos/lib/user32/Makefile | 3 +- reactos/lib/user32/windows/defwnd.c | 1107 ++------------------ reactos/lib/user32/windows/menu.c | 4 +- reactos/lib/user32/windows/nonclient.c | 1209 ++++++++++++++++++++++ reactos/lib/user32/windows/window.c | 107 +- reactos/subsys/win32k/include/window.h | 2 +- reactos/subsys/win32k/ntuser/scrollbar.c | 4 +- reactos/subsys/win32k/ntuser/window.c | 20 +- 8 files changed, 1315 insertions(+), 1141 deletions(-) create mode 100644 reactos/lib/user32/windows/nonclient.c diff --git a/reactos/lib/user32/Makefile b/reactos/lib/user32/Makefile index fbb382f5a6a..fef7fc45aa8 100644 --- a/reactos/lib/user32/Makefile +++ b/reactos/lib/user32/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.26 2003/08/22 07:51:32 gvg Exp $ +# $Id: Makefile,v 1.27 2003/10/25 22:57:34 navaraf Exp $ PATH_TO_TOP = ../.. @@ -70,6 +70,7 @@ WINDOWS_OBJECTS = \ windows/mdi.o \ windows/menu.o \ windows/messagebox.o \ + windows/nonclient.o \ windows/paint.o \ windows/prop.o \ windows/rect.o \ diff --git a/reactos/lib/user32/windows/defwnd.c b/reactos/lib/user32/windows/defwnd.c index 25ca1d491d1..ba6b0aa0b21 100644 --- a/reactos/lib/user32/windows/defwnd.c +++ b/reactos/lib/user32/windows/defwnd.c @@ -1,4 +1,4 @@ -/* $Id: defwnd.c,v 1.101 2003/10/23 19:39:00 weiden Exp $ +/* $Id: defwnd.c,v 1.102 2003/10/25 22:57:34 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -23,9 +23,16 @@ #define NDEBUG #include +LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn); +LRESULT DefWndNCCalcSize(HWND hWnd, BOOL CalcSizeStruct, RECT *Rect); +LRESULT DefWndNCActivate(HWND hWnd, WPARAM wParam); +LRESULT DefWndNCHitTest(HWND hWnd, POINT Point); +LRESULT DefWndNCLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam); +LRESULT DefWndNCLButtonDblClk(HWND hWnd, WPARAM wParam, LPARAM lParam); +LRESULT DefWndNCLButtonUp(HWND hWnd, WPARAM wParam, LPARAM lParam); + /* GLOBALS *******************************************************************/ -static HBITMAP hbSysMenu; /* TODO: widgets will be cached here. static HBITMAP hbClose; static HBITMAP hbCloseD; @@ -43,7 +50,7 @@ static HBITMAP hbScrRight; static COLORREF SysColours[] = { - RGB(224, 224, 224) /* COLOR_SCROLLBAR */, + RGB(192, 192, 192) /* COLOR_SCROLLBAR */, RGB(58, 110, 165) /* COLOR_BACKGROUND */, RGB(0, 0, 128) /* COLOR_ACTIVECAPTION */, RGB(128, 128, 128) /* COLOR_INACTIVECAPTION */, @@ -53,28 +60,30 @@ static COLORREF SysColours[] = RGB(0, 0, 0) /* COLOR_MENUTEXT */, RGB(0, 0, 0) /* COLOR_WINDOWTEXT */, RGB(255, 255, 255) /* COLOR_CAPTIONTEXT */, - RGB(128, 128, 128) /* COLOR_ACTIVEBORDER */, - RGB(255, 255, 255) /* COLOR_INACTIVEBORDER */, - RGB(255, 255, 232) /* COLOR_APPWORKSPACE */, - RGB(224, 224, 224) /* COLOR_HILIGHT */, - RGB(0, 0, 128) /* COLOR_HILIGHTTEXT */, + RGB(192, 192, 192) /* COLOR_ACTIVEBORDER */, + RGB(192, 192, 192) /* COLOR_INACTIVEBORDER */, + RGB(128, 128, 128) /* COLOR_APPWORKSPACE */, + RGB(0, 0, 128) /* COLOR_HILIGHT */, + RGB(255, 255, 255) /* COLOR_HILIGHTTEXT */, RGB(192, 192, 192) /* COLOR_BTNFACE */, RGB(128, 128, 128) /* COLOR_BTNSHADOW */, - RGB(192, 192, 192) /* COLOR_GRAYTEXT */, + RGB(128, 128, 128) /* COLOR_GRAYTEXT */, RGB(0, 0, 0) /* COLOR_BTNTEXT */, RGB(192, 192, 192) /* COLOR_INACTIVECAPTIONTEXT */, RGB(255, 255, 255) /* COLOR_BTNHILIGHT */, RGB(32, 32, 32) /* COLOR_3DDKSHADOW */, - RGB(192, 192, 192) /* COLOR_3DLIGHT */, + RGB(224, 224, 224) /* COLOR_3DLIGHT */, RGB(0, 0, 0) /* COLOR_INFOTEXT */, RGB(255, 255, 192) /* COLOR_INFOBK */, - RGB(184, 180, 184) /* COLOR_ALTERNATEBTNFACE */, + RGB(180, 180, 180) /* COLOR_ALTERNATEBTNFACE */, RGB(0, 0, 255) /* COLOR_HOTLIGHT */, RGB(16, 132, 208) /* COLOR_GRADIENTACTIVECAPTION */, RGB(181, 181, 181) /* COLOR_GRADIENTINACTIVECAPTION */, }; -static ATOM AtomInternalPos; +#define NUM_SYSCOLORS (sizeof(SysColours) / sizeof(SysColours[0])) + +ATOM AtomInternalPos; /* Bits in the dwKeyData */ #define KEYDATA_ALT 0x2000 @@ -103,9 +112,9 @@ GetSysColor(int nIndex) HPEN STDCALL GetSysColorPen(int nIndex) { - static HPEN SysPens[sizeof(SysColours) / sizeof(SysColours[0])]; + static HPEN SysPens[NUM_SYSCOLORS]; - if (nIndex < 0 || sizeof(SysColours) / sizeof(SysColours[0]) < nIndex) + if (nIndex < 0 || NUM_SYSCOLORS < nIndex) { SetLastError(ERROR_INVALID_PARAMETER); return NULL; @@ -127,9 +136,9 @@ GetSysColorPen(int nIndex) HBRUSH STDCALL GetSysColorBrush(int nIndex) { - static HBRUSH SysBrushes[sizeof(SysColours) / sizeof(SysColours[0])]; + static HBRUSH SysBrushes[NUM_SYSCOLORS]; - if (nIndex < 0 || sizeof(SysColours) / sizeof(SysColours[0]) < nIndex) + if (nIndex < 0 || NUM_SYSCOLORS < nIndex) { SetLastError(ERROR_INVALID_PARAMETER); return NULL; @@ -181,29 +190,6 @@ UserGetInternalPos(HWND hWnd) return(lpPos); } -BOOL -DefWndRedrawIconTitle(HWND hWnd) -{ - PINTERNALPOS lpPos = (PINTERNALPOS)GetPropA(hWnd, (LPSTR)(DWORD)AtomInternalPos); - - if (lpPos != NULL) - { - if (lpPos->IconTitle != NULL) - { - SendMessageA(lpPos->IconTitle, WM_SHOWWINDOW, TRUE, 0); - InvalidateRect(lpPos->IconTitle, NULL, TRUE); - return(TRUE); - } - } - return(FALSE); -} - -BOOL -UserHasMenu(HWND hWnd, ULONG Style) -{ - return (!(Style & WS_CHILD) && GetMenu(hWnd) != 0); -} - ULONG UserHasAnyFrameStyle(ULONG Style, ULONG ExStyle) { @@ -239,33 +225,6 @@ UserHasBigFrameStyle(ULONG Style, ULONG ExStyle) (ExStyle & WS_EX_DLGMODALFRAME)); } -void -UserGetFrameSize(ULONG Style, ULONG ExStyle, SIZE *Size) -{ - if (UserHasThickFrameStyle(Style, ExStyle)) - { - Size->cx = GetSystemMetrics(SM_CXFRAME); - Size->cy = GetSystemMetrics(SM_CYFRAME); - return; - } - else if (UserHasDlgFrameStyle(Style, ExStyle)) - { - Size->cx = GetSystemMetrics(SM_CXDLGFRAME); - Size->cy = GetSystemMetrics(SM_CYDLGFRAME); - return; - } - else if (UserHasThinFrameStyle(Style, ExStyle)) - { - Size->cx = GetSystemMetrics(SM_CXBORDER); - Size->cy = GetSystemMetrics(SM_CYBORDER); - return; - } - else - { - Size->cx = Size->cy = 0; - } -} - void UserGetInsideRectNC(HWND hWnd, RECT *rect) { @@ -312,812 +271,6 @@ UserGetInsideRectNC(HWND hWnd, RECT *rect) } } -WINBOOL -UserDrawSysMenuButton(HWND hWnd, HDC hDC, LPRECT Rect, BOOL down) -{ - HDC hDcMem; - HBITMAP hSavedBitmap; - - if (!hbSysMenu) - { - hbSysMenu = (HBITMAP)LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CLOSE)); - } - hDcMem = CreateCompatibleDC(hDC); - if (!hDcMem) - { - return FALSE; - } - hSavedBitmap = SelectObject(hDcMem, hbSysMenu); - if (!hSavedBitmap) - { - DeleteDC(hDcMem); - return FALSE; - } - - BitBlt(hDC, Rect->left + 2, Rect->top + 3, 16, 14, hDcMem, - (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD) ? - GetSystemMetrics(SM_CXSIZE): 0, 0, SRCCOPY); - - SelectObject(hDcMem, hSavedBitmap); - DeleteDC(hDcMem); - return TRUE; -} - -/* - * FIXME: - * Cache bitmaps, then just bitblt instead of calling DFC() (and - * wasting precious CPU cycles) every time - */ -static void -UserDrawCaptionButton(HWND hWnd, HDC hDC, BOOL bDown, ULONG Type) -{ - RECT rect; - ULONG ExStyle; - ULONG Style = GetWindowLongW(hWnd, GWL_STYLE); - INT iBmpWidth = GetSystemMetrics(SM_CXSIZE) - 2; - INT iBmpHeight = GetSystemMetrics(SM_CYSIZE) - 4; - SIZE FrameSize; - - if (!(Style & WS_SYSMENU)) - { - return; - } - - ExStyle = GetWindowLongW(hWnd, GWL_EXSTYLE); - UserGetFrameSize(Style, ExStyle, &FrameSize); - - GetWindowRect(hWnd, &rect); - - rect.right = rect.right - rect.left; - rect.bottom = rect.bottom - rect.top; - rect.left = rect.top = 0; - - switch(Type) - { - case DFCS_CAPTIONMIN: - { - if ((ExStyle & WS_EX_TOOLWINDOW) == TRUE) - return; /* ToolWindows don't have min/max buttons */ - - SetRect(&rect, rect.right - FrameSize.cx - (iBmpWidth * 3) - 4, - FrameSize.cy + 2, rect.right - (iBmpWidth * 2) - FrameSize.cx - 4, - rect.top + iBmpHeight + FrameSize.cy + 2); - DrawFrameControl(hDC, &rect, DFC_CAPTION, - DFCS_CAPTIONMIN | (bDown ? DFCS_PUSHED : 0) | - ((Style & WS_MINIMIZEBOX) ? 0 : DFCS_INACTIVE)); - break; - } - case DFCS_CAPTIONMAX: - { - if ((ExStyle & WS_EX_TOOLWINDOW) == TRUE) - return; /* ToolWindows don't have min/max buttons */ - - SetRect(&rect, rect.right - FrameSize.cx - (iBmpWidth * 2) - 4, - FrameSize.cy + 2, rect.right - iBmpWidth - FrameSize.cx - 4, - rect.top + iBmpHeight + FrameSize.cy + 2); - DrawFrameControl(hDC, &rect, DFC_CAPTION, - (IsZoomed(hWnd) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMAX) | - (bDown ? DFCS_PUSHED : 0) | - ((Style & WS_MAXIMIZEBOX) ? 0 : DFCS_INACTIVE)); - break; - } - case DFCS_CAPTIONCLOSE: - { - SetRect(&rect, rect.right - FrameSize.cx - iBmpWidth - 2, - FrameSize.cy + 2, rect.right - FrameSize.cx - 2, - rect.top + iBmpHeight + FrameSize.cy + 2 ); - DrawFrameControl(hDC, &rect, DFC_CAPTION, - (DFCS_CAPTIONCLOSE | (bDown ? DFCS_PUSHED : 0) | - ((Style & WS_SYSMENU) ? 0 : DFCS_INACTIVE))); - break; - } - } -} - -// 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, 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 - - // If DC_GRADIENT is specified, a Win 98/2000 style caption gradient should - // be painted. For now, that flag is ignored: - // Windows 98/Me, Windows 2000/XP: When this flag is set, the function uses - // COLOR_GRADIENTACTIVECAPTION (if the DC_ACTIVE flag was set) or - // COLOR_GRADIENTINACTIVECAPTION for the title-bar color. - - // 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 - { - // DC_GRADIENT check should go here somewhere - 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; - } - - 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); - - if ((uFlags & DC_ICON) && (Style & WS_SYSMENU)) - { - // 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]) ))) - { - // Duplicate odd behaviour from Windows: - if ((! uFlags & DC_SMALLCAP) || (uFlags & DC_ICON) || (uFlags & DC_INBUTTON) || - (! uFlags & DC_ACTIVE)) - r.left += GetSystemMetrics(SM_CXSIZE) + Padding; - - r.right = (lprc->right - lprc->left); - ButtonWidth = GetSystemMetrics(SM_CXSIZE) - 2; - - if (Style & WS_SYSMENU) - { - r.right -= 3 + ButtonWidth; - if (! (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW)) - { - 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 (Style & WS_EX_TOOLWINDOW) -// if (uFlags & DC_SMALLCAP) // incorrect - 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, SysColours[ uFlags & DC_ACTIVE ? COLOR_BTNTEXT : COLOR_GRAYTEXT]); - else - OldTextColor = SetTextColor(MemDC, SysColours[ uFlags & DC_ACTIVE ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT]); - - DrawTextW(MemDC, buffer, wcslen(buffer), &r, DT_VCENTER | DT_END_ELLIPSIS); - - SetTextColor(MemDC, OldTextColor); - } - - 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, - RECT *rect, - HWND hWnd, - DWORD style, - BOOL active ) -{ - POINT OldPos; - HPEN lPen, oPen; - RECT r = *rect; - ULONG ExStyle; - UINT capflags = 0; - SIZE FrameSize; - - ExStyle = GetWindowLongW(hWnd, GWL_EXSTYLE); - - capflags = DC_ICON | DC_TEXT; - capflags |= (active & DC_ACTIVE); - - if(style & WS_EX_TOOLWINDOW) - capflags |= DC_SMALLCAP; - - UserGetFrameSize(style, ExStyle, &FrameSize); - - r.left += FrameSize.cx; - r.top += FrameSize.cy; - r.right -= FrameSize.cx; - r.bottom = r.top + GetSystemMetrics(SM_CYCAPTION) - 1; - - DrawCaption(hWnd, hDC, &r, capflags); - - /* draw line below caption */ - lPen = GetSysColorPen(COLOR_MENU); - oPen = SelectObject(hDC, lPen); - MoveToEx(hDC, r.left, r.bottom, &OldPos); - LineTo(hDC, r.right, r.bottom); - MoveToEx(hDC, OldPos.x, OldPos.y, NULL); - SelectObject(hDC, oPen); - r.bottom++; - - if (style & WS_SYSMENU) - { - r.left += GetSystemMetrics(SM_CXSIZE) + 1; - UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONCLOSE); - r.right -= GetSystemMetrics(SM_CXSMSIZE) + 1; - if((style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX)) && !(ExStyle & WS_EX_TOOLWINDOW)) - { - UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMIN); - UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMAX); - } - } -} - - -static VOID -UserDrawFrameNC(HDC hDC, RECT* rect, BOOL dlgFrame, BOOL active) -{ - DrawEdge(hDC, rect, EDGE_RAISED, BF_RECT | BF_MIDDLE); -} - - -void -SCROLL_DrawScrollBar (HWND hWnd, HDC hDC, INT nBar, BOOL arrows, BOOL interior); - -VOID -DefWndDoPaintNC(HWND hWnd, HRGN clip) -{ - BOOL Active = FALSE; - HDC hDC; - RECT rect, clientrect; - ULONG Style; - ULONG ExStyle; - SIZE FrameSize; - HGDIOBJ OldObj; - - if (GetActiveWindow() == hWnd) Active = TRUE; - - hDC = GetDCEx(hWnd, (clip > (HRGN)1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW | - ((clip > (HRGN)1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0)); - if (hDC == 0) - { - return; - } - - Style = GetWindowLongW(hWnd, GWL_STYLE); - ExStyle = GetWindowLongW(hWnd, GWL_EXSTYLE); - - /* FIXME: Test whether we need to draw anything at all. */ - - GetWindowRect(hWnd, &rect); - GetClientRect(hWnd, &clientrect); - - rect.right -= rect.left; - rect.bottom -= rect.top; - rect.top = rect.left = 0; - - UserGetFrameSize(Style, ExStyle, &FrameSize); - - OldObj = SelectObject(hDC, GetSysColorPen(COLOR_WINDOWFRAME)); - - if(UserHasThickFrameStyle(Style, ExStyle)) - UserDrawFrameNC(hDC, &rect, FALSE, Active); - else if (UserHasDlgFrameStyle(Style, ExStyle)) - UserDrawFrameNC(hDC, &rect, TRUE, Active); - - if (Style & WS_CAPTION) - { - RECT r = rect; - r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE); - rect.top += GetSystemMetrics(SM_CYCAPTION) + FrameSize.cy; - DbgPrint("1. rect.top == %d\n", rect.top); - UserDrawCaptionNC(hDC, &r, hWnd, Style, Active); - } - - /* Draw menu bar. */ - if (UserHasMenu(hWnd, Style)) - {DbgPrint("2. rect.top == %d\n", rect.top); - RECT r = rect; - r.bottom = rect.top + GetSystemMetrics(SM_CYMENU); - r.left += FrameSize.cx; - r.right -= FrameSize.cx; - rect.top += MenuDrawMenuBar(hDC, &r, hWnd, FALSE); - DbgPrint("3. rect.top == %d\n", rect.top); - } - - if (ExStyle & WS_EX_CLIENTEDGE) - DrawEdge(hDC, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); - - /* Draw scrollbars */ - if((Style & WS_VSCROLL) && (clientrect.right < rect.right - (2 * FrameSize.cx))) - SCROLL_DrawScrollBar(hWnd, hDC, SB_VERT, TRUE, TRUE); - DbgPrint("HSCROLL: %d < %d - %d - %d\n", clientrect.bottom, rect.bottom, rect.top, FrameSize.cy); - if((Style & WS_HSCROLL) && (clientrect.bottom < rect.bottom - rect.top - FrameSize.cy)) - SCROLL_DrawScrollBar(hWnd, hDC, SB_HORZ, TRUE, TRUE); - - /* FIXME: Draw size box.*/ - SelectObject(hDC, OldObj); - - ReleaseDC(hWnd, hDC); -} - - -LRESULT -DefWndPaintNC(HWND hWnd, HRGN clip) -{ - if (IsWindowVisible(hWnd)) - { - if (IsIconic(hWnd)) - { - DefWndRedrawIconTitle(hWnd); - } - else - { - DefWndDoPaintNC(hWnd, clip); - } - } - return(0); -} - - -LRESULT -DefWndHitTestNC(HWND hWnd, POINT Point) -{ - RECT WindowRect, ClientRect, WndRect; - LONG ScrollXY; - SIZE FrameSize; - ULONG Style = GetWindowLongW(hWnd, GWL_STYLE); - ULONG ExStyle = GetWindowLongW(hWnd, GWL_EXSTYLE); - - GetWindowRect(hWnd, &WindowRect); - WndRect = WindowRect; - if (!PtInRect(&WindowRect, Point)) - { - return(HTNOWHERE); - } - if (Style & WS_MINIMIZE) - { - return(HTCAPTION); - } - if (UserHasThickFrameStyle(Style, ExStyle)) - { - FrameSize.cx = GetSystemMetrics(SM_CXFRAME); - FrameSize.cy = GetSystemMetrics(SM_CYFRAME); - InflateRect(&WindowRect, -FrameSize.cx, -FrameSize.cy); - if (!PtInRect(&WindowRect, Point)) - { - if (Point.y < WindowRect.top) - { - if (Point.x < (WindowRect.left + GetSystemMetrics(SM_CXSIZE))) - { - return(HTTOPLEFT); - } - if (Point.x >= (WindowRect.right - GetSystemMetrics(SM_CXSIZE))) - { - return(HTTOPRIGHT); - } - return(HTTOP); - } - if (Point.y >= WindowRect.bottom) - { - if (Point.x < (WindowRect.left + GetSystemMetrics(SM_CXSIZE))) - { - return(HTBOTTOMLEFT); - } - if (Point.x >= (WindowRect.right - GetSystemMetrics(SM_CXSIZE))) - { - return(HTBOTTOMRIGHT); - } - return(HTBOTTOM); - } - if (Point.x < WindowRect.left) - { - if (Point.y < (WindowRect.top + GetSystemMetrics(SM_CYSIZE))) - { - return(HTTOPLEFT); - } - if (Point.y >= (WindowRect.bottom - GetSystemMetrics(SM_CYSIZE))) - { - return(HTBOTTOMLEFT); - } - return(HTLEFT); - } - if (Point.x >= WindowRect.right) - { - if (Point.y < (WindowRect.top + GetSystemMetrics(SM_CYSIZE))) - { - return(HTTOPRIGHT); - } - if (Point.y >= (WindowRect.bottom - GetSystemMetrics(SM_CYSIZE))) - { - return(HTBOTTOMRIGHT); - } - return(HTRIGHT); - } - } - } - else - { - if (UserHasDlgFrameStyle(Style, ExStyle)) - { - FrameSize.cx = GetSystemMetrics(SM_CXDLGFRAME); - FrameSize.cy = GetSystemMetrics(SM_CYDLGFRAME); - InflateRect(&WindowRect, -FrameSize.cx, -FrameSize.cy); - } - else if (UserHasThinFrameStyle(Style, ExStyle)) - { - FrameSize.cx = GetSystemMetrics(SM_CXBORDER); - FrameSize.cy = GetSystemMetrics(SM_CYBORDER); - InflateRect(&WindowRect, -FrameSize.cx, -FrameSize.cy); - } - if (!PtInRect(&WindowRect, Point)) - { - return(HTBORDER); - } - } - - if ((Style & WS_CAPTION) == WS_CAPTION) - { - WindowRect.top += (GetSystemMetrics(SM_CYCAPTION)); - if (!PtInRect(&WindowRect, Point)) - { - if ((Style & WS_SYSMENU) && !(ExStyle & WS_EX_TOOLWINDOW)) - { - WindowRect.left += GetSystemMetrics(SM_CXSIZE); - WindowRect.right -= GetSystemMetrics(SM_CXSIZE); - } - if (Point.x <= WindowRect.left) - { - return(HTSYSMENU); - } - if (WindowRect.right <= Point.x) - { - return(HTCLOSE); - } - - if (Style & WS_MAXIMIZEBOX || Style & WS_MINIMIZEBOX) - { - WindowRect.right -= GetSystemMetrics(SM_CXSIZE); - } - if (Point.x >= WindowRect.right) - { - return(HTMAXBUTTON); - } - - if (Style & WS_MINIMIZEBOX) - { - WindowRect.right -= GetSystemMetrics(SM_CXSIZE); - } - if (Point.x >= WindowRect.right) - { - return(HTMINBUTTON); - } - return(HTCAPTION); - } - } - - ScreenToClient(hWnd, &Point); - GetClientRect(hWnd, &ClientRect); - WndRect.right -= WndRect.left; - WndRect.bottom -= WndRect.top; - WndRect.left = WndRect.top = 0; - - if (PtInRect(&ClientRect, Point)) - { - return(HTCLIENT); - } - - if (UserHasMenu(hWnd, Style)) - { - if (Point.y < 0 && Point.x >= 0 && Point.x <= WindowRect.right) - { - return(HTMENU); - } - } - - if (Style & WS_VSCROLL) - { - ScrollXY = GetSystemMetrics(SM_CXVSCROLL); - ClientRect.left = ClientRect.right; - ClientRect.right += ScrollXY; - if (PtInRect(&ClientRect, Point) && PtInRect(&WndRect, Point)) - { - return(HTVSCROLL); - } - } - else - ScrollXY = 0; - - if (Style & WS_HSCROLL) - { - GetClientRect(hWnd, &ClientRect); - ClientRect.top = ClientRect.bottom; - ClientRect.bottom = ClientRect.top + GetSystemMetrics(SM_CXVSCROLL); - if (PtInRect(&ClientRect, Point) && PtInRect(&WndRect, Point)) - { - return(HTHSCROLL); - } - if (ScrollXY) - { - ClientRect.left = ClientRect.right; - ClientRect.right += ScrollXY; - if(PtInRect(&WndRect, Point) && PtInRect(&ClientRect, Point)) - { - return(HTBOTTOMRIGHT); - } - } - } - - return(HTNOWHERE); -} - -VOID STATIC -DefWndDoButton(HWND hWnd, WPARAM wParam) -{ - MSG Msg; - BOOL InBtn, HasBtn = FALSE; - ULONG Btn, Style; - WPARAM SCMsg, CurBtn = wParam, OrigBtn = wParam; - - Style = GetWindowLongW(hWnd, GWL_STYLE); - switch(wParam) - { - case HTCLOSE: - Btn = DFCS_CAPTIONCLOSE; - SCMsg = SC_CLOSE; - HasBtn = (Style & WS_SYSMENU); - break; - case HTMINBUTTON: - Btn = DFCS_CAPTIONMIN; - SCMsg = SC_MINIMIZE; - HasBtn = (Style & WS_MINIMIZEBOX); - break; - case HTMAXBUTTON: - Btn = DFCS_CAPTIONMAX; - SCMsg = SC_MAXIMIZE; - HasBtn = (Style & WS_MAXIMIZEBOX); - break; - default: - return; - } - - InBtn = HasBtn; - - SetCapture(hWnd); - - if(HasBtn) - UserDrawCaptionButton( hWnd, GetWindowDC(hWnd), HasBtn , Btn); - - while(1) - { - GetMessageW(&Msg, 0, 0, 0); - switch(Msg.message) - { - case WM_NCLBUTTONUP: - case WM_LBUTTONUP: - if(InBtn) - goto done; - else - { - ReleaseCapture(); - return; - } - case WM_NCMOUSEMOVE: - case WM_MOUSEMOVE: - if(HasBtn) - { - CurBtn = DefWndHitTestNC(hWnd, Msg.pt); - if(InBtn != (CurBtn == OrigBtn)) - { - UserDrawCaptionButton( hWnd, GetWindowDC(hWnd), (CurBtn == OrigBtn) , Btn); - } - InBtn = CurBtn == OrigBtn; - } - break; - } - } - -done: - UserDrawCaptionButton( hWnd, GetWindowDC(hWnd), FALSE , Btn); - ReleaseCapture(); - SendMessageA(hWnd, WM_SYSCOMMAND, SCMsg, 0); - return; -} - -VOID STATIC -DefWndDoScrollBarDown(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - POINT Point; - DWORD hit; - Point.x = SLOWORD(lParam); - Point.y = SHIWORD(lParam); - - hit = SCROLL_HitTest(hWnd, (wParam == HTHSCROLL) ? SB_HORZ : SB_VERT, Point, FALSE); - - if(hit) - DPRINT("SCROLL_HitTest() == 0x%x\n", hit); - - SendMessageA(hWnd, WM_SYSCOMMAND, Msg + (UINT)wParam, lParam); -} - -LRESULT -DefWndHandleLButtonDownNC(HWND hWnd, WPARAM wParam, LPARAM lParam) -{ - switch (wParam) - { - case HTCAPTION: - { - HWND hTopWnd = GetAncestor(hWnd, GA_ROOT); - if (SetActiveWindow(hTopWnd) || GetActiveWindow() == hTopWnd) - { - SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam); - } - break; - } - case HTSYSMENU: - { - if (GetWindowLongW(hWnd, GWL_STYLE) & WS_SYSMENU) - { - if (!(GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE)) - { - HDC hDC = GetWindowDC(hWnd); -// UserDrawSysMenuButton(hWnd, hDC, TRUE); - ReleaseDC(hWnd, hDC); - } - SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, - lParam); - } - break; - } - case HTMENU: - { - SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTMENU, lParam); - break; - } - case HTHSCROLL: - { - DefWndDoScrollBarDown(hWnd, SC_HSCROLL, HTHSCROLL, lParam); - //SendMessageA(hWnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam); - break; - } - case HTVSCROLL: - { - DefWndDoScrollBarDown(hWnd, SC_VSCROLL, HTVSCROLL, lParam); - //SendMessageA(hWnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam); - break; - } - case HTMINBUTTON: - case HTMAXBUTTON: - case HTCLOSE: - { - DefWndDoButton(hWnd, wParam); - break; - } - case HTLEFT: - case HTRIGHT: - case HTTOP: - case HTBOTTOM: - case HTTOPLEFT: - case HTTOPRIGHT: - case HTBOTTOMLEFT: - case HTBOTTOMRIGHT: - { - SendMessageA(hWnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam); - break; - } - } - return(0); -} - - -LRESULT -DefWndHandleLButtonDblClkNC(HWND hWnd, WPARAM wParam, LPARAM lParam) -{ - UNIMPLEMENTED; - return(0); -} - - -LRESULT -DefWndHandleLButtonUpNC(HWND hWnd, WPARAM wParam, LPARAM lParam) -{ - UNIMPLEMENTED; - return(0); -} - - -LRESULT -DefWndHandleActiveNC(HWND hWnd, WPARAM wParam) -{ - UNIMPLEMENTED; - return(0); -} - VOID DefWndSetRedraw(HWND hWnd, WPARAM wParam) @@ -1221,7 +374,7 @@ DefWndStartSizeMove(HWND hWnd, WPARAM wParam, POINT *capturePoint) switch(msg.message) { case WM_MOUSEMOVE: - hittest = DefWndHitTestNC(hWnd, msg.pt); + hittest = DefWndNCHitTest(hWnd, msg.pt); if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT)) hittest = 0; break; @@ -1620,116 +773,6 @@ DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, POINT Pt) return(0); } - -VOID -DefWndAdjustRect(HWND hWnd, RECT* Rect, ULONG Style, BOOL Menu, ULONG ExStyle) -{ - SIZE FrameSize; - - if(Style & WS_ICONIC) - return; - - UserGetFrameSize(Style, ExStyle, &FrameSize); - - InflateRect(Rect, FrameSize.cx, FrameSize.cy); - - if(Style & WS_CAPTION) - { - Rect->top -= GetSystemMetrics(SM_CYCAPTION); - } - if(Menu) - { - Rect->top -= MenuGetMenuBarHeight(hWnd, Rect->right - Rect->left, -Rect->left, -Rect->top); - } -} - -LRESULT STDCALL -DefWndNCCalcSize(HWND hWnd, BOOL CalcSizeStruct, RECT* Rect) -{ - LRESULT Result = 0; - LONG ScrollXY; - SIZE FrameSize; - NCCALCSIZE_PARAMS *SizeStruct = (NCCALCSIZE_PARAMS *)Rect; - RECT NewRect, TmpRect = {0, 0, 0, 0}; - ULONG ExStyle = GetWindowLongW(hWnd, GWL_EXSTYLE); - LONG Style = GetClassLongW(hWnd, GCL_STYLE); - - if (Style & CS_VREDRAW) - { - Result |= WVR_VREDRAW; - } - if (Style & CS_HREDRAW) - { - Result |= WVR_HREDRAW; - } - - Style = GetWindowLongW(hWnd, GWL_STYLE); - - if (!(Style & WS_MINIMIZE)) - { - if(!(Style & WS_ICONIC)) - { - UserGetFrameSize(Style, ExStyle, &FrameSize); - InflateRect(&TmpRect, FrameSize.cx, FrameSize.cy); - if(Style & WS_CAPTION) - TmpRect.top -= GetSystemMetrics(SM_CYCAPTION); - } - - if(CalcSizeStruct) - { - Rect = &(SizeStruct->rgrc[0]); - } - else - { - Result = 0; - } - - NewRect.left = Rect->left - TmpRect.left; - NewRect.top = Rect->top - TmpRect.top; - NewRect.right = Rect->right - TmpRect.right; - NewRect.bottom = Rect->bottom - TmpRect.bottom; - if(NewRect.top > NewRect.bottom) - NewRect.bottom = NewRect.top; - if(NewRect.left > NewRect.right) - NewRect.right = NewRect.left; - - if(UserHasMenu(hWnd, Style)) - NewRect.top += MenuGetMenuBarHeight(hWnd, NewRect.right - NewRect.left, NewRect.left, NewRect.top); - - if (Style & WS_VSCROLL) - { - ScrollXY = GetSystemMetrics(SM_CXVSCROLL); - if(NewRect.right - NewRect.left > ScrollXY) - { - NewRect.right -= ScrollXY + 1; - if (UserHasAnyFrameStyle(Style, ExStyle)) - { - NewRect.right++; - } - } - } - if (Style & WS_HSCROLL) - { - ScrollXY = GetSystemMetrics(SM_CYHSCROLL); - if(NewRect.bottom - NewRect.top > ScrollXY) - { - NewRect.bottom -= ScrollXY + 1; - if (UserHasAnyFrameStyle(Style, ExStyle)) - { - NewRect.bottom++; - } - } - } - - Rect->left = NewRect.left; - Rect->top = NewRect.top; - Rect->right = NewRect.right; - Rect->bottom = NewRect.bottom; - - } - return Result; -} - LRESULT DefWndHandleWindowPosChanging(HWND hWnd, WINDOWPOS* Pos) { @@ -1843,14 +886,52 @@ User32DefWindowProc(HWND hWnd, { switch (Msg) { - case WM_NCPAINT: - { - return (DefWndPaintNC(hWnd, (HRGN)wParam)); + case WM_NCPAINT: + { + return DefWndNCPaint(hWnd, (HRGN)wParam); } case WM_NCCALCSIZE: { - return (DefWndNCCalcSize(hWnd, (BOOL)wParam, (RECT*)lParam)); + return DefWndNCCalcSize(hWnd, (BOOL)wParam, (RECT*)lParam); + } + + case WM_NCACTIVATE: + { + return DefWndNCActivate(hWnd, wParam); + } + + case WM_NCHITTEST: + { + POINT Point; + Point.x = SLOWORD(lParam); + Point.y = SHIWORD(lParam); + return (DefWndNCHitTest(hWnd, Point)); + } + + case WM_NCLBUTTONDOWN: + { + return (DefWndNCLButtonDown(hWnd, wParam, lParam)); + } + + case WM_NCLBUTTONUP: + { + return (DefWndNCLButtonUp(hWnd, wParam, lParam)); + } + + case WM_LBUTTONDBLCLK: + case WM_NCLBUTTONDBLCLK: + { + return (DefWndNCLButtonDblClk(hWnd, wParam, lParam)); + } + + case WM_NCRBUTTONDOWN: + { + if (wParam == HTCAPTION) + { + SetCapture(hWnd); + } + break; } case WM_WINDOWPOSCHANGING: @@ -1863,39 +944,6 @@ User32DefWindowProc(HWND hWnd, return (DefWndHandleWindowPosChanged(hWnd, (WINDOWPOS*)lParam)); } - case WM_NCHITTEST: - { - POINT Point; - Point.x = SLOWORD(lParam); - Point.y = SHIWORD(lParam); - return (DefWndHitTestNC(hWnd, Point)); - } - - case WM_NCLBUTTONDOWN: - { - return (DefWndHandleLButtonDownNC(hWnd, wParam, lParam)); - } - - case WM_NCLBUTTONUP: - { - return (DefWndHandleLButtonUpNC(hWnd, wParam, lParam)); - } - - case WM_LBUTTONDBLCLK: - case WM_NCLBUTTONDBLCLK: - { - return (DefWndHandleLButtonDblClkNC(hWnd, wParam, lParam)); - } - - case WM_NCRBUTTONDOWN: - { - if (wParam == HTCAPTION) - { - SetCapture(hWnd); - } - break; - } - case WM_RBUTTONUP: { POINT Pt; @@ -1943,7 +991,7 @@ User32DefWindowProc(HWND hWnd, ScreenToClient(GetParent(hWnd), &Pt); } - HitCode = DefWndHitTestNC(hWnd, Pt); + HitCode = DefWndNCHitTest(hWnd, Pt); if (HitCode == HTCAPTION || HitCode == HTSYSMENU) { @@ -1951,15 +999,10 @@ User32DefWindowProc(HWND hWnd, TPM_LEFTBUTTON | TPM_RIGHTBUTTON, Pt.x, Pt.y, 0, hWnd, NULL); } - } + } break; } - case WM_NCACTIVATE: - { - return (DefWndHandleActiveNC(hWnd, wParam)); - } - case WM_PRINT: { /* FIXME: Implement. */ @@ -2370,9 +1413,9 @@ DefWindowProcA(HWND hWnd, (strlen((PSTR)lParam) + 1) * sizeof(CHAR)); strcpy(WindowText, (PSTR)lParam); SetPropA(hWnd, WindowTextAtom, WindowText); - if (0 != (GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION)) - { - DefWndPaintNC(hWnd, (HRGN) 1); + if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION) + { + DefWndNCPaint(hWnd, (HRGN)1); } return (1); } @@ -2475,8 +1518,8 @@ DefWindowProcW(HWND hWnd, wcscpy(WindowText, (PWSTR)lParam); SetPropW(hWnd, WindowTextAtom, WindowText); if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION) - { - DefWndPaintNC(hWnd, (HRGN)1); + { + DefWndNCPaint(hWnd, (HRGN)1); } return (1); } diff --git a/reactos/lib/user32/windows/menu.c b/reactos/lib/user32/windows/menu.c index 5fda84f8b8d..0f3407b5f11 100644 --- a/reactos/lib/user32/windows/menu.c +++ b/reactos/lib/user32/windows/menu.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: menu.c,v 1.33 2003/08/29 10:20:53 gvg Exp $ +/* $Id: menu.c,v 1.34 2003/10/25 22:57:34 navaraf Exp $ * * PROJECT: ReactOS user32.dll * FILE: lib/user32/windows/menu.c @@ -395,6 +395,8 @@ MenuDrawMenuBar(HDC hDC, LPRECT Rect, HWND hWnd, BOOL Draw) RECT *omir, *mir = NULL; LPWSTR str; + FillRect(hDC, Rect, GetSysColorBrush(COLOR_MENU)); + height = Rect->bottom - Rect->top; mnu = GetMenu(hWnd); /* Fixme - pass menu handle as parameter */ /* get menu item list size */ diff --git a/reactos/lib/user32/windows/nonclient.c b/reactos/lib/user32/windows/nonclient.c new file mode 100644 index 00000000000..b7b9b394113 --- /dev/null +++ b/reactos/lib/user32/windows/nonclient.c @@ -0,0 +1,1209 @@ +/* + * ReactOS User32 Library + * - Window non-client area management + * + * Copyright (C) 2003 ReactOS Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* INCLUDES *******************************************************************/ + +/* + * Define this to get the code working on ReactOS. It should be removed later. + */ +#define __REACTOS__ + +/* + * Use w32api headers + */ +#define __USE_W32API +#define _WIN32_WINNT 0x0501 + +#include +#include +#include +#include +#include +#include + +#define NDEBUG +#include + +/* + * FIXME: This should be moved to a header + */ +VOID +SCROLL_DrawScrollBar(HWND hWnd, HDC hDC, INT nBar, BOOL arrows, BOOL interior); +DWORD +SCROLL_HitTest( HWND hwnd, INT nBar, POINT pt, BOOL bDragging ); +HPEN STDCALL +GetSysColorPen(int nIndex); + +extern ATOM AtomInternalPos; + +/* PRIVATE FUNCTIONS **********************************************************/ + +BOOL +UserHasWindowEdge(DWORD Style, DWORD ExStyle) +{ + if (ExStyle & WS_EX_DLGMODALFRAME) + return TRUE; + if (ExStyle & WS_EX_STATICEDGE) + return FALSE; + if (Style & WS_THICKFRAME) + return TRUE; + Style &= WS_CAPTION; + if (Style == WS_DLGFRAME || Style == WS_CAPTION) + return TRUE; + return FALSE; +} + +VOID +UserGetWindowBorders(DWORD Style, DWORD ExStyle, SIZE *Size, BOOL WithClient) +{ + DWORD Border = 0; + + if (UserHasWindowEdge(Style, ExStyle)) + Border += 2; + else if (ExStyle & WS_EX_STATICEDGE) + Border += 1; + if ((ExStyle & WS_EX_CLIENTEDGE) && WithClient) + Border += 2; + if (Style & WS_CAPTION || ExStyle & WS_EX_DLGMODALFRAME) + Border ++; + Size->cx = Size->cy = Border; + if (Style & WS_THICKFRAME) + { + Size->cx += GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXDLGFRAME); + Size->cy += GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYDLGFRAME); + } + Size->cx *= GetSystemMetrics(SM_CXBORDER); + Size->cy *= GetSystemMetrics(SM_CYBORDER); +} + +BOOL +UserHasMenu(HWND hWnd, ULONG Style) +{ + return (!(Style & WS_CHILD) && GetMenu(hWnd) != 0); +} + +BOOL +UserDrawSysMenuButton(HWND hWnd, HDC hDC, LPRECT Rect, BOOL down) +{ + HDC hDcMem; + HBITMAP hSavedBitmap; + static HBITMAP hbSysMenu = NULL; + + if (hbSysMenu == NULL) + { + hbSysMenu = (HBITMAP)LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CLOSE)); + } + + hDcMem = CreateCompatibleDC(hDC); + if (!hDcMem) + { + return FALSE; + } + + hSavedBitmap = SelectObject(hDcMem, hbSysMenu); + if (!hSavedBitmap) + { + DeleteDC(hDcMem); + return FALSE; + } + + BitBlt(hDC, Rect->left + 2, Rect->top + 3, 16, 14, hDcMem, + (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD) ? + GetSystemMetrics(SM_CXSIZE): 0, 0, SRCCOPY); + + SelectObject(hDcMem, hSavedBitmap); + DeleteDC(hDcMem); + + return TRUE; +} + +/* + * FIXME: + * - Cache bitmaps, then just bitblt instead of calling DFC() (and + * wasting precious CPU cycles) every time + * - Center the buttons verticaly in the rect + */ +VOID +UserDrawCaptionButton(LPRECT Rect, DWORD Style, DWORD ExStyle, HDC hDC, BOOL bDown, ULONG Type) +{ + RECT TempRect; + + if (!(Style & WS_SYSMENU)) + { + return; + } + + TempRect = *Rect; + + switch (Type) + { + case DFCS_CAPTIONMIN: + { + if ((ExStyle & WS_EX_TOOLWINDOW) == TRUE) + return; /* ToolWindows don't have min/max buttons */ + + if (Style & WS_SYSMENU) + TempRect.right -= GetSystemMetrics(SM_CXSIZE) + 1; + if (Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX)) + TempRect.right -= GetSystemMetrics(SM_CXSIZE) - 2; + TempRect.left = TempRect.right - GetSystemMetrics(SM_CXSIZE) + 1; + TempRect.bottom = TempRect.top + GetSystemMetrics(SM_CYSIZE) - 2; + TempRect.top += 2; + TempRect.right -= 1; + + DrawFrameControl(hDC, &TempRect, DFC_CAPTION, + DFCS_CAPTIONMIN | (bDown ? DFCS_PUSHED : 0) | + ((Style & WS_MINIMIZEBOX) ? 0 : DFCS_INACTIVE)); + break; + } + case DFCS_CAPTIONMAX: + { + if ((ExStyle & WS_EX_TOOLWINDOW) == TRUE) + return; /* ToolWindows don't have min/max buttons */ + + if (Style & WS_SYSMENU) + TempRect.right -= GetSystemMetrics(SM_CXSIZE) + 1; + TempRect.left = TempRect.right - GetSystemMetrics(SM_CXSIZE) + 1; + TempRect.bottom = TempRect.top + GetSystemMetrics(SM_CYSIZE) - 2; + TempRect.top += 2; + TempRect.right -= 1; + + DrawFrameControl(hDC, &TempRect, DFC_CAPTION, + ((Style & WS_MAXIMIZE) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMAX) | + (bDown ? DFCS_PUSHED : 0) | + ((Style & WS_MAXIMIZEBOX) ? 0 : DFCS_INACTIVE)); + break; + } + case DFCS_CAPTIONCLOSE: + { + /* FIXME: A tool window has a smaller Close button */ + + TempRect.left = TempRect.right - GetSystemMetrics(SM_CXSIZE); + TempRect.bottom = TempRect.top + GetSystemMetrics(SM_CYSIZE) - 2; + TempRect.top += 2; + TempRect.right -= 2; + + DrawFrameControl(hDC, &TempRect, DFC_CAPTION, + (DFCS_CAPTIONCLOSE | (bDown ? DFCS_PUSHED : 0) | + ((Style & WS_SYSMENU) ? 0 : DFCS_INACTIVE))); + break; + } + } +} + +VOID +UserDrawCaptionButtonWnd(HWND hWnd, HDC hDC, BOOL bDown, ULONG Type) +{ + RECT WindowRect; + SIZE WindowBorder; + DWORD Style, ExStyle; + + GetWindowRect(hWnd, &WindowRect); + Style = GetWindowLong(hWnd, GWL_STYLE); + ExStyle = GetWindowLong(hWnd, GWL_EXSTYLE); + UserGetWindowBorders(Style, ExStyle, &WindowBorder, FALSE); + InflateRect(&WindowRect, -WindowBorder.cx, -WindowBorder.cy); + UserDrawCaptionButton(&WindowRect, Style, ExStyle, hDC, bDown, Type); +} + +/* + * FIXME: + * - Move to controls/scroll.c ? + * - Handle drawing of reversed size grip + */ +VOID +SCROLL_DrawSizeGrip(HDC hDC, LPRECT lpRect) +{ + HPEN hPenFace, hPenShadow, hPenHighlight, hOldPen; + POINT pt; + INT i; + + pt.x = lpRect->right - 1; + pt.y = lpRect->bottom - 1; + + hPenFace = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DFACE)); + hOldPen = SelectObject(hDC, hPenFace); + MoveToEx(hDC, pt.x - 12, pt.y, NULL); + LineTo(hDC, pt.x, pt.y); + LineTo(hDC, pt.x, pt.y - 13); + + pt.x--; + pt.y--; + + hPenShadow = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW)); + SelectObject(hDC, hPenShadow); + for (i = 1; i < 11; i += 4) + { + MoveToEx(hDC, pt.x - i, pt.y, NULL); + LineTo(hDC, pt.x + 1, pt.y - i - 1); + MoveToEx(hDC, pt.x - i - 1, pt.y, NULL); + LineTo(hDC, pt.x + 1, pt.y - i - 2); + } + + hPenHighlight = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DHIGHLIGHT)); + SelectObject(hDC, hPenHighlight ); + for (i = 3; i < 13; i += 4) + { + MoveToEx(hDC, pt.x - i, pt.y, NULL); + LineTo(hDC, pt.x + 1, pt.y - i - 1); + } + + SelectObject(hDC, hOldPen); + DeleteObject(hPenFace); + DeleteObject(hPenShadow); + DeleteObject(hPenHighlight); +} + +/* FIXME: Verify implementation. */ +BOOL +DefWndRedrawIconTitle(HWND hWnd) +{ + PINTERNALPOS lpPos = (PINTERNALPOS)GetPropA(hWnd, (LPSTR)(DWORD)AtomInternalPos); + + if (lpPos != NULL) + { + if (lpPos->IconTitle != NULL) + { + SendMessageA(lpPos->IconTitle, WM_SHOWWINDOW, TRUE, 0); + InvalidateRect(lpPos->IconTitle, NULL, TRUE); + return TRUE; + } + } + return FALSE; +} + +/* + * FIXME: + * - Drawing of WS_BORDER after scrollbars + * - Correct drawing of size-box + */ +LRESULT +DefWndNCPaint(HWND hWnd, HRGN hRgn) +{ + HDC hDC; + BOOL Active; + DWORD Style, ExStyle; + RECT ClientRect, WindowRect, CurrentRect, TempRect; + + if (!IsWindowVisible(hWnd)) + return 0; + + Style = GetWindowLongW(hWnd, GWL_STYLE); + + if (Style & WS_MINIMIZE) + { + DefWndRedrawIconTitle(hWnd); + return 0; + } + +/* FIXME: This works on Windows, but not on ReactOS! */ +#ifdef __REACTOS__ + hDC = GetDCEx(hWnd, (hRgn > (HRGN)1) ? hRgn : 0, + /*DCX_USESTYLE*/0x10000 | DCX_WINDOW | + ((hRgn > (HRGN)1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0)); +#else + hDC = GetDCEx(hWnd, hRgn, DCX_WINDOW | DCX_INTERSECTRGN | 0x10000); +#endif + if (hDC == 0) + { + return 0; + } + + ExStyle = GetWindowLongW(hWnd, GWL_EXSTYLE); + Active = (GetActiveWindow() == hWnd); + GetWindowRect(hWnd, &WindowRect); + GetClientRect(hWnd, &ClientRect); + + CurrentRect.top = CurrentRect.left = 0; + CurrentRect.right = WindowRect.right - WindowRect.left; + CurrentRect.bottom = WindowRect.bottom - WindowRect.top; + + /* Draw outer edge */ + if (UserHasWindowEdge(Style, ExStyle)) + { + DrawEdge(hDC, &CurrentRect, EDGE_RAISED, BF_RECT | BF_ADJUST); + } else + if (ExStyle & WS_EX_STATICEDGE) + { + DrawEdge(hDC, &CurrentRect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST); + } + + /* Firstly the "thick" frame */ + if (Style & WS_THICKFRAME) + { + DWORD Width = + (GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXDLGFRAME)) * + GetSystemMetrics(SM_CXBORDER); + DWORD Height = + (GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYDLGFRAME)) * + GetSystemMetrics(SM_CYBORDER); + + SelectObject(hDC, GetSysColorBrush(Active ? COLOR_ACTIVEBORDER : + COLOR_INACTIVEBORDER)); + + /* Draw frame */ + PatBlt(hDC, CurrentRect.left, CurrentRect.top, CurrentRect.right - CurrentRect.left, Height, PATCOPY); + PatBlt(hDC, CurrentRect.left, CurrentRect.top, Width, CurrentRect.bottom - CurrentRect.top, PATCOPY); +#ifdef __REACTOS__ + PatBlt(hDC, CurrentRect.left, CurrentRect.bottom - 1, CurrentRect.right - CurrentRect.left, -Height, PATCOPY); + PatBlt(hDC, CurrentRect.right - 1, CurrentRect.top, -Width, CurrentRect.bottom - CurrentRect.top, PATCOPY); +#else + PatBlt(hDC, CurrentRect.left, CurrentRect.bottom, CurrentRect.right - CurrentRect.left, -Height, PATCOPY); + PatBlt(hDC, CurrentRect.right, CurrentRect.top, -Width, CurrentRect.bottom - CurrentRect.top, PATCOPY); +#endif + + InflateRect(&CurrentRect, -Width, -Height); + } + + /* Now the other bit of the frame */ + if (Style & WS_CAPTION || ExStyle & WS_EX_DLGMODALFRAME) + { + DWORD Width = GetSystemMetrics(SM_CXBORDER); + DWORD Height = GetSystemMetrics(SM_CYBORDER); + + SelectObject(hDC, GetSysColorBrush( + (ExStyle & (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE)) ? COLOR_3DFACE : + (ExStyle & WS_EX_STATICEDGE) ? COLOR_WINDOWFRAME : + (Style & (WS_DLGFRAME | WS_THICKFRAME)) ? COLOR_3DFACE : + COLOR_WINDOWFRAME)); + + /* Draw frame */ + PatBlt(hDC, CurrentRect.left, CurrentRect.top, CurrentRect.right - CurrentRect.left, Height, PATCOPY); + PatBlt(hDC, CurrentRect.left, CurrentRect.top, Width, CurrentRect.bottom - CurrentRect.top, PATCOPY); +#ifdef __REACTOS__ + PatBlt(hDC, CurrentRect.left, CurrentRect.bottom - 1, CurrentRect.right - CurrentRect.left, -Height, PATCOPY); + PatBlt(hDC, CurrentRect.right - 1, CurrentRect.top, -Width, CurrentRect.bottom - CurrentRect.top, PATCOPY); +#else + PatBlt(hDC, CurrentRect.left, CurrentRect.bottom, CurrentRect.right - CurrentRect.left, -Height, PATCOPY); + PatBlt(hDC, CurrentRect.right, CurrentRect.top, -Width, CurrentRect.bottom - CurrentRect.top, PATCOPY); +#endif + + InflateRect(&CurrentRect, -Width, -Height); + } + + /* Draw caption */ + if ((Style & WS_CAPTION) == WS_CAPTION) + { + DWORD CaptionFlags = DC_ICON | DC_TEXT | DC_GRADIENT | DC_BUTTONS; + HPEN PreviousPen; + + TempRect = CurrentRect; + + if (Active) + { + CaptionFlags |= DC_ACTIVE; + } + + if (Style & WS_EX_TOOLWINDOW) + { + CaptionFlags |= DC_SMALLCAP; + TempRect.bottom = TempRect.top + GetSystemMetrics(SM_CYSMCAPTION) - 1; + CurrentRect.top += GetSystemMetrics(SM_CYSMCAPTION); + } + else + { + TempRect.bottom = TempRect.top + GetSystemMetrics(SM_CYCAPTION) - 1; + CurrentRect.top += GetSystemMetrics(SM_CYCAPTION); + } + + DrawCaption(hWnd, hDC, &TempRect, CaptionFlags); + + /* Draw buttons */ + if (Style & WS_SYSMENU) + { + UserDrawCaptionButton(&TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONCLOSE); + if ((Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX)) && !(ExStyle & WS_EX_TOOLWINDOW)) + { + UserDrawCaptionButton(&TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONMIN); + UserDrawCaptionButton(&TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONMAX); + } + } + + /* Line under caption */ + PreviousPen = SelectObject(hDC, GetSysColorPen( + ((ExStyle & (WS_EX_STATICEDGE | WS_EX_CLIENTEDGE | + WS_EX_DLGMODALFRAME)) == WS_EX_STATICEDGE) ? + COLOR_WINDOWFRAME : COLOR_3DFACE)); + MoveToEx(hDC, TempRect.left, TempRect.bottom, NULL); + LineTo(hDC, TempRect.right, TempRect.bottom); + SelectObject(hDC, PreviousPen); + } + + /* Draw menu bar */ + if (UserHasMenu(hWnd, Style)) + { + TempRect = CurrentRect; + TempRect.bottom = TempRect.top + GetSystemMetrics(SM_CYMENU); + CurrentRect.top += MenuDrawMenuBar(hDC, &TempRect, hWnd, FALSE); + } + + if (ExStyle & WS_EX_CLIENTEDGE) + { + DrawEdge(hDC, &CurrentRect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); + } + + /* Draw the scrollbars */ + if ((Style & WS_VSCROLL) && (Style & WS_HSCROLL) && + (CurrentRect.bottom - CurrentRect.top) > GetSystemMetrics(SM_CYHSCROLL)) + { + TempRect = CurrentRect; + if ((ExStyle & WS_EX_LEFTSCROLLBAR) != 0) + TempRect.right = TempRect.left + GetSystemMetrics(SM_CXVSCROLL); + else + TempRect.left = TempRect.right - GetSystemMetrics(SM_CXVSCROLL); + TempRect.top = TempRect.bottom - GetSystemMetrics(SM_CYHSCROLL); + FillRect(hDC, &TempRect, GetSysColorBrush(COLOR_SCROLLBAR)); + /* FIXME: Correct drawing of size-box with WS_EX_LEFTSCROLLBAR */ + SCROLL_DrawSizeGrip(hDC, &TempRect); + SCROLL_DrawScrollBar(hWnd, hDC, SB_VERT, TRUE, TRUE); + SCROLL_DrawScrollBar(hWnd, hDC, SB_HORZ, TRUE, TRUE); + } + else + { + if (Style & WS_VSCROLL) + SCROLL_DrawScrollBar(hWnd, hDC, SB_VERT, TRUE, TRUE); + else if (Style & WS_HSCROLL) + SCROLL_DrawScrollBar(hWnd, hDC, SB_HORZ, TRUE, TRUE); + } + + ReleaseDC(hWnd, hDC); + + return 0; +} + +LRESULT +DefWndNCCalcSize(HWND hWnd, BOOL CalcSizeStruct, RECT *Rect) +{ + LRESULT Result = 0; + DWORD Style = GetClassLongW(hWnd, GCL_STYLE); + DWORD ExStyle; + SIZE WindowBorders; + + if (CalcSizeStruct) + { + if (Style & CS_VREDRAW) + { + Result |= WVR_VREDRAW; + } + if (Style & CS_HREDRAW) + { + Result |= WVR_HREDRAW; + } + Result |= WVR_VALIDRECTS; + } + + Style = GetWindowLongW(hWnd, GWL_STYLE); + ExStyle = GetWindowLongW(hWnd, GWL_EXSTYLE); + + if (!(Style & WS_MINIMIZE)) + { + UserGetWindowBorders(Style, ExStyle, &WindowBorders, FALSE); + InflateRect(Rect, -WindowBorders.cx, -WindowBorders.cy); + if ((Style & WS_CAPTION) == WS_CAPTION) + Rect->top += GetSystemMetrics(SM_CYCAPTION); + + if (UserHasMenu(hWnd, Style)) + Rect->top += MenuGetMenuBarHeight(hWnd, Rect->right - Rect->left, Rect->left, Rect->top); + + if (ExStyle & WS_EX_CLIENTEDGE) + { + InflateRect(Rect, -2 * GetSystemMetrics(SM_CXBORDER), + -2 * GetSystemMetrics(SM_CYBORDER)); + } + + if ((Style & WS_VSCROLL) && (Style & WS_HSCROLL) && + (Rect->bottom - Rect->top) > GetSystemMetrics(SM_CYHSCROLL)) + { + if ((ExStyle & WS_EX_LEFTSCROLLBAR) != 0) + Rect->left += GetSystemMetrics(SM_CXVSCROLL); + else + Rect->right -= GetSystemMetrics(SM_CXVSCROLL); + Rect->bottom -= GetSystemMetrics(SM_CYHSCROLL); + } + else + { + if (Style & WS_VSCROLL) + { + if ((ExStyle & WS_EX_LEFTSCROLLBAR) != 0) + Rect->left += GetSystemMetrics(SM_CXVSCROLL); + else + Rect->right -= GetSystemMetrics(SM_CXVSCROLL); + } + else if (Style & WS_HSCROLL) + Rect->bottom -= GetSystemMetrics(SM_CYHSCROLL); + } + if (Rect->top > Rect->bottom) + Rect->bottom = Rect->top; + if (Rect->left > Rect->right) + Rect->right = Rect->left; + } + + return Result; +} + +LRESULT +DefWndNCActivate(HWND hWnd, WPARAM wParam) +{ + DefWndNCPaint(hWnd, (HRGN)1); + return TRUE; +} + +ULONG +UserHasDlgFrameStyle(ULONG Style, ULONG ExStyle); +ULONG +UserHasThickFrameStyle(ULONG Style, ULONG ExStyle); +ULONG +UserHasThinFrameStyle(ULONG Style, ULONG ExStyle); + +/* FIXME: Rewrite */ +LRESULT +DefWndNCHitTest(HWND hWnd, POINT Point) +{ + LONG ScrollXY; + SIZE FrameSize; + RECT WindowRect, ClientRect, WndRect; + ULONG Style = GetWindowLongW(hWnd, GWL_STYLE); + ULONG ExStyle = GetWindowLongW(hWnd, GWL_EXSTYLE); + + GetWindowRect(hWnd, &WindowRect); + WndRect = WindowRect; + if (!PtInRect(&WindowRect, Point)) + { + return HTNOWHERE; + } + if (Style & WS_MINIMIZE) + { + return HTCAPTION; + } + + if (UserHasThickFrameStyle(Style, ExStyle)) + { + FrameSize.cx = GetSystemMetrics(SM_CXFRAME); + FrameSize.cy = GetSystemMetrics(SM_CYFRAME); + InflateRect(&WindowRect, -FrameSize.cx, -FrameSize.cy); + if (!PtInRect(&WindowRect, Point)) + { + if (Point.y < WindowRect.top) + { + if (Point.x < (WindowRect.left + GetSystemMetrics(SM_CXSIZE))) + { + return(HTTOPLEFT); + } + if (Point.x >= (WindowRect.right - GetSystemMetrics(SM_CXSIZE))) + { + return(HTTOPRIGHT); + } + return(HTTOP); + } + if (Point.y >= WindowRect.bottom) + { + if (Point.x < (WindowRect.left + GetSystemMetrics(SM_CXSIZE))) + { + return(HTBOTTOMLEFT); + } + if (Point.x >= (WindowRect.right - GetSystemMetrics(SM_CXSIZE))) + { + return(HTBOTTOMRIGHT); + } + return(HTBOTTOM); + } + if (Point.x < WindowRect.left) + { + if (Point.y < (WindowRect.top + GetSystemMetrics(SM_CYSIZE))) + { + return(HTTOPLEFT); + } + if (Point.y >= (WindowRect.bottom - GetSystemMetrics(SM_CYSIZE))) + { + return(HTBOTTOMLEFT); + } + return(HTLEFT); + } + if (Point.x >= WindowRect.right) + { + if (Point.y < (WindowRect.top + GetSystemMetrics(SM_CYSIZE))) + { + return(HTTOPRIGHT); + } + if (Point.y >= (WindowRect.bottom - GetSystemMetrics(SM_CYSIZE))) + { + return(HTBOTTOMRIGHT); + } + return(HTRIGHT); + } + } + } + else + { + if (UserHasDlgFrameStyle(Style, ExStyle)) + { + FrameSize.cx = GetSystemMetrics(SM_CXDLGFRAME); + FrameSize.cy = GetSystemMetrics(SM_CYDLGFRAME); + InflateRect(&WindowRect, -FrameSize.cx, -FrameSize.cy); + } + else if (UserHasThinFrameStyle(Style, ExStyle)) + { + FrameSize.cx = GetSystemMetrics(SM_CXBORDER); + FrameSize.cy = GetSystemMetrics(SM_CYBORDER); + InflateRect(&WindowRect, -FrameSize.cx, -FrameSize.cy); + } + if (!PtInRect(&WindowRect, Point)) + { + return(HTBORDER); + } + } + + if ((Style & WS_CAPTION) == WS_CAPTION) + { + WindowRect.top += (GetSystemMetrics(SM_CYCAPTION)); + if (!PtInRect(&WindowRect, Point)) + { + if ((Style & WS_SYSMENU) && !(ExStyle & WS_EX_TOOLWINDOW)) + { + WindowRect.left += GetSystemMetrics(SM_CXSIZE); + WindowRect.right -= GetSystemMetrics(SM_CXSIZE); + } + if (Point.x <= WindowRect.left) + { + return(HTSYSMENU); + } + if (WindowRect.right <= Point.x) + { + return(HTCLOSE); + } + + if (Style & WS_MAXIMIZEBOX || Style & WS_MINIMIZEBOX) + { + WindowRect.right -= GetSystemMetrics(SM_CXSIZE); + } + if (Point.x >= WindowRect.right) + { + return(HTMAXBUTTON); + } + + if (Style & WS_MINIMIZEBOX) + { + WindowRect.right -= GetSystemMetrics(SM_CXSIZE); + } + if (Point.x >= WindowRect.right) + { + return(HTMINBUTTON); + } + return(HTCAPTION); + } + } + + ScreenToClient(hWnd, &Point); + GetClientRect(hWnd, &ClientRect); + WndRect.right -= WndRect.left; + WndRect.bottom -= WndRect.top; + WndRect.left = WndRect.top = 0; + + if (PtInRect(&ClientRect, Point)) + { + return(HTCLIENT); + } + + if (UserHasMenu(hWnd, Style)) + { + if (Point.y < 0 && Point.x >= 0 && Point.x <= WindowRect.right) + { + return(HTMENU); + } + } + + if (Style & WS_VSCROLL) + { + ScrollXY = GetSystemMetrics(SM_CXVSCROLL); + ClientRect.left = ClientRect.right; + ClientRect.right += ScrollXY; + if (PtInRect(&ClientRect, Point) && PtInRect(&WndRect, Point)) + { + return(HTVSCROLL); + } + } + else + ScrollXY = 0; + + if (Style & WS_HSCROLL) + { + GetClientRect(hWnd, &ClientRect); + ClientRect.top = ClientRect.bottom; + ClientRect.bottom = ClientRect.top + GetSystemMetrics(SM_CXVSCROLL); + if (PtInRect(&ClientRect, Point) && PtInRect(&WndRect, Point)) + { + return(HTHSCROLL); + } + if (ScrollXY) + { + ClientRect.left = ClientRect.right; + ClientRect.right += ScrollXY; + if(PtInRect(&WndRect, Point) && PtInRect(&ClientRect, Point)) + { + return(HTBOTTOMRIGHT); + } + } + } + + return(HTNOWHERE); +} + + +VOID +DefWndDoScrollBarDown(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + POINT Point; + DWORD hit; + Point.x = GET_X_LPARAM(lParam); + Point.y = GET_Y_LPARAM(lParam); + + hit = SCROLL_HitTest(hWnd, (wParam == HTHSCROLL) ? SB_HORZ : SB_VERT, Point, FALSE); + + if(hit) + DPRINT("SCROLL_HitTest() == 0x%x\n", hit); + + SendMessageA(hWnd, WM_SYSCOMMAND, Msg + (UINT)wParam, lParam); +} + +VOID +DefWndDoButton(HWND hWnd, WPARAM wParam) +{ + MSG Msg; + BOOL InBtn, HasBtn = FALSE; + ULONG Btn, Style; + WPARAM SCMsg, CurBtn = wParam, OrigBtn = wParam; + + Style = GetWindowLongW(hWnd, GWL_STYLE); + switch(wParam) + { + case HTCLOSE: + Btn = DFCS_CAPTIONCLOSE; + SCMsg = SC_CLOSE; + HasBtn = (Style & WS_SYSMENU); + break; + case HTMINBUTTON: + Btn = DFCS_CAPTIONMIN; + SCMsg = SC_MINIMIZE; + HasBtn = (Style & WS_MINIMIZEBOX); + break; + case HTMAXBUTTON: + Btn = DFCS_CAPTIONMAX; + SCMsg = SC_MAXIMIZE; + HasBtn = (Style & WS_MAXIMIZEBOX); + break; + default: + return; + } + + InBtn = HasBtn; + + SetCapture(hWnd); + + if(HasBtn) + UserDrawCaptionButtonWnd( hWnd, GetWindowDC(hWnd), HasBtn , Btn); + + while(1) + { + GetMessageW(&Msg, 0, 0, 0); + switch(Msg.message) + { + case WM_NCLBUTTONUP: + case WM_LBUTTONUP: + if(InBtn) + goto done; + else + { + ReleaseCapture(); + return; + } + case WM_NCMOUSEMOVE: + case WM_MOUSEMOVE: + if(HasBtn) + { + CurBtn = DefWndNCHitTest(hWnd, Msg.pt); + if(InBtn != (CurBtn == OrigBtn)) + { + UserDrawCaptionButtonWnd( hWnd, GetWindowDC(hWnd), (CurBtn == OrigBtn) , Btn); + } + InBtn = CurBtn == OrigBtn; + } + break; + } + } + +done: + UserDrawCaptionButtonWnd( hWnd, GetWindowDC(hWnd), FALSE , Btn); + ReleaseCapture(); + SendMessageA(hWnd, WM_SYSCOMMAND, SCMsg, 0); + return; +} + + +LRESULT +DefWndNCLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam) +{ + switch (wParam) + { + case HTCAPTION: + { + HWND hTopWnd = GetAncestor(hWnd, GA_ROOT); + if (SetActiveWindow(hTopWnd) || GetActiveWindow() == hTopWnd) + { + SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam); + } + break; + } + case HTSYSMENU: + { + if (GetWindowLongW(hWnd, GWL_STYLE) & WS_SYSMENU) + { + if (!(GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE)) + { + HDC hDC = GetWindowDC(hWnd); +// UserDrawSysMenuButton(hWnd, hDC, TRUE); + ReleaseDC(hWnd, hDC); + } + SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, + lParam); + } + break; + } + case HTMENU: + { + SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTMENU, lParam); + break; + } + case HTHSCROLL: + { + DefWndDoScrollBarDown(hWnd, SC_HSCROLL, HTHSCROLL, lParam); + //SendMessageA(hWnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam); + break; + } + case HTVSCROLL: + { + DefWndDoScrollBarDown(hWnd, SC_VSCROLL, HTVSCROLL, lParam); + //SendMessageA(hWnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam); + break; + } + case HTMINBUTTON: + case HTMAXBUTTON: + case HTCLOSE: + { + DefWndDoButton(hWnd, wParam); + break; + } + case HTLEFT: + case HTRIGHT: + case HTTOP: + case HTBOTTOM: + case HTTOPLEFT: + case HTTOPRIGHT: + case HTBOTTOMLEFT: + case HTBOTTOMRIGHT: + { + SendMessageA(hWnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam); + break; + } + } + return(0); +} + + +LRESULT +DefWndNCLButtonDblClk(HWND hWnd, WPARAM wParam, LPARAM lParam) +{ + UNIMPLEMENTED; + return(0); +} + + +LRESULT +DefWndNCLButtonUp(HWND hWnd, WPARAM wParam, LPARAM lParam) +{ +/* DWORD Style = GetWindowLongW(hWnd, GWL_STYLE);*/ + + switch (wParam) /* Hit test */ + { + case HTCAPTION: + { + HWND Top = GetAncestor(hWnd, GA_ROOT); + + SetActiveWindow(Top); + SendMessageW(hWnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam); + break; + } + + case HTSYSMENU: + /* FIXME */ + break; + + case HTMENU: + /* FIXME */ + break; + + case HTHSCROLL: + /* FIXME */ + break; + + case HTVSCROLL: + /* FIXME */ + break; + + case HTMINBUTTON: + case HTMAXBUTTON: + /* FIXME */ + break; + + case HTCLOSE: + /* FIXME */ + break; + + case HTLEFT: + case HTRIGHT: + case HTTOP: + case HTTOPLEFT: + case HTTOPRIGHT: + case HTBOTTOM: + case HTBOTTOMLEFT: + case HTBOTTOMRIGHT: + SendMessageW(hWnd, WM_SYSCOMMAND, SC_SIZE + wParam - (HTLEFT - WMSZ_LEFT), lParam); + break; + + case HTBORDER: + break; + } + return 0; +} + +/* PUBLIC FUNCTIONS ***********************************************************/ + +/* + * @implemented + */ +WINBOOL STDCALL +AdjustWindowRectEx(LPRECT lpRect, + DWORD dwStyle, + WINBOOL bMenu, + DWORD dwExStyle) +{ + SIZE BorderSize; + + if (bMenu) + { + lpRect->top -= GetSystemMetrics(SM_CYMENU); + } + if ((dwStyle & WS_CAPTION) == WS_CAPTION) + { + if (dwExStyle & WS_EX_TOOLWINDOW) + lpRect->top -= GetSystemMetrics(SM_CYSMCAPTION); + else + lpRect->top -= GetSystemMetrics(SM_CYCAPTION); + } + UserGetWindowBorders(dwStyle, dwExStyle, &BorderSize, TRUE); + InflateRect( + lpRect, + BorderSize.cx, + BorderSize.cy); + + return TRUE; +} + + +/* + * @implemented + */ +WINBOOL STDCALL +AdjustWindowRect(LPRECT lpRect, + DWORD dwStyle, + WINBOOL bMenu) +{ + return AdjustWindowRectEx(lpRect, dwStyle, bMenu, 0); +} + +// 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 + */ +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 + + // If DC_GRADIENT is specified, a Win 98/2000 style caption gradient should + // be painted. For now, that flag is ignored: + // Windows 98/Me, Windows 2000/XP: When this flag is set, the function uses + // COLOR_GRADIENTACTIVECAPTION (if the DC_ACTIVE flag was set) or + // COLOR_GRADIENTINACTIVECAPTION for the title-bar color. + + // 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 + { + // DC_GRADIENT check should go here somewhere + 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; + } + + 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); + + if ((uFlags & DC_ICON) && (Style & WS_SYSMENU)) + { + // 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]) ))) + { + // Duplicate odd behaviour from Windows: + if ((! uFlags & DC_SMALLCAP) || (uFlags & DC_ICON) || (uFlags & DC_INBUTTON) || + (! uFlags & DC_ACTIVE)) + r.left += GetSystemMetrics(SM_CXSIZE) + Padding; + + r.right = (lprc->right - lprc->left); + ButtonWidth = GetSystemMetrics(SM_CXSIZE) - 2; + + if (Style & WS_SYSMENU) + { + r.right -= 3 + ButtonWidth; + if (! (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW)) + { + 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 (Style & WS_EX_TOOLWINDOW) +// if (uFlags & DC_SMALLCAP) // incorrect + 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; +} + diff --git a/reactos/lib/user32/windows/window.c b/reactos/lib/user32/windows/window.c index 05689f41281..4c3c0561128 100644 --- a/reactos/lib/user32/windows/window.c +++ b/reactos/lib/user32/windows/window.c @@ -1,4 +1,4 @@ -/* $Id: window.c,v 1.74 2003/10/19 19:51:48 navaraf Exp $ +/* $Id: window.c,v 1.75 2003/10/25 22:57:34 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -24,12 +24,6 @@ static BOOL ControlsInitCalled = FALSE; /* FUNCTIONS *****************************************************************/ -ULONG -WinHasThickFrameStyle(ULONG Style, ULONG ExStyle) -{ - return((Style & WS_THICKFRAME) && - (!((Style & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME))); -} NTSTATUS STDCALL @@ -275,95 +269,6 @@ User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength) } -static void NC_AdjustRectOuter95 (LPRECT rect, DWORD style, BOOL menu, DWORD exStyle) -{ - int adjust; - if(style & WS_ICONIC) return; - - if ((exStyle & (WS_EX_STATICEDGE|WS_EX_DLGMODALFRAME)) == - WS_EX_STATICEDGE) - { - adjust = 1; /* for the outer frame always present */ - } - else - { - adjust = 0; - if ((exStyle & WS_EX_DLGMODALFRAME) || - (style & (WS_THICKFRAME|WS_DLGFRAME))) adjust = 2; /* outer */ - } - if (style & WS_THICKFRAME) - adjust += ( GetSystemMetrics (SM_CXFRAME) - - GetSystemMetrics (SM_CXDLGFRAME)); /* The resize border */ - if ((style & (WS_BORDER|WS_DLGFRAME)) || - (exStyle & WS_EX_DLGMODALFRAME)) - adjust++; /* The other border */ - - InflateRect (rect, adjust, adjust); - - if ((style & WS_CAPTION) == WS_CAPTION) - { - if (exStyle & WS_EX_TOOLWINDOW) - rect->top -= GetSystemMetrics(SM_CYSMCAPTION); - else - rect->top -= GetSystemMetrics(SM_CYCAPTION); - } - if (menu) rect->top -= GetSystemMetrics(SM_CYMENU); -} - - -static void -NC_AdjustRectInner95 (LPRECT rect, DWORD style, DWORD exStyle) -{ - if(style & WS_ICONIC) return; - - if (exStyle & WS_EX_CLIENTEDGE) - InflateRect(rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)); - - if (style & WS_VSCROLL) - { - if((exStyle & WS_EX_LEFTSCROLLBAR) != 0) - rect->left -= GetSystemMetrics(SM_CXVSCROLL); - else - rect->right += GetSystemMetrics(SM_CXVSCROLL); - } - if (style & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL); -} - - -/* - * @implemented - */ -WINBOOL STDCALL -AdjustWindowRectEx(LPRECT lpRect, - DWORD dwStyle, - WINBOOL bMenu, - DWORD dwExStyle) -{ - dwStyle &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD); - dwExStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | - WS_EX_STATICEDGE | WS_EX_TOOLWINDOW); - if (dwExStyle & WS_EX_DLGMODALFRAME) dwStyle &= ~WS_THICKFRAME; - - NC_AdjustRectOuter95( lpRect, dwStyle, bMenu, dwExStyle ); - NC_AdjustRectInner95( lpRect, dwStyle, dwExStyle ); - lpRect->right += 2; - lpRect->bottom += 2; - return TRUE; -} - - -/* - * @implemented - */ -WINBOOL STDCALL -AdjustWindowRect(LPRECT lpRect, - DWORD dwStyle, - WINBOOL bMenu) -{ - return(AdjustWindowRectEx(lpRect, dwStyle, bMenu, 0)); -} - - /* * @unimplemented */ @@ -497,6 +402,11 @@ CreateWindowExA(DWORD dwExStyle, ControlsInitCalled = TRUE; } + if ((dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD && !hWndParent) + { + return (HWND)0; /* WS_CHILD needs a parent, but WS_POPUP doesn't */ + } + if (IS_ATOM(lpClassName)) { RtlInitUnicodeString(&ClassName, NULL); @@ -639,6 +549,11 @@ CreateWindowExW(DWORD dwExStyle, ControlsInitCalled = TRUE; } + if ((dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD && !hWndParent) + { + return (HWND)0; /* WS_CHILD needs a parent, but WS_POPUP doesn't */ + } + if (IS_ATOM(lpClassName)) { RtlInitUnicodeString(&ClassName, NULL); diff --git a/reactos/subsys/win32k/include/window.h b/reactos/subsys/win32k/include/window.h index 32ce76f4874..370e110c01b 100644 --- a/reactos/subsys/win32k/include/window.h +++ b/reactos/subsys/win32k/include/window.h @@ -51,7 +51,7 @@ typedef struct _WINDOW_OBJECT /* Entry in the thread's list of windows. */ LIST_ENTRY ListEntry; /* Pointer to the extra data associated with the window. */ - PULONG ExtraData; + PCHAR ExtraData; /* Size of the extra data associated with the window. */ ULONG ExtraDataSize; /* Position of the window. */ diff --git a/reactos/subsys/win32k/ntuser/scrollbar.c b/reactos/subsys/win32k/ntuser/scrollbar.c index d692fbb1582..2bfe5a43ed5 100644 --- a/reactos/subsys/win32k/ntuser/scrollbar.c +++ b/reactos/subsys/win32k/ntuser/scrollbar.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: scrollbar.c,v 1.17 2003/10/06 17:25:16 weiden Exp $ +/* $Id: scrollbar.c,v 1.18 2003/10/25 22:57:34 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -868,6 +868,8 @@ NtUserShowScrollBar(HWND hWnd, int wBar, DWORD bShow) return FALSE; /* Nothing to do! */ } + IntReleaseWindowObject(Window); + if (fShowH || fShowV) /* frame has been changed, let the window redraw itself */ { WinPosSetWindowPos (hWnd, 0, 0, 0, 0, 0, diff --git a/reactos/subsys/win32k/ntuser/window.c b/reactos/subsys/win32k/ntuser/window.c index 8559e041f1d..32ad07c3538 100644 --- a/reactos/subsys/win32k/ntuser/window.c +++ b/reactos/subsys/win32k/ntuser/window.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: window.c,v 1.118 2003/10/23 09:07:54 gvg Exp $ +/* $Id: window.c,v 1.119 2003/10/25 22:57:34 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -1340,7 +1340,7 @@ NtUserCreateWindowEx(DWORD dwExStyle, /* extra window data */ if (ClassObject->cbWndExtra != 0) { - WindowObject->ExtraData = (PULONG)(WindowObject + 1); + WindowObject->ExtraData = (PCHAR)(WindowObject + 1); WindowObject->ExtraDataSize = ClassObject->cbWndExtra; RtlZeroMemory(WindowObject->ExtraData, WindowObject->ExtraDataSize); } @@ -2242,13 +2242,14 @@ NtUserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi) if (0 <= (int) Index) { - if (WindowObject->ExtraDataSize - sizeof(LONG) < Index || - 0 != Index % sizeof(LONG)) + DbgPrint("GetWindowLong(%x, %d)\n", hWnd, Index); + if (Index > WindowObject->ExtraDataSize - sizeof(LONG)) { SetLastWin32Error(ERROR_INVALID_PARAMETER); return 0; } - Result = WindowObject->ExtraData[Index / sizeof(LONG)]; + Result = *((LONG *)(WindowObject->ExtraData + Index)); + DbgPrint("Result: %x\n", Result); } else { @@ -2939,14 +2940,15 @@ NtUserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi) if (0 <= (int) Index) { - if (WindowObject->ExtraDataSize - sizeof(LONG) < Index || - 0 != Index % sizeof(LONG)) + DbgPrint("SetWindowLong(%x, %d, %x)\n", hWnd, Index, NewValue); + if (Index > WindowObject->ExtraDataSize - sizeof(LONG)) { SetLastWin32Error(ERROR_INVALID_PARAMETER); return 0; } - OldValue = WindowObject->ExtraData[Index / sizeof(LONG)]; - WindowObject->ExtraData[Index / sizeof(LONG)] = NewValue; + OldValue = *((LONG *)(WindowObject->ExtraData + Index)); + *((LONG *)(WindowObject->ExtraData + Index)) = NewValue; + DbgPrint("OldValue: %x\n", OldValue); } else {