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