[User32]
[reactos.git] / reactos / win32ss / user / user32 / windows / defwnd.c
1 /*
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS user32.dll
5 * FILE: 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
626 Pt.x = GET_X_LPARAM(lParam);
627 Pt.y = GET_Y_LPARAM(lParam);
628 ClientToScreen(hWnd, &Pt);
629 lParam = MAKELPARAM(Pt.x, Pt.y);
630 if (bUnicode)
631 {
632 SendMessageW(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
633 }
634 else
635 {
636 SendMessageA(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
637 }
638 break;
639 }
640
641 case WM_NCRBUTTONUP:
642 /*
643 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
644 * in Windows), but what _should_ we do? According to MSDN :
645 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
646 * message to the window". When is it appropriate?
647 */
648 break;
649
650 case WM_CONTEXTMENU:
651 {
652 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD)
653 {
654 if (bUnicode)
655 {
656 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
657 }
658 else
659 {
660 SendMessageA(GetParent(hWnd), WM_CONTEXTMENU, wParam, lParam);
661 }
662 }
663 else
664 {
665 POINT Pt;
666 LONG_PTR Style;
667 LONG HitCode;
668
669 Style = GetWindowLongPtrW(hWnd, GWL_STYLE);
670
671 Pt.x = GET_X_LPARAM(lParam);
672 Pt.y = GET_Y_LPARAM(lParam);
673 if (Style & WS_CHILD)
674 {
675 ScreenToClient(GetParent(hWnd), &Pt);
676 }
677
678 HitCode = DefWndNCHitTest(hWnd, Pt);
679
680 if (HitCode == HTCAPTION || HitCode == HTSYSMENU)
681 {
682 HMENU SystemMenu;
683 UINT Flags;
684
685 if((SystemMenu = GetSystemMenu(hWnd, FALSE)))
686 {
687 MenuInitSysMenuPopup(SystemMenu, GetWindowLongPtrW(hWnd, GWL_STYLE),
688 GetClassLongPtrW(hWnd, GCL_STYLE), HitCode);
689
690 if(HitCode == HTCAPTION)
691 Flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON;
692 else
693 Flags = TPM_LEFTBUTTON;
694
695 TrackPopupMenu(SystemMenu, Flags,
696 Pt.x, Pt.y, 0, hWnd, NULL);
697 }
698 }
699 }
700 break;
701 }
702
703 case WM_PRINT:
704 {
705 DefWndPrint(hWnd, (HDC)wParam, lParam);
706 return (0);
707 }
708
709 case WM_SYSCOLORCHANGE:
710 {
711 /* force to redraw non-client area */
712 DefWndNCPaint(hWnd, HRGN_WINDOW, -1);
713 /* Use InvalidateRect to redraw client area, enable
714 * erase to redraw all subcontrols otherwise send the
715 * WM_SYSCOLORCHANGE to child windows/controls is required
716 */
717 InvalidateRect(hWnd,NULL,TRUE);
718 return (0);
719 }
720
721 case WM_PAINTICON:
722 case WM_PAINT:
723 {
724 PAINTSTRUCT Ps;
725 HDC hDC;
726
727 /* If already in Paint and Client area is not empty just return. */
728 if (pWnd->state2 & WNDS2_STARTPAINT && !IsRectEmpty(&pWnd->rcClient))
729 {
730 ERR("In Paint and Client area is not empty!\n");
731 return 0;
732 }
733
734 hDC = BeginPaint(hWnd, &Ps);
735 if (hDC)
736 {
737 HICON hIcon;
738
739 if (IsIconic(hWnd) && ((hIcon = (HICON)GetClassLongPtrW( hWnd, GCLP_HICON))))
740 {
741 RECT ClientRect;
742 INT x, y;
743 GetClientRect(hWnd, &ClientRect);
744 x = (ClientRect.right - ClientRect.left -
745 GetSystemMetrics(SM_CXICON)) / 2;
746 y = (ClientRect.bottom - ClientRect.top -
747 GetSystemMetrics(SM_CYICON)) / 2;
748 DrawIcon(hDC, x, y, hIcon);
749 }
750 EndPaint(hWnd, &Ps);
751 }
752 return (0);
753 }
754
755 case WM_CLOSE:
756 DestroyWindow(hWnd);
757 return (0);
758
759 case WM_MOUSEACTIVATE:
760 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD)
761 {
762 LONG Ret = SendMessageW(GetParent(hWnd), WM_MOUSEACTIVATE, wParam, lParam);
763 if (Ret) return (Ret);
764 }
765 return ( (HIWORD(lParam) == WM_LBUTTONDOWN && LOWORD(lParam) == HTCAPTION) ? MA_NOACTIVATE : MA_ACTIVATE );
766
767 case WM_ACTIVATE:
768 /* The default action in Windows is to set the keyboard focus to
769 * the window, if it's being activated and not minimized */
770 if (LOWORD(wParam) != WA_INACTIVE &&
771 !(GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MINIMIZE))
772 {
773 //ERR("WM_ACTIVATE %p\n",hWnd);
774 SetFocus(hWnd);
775 }
776 break;
777
778 case WM_MOUSEWHEEL:
779 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD)
780 return SendMessageW( GetParent(hWnd), WM_MOUSEWHEEL, wParam, lParam);
781 break;
782
783 case WM_ERASEBKGND:
784 case WM_ICONERASEBKGND:
785 {
786 RECT Rect;
787 HBRUSH hBrush = (HBRUSH)GetClassLongPtrW(hWnd, GCL_HBRBACKGROUND);
788
789 if (NULL == hBrush)
790 {
791 return 0;
792 }
793 if (GetClassLongPtrW(hWnd, GCL_STYLE) & CS_PARENTDC)
794 {
795 /* can't use GetClipBox with a parent DC or we fill the whole parent */
796 GetClientRect(hWnd, &Rect);
797 DPtoLP((HDC)wParam, (LPPOINT)&Rect, 2);
798 }
799 else
800 {
801 GetClipBox((HDC)wParam, &Rect);
802 }
803 FillRect((HDC)wParam, &Rect, hBrush);
804 return (1);
805 }
806
807 case WM_CTLCOLORMSGBOX:
808 case WM_CTLCOLOREDIT:
809 case WM_CTLCOLORLISTBOX:
810 case WM_CTLCOLORBTN:
811 case WM_CTLCOLORDLG:
812 case WM_CTLCOLORSTATIC:
813 case WM_CTLCOLORSCROLLBAR:
814 return (LRESULT) DefWndControlColor((HDC)wParam, Msg - WM_CTLCOLORMSGBOX);
815
816 case WM_CTLCOLOR:
817 return (LRESULT) DefWndControlColor((HDC)wParam, HIWORD(lParam));
818
819 case WM_SETCURSOR:
820 {
821 LONG_PTR Style = GetWindowLongPtrW(hWnd, GWL_STYLE);
822
823 if (Style & WS_CHILD)
824 {
825 /* with the exception of the border around a resizable wnd,
826 * give the parent first chance to set the cursor */
827 if (LOWORD(lParam) < HTLEFT || LOWORD(lParam) > HTBOTTOMRIGHT)
828 {
829 HWND parent = GetParent( hWnd );
830 if (bUnicode)
831 {
832 if (parent != GetDesktopWindow() &&
833 SendMessageW( parent, WM_SETCURSOR, wParam, lParam))
834 return TRUE;
835 }
836 else
837 {
838 if (parent != GetDesktopWindow() &&
839 SendMessageA( parent, WM_SETCURSOR, wParam, lParam))
840 return TRUE;
841 }
842 }
843 }
844 return (DefWndHandleSetCursor(hWnd, wParam, lParam, Style));
845 }
846
847 case WM_SYSCOMMAND:
848 return (DefWndHandleSysCommand(hWnd, wParam, lParam));
849
850 case WM_KEYDOWN:
851 if(wParam == VK_F10) iF10Key = VK_F10;
852 break;
853
854 case WM_SYSKEYDOWN:
855 {
856 if (HIWORD(lParam) & KF_ALTDOWN)
857 { /* Previous state, if the key was down before this message,
858 this is a cheap way to ignore autorepeat keys. */
859 if ( !(HIWORD(lParam) & KF_REPEAT) )
860 {
861 if ( ( wParam == VK_MENU ||
862 wParam == VK_LMENU ||
863 wParam == VK_RMENU ) && !iMenuSysKey )
864 iMenuSysKey = 1;
865 else
866 iMenuSysKey = 0;
867 }
868
869 iF10Key = 0;
870
871 if (wParam == VK_F4) /* Try to close the window */
872 {
873 HWND top = GetAncestor(hWnd, GA_ROOT);
874 if (!(GetClassLongPtrW(top, GCL_STYLE) & CS_NOCLOSE))
875 PostMessageW(top, WM_SYSCOMMAND, SC_CLOSE, 0);
876 }
877 else if (wParam == VK_SNAPSHOT) // Alt-VK_SNAPSHOT?
878 {
879 HWND hwnd = hWnd;
880 while (GetParent(hwnd) != NULL)
881 {
882 hwnd = GetParent(hwnd);
883 }
884 DefWndScreenshot(hwnd);
885 }
886 else if ( wParam == VK_ESCAPE || wParam == VK_TAB ) // Alt-Tab/ESC Alt-Shift-Tab/ESC
887 {
888 WPARAM wParamTmp;
889 HWND Active = GetActiveWindow(); // Noticed MDI problem.
890 if (!Active)
891 {
892 FIXME("WM_SYSKEYDOWN VK_ESCAPE no active\n");
893 break;
894 }
895 wParamTmp = GetKeyState(VK_SHIFT) & 0x8000 ? SC_PREVWINDOW : SC_NEXTWINDOW;
896 SendMessageW( Active, WM_SYSCOMMAND, wParamTmp, wParam );
897 }
898 }
899 else if( wParam == VK_F10 )
900 {
901 if (GetKeyState(VK_SHIFT) & 0x8000)
902 SendMessageW( hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, MAKELPARAM(-1, -1) );
903 iF10Key = 1;
904 }
905 break;
906 }
907
908 case WM_KEYUP:
909 case WM_SYSKEYUP:
910 {
911 /* Press and release F10 or ALT */
912 if (((wParam == VK_MENU || wParam == VK_LMENU || wParam == VK_RMENU)
913 && iMenuSysKey) || ((wParam == VK_F10) && iF10Key))
914 SendMessageW( GetAncestor( hWnd, GA_ROOT ), WM_SYSCOMMAND, SC_KEYMENU, 0L );
915 iMenuSysKey = iF10Key = 0;
916 break;
917 }
918
919 case WM_SYSCHAR:
920 {
921 iMenuSysKey = 0;
922 if (wParam == VK_RETURN && IsIconic(hWnd))
923 {
924 PostMessageW( hWnd, WM_SYSCOMMAND, SC_RESTORE, 0L );
925 break;
926 }
927 if ((HIWORD(lParam) & KF_ALTDOWN) && wParam)
928 {
929 if (wParam == VK_TAB || wParam == VK_ESCAPE) break;
930 if (wParam == VK_SPACE && (GetWindowLongPtrW( hWnd, GWL_STYLE ) & WS_CHILD))
931 SendMessageW( GetParent(hWnd), Msg, wParam, lParam );
932 else
933 SendMessageW( hWnd, WM_SYSCOMMAND, SC_KEYMENU, wParam );
934 }
935 else /* check for Ctrl-Esc */
936 if (wParam != VK_ESCAPE) MessageBeep(0);
937 break;
938 }
939
940 case WM_CANCELMODE:
941 {
942 iMenuSysKey = 0;
943 /* FIXME: Check for a desktop. */
944 //if (!(GetWindowLongPtrW( hWnd, GWL_STYLE ) & WS_CHILD)) EndMenu();
945 MENU_EndMenu( hWnd );
946 if (GetCapture() == hWnd)
947 {
948 ReleaseCapture();
949 }
950 break;
951 }
952
953 case WM_VKEYTOITEM:
954 case WM_CHARTOITEM:
955 return (-1);
956 /*
957 case WM_DROPOBJECT:
958 return DRAG_FILE;
959 */
960 case WM_QUERYDROPOBJECT:
961 {
962 if (GetWindowLongPtrW(hWnd, GWL_EXSTYLE) & WS_EX_ACCEPTFILES)
963 {
964 return(1);
965 }
966 break;
967 }
968
969 case WM_QUERYDRAGICON:
970 {
971 UINT Len;
972 HICON hIcon;
973
974 hIcon = (HICON)GetClassLongPtrW(hWnd, GCL_HICON);
975 if (hIcon)
976 {
977 return ((LRESULT)hIcon);
978 }
979 for (Len = 1; Len < 64; Len++)
980 {
981 if ((hIcon = LoadIconW(NULL, MAKEINTRESOURCEW(Len))) != NULL)
982 {
983 return((LRESULT)hIcon);
984 }
985 }
986 return ((LRESULT)LoadIconW(0, IDI_APPLICATION));
987 }
988
989 case WM_ISACTIVEICON:
990 {
991 BOOL isai;
992 isai = (pWnd->state & WNDS_ACTIVEFRAME) != 0;
993 return isai;
994 }
995
996 case WM_NOTIFYFORMAT:
997 {
998 if (lParam == NF_QUERY)
999 return IsWindowUnicode(hWnd) ? NFR_UNICODE : NFR_ANSI;
1000 break;
1001 }
1002
1003 case WM_SETICON:
1004 {
1005 return DefWndSetIcon(pWnd, wParam, lParam);
1006 }
1007
1008 case WM_GETICON:
1009 {
1010 return DefWndGetIcon(pWnd, wParam, lParam);
1011 }
1012
1013 case WM_HELP:
1014 {
1015 if (bUnicode)
1016 {
1017 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
1018 }
1019 else
1020 {
1021 SendMessageA(GetParent(hWnd), Msg, wParam, lParam);
1022 }
1023 break;
1024 }
1025
1026 case WM_SYSTIMER:
1027 {
1028 THRDCARETINFO CaretInfo;
1029 switch(wParam)
1030 {
1031 case 0xffff: /* Caret timer */
1032 /* switch showing byte in win32k and get information about the caret */
1033 if(NtUserxSwitchCaretShowing(&CaretInfo) && (CaretInfo.hWnd == hWnd))
1034 {
1035 DrawCaret(hWnd, &CaretInfo);
1036 }
1037 break;
1038 }
1039 break;
1040 }
1041
1042 case WM_QUERYOPEN:
1043 case WM_QUERYENDSESSION:
1044 {
1045 return (1);
1046 }
1047
1048 case WM_INPUTLANGCHANGEREQUEST:
1049 {
1050 HKL NewHkl;
1051
1052 if(wParam & INPUTLANGCHANGE_BACKWARD
1053 && wParam & INPUTLANGCHANGE_FORWARD)
1054 {
1055 return FALSE;
1056 }
1057
1058 //FIXME: What to do with INPUTLANGCHANGE_SYSCHARSET ?
1059
1060 if(wParam & INPUTLANGCHANGE_BACKWARD) NewHkl = (HKL) HKL_PREV;
1061 else if(wParam & INPUTLANGCHANGE_FORWARD) NewHkl = (HKL) HKL_NEXT;
1062 else NewHkl = (HKL) lParam;
1063
1064 NtUserActivateKeyboardLayout(NewHkl, 0);
1065
1066 return TRUE;
1067 }
1068
1069 case WM_INPUTLANGCHANGE:
1070 {
1071 int count = 0;
1072 HWND *win_array = WIN_ListChildren( hWnd );
1073
1074 if (!win_array)
1075 break;
1076 while (win_array[count])
1077 SendMessageW( win_array[count++], WM_INPUTLANGCHANGE, wParam, lParam);
1078 HeapFree(GetProcessHeap(),0,win_array);
1079 break;
1080 }
1081
1082 case WM_QUERYUISTATE:
1083 {
1084 LRESULT Ret = 0;
1085 PWND Wnd = ValidateHwnd(hWnd);
1086 if (Wnd != NULL)
1087 {
1088 if (Wnd->HideFocus)
1089 Ret |= UISF_HIDEFOCUS;
1090 if (Wnd->HideAccel)
1091 Ret |= UISF_HIDEACCEL;
1092 }
1093 return Ret;
1094 }
1095
1096 case WM_CHANGEUISTATE:
1097 {
1098 BOOL AlwaysShowCues = FALSE;
1099 WORD Action = LOWORD(wParam);
1100 WORD Flags = HIWORD(wParam);
1101 PWND Wnd;
1102
1103 SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0);
1104 if (AlwaysShowCues)
1105 break;
1106
1107 Wnd= ValidateHwnd(hWnd);
1108 if (!Wnd || lParam != 0)
1109 break;
1110
1111 if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE))
1112 break;
1113
1114 if (Flags & UISF_ACTIVE)
1115 {
1116 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n");
1117 }
1118
1119 if (Action == UIS_INITIALIZE)
1120 {
1121 PDESKTOPINFO Desk = GetThreadDesktopInfo();
1122 if (Desk == NULL)
1123 break;
1124
1125 Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET;
1126 Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL;
1127
1128 /* We need to update wParam in case we need to send out messages */
1129 wParam = MAKEWPARAM(Action, Flags);
1130 }
1131
1132 switch (Action)
1133 {
1134 case UIS_SET:
1135 /* See if we actually need to change something */
1136 if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus)
1137 break;
1138 if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel)
1139 break;
1140
1141 /* Don't need to do anything... */
1142 return 0;
1143
1144 case UIS_CLEAR:
1145 /* See if we actually need to change something */
1146 if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus)
1147 break;
1148 if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel)
1149 break;
1150
1151 /* Don't need to do anything... */
1152 return 0;
1153
1154 default:
1155 WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action);
1156 break;
1157 }
1158
1159 if ((Wnd->style & WS_CHILD) && Wnd->spwndParent != NULL)
1160 {
1161 /* We're a child window and we need to pass this message down until
1162 we reach the root */
1163 hWnd = UserHMGetHandle((PWND)DesktopPtrToUser(Wnd->spwndParent));
1164 }
1165 else
1166 {
1167 /* We're a top level window, we need to change the UI state */
1168 Msg = WM_UPDATEUISTATE;
1169 }
1170
1171 if (bUnicode)
1172 return SendMessageW(hWnd, Msg, wParam, lParam);
1173 else
1174 return SendMessageA(hWnd, Msg, wParam, lParam);
1175 }
1176
1177 case WM_UPDATEUISTATE:
1178 {
1179 BOOL Change = TRUE;
1180 BOOL AlwaysShowCues = FALSE;
1181 WORD Action = LOWORD(wParam);
1182 WORD Flags = HIWORD(wParam);
1183 PWND Wnd;
1184
1185 SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0);
1186 if (AlwaysShowCues)
1187 break;
1188
1189 Wnd = ValidateHwnd(hWnd);
1190 if (!Wnd || lParam != 0)
1191 break;
1192
1193 if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE))
1194 break;
1195
1196 if (Flags & UISF_ACTIVE)
1197 {
1198 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n");
1199 }
1200
1201 if (Action == UIS_INITIALIZE)
1202 {
1203 PDESKTOPINFO Desk = GetThreadDesktopInfo();
1204 if (Desk == NULL)
1205 break;
1206
1207 Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET;
1208 Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL;
1209
1210 /* We need to update wParam for broadcasting the update */
1211 wParam = MAKEWPARAM(Action, Flags);
1212 }
1213
1214 switch (Action)
1215 {
1216 case UIS_SET:
1217 /* See if we actually need to change something */
1218 if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus)
1219 break;
1220 if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel)
1221 break;
1222
1223 /* Don't need to do anything... */
1224 Change = FALSE;
1225 break;
1226
1227 case UIS_CLEAR:
1228 /* See if we actually need to change something */
1229 if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus)
1230 break;
1231 if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel)
1232 break;
1233
1234 /* Don't need to do anything... */
1235 Change = FALSE;
1236 break;
1237
1238 default:
1239 WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action);
1240 return 0;
1241 }
1242
1243 /* Pack the information and call win32k */
1244 if (Change)
1245 {
1246 if (!NtUserxUpdateUiState(hWnd, Flags | ((DWORD)Action << 3)))
1247 break;
1248 }
1249
1250 /* Always broadcast the update to all children */
1251 EnumChildWindows(hWnd,
1252 UserSendUiUpdateMsg,
1253 (LPARAM)wParam);
1254
1255 break;
1256 }
1257
1258 /* Move to Win32k !*/
1259 case WM_SHOWWINDOW:
1260 if (!lParam) break; // Call when it is necessary.
1261 case WM_SYNCPAINT:
1262 case WM_SETREDRAW:
1263 case WM_CLIENTSHUTDOWN:
1264 case WM_GETHOTKEY:
1265 case WM_SETHOTKEY:
1266 case WM_WINDOWPOSCHANGING:
1267 case WM_WINDOWPOSCHANGED:
1268 case WM_APPCOMMAND:
1269 {
1270 LRESULT lResult;
1271 NtUserMessageCall( hWnd, Msg, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, !bUnicode);
1272 return lResult;
1273 }
1274 }
1275 return 0;
1276 }
1277
1278
1279 /*
1280 * helpers for calling IMM32 (from Wine 10/22/2008)
1281 *
1282 * WM_IME_* messages are generated only by IMM32,
1283 * so I assume imm32 is already LoadLibrary-ed.
1284 */
1285 static HWND
1286 DefWndImmGetDefaultIMEWnd(HWND hwnd)
1287 {
1288 HINSTANCE hInstIMM = GetModuleHandleW(L"imm32\0");
1289 HWND (WINAPI *pFunc)(HWND);
1290 HWND hwndRet = 0;
1291
1292 if (!hInstIMM)
1293 {
1294 ERR("cannot get IMM32 handle\n");
1295 return 0;
1296 }
1297
1298 pFunc = (void*) GetProcAddress(hInstIMM, "ImmGetDefaultIMEWnd");
1299 if (pFunc != NULL)
1300 hwndRet = (*pFunc)(hwnd);
1301
1302 return hwndRet;
1303 }
1304
1305
1306 static BOOL
1307 DefWndImmIsUIMessageA(HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1308 {
1309 HINSTANCE hInstIMM = GetModuleHandleW(L"imm32\0");
1310 BOOL (WINAPI *pFunc)(HWND,UINT,WPARAM,LPARAM);
1311 BOOL fRet = FALSE;
1312
1313 if (!hInstIMM)
1314 {
1315 ERR("cannot get IMM32 handle\n");
1316 return FALSE;
1317 }
1318
1319 pFunc = (void*) GetProcAddress(hInstIMM, "ImmIsUIMessageA");
1320 if (pFunc != NULL)
1321 fRet = (*pFunc)(hwndIME, msg, wParam, lParam);
1322
1323 return fRet;
1324 }
1325
1326
1327 static BOOL
1328 DefWndImmIsUIMessageW(HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1329 {
1330 HINSTANCE hInstIMM = GetModuleHandleW(L"imm32\0");
1331 BOOL (WINAPI *pFunc)(HWND,UINT,WPARAM,LPARAM);
1332 BOOL fRet = FALSE;
1333
1334 if (!hInstIMM)
1335 {
1336 ERR("cannot get IMM32 handle\n");
1337 return FALSE;
1338 }
1339
1340 pFunc = (void*) GetProcAddress(hInstIMM, "ImmIsUIMessageW");
1341 if (pFunc != NULL)
1342 fRet = (*pFunc)(hwndIME, msg, wParam, lParam);
1343
1344 return fRet;
1345 }
1346
1347
1348 LRESULT WINAPI
1349 RealDefWindowProcA(HWND hWnd,
1350 UINT Msg,
1351 WPARAM wParam,
1352 LPARAM lParam)
1353 {
1354 LRESULT Result = 0;
1355 PWND Wnd;
1356
1357 Wnd = ValidateHwnd(hWnd);
1358
1359 if ( !Wnd &&
1360 Msg != WM_CTLCOLORMSGBOX &&
1361 Msg != WM_CTLCOLORBTN &&
1362 Msg != WM_CTLCOLORDLG &&
1363 Msg != WM_CTLCOLORSTATIC )
1364 return 0;
1365
1366 SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam);
1367 switch (Msg)
1368 {
1369 case WM_NCCREATE:
1370 {
1371 if ( Wnd &&
1372 Wnd->style & (WS_HSCROLL | WS_VSCROLL) )
1373 {
1374 if (!Wnd->pSBInfo)
1375 {
1376 SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0};
1377 SetScrollInfo( hWnd, SB_HORZ, &si, FALSE );
1378 SetScrollInfo( hWnd, SB_VERT, &si, FALSE );
1379 }
1380 }
1381
1382 if (lParam)
1383 {
1384 LPCREATESTRUCTA cs = (LPCREATESTRUCTA)lParam;
1385 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1386 * may have child window IDs instead of window name */
1387 if (HIWORD(cs->lpszName))
1388 {
1389 DefSetText(hWnd, (PCWSTR)cs->lpszName, TRUE);
1390 }
1391 Result = 1;
1392 }
1393 break;
1394 }
1395
1396 case WM_GETTEXTLENGTH:
1397 {
1398 PWSTR buf;
1399 ULONG len;
1400
1401 if (Wnd != NULL && Wnd->strName.Length != 0)
1402 {
1403 buf = DesktopPtrToUser(Wnd->strName.Buffer);
1404 if (buf != NULL &&
1405 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len,
1406 buf,
1407 Wnd->strName.Length)))
1408 {
1409 Result = (LRESULT) len;
1410 }
1411 }
1412 else Result = 0L;
1413
1414 break;
1415 }
1416
1417 case WM_GETTEXT:
1418 {
1419 PWSTR buf = NULL;
1420 PSTR outbuf = (PSTR)lParam;
1421 UINT copy;
1422
1423 if (Wnd != NULL && wParam != 0)
1424 {
1425 if (Wnd->strName.Buffer != NULL)
1426 buf = DesktopPtrToUser(Wnd->strName.Buffer);
1427 else
1428 outbuf[0] = L'\0';
1429
1430 if (buf != NULL)
1431 {
1432 if (Wnd->strName.Length != 0)
1433 {
1434 copy = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1);
1435 Result = WideCharToMultiByte(CP_ACP,
1436 0,
1437 buf,
1438 copy,
1439 outbuf,
1440 wParam,
1441 NULL,
1442 NULL);
1443 outbuf[Result] = '\0';
1444 }
1445 else
1446 outbuf[0] = '\0';
1447 }
1448 }
1449 break;
1450 }
1451
1452 case WM_SETTEXT:
1453 {
1454 DefSetText(hWnd, (PCWSTR)lParam, TRUE);
1455
1456 if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1457 {
1458 /* FIXME: this is not 100% correct */
1459 if(gpsi->dwSRVIFlags & SRVINFO_APIHOOK)
1460 {
1461 SendMessage(hWnd, WM_NCUAHDRAWCAPTION,0,0);
1462 }
1463 else
1464 {
1465 DefWndNCPaint(hWnd, HRGN_WINDOW, -1);
1466 }
1467 }
1468 Result = 1;
1469 break;
1470 }
1471
1472 case WM_IME_KEYDOWN:
1473 {
1474 Result = PostMessageA(hWnd, WM_KEYDOWN, wParam, lParam);
1475 break;
1476 }
1477
1478 case WM_IME_KEYUP:
1479 {
1480 Result = PostMessageA(hWnd, WM_KEYUP, wParam, lParam);
1481 break;
1482 }
1483
1484 case WM_IME_CHAR:
1485 {
1486 if (HIBYTE(wParam))
1487 PostMessageA(hWnd, WM_CHAR, HIBYTE(wParam), lParam);
1488 PostMessageA(hWnd, WM_CHAR, LOBYTE(wParam), lParam);
1489 break;
1490 }
1491
1492 case WM_IME_STARTCOMPOSITION:
1493 case WM_IME_COMPOSITION:
1494 case WM_IME_ENDCOMPOSITION:
1495 case WM_IME_SELECT:
1496 case WM_IME_NOTIFY:
1497 {
1498 HWND hwndIME;
1499
1500 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
1501 if (hwndIME)
1502 Result = SendMessageA(hwndIME, Msg, wParam, lParam);
1503 break;
1504 }
1505
1506 case WM_IME_SETCONTEXT:
1507 {
1508 HWND hwndIME;
1509
1510 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
1511 if (hwndIME)
1512 Result = DefWndImmIsUIMessageA(hwndIME, Msg, wParam, lParam);
1513 break;
1514 }
1515
1516 /* fall through */
1517 default:
1518 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, FALSE);
1519 }
1520
1521 SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam);
1522 return Result;
1523 }
1524
1525
1526 LRESULT WINAPI
1527 RealDefWindowProcW(HWND hWnd,
1528 UINT Msg,
1529 WPARAM wParam,
1530 LPARAM lParam)
1531 {
1532 LRESULT Result = 0;
1533 PWND Wnd;
1534
1535 Wnd = ValidateHwnd(hWnd);
1536
1537 if ( !Wnd &&
1538 Msg != WM_CTLCOLORMSGBOX &&
1539 Msg != WM_CTLCOLORBTN &&
1540 Msg != WM_CTLCOLORDLG &&
1541 Msg != WM_CTLCOLORSTATIC )
1542 return 0;
1543
1544 SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam);
1545 switch (Msg)
1546 {
1547 case WM_NCCREATE:
1548 {
1549 if ( Wnd &&
1550 Wnd->style & (WS_HSCROLL | WS_VSCROLL) )
1551 {
1552 if (!Wnd->pSBInfo)
1553 {
1554 SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0};
1555 SetScrollInfo( hWnd, SB_HORZ, &si, FALSE );
1556 SetScrollInfo( hWnd, SB_VERT, &si, FALSE );
1557 }
1558 }
1559
1560 if (lParam)
1561 {
1562 LPCREATESTRUCTW cs = (LPCREATESTRUCTW)lParam;
1563 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1564 * may have child window IDs instead of window name */
1565 if (HIWORD(cs->lpszName))
1566 {
1567 DefSetText(hWnd, cs->lpszName, FALSE);
1568 }
1569 Result = 1;
1570 }
1571 break;
1572 }
1573
1574 case WM_GETTEXTLENGTH:
1575 {
1576 PWSTR buf;
1577 ULONG len;
1578
1579 if (Wnd != NULL && Wnd->strName.Length != 0)
1580 {
1581 buf = DesktopPtrToUser(Wnd->strName.Buffer);
1582 if (buf != NULL &&
1583 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len,
1584 buf,
1585 Wnd->strName.Length)))
1586 {
1587 Result = (LRESULT) (Wnd->strName.Length / sizeof(WCHAR));
1588 }
1589 }
1590 else Result = 0L;
1591
1592 break;
1593 }
1594
1595 case WM_GETTEXT:
1596 {
1597 PWSTR buf = NULL;
1598 PWSTR outbuf = (PWSTR)lParam;
1599
1600 if (Wnd != NULL && wParam != 0)
1601 {
1602 if (Wnd->strName.Buffer != NULL)
1603 buf = DesktopPtrToUser(Wnd->strName.Buffer);
1604 else
1605 outbuf[0] = L'\0';
1606
1607 if (buf != NULL)
1608 {
1609 if (Wnd->strName.Length != 0)
1610 {
1611 Result = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1);
1612 RtlCopyMemory(outbuf,
1613 buf,
1614 Result * sizeof(WCHAR));
1615 outbuf[Result] = L'\0';
1616 }
1617 else
1618 outbuf[0] = L'\0';
1619 }
1620 }
1621 break;
1622 }
1623
1624 case WM_SETTEXT:
1625 {
1626 DefSetText(hWnd, (PCWSTR)lParam, FALSE);
1627
1628 if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1629 {
1630 /* FIXME: this is not 100% correct */
1631 if(gpsi->dwSRVIFlags & SRVINFO_APIHOOK)
1632 {
1633 SendMessage(hWnd, WM_NCUAHDRAWCAPTION,0,0);
1634 }
1635 else
1636 {
1637 DefWndNCPaint(hWnd, HRGN_WINDOW, -1);
1638 }
1639 }
1640 Result = 1;
1641 break;
1642 }
1643
1644 case WM_IME_CHAR:
1645 {
1646 PostMessageW(hWnd, WM_CHAR, wParam, lParam);
1647 Result = 0;
1648 break;
1649 }
1650
1651 case WM_IME_KEYDOWN:
1652 {
1653 Result = PostMessageW(hWnd, WM_KEYDOWN, wParam, lParam);
1654 break;
1655 }
1656
1657 case WM_IME_KEYUP:
1658 {
1659 Result = PostMessageW(hWnd, WM_KEYUP, wParam, lParam);
1660 break;
1661 }
1662
1663 case WM_IME_STARTCOMPOSITION:
1664 case WM_IME_COMPOSITION:
1665 case WM_IME_ENDCOMPOSITION:
1666 case WM_IME_SELECT:
1667 case WM_IME_NOTIFY:
1668 {
1669 HWND hwndIME;
1670
1671 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
1672 if (hwndIME)
1673 Result = SendMessageW(hwndIME, Msg, wParam, lParam);
1674 break;
1675 }
1676
1677 case WM_IME_SETCONTEXT:
1678 {
1679 HWND hwndIME;
1680
1681 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
1682 if (hwndIME)
1683 Result = DefWndImmIsUIMessageW(hwndIME, Msg, wParam, lParam);
1684 break;
1685 }
1686
1687 default:
1688 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, TRUE);
1689 }
1690 SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam);
1691
1692 return Result;
1693 }
1694
1695 LRESULT WINAPI
1696 DefWindowProcA(HWND hWnd,
1697 UINT Msg,
1698 WPARAM wParam,
1699 LPARAM lParam)
1700 {
1701 BOOL Hook, msgOverride = FALSE;
1702 LRESULT Result = 0;
1703
1704 LoadUserApiHook();
1705
1706 Hook = BeginIfHookedUserApiHook();
1707 if (Hook)
1708 {
1709 msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray);
1710 if(msgOverride == FALSE)
1711 {
1712 EndUserApiHook();
1713 }
1714 }
1715
1716 /* Bypass SEH and go direct. */
1717 if (!Hook || !msgOverride)
1718 return RealDefWindowProcA(hWnd, Msg, wParam, lParam);
1719
1720 _SEH2_TRY
1721 {
1722 Result = guah.DefWindowProcA(hWnd, Msg, wParam, lParam);
1723 }
1724 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1725 {
1726 }
1727 _SEH2_END;
1728
1729 EndUserApiHook();
1730
1731 return Result;
1732 }
1733
1734 LRESULT WINAPI
1735 DefWindowProcW(HWND hWnd,
1736 UINT Msg,
1737 WPARAM wParam,
1738 LPARAM lParam)
1739 {
1740 BOOL Hook, msgOverride = FALSE;
1741 LRESULT Result = 0;
1742
1743 LoadUserApiHook();
1744
1745 Hook = BeginIfHookedUserApiHook();
1746 if (Hook)
1747 {
1748 msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray);
1749 if(msgOverride == FALSE)
1750 {
1751 EndUserApiHook();
1752 }
1753 }
1754
1755 /* Bypass SEH and go direct. */
1756 if (!Hook || !msgOverride)
1757 return RealDefWindowProcW(hWnd, Msg, wParam, lParam);
1758
1759 _SEH2_TRY
1760 {
1761 Result = guah.DefWindowProcW(hWnd, Msg, wParam, lParam);
1762 }
1763 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1764 {
1765 }
1766 _SEH2_END;
1767
1768 EndUserApiHook();
1769
1770 return Result;
1771 }