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