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