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