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