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