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