2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Win32k subsystem
4 * PURPOSE: Miscellaneous User functions
5 * FILE: subsystems/win32/win32k/ntuser/defwnd.c
13 DBG_DEFAULT_CHANNEL(UserDefwnd
);
15 #define UserHasDlgFrameStyle(Style, ExStyle) \
16 (((ExStyle) & WS_EX_DLGMODALFRAME) || \
17 (((Style) & WS_DLGFRAME) && (!((Style) & WS_THICKFRAME))))
19 #define UserHasThickFrameStyle(Style, ExStyle) \
20 (((Style) & WS_THICKFRAME) && \
21 (!(((Style) & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)))
23 #define UserHasThinFrameStyle(Style, ExStyle) \
24 (((Style) & WS_BORDER) || (!((Style) & (WS_CHILD | WS_POPUP))))
26 #define ON_LEFT_BORDER(hit) \
27 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
28 #define ON_RIGHT_BORDER(hit) \
29 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
30 #define ON_TOP_BORDER(hit) \
31 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
32 #define ON_BOTTOM_BORDER(hit) \
33 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
35 // Client Shutdown messages
36 #define MCS_SHUTDOWNTIMERS 1
37 #define MCS_QUERYENDSESSION 2
38 // Client Shutdown returns
39 #define MCSR_GOODFORSHUTDOWN 1
40 #define MCSR_SHUTDOWNFINISHED 2
41 #define MCSR_DONOTSHUTDOWN 3
44 * Based on CSRSS and described in pages 1115 - 1118 "Windows Internals, Fifth Edition".
45 * Apparently CSRSS sends out messages to do this w/o going into win32k internals.
58 LRESULT lResult
= MCSR_GOODFORSHUTDOWN
;
61 lParams
= wParam
& (ENDSESSION_LOGOFF
|ENDSESSION_CRITICAL
|ENDSESSION_CLOSEAPP
);
62 KillTimers
= wParam
& MCS_SHUTDOWNTIMERS
? TRUE
: FALSE
;
64 First, send end sessions to children.
66 List
= IntWinListChildren(pWindow
);
70 for (i
= 0; List
[i
]; i
++)
74 if (!(WndChild
= UserGetWindowObject(List
[i
])))
77 if (wParam
& MCS_QUERYENDSESSION
)
79 if (!co_IntSendMessage(WndChild
->head
.h
, WM_QUERYENDSESSION
, 0, lParams
))
81 lResult
= MCSR_DONOTSHUTDOWN
;
87 co_IntSendMessage(WndChild
->head
.h
, WM_ENDSESSION
, KillTimers
, lParams
);
90 DestroyTimersForWindow(WndChild
->head
.pti
, WndChild
);
92 lResult
= MCSR_SHUTDOWNFINISHED
;
95 ExFreePoolWithTag(List
, USERTAG_WINDOWLIST
);
97 if (List
&& (lResult
== MCSR_DONOTSHUTDOWN
)) return lResult
;
101 if (wParam
& MCS_QUERYENDSESSION
)
103 if (!co_IntSendMessage(pWindow
->head
.h
, WM_QUERYENDSESSION
, 0, lParams
))
105 lResult
= MCSR_DONOTSHUTDOWN
;
110 co_IntSendMessage(pWindow
->head
.h
, WM_ENDSESSION
, KillTimers
, lParams
);
113 DestroyTimersForWindow(pWindow
->head
.pti
, pWindow
);
115 lResult
= MCSR_SHUTDOWNFINISHED
;
121 DefWndControlColor(HDC hDC
, UINT ctlType
)
123 if (ctlType
== CTLCOLOR_SCROLLBAR
)
125 HBRUSH hb
= IntGetSysColorBrush(COLOR_SCROLLBAR
);
126 COLORREF bk
= IntGetSysColor(COLOR_3DHILIGHT
);
127 IntGdiSetTextColor(hDC
, IntGetSysColor(COLOR_3DFACE
));
128 IntGdiSetBkColor(hDC
, bk
);
130 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
131 * we better use 0x55aa bitmap brush to make scrollbar's background
132 * look different from the window background.
134 if ( bk
== IntGetSysColor(COLOR_WINDOW
))
135 return gpsi
->hbrGray
;
137 NtGdiUnrealizeObject( hb
);
141 IntGdiSetTextColor(hDC
, IntGetSysColor(COLOR_WINDOWTEXT
));
143 if ((ctlType
== CTLCOLOR_EDIT
) || (ctlType
== CTLCOLOR_LISTBOX
))
145 IntGdiSetBkColor(hDC
, IntGetSysColor(COLOR_WINDOW
));
149 IntGdiSetBkColor(hDC
, IntGetSysColor(COLOR_3DFACE
));
150 return IntGetSysColorBrush(COLOR_3DFACE
);
153 return IntGetSysColorBrush(COLOR_WINDOW
);
157 DefWndHandleWindowPosChanging(PWND pWnd
, WINDOWPOS
* Pos
)
159 POINT maxTrack
, minTrack
;
160 LONG style
= pWnd
->style
;
162 if (Pos
->flags
& SWP_NOSIZE
) return 0;
163 if ((style
& WS_THICKFRAME
) || ((style
& (WS_POPUP
| WS_CHILD
)) == 0))
165 co_WinPosGetMinMaxInfo(pWnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
166 Pos
->cx
= min(Pos
->cx
, maxTrack
.x
);
167 Pos
->cy
= min(Pos
->cy
, maxTrack
.y
);
168 if (!(style
& WS_MINIMIZE
))
170 if (Pos
->cx
< minTrack
.x
) Pos
->cx
= minTrack
.x
;
171 if (Pos
->cy
< minTrack
.y
) Pos
->cy
= minTrack
.y
;
176 Pos
->cx
= max(Pos
->cx
, 0);
177 Pos
->cy
= max(Pos
->cy
, 0);
183 DefWndHandleWindowPosChanged(PWND pWnd
, WINDOWPOS
* Pos
)
186 LONG style
= pWnd
->style
;
188 IntGetClientRect(pWnd
, &Rect
);
189 IntMapWindowPoints(pWnd
, (style
& WS_CHILD
? IntGetParent(pWnd
) : NULL
), (LPPOINT
) &Rect
, 2);
191 if (!(Pos
->flags
& SWP_NOCLIENTMOVE
))
193 co_IntSendMessage(UserHMGetHandle(pWnd
), WM_MOVE
, 0, MAKELONG(Rect
.left
, Rect
.top
));
196 if (!(Pos
->flags
& SWP_NOCLIENTSIZE
) || (Pos
->flags
& SWP_STATECHANGED
))
198 if (style
& WS_MINIMIZE
) co_IntSendMessage(UserHMGetHandle(pWnd
), WM_SIZE
, SIZE_MINIMIZED
, 0 );
201 WPARAM wp
= (style
& WS_MAXIMIZE
) ? SIZE_MAXIMIZED
: SIZE_RESTORED
;
202 co_IntSendMessage(UserHMGetHandle(pWnd
), WM_SIZE
, wp
, MAKELONG(Rect
.right
- Rect
.left
, Rect
.bottom
- Rect
.top
));
209 UserDrawWindowFrame(HDC hdc
,
214 HBRUSH hbrush
= NtGdiSelectBrush( hdc
, gpsi
->hbrGray
);
215 NtGdiPatBlt( hdc
, rect
->left
, rect
->top
, rect
->right
- rect
->left
- width
, height
, PATINVERT
);
216 NtGdiPatBlt( hdc
, rect
->left
, rect
->top
+ height
, width
, rect
->bottom
- rect
->top
- height
, PATINVERT
);
217 NtGdiPatBlt( hdc
, rect
->left
+ width
, rect
->bottom
- 1, rect
->right
- rect
->left
- width
, -height
, PATINVERT
);
218 NtGdiPatBlt( hdc
, rect
->right
- 1, rect
->top
, -width
, rect
->bottom
- rect
->top
- height
, PATINVERT
);
219 NtGdiSelectBrush( hdc
, hbrush
);
223 UserDrawMovingFrame(HDC hdc
,
227 if (thickframe
) UserDrawWindowFrame(hdc
, rect
, UserGetSystemMetrics(SM_CXFRAME
), UserGetSystemMetrics(SM_CYFRAME
));
228 else UserDrawWindowFrame(hdc
, rect
, 1, 1);
231 /***********************************************************************
234 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
235 * but without the borders (if any).
238 NC_GetInsideRect(PWND Wnd
, RECT
*rect
)
244 ExStyle
= Wnd
->ExStyle
;
246 rect
->top
= rect
->left
= 0;
247 rect
->right
= Wnd
->rcWindow
.right
- Wnd
->rcWindow
.left
;
248 rect
->bottom
= Wnd
->rcWindow
.bottom
- Wnd
->rcWindow
.top
;
250 if (Style
& WS_ICONIC
) return;
252 /* Remove frame from rectangle */
253 if (UserHasThickFrameStyle(Style
, ExStyle
))
255 RECTL_vInflateRect(rect
, -UserGetSystemMetrics(SM_CXFRAME
), -UserGetSystemMetrics(SM_CYFRAME
));
259 if (UserHasDlgFrameStyle(Style
, ExStyle
))
261 RECTL_vInflateRect(rect
, -UserGetSystemMetrics(SM_CXDLGFRAME
), -UserGetSystemMetrics(SM_CYDLGFRAME
));
262 /* FIXME: this isn't in NC_AdjustRect? why not? */
263 if (ExStyle
& WS_EX_DLGMODALFRAME
)
264 RECTL_vInflateRect( rect
, -1, 0 );
268 if (UserHasThinFrameStyle(Style
, ExStyle
))
270 RECTL_vInflateRect(rect
, -UserGetSystemMetrics(SM_CXBORDER
), -UserGetSystemMetrics(SM_CYBORDER
));
274 /* We have additional border information if the window
275 * is a child (but not an MDI child) */
276 if ((Style
& WS_CHILD
) && !(ExStyle
& WS_EX_MDICHILD
))
278 if (ExStyle
& WS_EX_CLIENTEDGE
)
279 RECTL_vInflateRect (rect
, -UserGetSystemMetrics(SM_CXEDGE
), -UserGetSystemMetrics(SM_CYEDGE
));
280 if (ExStyle
& WS_EX_STATICEDGE
)
281 RECTL_vInflateRect (rect
, -UserGetSystemMetrics(SM_CXBORDER
), -UserGetSystemMetrics(SM_CYBORDER
));
286 DefWndStartSizeMove(PWND Wnd
, WPARAM wParam
, POINT
*capturePoint
)
292 ULONG Style
= Wnd
->style
;
293 PTHREADINFO pti
= PsGetCurrentThreadWin32Thread();
295 rectWindow
= Wnd
->rcWindow
;
297 if ((wParam
& 0xfff0) == SC_MOVE
)
299 /* Move pointer at the center of the caption */
300 RECT rect
= rectWindow
;
301 /* Note: to be exactly centered we should take the different types
302 * of border into account, but it shouldn't make more than a few pixels
303 * of difference so let's not bother with that */
304 if (Style
& WS_SYSMENU
)
305 rect
.left
+= UserGetSystemMetrics(SM_CXSIZE
) + 1;
306 if (Style
& WS_MINIMIZEBOX
)
307 rect
.right
-= UserGetSystemMetrics(SM_CXSIZE
) + 1;
308 if (Style
& WS_MAXIMIZEBOX
)
309 rect
.right
-= UserGetSystemMetrics(SM_CXSIZE
) + 1;
310 pt
.x
= (rect
.right
+ rect
.left
) / 2;
311 pt
.y
= rect
.top
+ UserGetSystemMetrics(SM_CYSIZE
)/2;
320 if (!co_IntGetPeekMessage(&msg
, 0, 0, 0, PM_REMOVE
, TRUE
)) return 0;
321 if (IntCallMsgFilter( &msg
, MSGF_SIZE
)) continue;
326 //// Clamp the mouse position to the window rectangle when starting a window resize.
327 pt
.x
= min( max( msg
.pt
.x
, rectWindow
.left
), rectWindow
.right
- 1 );
328 pt
.y
= min( max( msg
.pt
.y
, rectWindow
.top
), rectWindow
.bottom
- 1 );
329 hittest
= GetNCHitEx(Wnd
, pt
);
330 if ((hittest
< HTLEFT
) || (hittest
> HTBOTTOMRIGHT
)) hittest
= 0;
341 pt
.x
= (rectWindow
.left
+rectWindow
.right
)/2;
342 pt
.y
= rectWindow
.top
+ UserGetSystemMetrics(SM_CYFRAME
) / 2;
346 pt
.x
= (rectWindow
.left
+rectWindow
.right
)/2;
347 pt
.y
= rectWindow
.bottom
- UserGetSystemMetrics(SM_CYFRAME
) / 2;
351 pt
.x
= rectWindow
.left
+ UserGetSystemMetrics(SM_CXFRAME
) / 2;
352 pt
.y
= (rectWindow
.top
+rectWindow
.bottom
)/2;
356 pt
.x
= rectWindow
.right
- UserGetSystemMetrics(SM_CXFRAME
) / 2;
357 pt
.y
= (rectWindow
.top
+rectWindow
.bottom
)/2;
364 IntTranslateKbdMessage( &msg
, 0 );
365 pti
->TIF_flags
|= TIF_MOVESIZETRACKING
;
366 IntDispatchMessage( &msg
);
367 pti
->TIF_flags
|= TIF_MOVESIZETRACKING
;
373 UserSetCursorPos(pt
.x
, pt
.y
, 0, 0, FALSE
);
374 co_IntSendMessage(UserHMGetHandle(Wnd
), WM_SETCURSOR
, (WPARAM
)UserHMGetHandle(Wnd
), MAKELONG(hittest
, WM_MOUSEMOVE
));
379 // System Command Size and Move
381 // Perform SC_MOVE and SC_SIZE commands.
384 DefWndDoSizeMove(PWND pwnd
, WORD wParam
)
387 RECT sizingRect
, mouseRect
, origRect
, unmodRect
;
389 LONG hittest
= (LONG
)(wParam
& 0x0f);
390 #ifdef NEW_CURSORICON
391 PCURICON_OBJECT DragCursor
= NULL
, OldCursor
= NULL
;
393 HCURSOR hDragCursor
= 0, hOldCursor
= 0;
395 POINT minTrack
, maxTrack
;
396 POINT capturePoint
, pt
;
397 ULONG Style
, ExStyle
;
401 BOOL DragFullWindows
= FALSE
;
402 PWND pWndParent
= NULL
;
403 WPARAM syscommand
= (wParam
& 0xfff0);
404 PTHREADINFO pti
= PsGetCurrentThreadWin32Thread();
405 //PMONITOR mon = 0; Don't port sync from wine!!! This breaks explorer task bar sizing!!
406 // The task bar can grow in size and can not reduce due to the change
410 ExStyle
= pwnd
->ExStyle
;
411 iconic
= (Style
& WS_MINIMIZE
) != 0;
413 if ((Style
& WS_MAXIMIZE
) || !IntIsWindowVisible(pwnd
)) return;
415 thickframe
= UserHasThickFrameStyle(Style
, ExStyle
) && !iconic
;
418 // Show window contents while dragging the window, get flag from registry data.
420 UserSystemParametersInfo(SPI_GETDRAGFULLWINDOWS
, 0, &DragFullWindows
, 0);
422 pt
.x
= pti
->ptLast
.x
;
423 pt
.y
= pti
->ptLast
.y
;
425 UserClipCursor( NULL
);
427 TRACE("pwnd %p command %04lx, hittest %d, pos %d,%d\n",
428 pwnd
, syscommand
, hittest
, pt
.x
, pt
.y
);
430 if (syscommand
== SC_MOVE
)
432 if (!hittest
) hittest
= DefWndStartSizeMove(pwnd
, wParam
, &capturePoint
);
433 if (!hittest
) return;
437 if (!thickframe
) return;
438 if (hittest
&& (syscommand
!= SC_MOUSEMENU
))
440 hittest
+= (HTLEFT
- WMSZ_LEFT
);
444 co_UserSetCapture(UserHMGetHandle(pwnd
));
445 hittest
= DefWndStartSizeMove(pwnd
, wParam
, &capturePoint
);
454 /* Get min/max info */
456 co_WinPosGetMinMaxInfo(pwnd
, NULL
, NULL
, &minTrack
, &maxTrack
);
457 sizingRect
= pwnd
->rcWindow
;
458 origRect
= sizingRect
;
459 if (Style
& WS_CHILD
)
461 pWndParent
= IntGetParent(pwnd
);
462 IntGetClientRect( pWndParent
, &mouseRect
);
463 IntMapWindowPoints( pWndParent
, 0, (LPPOINT
)&mouseRect
, 2 );
464 IntMapWindowPoints( 0, pWndParent
, (LPPOINT
)&sizingRect
, 2 );
465 unmodRect
= sizingRect
;
469 if (!(ExStyle
& WS_EX_TOPMOST
))
471 UserSystemParametersInfo(SPI_GETWORKAREA
, 0, &mouseRect
, 0);
475 RECTL_vSetRect(&mouseRect
, 0, 0, UserGetSystemMetrics(SM_CXSCREEN
), UserGetSystemMetrics(SM_CYSCREEN
));
477 unmodRect
= sizingRect
;
480 if (ON_LEFT_BORDER(hittest
))
482 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.right
-maxTrack
.x
+capturePoint
.x
-sizingRect
.left
);
483 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.right
-minTrack
.x
+capturePoint
.x
-sizingRect
.left
);
485 else if (ON_RIGHT_BORDER(hittest
))
487 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.left
+minTrack
.x
+capturePoint
.x
-sizingRect
.right
);
488 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.left
+maxTrack
.x
+capturePoint
.x
-sizingRect
.right
);
490 if (ON_TOP_BORDER(hittest
))
492 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.bottom
-maxTrack
.y
+capturePoint
.y
-sizingRect
.top
);
493 mouseRect
.bottom
= min( mouseRect
.bottom
,sizingRect
.bottom
-minTrack
.y
+capturePoint
.y
-sizingRect
.top
);
495 else if (ON_BOTTOM_BORDER(hittest
))
497 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.top
+minTrack
.y
+capturePoint
.y
-sizingRect
.bottom
);
498 mouseRect
.bottom
= min( mouseRect
.bottom
, sizingRect
.top
+maxTrack
.y
+capturePoint
.y
-sizingRect
.bottom
);
501 hdc
= UserGetDCEx( pWndParent
, 0, DCX_CACHE
);
502 #ifdef NEW_CURSORICON
505 DragCursor
= pwnd
->pcls
->spicn
;
508 UserReferenceObject(DragCursor
);
512 HCURSOR CursorHandle
= (HCURSOR
)co_IntSendMessage( UserHMGetHandle(pwnd
), WM_QUERYDRAGICON
, 0, 0 );
515 DragCursor
= UserGetCurIconObject(CursorHandle
);
524 if ( iconic
) /* create a cursor for dragging */
526 hDragCursor
= pwnd
->pcls
->hIcon
;
527 if ( !hDragCursor
) hDragCursor
= (HCURSOR
)co_IntSendMessage( UserHMGetHandle(pwnd
), WM_QUERYDRAGICON
, 0, 0 );
528 if ( !hDragCursor
) iconic
= FALSE
;
532 /* repaint the window before moving it around */
533 co_UserRedrawWindow( pwnd
, NULL
, 0, RDW_UPDATENOW
| RDW_ALLCHILDREN
);
535 IntNotifyWinEvent( EVENT_SYSTEM_MOVESIZESTART
, pwnd
, OBJID_WINDOW
, CHILDID_SELF
, 0);
537 co_IntSendMessage( UserHMGetHandle(pwnd
), WM_ENTERSIZEMOVE
, 0, 0 );
539 MsqSetStateWindow(pti
, MSQ_STATE_MOVESIZE
, UserHMGetHandle(pwnd
));
541 if (IntGetCapture() != UserHMGetHandle(pwnd
)) co_UserSetCapture( UserHMGetHandle(pwnd
) );
543 pwnd
->head
.pti
->TIF_flags
|= TIF_MOVESIZETRACKING
;
549 if (!co_IntGetPeekMessage(&msg
, 0, 0, 0, PM_REMOVE
, TRUE
)) break;
550 if (IntCallMsgFilter( &msg
, MSGF_SIZE
)) continue;
552 /* Exit on button-up, Return, or Esc */
553 if ((msg
.message
== WM_LBUTTONUP
) ||
554 ((msg
.message
== WM_KEYDOWN
) &&
555 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
557 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
559 IntTranslateKbdMessage( &msg
, 0 );
560 IntDispatchMessage( &msg
);
561 continue; /* We are not interested in other messages */
566 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
568 case VK_UP
: pt
.y
-= 8; break;
569 case VK_DOWN
: pt
.y
+= 8; break;
570 case VK_LEFT
: pt
.x
-= 8; break;
571 case VK_RIGHT
: pt
.x
+= 8; break;
574 pt
.x
= max( pt
.x
, mouseRect
.left
);
575 pt
.x
= min( pt
.x
, mouseRect
.right
- 1 );
576 pt
.y
= max( pt
.y
, mouseRect
.top
);
577 pt
.y
= min( pt
.y
, mouseRect
.bottom
- 1 );
579 dx
= pt
.x
- capturePoint
.x
;
580 dy
= pt
.y
- capturePoint
.y
;
587 if ( iconic
) /* ok, no system popup tracking */
589 #ifdef NEW_CURSORICON
590 OldCursor
= UserSetCursor(DragCursor
, FALSE
);
592 hOldCursor
= IntSetCursor(hDragCursor
);
594 UserShowCursor( TRUE
);
596 else if(!DragFullWindows
)
597 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
600 if (msg
.message
== WM_KEYDOWN
) UserSetCursorPos(pt
.x
, pt
.y
, 0, 0, FALSE
);
603 RECT newRect
= unmodRect
;
605 if (!iconic
&& !DragFullWindows
) UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
606 if (hittest
== HTCAPTION
) RECTL_vOffsetRect( &newRect
, dx
, dy
);
607 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
608 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
609 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
610 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
614 // Save the new position to the unmodified rectangle. This allows explorer task bar
615 // sizing. Explorer will forces back the position unless a certain amount of sizing
620 /* determine the hit location */
621 if (syscommand
== SC_SIZE
)
623 WPARAM wpSizingHit
= 0;
625 if (hittest
>= HTLEFT
&& hittest
<= HTBOTTOMRIGHT
)
626 wpSizingHit
= WMSZ_LEFT
+ (hittest
- HTLEFT
);
627 co_IntSendMessage( UserHMGetHandle(pwnd
), WM_SIZING
, wpSizingHit
, (LPARAM
)&newRect
);
630 co_IntSendMessage( UserHMGetHandle(pwnd
), WM_MOVING
, 0, (LPARAM
)&newRect
);
634 if (!DragFullWindows
)
635 UserDrawMovingFrame( hdc
, &newRect
, thickframe
);
637 { // Moving the whole window now!
639 //// This causes the mdi child window to jump up when it is moved.
640 //IntMapWindowPoints( 0, pWndParent, (POINT *)&rect, 2 );
641 co_WinPosSetWindowPos( pwnd
,
645 newRect
.right
- newRect
.left
,
646 newRect
.bottom
- newRect
.top
,
647 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
649 // Update all the windows after the move or size, including this window.
650 for ( pwndTemp
= pwnd
->head
.rpdesk
->pDeskInfo
->spwnd
->spwndChild
;
652 pwndTemp
= pwndTemp
->spwndNext
)
655 // Only the windows that overlap will be redrawn.
656 if (RECTL_bIntersectRect( &rect
, &pwnd
->rcWindow
, &pwndTemp
->rcWindow
))
658 co_UserRedrawWindow( pwndTemp
, NULL
, NULL
, RDW_UPDATENOW
| RDW_ALLCHILDREN
);
663 sizingRect
= newRect
;
668 pwnd
->head
.pti
->TIF_flags
&= ~TIF_MOVESIZETRACKING
;
674 if ( moved
) /* restore cursors, show icon title later on */
676 UserShowCursor( FALSE
);
677 #ifdef NEW_CURSORICON
678 OldCursor
= UserSetCursor(OldCursor
, FALSE
);
680 IntSetCursor( hOldCursor
);
683 #ifdef NEW_CURSORICON
684 /* It could be that the cursor was already changed while we were proceeding,
685 * so we must unreference whatever cursor was current at the time we restored the old one.
686 * Maybe it is DragCursor, but maybe it is another one and DragCursor got already freed.
688 UserDereferenceObject(OldCursor
);
690 IntDestroyCursor( hDragCursor
, FALSE
);
693 else if ( moved
&& !DragFullWindows
)
694 UserDrawMovingFrame( hdc
, &sizingRect
, thickframe
);
696 UserReleaseDC(NULL
, hdc
, FALSE
);
698 //// This causes the mdi child window to jump up when it is moved.
699 //if (pWndParent) IntMapWindowPoints( 0, pWndParent, (POINT *)&sizingRect, 2 );
701 if (co_HOOK_CallHooks(WH_CBT
, HCBT_MOVESIZE
, (WPARAM
)UserHMGetHandle(pwnd
), (LPARAM
)&sizingRect
))
703 ERR("DoSizeMove : WH_CBT Call Hook return!\n");
707 IntNotifyWinEvent( EVENT_SYSTEM_MOVESIZEEND
, pwnd
, OBJID_WINDOW
, CHILDID_SELF
, 0);
709 MsqSetStateWindow(pti
, MSQ_STATE_MOVESIZE
, NULL
);
711 co_IntSendMessage( UserHMGetHandle(pwnd
), WM_EXITSIZEMOVE
, 0, 0 );
713 co_IntSendMessage( UserHMGetHandle(pwnd
), WM_SETVISIBLE
, !!(pwnd
->style
& WS_MINIMIZE
), 0L);
715 /* window moved or resized */
718 /* if the moving/resizing isn't canceled call SetWindowPos
719 * with the new position or the new size of the window
721 if (!((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
723 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
724 if (!DragFullWindows
|| iconic
)
726 co_WinPosSetWindowPos( pwnd
,
730 sizingRect
.right
- sizingRect
.left
,
731 sizingRect
.bottom
- sizingRect
.top
,
732 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
736 { /* restore previous size/position */
737 if ( DragFullWindows
)
739 co_WinPosSetWindowPos( pwnd
,
743 origRect
.right
- origRect
.left
,
744 origRect
.bottom
- origRect
.top
,
745 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
750 if ( IntIsWindow(UserHMGetHandle(pwnd
)) )
753 /* Single click brings up the system menu when iconized */
756 if( Style
& WS_SYSMENU
)
757 co_IntSendMessage( UserHMGetHandle(pwnd
), WM_SYSCOMMAND
, SC_MOUSEMENU
+ HTSYSMENU
, MAKELONG(pt
.x
,pt
.y
));
763 // Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
766 DefWndHandleSysCommand(PWND pWnd
, WPARAM wParam
, LPARAM lParam
)
771 if (ISITHOOKED(WH_CBT
) || (pWnd
->head
.rpdesk
->pDeskInfo
->fsHooks
& HOOKID_TO_FLAG(WH_CBT
)))
774 lResult
= co_HOOK_CallHooks(WH_CBT
, HCBT_SYSCOMMAND
, wParam
, lParam
);
776 if (lResult
) return lResult
;
779 switch (wParam
& 0xfff0)
783 DefWndDoSizeMove(pWnd
, wParam
);
787 if (UserHMGetHandle(pWnd
) == UserGetActiveWindow())
788 IntShowOwnedPopups(pWnd
,FALSE
); // This is done in ShowWindow! Need to retest!
789 co_WinPosShowWindow( pWnd
, SW_MINIMIZE
);
793 if (((pWnd
->style
& WS_MINIMIZE
) != 0) && UserHMGetHandle(pWnd
) == UserGetActiveWindow())
794 IntShowOwnedPopups(pWnd
,TRUE
);
795 co_WinPosShowWindow( pWnd
, SW_MAXIMIZE
);
799 if (((pWnd
->style
& WS_MINIMIZE
) != 0) && UserHMGetHandle(pWnd
) == UserGetActiveWindow())
800 IntShowOwnedPopups(pWnd
,TRUE
);
801 co_WinPosShowWindow( pWnd
, SW_RESTORE
);
805 return co_IntSendMessage(UserHMGetHandle(pWnd
), WM_CLOSE
, 0, 0);
808 ERR("Screensaver Called!\n");
809 UserPostMessage(hwndSAS
, WM_LOGONNOTIFY
, LN_START_SCREENSAVE
, 0); // always lParam 0 == not Secure
814 USER_REFERENCE_ENTRY Ref
;
816 pWnd
= ValidateHwndNoErr((HWND
)lParam
);
819 if (pWnd
->spwndLastActive
)
821 pWnd
= pWnd
->spwndLastActive
;
823 UserRefObjectCo(pWnd
, &Ref
);
824 co_IntSetForegroundWindow(pWnd
);
825 UserDerefObjectCo(pWnd
);
826 if (pWnd
->style
& WS_MINIMIZE
)
828 UserPostMessage(UserHMGetHandle(pWnd
), WM_SYSCOMMAND
, SC_RESTORE
, 0);
836 // We do not support anything else here so we should return normal even when sending a hook.
840 return(Hook
? 1 : 0); // Don't call us again from user space.
843 VOID FASTCALL
DefWndPrint( PWND pwnd
, HDC hdc
, ULONG uFlags
)
848 if ( (uFlags
& PRF_CHECKVISIBLE
) &&
849 !IntIsWindowVisible(pwnd
) )
853 * Unimplemented flags.
855 if ( (uFlags
& PRF_CHILDREN
) ||
856 (uFlags
& PRF_OWNED
) ||
857 (uFlags
& PRF_NONCLIENT
) )
859 FIXME("WM_PRINT message with unsupported flags\n");
865 if ( uFlags
& PRF_ERASEBKGND
)
866 co_IntSendMessage(UserHMGetHandle(pwnd
), WM_ERASEBKGND
, (WPARAM
)hdc
, 0);
871 if ( uFlags
& PRF_CLIENT
)
872 co_IntSendMessage(UserHMGetHandle(pwnd
), WM_PRINTCLIENT
, (WPARAM
)hdc
, uFlags
);
877 Win32k counterpart of User DefWindowProc
888 USER_REFERENCE_ENTRY Ref
;
890 if (Msg
> WM_USER
) return 0;
896 ERR("hwnd %p WM_SYSCOMMAND %lx %lx\n", Wnd
->head
.h
, wParam
, lParam
);
897 lResult
= DefWndHandleSysCommand(Wnd
, wParam
, lParam
);
902 if ((Wnd
->style
& WS_VISIBLE
) && wParam
) break;
903 if (!(Wnd
->style
& WS_VISIBLE
) && !wParam
) break;
904 if (!Wnd
->spwndOwner
) break;
909 if (!(Wnd
->state
& WNDS_HIDDENPOPUP
)) break;
910 Wnd
->state
&= ~WNDS_HIDDENPOPUP
;
913 Wnd
->state
|= WNDS_HIDDENPOPUP
;
915 co_WinPosShowWindow(Wnd
, wParam
? SW_SHOWNOACTIVATE
: SW_HIDE
);
919 case WM_CLIENTSHUTDOWN
:
920 return IntClientShutdown(Wnd
, wParam
, lParam
);
923 ERR("WM_APPCOMMAND\n");
924 if ( (Wnd
->style
& (WS_POPUP
|WS_CHILD
)) != WS_CHILD
&&
925 Wnd
!= co_GetDesktopWindow(Wnd
) )
927 if (!co_HOOK_CallHooks(WH_SHELL
, HSHELL_APPCOMMAND
, wParam
, lParam
))
928 co_IntShellHookNotify(HSHELL_APPCOMMAND
, wParam
, lParam
);
931 UserRefObjectCo(Wnd
->spwndParent
, &Ref
);
932 lResult
= co_IntSendMessage(UserHMGetHandle(Wnd
->spwndParent
), WM_APPCOMMAND
, wParam
, lParam
);
933 UserDerefObjectCo(Wnd
->spwndParent
);
937 co_UserDestroyWindow(Wnd
);
940 case WM_CTLCOLORMSGBOX
:
941 case WM_CTLCOLOREDIT
:
942 case WM_CTLCOLORLISTBOX
:
945 case WM_CTLCOLORSTATIC
:
946 case WM_CTLCOLORSCROLLBAR
:
947 return (LRESULT
) DefWndControlColor((HDC
)wParam
, Msg
- WM_CTLCOLORMSGBOX
);
950 return (LRESULT
) DefWndControlColor((HDC
)wParam
, HIWORD(lParam
));
953 /* The default action in Windows is to set the keyboard focus to
954 * the window, if it's being activated and not minimized */
955 if (LOWORD(wParam
) != WA_INACTIVE
&&
956 !(Wnd
->style
& WS_MINIMIZE
))
958 //ERR("WM_ACTIVATE %p\n",hWnd);
959 co_UserSetFocus(Wnd
);
964 if (Wnd
->style
& WS_CHILD
)
967 PWND pwndParent
= IntGetParent(Wnd
);
968 hwndParent
= pwndParent
? UserHMGetHandle(pwndParent
) : NULL
;
969 return co_IntSendMessage( hwndParent
, WM_MOUSEWHEEL
, wParam
, lParam
);
974 case WM_ICONERASEBKGND
:
977 HBRUSH hBrush
= Wnd
->pcls
->hbrBackground
;
978 if (!hBrush
) return 0;
979 if (hBrush
<= (HBRUSH
)COLOR_MENUBAR
)
981 hBrush
= IntGetSysColorBrush((INT
)hBrush
);
983 if (Wnd
->pcls
->style
& CS_PARENTDC
)
985 /* can't use GetClipBox with a parent DC or we fill the whole parent */
986 IntGetClientRect(Wnd
, &Rect
);
987 GreDPtoLP((HDC
)wParam
, (LPPOINT
)&Rect
, 2);
991 GdiGetClipBox((HDC
)wParam
, &Rect
);
993 FillRect((HDC
)wParam
, &Rect
, hBrush
);
998 //ERR("WM_GETHOTKEY\n");
999 return DefWndGetHotKey(Wnd
);
1001 //ERR("WM_SETHOTKEY\n");
1002 return DefWndSetHotKey(Wnd
, wParam
);
1007 Point
.x
= GET_X_LPARAM(lParam
);
1008 Point
.y
= GET_Y_LPARAM(lParam
);
1009 return GetNCHitEx(Wnd
, Point
);
1014 DefWndPrint(Wnd
, (HDC
)wParam
, lParam
);
1024 /* If already in Paint and Client area is not empty just return. */
1025 if (Wnd
->state2
& WNDS2_STARTPAINT
&& !RECTL_bIsEmptyRect(&Wnd
->rcClient
))
1027 ERR("In Paint and Client area is not empty!\n");
1031 hDC
= IntBeginPaint(Wnd
, &Ps
);
1034 #ifdef NEW_CURSORICON
1035 if (((Wnd
->style
& WS_MINIMIZE
) != 0) && (Wnd
->pcls
->spicn
))
1040 ERR("Doing Paint and Client area is empty!\n");
1041 IntGetClientRect(Wnd
, &ClientRect
);
1042 x
= (ClientRect
.right
- ClientRect
.left
- UserGetSystemMetrics(SM_CXICON
)) / 2;
1043 y
= (ClientRect
.bottom
- ClientRect
.top
- UserGetSystemMetrics(SM_CYICON
)) / 2;
1044 UserDrawIconEx(hDC
, x
, y
, Wnd
->pcls
->spicn
, 0, 0, 0, 0, DI_NORMAL
| DI_COMPAT
| DI_DEFAULTSIZE
);
1048 if (((Wnd
->style
& WS_MINIMIZE
) != 0) && (hIcon
= Wnd
->pcls
->hIcon
))
1052 PCURICON_OBJECT pIcon
;
1053 if (!(pIcon
= UserGetCurIconObject(hIcon
))) return 0;
1054 ERR("Doing Paint and Client area is empty!\n");
1055 IntGetClientRect(Wnd
, &ClientRect
);
1056 x
= (ClientRect
.right
- ClientRect
.left
- UserGetSystemMetrics(SM_CXICON
)) / 2;
1057 y
= (ClientRect
.bottom
- ClientRect
.top
- UserGetSystemMetrics(SM_CYICON
)) / 2;
1058 UserDrawIconEx( hDC
, x
, y
, pIcon
, 0, 0, 0, 0, DI_NORMAL
| DI_COMPAT
| DI_DEFAULTSIZE
);
1059 UserDereferenceObject(pIcon
);
1062 IntEndPaint(Wnd
, &Ps
);
1070 Wnd
->state
&= ~WNDS_SYNCPAINTPENDING
;
1071 ERR("WM_SYNCPAINT\n");
1072 Rgn
= IntSysCreateRectpRgn(0, 0, 0, 0);
1075 if (co_UserGetUpdateRgn(Wnd
, Rgn
, FALSE
) != NULLREGION
)
1078 wParam
= (RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
| RDW_ALLCHILDREN
);
1079 co_UserRedrawWindow(Wnd
, NULL
, Rgn
, wParam
);
1087 ERR("WM_SETREDRAW\n");
1090 if (!(Wnd
->style
& WS_VISIBLE
))
1092 IntSetStyle( Wnd
, WS_VISIBLE
, 0 );
1093 Wnd
->state
|= WNDS_SENDNCPAINT
;
1098 if (Wnd
->style
& WS_VISIBLE
)
1100 co_UserRedrawWindow( Wnd
, NULL
, NULL
, RDW_ALLCHILDREN
| RDW_VALIDATE
);
1101 IntSetStyle( Wnd
, 0, WS_VISIBLE
);
1106 case WM_WINDOWPOSCHANGING
:
1108 return (DefWndHandleWindowPosChanging(Wnd
, (WINDOWPOS
*)lParam
));
1111 case WM_WINDOWPOSCHANGED
:
1113 return (DefWndHandleWindowPosChanged(Wnd
, (WINDOWPOS
*)lParam
));
1129 ProbeForRead((PVOID
)lParam
,
1137 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1144 lResult
= co_HOOK_CallHooks(WH_CBT
, HCBT_MOVESIZE
, (WPARAM
)Wnd
->head
.h
, lParam
? (LPARAM
)&rt
: 0);
1155 PCURICON_OBJECT FASTCALL
NC_IconForWindow( PWND pWnd
)
1157 PCURICON_OBJECT pIcon
= NULL
;
1159 // First thing to do, init the Window Logo icons.
1160 if (!gpsi
->hIconSmWindows
) co_IntSetWndIcons();
1162 //FIXME: Some callers use this function as if it returns a boolean saying "this window has an icon".
1163 //FIXME: Hence we must return a pointer with no reference count.
1164 //FIXME: This is bad and we should feel bad.
1166 hIcon
= UserGetProp(pWnd
, gpsi
->atomIconSmProp
);
1167 if (!hIcon
) hIcon
= UserGetProp(pWnd
, gpsi
->atomIconProp
);
1168 #ifdef NEW_CURSORICON
1169 if (!hIcon
&& pWnd
->pcls
->spicnSm
)
1170 return pWnd
->pcls
->spicnSm
;
1171 if (!hIcon
&& pWnd
->pcls
->spicn
)
1172 return pWnd
->pcls
->spicn
;
1174 if (!hIcon
) hIcon
= pWnd
->pcls
->hIconSm
;
1175 if (!hIcon
) hIcon
= pWnd
->pcls
->hIcon
;
1178 if (!hIcon
&& (pWnd
->style
& DS_MODALFRAME
))
1180 if (!hIcon
) hIcon
= gpsi
->hIconSmWindows
; // Both are IDI_WINLOGO Small
1181 if (!hIcon
) hIcon
= gpsi
->hIconWindows
; // Reg size.
1185 pIcon
= UserGetCurIconObject(hIcon
);
1188 UserDereferenceObject(pIcon
);
1195 GetNCHitEx(PWND pWnd
, POINT pt
)
1197 RECT rcWindow
, rcClient
;
1198 DWORD Style
, ExStyle
;
1200 if (!pWnd
) return HTNOWHERE
;
1202 if (pWnd
== UserGetDesktopWindow()) // pWnd->fnid == FNID_DESKTOP)
1204 rcClient
.left
= rcClient
.top
= rcWindow
.left
= rcWindow
.top
= 0;
1205 rcWindow
.right
= UserGetSystemMetrics(SM_CXSCREEN
);
1206 rcWindow
.bottom
= UserGetSystemMetrics(SM_CYSCREEN
);
1207 rcClient
.right
= UserGetSystemMetrics(SM_CXSCREEN
);
1208 rcClient
.bottom
= UserGetSystemMetrics(SM_CYSCREEN
);
1212 rcClient
= pWnd
->rcClient
;
1213 rcWindow
= pWnd
->rcWindow
;
1216 if (!RECTL_bPointInRect(&rcWindow
, pt
.x
, pt
.y
)) return HTNOWHERE
;
1218 Style
= pWnd
->style
;
1219 ExStyle
= pWnd
->ExStyle
;
1221 if (Style
& WS_MINIMIZE
) return HTCAPTION
;
1223 if (RECTL_bPointInRect( &rcClient
, pt
.x
, pt
.y
)) return HTCLIENT
;
1226 if (HAS_THICKFRAME( Style
, ExStyle
))
1228 RECTL_vInflateRect(&rcWindow
, -UserGetSystemMetrics(SM_CXFRAME
), -UserGetSystemMetrics(SM_CYFRAME
) );
1229 if (!RECTL_bPointInRect(&rcWindow
, pt
.x
, pt
.y
))
1231 /* Check top sizing border */
1232 if (pt
.y
< rcWindow
.top
)
1234 if (pt
.x
< rcWindow
.left
+UserGetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
1235 if (pt
.x
>= rcWindow
.right
-UserGetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
1238 /* Check bottom sizing border */
1239 if (pt
.y
>= rcWindow
.bottom
)
1241 if (pt
.x
< rcWindow
.left
+UserGetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
1242 if (pt
.x
>= rcWindow
.right
-UserGetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
1245 /* Check left sizing border */
1246 if (pt
.x
< rcWindow
.left
)
1248 if (pt
.y
< rcWindow
.top
+UserGetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
1249 if (pt
.y
>= rcWindow
.bottom
-UserGetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
1252 /* Check right sizing border */
1253 if (pt
.x
>= rcWindow
.right
)
1255 if (pt
.y
< rcWindow
.top
+UserGetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
1256 if (pt
.y
>= rcWindow
.bottom
-UserGetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
1261 else /* No thick frame */
1263 if (HAS_DLGFRAME( Style
, ExStyle
))
1264 RECTL_vInflateRect(&rcWindow
, -UserGetSystemMetrics(SM_CXDLGFRAME
), -UserGetSystemMetrics(SM_CYDLGFRAME
));
1265 else if (HAS_THINFRAME( Style
, ExStyle
))
1266 RECTL_vInflateRect(&rcWindow
, -UserGetSystemMetrics(SM_CXBORDER
), -UserGetSystemMetrics(SM_CYBORDER
));
1267 if (!RECTL_bPointInRect( &rcWindow
, pt
.x
, pt
.y
)) return HTBORDER
;
1272 if ((Style
& WS_CAPTION
) == WS_CAPTION
)
1274 if (ExStyle
& WS_EX_TOOLWINDOW
)
1275 rcWindow
.top
+= UserGetSystemMetrics(SM_CYSMCAPTION
) - 1;
1277 rcWindow
.top
+= UserGetSystemMetrics(SM_CYCAPTION
) - 1;
1278 if (!RECTL_bPointInRect( &rcWindow
, pt
.x
, pt
.y
))
1280 BOOL min_or_max_box
= (Style
& WS_SYSMENU
) && (Style
& (WS_MINIMIZEBOX
|WS_MAXIMIZEBOX
));
1281 if (ExStyle
& WS_EX_LAYOUTRTL
)
1283 /* Check system menu */
1284 if ((Style
& WS_SYSMENU
) && !(ExStyle
& WS_EX_TOOLWINDOW
) && NC_IconForWindow(pWnd
))
1286 rcWindow
.right
-= UserGetSystemMetrics(SM_CYCAPTION
) - 1;
1287 if (pt
.x
> rcWindow
.right
) return HTSYSMENU
;
1290 /* Check close button */
1291 if (Style
& WS_SYSMENU
)
1293 rcWindow
.left
+= UserGetSystemMetrics(SM_CYCAPTION
);
1294 if (pt
.x
< rcWindow
.left
) return HTCLOSE
;
1297 /* Check maximize box */
1298 /* In Win95 there is automatically a Maximize button when there is a minimize one */
1299 if (min_or_max_box
&& !(ExStyle
& WS_EX_TOOLWINDOW
))
1301 rcWindow
.left
+= UserGetSystemMetrics(SM_CXSIZE
);
1302 if (pt
.x
< rcWindow
.left
) return HTMAXBUTTON
;
1305 /* Check minimize box */
1306 if (min_or_max_box
&& !(ExStyle
& WS_EX_TOOLWINDOW
))
1308 rcWindow
.left
+= UserGetSystemMetrics(SM_CXSIZE
);
1309 if (pt
.x
< rcWindow
.left
) return HTMINBUTTON
;
1314 /* Check system menu */
1315 if ((Style
& WS_SYSMENU
) && !(ExStyle
& WS_EX_TOOLWINDOW
) && NC_IconForWindow(pWnd
))
1317 rcWindow
.left
+= UserGetSystemMetrics(SM_CYCAPTION
) - 1;
1318 if (pt
.x
< rcWindow
.left
) return HTSYSMENU
;
1321 /* Check close button */
1322 if (Style
& WS_SYSMENU
)
1324 rcWindow
.right
-= UserGetSystemMetrics(SM_CYCAPTION
);
1325 if (pt
.x
> rcWindow
.right
) return HTCLOSE
;
1328 /* Check maximize box */
1329 /* In Win95 there is automatically a Maximize button when there is a minimize one */
1330 if (min_or_max_box
&& !(ExStyle
& WS_EX_TOOLWINDOW
))
1332 rcWindow
.right
-= UserGetSystemMetrics(SM_CXSIZE
);
1333 if (pt
.x
> rcWindow
.right
) return HTMAXBUTTON
;
1336 /* Check minimize box */
1337 if (min_or_max_box
&& !(ExStyle
& WS_EX_TOOLWINDOW
))
1339 rcWindow
.right
-= UserGetSystemMetrics(SM_CXSIZE
);
1340 if (pt
.x
> rcWindow
.right
) return HTMINBUTTON
;
1347 /* Check menu bar */
1349 if (HAS_MENU( pWnd
, Style
) && (pt
.y
< rcClient
.top
) &&
1350 (pt
.x
>= rcClient
.left
) && (pt
.x
< rcClient
.right
))
1353 /* Check vertical scroll bar */
1355 if (ExStyle
& WS_EX_LAYOUTRTL
) ExStyle
^= WS_EX_LEFTSCROLLBAR
;
1356 if (Style
& WS_VSCROLL
)
1358 if((ExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
1359 rcClient
.left
-= UserGetSystemMetrics(SM_CXVSCROLL
);
1361 rcClient
.right
+= UserGetSystemMetrics(SM_CXVSCROLL
);
1362 if (RECTL_bPointInRect( &rcClient
, pt
.x
, pt
.y
)) return HTVSCROLL
;
1365 /* Check horizontal scroll bar */
1367 if (Style
& WS_HSCROLL
)
1369 rcClient
.bottom
+= UserGetSystemMetrics(SM_CYHSCROLL
);
1370 if (RECTL_bPointInRect( &rcClient
, pt
.x
, pt
.y
))
1372 /* Check size box */
1373 if ((Style
& WS_VSCROLL
) &&
1374 ((((ExStyle
& WS_EX_LEFTSCROLLBAR
) != 0) && (pt
.x
<= rcClient
.left
+ UserGetSystemMetrics(SM_CXVSCROLL
))) ||
1375 (((ExStyle
& WS_EX_LEFTSCROLLBAR
) == 0) && (pt
.x
>= rcClient
.right
- UserGetSystemMetrics(SM_CXVSCROLL
)))))
1381 /* Has to return HTNOWHERE if nothing was found
1382 Could happen when a window has a customized non client area */