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