Sync with trunk r63343.
[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: dll/win32/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 LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active);
20 LRESULT DefWndNCCalcSize(HWND hWnd, BOOL CalcSizeStruct, RECT *Rect);
21 LRESULT DefWndNCActivate(HWND hWnd, WPARAM wParam, LPARAM lParam);
22 LRESULT DefWndNCHitTest(HWND hWnd, POINT Point);
23 LRESULT DefWndNCLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam);
24 LRESULT DefWndNCLButtonDblClk(HWND hWnd, WPARAM wParam, LPARAM lParam);
25 LRESULT NC_HandleNCRButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam );
26 void FASTCALL MenuInitSysMenuPopup(HMENU Menu, DWORD Style, DWORD ClsStyle, LONG HitTest );
27 void MENU_EndMenu( HWND );
28
29 /* GLOBALS *******************************************************************/
30
31 static short iF10Key = 0;
32 static short iMenuSysKey = 0;
33
34 /* FUNCTIONS *****************************************************************/
35
36 /*
37 * @implemented
38 */
39 DWORD
40 WINAPI
41 DECLSPEC_HOTPATCH
42 GetSysColor(int nIndex)
43 {
44 if(nIndex >= 0 && nIndex < NUM_SYSCOLORS)
45 {
46 return gpsi->argbSystem[nIndex];
47 }
48
49 SetLastError(ERROR_INVALID_PARAMETER);
50 return 0;
51 }
52
53 /*
54 * @implemented
55 */
56 HBRUSH
57 WINAPI
58 DECLSPEC_HOTPATCH
59 GetSysColorBrush(int nIndex)
60 {
61 if(nIndex >= 0 && nIndex < NUM_SYSCOLORS)
62 {
63 return gpsi->ahbrSystem[nIndex];
64 }
65
66 SetLastError(ERROR_INVALID_PARAMETER);
67 return NULL;
68 }
69
70 /*
71 * @implemented
72 */
73 BOOL
74 WINAPI
75 SetSysColors(
76 int cElements,
77 CONST INT *lpaElements,
78 CONST COLORREF *lpaRgbValues)
79 {
80 return NtUserSetSysColors(cElements, lpaElements, lpaRgbValues, 0);
81 }
82
83 BOOL
84 FASTCALL
85 DefSetText(HWND hWnd, PCWSTR String, BOOL Ansi)
86 {
87 BOOL Ret;
88 LARGE_STRING lsString;
89
90 if ( String )
91 {
92 if ( Ansi )
93 RtlInitLargeAnsiString((PLARGE_ANSI_STRING)&lsString, (PCSZ)String, 0);
94 else
95 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&lsString, String, 0);
96 }
97 Ret = NtUserDefSetText(hWnd, (String ? &lsString : NULL));
98
99 if (Ret)
100 IntNotifyWinEvent(EVENT_OBJECT_NAMECHANGE, hWnd, OBJID_WINDOW, CHILDID_SELF, 0);
101
102 return Ret;
103 }
104
105 void
106 UserGetInsideRectNC(PWND Wnd, RECT *rect)
107 {
108 ULONG Style;
109 ULONG ExStyle;
110
111 Style = Wnd->style;
112 ExStyle = Wnd->ExStyle;
113
114 rect->top = rect->left = 0;
115 rect->right = Wnd->rcWindow.right - Wnd->rcWindow.left;
116 rect->bottom = Wnd->rcWindow.bottom - Wnd->rcWindow.top;
117
118 if (Style & WS_ICONIC)
119 {
120 return;
121 }
122
123 /* Remove frame from rectangle */
124 if (UserHasThickFrameStyle(Style, ExStyle ))
125 {
126 InflateRect(rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME));
127 }
128 else
129 {
130 if (UserHasDlgFrameStyle(Style, ExStyle ))
131 {
132 InflateRect(rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
133 /* FIXME: this isn't in NC_AdjustRect? why not? */
134 if (ExStyle & WS_EX_DLGMODALFRAME)
135 InflateRect( rect, -1, 0 );
136 }
137 else
138 {
139 if (UserHasThinFrameStyle(Style, ExStyle))
140 {
141 InflateRect(rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
142 }
143 }
144 }
145 /* We have additional border information if the window
146 * is a child (but not an MDI child) */
147 if ((Style & WS_CHILD) && !(ExStyle & WS_EX_MDICHILD))
148 {
149 if (ExStyle & WS_EX_CLIENTEDGE)
150 InflateRect (rect, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE));
151 if (ExStyle & WS_EX_STATICEDGE)
152 InflateRect (rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
153 }
154 }
155
156 LRESULT
157 DefWndHandleSetCursor(HWND hWnd, WPARAM wParam, LPARAM lParam, ULONG Style)
158 {
159 /* Not for child windows. */
160 if (hWnd != (HWND)wParam)
161 {
162 return(0);
163 }
164
165 switch((INT_PTR) LOWORD(lParam))
166 {
167 case HTERROR:
168 {
169 WORD Msg = HIWORD(lParam);
170 if (Msg == WM_LBUTTONDOWN || Msg == WM_MBUTTONDOWN ||
171 Msg == WM_RBUTTONDOWN || Msg == WM_XBUTTONDOWN)
172 {
173 MessageBeep(0);
174 }
175 break;
176 }
177
178 case HTCLIENT:
179 {
180 HICON hCursor = (HICON)GetClassLongPtrW(hWnd, GCL_HCURSOR);
181 if (hCursor)
182 {
183 SetCursor(hCursor);
184 return(TRUE);
185 }
186 return(FALSE);
187 }
188
189 case HTLEFT:
190 case HTRIGHT:
191 {
192 if (Style & WS_MAXIMIZE)
193 {
194 break;
195 }
196 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZEWE)));
197 }
198
199 case HTTOP:
200 case HTBOTTOM:
201 {
202 if (Style & WS_MAXIMIZE)
203 {
204 break;
205 }
206 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENS)));
207 }
208
209 case HTTOPLEFT:
210 case HTBOTTOMRIGHT:
211 {
212 if (Style & WS_MAXIMIZE)
213 {
214 break;
215 }
216 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENWSE)));
217 }
218
219 case HTBOTTOMLEFT:
220 case HTTOPRIGHT:
221 {
222 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MAXIMIZE)
223 {
224 break;
225 }
226 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENESW)));
227 }
228 }
229 return((LRESULT)SetCursor(LoadCursorW(0, IDC_ARROW)));
230 }
231
232 /***********************************************************************
233 * DefWndTrackScrollBar
234 *
235 * Track a mouse button press on the horizontal or vertical scroll-bar.
236 */
237 static VOID
238 DefWndTrackScrollBar(HWND Wnd, WPARAM wParam, POINT Pt)
239 {
240 INT ScrollBar;
241
242 if (SC_HSCROLL == (wParam & 0xfff0))
243 {
244 if (HTHSCROLL != (wParam & 0x0f))
245 {
246 return;
247 }
248 ScrollBar = SB_HORZ;
249 }
250 else /* SC_VSCROLL */
251 {
252 if (HTVSCROLL != (wParam & 0x0f))
253 {
254 return;
255 }
256 ScrollBar = SB_VERT;
257 }
258 ScrollTrackScrollBar(Wnd, ScrollBar, Pt );
259 }
260
261 LRESULT WINAPI DoAppSwitch( WPARAM wParam, LPARAM lParam);
262
263 LRESULT
264 DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
265 {
266 POINT Pt;
267 LRESULT lResult;
268
269 if (!IsWindowEnabled( hWnd )) return 0;
270
271 if (ISITHOOKED(WH_CBT))
272 {
273 NtUserMessageCall( hWnd, WM_SYSCOMMAND, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE);
274 if (lResult) return 0;
275 }
276
277 switch (wParam & 0xfff0)
278 {
279 case SC_MOVE:
280 case SC_SIZE:
281 NtUserMessageCall( hWnd, WM_SYSCOMMAND, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE);
282 break;
283
284 case SC_MINIMIZE:
285 if (hWnd == GetActiveWindow())
286 ShowOwnedPopups(hWnd,FALSE);
287 ShowWindow( hWnd, SW_MINIMIZE );
288 break;
289
290 case SC_MAXIMIZE:
291 if (IsIconic(hWnd) && hWnd == GetActiveWindow())
292 ShowOwnedPopups(hWnd,TRUE);
293 ShowWindow( hWnd, SW_MAXIMIZE );
294 break;
295
296 case SC_RESTORE:
297 if (IsIconic(hWnd) && hWnd == GetActiveWindow())
298 ShowOwnedPopups(hWnd,TRUE);
299 ShowWindow( hWnd, SW_RESTORE );
300 break;
301
302 case SC_CLOSE:
303 return SendMessageW(hWnd, WM_CLOSE, 0, 0);
304
305 // case SC_DEFAULT:
306 case SC_MOUSEMENU:
307 {
308 Pt.x = (short)LOWORD(lParam);
309 Pt.y = (short)HIWORD(lParam);
310 MenuTrackMouseMenuBar(hWnd, wParam & 0x000f, Pt);
311 }
312 break;
313 case SC_KEYMENU:
314 MenuTrackKbdMenuBar(hWnd, wParam, (WCHAR)lParam);
315 break;
316 case SC_VSCROLL:
317 case SC_HSCROLL:
318 {
319 Pt.x = (short)LOWORD(lParam);
320 Pt.y = (short)HIWORD(lParam);
321 DefWndTrackScrollBar(hWnd, wParam, Pt);
322 }
323 break;
324
325 case SC_TASKLIST:
326 WinExec( "taskman.exe", SW_SHOWNORMAL );
327 break;
328
329 case SC_SCREENSAVE:
330 NtUserMessageCall( hWnd, WM_SYSCOMMAND, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE);
331 break;
332
333 case SC_NEXTWINDOW:
334 case SC_PREVWINDOW:
335 DoAppSwitch( wParam, lParam);
336 break;
337
338 case SC_HOTKEY:
339 {
340 HWND hwnd, hWndLastActive;
341 PWND pWnd;
342
343 hwnd = (HWND)lParam;
344 pWnd = ValidateHwnd(hwnd);
345 if (pWnd)
346 {
347 hWndLastActive = GetLastActivePopup(hwnd);
348 if (hWndLastActive)
349 {
350 hwnd = hWndLastActive;
351 pWnd = ValidateHwnd(hwnd);
352 }
353 SetForegroundWindow(hwnd);
354 if (pWnd->style & WS_MINIMIZE)
355 {
356 PostMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0);
357 }
358 }
359 }
360 break;
361
362 default:
363 FIXME("Unimplemented DefWndHandleSysCommand wParam 0x%x\n",wParam);
364 break;
365 }
366
367 return(0);
368 }
369
370 /***********************************************************************
371 * DefWndControlColor
372 *
373 * Default colors for control painting.
374 */
375 HBRUSH
376 DefWndControlColor(HDC hDC, UINT ctlType)
377 {
378 if (ctlType == CTLCOLOR_SCROLLBAR)
379 {
380 HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR);
381 COLORREF bk = GetSysColor(COLOR_3DHILIGHT);
382 SetTextColor(hDC, GetSysColor(COLOR_3DFACE));
383 SetBkColor(hDC, bk);
384
385 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
386 * we better use 0x55aa bitmap brush to make scrollbar's background
387 * look different from the window background.
388 */
389 if ( bk == GetSysColor(COLOR_WINDOW))
390 return gpsi->hbrGray;
391
392 UnrealizeObject( hb );
393 return hb;
394 }
395
396 SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
397
398 if ((ctlType == CTLCOLOR_EDIT) || (ctlType == CTLCOLOR_LISTBOX))
399 {
400 SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
401 }
402 else
403 {
404 SetBkColor(hDC, GetSysColor(COLOR_3DFACE));
405 return GetSysColorBrush(COLOR_3DFACE);
406 }
407
408 return GetSysColorBrush(COLOR_WINDOW);
409 }
410
411 static void DefWndPrint( HWND hwnd, HDC hdc, ULONG uFlags)
412 {
413 /*
414 * Visibility flag.
415 */
416 if ( (uFlags & PRF_CHECKVISIBLE) &&
417 !IsWindowVisible(hwnd) )
418 return;
419
420 /*
421 * Unimplemented flags.
422 */
423 if ( (uFlags & PRF_CHILDREN) ||
424 (uFlags & PRF_OWNED) ||
425 (uFlags & PRF_NONCLIENT) )
426 {
427 FIXME("WM_PRINT message with unsupported flags\n");
428 }
429
430 /*
431 * Background
432 */
433 if ( uFlags & PRF_ERASEBKGND)
434 SendMessageW(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0);
435
436 /*
437 * Client area
438 */
439 if ( uFlags & PRF_CLIENT)
440 SendMessageW(hwnd, WM_PRINTCLIENT, (WPARAM)hdc, uFlags);
441 }
442
443 static BOOL CALLBACK
444 UserSendUiUpdateMsg(HWND hwnd, LPARAM lParam)
445 {
446 SendMessageW(hwnd, WM_UPDATEUISTATE, (WPARAM)lParam, 0);
447 return TRUE;
448 }
449
450 // WM_SETICON
451 LRESULT FASTCALL
452 DefWndSetIcon(PWND pWnd, WPARAM wParam, LPARAM lParam)
453 {
454 HICON hIcon, hIconSmall, hIconOld;
455
456 if ( wParam > ICON_SMALL2 )
457 {
458 SetLastError(ERROR_INVALID_PARAMETER);
459 return 0;
460 }
461 hIconSmall = UserGetProp(UserHMGetHandle(pWnd), gpsi->atomIconSmProp);
462 hIcon = UserGetProp(UserHMGetHandle(pWnd), gpsi->atomIconProp);
463
464 hIconOld = wParam == ICON_BIG ? hIcon : hIconSmall;
465
466 switch(wParam)
467 {
468 case ICON_BIG:
469 hIcon = (HICON)lParam;
470 break;
471 case ICON_SMALL:
472 hIconSmall = (HICON)lParam;
473 break;
474 case ICON_SMALL2:
475 ERR("FIXME: Set ICON_SMALL2 support!\n");
476 default:
477 break;
478 }
479
480 NtUserSetProp(UserHMGetHandle(pWnd), gpsi->atomIconProp, hIcon);
481 NtUserSetProp(UserHMGetHandle(pWnd), gpsi->atomIconSmProp, hIconSmall);
482
483 if ((pWnd->style & WS_CAPTION ) == WS_CAPTION)
484 DefWndNCPaint(UserHMGetHandle(pWnd), HRGN_WINDOW, -1); /* Repaint caption */
485
486 return (LRESULT)hIconOld;
487 }
488
489 LRESULT FASTCALL
490 DefWndGetIcon(PWND pWnd, WPARAM wParam, LPARAM lParam)
491 {
492 HICON hIconRet;
493 if ( wParam > ICON_SMALL2 )
494 {
495 SetLastError(ERROR_INVALID_PARAMETER);
496 return 0;
497 }
498 switch(wParam)
499 {
500 case ICON_BIG:
501 hIconRet = UserGetProp(UserHMGetHandle(pWnd), gpsi->atomIconProp);
502 break;
503 case ICON_SMALL:
504 case ICON_SMALL2:
505 hIconRet = UserGetProp(UserHMGetHandle(pWnd), gpsi->atomIconSmProp);
506 break;
507 default:
508 break;
509 }
510 return (LRESULT)hIconRet;
511 }
512
513 VOID FASTCALL
514 DefWndScreenshot(HWND hWnd)
515 {
516 RECT rect;
517 HDC hdc;
518 INT w;
519 INT h;
520 HBITMAP hbitmap;
521 HDC hdc2;
522
523 OpenClipboard(hWnd);
524 EmptyClipboard();
525
526 hdc = GetWindowDC(hWnd);
527 GetWindowRect(hWnd, &rect);
528 w = rect.right - rect.left;
529 h = rect.bottom - rect.top;
530
531 hbitmap = CreateCompatibleBitmap(hdc, w, h);
532 hdc2 = CreateCompatibleDC(hdc);
533 SelectObject(hdc2, hbitmap);
534
535 BitBlt(hdc2, 0, 0, w, h,
536 hdc, 0, 0,
537 SRCCOPY);
538
539 SetClipboardData(CF_BITMAP, hbitmap);
540
541 ReleaseDC(hWnd, hdc);
542 ReleaseDC(hWnd, hdc2);
543
544 CloseClipboard();
545 }
546
547
548
549 LRESULT WINAPI
550 User32DefWindowProc(HWND hWnd,
551 UINT Msg,
552 WPARAM wParam,
553 LPARAM lParam,
554 BOOL bUnicode)
555 {
556 PWND pWnd = NULL;
557 if (hWnd)
558 {
559 pWnd = ValidateHwnd(hWnd);
560 if (!pWnd) return 0;
561 }
562
563 switch (Msg)
564 {
565 case WM_NCPAINT:
566 {
567 return DefWndNCPaint(hWnd, (HRGN)wParam, -1);
568 }
569
570 case WM_NCCALCSIZE:
571 {
572 return DefWndNCCalcSize(hWnd, (BOOL)wParam, (RECT*)lParam);
573 }
574
575 case WM_POPUPSYSTEMMENU:
576 {
577 /* This is an undocumented message used by the windows taskbar to
578 display the system menu of windows that belong to other processes. */
579 HMENU menu = GetSystemMenu(hWnd, FALSE);
580
581 if (menu)
582 TrackPopupMenu(menu, TPM_LEFTBUTTON|TPM_RIGHTBUTTON,
583 LOWORD(lParam), HIWORD(lParam), 0, hWnd, NULL);
584 return 0;
585 }
586
587 case WM_NCACTIVATE:
588 {
589 return DefWndNCActivate(hWnd, wParam, lParam);
590 }
591
592 case WM_NCHITTEST:
593 {
594 POINT Point;
595 Point.x = GET_X_LPARAM(lParam);
596 Point.y = GET_Y_LPARAM(lParam);
597 return (DefWndNCHitTest(hWnd, Point));
598 }
599
600 case WM_LBUTTONDOWN:
601 case WM_RBUTTONDOWN:
602 case WM_MBUTTONDOWN:
603 iF10Key = iMenuSysKey = 0;
604 break;
605
606 case WM_NCLBUTTONDOWN:
607 {
608 return (DefWndNCLButtonDown(hWnd, wParam, lParam));
609 }
610
611 case WM_LBUTTONDBLCLK:
612 return (DefWndNCLButtonDblClk(hWnd, HTCLIENT, lParam));
613
614 case WM_NCLBUTTONDBLCLK:
615 {
616 return (DefWndNCLButtonDblClk(hWnd, wParam, lParam));
617 }
618
619 case WM_NCRBUTTONDOWN:
620 return NC_HandleNCRButtonDown( hWnd, wParam, lParam );
621
622 case WM_RBUTTONUP:
623 {
624 POINT Pt;
625 if (hWnd == GetCapture())
626 {
627 ReleaseCapture();
628 }
629 Pt.x = GET_X_LPARAM(lParam);
630 Pt.y = GET_Y_LPARAM(lParam);
631 ClientToScreen(hWnd, &Pt);
632 lParam = MAKELPARAM(Pt.x, Pt.y);
633 if (bUnicode)
634 {
635 SendMessageW(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
636 }
637 else
638 {
639 SendMessageA(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
640 }
641 break;
642 }
643
644 case WM_NCRBUTTONUP:
645 /*
646 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
647 * in Windows), but what _should_ we do? According to MSDN :
648 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
649 * message to the window". When is it appropriate?
650 */
651 break;
652
653 case WM_CONTEXTMENU:
654 {
655 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD)
656 {
657 if (bUnicode)
658 {
659 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
660 }
661 else
662 {
663 SendMessageA(GetParent(hWnd), WM_CONTEXTMENU, wParam, lParam);
664 }
665 }
666 else
667 {
668 POINT Pt;
669 LONG_PTR Style;
670 LONG HitCode;
671
672 Style = GetWindowLongPtrW(hWnd, GWL_STYLE);
673
674 Pt.x = GET_X_LPARAM(lParam);
675 Pt.y = GET_Y_LPARAM(lParam);
676 if (Style & WS_CHILD)
677 {
678 ScreenToClient(GetParent(hWnd), &Pt);
679 }
680
681 HitCode = DefWndNCHitTest(hWnd, Pt);
682
683 if (HitCode == HTCAPTION || HitCode == HTSYSMENU)
684 {
685 HMENU SystemMenu;
686 UINT Flags;
687
688 if((SystemMenu = GetSystemMenu(hWnd, FALSE)))
689 {
690 MenuInitSysMenuPopup(SystemMenu, GetWindowLongPtrW(hWnd, GWL_STYLE),
691 GetClassLongPtrW(hWnd, GCL_STYLE), HitCode);
692
693 if(HitCode == HTCAPTION)
694 Flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON;
695 else
696 Flags = TPM_LEFTBUTTON;
697
698 TrackPopupMenu(SystemMenu, Flags,
699 Pt.x, Pt.y, 0, hWnd, NULL);
700 }
701 }
702 }
703 break;
704 }
705
706 case WM_PRINT:
707 {
708 DefWndPrint(hWnd, (HDC)wParam, lParam);
709 return (0);
710 }
711
712 case WM_SYSCOLORCHANGE:
713 {
714 /* force to redraw non-client area */
715 DefWndNCPaint(hWnd, HRGN_WINDOW, -1);
716 /* Use InvalidateRect to redraw client area, enable
717 * erase to redraw all subcontrols otherwise send the
718 * WM_SYSCOLORCHANGE to child windows/controls is required
719 */
720 InvalidateRect(hWnd,NULL,TRUE);
721 return (0);
722 }
723
724 case WM_PAINTICON:
725 case WM_PAINT:
726 {
727 PAINTSTRUCT Ps;
728 HDC hDC;
729
730 /* If already in Paint and Client area is not empty just return. */
731 if (pWnd->state2 & WNDS2_STARTPAINT && !IsRectEmpty(&pWnd->rcClient))
732 {
733 ERR("In Paint and Client area is not empty!\n");
734 return 0;
735 }
736
737 hDC = BeginPaint(hWnd, &Ps);
738 if (hDC)
739 {
740 HICON hIcon;
741
742 if (IsIconic(hWnd) && ((hIcon = (HICON)GetClassLongPtrW( hWnd, GCLP_HICON))))
743 {
744 RECT ClientRect;
745 INT x, y;
746 GetClientRect(hWnd, &ClientRect);
747 x = (ClientRect.right - ClientRect.left -
748 GetSystemMetrics(SM_CXICON)) / 2;
749 y = (ClientRect.bottom - ClientRect.top -
750 GetSystemMetrics(SM_CYICON)) / 2;
751 DrawIcon(hDC, x, y, hIcon);
752 }
753 EndPaint(hWnd, &Ps);
754 }
755 return (0);
756 }
757
758 case WM_CLOSE:
759 DestroyWindow(hWnd);
760 return (0);
761
762 case WM_MOUSEACTIVATE:
763 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD)
764 {
765 LONG Ret = SendMessageW(GetParent(hWnd), WM_MOUSEACTIVATE, wParam, lParam);
766 if (Ret) return (Ret);
767 }
768 return ( (HIWORD(lParam) == WM_LBUTTONDOWN && LOWORD(lParam) == HTCAPTION) ? MA_NOACTIVATE : MA_ACTIVATE );
769
770 case WM_ACTIVATE:
771 /* The default action in Windows is to set the keyboard focus to
772 * the window, if it's being activated and not minimized */
773 if (LOWORD(wParam) != WA_INACTIVE &&
774 !(GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MINIMIZE))
775 {
776 //ERR("WM_ACTIVATE %p\n",hWnd);
777 SetFocus(hWnd);
778 }
779 break;
780
781 case WM_MOUSEWHEEL:
782 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD)
783 return SendMessageW( GetParent(hWnd), WM_MOUSEWHEEL, wParam, lParam);
784 break;
785
786 case WM_ERASEBKGND:
787 case WM_ICONERASEBKGND:
788 {
789 RECT Rect;
790 HBRUSH hBrush = (HBRUSH)GetClassLongPtrW(hWnd, GCL_HBRBACKGROUND);
791
792 if (NULL == hBrush)
793 {
794 return 0;
795 }
796 if (GetClassLongPtrW(hWnd, GCL_STYLE) & CS_PARENTDC)
797 {
798 /* can't use GetClipBox with a parent DC or we fill the whole parent */
799 GetClientRect(hWnd, &Rect);
800 DPtoLP((HDC)wParam, (LPPOINT)&Rect, 2);
801 }
802 else
803 {
804 GetClipBox((HDC)wParam, &Rect);
805 }
806 FillRect((HDC)wParam, &Rect, hBrush);
807 return (1);
808 }
809
810 case WM_CTLCOLORMSGBOX:
811 case WM_CTLCOLOREDIT:
812 case WM_CTLCOLORLISTBOX:
813 case WM_CTLCOLORBTN:
814 case WM_CTLCOLORDLG:
815 case WM_CTLCOLORSTATIC:
816 case WM_CTLCOLORSCROLLBAR:
817 return (LRESULT) DefWndControlColor((HDC)wParam, Msg - WM_CTLCOLORMSGBOX);
818
819 case WM_CTLCOLOR:
820 return (LRESULT) DefWndControlColor((HDC)wParam, HIWORD(lParam));
821
822 case WM_SETCURSOR:
823 {
824 LONG_PTR Style = GetWindowLongPtrW(hWnd, GWL_STYLE);
825
826 if (Style & WS_CHILD)
827 {
828 /* with the exception of the border around a resizable wnd,
829 * give the parent first chance to set the cursor */
830 if (LOWORD(lParam) < HTLEFT || LOWORD(lParam) > HTBOTTOMRIGHT)
831 {
832 HWND parent = GetParent( hWnd );
833 if (bUnicode)
834 {
835 if (parent != GetDesktopWindow() &&
836 SendMessageW( parent, WM_SETCURSOR, wParam, lParam))
837 return TRUE;
838 }
839 else
840 {
841 if (parent != GetDesktopWindow() &&
842 SendMessageA( parent, WM_SETCURSOR, wParam, lParam))
843 return TRUE;
844 }
845 }
846 }
847 return (DefWndHandleSetCursor(hWnd, wParam, lParam, Style));
848 }
849
850 case WM_SYSCOMMAND:
851 return (DefWndHandleSysCommand(hWnd, wParam, lParam));
852
853 case WM_KEYDOWN:
854 if(wParam == VK_F10) iF10Key = VK_F10;
855 break;
856
857 case WM_SYSKEYDOWN:
858 {
859 if (HIWORD(lParam) & KF_ALTDOWN)
860 { /* Previous state, if the key was down before this message,
861 this is a cheap way to ignore autorepeat keys. */
862 if ( !(HIWORD(lParam) & KF_REPEAT) )
863 {
864 if ( ( wParam == VK_MENU ||
865 wParam == VK_LMENU ||
866 wParam == VK_RMENU ) && !iMenuSysKey )
867 iMenuSysKey = 1;
868 else
869 iMenuSysKey = 0;
870 }
871
872 iF10Key = 0;
873
874 if (wParam == VK_F4) /* Try to close the window */
875 {
876 HWND top = GetAncestor(hWnd, GA_ROOT);
877 if (!(GetClassLongPtrW(top, GCL_STYLE) & CS_NOCLOSE))
878 PostMessageW(top, WM_SYSCOMMAND, SC_CLOSE, 0);
879 }
880 else if (wParam == VK_SNAPSHOT) // Alt-VK_SNAPSHOT?
881 {
882 HWND hwnd = hWnd;
883 while (GetParent(hwnd) != NULL)
884 {
885 hwnd = GetParent(hwnd);
886 }
887 DefWndScreenshot(hwnd);
888 }
889 else if ( wParam == VK_ESCAPE || wParam == VK_TAB ) // Alt-Tab/ESC Alt-Shift-Tab/ESC
890 {
891 WPARAM wParamTmp;
892 HWND Active = GetActiveWindow(); // Noticed MDI problem.
893 if (!Active)
894 {
895 FIXME("WM_SYSKEYDOWN VK_ESCAPE no active\n");
896 break;
897 }
898 wParamTmp = GetKeyState(VK_SHIFT) & 0x8000 ? SC_PREVWINDOW : SC_NEXTWINDOW;
899 SendMessageW( Active, WM_SYSCOMMAND, wParamTmp, wParam );
900 }
901 }
902 else if( wParam == VK_F10 )
903 {
904 if (GetKeyState(VK_SHIFT) & 0x8000)
905 SendMessageW( hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, MAKELPARAM(-1, -1) );
906 iF10Key = 1;
907 }
908 break;
909 }
910
911 case WM_KEYUP:
912 case WM_SYSKEYUP:
913 {
914 /* Press and release F10 or ALT */
915 if (((wParam == VK_MENU || wParam == VK_LMENU || wParam == VK_RMENU)
916 && iMenuSysKey) || ((wParam == VK_F10) && iF10Key))
917 SendMessageW( GetAncestor( hWnd, GA_ROOT ), WM_SYSCOMMAND, SC_KEYMENU, 0L );
918 iMenuSysKey = iF10Key = 0;
919 break;
920 }
921
922 case WM_SYSCHAR:
923 {
924 iMenuSysKey = 0;
925 if (wParam == VK_RETURN && IsIconic(hWnd))
926 {
927 PostMessageW( hWnd, WM_SYSCOMMAND, SC_RESTORE, 0L );
928 break;
929 }
930 if ((HIWORD(lParam) & KF_ALTDOWN) && wParam)
931 {
932 if (wParam == VK_TAB || wParam == VK_ESCAPE) break;
933 if (wParam == VK_SPACE && (GetWindowLongPtrW( hWnd, GWL_STYLE ) & WS_CHILD))
934 SendMessageW( GetParent(hWnd), Msg, wParam, lParam );
935 else
936 SendMessageW( hWnd, WM_SYSCOMMAND, SC_KEYMENU, wParam );
937 }
938 else /* check for Ctrl-Esc */
939 if (wParam != VK_ESCAPE) MessageBeep(0);
940 break;
941 }
942
943 case WM_CANCELMODE:
944 {
945 iMenuSysKey = 0;
946 /* FIXME: Check for a desktop. */
947 //if (!(GetWindowLongPtrW( hWnd, GWL_STYLE ) & WS_CHILD)) EndMenu();
948 MENU_EndMenu( hWnd );
949 if (GetCapture() == hWnd)
950 {
951 ReleaseCapture();
952 }
953 break;
954 }
955
956 case WM_VKEYTOITEM:
957 case WM_CHARTOITEM:
958 return (-1);
959 /*
960 case WM_DROPOBJECT:
961 return DRAG_FILE;
962 */
963 case WM_QUERYDROPOBJECT:
964 {
965 if (GetWindowLongPtrW(hWnd, GWL_EXSTYLE) & WS_EX_ACCEPTFILES)
966 {
967 return(1);
968 }
969 break;
970 }
971
972 case WM_QUERYDRAGICON:
973 {
974 UINT Len;
975 HICON hIcon;
976
977 hIcon = (HICON)GetClassLongPtrW(hWnd, GCL_HICON);
978 if (hIcon)
979 {
980 return ((LRESULT)hIcon);
981 }
982 for (Len = 1; Len < 64; Len++)
983 {
984 if ((hIcon = LoadIconW(NULL, MAKEINTRESOURCEW(Len))) != NULL)
985 {
986 return((LRESULT)hIcon);
987 }
988 }
989 return ((LRESULT)LoadIconW(0, IDI_APPLICATION));
990 }
991
992 case WM_ISACTIVEICON:
993 {
994 BOOL isai;
995 isai = (pWnd->state & WNDS_ACTIVEFRAME) != 0;
996 return isai;
997 }
998
999 case WM_NOTIFYFORMAT:
1000 {
1001 if (lParam == NF_QUERY)
1002 return IsWindowUnicode(hWnd) ? NFR_UNICODE : NFR_ANSI;
1003 break;
1004 }
1005
1006 case WM_SETICON:
1007 {
1008 return DefWndSetIcon(pWnd, wParam, lParam);
1009 }
1010
1011 case WM_GETICON:
1012 {
1013 return DefWndGetIcon(pWnd, wParam, lParam);
1014 }
1015
1016 case WM_HELP:
1017 {
1018 if (bUnicode)
1019 {
1020 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
1021 }
1022 else
1023 {
1024 SendMessageA(GetParent(hWnd), Msg, wParam, lParam);
1025 }
1026 break;
1027 }
1028
1029 case WM_SYSTIMER:
1030 {
1031 THRDCARETINFO CaretInfo;
1032 switch(wParam)
1033 {
1034 case 0xffff: /* Caret timer */
1035 /* switch showing byte in win32k and get information about the caret */
1036 if(NtUserxSwitchCaretShowing(&CaretInfo) && (CaretInfo.hWnd == hWnd))
1037 {
1038 DrawCaret(hWnd, &CaretInfo);
1039 }
1040 break;
1041 }
1042 break;
1043 }
1044
1045 case WM_QUERYOPEN:
1046 case WM_QUERYENDSESSION:
1047 {
1048 return (1);
1049 }
1050
1051 case WM_INPUTLANGCHANGEREQUEST:
1052 {
1053 HKL NewHkl;
1054
1055 if(wParam & INPUTLANGCHANGE_BACKWARD
1056 && wParam & INPUTLANGCHANGE_FORWARD)
1057 {
1058 return FALSE;
1059 }
1060
1061 //FIXME: What to do with INPUTLANGCHANGE_SYSCHARSET ?
1062
1063 if(wParam & INPUTLANGCHANGE_BACKWARD) NewHkl = (HKL) HKL_PREV;
1064 else if(wParam & INPUTLANGCHANGE_FORWARD) NewHkl = (HKL) HKL_NEXT;
1065 else NewHkl = (HKL) lParam;
1066
1067 NtUserActivateKeyboardLayout(NewHkl, 0);
1068
1069 return TRUE;
1070 }
1071
1072 case WM_INPUTLANGCHANGE:
1073 {
1074 int count = 0;
1075 HWND *win_array = WIN_ListChildren( hWnd );
1076
1077 if (!win_array)
1078 break;
1079 while (win_array[count])
1080 SendMessageW( win_array[count++], WM_INPUTLANGCHANGE, wParam, lParam);
1081 HeapFree(GetProcessHeap(),0,win_array);
1082 break;
1083 }
1084
1085 case WM_QUERYUISTATE:
1086 {
1087 LRESULT Ret = 0;
1088 PWND Wnd = ValidateHwnd(hWnd);
1089 if (Wnd != NULL)
1090 {
1091 if (Wnd->HideFocus)
1092 Ret |= UISF_HIDEFOCUS;
1093 if (Wnd->HideAccel)
1094 Ret |= UISF_HIDEACCEL;
1095 }
1096 return Ret;
1097 }
1098
1099 case WM_CHANGEUISTATE:
1100 {
1101 BOOL AlwaysShowCues = FALSE;
1102 WORD Action = LOWORD(wParam);
1103 WORD Flags = HIWORD(wParam);
1104 PWND Wnd;
1105
1106 SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0);
1107 if (AlwaysShowCues)
1108 break;
1109
1110 Wnd= ValidateHwnd(hWnd);
1111 if (!Wnd || lParam != 0)
1112 break;
1113
1114 if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE))
1115 break;
1116
1117 if (Flags & UISF_ACTIVE)
1118 {
1119 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n");
1120 }
1121
1122 if (Action == UIS_INITIALIZE)
1123 {
1124 PDESKTOPINFO Desk = GetThreadDesktopInfo();
1125 if (Desk == NULL)
1126 break;
1127
1128 Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET;
1129 Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL;
1130
1131 /* We need to update wParam in case we need to send out messages */
1132 wParam = MAKEWPARAM(Action, Flags);
1133 }
1134
1135 switch (Action)
1136 {
1137 case UIS_SET:
1138 /* See if we actually need to change something */
1139 if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus)
1140 break;
1141 if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel)
1142 break;
1143
1144 /* Don't need to do anything... */
1145 return 0;
1146
1147 case UIS_CLEAR:
1148 /* See if we actually need to change something */
1149 if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus)
1150 break;
1151 if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel)
1152 break;
1153
1154 /* Don't need to do anything... */
1155 return 0;
1156
1157 default:
1158 WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action);
1159 break;
1160 }
1161
1162 if ((Wnd->style & WS_CHILD) && Wnd->spwndParent != NULL)
1163 {
1164 /* We're a child window and we need to pass this message down until
1165 we reach the root */
1166 hWnd = UserHMGetHandle((PWND)DesktopPtrToUser(Wnd->spwndParent));
1167 }
1168 else
1169 {
1170 /* We're a top level window, we need to change the UI state */
1171 Msg = WM_UPDATEUISTATE;
1172 }
1173
1174 if (bUnicode)
1175 return SendMessageW(hWnd, Msg, wParam, lParam);
1176 else
1177 return SendMessageA(hWnd, Msg, wParam, lParam);
1178 }
1179
1180 case WM_UPDATEUISTATE:
1181 {
1182 BOOL Change = TRUE;
1183 BOOL AlwaysShowCues = FALSE;
1184 WORD Action = LOWORD(wParam);
1185 WORD Flags = HIWORD(wParam);
1186 PWND Wnd;
1187
1188 SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0);
1189 if (AlwaysShowCues)
1190 break;
1191
1192 Wnd = ValidateHwnd(hWnd);
1193 if (!Wnd || lParam != 0)
1194 break;
1195
1196 if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE))
1197 break;
1198
1199 if (Flags & UISF_ACTIVE)
1200 {
1201 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n");
1202 }
1203
1204 if (Action == UIS_INITIALIZE)
1205 {
1206 PDESKTOPINFO Desk = GetThreadDesktopInfo();
1207 if (Desk == NULL)
1208 break;
1209
1210 Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET;
1211 Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL;
1212
1213 /* We need to update wParam for broadcasting the update */
1214 wParam = MAKEWPARAM(Action, Flags);
1215 }
1216
1217 switch (Action)
1218 {
1219 case UIS_SET:
1220 /* See if we actually need to change something */
1221 if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus)
1222 break;
1223 if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel)
1224 break;
1225
1226 /* Don't need to do anything... */
1227 Change = FALSE;
1228 break;
1229
1230 case UIS_CLEAR:
1231 /* See if we actually need to change something */
1232 if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus)
1233 break;
1234 if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel)
1235 break;
1236
1237 /* Don't need to do anything... */
1238 Change = FALSE;
1239 break;
1240
1241 default:
1242 WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action);
1243 return 0;
1244 }
1245
1246 /* Pack the information and call win32k */
1247 if (Change)
1248 {
1249 if (!NtUserxUpdateUiState(hWnd, Flags | ((DWORD)Action << 3)))
1250 break;
1251 }
1252
1253 /* Always broadcast the update to all children */
1254 EnumChildWindows(hWnd,
1255 UserSendUiUpdateMsg,
1256 (LPARAM)wParam);
1257
1258 break;
1259 }
1260
1261 /* Move to Win32k !*/
1262 case WM_SHOWWINDOW:
1263 if (!lParam) break; // Call when it is necessary.
1264 case WM_SYNCPAINT:
1265 case WM_SETREDRAW:
1266 case WM_CLIENTSHUTDOWN:
1267 case WM_GETHOTKEY:
1268 case WM_SETHOTKEY:
1269 case WM_WINDOWPOSCHANGING:
1270 case WM_WINDOWPOSCHANGED:
1271 case WM_APPCOMMAND:
1272 {
1273 LRESULT lResult;
1274 NtUserMessageCall( hWnd, Msg, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, !bUnicode);
1275 return lResult;
1276 }
1277 }
1278 return 0;
1279 }
1280
1281
1282 /*
1283 * helpers for calling IMM32 (from Wine 10/22/2008)
1284 *
1285 * WM_IME_* messages are generated only by IMM32,
1286 * so I assume imm32 is already LoadLibrary-ed.
1287 */
1288 static HWND
1289 DefWndImmGetDefaultIMEWnd(HWND hwnd)
1290 {
1291 HINSTANCE hInstIMM = GetModuleHandleW(L"imm32\0");
1292 HWND (WINAPI *pFunc)(HWND);
1293 HWND hwndRet = 0;
1294
1295 if (!hInstIMM)
1296 {
1297 ERR("cannot get IMM32 handle\n");
1298 return 0;
1299 }
1300
1301 pFunc = (void*) GetProcAddress(hInstIMM, "ImmGetDefaultIMEWnd");
1302 if (pFunc != NULL)
1303 hwndRet = (*pFunc)(hwnd);
1304
1305 return hwndRet;
1306 }
1307
1308
1309 static BOOL
1310 DefWndImmIsUIMessageA(HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1311 {
1312 HINSTANCE hInstIMM = GetModuleHandleW(L"imm32\0");
1313 BOOL (WINAPI *pFunc)(HWND,UINT,WPARAM,LPARAM);
1314 BOOL fRet = FALSE;
1315
1316 if (!hInstIMM)
1317 {
1318 ERR("cannot get IMM32 handle\n");
1319 return FALSE;
1320 }
1321
1322 pFunc = (void*) GetProcAddress(hInstIMM, "ImmIsUIMessageA");
1323 if (pFunc != NULL)
1324 fRet = (*pFunc)(hwndIME, msg, wParam, lParam);
1325
1326 return fRet;
1327 }
1328
1329
1330 static BOOL
1331 DefWndImmIsUIMessageW(HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1332 {
1333 HINSTANCE hInstIMM = GetModuleHandleW(L"imm32\0");
1334 BOOL (WINAPI *pFunc)(HWND,UINT,WPARAM,LPARAM);
1335 BOOL fRet = FALSE;
1336
1337 if (!hInstIMM)
1338 {
1339 ERR("cannot get IMM32 handle\n");
1340 return FALSE;
1341 }
1342
1343 pFunc = (void*) GetProcAddress(hInstIMM, "ImmIsUIMessageW");
1344 if (pFunc != NULL)
1345 fRet = (*pFunc)(hwndIME, msg, wParam, lParam);
1346
1347 return fRet;
1348 }
1349
1350
1351 LRESULT WINAPI
1352 RealDefWindowProcA(HWND hWnd,
1353 UINT Msg,
1354 WPARAM wParam,
1355 LPARAM lParam)
1356 {
1357 LRESULT Result = 0;
1358 PWND Wnd;
1359
1360 Wnd = ValidateHwnd(hWnd);
1361
1362 if ( !Wnd &&
1363 Msg != WM_CTLCOLORMSGBOX &&
1364 Msg != WM_CTLCOLORBTN &&
1365 Msg != WM_CTLCOLORDLG &&
1366 Msg != WM_CTLCOLORSTATIC )
1367 return 0;
1368
1369 SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam);
1370 switch (Msg)
1371 {
1372 case WM_NCCREATE:
1373 {
1374 if ( Wnd &&
1375 Wnd->style & (WS_HSCROLL | WS_VSCROLL) )
1376 {
1377 if (!Wnd->pSBInfo)
1378 {
1379 SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0};
1380 SetScrollInfo( hWnd, SB_HORZ, &si, FALSE );
1381 SetScrollInfo( hWnd, SB_VERT, &si, FALSE );
1382 }
1383 }
1384
1385 if (lParam)
1386 {
1387 LPCREATESTRUCTA cs = (LPCREATESTRUCTA)lParam;
1388 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1389 * may have child window IDs instead of window name */
1390 if (HIWORD(cs->lpszName))
1391 {
1392 DefSetText(hWnd, (PCWSTR)cs->lpszName, TRUE);
1393 }
1394 Result = 1;
1395 }
1396 break;
1397 }
1398
1399 case WM_GETTEXTLENGTH:
1400 {
1401 PWSTR buf;
1402 ULONG len;
1403
1404 if (Wnd != NULL && Wnd->strName.Length != 0)
1405 {
1406 buf = DesktopPtrToUser(Wnd->strName.Buffer);
1407 if (buf != NULL &&
1408 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len,
1409 buf,
1410 Wnd->strName.Length)))
1411 {
1412 Result = (LRESULT) len;
1413 }
1414 }
1415 else Result = 0L;
1416
1417 break;
1418 }
1419
1420 case WM_GETTEXT:
1421 {
1422 PWSTR buf = NULL;
1423 PSTR outbuf = (PSTR)lParam;
1424 UINT copy;
1425
1426 if (Wnd != NULL && wParam != 0)
1427 {
1428 if (Wnd->strName.Buffer != NULL)
1429 buf = DesktopPtrToUser(Wnd->strName.Buffer);
1430 else
1431 outbuf[0] = L'\0';
1432
1433 if (buf != NULL)
1434 {
1435 if (Wnd->strName.Length != 0)
1436 {
1437 copy = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1);
1438 Result = WideCharToMultiByte(CP_ACP,
1439 0,
1440 buf,
1441 copy,
1442 outbuf,
1443 wParam,
1444 NULL,
1445 NULL);
1446 outbuf[Result] = '\0';
1447 }
1448 else
1449 outbuf[0] = '\0';
1450 }
1451 }
1452 break;
1453 }
1454
1455 case WM_SETTEXT:
1456 {
1457 DefSetText(hWnd, (PCWSTR)lParam, TRUE);
1458
1459 if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1460 {
1461 /* FIXME: this is not 100% correct */
1462 if(gpsi->dwSRVIFlags & SRVINFO_APIHOOK)
1463 {
1464 SendMessage(hWnd, WM_NCUAHDRAWCAPTION,0,0);
1465 }
1466 else
1467 {
1468 DefWndNCPaint(hWnd, HRGN_WINDOW, -1);
1469 }
1470 }
1471 Result = 1;
1472 break;
1473 }
1474
1475 case WM_IME_KEYDOWN:
1476 {
1477 Result = PostMessageA(hWnd, WM_KEYDOWN, wParam, lParam);
1478 break;
1479 }
1480
1481 case WM_IME_KEYUP:
1482 {
1483 Result = PostMessageA(hWnd, WM_KEYUP, wParam, lParam);
1484 break;
1485 }
1486
1487 case WM_IME_CHAR:
1488 {
1489 if (HIBYTE(wParam))
1490 PostMessageA(hWnd, WM_CHAR, HIBYTE(wParam), lParam);
1491 PostMessageA(hWnd, WM_CHAR, LOBYTE(wParam), lParam);
1492 break;
1493 }
1494
1495 case WM_IME_STARTCOMPOSITION:
1496 case WM_IME_COMPOSITION:
1497 case WM_IME_ENDCOMPOSITION:
1498 case WM_IME_SELECT:
1499 case WM_IME_NOTIFY:
1500 {
1501 HWND hwndIME;
1502
1503 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
1504 if (hwndIME)
1505 Result = SendMessageA(hwndIME, Msg, wParam, lParam);
1506 break;
1507 }
1508
1509 case WM_IME_SETCONTEXT:
1510 {
1511 HWND hwndIME;
1512
1513 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
1514 if (hwndIME)
1515 Result = DefWndImmIsUIMessageA(hwndIME, Msg, wParam, lParam);
1516 break;
1517 }
1518
1519 /* fall through */
1520 default:
1521 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, FALSE);
1522 }
1523
1524 SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam);
1525 return Result;
1526 }
1527
1528
1529 LRESULT WINAPI
1530 RealDefWindowProcW(HWND hWnd,
1531 UINT Msg,
1532 WPARAM wParam,
1533 LPARAM lParam)
1534 {
1535 LRESULT Result = 0;
1536 PWND Wnd;
1537
1538 Wnd = ValidateHwnd(hWnd);
1539
1540 if ( !Wnd &&
1541 Msg != WM_CTLCOLORMSGBOX &&
1542 Msg != WM_CTLCOLORBTN &&
1543 Msg != WM_CTLCOLORDLG &&
1544 Msg != WM_CTLCOLORSTATIC )
1545 return 0;
1546
1547 SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam);
1548 switch (Msg)
1549 {
1550 case WM_NCCREATE:
1551 {
1552 if ( Wnd &&
1553 Wnd->style & (WS_HSCROLL | WS_VSCROLL) )
1554 {
1555 if (!Wnd->pSBInfo)
1556 {
1557 SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0};
1558 SetScrollInfo( hWnd, SB_HORZ, &si, FALSE );
1559 SetScrollInfo( hWnd, SB_VERT, &si, FALSE );
1560 }
1561 }
1562
1563 if (lParam)
1564 {
1565 LPCREATESTRUCTW cs = (LPCREATESTRUCTW)lParam;
1566 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1567 * may have child window IDs instead of window name */
1568 if (HIWORD(cs->lpszName))
1569 {
1570 DefSetText(hWnd, cs->lpszName, FALSE);
1571 }
1572 Result = 1;
1573 }
1574 break;
1575 }
1576
1577 case WM_GETTEXTLENGTH:
1578 {
1579 PWSTR buf;
1580 ULONG len;
1581
1582 if (Wnd != NULL && Wnd->strName.Length != 0)
1583 {
1584 buf = DesktopPtrToUser(Wnd->strName.Buffer);
1585 if (buf != NULL &&
1586 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len,
1587 buf,
1588 Wnd->strName.Length)))
1589 {
1590 Result = (LRESULT) (Wnd->strName.Length / sizeof(WCHAR));
1591 }
1592 }
1593 else Result = 0L;
1594
1595 break;
1596 }
1597
1598 case WM_GETTEXT:
1599 {
1600 PWSTR buf = NULL;
1601 PWSTR outbuf = (PWSTR)lParam;
1602
1603 if (Wnd != NULL && wParam != 0)
1604 {
1605 if (Wnd->strName.Buffer != NULL)
1606 buf = DesktopPtrToUser(Wnd->strName.Buffer);
1607 else
1608 outbuf[0] = L'\0';
1609
1610 if (buf != NULL)
1611 {
1612 if (Wnd->strName.Length != 0)
1613 {
1614 Result = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1);
1615 RtlCopyMemory(outbuf,
1616 buf,
1617 Result * sizeof(WCHAR));
1618 outbuf[Result] = L'\0';
1619 }
1620 else
1621 outbuf[0] = L'\0';
1622 }
1623 }
1624 break;
1625 }
1626
1627 case WM_SETTEXT:
1628 {
1629 DefSetText(hWnd, (PCWSTR)lParam, FALSE);
1630
1631 if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1632 {
1633 /* FIXME: this is not 100% correct */
1634 if(gpsi->dwSRVIFlags & SRVINFO_APIHOOK)
1635 {
1636 SendMessage(hWnd, WM_NCUAHDRAWCAPTION,0,0);
1637 }
1638 else
1639 {
1640 DefWndNCPaint(hWnd, HRGN_WINDOW, -1);
1641 }
1642 }
1643 Result = 1;
1644 break;
1645 }
1646
1647 case WM_IME_CHAR:
1648 {
1649 PostMessageW(hWnd, WM_CHAR, wParam, lParam);
1650 Result = 0;
1651 break;
1652 }
1653
1654 case WM_IME_KEYDOWN:
1655 {
1656 Result = PostMessageW(hWnd, WM_KEYDOWN, wParam, lParam);
1657 break;
1658 }
1659
1660 case WM_IME_KEYUP:
1661 {
1662 Result = PostMessageW(hWnd, WM_KEYUP, wParam, lParam);
1663 break;
1664 }
1665
1666 case WM_IME_STARTCOMPOSITION:
1667 case WM_IME_COMPOSITION:
1668 case WM_IME_ENDCOMPOSITION:
1669 case WM_IME_SELECT:
1670 case WM_IME_NOTIFY:
1671 {
1672 HWND hwndIME;
1673
1674 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
1675 if (hwndIME)
1676 Result = SendMessageW(hwndIME, Msg, wParam, lParam);
1677 break;
1678 }
1679
1680 case WM_IME_SETCONTEXT:
1681 {
1682 HWND hwndIME;
1683
1684 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
1685 if (hwndIME)
1686 Result = DefWndImmIsUIMessageW(hwndIME, Msg, wParam, lParam);
1687 break;
1688 }
1689
1690 default:
1691 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, TRUE);
1692 }
1693 SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam);
1694
1695 return Result;
1696 }
1697
1698 LRESULT WINAPI
1699 DefWindowProcA(HWND hWnd,
1700 UINT Msg,
1701 WPARAM wParam,
1702 LPARAM lParam)
1703 {
1704 BOOL Hook, msgOverride = FALSE;
1705 LRESULT Result = 0;
1706
1707 LoadUserApiHook();
1708
1709 Hook = BeginIfHookedUserApiHook();
1710 if (Hook)
1711 {
1712 msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray);
1713 if(msgOverride == FALSE)
1714 {
1715 EndUserApiHook();
1716 }
1717 }
1718
1719 /* Bypass SEH and go direct. */
1720 if (!Hook || !msgOverride)
1721 return RealDefWindowProcA(hWnd, Msg, wParam, lParam);
1722
1723 _SEH2_TRY
1724 {
1725 Result = guah.DefWindowProcA(hWnd, Msg, wParam, lParam);
1726 }
1727 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1728 {
1729 }
1730 _SEH2_END;
1731
1732 EndUserApiHook();
1733
1734 return Result;
1735 }
1736
1737 LRESULT WINAPI
1738 DefWindowProcW(HWND hWnd,
1739 UINT Msg,
1740 WPARAM wParam,
1741 LPARAM lParam)
1742 {
1743 BOOL Hook, msgOverride = FALSE;
1744 LRESULT Result = 0;
1745
1746 LoadUserApiHook();
1747
1748 Hook = BeginIfHookedUserApiHook();
1749 if (Hook)
1750 {
1751 msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray);
1752 if(msgOverride == FALSE)
1753 {
1754 EndUserApiHook();
1755 }
1756 }
1757
1758 /* Bypass SEH and go direct. */
1759 if (!Hook || !msgOverride)
1760 return RealDefWindowProcW(hWnd, Msg, wParam, lParam);
1761
1762 _SEH2_TRY
1763 {
1764 Result = guah.DefWindowProcW(hWnd, Msg, wParam, lParam);
1765 }
1766 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1767 {
1768 }
1769 _SEH2_END;
1770
1771 EndUserApiHook();
1772
1773 return Result;
1774 }