xref: /reactos/win32ss/user/ntuser/defwnd.c (revision ccef43f3)
1 /*
2  * PROJECT:     ReactOS Win32k subsystem
3  * LICENSE:     See COPYING in the top level directory
4  * PURPOSE:     Miscellaneous User functions
5  * COPYRIGHT:   2008-2020 James Tabor <james.tabor@reactos.org>
6  */
7 
8 #include <win32k.h>
9 #include <windowsx.h>
10 
11 DBG_DEFAULT_CHANNEL(UserDefwnd);
12 
13 INT WINAPI DrawTextExWorker( HDC hdc, LPWSTR str, INT i_count,
14                         LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp );
15 
16 INT WINAPI DrawTextW( HDC hdc, LPCWSTR str, INT count, LPRECT rect, UINT flags )
17 {
18     DRAWTEXTPARAMS dtp;
19 
20     memset (&dtp, 0, sizeof(dtp));
21     dtp.cbSize = sizeof(dtp);
22     if (flags & DT_TABSTOP)
23     {
24         dtp.iTabLength = (flags >> 8) & 0xff;
25         flags &= 0xffff00ff;
26     }
27     return DrawTextExWorker(hdc, (LPWSTR)str, count, rect, flags, &dtp);
28 }
29 
30 
31 HBRUSH FASTCALL
32 DefWndControlColor(HDC hDC, UINT ctlType)
33 {
34   if (ctlType == CTLCOLOR_SCROLLBAR)
35   {
36       HBRUSH hb = IntGetSysColorBrush(COLOR_SCROLLBAR);
37       COLORREF bk = IntGetSysColor(COLOR_3DHILIGHT);
38       IntGdiSetTextColor(hDC, IntGetSysColor(COLOR_3DFACE));
39       IntGdiSetBkColor(hDC, bk);
40 
41       /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
42        * we better use 0x55aa bitmap brush to make scrollbar's background
43        * look different from the window background.
44        */
45       if ( bk == IntGetSysColor(COLOR_WINDOW))
46           return gpsi->hbrGray;
47 
48       NtGdiUnrealizeObject( hb );
49       return hb;
50   }
51 
52   IntGdiSetTextColor(hDC, IntGetSysColor(COLOR_WINDOWTEXT));
53 
54   if ((ctlType == CTLCOLOR_EDIT) || (ctlType == CTLCOLOR_LISTBOX))
55   {
56       IntGdiSetBkColor(hDC, IntGetSysColor(COLOR_WINDOW));
57   }
58   else
59   {
60       IntGdiSetBkColor(hDC, IntGetSysColor(COLOR_3DFACE));
61       return IntGetSysColorBrush(COLOR_3DFACE);
62   }
63 
64   return IntGetSysColorBrush(COLOR_WINDOW);
65 }
66 
67 LRESULT FASTCALL
68 DefWndHandleWindowPosChanging(PWND pWnd, WINDOWPOS* Pos)
69 {
70     POINT maxTrack, minTrack;
71     LONG style = pWnd->style;
72 
73     if (Pos->flags & SWP_NOSIZE) return 0;
74     if ((style & WS_THICKFRAME) || ((style & (WS_POPUP | WS_CHILD)) == 0))
75     {
76         co_WinPosGetMinMaxInfo(pWnd, NULL, NULL, &minTrack, &maxTrack);
77         Pos->cx = min(Pos->cx, maxTrack.x);
78         Pos->cy = min(Pos->cy, maxTrack.y);
79         if (!(style & WS_MINIMIZE))
80         {
81             if (Pos->cx < minTrack.x) Pos->cx = minTrack.x;
82             if (Pos->cy < minTrack.y) Pos->cy = minTrack.y;
83         }
84     }
85     else
86     {
87         Pos->cx = max(Pos->cx, 0);
88         Pos->cy = max(Pos->cy, 0);
89     }
90     return 0;
91 }
92 
93 /* Win: xxxHandleWindowPosChanged */
94 LRESULT FASTCALL
95 DefWndHandleWindowPosChanged(PWND pWnd, WINDOWPOS* Pos)
96 {
97    RECT Rect;
98    LONG style = pWnd->style;
99 
100    IntGetClientRect(pWnd, &Rect);
101    IntMapWindowPoints(pWnd, (style & WS_CHILD ? IntGetParent(pWnd) : NULL), (LPPOINT) &Rect, 2);
102 
103    if (!(Pos->flags & SWP_NOCLIENTMOVE))
104    {
105       co_IntSendMessage(UserHMGetHandle(pWnd), WM_MOVE, 0, MAKELONG(Rect.left, Rect.top));
106    }
107 
108    if (!(Pos->flags & SWP_NOCLIENTSIZE) || (Pos->flags & SWP_STATECHANGED))
109    {
110       if (style & WS_MINIMIZE) co_IntSendMessage(UserHMGetHandle(pWnd), WM_SIZE, SIZE_MINIMIZED, 0 );
111       else
112       {
113          WPARAM wp = (style & WS_MAXIMIZE) ? SIZE_MAXIMIZED : SIZE_RESTORED;
114          co_IntSendMessage(UserHMGetHandle(pWnd), WM_SIZE, wp, MAKELONG(Rect.right - Rect.left, Rect.bottom - Rect.top));
115       }
116    }
117    return 0;
118 }
119 
120 //
121 // Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
122 //
123 // Win: xxxSysCommand
124 LRESULT FASTCALL
125 DefWndHandleSysCommand(PWND pWnd, WPARAM wParam, LPARAM lParam)
126 {
127    LRESULT lResult = 0;
128    BOOL Hook = FALSE;
129 
130    if (ISITHOOKED(WH_CBT) || (pWnd->head.rpdesk->pDeskInfo->fsHooks & HOOKID_TO_FLAG(WH_CBT)))
131    {
132       Hook = TRUE;
133       lResult = co_HOOK_CallHooks(WH_CBT, HCBT_SYSCOMMAND, wParam, lParam);
134 
135       if (lResult) return lResult;
136    }
137 
138    switch (wParam & 0xfff0)
139    {
140       case SC_MOVE:
141       case SC_SIZE:
142         DefWndDoSizeMove(pWnd, wParam);
143         break;
144 
145       case SC_MINIMIZE:
146         if (UserHMGetHandle(pWnd) == UserGetActiveWindow())
147             IntShowOwnedPopups(pWnd,FALSE); // This is done in ShowWindow! Need to retest!
148         co_WinPosShowWindow( pWnd, SW_MINIMIZE );
149         break;
150 
151       case SC_MAXIMIZE:
152         if (((pWnd->style & WS_MINIMIZE) != 0) && UserHMGetHandle(pWnd) == UserGetActiveWindow())
153             IntShowOwnedPopups(pWnd,TRUE);
154         co_WinPosShowWindow( pWnd, SW_MAXIMIZE );
155         break;
156 
157       case SC_RESTORE:
158         if (((pWnd->style & WS_MINIMIZE) != 0) && UserHMGetHandle(pWnd) == UserGetActiveWindow())
159             IntShowOwnedPopups(pWnd,TRUE);
160         co_WinPosShowWindow( pWnd, SW_RESTORE );
161         break;
162 
163       case SC_CLOSE:
164         return co_IntSendMessage(UserHMGetHandle(pWnd), WM_CLOSE, 0, 0);
165 
166       case SC_SCREENSAVE:
167         ERR("Screensaver Called!\n");
168         UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_START_SCREENSAVE, 0); // always lParam 0 == not Secure
169         break;
170 
171       case SC_HOTKEY:
172         {
173            USER_REFERENCE_ENTRY Ref;
174 
175            pWnd = ValidateHwndNoErr((HWND)lParam);
176            if (pWnd)
177            {
178               if (pWnd->spwndLastActive)
179               {
180                  pWnd = pWnd->spwndLastActive;
181               }
182               UserRefObjectCo(pWnd, &Ref);
183               co_IntSetForegroundWindow(pWnd);
184               UserDerefObjectCo(pWnd);
185               if (pWnd->style & WS_MINIMIZE)
186               {
187                  UserPostMessage(UserHMGetHandle(pWnd), WM_SYSCOMMAND, SC_RESTORE, 0);
188               }
189            }
190         }
191         break;
192 //      case SC_DEFAULT:
193       case SC_MOUSEMENU:
194         {
195           POINT Pt;
196           Pt.x = (short)LOWORD(lParam);
197           Pt.y = (short)HIWORD(lParam);
198           MENU_TrackMouseMenuBar(pWnd, wParam & 0x000f, Pt);
199         }
200 	break;
201 
202       case SC_KEYMENU:
203         MENU_TrackKbdMenuBar(pWnd, wParam, (WCHAR)lParam);
204 	break;
205 
206 
207       default:
208    // We do not support anything else here so we should return normal even when sending a hook.
209         return 0;
210    }
211 
212    return(Hook ? 1 : 0); // Don't call us again from user space.
213 }
214 
215 PWND FASTCALL
216 co_IntFindChildWindowToOwner(PWND Root, PWND Owner)
217 {
218    PWND Ret;
219    PWND Child, OwnerWnd;
220 
221    for(Child = Root->spwndChild; Child; Child = Child->spwndNext)
222    {
223       OwnerWnd = Child->spwndOwner;
224       if(!OwnerWnd)
225          continue;
226 
227       if (!(Child->style & WS_POPUP) ||
228           !(Child->style & WS_VISIBLE) ||
229           /* Fixes CMD pop up properties window from having foreground. */
230            Owner->head.pti->MessageQueue != Child->head.pti->MessageQueue)
231          continue;
232 
233       if(OwnerWnd == Owner)
234       {
235          Ret = Child;
236          return Ret;
237       }
238    }
239    return NULL;
240 }
241 
242 LRESULT
243 DefWndHandleSetCursor(PWND pWnd, WPARAM wParam, LPARAM lParam)
244 {
245    PWND pwndPopUP = NULL;
246    WORD Msg = HIWORD(lParam);
247 
248    /* Not for child windows. */
249    if (UserHMGetHandle(pWnd) != (HWND)wParam)
250    {
251       return FALSE;
252    }
253 
254    switch((short)LOWORD(lParam))
255    {
256       case HTERROR:
257       {
258          //// This is the real fix for CORE-6129! This was a "Code hole".
259          USER_REFERENCE_ENTRY Ref;
260 
261          if (Msg == WM_LBUTTONDOWN)
262          {
263             // Find a pop up window to bring active.
264             pwndPopUP = co_IntFindChildWindowToOwner(UserGetDesktopWindow(), pWnd);
265             if (pwndPopUP)
266             {
267                // Not a child pop up from desktop.
268                if ( pwndPopUP != UserGetDesktopWindow()->spwndChild )
269                {
270                   // Get original active window.
271                   PWND pwndOrigActive = gpqForeground->spwndActive;
272 
273                   co_WinPosSetWindowPos(pWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
274 
275                   UserRefObjectCo(pwndPopUP, &Ref);
276                   //UserSetActiveWindow(pwndPopUP);
277                   co_IntSetForegroundWindow(pwndPopUP); // HACK
278                   UserDerefObjectCo(pwndPopUP);
279 
280                   // If the change was made, break out.
281                   if (pwndOrigActive != gpqForeground->spwndActive)
282                      break;
283                }
284             }
285          }
286          ////
287 	 if (Msg == WM_LBUTTONDOWN || Msg == WM_MBUTTONDOWN ||
288 	     Msg == WM_RBUTTONDOWN || Msg == WM_XBUTTONDOWN)
289 	 {
290              if (pwndPopUP)
291              {
292                  FLASHWINFO fwi =
293                     {sizeof(FLASHWINFO),
294                      UserHMGetHandle(pwndPopUP),
295                      FLASHW_ALL,
296                      gspv.dwForegroundFlashCount,
297                      (gpsi->dtCaretBlink >> 3)};
298 
299                  // Now shake that window!
300                  IntFlashWindowEx(pwndPopUP, &fwi);
301              }
302 	     UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_MESSAGE_BEEP, 0);
303 	 }
304 	 break;
305       }
306 
307       case HTCLIENT:
308       {
309          if (pWnd->pcls->spcur)
310          {
311             IntSystemSetCursor(pWnd->pcls->spcur);
312 	 }
313 	 return FALSE;
314       }
315 
316       case HTLEFT:
317       case HTRIGHT:
318       {
319          if (pWnd->style & WS_MAXIMIZE)
320          {
321             break;
322          }
323          IntSystemSetCursor(SYSTEMCUR(SIZEWE));
324          return TRUE;
325       }
326 
327       case HTTOP:
328       case HTBOTTOM:
329       {
330          if (pWnd->style & WS_MAXIMIZE)
331          {
332             break;
333          }
334          IntSystemSetCursor(SYSTEMCUR(SIZENS));
335          return TRUE;
336        }
337 
338        case HTTOPLEFT:
339        case HTBOTTOMRIGHT:
340        {
341          if (pWnd->style & WS_MAXIMIZE)
342          {
343             break;
344          }
345          IntSystemSetCursor(SYSTEMCUR(SIZENWSE));
346          return TRUE;
347        }
348 
349        case HTBOTTOMLEFT:
350        case HTTOPRIGHT:
351        {
352          if (pWnd->style & WS_MAXIMIZE)
353          {
354             break;
355          }
356          IntSystemSetCursor(SYSTEMCUR(SIZENESW));
357          return TRUE;
358        }
359    }
360    IntSystemSetCursor(SYSTEMCUR(ARROW));
361    return FALSE;
362 }
363 
364 /* Win: xxxDWPPrint */
365 VOID FASTCALL DefWndPrint( PWND pwnd, HDC hdc, ULONG uFlags)
366 {
367   /*
368    * Visibility flag.
369    */
370   if ( (uFlags & PRF_CHECKVISIBLE) &&
371        !IntIsWindowVisible(pwnd) )
372       return;
373 
374   /*
375    * Unimplemented flags.
376    */
377   if ( (uFlags & PRF_CHILDREN) ||
378        (uFlags & PRF_OWNED)    ||
379        (uFlags & PRF_NONCLIENT) )
380   {
381     FIXME("WM_PRINT message with unsupported flags\n");
382   }
383 
384   /*
385    * Background
386    */
387   if ( uFlags & PRF_ERASEBKGND)
388     co_IntSendMessage(UserHMGetHandle(pwnd), WM_ERASEBKGND, (WPARAM)hdc, 0);
389 
390   /*
391    * Client area
392    */
393   if ( uFlags & PRF_CLIENT)
394     co_IntSendMessage(UserHMGetHandle(pwnd), WM_PRINTCLIENT, (WPARAM)hdc, uFlags);
395 }
396 
397 BOOL
398 UserPaintCaption(PWND pWnd, INT Flags)
399 {
400   BOOL Ret = FALSE;
401 
402   if ( (pWnd->style & WS_VISIBLE) && ((pWnd->style & WS_CAPTION) == WS_CAPTION) )
403   {
404       if (pWnd->state & WNDS_HASCAPTION && pWnd->head.pti->MessageQueue == gpqForeground)
405          Flags |= DC_ACTIVE;
406     /*
407      * When themes are not enabled we can go on and paint the non client area.
408      * However if we do that with themes enabled we will draw a classic frame.
409      * This is solved by sending a themes specific message to notify the themes
410      * engine that the caption needs to be redrawn.
411      */
412       if (gpsi->dwSRVIFlags & SRVINFO_APIHOOK)
413       {
414         /*
415          * This will cause uxtheme to either paint the themed caption or call
416          * RealUserDrawCaption in order to draw the classic caption when themes
417          * are disabled but the themes service is enabled.
418          */
419          TRACE("UDCB Flags %08x\n", Flags);
420          co_IntSendMessage(UserHMGetHandle(pWnd), WM_NCUAHDRAWCAPTION, Flags, 0);
421       }
422       else
423       {
424          HDC hDC = UserGetDCEx(pWnd, NULL, DCX_WINDOW|DCX_USESTYLE);
425          UserDrawCaptionBar(pWnd, hDC, Flags | DC_FRAME); // DCFRAME added as fix for CORE-10855.
426          UserReleaseDC(pWnd, hDC, FALSE);
427       }
428       Ret = TRUE;
429    }
430    // Support window tray
431    return Ret;
432 }
433 
434 // WM_SETICON
435 /* Win: xxxDWP_SetIcon */
436 LRESULT FASTCALL
437 DefWndSetIcon(PWND pWnd, WPARAM wParam, LPARAM lParam)
438 {
439     HICON hIcon, hIconSmall, hIconOld;
440 
441     if ( wParam > ICON_SMALL2 )
442     {
443         EngSetLastError(ERROR_INVALID_PARAMETER);
444         return 0;
445     }
446     hIconSmall = UserGetProp(pWnd, gpsi->atomIconSmProp, TRUE);
447     hIcon      = UserGetProp(pWnd, gpsi->atomIconProp, TRUE);
448 
449     hIconOld = wParam == ICON_BIG ? hIcon : hIconSmall;
450 
451     switch(wParam)
452     {
453         case ICON_BIG:
454             hIcon = (HICON)lParam;
455             break;
456         case ICON_SMALL:
457             hIconSmall = (HICON)lParam;
458             break;
459         case ICON_SMALL2:
460             ERR("FIXME: Set ICON_SMALL2 support!\n");
461         default:
462             break;
463     }
464 
465     UserSetProp(pWnd, gpsi->atomIconProp, hIcon, TRUE);
466     UserSetProp(pWnd, gpsi->atomIconSmProp, hIconSmall, TRUE);
467 
468     if ((pWnd->style & WS_CAPTION ) == WS_CAPTION)
469        UserPaintCaption(pWnd, DC_ICON);
470 
471     return (LRESULT)hIconOld;
472 }
473 
474 /* Win: DWP_GetIcon */
475 LRESULT FASTCALL
476 DefWndGetIcon(PWND pWnd, WPARAM wParam, LPARAM lParam)
477 {
478     HICON hIconRet;
479     if ( wParam > ICON_SMALL2 )
480     {
481         EngSetLastError(ERROR_INVALID_PARAMETER);
482         return 0;
483     }
484     switch(wParam)
485     {
486         case ICON_BIG:
487             hIconRet = UserGetProp(pWnd, gpsi->atomIconProp, TRUE);
488             break;
489         case ICON_SMALL:
490         case ICON_SMALL2:
491             hIconRet = UserGetProp(pWnd, gpsi->atomIconSmProp, TRUE);
492             break;
493         DEFAULT_UNREACHABLE;
494     }
495     return (LRESULT)hIconRet;
496 }
497 
498 VOID FASTCALL
499 DefWndScreenshot(PWND pWnd)
500 {
501     RECT rect;
502     HDC hdc;
503     INT w;
504     INT h;
505     HBITMAP hbitmap;
506     HDC hdc2;
507     SETCLIPBDATA scd = {FALSE, FALSE};
508 
509     UserOpenClipboard(UserHMGetHandle(pWnd));
510     UserEmptyClipboard();
511 
512     hdc = UserGetWindowDC(pWnd);
513     IntGetWindowRect(pWnd, &rect);
514     w = rect.right - rect.left;
515     h = rect.bottom - rect.top;
516 
517     hbitmap = NtGdiCreateCompatibleBitmap(hdc, w, h);
518     hdc2 = NtGdiCreateCompatibleDC(hdc);
519     NtGdiSelectBitmap(hdc2, hbitmap);
520 
521     NtGdiBitBlt(hdc2, 0, 0, w, h, hdc, 0, 0, SRCCOPY, 0, 0);
522 
523     UserSetClipboardData(CF_BITMAP, hbitmap, &scd);
524 
525     UserReleaseDC(pWnd, hdc, FALSE);
526     UserReleaseDC(pWnd, hdc2, FALSE);
527 
528     UserCloseClipboard();
529 }
530 
531 /*
532    Win32k counterpart of User DefWindowProc
533  */
534 /* Win: xxxRealDefWindowProc */
535 LRESULT FASTCALL
536 IntDefWindowProc(
537    PWND Wnd,
538    UINT Msg,
539    WPARAM wParam,
540    LPARAM lParam,
541    BOOL Ansi)
542 {
543    PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
544    LRESULT lResult = 0;
545    USER_REFERENCE_ENTRY Ref;
546 
547    if (Msg > WM_USER) return 0;
548 
549    switch (Msg)
550    {
551       case WM_DEVICECHANGE:
552             return TRUE;
553 
554       case WM_GETTEXTLENGTH:
555       {
556             PWSTR buf;
557             ULONG len;
558 
559             if (Wnd != NULL && Wnd->strName.Length != 0)
560             {
561                 buf = Wnd->strName.Buffer;
562                 if (buf != NULL &&
563                     NT_SUCCESS(RtlUnicodeToMultiByteSize(&len,
564                                                          buf,
565                                                          Wnd->strName.Length)))
566                 {
567                     lResult = (LRESULT) (Wnd->strName.Length / sizeof(WCHAR));
568                 }
569             }
570             else lResult = 0L;
571 
572             break;
573       }
574 
575       case WM_GETTEXT: // FIXME: Handle Ansi
576       {
577             PWSTR buf = NULL;
578             PWSTR outbuf = (PWSTR)lParam;
579 
580             if (Wnd != NULL && wParam != 0)
581             {
582                 if (Wnd->strName.Buffer != NULL)
583                     buf = Wnd->strName.Buffer;
584                 else
585                     outbuf[0] = L'\0';
586 
587                 if (buf != NULL)
588                 {
589                     if (Wnd->strName.Length != 0)
590                     {
591                         lResult = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1);
592                         RtlCopyMemory(outbuf,
593                                       buf,
594                                       lResult * sizeof(WCHAR));
595                         outbuf[lResult] = L'\0';
596                     }
597                     else
598                         outbuf[0] = L'\0';
599                 }
600             }
601             break;
602       }
603 
604       case WM_SETTEXT: // FIXME: Handle Ansi
605       {
606             DefSetText(Wnd, (PCWSTR)lParam);
607 
608             if ((Wnd->style & WS_CAPTION) == WS_CAPTION)
609                 UserPaintCaption(Wnd, DC_TEXT);
610             IntNotifyWinEvent(EVENT_OBJECT_NAMECHANGE, Wnd, OBJID_WINDOW, CHILDID_SELF, 0);
611             lResult = 1;
612             break;
613       }
614 
615       case WM_SYSCOMMAND:
616       {
617          TRACE("hwnd %p WM_SYSCOMMAND %lx %lx\n", Wnd->head.h, wParam, lParam );
618          lResult = DefWndHandleSysCommand(Wnd, wParam, lParam);
619          break;
620       }
621 
622       case WM_SHOWWINDOW:
623       {
624          if ((Wnd->style & WS_VISIBLE) && wParam) break;
625          if (!(Wnd->style & WS_VISIBLE) && !wParam) break;
626          if (!Wnd->spwndOwner) break;
627          if (LOWORD(lParam))
628          {
629             co_WinPosShowWindow(Wnd, wParam ? SW_SHOWNOACTIVATE : SW_HIDE);
630          }
631          break;
632       }
633 
634       case WM_CLIENTSHUTDOWN:
635          return IntClientShutdown(Wnd, wParam, lParam);
636 
637       case WM_APPCOMMAND:
638          if ( (Wnd->style & (WS_POPUP|WS_CHILD)) != WS_CHILD &&
639                Wnd != co_GetDesktopWindow(Wnd) )
640          {
641             if (!co_HOOK_CallHooks(WH_SHELL, HSHELL_APPCOMMAND, wParam, lParam))
642                co_IntShellHookNotify(HSHELL_APPCOMMAND, wParam, lParam);
643             break;
644          }
645          UserRefObjectCo(Wnd->spwndParent, &Ref);
646          lResult = co_IntSendMessage(UserHMGetHandle(Wnd->spwndParent), WM_APPCOMMAND, wParam, lParam);
647          UserDerefObjectCo(Wnd->spwndParent);
648          break;
649 
650       case WM_KEYF1:
651       {
652          HELPINFO hi;
653          HMENU hMenu = UlongToHandle(Wnd->IDMenu);
654          PWND pwndActive = MENU_IsMenuActive();
655          hi.cbSize = sizeof(HELPINFO);
656          hi.MousePos = gpsi->ptCursor;
657          hi.iContextType = HELPINFO_MENUITEM;
658          hi.hItemHandle = pwndActive ? UserHMGetHandle(pwndActive) : UserHMGetHandle(Wnd);
659          hi.iCtrlId = (Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD ? IntMenuItemFromPoint(Wnd, hMenu, hi.MousePos) : 0;
660          hi.dwContextId = IntGetWindowContextHelpId(Wnd);
661 
662          co_IntSendMessage( UserHMGetHandle(Wnd), WM_HELP, 0, (LPARAM)&hi );
663          break;
664       }
665 
666       case WM_SETICON:
667       {
668          return DefWndSetIcon(Wnd, wParam, lParam);
669       }
670 
671       case WM_GETICON:
672       {
673          return DefWndGetIcon(Wnd, wParam, lParam);
674       }
675 
676       case WM_HELP:
677       {
678          PWND Parent = IntGetParent(Wnd);
679          co_IntSendMessage(UserHMGetHandle(Parent), Msg, wParam, lParam);
680          break;
681       }
682 
683       case WM_LBUTTONDOWN:
684       case WM_RBUTTONDOWN:
685       case WM_MBUTTONDOWN:
686           pti->MessageQueue->QF_flags &= ~(QF_FMENUSTATUS|QF_FMENUSTATUSBREAK);
687           break;
688 
689       case WM_NCLBUTTONDOWN:
690           return NC_HandleNCLButtonDown(Wnd, wParam, lParam);
691 
692       case WM_NCRBUTTONDOWN:
693           return NC_HandleNCRButtonDown(Wnd, wParam, lParam);
694 
695       case WM_LBUTTONDBLCLK:
696           return NC_HandleNCLButtonDblClk(Wnd, HTCLIENT, lParam);
697 
698       case WM_NCLBUTTONDBLCLK:
699           return NC_HandleNCLButtonDblClk(Wnd, wParam, lParam);
700 
701       case WM_RBUTTONUP:
702       {
703             POINT Pt;
704 
705             Pt.x = GET_X_LPARAM(lParam);
706             Pt.y = GET_Y_LPARAM(lParam);
707             IntClientToScreen(Wnd, &Pt);
708             lParam = MAKELPARAM(Pt.x, Pt.y);
709             co_IntSendMessage(UserHMGetHandle(Wnd), WM_CONTEXTMENU, (WPARAM)UserHMGetHandle(Wnd), lParam);
710             break;
711       }
712 
713       case WM_NCRBUTTONUP:
714           /*
715            * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
716            * in Windows), but what _should_ we do? According to MSDN :
717            * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
718            * message to the window". When is it appropriate?
719            */
720            ERR("WM_NCRBUTTONUP\n");
721           break;
722 
723       case WM_XBUTTONUP:
724       case WM_NCXBUTTONUP:
725           if (HIWORD(wParam) == XBUTTON1 || HIWORD(wParam) == XBUTTON2)
726           {
727               co_IntSendMessage(UserHMGetHandle(Wnd), WM_APPCOMMAND, (WPARAM)UserHMGetHandle(Wnd),
728                                 MAKELPARAM(LOWORD(wParam), FAPPCOMMAND_MOUSE | HIWORD(wParam)));
729           }
730           break;
731 
732 
733       case WM_CONTEXTMENU:
734       {
735             if (Wnd->style & WS_CHILD)
736             {
737                 co_IntSendMessage(UserHMGetHandle(IntGetParent(Wnd)), Msg, (WPARAM)UserHMGetHandle(Wnd), lParam);
738             }
739             else
740             {
741                 POINT Pt;
742                 LONG_PTR Style;
743                 LONG HitCode;
744 
745                 Style = Wnd->style;
746 
747                 Pt.x = GET_X_LPARAM(lParam);
748                 Pt.y = GET_Y_LPARAM(lParam);
749                 if (Style & WS_CHILD)
750                 {
751                     IntScreenToClient(IntGetParent(Wnd), &Pt);
752                 }
753 
754                 HitCode = GetNCHitEx(Wnd, Pt);
755 
756                 if (HitCode == HTCAPTION || HitCode == HTSYSMENU)
757                 {
758                     PMENU SystemMenu;
759                     UINT Flags;
760 
761                     if((SystemMenu = IntGetSystemMenu(Wnd, FALSE)))
762                     {
763                       MENU_InitSysMenuPopup(SystemMenu, Wnd->style, Wnd->pcls->style, HitCode);
764 
765                       if(HitCode == HTCAPTION)
766                         Flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON;
767                       else
768                         Flags = TPM_LEFTBUTTON;
769 
770                       IntTrackPopupMenuEx(SystemMenu, Flags|TPM_SYSTEM_MENU, Pt.x, Pt.y, Wnd, NULL);
771                     }
772                 }
773                 if (HitCode == HTHSCROLL || HitCode == HTVSCROLL)
774                 {
775                    WARN("Scroll Menu Not Supported\n");
776                 }
777 	    }
778             break;
779       }
780 
781       case WM_KEYDOWN:
782          if (wParam == VK_F10)
783          {
784             pti->MessageQueue->QF_flags |= QF_FF10STATUS;
785 
786             if (UserGetKeyState(VK_SHIFT) & 0x8000)
787             {
788                co_IntSendMessage(UserHMGetHandle(Wnd), WM_CONTEXTMENU, (WPARAM)UserHMGetHandle(Wnd), MAKELPARAM(-1, -1));
789             }
790          }
791          if (g_bWindowSnapEnabled && (IS_KEY_DOWN(gafAsyncKeyState, VK_LWIN) || IS_KEY_DOWN(gafAsyncKeyState, VK_RWIN)))
792          {
793             BOOL IsTaskBar;
794             DWORD StyleTB;
795             DWORD ExStyleTB;
796             HWND hwndTop = UserGetForegroundWindow();
797             PWND topWnd = UserGetWindowObject(hwndTop);
798 
799             // MS Doc: foreground window can be NULL, e.g. when window is losing activation
800             if (!topWnd)
801                return 0;
802 
803             // We want to forbid snapping operations on the TaskBar
804             // We use a heuristic for detecting the TaskBar Wnd by its typical Style & ExStyle Values
805             ExStyleTB = (topWnd->ExStyle & WS_EX_TOOLWINDOW);
806             StyleTB = (topWnd->style & (WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN));
807             IsTaskBar = (StyleTB == (WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN))
808                         && (ExStyleTB == WS_EX_TOOLWINDOW);
809             TRACE("ExStyle=%x Style=%x IsTaskBar=%d\n", ExStyleTB, StyleTB, IsTaskBar);
810 
811             if (!IsTaskBar)
812             {
813                if ((topWnd->style & WS_THICKFRAME) == 0)
814                   return 0;
815 
816                if (wParam == VK_DOWN)
817                {
818                    if (topWnd->style & WS_MAXIMIZE)
819                    {
820                        co_IntSendMessage(hwndTop, WM_SYSCOMMAND, SC_RESTORE, lParam);
821 
822                        /* "Normal size" must be erased after restoring, otherwise it will block next side snap actions */
823                        RECTL_vSetEmptyRect(&topWnd->InternalPos.NormalRect);
824                    }
825                    else
826                    {
827                        co_IntSendMessage(hwndTop, WM_SYSCOMMAND, SC_MINIMIZE, lParam);
828                    }
829                }
830                else if (wParam == VK_UP)
831                {
832                   RECT currentRect;
833                   if ((topWnd->InternalPos.NormalRect.right == topWnd->InternalPos.NormalRect.left) ||
834                       (topWnd->InternalPos.NormalRect.top == topWnd->InternalPos.NormalRect.bottom))
835                   {
836                       currentRect = topWnd->rcWindow;
837                   }
838                   else
839                   {
840                       currentRect = topWnd->InternalPos.NormalRect;
841                   }
842                   co_IntSendMessage(hwndTop, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
843 
844                   // save normal rect if maximazing snapped window
845                   topWnd->InternalPos.NormalRect = currentRect;
846                }
847                else if (wParam == VK_LEFT || wParam == VK_RIGHT)
848                {
849                   RECT snapRect, normalRect, windowRect;
850                   BOOL snapped;
851                   normalRect = topWnd->InternalPos.NormalRect;
852                   snapped = (normalRect.left != 0 && normalRect.right != 0 &&
853                              normalRect.top != 0 && normalRect.bottom != 0);
854 
855                   if (topWnd->style & WS_MAXIMIZE)
856                   {
857                      co_IntSendMessage(hwndTop, WM_SYSCOMMAND, SC_RESTORE, lParam);
858                      snapped = FALSE;
859                   }
860                   windowRect = topWnd->rcWindow;
861 
862                   UserSystemParametersInfo(SPI_GETWORKAREA, 0, &snapRect, 0);
863                   if (wParam == VK_LEFT)
864                   {
865                      snapRect.right = (snapRect.left + snapRect.right) / 2;
866                   }
867                   else // VK_RIGHT
868                   {
869                      snapRect.left = (snapRect.left + snapRect.right) / 2;
870                   }
871 
872                   if (snapped)
873                   {
874                      // if window was snapped but moved to other location - restore normal size
875                      if (!IntEqualRect(&snapRect, &windowRect))
876                      {
877                         RECT empty = {0, 0, 0, 0};
878                         co_WinPosSetWindowPos(topWnd,
879                                               0,
880                                               normalRect.left,
881                                               normalRect.top,
882                                               normalRect.right - normalRect.left,
883                                               normalRect.bottom - normalRect.top,
884                                               0);
885                         topWnd->InternalPos.NormalRect = empty;
886                      }
887                   }
888                   else
889                   {
890                      co_WinPosSetWindowPos(topWnd,
891                                            0,
892                                            snapRect.left,
893                                            snapRect.top,
894                                            snapRect.right - snapRect.left,
895                                            snapRect.bottom - snapRect.top,
896                                            0);
897                      topWnd->InternalPos.NormalRect = windowRect;
898                   }
899                }
900             }
901          }
902          break;
903 
904       case WM_SYSKEYDOWN:
905       {
906             if (HIWORD(lParam) & KF_ALTDOWN)
907             {   /* Previous state, if the key was down before this message,
908                    this is a cheap way to ignore autorepeat keys. */
909                 if ( !(HIWORD(lParam) & KF_REPEAT) )
910                 {
911                    if ( ( wParam == VK_MENU  ||
912                           wParam == VK_LMENU ||
913                           wParam == VK_RMENU ) && !(pti->MessageQueue->QF_flags & QF_FMENUSTATUS)) //iMenuSysKey )
914                        pti->MessageQueue->QF_flags |= QF_FMENUSTATUS; //iMenuSysKey = 1;
915                    else
916                        pti->MessageQueue->QF_flags &= ~QF_FMENUSTATUS; //iMenuSysKey = 0;
917                 }
918 
919                 pti->MessageQueue->QF_flags &= ~QF_FF10STATUS; //iF10Key = 0;
920 
921                 if (wParam == VK_F4) /* Try to close the window */
922                 {
923                    PWND top = UserGetAncestor(Wnd, GA_ROOT);
924                    if (!(top->style & CS_NOCLOSE))
925                       UserPostMessage(UserHMGetHandle(top), WM_SYSCOMMAND, SC_CLOSE, 0);
926                 }
927                 else if (wParam == VK_SNAPSHOT) // Alt-VK_SNAPSHOT?
928                 {
929                    PWND pwnd = Wnd;
930                    while (IntGetParent(pwnd) != NULL)
931                    {
932                        pwnd = IntGetParent(pwnd);
933                    }
934                    ERR("DefWndScreenshot\n");
935                    DefWndScreenshot(pwnd);
936                 }
937                 else if ( wParam == VK_ESCAPE || wParam == VK_TAB ) // Alt-Tab/ESC Alt-Shift-Tab/ESC
938                 {
939                    WPARAM wParamTmp;
940                    HWND Active = UserGetActiveWindow(); // Noticed MDI problem.
941                    if (!Active)
942                    {
943                       FIXME("WM_SYSKEYDOWN VK_ESCAPE no active\n");
944                       break;
945                    }
946                    wParamTmp = UserGetKeyState(VK_SHIFT) & 0x8000 ? SC_PREVWINDOW : SC_NEXTWINDOW;
947                    co_IntSendMessage( Active, WM_SYSCOMMAND, wParamTmp, wParam );
948                 }
949                 else if (wParam == VK_SHIFT) // Alt+Shift
950                 {
951                     RTL_ATOM ClassAtom = 0;
952                     UNICODE_STRING ustrClass, ustrWindow;
953                     HWND hwndSwitch;
954 
955                     RtlInitUnicodeString(&ustrClass, L"kbswitcher");
956                     RtlInitUnicodeString(&ustrWindow, L"");
957 
958                     IntGetAtomFromStringOrAtom(&ustrClass, &ClassAtom);
959 
960                     hwndSwitch = IntFindWindow(UserGetDesktopWindow(), NULL, ClassAtom, &ustrWindow);
961                     if (hwndSwitch)
962                     {
963 #define ID_NEXTLAYOUT 10003
964                         UserPostMessage(hwndSwitch, WM_COMMAND, ID_NEXTLAYOUT, (LPARAM)UserHMGetHandle(Wnd));
965                     }
966                 }
967             }
968             else if( wParam == VK_F10 )
969             {
970                 if (UserGetKeyState(VK_SHIFT) & 0x8000)
971                     co_IntSendMessage( UserHMGetHandle(Wnd), WM_CONTEXTMENU, (WPARAM)UserHMGetHandle(Wnd), MAKELPARAM(-1, -1) );
972                 pti->MessageQueue->QF_flags |= QF_FF10STATUS; //iF10Key = 1;
973             }
974             else if( wParam == VK_ESCAPE && (UserGetKeyState(VK_SHIFT) & 0x8000))
975                   co_IntSendMessage( UserHMGetHandle(Wnd), WM_SYSCOMMAND, SC_KEYMENU, ' ' );
976             break;
977       }
978 
979       case WM_KEYUP:
980       case WM_SYSKEYUP:
981       {
982            /* Press and release F10 or ALT */
983             if (((wParam == VK_MENU || wParam == VK_LMENU || wParam == VK_RMENU)
984                  && (pti->MessageQueue->QF_flags & (QF_FMENUSTATUS|QF_FMENUSTATUSBREAK)) == QF_FMENUSTATUS /*iMenuSysKey*/) ||
985                  ((wParam == VK_F10) && pti->MessageQueue->QF_flags & QF_FF10STATUS /*iF10Key*/))
986                 co_IntSendMessage( UserHMGetHandle(UserGetAncestor( Wnd, GA_ROOT )), WM_SYSCOMMAND, SC_KEYMENU, 0L );
987             pti->MessageQueue->QF_flags &= ~(QF_FMENUSTATUS|QF_FMENUSTATUSBREAK|QF_FF10STATUS); //iMenuSysKey = iF10Key = 0;
988             break;
989       }
990 
991       case WM_SYSCHAR:
992       {
993             pti->MessageQueue->QF_flags &= ~(QF_FMENUSTATUS|QF_FMENUSTATUSBREAK); //iMenuSysKey = 0;
994             if (wParam == VK_RETURN && (Wnd->style & WS_MINIMIZE) != 0)
995             {
996                 UserPostMessage( UserHMGetHandle(Wnd), WM_SYSCOMMAND, SC_RESTORE, 0L );
997                 break;
998             }
999             if ((HIWORD(lParam) & KF_ALTDOWN) && wParam)
1000             {
1001                 if (wParam == VK_TAB || wParam == VK_ESCAPE) break;
1002                 if (wParam == VK_SPACE && Wnd->style & WS_CHILD)
1003                     co_IntSendMessage( UserHMGetHandle(IntGetParent(Wnd)), Msg, wParam, lParam );
1004                 else
1005                     co_IntSendMessage( UserHMGetHandle(Wnd), WM_SYSCOMMAND, SC_KEYMENU, wParam );
1006             }
1007             else /* check for Ctrl-Esc */
1008                 if (wParam != VK_ESCAPE) UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_MESSAGE_BEEP, 0); //MessageBeep(0);
1009             break;
1010       }
1011 
1012       case WM_CANCELMODE:
1013       {
1014          pti->MessageQueue->QF_flags &= ~(QF_FMENUSTATUS|QF_FMENUSTATUSBREAK);
1015 
1016          MENU_EndMenu( Wnd );
1017          if (IntGetCaptureWindow() == UserHMGetHandle(Wnd))
1018          {
1019             IntReleaseCapture();
1020          }
1021          break;
1022       }
1023 
1024       case WM_CLOSE:
1025          co_UserDestroyWindow(Wnd);
1026          break;
1027 
1028       case WM_CTLCOLORMSGBOX:
1029       case WM_CTLCOLOREDIT:
1030       case WM_CTLCOLORLISTBOX:
1031       case WM_CTLCOLORBTN:
1032       case WM_CTLCOLORDLG:
1033       case WM_CTLCOLORSTATIC:
1034       case WM_CTLCOLORSCROLLBAR:
1035            return (LRESULT) DefWndControlColor((HDC)wParam, Msg - WM_CTLCOLORMSGBOX);
1036 
1037       case WM_CTLCOLOR:
1038            return (LRESULT) DefWndControlColor((HDC)wParam, HIWORD(lParam));
1039 
1040       case WM_SETCURSOR:
1041       {
1042          if (Wnd->style & WS_CHILD)
1043          {
1044              /* with the exception of the border around a resizable wnd,
1045               * give the parent first chance to set the cursor */
1046              if (LOWORD(lParam) < HTLEFT || LOWORD(lParam) > HTBOTTOMRIGHT)
1047              {
1048                  PWND parent = Wnd->spwndParent;//IntGetParent( Wnd );
1049                  if (parent != UserGetDesktopWindow() &&
1050                      co_IntSendMessage( UserHMGetHandle(parent), WM_SETCURSOR, wParam, lParam))
1051                     return TRUE;
1052              }
1053          }
1054          return DefWndHandleSetCursor(Wnd, wParam, lParam);
1055       }
1056 
1057       case WM_MOUSEACTIVATE:
1058          if (Wnd->style & WS_CHILD)
1059          {
1060              LONG Ret;
1061              HWND hwndParent;
1062              PWND pwndParent = IntGetParent(Wnd);
1063              hwndParent = pwndParent ? UserHMGetHandle(pwndParent) : NULL;
1064              if (hwndParent) Ret = co_IntSendMessage(hwndParent, WM_MOUSEACTIVATE, wParam, lParam);
1065              if (Ret) return (Ret);
1066          }
1067          return ( (HIWORD(lParam) == WM_LBUTTONDOWN && LOWORD(lParam) == HTCAPTION) ? MA_NOACTIVATE : MA_ACTIVATE );
1068 
1069       case WM_ACTIVATE:
1070        /* The default action in Windows is to set the keyboard focus to
1071         * the window, if it's being activated and not minimized */
1072          if (LOWORD(wParam) != WA_INACTIVE &&
1073               !(Wnd->style & WS_MINIMIZE))
1074          {
1075             //ERR("WM_ACTIVATE %p\n",hWnd);
1076             co_UserSetFocus(Wnd);
1077          }
1078          break;
1079 
1080       case WM_MOUSEWHEEL:
1081          if (Wnd->style & WS_CHILD)
1082          {
1083             HWND hwndParent;
1084             PWND pwndParent = IntGetParent(Wnd);
1085             hwndParent = pwndParent ? UserHMGetHandle(pwndParent) : NULL;
1086             return co_IntSendMessage( hwndParent, WM_MOUSEWHEEL, wParam, lParam);
1087          }
1088          break;
1089 
1090       case WM_ERASEBKGND:
1091       case WM_ICONERASEBKGND:
1092       {
1093          RECT Rect;
1094          HBRUSH hBrush = Wnd->pcls->hbrBackground;
1095          if (!hBrush) return 0;
1096          if (hBrush <= (HBRUSH)COLOR_MENUBAR)
1097          {
1098             hBrush = IntGetSysColorBrush(HandleToUlong(hBrush));
1099          }
1100          if (Wnd->pcls->style & CS_PARENTDC)
1101          {
1102             /* can't use GetClipBox with a parent DC or we fill the whole parent */
1103             IntGetClientRect(Wnd, &Rect);
1104             GreDPtoLP((HDC)wParam, (LPPOINT)&Rect, 2);
1105          }
1106          else
1107          {
1108             GdiGetClipBox((HDC)wParam, &Rect);
1109          }
1110          FillRect((HDC)wParam, &Rect, hBrush);
1111          return (1);
1112       }
1113 
1114       case WM_GETHOTKEY:
1115          //ERR("WM_GETHOTKEY\n");
1116          return DefWndGetHotKey(Wnd);
1117       case WM_SETHOTKEY:
1118          //ERR("WM_SETHOTKEY\n");
1119          return DefWndSetHotKey(Wnd, wParam);
1120 
1121       case WM_NCHITTEST:
1122       {
1123          POINT Point;
1124          Point.x = GET_X_LPARAM(lParam);
1125          Point.y = GET_Y_LPARAM(lParam);
1126          return GetNCHitEx(Wnd, Point);
1127       }
1128 
1129       case WM_PRINT:
1130       {
1131          DefWndPrint(Wnd, (HDC)wParam, lParam);
1132          return (0);
1133       }
1134 
1135       case WM_SYSCOLORCHANGE:
1136       {
1137          /* force to redraw non-client area */
1138          UserPaintCaption(Wnd, DC_NC);
1139          /* Use InvalidateRect to redraw client area, enable
1140           * erase to redraw all subcontrols otherwise send the
1141           * WM_SYSCOLORCHANGE to child windows/controls is required
1142           */
1143          co_UserRedrawWindow( Wnd, NULL, NULL, RDW_ALLCHILDREN|RDW_INVALIDATE|RDW_ERASE);
1144          return (0);
1145       }
1146 
1147       case WM_PAINTICON:
1148       case WM_PAINT:
1149       {
1150          PAINTSTRUCT Ps;
1151          HDC hDC;
1152 
1153          /* If already in Paint and Client area is not empty just return. */
1154          if (Wnd->state2 & WNDS2_STARTPAINT && !RECTL_bIsEmptyRect(&Wnd->rcClient))
1155          {
1156             ERR("In Paint and Client area is not empty!\n");
1157             return 0;
1158          }
1159 
1160          hDC = IntBeginPaint(Wnd, &Ps);
1161          if (hDC)
1162          {
1163              if (((Wnd->style & WS_MINIMIZE) != 0) && (Wnd->pcls->spicn))
1164              {
1165                  RECT ClientRect;
1166                  INT x, y;
1167 
1168                  ERR("Doing Paint and Client area is empty!\n");
1169                  IntGetClientRect(Wnd, &ClientRect);
1170                  x = (ClientRect.right - ClientRect.left - UserGetSystemMetrics(SM_CXICON)) / 2;
1171                  y = (ClientRect.bottom - ClientRect.top - UserGetSystemMetrics(SM_CYICON)) / 2;
1172                  UserReferenceObject(Wnd->pcls->spicn);
1173                  UserDrawIconEx(hDC, x, y, Wnd->pcls->spicn, 0, 0, 0, 0, DI_NORMAL | DI_COMPAT | DI_DEFAULTSIZE);
1174                  UserDereferenceObject(Wnd->pcls->spicn);
1175              }
1176 
1177              IntEndPaint(Wnd, &Ps);
1178          }
1179          return (0);
1180       }
1181 
1182       case WM_SYNCPAINT:
1183       {
1184          HRGN hRgn;
1185          Wnd->state &= ~WNDS_SYNCPAINTPENDING;
1186          TRACE("WM_SYNCPAINT\n");
1187          hRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
1188          if (hRgn)
1189          {
1190              if (co_UserGetUpdateRgn(Wnd, hRgn, FALSE) != NULLREGION)
1191              {
1192                 PREGION pRgn = REGION_LockRgn(hRgn);
1193                 if (pRgn) REGION_UnlockRgn(pRgn);
1194                 if (!wParam)
1195                     wParam = (RDW_ERASENOW | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN);
1196                 co_UserRedrawWindow(Wnd, NULL, pRgn, wParam);
1197              }
1198              GreDeleteObject(hRgn);
1199          }
1200          return 0;
1201       }
1202 
1203       case WM_SETREDRAW:
1204           if (wParam)
1205           {
1206              if (!(Wnd->style & WS_VISIBLE))
1207              {
1208                 IntSetStyle( Wnd, WS_VISIBLE, 0 );
1209                 Wnd->state |= WNDS_SENDNCPAINT;
1210              }
1211           }
1212           else
1213           {
1214              if (Wnd->style & WS_VISIBLE)
1215              {
1216                 co_UserRedrawWindow( Wnd, NULL, NULL, RDW_ALLCHILDREN | RDW_VALIDATE );
1217                 IntSetStyle( Wnd, 0, WS_VISIBLE );
1218              }
1219           }
1220           return 0;
1221 
1222       case WM_WINDOWPOSCHANGING:
1223       {
1224           return (DefWndHandleWindowPosChanging(Wnd, (WINDOWPOS*)lParam));
1225       }
1226 
1227       case WM_WINDOWPOSCHANGED:
1228       {
1229           return (DefWndHandleWindowPosChanged(Wnd, (WINDOWPOS*)lParam));
1230       }
1231 
1232       case WM_NCCALCSIZE:
1233       {
1234          return NC_HandleNCCalcSize( Wnd, wParam, (RECTL *)lParam, FALSE );
1235       }
1236 
1237       case WM_NCACTIVATE:
1238       {
1239           return NC_HandleNCActivate( Wnd, wParam, lParam );
1240       }
1241 
1242       //
1243       // NC Paint mode.
1244       //
1245       case WM_NCPAINT:
1246       {
1247           HDC hDC = UserGetDCEx(Wnd, (HRGN)wParam, DCX_WINDOW | DCX_INTERSECTRGN | DCX_USESTYLE | DCX_KEEPCLIPRGN);
1248           Wnd->state |= WNDS_FORCEMENUDRAW;
1249           NC_DoNCPaint(Wnd, hDC, -1);
1250           Wnd->state &= ~WNDS_FORCEMENUDRAW;
1251           UserReleaseDC(Wnd, hDC, FALSE);
1252           return 0;
1253       }
1254       //
1255       //  Draw Caption mode.
1256       //
1257       //  wParam are DC_* flags.
1258       //
1259       case WM_NCUAHDRAWCAPTION:
1260       {
1261           HDC hDC = UserGetDCEx(Wnd, NULL, DCX_WINDOW|DCX_USESTYLE);
1262           TRACE("WM_NCUAHDRAWCAPTION: wParam DC_ flags %08x\n",wParam);
1263           UserDrawCaptionBar(Wnd, hDC, wParam | DC_FRAME); // Include DC_FRAME to comp for drawing glitch.
1264           UserReleaseDC(Wnd, hDC, FALSE);
1265           return 0;
1266       }
1267       //
1268       //  Draw Frame mode.
1269       //
1270       //  wParam is HDC, lParam are DC_ACTIVE and or DC_REDRAWHUNGWND.
1271       //
1272       case WM_NCUAHDRAWFRAME:
1273       {
1274           TRACE("WM_NCUAHDRAWFRAME: wParam hDC %p lParam DC_ flags %08x\n",wParam,lParam);
1275           NC_DoNCPaint(Wnd, (HDC)wParam, lParam|DC_NC);
1276           return 0;
1277       }
1278 
1279       /* ReactOS only. */
1280       case WM_CBT:
1281       {
1282          switch (wParam)
1283          {
1284             case HCBT_MOVESIZE:
1285             {
1286                RECTL rt;
1287 
1288                if (lParam)
1289                {
1290                   _SEH2_TRY
1291                   {
1292                       ProbeForRead((PVOID)lParam,
1293                                    sizeof(RECT),
1294                                    1);
1295 
1296                       RtlCopyMemory(&rt,
1297                                     (PVOID)lParam,
1298                                     sizeof(RECT));
1299                   }
1300                   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1301                   {
1302                       lResult = 1;
1303                   }
1304                   _SEH2_END;
1305                }
1306                if (!lResult)
1307                   lResult = co_HOOK_CallHooks(WH_CBT, HCBT_MOVESIZE, (WPARAM)Wnd->head.h, lParam ? (LPARAM)&rt : 0);
1308            }
1309             break;
1310          }
1311          break;
1312       }
1313       break;
1314    }
1315    return lResult;
1316 }
1317 
1318 /* EOF */
1319