xref: /reactos/win32ss/user/user32/windows/defwnd.c (revision 49bb853b)
1 /*
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS user32.dll
5  * FILE:            win32ss/user/user32/windows/defwnd.c
6  * PURPOSE:         Window management
7  * PROGRAMMER:      Casper S. Hornstrup (chorns@users.sourceforge.net)
8  * UPDATE HISTORY:
9  *      06-06-2001  CSH  Created
10  */
11 
12 #include <user32.h>
13 
14 WINE_DEFAULT_DEBUG_CHANNEL(user32);
15 
16 /*
17  * @implemented
18  */
19 DWORD
20 WINAPI
21 DECLSPEC_HOTPATCH
22 GetSysColor(int nIndex)
23 {
24   if(nIndex >= 0 && nIndex < NUM_SYSCOLORS)
25   {
26     return gpsi->argbSystem[nIndex];
27   }
28 
29   SetLastError(ERROR_INVALID_PARAMETER);
30   return 0;
31 }
32 
33 /*
34  * @implemented
35  */
36 HBRUSH
37 WINAPI
38 DECLSPEC_HOTPATCH
39 GetSysColorBrush(int nIndex)
40 {
41   if(nIndex >= 0 && nIndex < NUM_SYSCOLORS)
42   {
43     return gpsi->ahbrSystem[nIndex];
44   }
45 
46   return NULL;
47 }
48 
49 /*
50  * @implemented
51  */
52 BOOL
53 WINAPI
54 SetSysColors(
55   int cElements,
56   CONST INT *lpaElements,
57   CONST COLORREF *lpaRgbValues)
58 {
59   return NtUserSetSysColors(cElements, lpaElements, lpaRgbValues, 0);
60 }
61 
62 BOOL
63 FASTCALL
64 DefSetText(HWND hWnd, PCWSTR String, BOOL Ansi)
65 {
66   BOOL Ret;
67   LARGE_STRING lsString;
68 
69   if ( String )
70   {
71      if ( Ansi )
72         RtlInitLargeAnsiString((PLARGE_ANSI_STRING)&lsString, (PCSZ)String, 0);
73      else
74         RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&lsString, String, 0);
75   }
76   Ret = NtUserDefSetText(hWnd, (String ? &lsString : NULL));
77 
78   return Ret;
79 }
80 
81 HWND FASTCALL
82 IntFindChildWindowToOwner(HWND hRoot, HWND hOwner)
83 {
84    HWND Ret;
85    PWND Child, OwnerWnd, Root, Owner;
86 
87    Root = ValidateHwnd(hRoot);
88    Owner = ValidateHwnd(hOwner);
89 
90    for( Child = Root->spwndChild ? DesktopPtrToUser(Root->spwndChild) : NULL;
91         Child;
92         Child = Child->spwndNext ? DesktopPtrToUser(Child->spwndNext) : NULL )
93    {
94       OwnerWnd = Child->spwndOwner ? DesktopPtrToUser(Child->spwndOwner) : NULL;
95       if(!OwnerWnd)
96          continue;
97 
98       if (!(Child->style & WS_POPUP) || !(Child->style & WS_VISIBLE))
99          continue;
100 
101       if(OwnerWnd == Owner)
102       {
103          Ret = Child->head.h;
104          return Ret;
105       }
106    }
107    ERR("IDCWTO Nothing found\n");
108    return NULL;
109 }
110 
111 /***********************************************************************
112  *           DefWndTrackScrollBar
113  *
114  * Track a mouse button press on the horizontal or vertical scroll-bar.
115  */
116 static  VOID
117 DefWndTrackScrollBar(HWND Wnd, WPARAM wParam, POINT Pt)
118 {
119   INT ScrollBar;
120 
121   if (SC_HSCROLL == (wParam & 0xfff0))
122     {
123       if (HTHSCROLL != (wParam & 0x0f))
124         {
125           return;
126         }
127       ScrollBar = SB_HORZ;
128     }
129   else  /* SC_VSCROLL */
130     {
131       if (HTVSCROLL != (wParam & 0x0f))
132         {
133           return;
134         }
135       ScrollBar = SB_VERT;
136     }
137   ScrollTrackScrollBar(Wnd, ScrollBar, Pt );
138 }
139 
140 LRESULT WINAPI DoAppSwitch( WPARAM wParam, LPARAM lParam);
141 
142 LRESULT
143 DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
144 {
145   POINT Pt;
146   LRESULT lResult;
147 
148   if (!IsWindowEnabled( hWnd )) return 0;
149 
150   switch (wParam & 0xfff0)
151     {
152       case SC_MOVE:
153       case SC_SIZE:
154 //      case SC_DEFAULT:
155       case SC_MOUSEMENU:
156       case SC_KEYMENU:
157       case SC_SCREENSAVE:
158       case SC_MINIMIZE:
159       case SC_MAXIMIZE:
160       case SC_RESTORE:
161       case SC_CLOSE:
162       case SC_HOTKEY:
163         NtUserMessageCall( hWnd, WM_SYSCOMMAND, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE);
164         return 0;
165 
166       default:
167         break;
168     }
169 
170   if (ISITHOOKED(WH_CBT))
171   {
172      NtUserMessageCall( hWnd, WM_SYSCOMMAND, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE);
173      if (lResult) return 0;
174   }
175 
176   switch (wParam & 0xfff0)
177     {
178 
179       case SC_VSCROLL:
180       case SC_HSCROLL:
181         {
182           Pt.x = (short)LOWORD(lParam);
183           Pt.y = (short)HIWORD(lParam);
184           DefWndTrackScrollBar(hWnd, wParam, Pt);
185         }
186 	break;
187 
188       case SC_TASKLIST:
189         WinExec( "taskman.exe", SW_SHOWNORMAL );
190         break;
191 
192 
193       case SC_NEXTWINDOW:
194       case SC_PREVWINDOW:
195         DoAppSwitch( wParam, lParam);
196         break;
197 
198       default:
199         FIXME("Unimplemented DefWndHandleSysCommand wParam 0x%x\n",wParam);
200         break;
201     }
202 
203   return(0);
204 }
205 
206 /***********************************************************************
207  *           DefWndControlColor
208  *
209  * Default colors for control painting.
210  */
211 HBRUSH
212 DefWndControlColor(HDC hDC, UINT ctlType)
213 {
214   if (ctlType == CTLCOLOR_SCROLLBAR)
215   {
216       HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR);
217       COLORREF bk = GetSysColor(COLOR_3DHILIGHT);
218       SetTextColor(hDC, GetSysColor(COLOR_3DFACE));
219       SetBkColor(hDC, bk);
220 
221       /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
222        * we better use 0x55aa bitmap brush to make scrollbar's background
223        * look different from the window background.
224        */
225       if ( bk == GetSysColor(COLOR_WINDOW))
226           return gpsi->hbrGray;
227 
228       UnrealizeObject( hb );
229       return hb;
230   }
231 
232   SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
233 
234   if ((ctlType == CTLCOLOR_EDIT) || (ctlType == CTLCOLOR_LISTBOX))
235   {
236       SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
237   }
238   else
239   {
240       SetBkColor(hDC, GetSysColor(COLOR_3DFACE));
241       return GetSysColorBrush(COLOR_3DFACE);
242   }
243 
244   return GetSysColorBrush(COLOR_WINDOW);
245 }
246 
247 static BOOL CALLBACK
248 UserSendUiUpdateMsg(HWND hwnd, LPARAM lParam)
249 {
250     SendMessageW(hwnd, WM_UPDATEUISTATE, (WPARAM)lParam, 0);
251     return TRUE;
252 }
253 
254 /* WARNING: Redundant with /ntuser/defwnd.c!UserPaintCaption !!
255    Use TWOPARAM_ROUTINE_REDRAWTITLE/REDRAWFRAME or HWNDLOCK_ROUTINE_REDRAWFRAMEANDHOOK .
256  */
257 static void
258 UserPaintCaption(PWND pwnd, INT Flags)
259 {
260   if ( pwnd->style & WS_VISIBLE && (pwnd->style & WS_CAPTION) == WS_CAPTION )
261   {
262      if (pwnd->state & WNDS_HASCAPTION && NtUserQueryWindow(UserHMGetHandle(pwnd), QUERY_WINDOW_FOREGROUND))
263         Flags |= DC_ACTIVE;
264     /*
265      * When themes are not enabled we can go on and paint the non client area.
266      * However if we do that with themes enabled we will draw a classic frame.
267      * This is solved by sending a themes specific message to notify the themes
268      * engine that the caption needs to be redrawn
269      */
270     if(gpsi->dwSRVIFlags & SRVINFO_APIHOOK)
271     {
272         /*
273          * This will cause uxtheme to either paint the themed caption or call
274          * RealUserDrawCaption in order to draw the classic caption when themes
275          * are disabled but the themes service is enabled
276          */
277         SendMessageW(UserHMGetHandle(pwnd), WM_NCUAHDRAWCAPTION, Flags, 0);
278     }
279     else
280     {
281         RECT rc = {0,0,0,0};
282         HDC hDC = GetDCEx(UserHMGetHandle(pwnd), NULL, DCX_WINDOW|DCX_USESTYLE);
283         NtUserDrawCaption(UserHMGetHandle(pwnd), hDC, &rc, DC_DRAWCAPTIONMD|Flags);
284         ReleaseDC(UserHMGetHandle(pwnd), hDC);
285     }
286   }
287   //NtUserCallTwoParam((DWORD_PTR)UserHMGetHandle(pwnd),Flags,TWOPARAM_ROUTINE_REDRAWTITLE)
288 }
289 
290 LRESULT FASTCALL
291 DefWndGetIcon(PWND pWnd, WPARAM wParam, LPARAM lParam)
292 {
293     HICON hIconRet;
294     if ( wParam > ICON_SMALL2 )
295     {
296         SetLastError(ERROR_INVALID_PARAMETER);
297         return 0;
298     }
299     switch(wParam)
300     {
301         case ICON_BIG:
302             hIconRet = UserGetProp(UserHMGetHandle(pWnd), gpsi->atomIconProp, TRUE);
303             break;
304         case ICON_SMALL:
305         case ICON_SMALL2:
306             hIconRet = UserGetProp(UserHMGetHandle(pWnd), gpsi->atomIconSmProp, TRUE);
307             break;
308         default:
309             break;
310     }
311     return (LRESULT)hIconRet;
312 }
313 
314 
315 LRESULT WINAPI
316 User32DefWindowProc(HWND hWnd,
317                     UINT Msg,
318                     WPARAM wParam,
319                     LPARAM lParam,
320                     BOOL bUnicode)
321 {
322     PWND pWnd = NULL;
323     if (hWnd)
324     {
325        pWnd = ValidateHwnd(hWnd);
326        if (!pWnd) return 0;
327     }
328 
329     switch (Msg)
330     {
331         case WM_DEVICECHANGE:
332             return TRUE;
333 
334         case WM_POPUPSYSTEMMENU:
335         {
336             /* This is an undocumented message used by the windows taskbar to
337                display the system menu of windows that belong to other processes. */
338             HMENU menu = GetSystemMenu(hWnd, FALSE);
339             ERR("WM_POPUPSYSTEMMENU\n");
340             if (menu)
341             {
342                 SetForegroundWindow(hWnd);
343                 TrackPopupMenu(menu, TPM_LEFTBUTTON|TPM_RIGHTBUTTON|TPM_SYSTEM_MENU,
344                                LOWORD(lParam), HIWORD(lParam), 0, hWnd, NULL);
345             }
346             return 0;
347         }
348 
349         case WM_RBUTTONUP:
350         {
351             POINT Pt;
352             Pt.x = GET_X_LPARAM(lParam);
353             Pt.y = GET_Y_LPARAM(lParam);
354             ClientToScreen(hWnd, &Pt);
355             lParam = MAKELPARAM(Pt.x, Pt.y);
356             if (bUnicode)
357             {
358                 SendMessageW(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
359             }
360             else
361             {
362                 SendMessageA(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
363             }
364             break;
365         }
366 
367         case WM_NCRBUTTONUP:
368           /*
369            * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
370            * in Windows), but what _should_ we do? According to MSDN :
371            * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
372            * message to the window". When is it appropriate?
373            */
374            ERR("WM_NCRBUTTONUP\n");
375             break;
376 
377         case WM_XBUTTONUP:
378         case WM_NCXBUTTONUP:
379             if (HIWORD(wParam) == XBUTTON1 || HIWORD(wParam) == XBUTTON2)
380             {
381                SendMessageW(hWnd, WM_APPCOMMAND, (WPARAM)hWnd,
382                          MAKELPARAM(LOWORD(wParam), FAPPCOMMAND_MOUSE | HIWORD(wParam)));
383             }
384             break;
385 
386         case WM_CONTEXTMENU:
387         {
388             if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD)
389             {
390                 if (bUnicode)
391                 {
392                     SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
393                 }
394                 else
395                 {
396                     SendMessageA(GetParent(hWnd), WM_CONTEXTMENU, wParam, lParam);
397                 }
398             }
399             else
400             {
401                goto GoSS;
402             }
403             break;
404         }
405 
406         case WM_CLOSE:
407             DestroyWindow(hWnd);
408             return (0);
409 
410         case WM_MOUSEACTIVATE:
411             if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD)
412             {
413                 LONG Ret = SendMessageW(GetParent(hWnd), WM_MOUSEACTIVATE, wParam, lParam);
414                 if (Ret) return (Ret);
415             }
416             return ( (HIWORD(lParam) == WM_LBUTTONDOWN && LOWORD(lParam) == HTCAPTION) ? MA_NOACTIVATE : MA_ACTIVATE );
417 
418         case WM_ACTIVATE:
419             /* The default action in Windows is to set the keyboard focus to
420              * the window, if it's being activated and not minimized */
421             if (LOWORD(wParam) != WA_INACTIVE &&
422                 !(GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MINIMIZE))
423             {
424                 //ERR("WM_ACTIVATE %p\n",hWnd);
425                 SetFocus(hWnd);
426             }
427             break;
428 
429         case WM_MOUSEWHEEL:
430             if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD)
431                 return SendMessageW( GetParent(hWnd), WM_MOUSEWHEEL, wParam, lParam);
432             break;
433 
434         case WM_ERASEBKGND:
435         case WM_ICONERASEBKGND:
436         {
437             RECT Rect;
438             HBRUSH hBrush = (HBRUSH)GetClassLongPtrW(hWnd, GCL_HBRBACKGROUND);
439 
440             if (NULL == hBrush)
441             {
442                 return 0;
443             }
444             if (GetClassLongPtrW(hWnd, GCL_STYLE) & CS_PARENTDC)
445             {
446                 /* can't use GetClipBox with a parent DC or we fill the whole parent */
447                 GetClientRect(hWnd, &Rect);
448                 DPtoLP((HDC)wParam, (LPPOINT)&Rect, 2);
449             }
450             else
451             {
452                 GetClipBox((HDC)wParam, &Rect);
453             }
454             FillRect((HDC)wParam, &Rect, hBrush);
455             return (1);
456         }
457 
458         case WM_CTLCOLORMSGBOX:
459         case WM_CTLCOLOREDIT:
460         case WM_CTLCOLORLISTBOX:
461         case WM_CTLCOLORBTN:
462         case WM_CTLCOLORDLG:
463         case WM_CTLCOLORSTATIC:
464         case WM_CTLCOLORSCROLLBAR:
465             return (LRESULT) DefWndControlColor((HDC)wParam, Msg - WM_CTLCOLORMSGBOX);
466 
467         case WM_CTLCOLOR:
468             return (LRESULT) DefWndControlColor((HDC)wParam, HIWORD(lParam));
469 
470         case WM_SYSCOMMAND:
471             return (DefWndHandleSysCommand(hWnd, wParam, lParam));
472 
473         case WM_VKEYTOITEM:
474         case WM_CHARTOITEM:
475             return (-1);
476 /*
477         case WM_DROPOBJECT:
478             return DRAG_FILE;
479 */
480         case WM_QUERYDROPOBJECT:
481         {
482             if (GetWindowLongPtrW(hWnd, GWL_EXSTYLE) & WS_EX_ACCEPTFILES)
483             {
484                 return(1);
485             }
486             break;
487         }
488 
489         case WM_QUERYDRAGICON:
490         {
491             UINT Len;
492             HICON hIcon;
493 
494             hIcon = (HICON)GetClassLongPtrW(hWnd, GCL_HICON);
495             if (hIcon)
496             {
497                 return ((LRESULT)hIcon);
498             }
499             for (Len = 1; Len < 64; Len++)
500             {
501                 if ((hIcon = LoadIconW(NULL, MAKEINTRESOURCEW(Len))) != NULL)
502                 {
503                     return((LRESULT)hIcon);
504                 }
505             }
506             return ((LRESULT)LoadIconW(0, IDI_APPLICATION));
507         }
508 
509         case WM_ISACTIVEICON:
510         {
511            BOOL isai;
512            isai = (pWnd->state & WNDS_ACTIVEFRAME) != 0;
513            return isai;
514         }
515 
516         case WM_NOTIFYFORMAT:
517         {
518             if (lParam == NF_QUERY)
519                 return IsWindowUnicode(hWnd) ? NFR_UNICODE : NFR_ANSI;
520             break;
521         }
522 
523         case WM_GETICON:
524         {
525            return DefWndGetIcon(pWnd, wParam, lParam);
526         }
527 
528         case WM_HELP:
529         {
530             if (bUnicode)
531             {
532                 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
533             }
534             else
535             {
536                 SendMessageA(GetParent(hWnd), Msg, wParam, lParam);
537             }
538             break;
539         }
540 
541         case WM_QUERYOPEN:
542         case WM_QUERYENDSESSION:
543         {
544             return (1);
545         }
546 
547         case WM_INPUTLANGCHANGEREQUEST:
548         {
549             HKL NewHkl;
550 
551             if(wParam & INPUTLANGCHANGE_BACKWARD
552                && wParam & INPUTLANGCHANGE_FORWARD)
553             {
554                 return FALSE;
555             }
556 
557             //FIXME: What to do with INPUTLANGCHANGE_SYSCHARSET ?
558 
559             if(wParam & INPUTLANGCHANGE_BACKWARD) NewHkl = (HKL) HKL_PREV;
560             else if(wParam & INPUTLANGCHANGE_FORWARD) NewHkl = (HKL) HKL_NEXT;
561             else NewHkl = (HKL) lParam;
562 
563             NtUserActivateKeyboardLayout(NewHkl, 0);
564 
565             return TRUE;
566         }
567 
568         case WM_INPUTLANGCHANGE:
569         {
570             int count = 0;
571             HWND *win_array = WIN_ListChildren( hWnd );
572 
573             if (!win_array)
574                 break;
575             while (win_array[count])
576                 SendMessageW( win_array[count++], WM_INPUTLANGCHANGE, wParam, lParam);
577             HeapFree(GetProcessHeap(),0,win_array);
578             break;
579         }
580 
581         case WM_QUERYUISTATE:
582         {
583             LRESULT Ret = 0;
584             PWND Wnd = ValidateHwnd(hWnd);
585             if (Wnd != NULL)
586             {
587                 if (Wnd->HideFocus)
588                     Ret |= UISF_HIDEFOCUS;
589                 if (Wnd->HideAccel)
590                     Ret |= UISF_HIDEACCEL;
591             }
592             return Ret;
593         }
594 
595         case WM_CHANGEUISTATE:
596         {
597             BOOL AlwaysShowCues = FALSE;
598             WORD Action = LOWORD(wParam);
599             WORD Flags = HIWORD(wParam);
600             PWND Wnd;
601 
602             SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0);
603             if (AlwaysShowCues)
604                 break;
605 
606             Wnd= ValidateHwnd(hWnd);
607             if (!Wnd || lParam != 0)
608                 break;
609 
610             if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE))
611                 break;
612 
613             if (Flags & UISF_ACTIVE)
614             {
615                 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n");
616             }
617 
618             if (Action == UIS_INITIALIZE)
619             {
620                 PDESKTOPINFO Desk = GetThreadDesktopInfo();
621                 if (Desk == NULL)
622                     break;
623 
624                 Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET;
625                 Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL;
626 
627                 /* We need to update wParam in case we need to send out messages */
628                 wParam = MAKEWPARAM(Action, Flags);
629             }
630 
631             switch (Action)
632             {
633                 case UIS_SET:
634                     /* See if we actually need to change something */
635                     if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus)
636                         break;
637                     if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel)
638                         break;
639 
640                     /* Don't need to do anything... */
641                     return 0;
642 
643                 case UIS_CLEAR:
644                     /* See if we actually need to change something */
645                     if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus)
646                         break;
647                     if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel)
648                         break;
649 
650                     /* Don't need to do anything... */
651                     return 0;
652 
653                 default:
654                     WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action);
655                     break;
656             }
657 
658             if ((Wnd->style & WS_CHILD) && Wnd->spwndParent != NULL)
659             {
660                 /* We're a child window and we need to pass this message down until
661                    we reach the root */
662                 hWnd = UserHMGetHandle((PWND)DesktopPtrToUser(Wnd->spwndParent));
663             }
664             else
665             {
666                 /* We're a top level window, we need to change the UI state */
667                 Msg = WM_UPDATEUISTATE;
668             }
669 
670             if (bUnicode)
671                 return SendMessageW(hWnd, Msg, wParam, lParam);
672             else
673                 return SendMessageA(hWnd, Msg, wParam, lParam);
674         }
675 
676         case WM_UPDATEUISTATE:
677         {
678             BOOL Change = TRUE;
679             BOOL AlwaysShowCues = FALSE;
680             WORD Action = LOWORD(wParam);
681             WORD Flags = HIWORD(wParam);
682             PWND Wnd;
683 
684             SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0);
685             if (AlwaysShowCues)
686                 break;
687 
688             Wnd = ValidateHwnd(hWnd);
689             if (!Wnd || lParam != 0)
690                 break;
691 
692             if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE))
693                 break;
694 
695             if (Flags & UISF_ACTIVE)
696             {
697                 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n");
698             }
699 
700             if (Action == UIS_INITIALIZE)
701             {
702                 PDESKTOPINFO Desk = GetThreadDesktopInfo();
703                 if (Desk == NULL)
704                     break;
705 
706                 Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET;
707                 Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL;
708 
709                 /* We need to update wParam for broadcasting the update */
710                 wParam = MAKEWPARAM(Action, Flags);
711             }
712 
713             switch (Action)
714             {
715                 case UIS_SET:
716                     /* See if we actually need to change something */
717                     if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus)
718                         break;
719                     if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel)
720                         break;
721 
722                     /* Don't need to do anything... */
723                     Change = FALSE;
724                     break;
725 
726                 case UIS_CLEAR:
727                     /* See if we actually need to change something */
728                     if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus)
729                         break;
730                     if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel)
731                         break;
732 
733                     /* Don't need to do anything... */
734                     Change = FALSE;
735                     break;
736 
737                 default:
738                     WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action);
739                     return 0;
740             }
741 
742             /* Pack the information and call win32k */
743             if (Change)
744             {
745                 if (!NtUserxUpdateUiState(hWnd, Flags | ((DWORD)Action << 3)))
746                     break;
747             }
748 
749             /* Always broadcast the update to all children */
750             EnumChildWindows(hWnd,
751                              UserSendUiUpdateMsg,
752                              (LPARAM)wParam);
753 
754             break;
755         }
756 
757         case WM_COPYGLOBALDATA:
758         {
759             TRACE("WM_COPYGLOBALDATA hGlobal %p Size %d Flags 0x%x\n",lParam,wParam,GlobalFlags((HGLOBAL)lParam));
760             return lParam;
761         }
762 
763 /* Move to Win32k !*/
764         case WM_SHOWWINDOW:
765             if (!lParam) break; // Call when it is necessary.
766         case WM_LBUTTONDOWN:
767         case WM_RBUTTONDOWN:
768         case WM_MBUTTONDOWN:
769         case WM_NCLBUTTONDOWN:
770         case WM_NCRBUTTONDOWN:
771         case WM_LBUTTONDBLCLK:
772         case WM_NCLBUTTONDBLCLK:
773         case WM_KEYF1:
774         case WM_KEYUP:
775         case WM_SYSKEYUP:
776         case WM_KEYDOWN:
777         case WM_SYSKEYDOWN:
778         case WM_SYSCHAR:
779         case WM_CANCELMODE:
780         case WM_PAINTICON:
781         case WM_PAINT:
782         case WM_PRINT:
783         case WM_SETICON:
784         case WM_SYSCOLORCHANGE:
785         case WM_NCUAHDRAWCAPTION:
786         case WM_NCUAHDRAWFRAME:
787         case WM_NCPAINT:
788         case WM_NCACTIVATE:
789         case WM_NCCALCSIZE:
790         case WM_NCHITTEST:
791         case WM_SYNCPAINT:
792         case WM_SETREDRAW:
793         case WM_CLIENTSHUTDOWN:
794         case WM_GETHOTKEY:
795         case WM_SETHOTKEY:
796         case WM_WINDOWPOSCHANGING:
797         case WM_WINDOWPOSCHANGED:
798         case WM_APPCOMMAND:
799         case WM_SETCURSOR:
800 GoSS:
801         {
802             LRESULT lResult;
803             NtUserMessageCall( hWnd, Msg, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, !bUnicode);
804             return lResult;
805         }
806     }
807     return 0;
808 }
809 
810 
811 LRESULT WINAPI
812 RealDefWindowProcA(HWND hWnd,
813                    UINT Msg,
814                    WPARAM wParam,
815                    LPARAM lParam)
816 {
817     LRESULT Result = 0;
818     PWND Wnd;
819 
820     Wnd = ValidateHwnd(hWnd);
821 
822     if ( !Wnd &&
823          Msg != WM_CTLCOLORMSGBOX &&
824          Msg != WM_CTLCOLORBTN    &&
825          Msg != WM_CTLCOLORDLG    &&
826          Msg != WM_CTLCOLORSTATIC )
827        return 0;
828 
829     SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam);
830     switch (Msg)
831     {
832         case WM_NCCREATE:
833         {
834             if ( Wnd &&
835                  Wnd->style & (WS_HSCROLL | WS_VSCROLL) )
836             {
837                if (!Wnd->pSBInfo)
838                {
839                   SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0};
840                   SetScrollInfo( hWnd, SB_HORZ, &si, FALSE );
841                   SetScrollInfo( hWnd, SB_VERT, &si, FALSE );
842                }
843             }
844 
845             if (lParam)
846             {
847                 LPCREATESTRUCTA cs = (LPCREATESTRUCTA)lParam;
848                 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
849                  * may have child window IDs instead of window name */
850                 if (HIWORD(cs->lpszName))
851                 {
852                     DefSetText(hWnd, (PCWSTR)cs->lpszName, TRUE);
853                 }
854                 Result = 1;
855             }
856             break;
857         }
858 
859         case WM_GETTEXTLENGTH:
860         {
861             PWSTR buf;
862             ULONG len;
863 
864             if (Wnd != NULL && Wnd->strName.Length != 0)
865             {
866                 buf = DesktopPtrToUser(Wnd->strName.Buffer);
867                 if (buf != NULL &&
868                     NT_SUCCESS(RtlUnicodeToMultiByteSize(&len,
869                                                          buf,
870                                                          Wnd->strName.Length)))
871                 {
872                     Result = (LRESULT) len;
873                 }
874             }
875             else Result = 0L;
876 
877             break;
878         }
879 
880         case WM_GETTEXT:
881         {
882             PWSTR buf = NULL;
883             PSTR outbuf = (PSTR)lParam;
884             SIZE_T copy;
885 
886             if (Wnd != NULL && wParam != 0)
887             {
888                 if (Wnd->strName.Buffer != NULL)
889                     buf = DesktopPtrToUser(Wnd->strName.Buffer);
890                 else
891                     outbuf[0] = L'\0';
892 
893                 if (buf != NULL)
894                 {
895                     if (Wnd->strName.Length != 0)
896                     {
897                         copy = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1);
898                         Result = WideCharToMultiByte(CP_ACP,
899                                                      0,
900                                                      buf,
901                                                      copy,
902                                                      outbuf,
903                                                      wParam,
904                                                      NULL,
905                                                      NULL);
906                         outbuf[Result] = '\0';
907                     }
908                     else
909                         outbuf[0] = '\0';
910                 }
911             }
912             break;
913         }
914 
915         case WM_SETTEXT:
916         {
917             DefSetText(hWnd, (PCWSTR)lParam, TRUE);
918 
919             if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
920             {
921                 UserPaintCaption(Wnd, DC_TEXT);
922                 IntNotifyWinEvent(EVENT_OBJECT_NAMECHANGE, hWnd, OBJID_WINDOW, CHILDID_SELF, 0);
923             }
924             Result = 1;
925             break;
926         }
927 
928         case WM_IME_KEYDOWN:
929         {
930             Result = PostMessageA(hWnd, WM_KEYDOWN, wParam, lParam);
931             break;
932         }
933 
934         case WM_IME_KEYUP:
935         {
936             Result = PostMessageA(hWnd, WM_KEYUP, wParam, lParam);
937             break;
938         }
939 
940         case WM_IME_CHAR:
941         {
942             if (HIBYTE(wParam))
943                 PostMessageA(hWnd, WM_CHAR, HIBYTE(wParam), lParam);
944             PostMessageA(hWnd, WM_CHAR, LOBYTE(wParam), lParam);
945             break;
946         }
947 
948         case WM_IME_COMPOSITION:
949         if (lParam & GCS_RESULTSTR)
950         {
951             LONG size, i;
952             unsigned char lead = 0;
953             char *buf = NULL;
954             HIMC himc = ImmGetContext( hWnd );
955 
956             if (himc)
957             {
958                 if ((size = ImmGetCompositionStringA( himc, GCS_RESULTSTR, NULL, 0 )))
959                 {
960                     if (!(buf = HeapAlloc( GetProcessHeap(), 0, size ))) size = 0;
961                     else size = ImmGetCompositionStringA( himc, GCS_RESULTSTR, buf, size );
962                 }
963                 ImmReleaseContext( hWnd, himc );
964 
965                 for (i = 0; i < size; i++)
966                 {
967                     unsigned char c = buf[i];
968                     if (!lead)
969                     {
970                         if (IsDBCSLeadByte( c ))
971                             lead = c;
972                         else
973                             SendMessageA( hWnd, WM_IME_CHAR, c, 1 );
974                     }
975                     else
976                     {
977                         SendMessageA( hWnd, WM_IME_CHAR, MAKEWORD(c, lead), 1 );
978                         lead = 0;
979                     }
980                 }
981                 HeapFree( GetProcessHeap(), 0, buf );
982             }
983         }
984         /* fall through */
985         case WM_IME_STARTCOMPOSITION:
986         case WM_IME_ENDCOMPOSITION:
987         case WM_IME_SELECT:
988         case WM_IME_NOTIFY:
989         case WM_IME_CONTROL:
990         {
991             HWND hwndIME;
992 
993             hwndIME = ImmGetDefaultIMEWnd(hWnd);
994             if (hwndIME)
995                 Result = SendMessageA(hwndIME, Msg, wParam, lParam);
996             break;
997         }
998 
999         case WM_IME_SETCONTEXT:
1000         {
1001             HWND hwndIME;
1002 
1003             hwndIME = ImmGetDefaultIMEWnd(hWnd);
1004             if (hwndIME)
1005                 Result = ImmIsUIMessageA(hwndIME, Msg, wParam, lParam);
1006             break;
1007         }
1008 
1009         /* fall through */
1010         default:
1011             Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, FALSE);
1012     }
1013 
1014     SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam);
1015     return Result;
1016 }
1017 
1018 
1019 LRESULT WINAPI
1020 RealDefWindowProcW(HWND hWnd,
1021                    UINT Msg,
1022                    WPARAM wParam,
1023                    LPARAM lParam)
1024 {
1025     LRESULT Result = 0;
1026     PWND Wnd;
1027 
1028     Wnd = ValidateHwnd(hWnd);
1029 
1030     if ( !Wnd &&
1031          Msg != WM_CTLCOLORMSGBOX &&
1032          Msg != WM_CTLCOLORBTN    &&
1033          Msg != WM_CTLCOLORDLG    &&
1034          Msg != WM_CTLCOLORSTATIC )
1035        return 0;
1036 
1037     SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam);
1038     switch (Msg)
1039     {
1040         case WM_NCCREATE:
1041         {
1042             if ( Wnd &&
1043                  Wnd->style & (WS_HSCROLL | WS_VSCROLL) )
1044             {
1045                if (!Wnd->pSBInfo)
1046                {
1047                   SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0};
1048                   if (Wnd->style & WS_HSCROLL)
1049                      SetScrollInfo( hWnd, SB_HORZ, &si, FALSE );
1050                   if (Wnd->style & WS_VSCROLL)
1051                      SetScrollInfo( hWnd, SB_VERT, &si, FALSE );
1052                }
1053             }
1054 
1055             if (lParam)
1056             {
1057                 LPCREATESTRUCTW cs = (LPCREATESTRUCTW)lParam;
1058                 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1059                  * may have child window IDs instead of window name */
1060                 if (HIWORD(cs->lpszName))
1061                 {
1062                     DefSetText(hWnd, cs->lpszName, FALSE);
1063                 }
1064                 Result = 1;
1065             }
1066             break;
1067         }
1068 
1069         case WM_GETTEXTLENGTH:
1070         {
1071             PWSTR buf;
1072             ULONG len;
1073 
1074             if (Wnd != NULL && Wnd->strName.Length != 0)
1075             {
1076                 buf = DesktopPtrToUser(Wnd->strName.Buffer);
1077                 if (buf != NULL &&
1078                     NT_SUCCESS(RtlUnicodeToMultiByteSize(&len,
1079                                                          buf,
1080                                                          Wnd->strName.Length)))
1081                 {
1082                     Result = (LRESULT) (Wnd->strName.Length / sizeof(WCHAR));
1083                 }
1084             }
1085             else Result = 0L;
1086 
1087             break;
1088         }
1089 
1090         case WM_GETTEXT:
1091         {
1092             PWSTR buf = NULL;
1093             PWSTR outbuf = (PWSTR)lParam;
1094 
1095             if (Wnd != NULL && wParam != 0)
1096             {
1097                 if (Wnd->strName.Buffer != NULL)
1098                     buf = DesktopPtrToUser(Wnd->strName.Buffer);
1099                 else
1100                     outbuf[0] = L'\0';
1101 
1102                 if (buf != NULL)
1103                 {
1104                     if (Wnd->strName.Length != 0)
1105                     {
1106                         Result = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1);
1107                         RtlCopyMemory(outbuf,
1108                                       buf,
1109                                       Result * sizeof(WCHAR));
1110                         outbuf[Result] = L'\0';
1111                     }
1112                     else
1113                         outbuf[0] = L'\0';
1114                 }
1115             }
1116             break;
1117         }
1118 
1119         case WM_SETTEXT:
1120         {
1121             DefSetText(hWnd, (PCWSTR)lParam, FALSE);
1122 
1123             if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1124                 UserPaintCaption(Wnd, DC_TEXT);
1125             Result = 1;
1126             break;
1127         }
1128 
1129         case WM_IME_CHAR:
1130         {
1131             PostMessageW(hWnd, WM_CHAR, wParam, lParam);
1132             Result = 0;
1133             break;
1134         }
1135 
1136         case WM_IME_KEYDOWN:
1137         {
1138             Result = PostMessageW(hWnd, WM_KEYDOWN, wParam, lParam);
1139             break;
1140         }
1141 
1142         case WM_IME_KEYUP:
1143         {
1144             Result = PostMessageW(hWnd, WM_KEYUP, wParam, lParam);
1145             break;
1146         }
1147 
1148         case WM_IME_COMPOSITION:
1149         if (lParam & GCS_RESULTSTR)
1150         {
1151             LONG size, i;
1152             WCHAR *buf = NULL;
1153             HIMC himc = ImmGetContext( hWnd );
1154 
1155             if (himc)
1156             {
1157                 if ((size = ImmGetCompositionStringW( himc, GCS_RESULTSTR, NULL, 0 )))
1158                 {
1159                     if (!(buf = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) size = 0;
1160                     else size = ImmGetCompositionStringW( himc, GCS_RESULTSTR, buf, size * sizeof(WCHAR) );
1161                 }
1162                 ImmReleaseContext( hWnd, himc );
1163 
1164                 for (i = 0; i < size / sizeof(WCHAR); i++)
1165                     SendMessageW( hWnd, WM_IME_CHAR, buf[i], 1 );
1166                 HeapFree( GetProcessHeap(), 0, buf );
1167             }
1168         }
1169         /* fall through */
1170         case WM_IME_STARTCOMPOSITION:
1171         case WM_IME_ENDCOMPOSITION:
1172         case WM_IME_SELECT:
1173         case WM_IME_NOTIFY:
1174         case WM_IME_CONTROL:
1175         {
1176             HWND hwndIME;
1177 
1178             hwndIME = ImmGetDefaultIMEWnd(hWnd);
1179             if (hwndIME)
1180                 Result = SendMessageW(hwndIME, Msg, wParam, lParam);
1181             break;
1182         }
1183 
1184         case WM_IME_SETCONTEXT:
1185         {
1186             HWND hwndIME;
1187 
1188             hwndIME = ImmGetDefaultIMEWnd(hWnd);
1189             if (hwndIME)
1190                 Result = ImmIsUIMessageW(hwndIME, Msg, wParam, lParam);
1191             break;
1192         }
1193 
1194         default:
1195             Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, TRUE);
1196     }
1197     SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam);
1198 
1199     return Result;
1200 }
1201 
1202 LRESULT WINAPI
1203 DefWindowProcA(HWND hWnd,
1204 	       UINT Msg,
1205 	       WPARAM wParam,
1206 	       LPARAM lParam)
1207 {
1208    BOOL Hook, msgOverride = FALSE;
1209    LRESULT Result = 0;
1210 
1211    LoadUserApiHook();
1212 
1213    Hook = BeginIfHookedUserApiHook();
1214    if (Hook)
1215    {
1216       msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray);
1217       if(msgOverride == FALSE)
1218       {
1219           EndUserApiHook();
1220       }
1221    }
1222 
1223    /* Bypass SEH and go direct. */
1224    if (!Hook || !msgOverride)
1225       return RealDefWindowProcA(hWnd, Msg, wParam, lParam);
1226 
1227    _SEH2_TRY
1228    {
1229       Result = guah.DefWindowProcA(hWnd, Msg, wParam, lParam);
1230    }
1231    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1232    {
1233        ERR("Got exception in hooked DefWindowProcA!\n");
1234    }
1235    _SEH2_END;
1236 
1237    EndUserApiHook();
1238 
1239    return Result;
1240 }
1241 
1242 LRESULT WINAPI
1243 DefWindowProcW(HWND hWnd,
1244 	       UINT Msg,
1245 	       WPARAM wParam,
1246 	       LPARAM lParam)
1247 {
1248    BOOL Hook, msgOverride = FALSE;
1249    LRESULT Result = 0;
1250 
1251    LoadUserApiHook();
1252 
1253    Hook = BeginIfHookedUserApiHook();
1254    if (Hook)
1255    {
1256       msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray);
1257       if(msgOverride == FALSE)
1258       {
1259           EndUserApiHook();
1260       }
1261    }
1262 
1263    /* Bypass SEH and go direct. */
1264    if (!Hook || !msgOverride)
1265       return RealDefWindowProcW(hWnd, Msg, wParam, lParam);
1266 
1267    _SEH2_TRY
1268    {
1269       Result = guah.DefWindowProcW(hWnd, Msg, wParam, lParam);
1270    }
1271    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1272    {
1273        ERR("Got exception in hooked DefWindowProcW!\n");
1274    }
1275    _SEH2_END;
1276 
1277    EndUserApiHook();
1278 
1279    return Result;
1280 }
1281