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