xref: /reactos/win32ss/user/user32/windows/defwnd.c (revision 1ac9e484)
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_POPUPSYSTEMMENU:
332         {
333             /* This is an undocumented message used by the windows taskbar to
334                display the system menu of windows that belong to other processes. */
335             HMENU menu = GetSystemMenu(hWnd, FALSE);
336             ERR("WM_POPUPSYSTEMMENU\n");
337             if (menu)
338                 TrackPopupMenu(menu, TPM_LEFTBUTTON|TPM_RIGHTBUTTON|TPM_SYSTEM_MENU,
339                                LOWORD(lParam), HIWORD(lParam), 0, hWnd, NULL);
340             return 0;
341         }
342 
343         case WM_RBUTTONUP:
344         {
345             POINT Pt;
346             Pt.x = GET_X_LPARAM(lParam);
347             Pt.y = GET_Y_LPARAM(lParam);
348             ClientToScreen(hWnd, &Pt);
349             lParam = MAKELPARAM(Pt.x, Pt.y);
350             if (bUnicode)
351             {
352                 SendMessageW(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
353             }
354             else
355             {
356                 SendMessageA(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
357             }
358             break;
359         }
360 
361         case WM_NCRBUTTONUP:
362           /*
363            * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
364            * in Windows), but what _should_ we do? According to MSDN :
365            * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
366            * message to the window". When is it appropriate?
367            */
368            ERR("WM_NCRBUTTONUP\n");
369             break;
370 
371         case WM_XBUTTONUP:
372         case WM_NCXBUTTONUP:
373             if (HIWORD(wParam) == XBUTTON1 || HIWORD(wParam) == XBUTTON2)
374             {
375                SendMessageW(hWnd, WM_APPCOMMAND, (WPARAM)hWnd,
376                          MAKELPARAM(LOWORD(wParam), FAPPCOMMAND_MOUSE | HIWORD(wParam)));
377             }
378             break;
379 
380         case WM_CONTEXTMENU:
381         {
382             if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD)
383             {
384                 if (bUnicode)
385                 {
386                     SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
387                 }
388                 else
389                 {
390                     SendMessageA(GetParent(hWnd), WM_CONTEXTMENU, wParam, lParam);
391                 }
392             }
393             else
394             {
395                goto GoSS;
396             }
397             break;
398         }
399 
400         case WM_CLOSE:
401             DestroyWindow(hWnd);
402             return (0);
403 
404         case WM_MOUSEACTIVATE:
405             if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD)
406             {
407                 LONG Ret = SendMessageW(GetParent(hWnd), WM_MOUSEACTIVATE, wParam, lParam);
408                 if (Ret) return (Ret);
409             }
410             return ( (HIWORD(lParam) == WM_LBUTTONDOWN && LOWORD(lParam) == HTCAPTION) ? MA_NOACTIVATE : MA_ACTIVATE );
411 
412         case WM_ACTIVATE:
413             /* The default action in Windows is to set the keyboard focus to
414              * the window, if it's being activated and not minimized */
415             if (LOWORD(wParam) != WA_INACTIVE &&
416                 !(GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MINIMIZE))
417             {
418                 //ERR("WM_ACTIVATE %p\n",hWnd);
419                 SetFocus(hWnd);
420             }
421             break;
422 
423         case WM_MOUSEWHEEL:
424             if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD)
425                 return SendMessageW( GetParent(hWnd), WM_MOUSEWHEEL, wParam, lParam);
426             break;
427 
428         case WM_ERASEBKGND:
429         case WM_ICONERASEBKGND:
430         {
431             RECT Rect;
432             HBRUSH hBrush = (HBRUSH)GetClassLongPtrW(hWnd, GCL_HBRBACKGROUND);
433 
434             if (NULL == hBrush)
435             {
436                 return 0;
437             }
438             if (GetClassLongPtrW(hWnd, GCL_STYLE) & CS_PARENTDC)
439             {
440                 /* can't use GetClipBox with a parent DC or we fill the whole parent */
441                 GetClientRect(hWnd, &Rect);
442                 DPtoLP((HDC)wParam, (LPPOINT)&Rect, 2);
443             }
444             else
445             {
446                 GetClipBox((HDC)wParam, &Rect);
447             }
448             FillRect((HDC)wParam, &Rect, hBrush);
449             return (1);
450         }
451 
452         case WM_CTLCOLORMSGBOX:
453         case WM_CTLCOLOREDIT:
454         case WM_CTLCOLORLISTBOX:
455         case WM_CTLCOLORBTN:
456         case WM_CTLCOLORDLG:
457         case WM_CTLCOLORSTATIC:
458         case WM_CTLCOLORSCROLLBAR:
459             return (LRESULT) DefWndControlColor((HDC)wParam, Msg - WM_CTLCOLORMSGBOX);
460 
461         case WM_CTLCOLOR:
462             return (LRESULT) DefWndControlColor((HDC)wParam, HIWORD(lParam));
463 
464         case WM_SYSCOMMAND:
465             return (DefWndHandleSysCommand(hWnd, wParam, lParam));
466 
467         case WM_VKEYTOITEM:
468         case WM_CHARTOITEM:
469             return (-1);
470 /*
471         case WM_DROPOBJECT:
472             return DRAG_FILE;
473 */
474         case WM_QUERYDROPOBJECT:
475         {
476             if (GetWindowLongPtrW(hWnd, GWL_EXSTYLE) & WS_EX_ACCEPTFILES)
477             {
478                 return(1);
479             }
480             break;
481         }
482 
483         case WM_QUERYDRAGICON:
484         {
485             UINT Len;
486             HICON hIcon;
487 
488             hIcon = (HICON)GetClassLongPtrW(hWnd, GCL_HICON);
489             if (hIcon)
490             {
491                 return ((LRESULT)hIcon);
492             }
493             for (Len = 1; Len < 64; Len++)
494             {
495                 if ((hIcon = LoadIconW(NULL, MAKEINTRESOURCEW(Len))) != NULL)
496                 {
497                     return((LRESULT)hIcon);
498                 }
499             }
500             return ((LRESULT)LoadIconW(0, IDI_APPLICATION));
501         }
502 
503         case WM_ISACTIVEICON:
504         {
505            BOOL isai;
506            isai = (pWnd->state & WNDS_ACTIVEFRAME) != 0;
507            return isai;
508         }
509 
510         case WM_NOTIFYFORMAT:
511         {
512             if (lParam == NF_QUERY)
513                 return IsWindowUnicode(hWnd) ? NFR_UNICODE : NFR_ANSI;
514             break;
515         }
516 
517         case WM_GETICON:
518         {
519            return DefWndGetIcon(pWnd, wParam, lParam);
520         }
521 
522         case WM_HELP:
523         {
524             if (bUnicode)
525             {
526                 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
527             }
528             else
529             {
530                 SendMessageA(GetParent(hWnd), Msg, wParam, lParam);
531             }
532             break;
533         }
534 
535         case WM_QUERYOPEN:
536         case WM_QUERYENDSESSION:
537         {
538             return (1);
539         }
540 
541         case WM_INPUTLANGCHANGEREQUEST:
542         {
543             HKL NewHkl;
544 
545             if(wParam & INPUTLANGCHANGE_BACKWARD
546                && wParam & INPUTLANGCHANGE_FORWARD)
547             {
548                 return FALSE;
549             }
550 
551             //FIXME: What to do with INPUTLANGCHANGE_SYSCHARSET ?
552 
553             if(wParam & INPUTLANGCHANGE_BACKWARD) NewHkl = (HKL) HKL_PREV;
554             else if(wParam & INPUTLANGCHANGE_FORWARD) NewHkl = (HKL) HKL_NEXT;
555             else NewHkl = (HKL) lParam;
556 
557             NtUserActivateKeyboardLayout(NewHkl, 0);
558 
559             return TRUE;
560         }
561 
562         case WM_INPUTLANGCHANGE:
563         {
564             int count = 0;
565             HWND *win_array = WIN_ListChildren( hWnd );
566 
567             if (!win_array)
568                 break;
569             while (win_array[count])
570                 SendMessageW( win_array[count++], WM_INPUTLANGCHANGE, wParam, lParam);
571             HeapFree(GetProcessHeap(),0,win_array);
572             break;
573         }
574 
575         case WM_QUERYUISTATE:
576         {
577             LRESULT Ret = 0;
578             PWND Wnd = ValidateHwnd(hWnd);
579             if (Wnd != NULL)
580             {
581                 if (Wnd->HideFocus)
582                     Ret |= UISF_HIDEFOCUS;
583                 if (Wnd->HideAccel)
584                     Ret |= UISF_HIDEACCEL;
585             }
586             return Ret;
587         }
588 
589         case WM_CHANGEUISTATE:
590         {
591             BOOL AlwaysShowCues = FALSE;
592             WORD Action = LOWORD(wParam);
593             WORD Flags = HIWORD(wParam);
594             PWND Wnd;
595 
596             SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0);
597             if (AlwaysShowCues)
598                 break;
599 
600             Wnd= ValidateHwnd(hWnd);
601             if (!Wnd || lParam != 0)
602                 break;
603 
604             if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE))
605                 break;
606 
607             if (Flags & UISF_ACTIVE)
608             {
609                 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n");
610             }
611 
612             if (Action == UIS_INITIALIZE)
613             {
614                 PDESKTOPINFO Desk = GetThreadDesktopInfo();
615                 if (Desk == NULL)
616                     break;
617 
618                 Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET;
619                 Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL;
620 
621                 /* We need to update wParam in case we need to send out messages */
622                 wParam = MAKEWPARAM(Action, Flags);
623             }
624 
625             switch (Action)
626             {
627                 case UIS_SET:
628                     /* See if we actually need to change something */
629                     if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus)
630                         break;
631                     if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel)
632                         break;
633 
634                     /* Don't need to do anything... */
635                     return 0;
636 
637                 case UIS_CLEAR:
638                     /* See if we actually need to change something */
639                     if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus)
640                         break;
641                     if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel)
642                         break;
643 
644                     /* Don't need to do anything... */
645                     return 0;
646 
647                 default:
648                     WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action);
649                     break;
650             }
651 
652             if ((Wnd->style & WS_CHILD) && Wnd->spwndParent != NULL)
653             {
654                 /* We're a child window and we need to pass this message down until
655                    we reach the root */
656                 hWnd = UserHMGetHandle((PWND)DesktopPtrToUser(Wnd->spwndParent));
657             }
658             else
659             {
660                 /* We're a top level window, we need to change the UI state */
661                 Msg = WM_UPDATEUISTATE;
662             }
663 
664             if (bUnicode)
665                 return SendMessageW(hWnd, Msg, wParam, lParam);
666             else
667                 return SendMessageA(hWnd, Msg, wParam, lParam);
668         }
669 
670         case WM_UPDATEUISTATE:
671         {
672             BOOL Change = TRUE;
673             BOOL AlwaysShowCues = FALSE;
674             WORD Action = LOWORD(wParam);
675             WORD Flags = HIWORD(wParam);
676             PWND Wnd;
677 
678             SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0);
679             if (AlwaysShowCues)
680                 break;
681 
682             Wnd = ValidateHwnd(hWnd);
683             if (!Wnd || lParam != 0)
684                 break;
685 
686             if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE))
687                 break;
688 
689             if (Flags & UISF_ACTIVE)
690             {
691                 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n");
692             }
693 
694             if (Action == UIS_INITIALIZE)
695             {
696                 PDESKTOPINFO Desk = GetThreadDesktopInfo();
697                 if (Desk == NULL)
698                     break;
699 
700                 Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET;
701                 Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL;
702 
703                 /* We need to update wParam for broadcasting the update */
704                 wParam = MAKEWPARAM(Action, Flags);
705             }
706 
707             switch (Action)
708             {
709                 case UIS_SET:
710                     /* See if we actually need to change something */
711                     if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus)
712                         break;
713                     if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel)
714                         break;
715 
716                     /* Don't need to do anything... */
717                     Change = FALSE;
718                     break;
719 
720                 case UIS_CLEAR:
721                     /* See if we actually need to change something */
722                     if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus)
723                         break;
724                     if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel)
725                         break;
726 
727                     /* Don't need to do anything... */
728                     Change = FALSE;
729                     break;
730 
731                 default:
732                     WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action);
733                     return 0;
734             }
735 
736             /* Pack the information and call win32k */
737             if (Change)
738             {
739                 if (!NtUserxUpdateUiState(hWnd, Flags | ((DWORD)Action << 3)))
740                     break;
741             }
742 
743             /* Always broadcast the update to all children */
744             EnumChildWindows(hWnd,
745                              UserSendUiUpdateMsg,
746                              (LPARAM)wParam);
747 
748             break;
749         }
750 
751         case WM_COPYGLOBALDATA:
752         {
753             TRACE("WM_COPYGLOBALDATA hGlobal %p Size %d Flags 0x%x\n",lParam,wParam,GlobalFlags((HGLOBAL)lParam));
754             return lParam;
755         }
756 
757 /* Move to Win32k !*/
758         case WM_SHOWWINDOW:
759             if (!lParam) break; // Call when it is necessary.
760         case WM_LBUTTONDOWN:
761         case WM_RBUTTONDOWN:
762         case WM_MBUTTONDOWN:
763         case WM_NCLBUTTONDOWN:
764         case WM_NCRBUTTONDOWN:
765         case WM_LBUTTONDBLCLK:
766         case WM_NCLBUTTONDBLCLK:
767         case WM_KEYF1:
768         case WM_KEYUP:
769         case WM_SYSKEYUP:
770         case WM_KEYDOWN:
771         case WM_SYSKEYDOWN:
772         case WM_SYSCHAR:
773         case WM_CANCELMODE:
774         case WM_PAINTICON:
775         case WM_PAINT:
776         case WM_PRINT:
777         case WM_SETICON:
778         case WM_SYSCOLORCHANGE:
779         case WM_NCUAHDRAWCAPTION:
780         case WM_NCUAHDRAWFRAME:
781         case WM_NCPAINT:
782         case WM_NCACTIVATE:
783         case WM_NCCALCSIZE:
784         case WM_NCHITTEST:
785         case WM_SYNCPAINT:
786         case WM_SETREDRAW:
787         case WM_CLIENTSHUTDOWN:
788         case WM_GETHOTKEY:
789         case WM_SETHOTKEY:
790         case WM_WINDOWPOSCHANGING:
791         case WM_WINDOWPOSCHANGED:
792         case WM_APPCOMMAND:
793         case WM_SETCURSOR:
794 GoSS:
795         {
796             LRESULT lResult;
797             NtUserMessageCall( hWnd, Msg, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, !bUnicode);
798             return lResult;
799         }
800     }
801     return 0;
802 }
803 
804 
805 LRESULT WINAPI
806 RealDefWindowProcA(HWND hWnd,
807                    UINT Msg,
808                    WPARAM wParam,
809                    LPARAM lParam)
810 {
811     LRESULT Result = 0;
812     PWND Wnd;
813 
814     Wnd = ValidateHwnd(hWnd);
815 
816     if ( !Wnd &&
817          Msg != WM_CTLCOLORMSGBOX &&
818          Msg != WM_CTLCOLORBTN    &&
819          Msg != WM_CTLCOLORDLG    &&
820          Msg != WM_CTLCOLORSTATIC )
821        return 0;
822 
823     SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam);
824     switch (Msg)
825     {
826         case WM_NCCREATE:
827         {
828             if ( Wnd &&
829                  Wnd->style & (WS_HSCROLL | WS_VSCROLL) )
830             {
831                if (!Wnd->pSBInfo)
832                {
833                   SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0};
834                   SetScrollInfo( hWnd, SB_HORZ, &si, FALSE );
835                   SetScrollInfo( hWnd, SB_VERT, &si, FALSE );
836                }
837             }
838 
839             if (lParam)
840             {
841                 LPCREATESTRUCTA cs = (LPCREATESTRUCTA)lParam;
842                 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
843                  * may have child window IDs instead of window name */
844                 if (HIWORD(cs->lpszName))
845                 {
846                     DefSetText(hWnd, (PCWSTR)cs->lpszName, TRUE);
847                 }
848                 Result = 1;
849             }
850             break;
851         }
852 
853         case WM_GETTEXTLENGTH:
854         {
855             PWSTR buf;
856             ULONG len;
857 
858             if (Wnd != NULL && Wnd->strName.Length != 0)
859             {
860                 buf = DesktopPtrToUser(Wnd->strName.Buffer);
861                 if (buf != NULL &&
862                     NT_SUCCESS(RtlUnicodeToMultiByteSize(&len,
863                                                          buf,
864                                                          Wnd->strName.Length)))
865                 {
866                     Result = (LRESULT) len;
867                 }
868             }
869             else Result = 0L;
870 
871             break;
872         }
873 
874         case WM_GETTEXT:
875         {
876             PWSTR buf = NULL;
877             PSTR outbuf = (PSTR)lParam;
878             SIZE_T copy;
879 
880             if (Wnd != NULL && wParam != 0)
881             {
882                 if (Wnd->strName.Buffer != NULL)
883                     buf = DesktopPtrToUser(Wnd->strName.Buffer);
884                 else
885                     outbuf[0] = L'\0';
886 
887                 if (buf != NULL)
888                 {
889                     if (Wnd->strName.Length != 0)
890                     {
891                         copy = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1);
892                         Result = WideCharToMultiByte(CP_ACP,
893                                                      0,
894                                                      buf,
895                                                      copy,
896                                                      outbuf,
897                                                      wParam,
898                                                      NULL,
899                                                      NULL);
900                         outbuf[Result] = '\0';
901                     }
902                     else
903                         outbuf[0] = '\0';
904                 }
905             }
906             break;
907         }
908 
909         case WM_SETTEXT:
910         {
911             DefSetText(hWnd, (PCWSTR)lParam, TRUE);
912 
913             if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
914             {
915                 UserPaintCaption(Wnd, DC_TEXT);
916                 IntNotifyWinEvent(EVENT_OBJECT_NAMECHANGE, hWnd, OBJID_WINDOW, CHILDID_SELF, 0);
917             }
918             Result = 1;
919             break;
920         }
921 
922         case WM_IME_KEYDOWN:
923         {
924             Result = PostMessageA(hWnd, WM_KEYDOWN, wParam, lParam);
925             break;
926         }
927 
928         case WM_IME_KEYUP:
929         {
930             Result = PostMessageA(hWnd, WM_KEYUP, wParam, lParam);
931             break;
932         }
933 
934         case WM_IME_CHAR:
935         {
936             if (HIBYTE(wParam))
937                 PostMessageA(hWnd, WM_CHAR, HIBYTE(wParam), lParam);
938             PostMessageA(hWnd, WM_CHAR, LOBYTE(wParam), lParam);
939             break;
940         }
941 
942         case WM_IME_COMPOSITION:
943         if (lParam & GCS_RESULTSTR)
944         {
945             LONG size, i;
946             unsigned char lead = 0;
947             char *buf = NULL;
948             HIMC himc = ImmGetContext( hWnd );
949 
950             if (himc)
951             {
952                 if ((size = ImmGetCompositionStringA( himc, GCS_RESULTSTR, NULL, 0 )))
953                 {
954                     if (!(buf = HeapAlloc( GetProcessHeap(), 0, size ))) size = 0;
955                     else size = ImmGetCompositionStringA( himc, GCS_RESULTSTR, buf, size );
956                 }
957                 ImmReleaseContext( hWnd, himc );
958 
959                 for (i = 0; i < size; i++)
960                 {
961                     unsigned char c = buf[i];
962                     if (!lead)
963                     {
964                         if (IsDBCSLeadByte( c ))
965                             lead = c;
966                         else
967                             SendMessageA( hWnd, WM_IME_CHAR, c, 1 );
968                     }
969                     else
970                     {
971                         SendMessageA( hWnd, WM_IME_CHAR, MAKEWORD(c, lead), 1 );
972                         lead = 0;
973                     }
974                 }
975                 HeapFree( GetProcessHeap(), 0, buf );
976             }
977         }
978         /* fall through */
979         case WM_IME_STARTCOMPOSITION:
980         case WM_IME_ENDCOMPOSITION:
981         case WM_IME_SELECT:
982         case WM_IME_NOTIFY:
983         case WM_IME_CONTROL:
984         {
985             HWND hwndIME;
986 
987             hwndIME = ImmGetDefaultIMEWnd(hWnd);
988             if (hwndIME)
989                 Result = SendMessageA(hwndIME, Msg, wParam, lParam);
990             break;
991         }
992 
993         case WM_IME_SETCONTEXT:
994         {
995             HWND hwndIME;
996 
997             hwndIME = ImmGetDefaultIMEWnd(hWnd);
998             if (hwndIME)
999                 Result = ImmIsUIMessageA(hwndIME, Msg, wParam, lParam);
1000             break;
1001         }
1002 
1003         /* fall through */
1004         default:
1005             Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, FALSE);
1006     }
1007 
1008     SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam);
1009     return Result;
1010 }
1011 
1012 
1013 LRESULT WINAPI
1014 RealDefWindowProcW(HWND hWnd,
1015                    UINT Msg,
1016                    WPARAM wParam,
1017                    LPARAM lParam)
1018 {
1019     LRESULT Result = 0;
1020     PWND Wnd;
1021 
1022     Wnd = ValidateHwnd(hWnd);
1023 
1024     if ( !Wnd &&
1025          Msg != WM_CTLCOLORMSGBOX &&
1026          Msg != WM_CTLCOLORBTN    &&
1027          Msg != WM_CTLCOLORDLG    &&
1028          Msg != WM_CTLCOLORSTATIC )
1029        return 0;
1030 
1031     SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam);
1032     switch (Msg)
1033     {
1034         case WM_NCCREATE:
1035         {
1036             if ( Wnd &&
1037                  Wnd->style & (WS_HSCROLL | WS_VSCROLL) )
1038             {
1039                if (!Wnd->pSBInfo)
1040                {
1041                   SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0};
1042                   SetScrollInfo( hWnd, SB_HORZ, &si, FALSE );
1043                   SetScrollInfo( hWnd, SB_VERT, &si, FALSE );
1044                }
1045             }
1046 
1047             if (lParam)
1048             {
1049                 LPCREATESTRUCTW cs = (LPCREATESTRUCTW)lParam;
1050                 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1051                  * may have child window IDs instead of window name */
1052                 if (HIWORD(cs->lpszName))
1053                 {
1054                     DefSetText(hWnd, cs->lpszName, FALSE);
1055                 }
1056                 Result = 1;
1057             }
1058             break;
1059         }
1060 
1061         case WM_GETTEXTLENGTH:
1062         {
1063             PWSTR buf;
1064             ULONG len;
1065 
1066             if (Wnd != NULL && Wnd->strName.Length != 0)
1067             {
1068                 buf = DesktopPtrToUser(Wnd->strName.Buffer);
1069                 if (buf != NULL &&
1070                     NT_SUCCESS(RtlUnicodeToMultiByteSize(&len,
1071                                                          buf,
1072                                                          Wnd->strName.Length)))
1073                 {
1074                     Result = (LRESULT) (Wnd->strName.Length / sizeof(WCHAR));
1075                 }
1076             }
1077             else Result = 0L;
1078 
1079             break;
1080         }
1081 
1082         case WM_GETTEXT:
1083         {
1084             PWSTR buf = NULL;
1085             PWSTR outbuf = (PWSTR)lParam;
1086 
1087             if (Wnd != NULL && wParam != 0)
1088             {
1089                 if (Wnd->strName.Buffer != NULL)
1090                     buf = DesktopPtrToUser(Wnd->strName.Buffer);
1091                 else
1092                     outbuf[0] = L'\0';
1093 
1094                 if (buf != NULL)
1095                 {
1096                     if (Wnd->strName.Length != 0)
1097                     {
1098                         Result = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1);
1099                         RtlCopyMemory(outbuf,
1100                                       buf,
1101                                       Result * sizeof(WCHAR));
1102                         outbuf[Result] = L'\0';
1103                     }
1104                     else
1105                         outbuf[0] = L'\0';
1106                 }
1107             }
1108             break;
1109         }
1110 
1111         case WM_SETTEXT:
1112         {
1113             DefSetText(hWnd, (PCWSTR)lParam, FALSE);
1114 
1115             if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1116                 UserPaintCaption(Wnd, DC_TEXT);
1117             Result = 1;
1118             break;
1119         }
1120 
1121         case WM_IME_CHAR:
1122         {
1123             PostMessageW(hWnd, WM_CHAR, wParam, lParam);
1124             Result = 0;
1125             break;
1126         }
1127 
1128         case WM_IME_KEYDOWN:
1129         {
1130             Result = PostMessageW(hWnd, WM_KEYDOWN, wParam, lParam);
1131             break;
1132         }
1133 
1134         case WM_IME_KEYUP:
1135         {
1136             Result = PostMessageW(hWnd, WM_KEYUP, wParam, lParam);
1137             break;
1138         }
1139 
1140         case WM_IME_COMPOSITION:
1141         if (lParam & GCS_RESULTSTR)
1142         {
1143             LONG size, i;
1144             WCHAR *buf = NULL;
1145             HIMC himc = ImmGetContext( hWnd );
1146 
1147             if (himc)
1148             {
1149                 if ((size = ImmGetCompositionStringW( himc, GCS_RESULTSTR, NULL, 0 )))
1150                 {
1151                     if (!(buf = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) size = 0;
1152                     else size = ImmGetCompositionStringW( himc, GCS_RESULTSTR, buf, size * sizeof(WCHAR) );
1153                 }
1154                 ImmReleaseContext( hWnd, himc );
1155 
1156                 for (i = 0; i < size / sizeof(WCHAR); i++)
1157                     SendMessageW( hWnd, WM_IME_CHAR, buf[i], 1 );
1158                 HeapFree( GetProcessHeap(), 0, buf );
1159             }
1160         }
1161         /* fall through */
1162         case WM_IME_STARTCOMPOSITION:
1163         case WM_IME_ENDCOMPOSITION:
1164         case WM_IME_SELECT:
1165         case WM_IME_NOTIFY:
1166         case WM_IME_CONTROL:
1167         {
1168             HWND hwndIME;
1169 
1170             hwndIME = ImmGetDefaultIMEWnd(hWnd);
1171             if (hwndIME)
1172                 Result = SendMessageW(hwndIME, Msg, wParam, lParam);
1173             break;
1174         }
1175 
1176         case WM_IME_SETCONTEXT:
1177         {
1178             HWND hwndIME;
1179 
1180             hwndIME = ImmGetDefaultIMEWnd(hWnd);
1181             if (hwndIME)
1182                 Result = ImmIsUIMessageW(hwndIME, Msg, wParam, lParam);
1183             break;
1184         }
1185 
1186         default:
1187             Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, TRUE);
1188     }
1189     SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam);
1190 
1191     return Result;
1192 }
1193 
1194 LRESULT WINAPI
1195 DefWindowProcA(HWND hWnd,
1196 	       UINT Msg,
1197 	       WPARAM wParam,
1198 	       LPARAM lParam)
1199 {
1200    BOOL Hook, msgOverride = FALSE;
1201    LRESULT Result = 0;
1202 
1203    LoadUserApiHook();
1204 
1205    Hook = BeginIfHookedUserApiHook();
1206    if (Hook)
1207    {
1208       msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray);
1209       if(msgOverride == FALSE)
1210       {
1211           EndUserApiHook();
1212       }
1213    }
1214 
1215    /* Bypass SEH and go direct. */
1216    if (!Hook || !msgOverride)
1217       return RealDefWindowProcA(hWnd, Msg, wParam, lParam);
1218 
1219    _SEH2_TRY
1220    {
1221       Result = guah.DefWindowProcA(hWnd, Msg, wParam, lParam);
1222    }
1223    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1224    {
1225        ERR("Got exception in hooked DefWindowProcA!\n");
1226    }
1227    _SEH2_END;
1228 
1229    EndUserApiHook();
1230 
1231    return Result;
1232 }
1233 
1234 LRESULT WINAPI
1235 DefWindowProcW(HWND hWnd,
1236 	       UINT Msg,
1237 	       WPARAM wParam,
1238 	       LPARAM lParam)
1239 {
1240    BOOL Hook, msgOverride = FALSE;
1241    LRESULT Result = 0;
1242 
1243    LoadUserApiHook();
1244 
1245    Hook = BeginIfHookedUserApiHook();
1246    if (Hook)
1247    {
1248       msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray);
1249       if(msgOverride == FALSE)
1250       {
1251           EndUserApiHook();
1252       }
1253    }
1254 
1255    /* Bypass SEH and go direct. */
1256    if (!Hook || !msgOverride)
1257       return RealDefWindowProcW(hWnd, Msg, wParam, lParam);
1258 
1259    _SEH2_TRY
1260    {
1261       Result = guah.DefWindowProcW(hWnd, Msg, wParam, lParam);
1262    }
1263    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1264    {
1265        ERR("Got exception in hooked DefWindowProcW!\n");
1266    }
1267    _SEH2_END;
1268 
1269    EndUserApiHook();
1270 
1271    return Result;
1272 }
1273