* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Win32k subsystem
* PURPOSE: Miscellaneous User functions
- * FILE: subsystems/win32/win32k/ntuser/defwnd.c
+ * FILE: win32ss/user/ntuser/defwnd.c
* PROGRAMER:
*/
#include <win32k.h>
-DBG_DEFAULT_CHANNEL(UserDefwnd);
-
-// Client Shutdown messages
-#define MCS_SHUTDOWNTIMERS 1
-#define MCS_QUERYENDSESSION 2
-// Client Shutdown returns
-#define MCSR_GOODFORSHUTDOWN 1
-#define MCSR_SHUTDOWNFINISHED 2
-#define MCSR_DONOTSHUTDOWN 3
-
-/*
- * Based on CSRSS and described in pages 1115 - 1118 "Windows Internals, Fifth Edition".
- * Apparently CSRSS sends out messages to do this w/o going into win32k internals.
- */
-static
-LRESULT FASTCALL
-IntClientShutdown(
- PWND pWindow,
- WPARAM wParam,
- LPARAM lParam
-)
-{
- LPARAM lParams;
- BOOL KillTimers;
- INT i;
- LRESULT lResult = MCSR_GOODFORSHUTDOWN;
- HWND *List;
-
- lParams = wParam & (ENDSESSION_LOGOFF|ENDSESSION_CRITICAL|ENDSESSION_CLOSEAPP);
- KillTimers = wParam & MCS_SHUTDOWNTIMERS ? TRUE : FALSE;
-/*
- First, send end sessions to children.
- */
- List = IntWinListChildren(pWindow);
-
- if (List)
- {
- for (i = 0; List[i]; i++)
- {
- PWND WndChild;
+#include <windowsx.h>
- if (!(WndChild = UserGetWindowObject(List[i])))
- continue;
+DBG_DEFAULT_CHANNEL(UserDefwnd);
- if (wParam & MCS_QUERYENDSESSION)
- {
- if (!co_IntSendMessage(WndChild->head.h, WM_QUERYENDSESSION, 0, lParams))
- {
- lResult = MCSR_DONOTSHUTDOWN;
- break;
- }
- }
- else
- {
- co_IntSendMessage(WndChild->head.h, WM_ENDSESSION, KillTimers, lParams);
- if (KillTimers)
- {
- DestroyTimersForWindow(WndChild->head.pti, WndChild);
- }
- lResult = MCSR_SHUTDOWNFINISHED;
- }
- }
- ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
- }
- if (List && (lResult == MCSR_DONOTSHUTDOWN)) return lResult;
-/*
- Send to the caller.
- */
- if (wParam & MCS_QUERYENDSESSION)
- {
- if (!co_IntSendMessage(pWindow->head.h, WM_QUERYENDSESSION, 0, lParams))
- {
- lResult = MCSR_DONOTSHUTDOWN;
- }
- }
- else
- {
- co_IntSendMessage(pWindow->head.h, WM_ENDSESSION, KillTimers, lParams);
- if (KillTimers)
- {
- DestroyTimersForWindow(pWindow->head.pti, pWindow);
- }
- lResult = MCSR_SHUTDOWNFINISHED;
- }
- return lResult;
-}
HBRUSH FASTCALL
DefWndControlColor(HDC hDC, UINT ctlType)
return IntGetSysColorBrush(COLOR_WINDOW);
}
+LRESULT FASTCALL
+DefWndHandleWindowPosChanging(PWND pWnd, WINDOWPOS* Pos)
+{
+ POINT maxTrack, minTrack;
+ LONG style = pWnd->style;
+
+ if (Pos->flags & SWP_NOSIZE) return 0;
+ if ((style & WS_THICKFRAME) || ((style & (WS_POPUP | WS_CHILD)) == 0))
+ {
+ co_WinPosGetMinMaxInfo(pWnd, NULL, NULL, &minTrack, &maxTrack);
+ Pos->cx = min(Pos->cx, maxTrack.x);
+ Pos->cy = min(Pos->cy, maxTrack.y);
+ if (!(style & WS_MINIMIZE))
+ {
+ if (Pos->cx < minTrack.x) Pos->cx = minTrack.x;
+ if (Pos->cy < minTrack.y) Pos->cy = minTrack.y;
+ }
+ }
+ else
+ {
+ Pos->cx = max(Pos->cx, 0);
+ Pos->cy = max(Pos->cy, 0);
+ }
+ return 0;
+}
+LRESULT FASTCALL
+DefWndHandleWindowPosChanged(PWND pWnd, WINDOWPOS* Pos)
+{
+ RECT Rect;
+ LONG style = pWnd->style;
+
+ IntGetClientRect(pWnd, &Rect);
+ IntMapWindowPoints(pWnd, (style & WS_CHILD ? IntGetParent(pWnd) : NULL), (LPPOINT) &Rect, 2);
+
+ if (!(Pos->flags & SWP_NOCLIENTMOVE))
+ {
+ co_IntSendMessage(UserHMGetHandle(pWnd), WM_MOVE, 0, MAKELONG(Rect.left, Rect.top));
+ }
+
+ if (!(Pos->flags & SWP_NOCLIENTSIZE) || (Pos->flags & SWP_STATECHANGED))
+ {
+ if (style & WS_MINIMIZE) co_IntSendMessage(UserHMGetHandle(pWnd), WM_SIZE, SIZE_MINIMIZED, 0 );
+ else
+ {
+ WPARAM wp = (style & WS_MAXIMIZE) ? SIZE_MAXIMIZED : SIZE_RESTORED;
+ co_IntSendMessage(UserHMGetHandle(pWnd), WM_SIZE, wp, MAKELONG(Rect.right - Rect.left, Rect.bottom - Rect.top));
+ }
+ }
+ return 0;
+}
+
+//
+// Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
+//
LRESULT FASTCALL
DefWndHandleSysCommand(PWND pWnd, WPARAM wParam, LPARAM lParam)
{
switch (wParam & 0xfff0)
{
+ case SC_MOVE:
+ case SC_SIZE:
+ DefWndDoSizeMove(pWnd, wParam);
+ break;
+
+ case SC_MINIMIZE:
+ if (UserHMGetHandle(pWnd) == UserGetActiveWindow())
+ IntShowOwnedPopups(pWnd,FALSE); // This is done in ShowWindow! Need to retest!
+ co_WinPosShowWindow( pWnd, SW_MINIMIZE );
+ break;
+
+ case SC_MAXIMIZE:
+ if (((pWnd->style & WS_MINIMIZE) != 0) && UserHMGetHandle(pWnd) == UserGetActiveWindow())
+ IntShowOwnedPopups(pWnd,TRUE);
+ co_WinPosShowWindow( pWnd, SW_MAXIMIZE );
+ break;
+
+ case SC_RESTORE:
+ if (((pWnd->style & WS_MINIMIZE) != 0) && UserHMGetHandle(pWnd) == UserGetActiveWindow())
+ IntShowOwnedPopups(pWnd,TRUE);
+ co_WinPosShowWindow( pWnd, SW_RESTORE );
+ break;
+
+ case SC_CLOSE:
+ return co_IntSendMessage(UserHMGetHandle(pWnd), WM_CLOSE, 0, 0);
+
case SC_SCREENSAVE:
ERR("Screensaver Called!\n");
UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_START_SCREENSAVE, 0); // always lParam 0 == not Secure
break;
+ case SC_HOTKEY:
+ {
+ USER_REFERENCE_ENTRY Ref;
+
+ pWnd = ValidateHwndNoErr((HWND)lParam);
+ if (pWnd)
+ {
+ if (pWnd->spwndLastActive)
+ {
+ pWnd = pWnd->spwndLastActive;
+ }
+ UserRefObjectCo(pWnd, &Ref);
+ co_IntSetForegroundWindow(pWnd);
+ UserDerefObjectCo(pWnd);
+ if (pWnd->style & WS_MINIMIZE)
+ {
+ UserPostMessage(UserHMGetHandle(pWnd), WM_SYSCOMMAND, SC_RESTORE, 0);
+ }
+ }
+ }
+ break;
+
+
default:
// We do not support anything else here so we should return normal even when sending a hook.
return 0;
return(Hook ? 1 : 0); // Don't call us again from user space.
}
+PWND FASTCALL
+co_IntFindChildWindowToOwner(PWND Root, PWND Owner)
+{
+ PWND Ret;
+ PWND Child, OwnerWnd;
+
+ for(Child = Root->spwndChild; Child; Child = Child->spwndNext)
+ {
+ OwnerWnd = Child->spwndOwner;
+ if(!OwnerWnd)
+ continue;
+
+ if (!(Child->style & WS_POPUP) ||
+ !(Child->style & WS_VISIBLE) ||
+ /* Fixes CMD pop up properties window from having foreground. */
+ Owner->head.pti->MessageQueue != Child->head.pti->MessageQueue)
+ continue;
+
+ if(OwnerWnd == Owner)
+ {
+ Ret = Child;
+ return Ret;
+ }
+ }
+ return NULL;
+}
+
+LRESULT
+DefWndHandleSetCursor(PWND pWnd, WPARAM wParam, LPARAM lParam)
+{
+ PWND pwndPopUP = NULL;
+ WORD Msg = HIWORD(lParam);
+
+ /* Not for child windows. */
+ if (UserHMGetHandle(pWnd) != (HWND)wParam)
+ {
+ return FALSE;
+ }
+
+ switch((short)LOWORD(lParam))
+ {
+ case HTERROR:
+ {
+ //// This is the real fix for CORE-6129! This was a "Code hole".
+ USER_REFERENCE_ENTRY Ref;
+
+ if (Msg == WM_LBUTTONDOWN)
+ {
+ // Find a pop up window to bring active.
+ pwndPopUP = co_IntFindChildWindowToOwner(UserGetDesktopWindow(), pWnd);
+ if (pwndPopUP)
+ {
+ // Not a child pop up from desktop.
+ if ( pwndPopUP != UserGetDesktopWindow()->spwndChild )
+ {
+ // Get original active window.
+ PWND pwndOrigActive = gpqForeground->spwndActive;
+
+ co_WinPosSetWindowPos(pWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+
+ UserRefObjectCo(pwndPopUP, &Ref);
+ //UserSetActiveWindow(pwndPopUP);
+ co_IntSetForegroundWindow(pwndPopUP); // HACK
+ UserDerefObjectCo(pwndPopUP);
+
+ // If the change was made, break out.
+ if (pwndOrigActive != gpqForeground->spwndActive)
+ break;
+ }
+ }
+ }
+ ////
+ if (Msg == WM_LBUTTONDOWN || Msg == WM_MBUTTONDOWN ||
+ Msg == WM_RBUTTONDOWN || Msg == WM_XBUTTONDOWN)
+ {
+ if (pwndPopUP)
+ {
+ FLASHWINFO fwi =
+ {sizeof(FLASHWINFO),
+ UserHMGetHandle(pwndPopUP),
+ FLASHW_ALL,
+ gspv.dwForegroundFlashCount,
+ (gpsi->dtCaretBlink >> 3)};
+
+ // Now shake that window!
+ IntFlashWindowEx(pwndPopUP, &fwi);
+ }
+ UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_MESSAGE_BEEP, 0);
+ }
+ break;
+ }
+
+ case HTCLIENT:
+ {
+ if (pWnd->pcls->spcur)
+ {
+ UserSetCursor(pWnd->pcls->spcur, FALSE);
+ }
+ return FALSE;
+ }
+
+ case HTLEFT:
+ case HTRIGHT:
+ {
+ if (pWnd->style & WS_MAXIMIZE)
+ {
+ break;
+ }
+ UserSetCursor(SYSTEMCUR(SIZEWE), FALSE);
+ return TRUE;
+ }
+
+ case HTTOP:
+ case HTBOTTOM:
+ {
+ if (pWnd->style & WS_MAXIMIZE)
+ {
+ break;
+ }
+ UserSetCursor(SYSTEMCUR(SIZENS), FALSE);
+ return TRUE;
+ }
+
+ case HTTOPLEFT:
+ case HTBOTTOMRIGHT:
+ {
+ if (pWnd->style & WS_MAXIMIZE)
+ {
+ break;
+ }
+ UserSetCursor(SYSTEMCUR(SIZENWSE), FALSE);
+ return TRUE;
+ }
+
+ case HTBOTTOMLEFT:
+ case HTTOPRIGHT:
+ {
+ if (pWnd->style & WS_MAXIMIZE)
+ {
+ break;
+ }
+ UserSetCursor(SYSTEMCUR(SIZENESW), FALSE);
+ return TRUE;
+ }
+ }
+ UserSetCursor(SYSTEMCUR(ARROW), FALSE);
+ return FALSE;
+}
+
+VOID FASTCALL DefWndPrint( PWND pwnd, HDC hdc, ULONG uFlags)
+{
+ /*
+ * Visibility flag.
+ */
+ if ( (uFlags & PRF_CHECKVISIBLE) &&
+ !IntIsWindowVisible(pwnd) )
+ return;
+
+ /*
+ * Unimplemented flags.
+ */
+ if ( (uFlags & PRF_CHILDREN) ||
+ (uFlags & PRF_OWNED) ||
+ (uFlags & PRF_NONCLIENT) )
+ {
+ FIXME("WM_PRINT message with unsupported flags\n");
+ }
+
+ /*
+ * Background
+ */
+ if ( uFlags & PRF_ERASEBKGND)
+ co_IntSendMessage(UserHMGetHandle(pwnd), WM_ERASEBKGND, (WPARAM)hdc, 0);
+
+ /*
+ * Client area
+ */
+ if ( uFlags & PRF_CLIENT)
+ co_IntSendMessage(UserHMGetHandle(pwnd), WM_PRINTCLIENT, (WPARAM)hdc, uFlags);
+}
+
+
/*
Win32k counterpart of User DefWindowProc
*/
}
}
break;
+
case WM_CLIENTSHUTDOWN:
return IntClientShutdown(Wnd, wParam, lParam);
UserDerefObjectCo(Wnd->spwndParent);
break;
+ case WM_CLOSE:
+ co_UserDestroyWindow(Wnd);
+ break;
+
case WM_CTLCOLORMSGBOX:
case WM_CTLCOLOREDIT:
case WM_CTLCOLORLISTBOX:
case WM_CTLCOLOR:
return (LRESULT) DefWndControlColor((HDC)wParam, HIWORD(lParam));
+ case WM_SETCURSOR:
+ {
+ if (Wnd->style & WS_CHILD)
+ {
+ /* with the exception of the border around a resizable wnd,
+ * give the parent first chance to set the cursor */
+ if (LOWORD(lParam) < HTLEFT || LOWORD(lParam) > HTBOTTOMRIGHT)
+ {
+ PWND parent = Wnd->spwndParent;//IntGetParent( Wnd );
+ if (parent != UserGetDesktopWindow() &&
+ co_IntSendMessage( UserHMGetHandle(parent), WM_SETCURSOR, wParam, lParam))
+ return TRUE;
+ }
+ }
+ return DefWndHandleSetCursor(Wnd, wParam, lParam);
+ }
+
+ case WM_ACTIVATE:
+ /* The default action in Windows is to set the keyboard focus to
+ * the window, if it's being activated and not minimized */
+ if (LOWORD(wParam) != WA_INACTIVE &&
+ !(Wnd->style & WS_MINIMIZE))
+ {
+ //ERR("WM_ACTIVATE %p\n",hWnd);
+ co_UserSetFocus(Wnd);
+ }
+ break;
+
+ case WM_MOUSEWHEEL:
+ if (Wnd->style & WS_CHILD)
+ {
+ HWND hwndParent;
+ PWND pwndParent = IntGetParent(Wnd);
+ hwndParent = pwndParent ? UserHMGetHandle(pwndParent) : NULL;
+ return co_IntSendMessage( hwndParent, WM_MOUSEWHEEL, wParam, lParam);
+ }
+ break;
+
+ case WM_ERASEBKGND:
+ case WM_ICONERASEBKGND:
+ {
+ RECT Rect;
+ HBRUSH hBrush = Wnd->pcls->hbrBackground;
+ if (!hBrush) return 0;
+ if (hBrush <= (HBRUSH)COLOR_MENUBAR)
+ {
+ hBrush = IntGetSysColorBrush((INT)hBrush);
+ }
+ if (Wnd->pcls->style & CS_PARENTDC)
+ {
+ /* can't use GetClipBox with a parent DC or we fill the whole parent */
+ IntGetClientRect(Wnd, &Rect);
+ GreDPtoLP((HDC)wParam, (LPPOINT)&Rect, 2);
+ }
+ else
+ {
+ GdiGetClipBox((HDC)wParam, &Rect);
+ }
+ FillRect((HDC)wParam, &Rect, hBrush);
+ return (1);
+ }
+
case WM_GETHOTKEY:
- return DefWndGetHotKey(UserHMGetHandle(Wnd));
+ //ERR("WM_GETHOTKEY\n");
+ return DefWndGetHotKey(Wnd);
case WM_SETHOTKEY:
+ //ERR("WM_SETHOTKEY\n");
return DefWndSetHotKey(Wnd, wParam);
case WM_NCHITTEST:
return GetNCHitEx(Wnd, Point);
}
+ case WM_PRINT:
+ {
+ DefWndPrint(Wnd, (HDC)wParam, lParam);
+ return (0);
+ }
+
+ case WM_PAINTICON:
+ case WM_PAINT:
+ {
+ PAINTSTRUCT Ps;
+ HDC hDC;
+
+ /* If already in Paint and Client area is not empty just return. */
+ if (Wnd->state2 & WNDS2_STARTPAINT && !RECTL_bIsEmptyRect(&Wnd->rcClient))
+ {
+ ERR("In Paint and Client area is not empty!\n");
+ return 0;
+ }
+
+ hDC = IntBeginPaint(Wnd, &Ps);
+ if (hDC)
+ {
+ if (((Wnd->style & WS_MINIMIZE) != 0) && (Wnd->pcls->spicn))
+ {
+ RECT ClientRect;
+ INT x, y;
+
+ ERR("Doing Paint and Client area is empty!\n");
+ IntGetClientRect(Wnd, &ClientRect);
+ x = (ClientRect.right - ClientRect.left - UserGetSystemMetrics(SM_CXICON)) / 2;
+ y = (ClientRect.bottom - ClientRect.top - UserGetSystemMetrics(SM_CYICON)) / 2;
+ UserDrawIconEx(hDC, x, y, Wnd->pcls->spicn, 0, 0, 0, 0, DI_NORMAL | DI_COMPAT | DI_DEFAULTSIZE);
+ }
+
+ IntEndPaint(Wnd, &Ps);
+ }
+ return (0);
+ }
+
case WM_SYNCPAINT:
{
HRGN hRgn;
Wnd->state &= ~WNDS_SYNCPAINTPENDING;
- ERR("WM_SYNCPAINT\n");
- hRgn = IntSysCreateRectRgn(0, 0, 0, 0);
- if (co_UserGetUpdateRgn(Wnd, hRgn, FALSE) != NULLREGION)
+ TRACE("WM_SYNCPAINT\n");
+ hRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
+ if (hRgn)
{
- if (!wParam) wParam = (RDW_ERASENOW | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN);
- co_UserRedrawWindow(Wnd, NULL, hRgn, wParam);
+ if (co_UserGetUpdateRgn(Wnd, hRgn, FALSE) != NULLREGION)
+ {
+ PREGION pRgn = REGION_LockRgn(hRgn);
+ if (pRgn) REGION_UnlockRgn(pRgn);
+ if (!wParam)
+ wParam = (RDW_ERASENOW | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN);
+ co_UserRedrawWindow(Wnd, NULL, pRgn, wParam);
+ }
+ GreDeleteObject(hRgn);
}
- GreDeleteObject(hRgn);
return 0;
}
case WM_SETREDRAW:
+ ERR("WM_SETREDRAW\n");
if (wParam)
{
if (!(Wnd->style & WS_VISIBLE))
}
return 0;
+ case WM_WINDOWPOSCHANGING:
+ {
+ return (DefWndHandleWindowPosChanging(Wnd, (WINDOWPOS*)lParam));
+ }
+
+ case WM_WINDOWPOSCHANGED:
+ {
+ return (DefWndHandleWindowPosChanged(Wnd, (WINDOWPOS*)lParam));
+ }
+
/* ReactOS only. */
case WM_CBT:
{
return lResult;
}
-HICON FASTCALL NC_IconForWindow( PWND pWnd )
-{
- HICON hIcon = 0;
- // First thing to do, init the Window Logo icons.
- if (!gpsi->hIconSmWindows) co_IntSetWndIcons();
-
- if (!hIcon) hIcon = UserGetProp(pWnd, gpsi->atomIconSmProp);
- if (!hIcon) hIcon = UserGetProp(pWnd, gpsi->atomIconProp);
- if (!hIcon) hIcon = pWnd->pcls->hIconSm;
- if (!hIcon) hIcon = pWnd->pcls->hIcon;
-
- if (!hIcon && pWnd->style & DS_MODALFRAME)
- {
- if (!hIcon) hIcon = gpsi->hIconSmWindows; // Both are IDI_WINLOGO Small
- if (!hIcon) hIcon = gpsi->hIconWindows; // Reg size.
- hIcon = (HICON)1;
- }
- return hIcon;
-}
-
-DWORD FASTCALL
-GetNCHitEx(PWND pWnd, POINT pt)
-{
- RECT rcWindow, rcClient;
- DWORD Style, ExStyle;
-
- if (!pWnd) return HTNOWHERE;
-
- if (pWnd == UserGetDesktopWindow()) // pWnd->fnid == FNID_DESKTOP)
- {
- rcClient.left = rcClient.top = rcWindow.left = rcWindow.top = 0;
- rcWindow.right = UserGetSystemMetrics(SM_CXSCREEN);
- rcWindow.bottom = UserGetSystemMetrics(SM_CYSCREEN);
- rcClient.right = UserGetSystemMetrics(SM_CXSCREEN);
- rcClient.bottom = UserGetSystemMetrics(SM_CYSCREEN);
- }
- else
- {
- rcClient = pWnd->rcClient;
- rcWindow = pWnd->rcWindow;
- }
-
- if (!RECTL_bPointInRect(&rcWindow, pt.x, pt.y)) return HTNOWHERE;
-
- Style = pWnd->style;
- ExStyle = pWnd->ExStyle;
-
- if (Style & WS_MINIMIZE) return HTCAPTION;
-
- if (RECTL_bPointInRect( &rcClient, pt.x, pt.y )) return HTCLIENT;
-
- /* Check borders */
- if (HAS_THICKFRAME( Style, ExStyle ))
- {
- RECTL_vInflateRect(&rcWindow, -UserGetSystemMetrics(SM_CXFRAME), -UserGetSystemMetrics(SM_CYFRAME) );
- if (!RECTL_bPointInRect(&rcWindow, pt.x, pt.y ))
- {
- /* Check top sizing border */
- if (pt.y < rcWindow.top)
- {
- if (pt.x < rcWindow.left+UserGetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
- if (pt.x >= rcWindow.right-UserGetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
- return HTTOP;
- }
- /* Check bottom sizing border */
- if (pt.y >= rcWindow.bottom)
- {
- if (pt.x < rcWindow.left+UserGetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
- if (pt.x >= rcWindow.right-UserGetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
- return HTBOTTOM;
- }
- /* Check left sizing border */
- if (pt.x < rcWindow.left)
- {
- if (pt.y < rcWindow.top+UserGetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
- if (pt.y >= rcWindow.bottom-UserGetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
- return HTLEFT;
- }
- /* Check right sizing border */
- if (pt.x >= rcWindow.right)
- {
- if (pt.y < rcWindow.top+UserGetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
- if (pt.y >= rcWindow.bottom-UserGetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
- return HTRIGHT;
- }
- }
- }
- else /* No thick frame */
- {
- if (HAS_DLGFRAME( Style, ExStyle ))
- RECTL_vInflateRect(&rcWindow, -UserGetSystemMetrics(SM_CXDLGFRAME), -UserGetSystemMetrics(SM_CYDLGFRAME));
- else if (HAS_THINFRAME( Style, ExStyle ))
- RECTL_vInflateRect(&rcWindow, -UserGetSystemMetrics(SM_CXBORDER), -UserGetSystemMetrics(SM_CYBORDER));
- if (!RECTL_bPointInRect( &rcWindow, pt.x, pt.y )) return HTBORDER;
- }
-
- /* Check caption */
-
- if ((Style & WS_CAPTION) == WS_CAPTION)
- {
- if (ExStyle & WS_EX_TOOLWINDOW)
- rcWindow.top += UserGetSystemMetrics(SM_CYSMCAPTION) - 1;
- else
- rcWindow.top += UserGetSystemMetrics(SM_CYCAPTION) - 1;
- if (!RECTL_bPointInRect( &rcWindow, pt.x, pt.y ))
- {
- BOOL min_or_max_box = (Style & WS_SYSMENU) && (Style & (WS_MINIMIZEBOX|WS_MAXIMIZEBOX));
- if (ExStyle & WS_EX_LAYOUTRTL)
- {
- /* Check system menu */
- if ((Style & WS_SYSMENU) && !(ExStyle & WS_EX_TOOLWINDOW) && NC_IconForWindow(pWnd))
- {
- rcWindow.right -= UserGetSystemMetrics(SM_CYCAPTION) - 1;
- if (pt.x > rcWindow.right) return HTSYSMENU;
- }
-
- /* Check close button */
- if (Style & WS_SYSMENU)
- {
- rcWindow.left += UserGetSystemMetrics(SM_CYCAPTION);
- if (pt.x < rcWindow.left) return HTCLOSE;
- }
-
- /* Check maximize box */
- /* In Win95 there is automatically a Maximize button when there is a minimize one */
- if (min_or_max_box && !(ExStyle & WS_EX_TOOLWINDOW))
- {
- rcWindow.left += UserGetSystemMetrics(SM_CXSIZE);
- if (pt.x < rcWindow.left) return HTMAXBUTTON;
- }
-
- /* Check minimize box */
- if (min_or_max_box && !(ExStyle & WS_EX_TOOLWINDOW))
- {
- rcWindow.left += UserGetSystemMetrics(SM_CXSIZE);
- if (pt.x < rcWindow.left) return HTMINBUTTON;
- }
- }
- else
- {
- /* Check system menu */
- if ((Style & WS_SYSMENU) && !(ExStyle & WS_EX_TOOLWINDOW) && NC_IconForWindow(pWnd))
- {
- rcWindow.left += UserGetSystemMetrics(SM_CYCAPTION) - 1;
- if (pt.x < rcWindow.left) return HTSYSMENU;
- }
-
- /* Check close button */
- if (Style & WS_SYSMENU)
- {
- rcWindow.right -= UserGetSystemMetrics(SM_CYCAPTION);
- if (pt.x > rcWindow.right) return HTCLOSE;
- }
-
- /* Check maximize box */
- /* In Win95 there is automatically a Maximize button when there is a minimize one */
- if (min_or_max_box && !(ExStyle & WS_EX_TOOLWINDOW))
- {
- rcWindow.right -= UserGetSystemMetrics(SM_CXSIZE);
- if (pt.x > rcWindow.right) return HTMAXBUTTON;
- }
-
- /* Check minimize box */
- if (min_or_max_box && !(ExStyle & WS_EX_TOOLWINDOW))
- {
- rcWindow.right -= UserGetSystemMetrics(SM_CXSIZE);
- if (pt.x > rcWindow.right) return HTMINBUTTON;
- }
- }
- return HTCAPTION;
- }
- }
-
- /* Check menu bar */
-
- if (HAS_MENU( pWnd, Style ) && (pt.y < rcClient.top) &&
- (pt.x >= rcClient.left) && (pt.x < rcClient.right))
- return HTMENU;
-
- /* Check vertical scroll bar */
-
- if (ExStyle & WS_EX_LAYOUTRTL) ExStyle ^= WS_EX_LEFTSCROLLBAR;
- if (Style & WS_VSCROLL)
- {
- if((ExStyle & WS_EX_LEFTSCROLLBAR) != 0)
- rcClient.left -= UserGetSystemMetrics(SM_CXVSCROLL);
- else
- rcClient.right += UserGetSystemMetrics(SM_CXVSCROLL);
- if (RECTL_bPointInRect( &rcClient, pt.x, pt.y )) return HTVSCROLL;
- }
-
- /* Check horizontal scroll bar */
-
- if (Style & WS_HSCROLL)
- {
- rcClient.bottom += UserGetSystemMetrics(SM_CYHSCROLL);
- if (RECTL_bPointInRect( &rcClient, pt.x, pt.y ))
- {
- /* Check size box */
- if ((Style & WS_VSCROLL) &&
- ((((ExStyle & WS_EX_LEFTSCROLLBAR) != 0) && (pt.x <= rcClient.left + UserGetSystemMetrics(SM_CXVSCROLL))) ||
- (((ExStyle & WS_EX_LEFTSCROLLBAR) == 0) && (pt.x >= rcClient.right - UserGetSystemMetrics(SM_CXVSCROLL)))))
- return HTSIZE;
- return HTHSCROLL;
- }
- }
-
- /* Has to return HTNOWHERE if nothing was found
- Could happen when a window has a customized non client area */
- return HTNOWHERE;
-}
-
/* EOF */