- Fix build.
[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 void FASTCALL MenuInitSysMenuPopup(HMENU Menu, DWORD Style, DWORD ClsStyle, LONG HitTest );
26 void MENU_EndMenu( HWND );
27
28 /* GLOBALS *******************************************************************/
29
30 static short iF10Key = 0;
31 static short iMenuSysKey = 0;
32
33 /* FUNCTIONS *****************************************************************/
34
35 /*
36 * @implemented
37 */
38 DWORD WINAPI
39 GetSysColor(int nIndex)
40 {
41 if(nIndex >= 0 && nIndex < NUM_SYSCOLORS)
42 {
43 return gpsi->argbSystem[nIndex];
44 }
45
46 SetLastError(ERROR_INVALID_PARAMETER);
47 return 0;
48 }
49
50 /*
51 * @implemented
52 */
53 HBRUSH WINAPI
54 GetSysColorBrush(int nIndex)
55 {
56 if(nIndex >= 0 && nIndex < NUM_SYSCOLORS)
57 {
58 return gpsi->ahbrSystem[nIndex];
59 }
60
61 SetLastError(ERROR_INVALID_PARAMETER);
62 return NULL;
63 }
64
65 /*
66 * @implemented
67 */
68 BOOL
69 WINAPI
70 SetSysColors(
71 int cElements,
72 CONST INT *lpaElements,
73 CONST COLORREF *lpaRgbValues)
74 {
75 return NtUserSetSysColors(cElements, lpaElements, lpaRgbValues, 0);
76 }
77
78 BOOL
79 FASTCALL
80 DefSetText(HWND hWnd, PCWSTR String, BOOL Ansi)
81 {
82 BOOL Ret;
83 LARGE_STRING lsString;
84
85 if ( String )
86 {
87 if ( Ansi )
88 RtlInitLargeAnsiString((PLARGE_ANSI_STRING)&lsString, (PCSZ)String, 0);
89 else
90 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&lsString, String, 0);
91 }
92 Ret = NtUserDefSetText(hWnd, (String ? &lsString : NULL));
93
94 if (Ret)
95 IntNotifyWinEvent(EVENT_OBJECT_NAMECHANGE, hWnd, OBJID_WINDOW, CHILDID_SELF, 0);
96
97 return Ret;
98 }
99
100 void
101 UserGetInsideRectNC(PWND Wnd, RECT *rect)
102 {
103 ULONG Style;
104 ULONG ExStyle;
105
106 Style = Wnd->style;
107 ExStyle = Wnd->ExStyle;
108
109 rect->top = rect->left = 0;
110 rect->right = Wnd->rcWindow.right - Wnd->rcWindow.left;
111 rect->bottom = Wnd->rcWindow.bottom - Wnd->rcWindow.top;
112
113 if (Style & WS_ICONIC)
114 {
115 return;
116 }
117
118 /* Remove frame from rectangle */
119 if (UserHasThickFrameStyle(Style, ExStyle ))
120 {
121 InflateRect(rect, -GetSystemMetrics(SM_CXFRAME),
122 -GetSystemMetrics(SM_CYFRAME));
123 }
124 else
125 {
126 if (UserHasDlgFrameStyle(Style, ExStyle ))
127 {
128 InflateRect(rect, -GetSystemMetrics(SM_CXDLGFRAME),
129 -GetSystemMetrics(SM_CYDLGFRAME));
130 /* FIXME: this isn't in NC_AdjustRect? why not? */
131 if (ExStyle & WS_EX_DLGMODALFRAME)
132 InflateRect( rect, -1, 0 );
133 }
134 else
135 {
136 if (UserHasThinFrameStyle(Style, ExStyle))
137 {
138 InflateRect(rect, -GetSystemMetrics(SM_CXBORDER),
139 -GetSystemMetrics(SM_CYBORDER));
140 }
141 }
142 }
143 }
144
145
146 VOID
147 DefWndSetRedraw(HWND hWnd, WPARAM wParam)
148 {
149 LONG Style = GetWindowLongPtr(hWnd, GWL_STYLE);
150 /* Content can be redrawn after a change. */
151 if (wParam)
152 {
153 if (!(Style & WS_VISIBLE)) /* Not Visible */
154 {
155 SetWindowLongPtr(hWnd, GWL_STYLE, WS_VISIBLE);
156 }
157 }
158 else /* Content cannot be redrawn after a change. */
159 {
160 if (Style & WS_VISIBLE) /* Visible */
161 {
162 RedrawWindow( hWnd, NULL, 0, RDW_ALLCHILDREN | RDW_VALIDATE );
163 Style &= ~WS_VISIBLE;
164 SetWindowLongPtr(hWnd, GWL_STYLE, Style); /* clear bits */
165 }
166 }
167 return;
168 }
169
170
171 LRESULT
172 DefWndHandleSetCursor(HWND hWnd, WPARAM wParam, LPARAM lParam, ULONG Style)
173 {
174 /* Not for child windows. */
175 if (hWnd != (HWND)wParam)
176 {
177 return(0);
178 }
179
180 switch((INT_PTR) LOWORD(lParam))
181 {
182 case HTERROR:
183 {
184 WORD Msg = HIWORD(lParam);
185 if (Msg == WM_LBUTTONDOWN || Msg == WM_MBUTTONDOWN ||
186 Msg == WM_RBUTTONDOWN || Msg == WM_XBUTTONDOWN)
187 {
188 MessageBeep(0);
189 }
190 break;
191 }
192
193 case HTCLIENT:
194 {
195 HICON hCursor = (HICON)GetClassLongPtrW(hWnd, GCL_HCURSOR);
196 if (hCursor)
197 {
198 SetCursor(hCursor);
199 return(TRUE);
200 }
201 return(FALSE);
202 }
203
204 case HTLEFT:
205 case HTRIGHT:
206 {
207 if (Style & WS_MAXIMIZE)
208 {
209 break;
210 }
211 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZEWE)));
212 }
213
214 case HTTOP:
215 case HTBOTTOM:
216 {
217 if (Style & WS_MAXIMIZE)
218 {
219 break;
220 }
221 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENS)));
222 }
223
224 case HTTOPLEFT:
225 case HTBOTTOMRIGHT:
226 {
227 if (Style & WS_MAXIMIZE)
228 {
229 break;
230 }
231 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENWSE)));
232 }
233
234 case HTBOTTOMLEFT:
235 case HTTOPRIGHT:
236 {
237 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MAXIMIZE)
238 {
239 break;
240 }
241 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENESW)));
242 }
243 }
244 return((LRESULT)SetCursor(LoadCursorW(0, IDC_ARROW)));
245 }
246
247 static LONG
248 DefWndStartSizeMove(HWND hWnd, PWND Wnd, WPARAM wParam, POINT *capturePoint)
249 {
250 LONG hittest = 0;
251 POINT pt;
252 MSG msg;
253 RECT rectWindow;
254 ULONG Style = Wnd->style;
255
256 rectWindow = Wnd->rcWindow;
257
258 if ((wParam & 0xfff0) == SC_MOVE)
259 {
260 /* Move pointer at the center of the caption */
261 RECT rect;
262 UserGetInsideRectNC(Wnd, &rect);
263 if (Style & WS_SYSMENU)
264 rect.left += GetSystemMetrics(SM_CXSIZE) + 1;
265 if (Style & WS_MINIMIZEBOX)
266 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
267 if (Style & WS_MAXIMIZEBOX)
268 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
269 pt.x = rectWindow.left + (rect.right - rect.left) / 2;
270 pt.y = rectWindow.top + rect.top + GetSystemMetrics(SM_CYSIZE)/2;
271 hittest = HTCAPTION;
272 *capturePoint = pt;
273 }
274 else /* SC_SIZE */
275 {
276 pt.x = pt.y = 0;
277 while(!hittest)
278 {
279 if (!GetMessageW(&msg, NULL, 0, 0)) break; //return 0;
280 if (CallMsgFilterW( &msg, MSGF_SIZE )) continue;
281
282 switch(msg.message)
283 {
284 case WM_MOUSEMOVE:
285 hittest = DefWndNCHitTest(hWnd, msg.pt);
286 if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
287 hittest = 0;
288 break;
289
290 case WM_LBUTTONUP:
291 return 0;
292
293 case WM_KEYDOWN:
294 switch(msg.wParam)
295 {
296 case VK_UP:
297 hittest = HTTOP;
298 pt.x =(rectWindow.left+rectWindow.right)/2;
299 pt.y = rectWindow.top + GetSystemMetrics(SM_CYFRAME) / 2;
300 break;
301 case VK_DOWN:
302 hittest = HTBOTTOM;
303 pt.x =(rectWindow.left+rectWindow.right)/2;
304 pt.y = rectWindow.bottom - GetSystemMetrics(SM_CYFRAME) / 2;
305 break;
306 case VK_LEFT:
307 hittest = HTLEFT;
308 pt.x = rectWindow.left + GetSystemMetrics(SM_CXFRAME) / 2;
309 pt.y =(rectWindow.top+rectWindow.bottom)/2;
310 break;
311 case VK_RIGHT:
312 hittest = HTRIGHT;
313 pt.x = rectWindow.right - GetSystemMetrics(SM_CXFRAME) / 2;
314 pt.y =(rectWindow.top+rectWindow.bottom)/2;
315 break;
316 case VK_RETURN:
317 case VK_ESCAPE:
318 return 0;
319 }
320 default:
321 TranslateMessage( &msg );
322 DispatchMessageW( &msg );
323 break;
324 }
325 }
326 *capturePoint = pt;
327 }
328 SetCursorPos( pt.x, pt.y );
329 DefWndHandleSetCursor(hWnd, (WPARAM)hWnd, MAKELONG(hittest, WM_MOUSEMOVE), Style);
330 return hittest;
331 }
332
333 #define ON_LEFT_BORDER(hit) \
334 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
335 #define ON_RIGHT_BORDER(hit) \
336 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
337 #define ON_TOP_BORDER(hit) \
338 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
339 #define ON_BOTTOM_BORDER(hit) \
340 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
341
342 static VOID
343 UserDrawWindowFrame(HDC hdc, const RECT *rect,
344 ULONG width, ULONG height)
345 {
346 static HBRUSH hDraggingRectBrush = NULL;
347 HBRUSH hbrush;
348
349 if(!hDraggingRectBrush)
350 {
351 static HBITMAP hDraggingPattern = NULL;
352 const DWORD Pattern[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA};
353
354 hDraggingPattern = CreateBitmap(8, 8, 1, 1, Pattern);
355 hDraggingRectBrush = CreatePatternBrush(hDraggingPattern);
356 }
357
358 hbrush = SelectObject( hdc, hDraggingRectBrush );
359 PatBlt( hdc, rect->left, rect->top,
360 rect->right - rect->left - width, height, PATINVERT );
361 PatBlt( hdc, rect->left, rect->top + height, width,
362 rect->bottom - rect->top - height, PATINVERT );
363 PatBlt( hdc, rect->left + width, rect->bottom - 1,
364 rect->right - rect->left - width, -height, PATINVERT );
365 PatBlt( hdc, rect->right - 1, rect->top, -width,
366 rect->bottom - rect->top - height, PATINVERT );
367 SelectObject( hdc, hbrush );
368 }
369
370 static VOID
371 UserDrawMovingFrame(HDC hdc, RECT *rect, BOOL thickframe)
372 {
373 if(thickframe)
374 {
375 UserDrawWindowFrame(hdc, rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME));
376 }
377 else
378 {
379 UserDrawWindowFrame(hdc, rect, 1, 1);
380 }
381 }
382
383 static VOID
384 DefWndDoSizeMove(HWND hwnd, WORD wParam)
385 {
386 HRGN DesktopRgn;
387 MSG msg;
388 RECT sizingRect, mouseRect, origRect, clipRect, unmodRect;
389 HDC hdc;
390 LONG hittest = (LONG)(wParam & 0x0f);
391 HCURSOR hDragCursor = 0, hOldCursor = 0;
392 POINT minTrack, maxTrack;
393 POINT capturePoint, pt;
394 ULONG Style, ExStyle;
395 BOOL thickframe;
396 BOOL iconic;
397 BOOL moved = FALSE;
398 DWORD dwPoint = GetMessagePos();
399 BOOL DragFullWindows = FALSE;
400 HWND hWndParent = NULL;
401 PWND Wnd;
402
403 Wnd = ValidateHwnd(hwnd);
404 if (!Wnd)
405 return;
406
407 Style = Wnd->style;
408 ExStyle = Wnd->ExStyle;
409 iconic = (Style & WS_MINIMIZE) != 0;
410
411 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS, 0, &DragFullWindows, 0);
412
413 pt.x = GET_X_LPARAM(dwPoint);
414 pt.y = GET_Y_LPARAM(dwPoint);
415 capturePoint = pt;
416
417 if ((Style & WS_MAXIMIZE) || !IsWindowVisible(hwnd))
418 {
419 return;
420 }
421
422 thickframe = UserHasThickFrameStyle(Style, ExStyle) && !(Style & WS_MINIMIZE);
423 if ((wParam & 0xfff0) == SC_MOVE)
424 {
425 if (!hittest)
426 {
427 hittest = DefWndStartSizeMove(hwnd, Wnd, wParam, &capturePoint);
428 }
429 if (!hittest)
430 {
431 return;
432 }
433 }
434 else /* SC_SIZE */
435 {
436 if (!thickframe)
437 {
438 return;
439 }
440 if (hittest && ((wParam & 0xfff0) != SC_MOUSEMENU))
441 {
442 hittest += (HTLEFT - WMSZ_LEFT);
443 }
444 else
445 {
446 SetCapture(hwnd);
447 hittest = DefWndStartSizeMove(hwnd, Wnd, wParam, &capturePoint);
448 if (!hittest)
449 {
450 ReleaseCapture();
451 return;
452 }
453 }
454 }
455
456 /* Get min/max info */
457
458 WinPosGetMinMaxInfo(hwnd, NULL, NULL, &minTrack, &maxTrack);
459 sizingRect = Wnd->rcWindow;
460 if (Style & WS_CHILD)
461 {
462 hWndParent = GetParent(hwnd);
463 MapWindowPoints( 0, hWndParent, (LPPOINT)&sizingRect, 2 );
464 unmodRect = sizingRect;
465 GetClientRect(hWndParent, &mouseRect );
466 clipRect = mouseRect;
467 MapWindowPoints(hWndParent, HWND_DESKTOP, (LPPOINT)&clipRect, 2);
468 }
469 else
470 {
471 if(!(ExStyle & WS_EX_TOPMOST))
472 {
473 SystemParametersInfoW(SPI_GETWORKAREA, 0, &clipRect, 0);
474 mouseRect = clipRect;
475 }
476 else
477 {
478 SetRect(&mouseRect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
479 clipRect = mouseRect;
480 }
481 unmodRect = sizingRect;
482 }
483 ClipCursor(&clipRect);
484
485 origRect = sizingRect;
486 if (ON_LEFT_BORDER(hittest))
487 {
488 mouseRect.left = max( mouseRect.left, sizingRect.right-maxTrack.x );
489 mouseRect.right = min( mouseRect.right, sizingRect.right-minTrack.x );
490 }
491 else if (ON_RIGHT_BORDER(hittest))
492 {
493 mouseRect.left = max( mouseRect.left, sizingRect.left+minTrack.x );
494 mouseRect.right = min( mouseRect.right, sizingRect.left+maxTrack.x );
495 }
496 if (ON_TOP_BORDER(hittest))
497 {
498 mouseRect.top = max( mouseRect.top, sizingRect.bottom-maxTrack.y );
499 mouseRect.bottom = min( mouseRect.bottom,sizingRect.bottom-minTrack.y);
500 }
501 else if (ON_BOTTOM_BORDER(hittest))
502 {
503 mouseRect.top = max( mouseRect.top, sizingRect.top+minTrack.y );
504 mouseRect.bottom = min( mouseRect.bottom, sizingRect.top+maxTrack.y );
505 }
506 if (Style & WS_CHILD)
507 {
508 MapWindowPoints( hWndParent, 0, (LPPOINT)&mouseRect, 2 );
509 }
510
511 SendMessageA( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
512 NtUserxSetGUIThreadHandle(MSQ_STATE_MOVESIZE, hwnd);
513 if (GetCapture() != hwnd) SetCapture( hwnd );
514
515 if (Style & WS_CHILD)
516 {
517 /* Retrieve a default cache DC (without using the window style) */
518 hdc = GetDCEx(hWndParent, 0, DCX_CACHE);
519 DesktopRgn = NULL;
520 }
521 else
522 {
523 hdc = GetDC( 0 );
524 DesktopRgn = CreateRectRgnIndirect(&clipRect);
525 }
526
527 SelectObject(hdc, DesktopRgn);
528
529 if( iconic ) /* create a cursor for dragging */
530 {
531 HICON hIcon = (HICON)GetClassLongPtrW(hwnd, GCL_HICON);
532 if(!hIcon) hIcon = (HICON)SendMessageW( hwnd, WM_QUERYDRAGICON, 0, 0L);
533 if( hIcon ) hDragCursor = CursorIconToCursor( hIcon, TRUE );
534 if( !hDragCursor ) iconic = FALSE;
535 }
536
537 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
538 if( !iconic && !DragFullWindows)
539 {
540 UserDrawMovingFrame( hdc, &sizingRect, thickframe);
541 }
542
543 for(;;)
544 {
545 int dx = 0, dy = 0;
546
547 if (!GetMessageW(&msg, 0, 0, 0)) break;
548 if (CallMsgFilterW( &msg, MSGF_SIZE )) continue;
549
550 /* Exit on button-up, Return, or Esc */
551 if ((msg.message == WM_LBUTTONUP) ||
552 ((msg.message == WM_KEYDOWN) &&
553 ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
554
555 if (msg.message == WM_PAINT)
556 {
557 if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
558 UpdateWindow( msg.hwnd );
559 if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
560 continue;
561 }
562
563 if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
564 {
565 TranslateMessage( &msg );
566 DispatchMessageW( &msg );
567 continue; /* We are not interested in other messages */
568 }
569
570 pt = msg.pt;
571
572 if (msg.message == WM_KEYDOWN) switch(msg.wParam)
573 {
574 case VK_UP: pt.y -= 8; break;
575 case VK_DOWN: pt.y += 8; break;
576 case VK_LEFT: pt.x -= 8; break;
577 case VK_RIGHT: pt.x += 8; break;
578 }
579
580 pt.x = max( pt.x, mouseRect.left );
581 pt.x = min( pt.x, mouseRect.right );
582 pt.y = max( pt.y, mouseRect.top );
583 pt.y = min( pt.y, mouseRect.bottom );
584
585 dx = pt.x - capturePoint.x;
586 dy = pt.y - capturePoint.y;
587
588 if (dx || dy)
589 {
590 if( !moved )
591 {
592 moved = TRUE;
593
594 if( iconic ) /* ok, no system popup tracking */
595 {
596 hOldCursor = SetCursor(hDragCursor);
597 ShowCursor( TRUE );
598 }
599 }
600
601 if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
602 else
603 {
604 RECT newRect = unmodRect;
605 WPARAM wpSizingHit = 0;
606
607 if (hittest == HTCAPTION) OffsetRect( &newRect, dx, dy );
608 if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
609 else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
610 if (ON_TOP_BORDER(hittest)) newRect.top += dy;
611 else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
612 if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
613 capturePoint = pt;
614
615 /* determine the hit location */
616 if (hittest >= HTLEFT && hittest <= HTBOTTOMRIGHT)
617 wpSizingHit = WMSZ_LEFT + (hittest - HTLEFT);
618 unmodRect = newRect;
619 SendMessageA( hwnd, WM_SIZING, wpSizingHit, (LPARAM)&newRect );
620
621 if (!iconic)
622 {
623 if(!DragFullWindows)
624 UserDrawMovingFrame( hdc, &newRect, thickframe );
625 else {
626 /* To avoid any deadlocks, all the locks on the windows
627 structures must be suspended before the SetWindowPos */
628 SetWindowPos( hwnd, 0, newRect.left, newRect.top,
629 newRect.right - newRect.left,
630 newRect.bottom - newRect.top,
631 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
632 }
633 }
634 sizingRect = newRect;
635 }
636 }
637 }
638
639 ReleaseCapture();
640 ClipCursor(NULL);
641 if( iconic )
642 {
643 if( moved ) /* restore cursors, show icon title later on */
644 {
645 ShowCursor( FALSE );
646 SetCursor( hOldCursor );
647 }
648 DestroyCursor( hDragCursor );
649 }
650 else if(!DragFullWindows)
651 UserDrawMovingFrame( hdc, &sizingRect, thickframe );
652
653 if (Style & WS_CHILD)
654 ReleaseDC( hWndParent, hdc );
655 else
656 {
657 ReleaseDC( 0, hdc );
658 if(DesktopRgn)
659 {
660 DeleteObject(DesktopRgn);
661 }
662 }
663
664 if (ISITHOOKED(WH_CBT))
665 {
666 LRESULT lResult;
667 NtUserMessageCall( hwnd, WM_CBT, HCBT_MOVESIZE, (LPARAM)&sizingRect, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE);
668 if (lResult) moved = FALSE;
669 }
670
671 NtUserxSetGUIThreadHandle(MSQ_STATE_MOVESIZE, NULL);
672 SendMessageA( hwnd, WM_EXITSIZEMOVE, 0, 0 );
673 SendMessageA( hwnd, WM_SETVISIBLE, !IsIconic(hwnd), 0L);
674
675 /* window moved or resized */
676 if (moved)
677 {
678 /* if the moving/resizing isn't canceled call SetWindowPos
679 * with the new position or the new size of the window
680 */
681 if (!((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
682 {
683 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
684 if(!DragFullWindows)
685 SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top,
686 sizingRect.right - sizingRect.left,
687 sizingRect.bottom - sizingRect.top,
688 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
689 }
690 else { /* restore previous size/position */
691 if(DragFullWindows)
692 SetWindowPos( hwnd, 0, origRect.left, origRect.top,
693 origRect.right - origRect.left,
694 origRect.bottom - origRect.top,
695 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
696 }
697 }
698
699 if( IsWindow(hwnd) )
700 if( Style & WS_MINIMIZE )
701 {
702 /* Single click brings up the system menu when iconized */
703
704 if( !moved )
705 {
706 if( Style & WS_SYSMENU )
707 SendMessageA( hwnd, WM_SYSCOMMAND,
708 SC_MOUSEMENU + HTSYSMENU, MAKELONG(pt.x,pt.y));
709 }
710 }
711 }
712
713
714 /***********************************************************************
715 * DefWndTrackScrollBar
716 *
717 * Track a mouse button press on the horizontal or vertical scroll-bar.
718 */
719 static VOID
720 DefWndTrackScrollBar(HWND Wnd, WPARAM wParam, POINT Pt)
721 {
722 INT ScrollBar;
723
724 if (SC_HSCROLL == (wParam & 0xfff0))
725 {
726 if (HTHSCROLL != (wParam & 0x0f))
727 {
728 return;
729 }
730 ScrollBar = SB_HORZ;
731 }
732 else /* SC_VSCROLL */
733 {
734 if (HTVSCROLL != (wParam & 0x0f))
735 {
736 return;
737 }
738 ScrollBar = SB_VERT;
739 }
740 ScrollTrackScrollBar(Wnd, ScrollBar, Pt );
741 }
742
743 LRESULT WINAPI DoAppSwitch( WPARAM wParam, LPARAM lParam);
744
745 LRESULT
746 DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
747 {
748 // WINDOWPLACEMENT wp;
749 POINT Pt;
750 LRESULT lResult;
751
752 if (!IsWindowEnabled( hWnd )) return 0;
753
754 if (ISITHOOKED(WH_CBT))
755 {
756 NtUserMessageCall( hWnd, WM_SYSCOMMAND, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE);
757 if (lResult) return 0;
758 }
759
760 switch (wParam & 0xfff0)
761 {
762 case SC_MOVE:
763 case SC_SIZE:
764 DefWndDoSizeMove(hWnd, wParam);
765 break;
766 case SC_MINIMIZE:
767 if (hWnd == GetActiveWindow())
768 ShowOwnedPopups(hWnd,FALSE);
769 ShowWindow( hWnd, SW_MINIMIZE );
770 break;
771
772 case SC_MAXIMIZE:
773 if (IsIconic(hWnd) && hWnd == GetActiveWindow())
774 ShowOwnedPopups(hWnd,TRUE);
775 ShowWindow( hWnd, SW_MAXIMIZE );
776 break;
777
778 case SC_RESTORE:
779 if (IsIconic(hWnd) && hWnd == GetActiveWindow())
780 ShowOwnedPopups(hWnd,TRUE);
781 ShowWindow( hWnd, SW_RESTORE );
782 break;
783
784 case SC_CLOSE:
785 return SendMessageW(hWnd, WM_CLOSE, 0, 0);
786 // case SC_DEFAULT:
787 case SC_MOUSEMENU:
788 {
789 Pt.x = (short)LOWORD(lParam);
790 Pt.y = (short)HIWORD(lParam);
791 MenuTrackMouseMenuBar(hWnd, wParam & 0x000f, Pt);
792 }
793 break;
794 case SC_KEYMENU:
795 MenuTrackKbdMenuBar(hWnd, wParam, (WCHAR)lParam);
796 break;
797 case SC_VSCROLL:
798 case SC_HSCROLL:
799 {
800 Pt.x = (short)LOWORD(lParam);
801 Pt.y = (short)HIWORD(lParam);
802 DefWndTrackScrollBar(hWnd, wParam, Pt);
803 }
804 break;
805
806 case SC_SCREENSAVE:
807 NtUserMessageCall( hWnd, WM_SYSCOMMAND, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE);
808 break;
809
810 case SC_NEXTWINDOW:
811 case SC_PREVWINDOW:
812 DoAppSwitch( wParam, lParam);
813 break;
814
815 case SC_HOTKEY:
816 {
817 HWND hwnd, hWndLastActive;
818 PWND pWnd;
819
820 hwnd = (HWND)lParam;
821 pWnd = ValidateHwnd(hwnd);
822 if (pWnd)
823 {
824 hWndLastActive = GetLastActivePopup(hwnd);
825 if (hWndLastActive)
826 {
827 hwnd = hWndLastActive;
828 pWnd = ValidateHwnd(hwnd);
829 }
830 SetForegroundWindow(hwnd);
831 if (pWnd->style & WS_MINIMIZE)
832 {
833 PostMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0);
834 }
835 }
836 }
837 break;
838
839 default:
840 FIXME("Unimplemented DefWndHandleSysCommand wParam 0x%x\n",wParam);
841 break;
842 }
843
844 return(0);
845 }
846
847 LRESULT
848 DefWndHandleWindowPosChanging(HWND hWnd, WINDOWPOS* Pos)
849 {
850 POINT maxTrack, minTrack;
851 LONG style = GetWindowLongPtrA(hWnd, GWL_STYLE);
852
853 if (Pos->flags & SWP_NOSIZE) return 0;
854 if ((style & WS_THICKFRAME) || ((style & (WS_POPUP | WS_CHILD)) == 0))
855 {
856 WinPosGetMinMaxInfo(hWnd, NULL, NULL, &minTrack, &maxTrack);
857 Pos->cx = min(Pos->cx, maxTrack.x);
858 Pos->cy = min(Pos->cy, maxTrack.y);
859 if (!(style & WS_MINIMIZE))
860 {
861 if (Pos->cx < minTrack.x) Pos->cx = minTrack.x;
862 if (Pos->cy < minTrack.y) Pos->cy = minTrack.y;
863 }
864 }
865 else
866 {
867 Pos->cx = max(Pos->cx, 0);
868 Pos->cy = max(Pos->cy, 0);
869 }
870 return 0;
871 }
872
873 LRESULT
874 DefWndHandleWindowPosChanged(HWND hWnd, WINDOWPOS* Pos)
875 {
876 RECT Rect;
877
878 GetClientRect(hWnd, &Rect);
879 MapWindowPoints(hWnd, (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD ?
880 GetParent(hWnd) : NULL), (LPPOINT) &Rect, 2);
881
882 if (! (Pos->flags & SWP_NOCLIENTMOVE))
883 {
884 SendMessageW(hWnd, WM_MOVE, 0, MAKELONG(Rect.left, Rect.top));
885 }
886
887 if (! (Pos->flags & SWP_NOCLIENTSIZE))
888 {
889 WPARAM wp = SIZE_RESTORED;
890 if (IsZoomed(hWnd))
891 {
892 wp = SIZE_MAXIMIZED;
893 }
894 else if (IsIconic(hWnd))
895 {
896 wp = SIZE_MINIMIZED;
897 }
898 SendMessageW(hWnd, WM_SIZE, wp,
899 MAKELONG(Rect.right - Rect.left, Rect.bottom - Rect.top));
900 }
901
902 return 0;
903 }
904
905 /***********************************************************************
906 * DefWndControlColor
907 *
908 * Default colors for control painting.
909 */
910 HBRUSH
911 DefWndControlColor(HDC hDC, UINT ctlType)
912 {
913 if (ctlType == CTLCOLOR_SCROLLBAR)
914 {
915 HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR);
916 COLORREF bk = GetSysColor(COLOR_3DHILIGHT);
917 SetTextColor(hDC, GetSysColor(COLOR_3DFACE));
918 SetBkColor(hDC, bk);
919
920 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
921 * we better use 0x55aa bitmap brush to make scrollbar's background
922 * look different from the window background.
923 */
924 if ( bk == GetSysColor(COLOR_WINDOW))
925 return gpsi->hbrGray;
926
927 UnrealizeObject( hb );
928 return hb;
929 }
930
931 SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
932
933 if ((ctlType == CTLCOLOR_EDIT) || (ctlType == CTLCOLOR_LISTBOX))
934 {
935 SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
936 }
937 else
938 {
939 SetBkColor(hDC, GetSysColor(COLOR_3DFACE));
940 return GetSysColorBrush(COLOR_3DFACE);
941 }
942
943 return GetSysColorBrush(COLOR_WINDOW);
944 }
945
946 static void DefWndPrint( HWND hwnd, HDC hdc, ULONG uFlags)
947 {
948 /*
949 * Visibility flag.
950 */
951 if ( (uFlags & PRF_CHECKVISIBLE) &&
952 !IsWindowVisible(hwnd) )
953 return;
954
955 /*
956 * Unimplemented flags.
957 */
958 if ( (uFlags & PRF_CHILDREN) ||
959 (uFlags & PRF_OWNED) ||
960 (uFlags & PRF_NONCLIENT) )
961 {
962 FIXME("WM_PRINT message with unsupported flags\n");
963 }
964
965 /*
966 * Background
967 */
968 if ( uFlags & PRF_ERASEBKGND)
969 SendMessageW(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0);
970
971 /*
972 * Client area
973 */
974 if ( uFlags & PRF_CLIENT)
975 SendMessageW(hwnd, WM_PRINTCLIENT, (WPARAM)hdc, uFlags);
976 }
977
978 static BOOL CALLBACK
979 UserSendUiUpdateMsg(HWND hwnd, LPARAM lParam)
980 {
981 SendMessageW(hwnd, WM_UPDATEUISTATE, (WPARAM)lParam, 0);
982 return TRUE;
983 }
984
985
986 VOID FASTCALL
987 DefWndScreenshot(HWND hWnd)
988 {
989 RECT rect;
990 HDC hdc;
991 INT w;
992 INT h;
993 HBITMAP hbitmap;
994 HDC hdc2;
995
996 OpenClipboard(hWnd);
997 EmptyClipboard();
998
999 hdc = GetWindowDC(hWnd);
1000 GetWindowRect(hWnd, &rect);
1001 w = rect.right - rect.left;
1002 h = rect.bottom - rect.top;
1003
1004 hbitmap = CreateCompatibleBitmap(hdc, w, h);
1005 hdc2 = CreateCompatibleDC(hdc);
1006 SelectObject(hdc2, hbitmap);
1007
1008 BitBlt(hdc2, 0, 0, w, h,
1009 hdc, 0, 0,
1010 SRCCOPY);
1011
1012 SetClipboardData(CF_BITMAP, hbitmap);
1013
1014 ReleaseDC(hWnd, hdc);
1015 ReleaseDC(hWnd, hdc2);
1016
1017 CloseClipboard();
1018
1019 }
1020
1021
1022
1023 LRESULT WINAPI
1024 User32DefWindowProc(HWND hWnd,
1025 UINT Msg,
1026 WPARAM wParam,
1027 LPARAM lParam,
1028 BOOL bUnicode)
1029 {
1030 PWND pWnd = NULL;
1031 if (hWnd)
1032 {
1033 pWnd = ValidateHwnd(hWnd);
1034 if (!pWnd) return 0;
1035 }
1036
1037 switch (Msg)
1038 {
1039 case WM_NCPAINT:
1040 {
1041 return DefWndNCPaint(hWnd, (HRGN)wParam, -1);
1042 }
1043
1044 case WM_NCCALCSIZE:
1045 {
1046 return DefWndNCCalcSize(hWnd, (BOOL)wParam, (RECT*)lParam);
1047 }
1048
1049 case WM_POPUPSYSTEMMENU:
1050 {
1051 /* This is an undocumented message used by the windows taskbar to
1052 display the system menu of windows that belong to other processes. */
1053 HMENU menu = GetSystemMenu(hWnd, FALSE);
1054
1055 if (menu)
1056 TrackPopupMenu(menu, TPM_LEFTBUTTON|TPM_RIGHTBUTTON,
1057 LOWORD(lParam), HIWORD(lParam), 0, hWnd, NULL);
1058 return 0;
1059 }
1060
1061 case WM_NCACTIVATE:
1062 {
1063 return DefWndNCActivate(hWnd, wParam, lParam);
1064 }
1065
1066 case WM_NCHITTEST:
1067 {
1068 POINT Point;
1069 Point.x = GET_X_LPARAM(lParam);
1070 Point.y = GET_Y_LPARAM(lParam);
1071 return (DefWndNCHitTest(hWnd, Point));
1072 }
1073
1074 case WM_LBUTTONDOWN:
1075 case WM_RBUTTONDOWN:
1076 case WM_MBUTTONDOWN:
1077 iF10Key = iMenuSysKey = 0;
1078 break;
1079
1080 case WM_NCLBUTTONDOWN:
1081 {
1082 return (DefWndNCLButtonDown(hWnd, wParam, lParam));
1083 }
1084
1085 case WM_LBUTTONDBLCLK:
1086 return (DefWndNCLButtonDblClk(hWnd, HTCLIENT, lParam));
1087
1088 case WM_NCLBUTTONDBLCLK:
1089 {
1090 return (DefWndNCLButtonDblClk(hWnd, wParam, lParam));
1091 }
1092
1093 case WM_WINDOWPOSCHANGING:
1094 {
1095 return (DefWndHandleWindowPosChanging(hWnd, (WINDOWPOS*)lParam));
1096 }
1097
1098 case WM_WINDOWPOSCHANGED:
1099 {
1100 return (DefWndHandleWindowPosChanged(hWnd, (WINDOWPOS*)lParam));
1101 }
1102
1103 case WM_NCRBUTTONDOWN:
1104 {
1105 /* in Windows, capture is taken when right-clicking on the caption bar */
1106 if (wParam == HTCAPTION)
1107 {
1108 SetCapture(hWnd);
1109 }
1110 break;
1111 }
1112
1113 case WM_RBUTTONUP:
1114 {
1115 POINT Pt;
1116 if (hWnd == GetCapture())
1117 {
1118 ReleaseCapture();
1119 }
1120 Pt.x = GET_X_LPARAM(lParam);
1121 Pt.y = GET_Y_LPARAM(lParam);
1122 ClientToScreen(hWnd, &Pt);
1123 lParam = MAKELPARAM(Pt.x, Pt.y);
1124 if (bUnicode)
1125 {
1126 SendMessageW(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
1127 }
1128 else
1129 {
1130 SendMessageA(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
1131 }
1132 break;
1133 }
1134
1135 case WM_NCRBUTTONUP:
1136 /*
1137 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
1138 * in Windows), but what _should_ we do? According to MSDN :
1139 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
1140 * message to the window". When is it appropriate?
1141 */
1142 break;
1143
1144 case WM_CONTEXTMENU:
1145 {
1146 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD)
1147 {
1148 if (bUnicode)
1149 {
1150 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
1151 }
1152 else
1153 {
1154 SendMessageA(GetParent(hWnd), WM_CONTEXTMENU, wParam, lParam);
1155 }
1156 }
1157 else
1158 {
1159 POINT Pt;
1160 LONG_PTR Style;
1161 LONG HitCode;
1162
1163 Style = GetWindowLongPtrW(hWnd, GWL_STYLE);
1164
1165 Pt.x = GET_X_LPARAM(lParam);
1166 Pt.y = GET_Y_LPARAM(lParam);
1167 if (Style & WS_CHILD)
1168 {
1169 ScreenToClient(GetParent(hWnd), &Pt);
1170 }
1171
1172 HitCode = DefWndNCHitTest(hWnd, Pt);
1173
1174 if (HitCode == HTCAPTION || HitCode == HTSYSMENU)
1175 {
1176 HMENU SystemMenu;
1177 UINT Flags;
1178
1179 if((SystemMenu = GetSystemMenu(hWnd, FALSE)))
1180 {
1181 MenuInitSysMenuPopup(SystemMenu, GetWindowLongPtrW(hWnd, GWL_STYLE),
1182 GetClassLongPtrW(hWnd, GCL_STYLE), HitCode);
1183
1184 if(HitCode == HTCAPTION)
1185 Flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON;
1186 else
1187 Flags = TPM_LEFTBUTTON;
1188
1189 TrackPopupMenu(SystemMenu, Flags,
1190 Pt.x, Pt.y, 0, hWnd, NULL);
1191 }
1192 }
1193 }
1194 break;
1195 }
1196
1197 case WM_PRINT:
1198 {
1199 DefWndPrint(hWnd, (HDC)wParam, lParam);
1200 return (0);
1201 }
1202
1203 case WM_SYSCOLORCHANGE:
1204 {
1205 /* force to redraw non-client area */
1206 DefWndNCPaint(hWnd, HRGN_WINDOW, -1);
1207 /* Use InvalidateRect to redraw client area, enable
1208 * erase to redraw all subcontrols otherwise send the
1209 * WM_SYSCOLORCHANGE to child windows/controls is required
1210 */
1211 InvalidateRect(hWnd,NULL,TRUE);
1212 return (0);
1213 }
1214
1215 case WM_PAINTICON:
1216 case WM_PAINT:
1217 {
1218 PAINTSTRUCT Ps;
1219
1220 /* If already in Paint and Client area is not empty just return. */
1221 if (pWnd->state2 & WNDS2_STARTPAINT && !IsRectEmpty(&pWnd->rcClient))
1222 {
1223 ERR("In Paint and Client area is not empty!\n");
1224 return 0;
1225 }
1226
1227 HDC hDC = BeginPaint(hWnd, &Ps);
1228 if (hDC)
1229 {
1230 HICON hIcon;
1231
1232 if (IsIconic(hWnd) && ((hIcon = (HICON)GetClassLongPtrW( hWnd, GCLP_HICON))))
1233 {
1234 RECT ClientRect;
1235 INT x, y;
1236 GetClientRect(hWnd, &ClientRect);
1237 x = (ClientRect.right - ClientRect.left -
1238 GetSystemMetrics(SM_CXICON)) / 2;
1239 y = (ClientRect.bottom - ClientRect.top -
1240 GetSystemMetrics(SM_CYICON)) / 2;
1241 DrawIcon(hDC, x, y, hIcon);
1242 }
1243 EndPaint(hWnd, &Ps);
1244 }
1245 return (0);
1246 }
1247
1248 case WM_SYNCPAINT:
1249 {
1250 HRGN hRgn;
1251 hRgn = CreateRectRgn(0, 0, 0, 0);
1252 if (GetUpdateRgn(hWnd, hRgn, FALSE) != NULLREGION)
1253 {
1254 RedrawWindow(hWnd, NULL, hRgn,
1255 RDW_ERASENOW | RDW_ERASE | RDW_FRAME |
1256 RDW_ALLCHILDREN);
1257 }
1258 DeleteObject(hRgn);
1259 return (0);
1260 }
1261
1262 case WM_SETREDRAW:
1263 {
1264 LONG_PTR Style = GetWindowLongPtrW(hWnd, GWL_STYLE);
1265 if (wParam) SetWindowLongPtr(hWnd, GWL_STYLE, Style | WS_VISIBLE);
1266 else
1267 {
1268 RedrawWindow(hWnd, NULL, 0, RDW_ALLCHILDREN | RDW_VALIDATE);
1269 Style &= ~WS_VISIBLE;
1270 SetWindowLongPtr(hWnd, GWL_STYLE, Style);
1271 }
1272 return (0);
1273 }
1274
1275 case WM_CLOSE:
1276 {
1277 DestroyWindow(hWnd);
1278 return (0);
1279 }
1280
1281 case WM_MOUSEACTIVATE:
1282 {
1283 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD)
1284 {
1285 LONG Ret;
1286 if (bUnicode)
1287 {
1288 Ret = SendMessageW(GetParent(hWnd), WM_MOUSEACTIVATE,
1289 wParam, lParam);
1290 }
1291 else
1292 {
1293 Ret = SendMessageA(GetParent(hWnd), WM_MOUSEACTIVATE,
1294 wParam, lParam);
1295 }
1296 if (Ret)
1297 {
1298 return (Ret);
1299 }
1300 }
1301 return ((LOWORD(lParam) >= HTCLIENT) ? MA_ACTIVATE : MA_NOACTIVATE);
1302 }
1303
1304 case WM_ACTIVATE:
1305 {
1306 /* Check if the window is minimized. */
1307 if (LOWORD(wParam) != WA_INACTIVE &&
1308 !(GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MINIMIZE))
1309 {
1310 SetFocus(hWnd);
1311 }
1312 break;
1313 }
1314
1315 case WM_MOUSEWHEEL:
1316 {
1317 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD)
1318 {
1319 if (bUnicode)
1320 {
1321 return (SendMessageW(GetParent(hWnd), WM_MOUSEWHEEL,
1322 wParam, lParam));
1323 }
1324 else
1325 {
1326 return (SendMessageA(GetParent(hWnd), WM_MOUSEWHEEL,
1327 wParam, lParam));
1328 }
1329 }
1330 break;
1331 }
1332
1333 case WM_ERASEBKGND:
1334 case WM_ICONERASEBKGND:
1335 {
1336 RECT Rect;
1337 HBRUSH hBrush = (HBRUSH)GetClassLongPtrW(hWnd, GCL_HBRBACKGROUND);
1338
1339 if (NULL == hBrush)
1340 {
1341 return 0;
1342 }
1343 if (GetClassLongPtrW(hWnd, GCL_STYLE) & CS_PARENTDC)
1344 {
1345 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1346 GetClientRect(hWnd, &Rect);
1347 DPtoLP((HDC)wParam, (LPPOINT)&Rect, 2);
1348 }
1349 else
1350 {
1351 GetClipBox((HDC)wParam, &Rect);
1352 }
1353 FillRect((HDC)wParam, &Rect, hBrush);
1354 return (1);
1355 }
1356
1357 case WM_CTLCOLORMSGBOX:
1358 case WM_CTLCOLOREDIT:
1359 case WM_CTLCOLORLISTBOX:
1360 case WM_CTLCOLORBTN:
1361 case WM_CTLCOLORDLG:
1362 case WM_CTLCOLORSTATIC:
1363 case WM_CTLCOLORSCROLLBAR:
1364 return (LRESULT) DefWndControlColor((HDC)wParam, Msg - WM_CTLCOLORMSGBOX);
1365
1366 case WM_CTLCOLOR:
1367 return (LRESULT) DefWndControlColor((HDC)wParam, HIWORD(lParam));
1368
1369 case WM_SETCURSOR:
1370 {
1371 LONG_PTR Style = GetWindowLongPtrW(hWnd, GWL_STYLE);
1372
1373 if (Style & WS_CHILD)
1374 {
1375 /* with the exception of the border around a resizable wnd,
1376 * give the parent first chance to set the cursor */
1377 if (LOWORD(lParam) < HTLEFT || LOWORD(lParam) > HTBOTTOMRIGHT)
1378 {
1379 HWND parent = GetParent( hWnd );
1380 if (bUnicode)
1381 {
1382 if (parent != GetDesktopWindow() &&
1383 SendMessageW( parent, WM_SETCURSOR, wParam, lParam))
1384 return TRUE;
1385 }
1386 else
1387 {
1388 if (parent != GetDesktopWindow() &&
1389 SendMessageA( parent, WM_SETCURSOR, wParam, lParam))
1390 return TRUE;
1391 }
1392 }
1393 }
1394 return (DefWndHandleSetCursor(hWnd, wParam, lParam, Style));
1395 }
1396
1397 case WM_SYSCOMMAND:
1398 return (DefWndHandleSysCommand(hWnd, wParam, lParam));
1399
1400 case WM_KEYDOWN:
1401 if(wParam == VK_F10) iF10Key = VK_F10;
1402 break;
1403
1404 case WM_SYSKEYDOWN:
1405 {
1406 if (HIWORD(lParam) & KF_ALTDOWN)
1407 { /* Previous state, if the key was down before this message,
1408 this is a cheap way to ignore autorepeat keys. */
1409 if ( !(HIWORD(lParam) & KF_REPEAT) )
1410 {
1411 if ( ( wParam == VK_MENU ||
1412 wParam == VK_LMENU ||
1413 wParam == VK_RMENU ) && !iMenuSysKey )
1414 iMenuSysKey = 1;
1415 else
1416 iMenuSysKey = 0;
1417 }
1418
1419 iF10Key = 0;
1420
1421 if (wParam == VK_F4) /* Try to close the window */
1422 {
1423 HWND top = GetAncestor(hWnd, GA_ROOT);
1424 if (!(GetClassLongPtrW(top, GCL_STYLE) & CS_NOCLOSE))
1425 PostMessageW(top, WM_SYSCOMMAND, SC_CLOSE, 0);
1426 }
1427 else if (wParam == VK_SNAPSHOT) // Alt-VK_SNAPSHOT?
1428 {
1429 HWND hwnd = hWnd;
1430 while (GetParent(hwnd) != NULL)
1431 {
1432 hwnd = GetParent(hwnd);
1433 }
1434 DefWndScreenshot(hwnd);
1435 }
1436 else if ( wParam == VK_ESCAPE || wParam == VK_TAB ) // Alt-Tab/ESC Alt-Shift-Tab/ESC
1437 {
1438 WPARAM wParamTmp;
1439 HWND Active = GetActiveWindow(); // Noticed MDI problem.
1440 if (!Active)
1441 {
1442 FIXME("WM_SYSKEYDOWN VK_ESCAPE no active\n");
1443 break;
1444 }
1445 wParamTmp = GetKeyState(VK_SHIFT) & 0x8000 ? SC_PREVWINDOW : SC_NEXTWINDOW;
1446 SendMessageW( Active, WM_SYSCOMMAND, wParamTmp, wParam );
1447 }
1448 }
1449 else if( wParam == VK_F10 )
1450 {
1451 if (GetKeyState(VK_SHIFT) & 0x8000)
1452 SendMessageW( hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, MAKELPARAM(-1, -1) );
1453 iF10Key = 1;
1454 }
1455 break;
1456 }
1457
1458 case WM_KEYUP:
1459 case WM_SYSKEYUP:
1460 {
1461 /* Press and release F10 or ALT */
1462 if (((wParam == VK_MENU || wParam == VK_LMENU || wParam == VK_RMENU)
1463 && iMenuSysKey) || ((wParam == VK_F10) && iF10Key))
1464 SendMessageW( GetAncestor( hWnd, GA_ROOT ), WM_SYSCOMMAND, SC_KEYMENU, 0L );
1465 iMenuSysKey = iF10Key = 0;
1466 break;
1467 }
1468
1469 case WM_SYSCHAR:
1470 {
1471 iMenuSysKey = 0;
1472 if (wParam == VK_RETURN && IsIconic(hWnd))
1473 {
1474 PostMessageW( hWnd, WM_SYSCOMMAND, SC_RESTORE, 0L );
1475 break;
1476 }
1477 if ((HIWORD(lParam) & KF_ALTDOWN) && wParam)
1478 {
1479 if (wParam == VK_TAB || wParam == VK_ESCAPE) break;
1480 if (wParam == VK_SPACE && (GetWindowLongPtrW( hWnd, GWL_STYLE ) & WS_CHILD))
1481 SendMessageW( GetParent(hWnd), Msg, wParam, lParam );
1482 else
1483 SendMessageW( hWnd, WM_SYSCOMMAND, SC_KEYMENU, wParam );
1484 }
1485 else /* check for Ctrl-Esc */
1486 if (wParam != VK_ESCAPE) MessageBeep(0);
1487 break;
1488 }
1489
1490 case WM_CANCELMODE:
1491 {
1492 iMenuSysKey = 0;
1493 /* FIXME: Check for a desktop. */
1494 //if (!(GetWindowLongPtrW( hWnd, GWL_STYLE ) & WS_CHILD)) EndMenu();
1495 MENU_EndMenu( hWnd );
1496 if (GetCapture() == hWnd)
1497 {
1498 ReleaseCapture();
1499 }
1500 break;
1501 }
1502
1503 case WM_VKEYTOITEM:
1504 case WM_CHARTOITEM:
1505 return (-1);
1506 /*
1507 case WM_DROPOBJECT:
1508 return DRAG_FILE;
1509 */
1510 case WM_QUERYDROPOBJECT:
1511 {
1512 if (GetWindowLongPtrW(hWnd, GWL_EXSTYLE) & WS_EX_ACCEPTFILES)
1513 {
1514 return(1);
1515 }
1516 break;
1517 }
1518
1519 case WM_QUERYDRAGICON:
1520 {
1521 UINT Len;
1522 HICON hIcon;
1523
1524 hIcon = (HICON)GetClassLongPtrW(hWnd, GCL_HICON);
1525 if (hIcon)
1526 {
1527 return ((LRESULT)hIcon);
1528 }
1529 for (Len = 1; Len < 64; Len++)
1530 {
1531 if ((hIcon = LoadIconW(NULL, MAKEINTRESOURCEW(Len))) != NULL)
1532 {
1533 return((LRESULT)hIcon);
1534 }
1535 }
1536 return ((LRESULT)LoadIconW(0, IDI_APPLICATION));
1537 }
1538
1539 case WM_ISACTIVEICON:
1540 {
1541 BOOL isai;
1542 isai = (pWnd->state & WNDS_ACTIVEFRAME) != 0;
1543 return isai;
1544 }
1545
1546 case WM_NOTIFYFORMAT:
1547 {
1548 if (lParam == NF_QUERY)
1549 return IsWindowUnicode(hWnd) ? NFR_UNICODE : NFR_ANSI;
1550 break;
1551 }
1552
1553 case WM_SETICON:
1554 {
1555 INT Index = (wParam != 0) ? GCL_HICON : GCL_HICONSM;
1556 HICON hOldIcon = (HICON)GetClassLongPtrW(hWnd, Index);
1557 SetClassLongPtrW(hWnd, Index, lParam);
1558 SetWindowPos(hWnd, 0, 0, 0, 0, 0,
1559 SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
1560 SWP_NOACTIVATE | SWP_NOZORDER);
1561 return ((LRESULT)hOldIcon);
1562 }
1563
1564 case WM_GETICON:
1565 {
1566 INT Index = (wParam == ICON_BIG) ? GCL_HICON : GCL_HICONSM;
1567 return (GetClassLongPtrW(hWnd, Index));
1568 }
1569
1570 case WM_HELP:
1571 {
1572 if (bUnicode)
1573 {
1574 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
1575 }
1576 else
1577 {
1578 SendMessageA(GetParent(hWnd), Msg, wParam, lParam);
1579 }
1580 break;
1581 }
1582
1583 case WM_SYSTIMER:
1584 {
1585 THRDCARETINFO CaretInfo;
1586 switch(wParam)
1587 {
1588 case 0xffff: /* Caret timer */
1589 /* switch showing byte in win32k and get information about the caret */
1590 if(NtUserxSwitchCaretShowing(&CaretInfo) && (CaretInfo.hWnd == hWnd))
1591 {
1592 DrawCaret(hWnd, &CaretInfo);
1593 }
1594 break;
1595 }
1596 break;
1597 }
1598
1599 case WM_QUERYOPEN:
1600 case WM_QUERYENDSESSION:
1601 {
1602 return (1);
1603 }
1604
1605 case WM_INPUTLANGCHANGEREQUEST:
1606 {
1607 HKL NewHkl;
1608
1609 if(wParam & INPUTLANGCHANGE_BACKWARD
1610 && wParam & INPUTLANGCHANGE_FORWARD)
1611 {
1612 return FALSE;
1613 }
1614
1615 //FIXME: What to do with INPUTLANGCHANGE_SYSCHARSET ?
1616
1617 if(wParam & INPUTLANGCHANGE_BACKWARD) NewHkl = (HKL) HKL_PREV;
1618 else if(wParam & INPUTLANGCHANGE_FORWARD) NewHkl = (HKL) HKL_NEXT;
1619 else NewHkl = (HKL) lParam;
1620
1621 NtUserActivateKeyboardLayout(NewHkl, 0);
1622
1623 return TRUE;
1624 }
1625
1626 case WM_INPUTLANGCHANGE:
1627 {
1628 int count = 0;
1629 HWND *win_array = WIN_ListChildren( hWnd );
1630
1631 if (!win_array)
1632 break;
1633 while (win_array[count])
1634 SendMessageW( win_array[count++], WM_INPUTLANGCHANGE, wParam, lParam);
1635 HeapFree(GetProcessHeap(),0,win_array);
1636 break;
1637 }
1638
1639 case WM_QUERYUISTATE:
1640 {
1641 LRESULT Ret = 0;
1642 PWND Wnd = ValidateHwnd(hWnd);
1643 if (Wnd != NULL)
1644 {
1645 if (Wnd->HideFocus)
1646 Ret |= UISF_HIDEFOCUS;
1647 if (Wnd->HideAccel)
1648 Ret |= UISF_HIDEACCEL;
1649 }
1650 return Ret;
1651 }
1652
1653 case WM_CHANGEUISTATE:
1654 {
1655 BOOL AlwaysShowCues = FALSE;
1656 WORD Action = LOWORD(wParam);
1657 WORD Flags = HIWORD(wParam);
1658 PWND Wnd;
1659
1660 SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0);
1661 if (AlwaysShowCues)
1662 break;
1663
1664 Wnd= ValidateHwnd(hWnd);
1665 if (!Wnd || lParam != 0)
1666 break;
1667
1668 if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE))
1669 break;
1670
1671 if (Flags & UISF_ACTIVE)
1672 {
1673 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n");
1674 }
1675
1676 if (Action == UIS_INITIALIZE)
1677 {
1678 PDESKTOPINFO Desk = GetThreadDesktopInfo();
1679 if (Desk == NULL)
1680 break;
1681
1682 Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET;
1683 Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL;
1684
1685 /* We need to update wParam in case we need to send out messages */
1686 wParam = MAKEWPARAM(Action, Flags);
1687 }
1688
1689 switch (Action)
1690 {
1691 case UIS_SET:
1692 /* See if we actually need to change something */
1693 if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus)
1694 break;
1695 if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel)
1696 break;
1697
1698 /* Don't need to do anything... */
1699 return 0;
1700
1701 case UIS_CLEAR:
1702 /* See if we actually need to change something */
1703 if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus)
1704 break;
1705 if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel)
1706 break;
1707
1708 /* Don't need to do anything... */
1709 return 0;
1710
1711 default:
1712 WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action);
1713 break;
1714 }
1715
1716 if ((Wnd->style & WS_CHILD) && Wnd->spwndParent != NULL)
1717 {
1718 /* We're a child window and we need to pass this message down until
1719 we reach the root */
1720 hWnd = UserHMGetHandle((PWND)DesktopPtrToUser(Wnd->spwndParent));
1721 }
1722 else
1723 {
1724 /* We're a top level window, we need to change the UI state */
1725 Msg = WM_UPDATEUISTATE;
1726 }
1727
1728 if (bUnicode)
1729 return SendMessageW(hWnd, Msg, wParam, lParam);
1730 else
1731 return SendMessageA(hWnd, Msg, wParam, lParam);
1732 }
1733
1734 case WM_UPDATEUISTATE:
1735 {
1736 BOOL Change = TRUE;
1737 BOOL AlwaysShowCues = FALSE;
1738 WORD Action = LOWORD(wParam);
1739 WORD Flags = HIWORD(wParam);
1740 PWND Wnd;
1741
1742 SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0);
1743 if (AlwaysShowCues)
1744 break;
1745
1746 Wnd = ValidateHwnd(hWnd);
1747 if (!Wnd || lParam != 0)
1748 break;
1749
1750 if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE))
1751 break;
1752
1753 if (Flags & UISF_ACTIVE)
1754 {
1755 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n");
1756 }
1757
1758 if (Action == UIS_INITIALIZE)
1759 {
1760 PDESKTOPINFO Desk = GetThreadDesktopInfo();
1761 if (Desk == NULL)
1762 break;
1763
1764 Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET;
1765 Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL;
1766
1767 /* We need to update wParam for broadcasting the update */
1768 wParam = MAKEWPARAM(Action, Flags);
1769 }
1770
1771 switch (Action)
1772 {
1773 case UIS_SET:
1774 /* See if we actually need to change something */
1775 if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus)
1776 break;
1777 if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel)
1778 break;
1779
1780 /* Don't need to do anything... */
1781 Change = FALSE;
1782 break;
1783
1784 case UIS_CLEAR:
1785 /* See if we actually need to change something */
1786 if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus)
1787 break;
1788 if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel)
1789 break;
1790
1791 /* Don't need to do anything... */
1792 Change = FALSE;
1793 break;
1794
1795 default:
1796 WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action);
1797 return 0;
1798 }
1799
1800 /* Pack the information and call win32k */
1801 if (Change)
1802 {
1803 if (!NtUserxUpdateUiState(hWnd, Flags | ((DWORD)Action << 3)))
1804 break;
1805 }
1806
1807 /* Always broadcast the update to all children */
1808 EnumChildWindows(hWnd,
1809 UserSendUiUpdateMsg,
1810 (LPARAM)wParam);
1811
1812 break;
1813 }
1814
1815 /* Move to win32k !*/
1816 case WM_SHOWWINDOW:
1817 if (!lParam) break; // Call when it is necessary.
1818 case WM_CLIENTSHUTDOWN:
1819 case WM_GETHOTKEY:
1820 case WM_SETHOTKEY:
1821 {
1822 LRESULT lResult;
1823 NtUserMessageCall( hWnd, Msg, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, !bUnicode);
1824 return lResult;
1825 }
1826 }
1827 return 0;
1828 }
1829
1830
1831 /*
1832 * helpers for calling IMM32 (from Wine 10/22/2008)
1833 *
1834 * WM_IME_* messages are generated only by IMM32,
1835 * so I assume imm32 is already LoadLibrary-ed.
1836 */
1837 static HWND
1838 DefWndImmGetDefaultIMEWnd(HWND hwnd)
1839 {
1840 HINSTANCE hInstIMM = GetModuleHandleW(L"imm32\0");
1841 HWND (WINAPI *pFunc)(HWND);
1842 HWND hwndRet = 0;
1843
1844 if (!hInstIMM)
1845 {
1846 ERR("cannot get IMM32 handle\n");
1847 return 0;
1848 }
1849
1850 pFunc = (void*) GetProcAddress(hInstIMM, "ImmGetDefaultIMEWnd");
1851 if (pFunc != NULL)
1852 hwndRet = (*pFunc)(hwnd);
1853
1854 return hwndRet;
1855 }
1856
1857
1858 static BOOL
1859 DefWndImmIsUIMessageA(HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1860 {
1861 HINSTANCE hInstIMM = GetModuleHandleW(L"imm32\0");
1862 BOOL (WINAPI *pFunc)(HWND,UINT,WPARAM,LPARAM);
1863 BOOL fRet = FALSE;
1864
1865 if (!hInstIMM)
1866 {
1867 ERR("cannot get IMM32 handle\n");
1868 return FALSE;
1869 }
1870
1871 pFunc = (void*) GetProcAddress(hInstIMM, "ImmIsUIMessageA");
1872 if (pFunc != NULL)
1873 fRet = (*pFunc)(hwndIME, msg, wParam, lParam);
1874
1875 return fRet;
1876 }
1877
1878
1879 static BOOL
1880 DefWndImmIsUIMessageW(HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1881 {
1882 HINSTANCE hInstIMM = GetModuleHandleW(L"imm32\0");
1883 BOOL (WINAPI *pFunc)(HWND,UINT,WPARAM,LPARAM);
1884 BOOL fRet = FALSE;
1885
1886 if (!hInstIMM)
1887 {
1888 ERR("cannot get IMM32 handle\n");
1889 return FALSE;
1890 }
1891
1892 pFunc = (void*) GetProcAddress(hInstIMM, "ImmIsUIMessageW");
1893 if (pFunc != NULL)
1894 fRet = (*pFunc)(hwndIME, msg, wParam, lParam);
1895
1896 return fRet;
1897 }
1898
1899
1900 LRESULT WINAPI
1901 RealDefWindowProcA(HWND hWnd,
1902 UINT Msg,
1903 WPARAM wParam,
1904 LPARAM lParam)
1905 {
1906 LRESULT Result = 0;
1907 PWND Wnd;
1908
1909 Wnd = ValidateHwnd(hWnd);
1910
1911 if ( !Wnd &&
1912 Msg != WM_CTLCOLORMSGBOX &&
1913 Msg != WM_CTLCOLORBTN &&
1914 Msg != WM_CTLCOLORDLG &&
1915 Msg != WM_CTLCOLORSTATIC )
1916 return 0;
1917
1918 SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam);
1919 switch (Msg)
1920 {
1921 case WM_NCCREATE:
1922 {
1923 if (lParam)
1924 {
1925 LPCREATESTRUCTA cs = (LPCREATESTRUCTA)lParam;
1926 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1927 * may have child window IDs instead of window name */
1928 if (HIWORD(cs->lpszName))
1929 {
1930 DefSetText(hWnd, (PCWSTR)cs->lpszName, TRUE);
1931 }
1932 Result = 1;
1933 }
1934 break;
1935 }
1936
1937 case WM_GETTEXTLENGTH:
1938 {
1939 PWSTR buf;
1940 ULONG len;
1941
1942 if (Wnd != NULL && Wnd->strName.Length != 0)
1943 {
1944 buf = DesktopPtrToUser(Wnd->strName.Buffer);
1945 if (buf != NULL &&
1946 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len,
1947 buf,
1948 Wnd->strName.Length)))
1949 {
1950 Result = (LRESULT) len;
1951 }
1952 }
1953 else Result = 0L;
1954
1955 break;
1956 }
1957
1958 case WM_GETTEXT:
1959 {
1960 PWSTR buf = NULL;
1961 PSTR outbuf = (PSTR)lParam;
1962 UINT copy;
1963
1964 if (Wnd != NULL && wParam != 0)
1965 {
1966 if (Wnd->strName.Buffer != NULL)
1967 buf = DesktopPtrToUser(Wnd->strName.Buffer);
1968 else
1969 outbuf[0] = L'\0';
1970
1971 if (buf != NULL)
1972 {
1973 if (Wnd->strName.Length != 0)
1974 {
1975 copy = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1);
1976 Result = WideCharToMultiByte(CP_ACP,
1977 0,
1978 buf,
1979 copy,
1980 outbuf,
1981 wParam,
1982 NULL,
1983 NULL);
1984 outbuf[Result] = '\0';
1985 }
1986 else
1987 outbuf[0] = '\0';
1988 }
1989 }
1990 break;
1991 }
1992
1993 case WM_SETTEXT:
1994 {
1995 DefSetText(hWnd, (PCWSTR)lParam, TRUE);
1996
1997 if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1998 {
1999 /* FIXME: this is not 100% correct */
2000 if(gpsi->dwSRVIFlags & SRVINFO_APIHOOK)
2001 {
2002 SendMessage(hWnd, WM_NCUAHDRAWCAPTION,0,0);
2003 }
2004 else
2005 {
2006 DefWndNCPaint(hWnd, HRGN_WINDOW, -1);
2007 }
2008 }
2009 Result = 1;
2010 break;
2011 }
2012
2013 case WM_IME_KEYDOWN:
2014 {
2015 Result = PostMessageA(hWnd, WM_KEYDOWN, wParam, lParam);
2016 break;
2017 }
2018
2019 case WM_IME_KEYUP:
2020 {
2021 Result = PostMessageA(hWnd, WM_KEYUP, wParam, lParam);
2022 break;
2023 }
2024
2025 case WM_IME_CHAR:
2026 {
2027 if (HIBYTE(wParam))
2028 PostMessageA(hWnd, WM_CHAR, HIBYTE(wParam), lParam);
2029 PostMessageA(hWnd, WM_CHAR, LOBYTE(wParam), lParam);
2030 break;
2031 }
2032
2033 case WM_IME_STARTCOMPOSITION:
2034 case WM_IME_COMPOSITION:
2035 case WM_IME_ENDCOMPOSITION:
2036 case WM_IME_SELECT:
2037 case WM_IME_NOTIFY:
2038 {
2039 HWND hwndIME;
2040
2041 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
2042 if (hwndIME)
2043 Result = SendMessageA(hwndIME, Msg, wParam, lParam);
2044 break;
2045 }
2046
2047 case WM_IME_SETCONTEXT:
2048 {
2049 HWND hwndIME;
2050
2051 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
2052 if (hwndIME)
2053 Result = DefWndImmIsUIMessageA(hwndIME, Msg, wParam, lParam);
2054 break;
2055 }
2056
2057 /* fall through */
2058 default:
2059 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, FALSE);
2060 }
2061
2062 SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam);
2063 return Result;
2064 }
2065
2066
2067 LRESULT WINAPI
2068 RealDefWindowProcW(HWND hWnd,
2069 UINT Msg,
2070 WPARAM wParam,
2071 LPARAM lParam)
2072 {
2073 LRESULT Result = 0;
2074 PWND Wnd;
2075
2076 Wnd = ValidateHwnd(hWnd);
2077
2078 if ( !Wnd &&
2079 Msg != WM_CTLCOLORMSGBOX &&
2080 Msg != WM_CTLCOLORBTN &&
2081 Msg != WM_CTLCOLORDLG &&
2082 Msg != WM_CTLCOLORSTATIC )
2083 return 0;
2084
2085 SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam);
2086 switch (Msg)
2087 {
2088 case WM_NCCREATE:
2089 {
2090 if (lParam)
2091 {
2092 LPCREATESTRUCTW cs = (LPCREATESTRUCTW)lParam;
2093 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
2094 * may have child window IDs instead of window name */
2095 if (HIWORD(cs->lpszName))
2096 {
2097 DefSetText(hWnd, cs->lpszName, FALSE);
2098 }
2099 Result = 1;
2100 }
2101 break;
2102 }
2103
2104 case WM_GETTEXTLENGTH:
2105 {
2106 PWSTR buf;
2107 ULONG len;
2108
2109 if (Wnd != NULL && Wnd->strName.Length != 0)
2110 {
2111 buf = DesktopPtrToUser(Wnd->strName.Buffer);
2112 if (buf != NULL &&
2113 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len,
2114 buf,
2115 Wnd->strName.Length)))
2116 {
2117 Result = (LRESULT) (Wnd->strName.Length / sizeof(WCHAR));
2118 }
2119 }
2120 else Result = 0L;
2121
2122 break;
2123 }
2124
2125 case WM_GETTEXT:
2126 {
2127 PWSTR buf = NULL;
2128 PWSTR outbuf = (PWSTR)lParam;
2129
2130 if (Wnd != NULL && wParam != 0)
2131 {
2132 if (Wnd->strName.Buffer != NULL)
2133 buf = DesktopPtrToUser(Wnd->strName.Buffer);
2134 else
2135 outbuf[0] = L'\0';
2136
2137 if (buf != NULL)
2138 {
2139 if (Wnd->strName.Length != 0)
2140 {
2141 Result = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1);
2142 RtlCopyMemory(outbuf,
2143 buf,
2144 Result * sizeof(WCHAR));
2145 outbuf[Result] = L'\0';
2146 }
2147 else
2148 outbuf[0] = L'\0';
2149 }
2150 }
2151 break;
2152 }
2153
2154 case WM_SETTEXT:
2155 {
2156 DefSetText(hWnd, (PCWSTR)lParam, FALSE);
2157
2158 if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
2159 {
2160 /* FIXME: this is not 100% correct */
2161 if(gpsi->dwSRVIFlags & SRVINFO_APIHOOK)
2162 {
2163 SendMessage(hWnd, WM_NCUAHDRAWCAPTION,0,0);
2164 }
2165 else
2166 {
2167 DefWndNCPaint(hWnd, HRGN_WINDOW, -1);
2168 }
2169 }
2170 Result = 1;
2171 break;
2172 }
2173
2174 case WM_IME_CHAR:
2175 {
2176 PostMessageW(hWnd, WM_CHAR, wParam, lParam);
2177 Result = 0;
2178 break;
2179 }
2180
2181 case WM_IME_KEYDOWN:
2182 {
2183 Result = PostMessageW(hWnd, WM_KEYDOWN, wParam, lParam);
2184 break;
2185 }
2186
2187 case WM_IME_KEYUP:
2188 {
2189 Result = PostMessageW(hWnd, WM_KEYUP, wParam, lParam);
2190 break;
2191 }
2192
2193 case WM_IME_STARTCOMPOSITION:
2194 case WM_IME_COMPOSITION:
2195 case WM_IME_ENDCOMPOSITION:
2196 case WM_IME_SELECT:
2197 case WM_IME_NOTIFY:
2198 {
2199 HWND hwndIME;
2200
2201 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
2202 if (hwndIME)
2203 Result = SendMessageW(hwndIME, Msg, wParam, lParam);
2204 break;
2205 }
2206
2207 case WM_IME_SETCONTEXT:
2208 {
2209 HWND hwndIME;
2210
2211 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
2212 if (hwndIME)
2213 Result = DefWndImmIsUIMessageW(hwndIME, Msg, wParam, lParam);
2214 break;
2215 }
2216
2217 default:
2218 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, TRUE);
2219 }
2220 SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam);
2221
2222 return Result;
2223 }
2224
2225 LRESULT WINAPI
2226 DefWindowProcA(HWND hWnd,
2227 UINT Msg,
2228 WPARAM wParam,
2229 LPARAM lParam)
2230 {
2231 BOOL Hook, msgOverride = FALSE;
2232 LRESULT Result = 0;
2233
2234 LoadUserApiHook();
2235
2236 Hook = BeginIfHookedUserApiHook();
2237 if (Hook)
2238 {
2239 msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray);
2240 if(msgOverride == FALSE)
2241 {
2242 EndUserApiHook();
2243 }
2244 }
2245
2246 /* Bypass SEH and go direct. */
2247 if (!Hook || !msgOverride)
2248 return RealDefWindowProcA(hWnd, Msg, wParam, lParam);
2249
2250 _SEH2_TRY
2251 {
2252 Result = guah.DefWindowProcA(hWnd, Msg, wParam, lParam);
2253 }
2254 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2255 {
2256 }
2257 _SEH2_END;
2258
2259 EndUserApiHook();
2260
2261 return Result;
2262 }
2263
2264 LRESULT WINAPI
2265 DefWindowProcW(HWND hWnd,
2266 UINT Msg,
2267 WPARAM wParam,
2268 LPARAM lParam)
2269 {
2270 BOOL Hook, msgOverride = FALSE;
2271 LRESULT Result = 0;
2272
2273 LoadUserApiHook();
2274
2275 Hook = BeginIfHookedUserApiHook();
2276 if (Hook)
2277 {
2278 msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray);
2279 if(msgOverride == FALSE)
2280 {
2281 EndUserApiHook();
2282 }
2283 }
2284
2285 /* Bypass SEH and go direct. */
2286 if (!Hook || !msgOverride)
2287 return RealDefWindowProcW(hWnd, Msg, wParam, lParam);
2288
2289 _SEH2_TRY
2290 {
2291 Result = guah.DefWindowProcW(hWnd, Msg, wParam, lParam);
2292 }
2293 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2294 {
2295 }
2296 _SEH2_END;
2297
2298 EndUserApiHook();
2299
2300 return Result;
2301 }