- Create another branch for networking fixes
[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: lib/user32/windows/window.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 #ifndef WM_SETVISIBLE
20 #define WM_SETVISIBLE 9
21 #endif
22 #ifndef WM_QUERYDROPOBJECT
23 #define WM_QUERYDROPOBJECT 0x022B
24 #endif
25
26 LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active);
27 LRESULT DefWndNCCalcSize(HWND hWnd, BOOL CalcSizeStruct, RECT *Rect);
28 LRESULT DefWndNCActivate(HWND hWnd, WPARAM wParam);
29 LRESULT DefWndNCHitTest(HWND hWnd, POINT Point);
30 LRESULT DefWndNCLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam);
31 LRESULT DefWndNCLButtonDblClk(HWND hWnd, WPARAM wParam, LPARAM lParam);
32 void FASTCALL MenuInitSysMenuPopup(HMENU Menu, DWORD Style, DWORD ClsStyle, LONG HitTest );
33
34 /* GLOBALS *******************************************************************/
35
36 /* Bits in the dwKeyData */
37 #define KEYDATA_ALT 0x2000
38 #define KEYDATA_PREVSTATE 0x4000
39
40 static short iF10Key = 0;
41 static short iMenuSysKey = 0;
42
43 /* FUNCTIONS *****************************************************************/
44
45 void
46 InitStockObjects(void)
47 {
48 /* FIXME - Instead of copying the stuff to usermode we should map the tables to
49 userland. The current implementation has one big flaw: the system color
50 table doesn't get updated when another process changes them. That's why
51 we should rather map the table into usermode. But it only affects the
52 SysColors table - the pens, brushes and stock objects are not affected
53 as their handles never change. But it'd be faster to map them, too. */
54
55 // Done! gpsi!
56 }
57
58 /*
59 * @implemented
60 */
61 DWORD WINAPI
62 GetSysColor(int nIndex)
63 {
64 if(nIndex >= 0 && nIndex < NUM_SYSCOLORS)
65 {
66 return gpsi->argbSystem[nIndex];
67 }
68
69 SetLastError(ERROR_INVALID_PARAMETER);
70 return 0;
71 }
72
73 /*
74 * @implemented
75 */
76 HBRUSH WINAPI
77 GetSysColorBrush(int nIndex)
78 {
79 if(nIndex >= 0 && nIndex < NUM_SYSCOLORS)
80 {
81 return gpsi->ahbrSystem[nIndex];
82 }
83
84 SetLastError(ERROR_INVALID_PARAMETER);
85 return NULL;
86 }
87
88 /*
89 * @implemented
90 */
91 BOOL
92 WINAPI
93 SetSysColors(
94 int cElements,
95 CONST INT *lpaElements,
96 CONST COLORREF *lpaRgbValues)
97 {
98 return NtUserSetSysColors(cElements, lpaElements, lpaRgbValues, 0);
99 }
100
101 BOOL
102 FASTCALL
103 DefSetText(HWND hWnd, PCWSTR String, BOOL Ansi)
104 {
105 LARGE_STRING lsString;
106
107 if ( String )
108 {
109 if ( Ansi )
110 RtlInitLargeAnsiString((PLARGE_ANSI_STRING)&lsString, (PCSZ)String, 0);
111 else
112 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&lsString, String, 0);
113 }
114 return NtUserDefSetText(hWnd, (String ? &lsString : NULL));
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
757 if (!IsWindowEnabled( hWnd )) return 0;
758
759 if (ISITHOOKED(WH_CBT))
760 {
761 LRESULT lResult;
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
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 default:
819 /* FIXME: Implement */
820 UNIMPLEMENTED;
821 break;
822 }
823
824 return(0);
825 }
826
827 LRESULT
828 DefWndHandleWindowPosChanging(HWND hWnd, WINDOWPOS* Pos)
829 {
830 POINT maxTrack, minTrack;
831 LONG style = GetWindowLongPtrA(hWnd, GWL_STYLE);
832
833 if (Pos->flags & SWP_NOSIZE) return 0;
834 if ((style & WS_THICKFRAME) || ((style & (WS_POPUP | WS_CHILD)) == 0))
835 {
836 WinPosGetMinMaxInfo(hWnd, NULL, NULL, &minTrack, &maxTrack);
837 Pos->cx = min(Pos->cx, maxTrack.x);
838 Pos->cy = min(Pos->cy, maxTrack.y);
839 if (!(style & WS_MINIMIZE))
840 {
841 if (Pos->cx < minTrack.x) Pos->cx = minTrack.x;
842 if (Pos->cy < minTrack.y) Pos->cy = minTrack.y;
843 }
844 }
845 else
846 {
847 Pos->cx = max(Pos->cx, 0);
848 Pos->cy = max(Pos->cy, 0);
849 }
850 return 0;
851 }
852
853 /* Undocumented flags. */
854 #define SWP_NOCLIENTMOVE 0x0800
855 #define SWP_NOCLIENTSIZE 0x1000
856
857 LRESULT
858 DefWndHandleWindowPosChanged(HWND hWnd, WINDOWPOS* Pos)
859 {
860 RECT Rect;
861
862 GetClientRect(hWnd, &Rect);
863 MapWindowPoints(hWnd, (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD ?
864 GetParent(hWnd) : NULL), (LPPOINT) &Rect, 2);
865
866 if (! (Pos->flags & SWP_NOCLIENTMOVE))
867 {
868 SendMessageW(hWnd, WM_MOVE, 0, MAKELONG(Rect.left, Rect.top));
869 }
870
871 if (! (Pos->flags & SWP_NOCLIENTSIZE))
872 {
873 WPARAM wp = SIZE_RESTORED;
874 if (IsZoomed(hWnd))
875 {
876 wp = SIZE_MAXIMIZED;
877 }
878 else if (IsIconic(hWnd))
879 {
880 wp = SIZE_MINIMIZED;
881 }
882 SendMessageW(hWnd, WM_SIZE, wp,
883 MAKELONG(Rect.right - Rect.left, Rect.bottom - Rect.top));
884 }
885
886 return 0;
887 }
888
889 /***********************************************************************
890 * DefWndControlColor
891 *
892 * Default colors for control painting.
893 */
894 HBRUSH
895 DefWndControlColor(HDC hDC, UINT ctlType)
896 {
897 if (CTLCOLOR_SCROLLBAR == ctlType)
898 {
899 HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR);
900 COLORREF bk = GetSysColor(COLOR_3DHILIGHT);
901 SetTextColor(hDC, GetSysColor(COLOR_3DFACE));
902 SetBkColor(hDC, bk);
903
904 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
905 * we better use 0x55aa bitmap brush to make scrollbar's background
906 * look different from the window background.
907 */
908 if (bk == GetSysColor(COLOR_WINDOW))
909 {
910 static const WORD wPattern55AA[] =
911 {
912 0x5555, 0xaaaa, 0x5555, 0xaaaa,
913 0x5555, 0xaaaa, 0x5555, 0xaaaa
914 };
915 static HBITMAP hPattern55AABitmap = NULL;
916 static HBRUSH hPattern55AABrush = NULL;
917 if (hPattern55AABrush == NULL)
918 {
919 hPattern55AABitmap = CreateBitmap(8, 8, 1, 1, wPattern55AA);
920 hPattern55AABrush = CreatePatternBrush(hPattern55AABitmap);
921 }
922 return hPattern55AABrush;
923 }
924 UnrealizeObject(hb);
925 return hb;
926 }
927
928 SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
929
930 if ((CTLCOLOR_EDIT == ctlType) || (CTLCOLOR_LISTBOX == ctlType))
931 {
932 SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
933 }
934 else
935 {
936 SetBkColor(hDC, GetSysColor(COLOR_3DFACE));
937 return GetSysColorBrush(COLOR_3DFACE);
938 }
939
940 return GetSysColorBrush(COLOR_WINDOW);
941 }
942
943 static void DefWndPrint( HWND hwnd, HDC hdc, ULONG uFlags)
944 {
945 /*
946 * Visibility flag.
947 */
948 if ( (uFlags & PRF_CHECKVISIBLE) &&
949 !IsWindowVisible(hwnd) )
950 return;
951
952 /*
953 * Unimplemented flags.
954 */
955 if ( (uFlags & PRF_CHILDREN) ||
956 (uFlags & PRF_OWNED) ||
957 (uFlags & PRF_NONCLIENT) )
958 {
959 FIXME("WM_PRINT message with unsupported flags\n");
960 }
961
962 /*
963 * Background
964 */
965 if ( uFlags & PRF_ERASEBKGND)
966 SendMessageW(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0);
967
968 /*
969 * Client area
970 */
971 if ( uFlags & PRF_CLIENT)
972 SendMessageW(hwnd, WM_PRINTCLIENT, (WPARAM)hdc, uFlags);
973 }
974
975 static BOOL CALLBACK
976 UserSendUiUpdateMsg(HWND hwnd, LPARAM lParam)
977 {
978 SendMessageW(hwnd, WM_UPDATEUISTATE, (WPARAM)lParam, 0);
979 return TRUE;
980 }
981
982
983 VOID FASTCALL
984 DefWndScreenshot(HWND hWnd)
985 {
986 RECT rect;
987 HDC hdc;
988 INT w;
989 INT h;
990 HBITMAP hbitmap;
991 HDC hdc2;
992
993 OpenClipboard(hWnd);
994 EmptyClipboard();
995
996 hdc = GetWindowDC(hWnd);
997 GetWindowRect(hWnd, &rect);
998 w = rect.right - rect.left;
999 h = rect.bottom - rect.top;
1000
1001 hbitmap = CreateCompatibleBitmap(hdc, w, h);
1002 hdc2 = CreateCompatibleDC(hdc);
1003 SelectObject(hdc2, hbitmap);
1004
1005 BitBlt(hdc2, 0, 0, w, h,
1006 hdc, 0, 0,
1007 SRCCOPY);
1008
1009 SetClipboardData(CF_BITMAP, hbitmap);
1010
1011 ReleaseDC(hWnd, hdc);
1012 ReleaseDC(hWnd, hdc2);
1013
1014 CloseClipboard();
1015
1016 }
1017
1018
1019
1020 LRESULT WINAPI
1021 User32DefWindowProc(HWND hWnd,
1022 UINT Msg,
1023 WPARAM wParam,
1024 LPARAM lParam,
1025 BOOL bUnicode)
1026 {
1027 switch (Msg)
1028 {
1029 case WM_NCPAINT:
1030 {
1031 return DefWndNCPaint(hWnd, (HRGN)wParam, -1);
1032 }
1033
1034 case WM_NCCALCSIZE:
1035 {
1036 return DefWndNCCalcSize(hWnd, (BOOL)wParam, (RECT*)lParam);
1037 }
1038
1039 case WM_POPUPSYSTEMMENU:
1040 {
1041 /* This is an undocumented message used by the windows taskbar to
1042 display the system menu of windows that belong to other processes. */
1043 HMENU menu = GetSystemMenu(hWnd, FALSE);
1044
1045 if (menu)
1046 TrackPopupMenu(menu, TPM_LEFTBUTTON|TPM_RIGHTBUTTON,
1047 LOWORD(lParam), HIWORD(lParam), 0, hWnd, NULL);
1048 return 0;
1049 }
1050
1051 case WM_NCACTIVATE:
1052 {
1053 return DefWndNCActivate(hWnd, wParam);
1054 }
1055
1056 case WM_NCHITTEST:
1057 {
1058 POINT Point;
1059 Point.x = GET_X_LPARAM(lParam);
1060 Point.y = GET_Y_LPARAM(lParam);
1061 return (DefWndNCHitTest(hWnd, Point));
1062 }
1063
1064 case WM_LBUTTONDOWN:
1065 case WM_RBUTTONDOWN:
1066 case WM_MBUTTONDOWN:
1067 iF10Key = iMenuSysKey = 0;
1068 break;
1069
1070 case WM_NCLBUTTONDOWN:
1071 {
1072 return (DefWndNCLButtonDown(hWnd, wParam, lParam));
1073 }
1074
1075 case WM_LBUTTONDBLCLK:
1076 return (DefWndNCLButtonDblClk(hWnd, HTCLIENT, lParam));
1077
1078 case WM_NCLBUTTONDBLCLK:
1079 {
1080 return (DefWndNCLButtonDblClk(hWnd, wParam, lParam));
1081 }
1082
1083 case WM_WINDOWPOSCHANGING:
1084 {
1085 return (DefWndHandleWindowPosChanging(hWnd, (WINDOWPOS*)lParam));
1086 }
1087
1088 case WM_WINDOWPOSCHANGED:
1089 {
1090 return (DefWndHandleWindowPosChanged(hWnd, (WINDOWPOS*)lParam));
1091 }
1092
1093 case WM_NCRBUTTONDOWN:
1094 {
1095 /* in Windows, capture is taken when right-clicking on the caption bar */
1096 if (wParam == HTCAPTION)
1097 {
1098 SetCapture(hWnd);
1099 }
1100 break;
1101 }
1102
1103 case WM_RBUTTONUP:
1104 {
1105 POINT Pt;
1106 if (hWnd == GetCapture())
1107 {
1108 ReleaseCapture();
1109 }
1110 Pt.x = GET_X_LPARAM(lParam);
1111 Pt.y = GET_Y_LPARAM(lParam);
1112 ClientToScreen(hWnd, &Pt);
1113 lParam = MAKELPARAM(Pt.x, Pt.y);
1114 if (bUnicode)
1115 {
1116 SendMessageW(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
1117 }
1118 else
1119 {
1120 SendMessageA(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
1121 }
1122 break;
1123 }
1124
1125 case WM_NCRBUTTONUP:
1126 /*
1127 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
1128 * in Windows), but what _should_ we do? According to MSDN :
1129 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
1130 * message to the window". When is it appropriate?
1131 */
1132 break;
1133
1134 case WM_CONTEXTMENU:
1135 {
1136 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD)
1137 {
1138 if (bUnicode)
1139 {
1140 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
1141 }
1142 else
1143 {
1144 SendMessageA(GetParent(hWnd), WM_CONTEXTMENU, wParam, lParam);
1145 }
1146 }
1147 else
1148 {
1149 POINT Pt;
1150 LONG_PTR Style;
1151 LONG HitCode;
1152
1153 Style = GetWindowLongPtrW(hWnd, GWL_STYLE);
1154
1155 Pt.x = GET_X_LPARAM(lParam);
1156 Pt.y = GET_Y_LPARAM(lParam);
1157 if (Style & WS_CHILD)
1158 {
1159 ScreenToClient(GetParent(hWnd), &Pt);
1160 }
1161
1162 HitCode = DefWndNCHitTest(hWnd, Pt);
1163
1164 if (HitCode == HTCAPTION || HitCode == HTSYSMENU)
1165 {
1166 HMENU SystemMenu;
1167 UINT Flags;
1168
1169 if((SystemMenu = GetSystemMenu(hWnd, FALSE)))
1170 {
1171 MenuInitSysMenuPopup(SystemMenu, GetWindowLongPtrW(hWnd, GWL_STYLE),
1172 GetClassLongPtrW(hWnd, GCL_STYLE), HitCode);
1173
1174 if(HitCode == HTCAPTION)
1175 Flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON;
1176 else
1177 Flags = TPM_LEFTBUTTON;
1178
1179 TrackPopupMenu(SystemMenu, Flags,
1180 Pt.x, Pt.y, 0, hWnd, NULL);
1181 }
1182 }
1183 }
1184 break;
1185 }
1186
1187 case WM_PRINT:
1188 {
1189 DefWndPrint(hWnd, (HDC)wParam, lParam);
1190 return (0);
1191 }
1192
1193 case WM_SYSCOLORCHANGE:
1194 {
1195 /* force to redraw non-client area */
1196 DefWndNCPaint(hWnd, (HRGN)1, -1);
1197 /* Use InvalidateRect to redraw client area, enable
1198 * erase to redraw all subcontrols otherwise send the
1199 * WM_SYSCOLORCHANGE to child windows/controls is required
1200 */
1201 InvalidateRect(hWnd,NULL,TRUE);
1202 return (0);
1203 }
1204
1205 case WM_PAINTICON:
1206 case WM_PAINT:
1207 {
1208 PAINTSTRUCT Ps;
1209 HDC hDC = BeginPaint(hWnd, &Ps);
1210 if (hDC)
1211 {
1212 HICON hIcon;
1213
1214 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MINIMIZE &&
1215 (hIcon = (HICON)GetClassLongPtrW(hWnd, GCL_HICON)) != NULL)
1216 {
1217 RECT ClientRect;
1218 INT x, y;
1219 GetClientRect(hWnd, &ClientRect);
1220 x = (ClientRect.right - ClientRect.left -
1221 GetSystemMetrics(SM_CXICON)) / 2;
1222 y = (ClientRect.bottom - ClientRect.top -
1223 GetSystemMetrics(SM_CYICON)) / 2;
1224 DrawIcon(hDC, x, y, hIcon);
1225 }
1226 EndPaint(hWnd, &Ps);
1227 }
1228 return (0);
1229 }
1230
1231 case WM_SYNCPAINT:
1232 {
1233 HRGN hRgn;
1234 hRgn = CreateRectRgn(0, 0, 0, 0);
1235 if (GetUpdateRgn(hWnd, hRgn, FALSE) != NULLREGION)
1236 {
1237 RedrawWindow(hWnd, NULL, hRgn,
1238 RDW_ERASENOW | RDW_ERASE | RDW_FRAME |
1239 RDW_ALLCHILDREN);
1240 }
1241 DeleteObject(hRgn);
1242 return (0);
1243 }
1244
1245 case WM_SETREDRAW:
1246 {
1247 LONG_PTR Style = GetWindowLongPtrW(hWnd, GWL_STYLE);
1248 if (wParam) SetWindowLongPtr(hWnd, GWL_STYLE, Style | WS_VISIBLE);
1249 else
1250 {
1251 RedrawWindow(hWnd, NULL, 0, RDW_ALLCHILDREN | RDW_VALIDATE);
1252 Style &= ~WS_VISIBLE;
1253 SetWindowLongPtr(hWnd, GWL_STYLE, Style);
1254 }
1255 return (0);
1256 }
1257
1258 case WM_CLOSE:
1259 {
1260 DestroyWindow(hWnd);
1261 return (0);
1262 }
1263
1264 case WM_MOUSEACTIVATE:
1265 {
1266 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD)
1267 {
1268 LONG Ret;
1269 if (bUnicode)
1270 {
1271 Ret = SendMessageW(GetParent(hWnd), WM_MOUSEACTIVATE,
1272 wParam, lParam);
1273 }
1274 else
1275 {
1276 Ret = SendMessageA(GetParent(hWnd), WM_MOUSEACTIVATE,
1277 wParam, lParam);
1278 }
1279 if (Ret)
1280 {
1281 return (Ret);
1282 }
1283 }
1284 return ((LOWORD(lParam) >= HTCLIENT) ? MA_ACTIVATE : MA_NOACTIVATE);
1285 }
1286
1287 case WM_ACTIVATE:
1288 {
1289 /* Check if the window is minimized. */
1290 if (LOWORD(wParam) != WA_INACTIVE &&
1291 !(GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MINIMIZE))
1292 {
1293 SetFocus(hWnd);
1294 }
1295 break;
1296 }
1297
1298 case WM_MOUSEWHEEL:
1299 {
1300 if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CHILD)
1301 {
1302 if (bUnicode)
1303 {
1304 return (SendMessageW(GetParent(hWnd), WM_MOUSEWHEEL,
1305 wParam, lParam));
1306 }
1307 else
1308 {
1309 return (SendMessageA(GetParent(hWnd), WM_MOUSEWHEEL,
1310 wParam, lParam));
1311 }
1312 }
1313 break;
1314 }
1315
1316 case WM_ERASEBKGND:
1317 case WM_ICONERASEBKGND:
1318 {
1319 RECT Rect;
1320 HBRUSH hBrush = (HBRUSH)GetClassLongPtrW(hWnd, GCL_HBRBACKGROUND);
1321
1322 if (NULL == hBrush)
1323 {
1324 return 0;
1325 }
1326 if (GetClassLongPtrW(hWnd, GCL_STYLE) & CS_PARENTDC)
1327 {
1328 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1329 GetClientRect(hWnd, &Rect);
1330 DPtoLP((HDC)wParam, (LPPOINT)&Rect, 2);
1331 }
1332 else
1333 {
1334 GetClipBox((HDC)wParam, &Rect);
1335 }
1336 FillRect((HDC)wParam, &Rect, hBrush);
1337 return (1);
1338 }
1339
1340 case WM_CTLCOLORMSGBOX:
1341 case WM_CTLCOLOREDIT:
1342 case WM_CTLCOLORLISTBOX:
1343 case WM_CTLCOLORBTN:
1344 case WM_CTLCOLORDLG:
1345 case WM_CTLCOLORSTATIC:
1346 case WM_CTLCOLORSCROLLBAR:
1347 return (LRESULT) DefWndControlColor((HDC)wParam, Msg - WM_CTLCOLORMSGBOX);
1348
1349 case WM_CTLCOLOR:
1350 return (LRESULT) DefWndControlColor((HDC)wParam, HIWORD(lParam));
1351
1352 case WM_SETCURSOR:
1353 {
1354 LONG_PTR Style = GetWindowLongPtrW(hWnd, GWL_STYLE);
1355
1356 if (Style & WS_CHILD)
1357 {
1358 if (LOWORD(lParam) < HTLEFT || LOWORD(lParam) > HTBOTTOMRIGHT)
1359 {
1360 BOOL bResult;
1361 if (bUnicode)
1362 {
1363 bResult = SendMessageW(GetParent(hWnd), WM_SETCURSOR,
1364 wParam, lParam);
1365 }
1366 else
1367 {
1368 bResult = SendMessageA(GetParent(hWnd), WM_SETCURSOR,
1369 wParam, lParam);
1370 }
1371 if (bResult)
1372 {
1373 return(TRUE);
1374 }
1375 }
1376 }
1377 return (DefWndHandleSetCursor(hWnd, wParam, lParam, Style));
1378 }
1379
1380 case WM_SYSCOMMAND:
1381 return (DefWndHandleSysCommand(hWnd, wParam, lParam));
1382
1383 case WM_KEYDOWN:
1384 if(wParam == VK_F10) iF10Key = VK_F10;
1385 break;
1386
1387 /* FIXME: This is also incomplete. */
1388 case WM_SYSKEYDOWN:
1389 {
1390 if (HIWORD(lParam) & KEYDATA_ALT)
1391 {
1392 HWND top = GetAncestor(hWnd, GA_ROOT);
1393 /* if( HIWORD(lParam) & ~KEYDATA_PREVSTATE ) */
1394 if ( (wParam == VK_MENU || wParam == VK_LMENU
1395 || wParam == VK_RMENU) && !iMenuSysKey )
1396 iMenuSysKey = 1;
1397 else
1398 iMenuSysKey = 0;
1399
1400 iF10Key = 0;
1401
1402 if (wParam == VK_F4) /* Try to close the window */
1403 {
1404 if (!(GetClassLongPtrW(top, GCL_STYLE) & CS_NOCLOSE))
1405 {
1406 if (bUnicode)
1407 PostMessageW(top, WM_SYSCOMMAND, SC_CLOSE, 0);
1408 else
1409 PostMessageA(top, WM_SYSCOMMAND, SC_CLOSE, 0);
1410 }
1411 }
1412 else if (wParam == VK_SNAPSHOT)
1413 {
1414 HWND hwnd = hWnd;
1415 while (GetParent(hwnd) != NULL)
1416 {
1417 hwnd = GetParent(hwnd);
1418 }
1419 DefWndScreenshot(hwnd);
1420 }
1421 }
1422 else if( wParam == VK_F10 )
1423 iF10Key = 1;
1424 else if( wParam == VK_ESCAPE && (GetKeyState(VK_SHIFT) & 0x8000))
1425 SendMessageW( hWnd, WM_SYSCOMMAND, SC_KEYMENU, ' ' );
1426 break;
1427 }
1428
1429 case WM_KEYUP:
1430 case WM_SYSKEYUP:
1431 {
1432 /* Press and release F10 or ALT */
1433 if (((wParam == VK_MENU || wParam == VK_LMENU || wParam == VK_RMENU)
1434 && iMenuSysKey) || ((wParam == VK_F10) && iF10Key))
1435 SendMessageW( GetAncestor( hWnd, GA_ROOT ), WM_SYSCOMMAND, SC_KEYMENU, 0L );
1436 iMenuSysKey = iF10Key = 0;
1437 break;
1438 }
1439
1440 case WM_SYSCHAR:
1441 {
1442 iMenuSysKey = 0;
1443 if (wParam == '\r' && IsIconic(hWnd))
1444 {
1445 PostMessageW( hWnd, WM_SYSCOMMAND, SC_RESTORE, 0L );
1446 break;
1447 }
1448 if ((HIWORD(lParam) & KEYDATA_ALT) && wParam)
1449 {
1450 if (wParam == '\t' || wParam == '\x1b') break;
1451 if (wParam == ' ' && (GetWindowLongPtrW( hWnd, GWL_STYLE ) & WS_CHILD))
1452 SendMessageW( GetParent(hWnd), Msg, wParam, lParam );
1453 else
1454 SendMessageW( hWnd, WM_SYSCOMMAND, SC_KEYMENU, wParam );
1455 }
1456 else /* check for Ctrl-Esc */
1457 if (wParam != '\x1b') MessageBeep(0);
1458 break;
1459 }
1460
1461 case WM_SHOWWINDOW:
1462 {
1463 if (lParam) // Call when it is necessary.
1464 NtUserMessageCall( hWnd, Msg, wParam, lParam, 0, FNID_DEFWINDOWPROC, FALSE);
1465 break;
1466 }
1467
1468 case WM_CLIENTSHUTDOWN:
1469 {
1470 LRESULT lResult;
1471 NtUserMessageCall( hWnd, Msg, wParam, lParam, (ULONG_PTR)&lResult, FNID_DEFWINDOWPROC, FALSE);
1472 return lResult;
1473 }
1474
1475 case WM_CANCELMODE:
1476 {
1477 iMenuSysKey = 0;
1478 /* FIXME: Check for a desktop. */
1479 if (!(GetWindowLongPtrW( hWnd, GWL_STYLE ) & WS_CHILD)) EndMenu();
1480 if (GetCapture() == hWnd)
1481 {
1482 ReleaseCapture();
1483 }
1484 break;
1485 }
1486
1487 case WM_VKEYTOITEM:
1488 case WM_CHARTOITEM:
1489 return (-1);
1490 /*
1491 case WM_DROPOBJECT:
1492 return DRAG_FILE;
1493 */
1494 case WM_QUERYDROPOBJECT:
1495 {
1496 if (GetWindowLongPtrW(hWnd, GWL_EXSTYLE) & WS_EX_ACCEPTFILES)
1497 {
1498 return(1);
1499 }
1500 break;
1501 }
1502
1503 case WM_QUERYDRAGICON:
1504 {
1505 UINT Len;
1506 HICON hIcon;
1507
1508 hIcon = (HICON)GetClassLongPtrW(hWnd, GCL_HICON);
1509 if (hIcon)
1510 {
1511 return ((LRESULT)hIcon);
1512 }
1513 for (Len = 1; Len < 64; Len++)
1514 {
1515 if ((hIcon = LoadIconW(NULL, MAKEINTRESOURCEW(Len))) != NULL)
1516 {
1517 return((LRESULT)hIcon);
1518 }
1519 }
1520 return ((LRESULT)LoadIconW(0, IDI_APPLICATION));
1521 }
1522
1523 case WM_ISACTIVEICON:
1524 {
1525 PWND pWnd;
1526 BOOL isai;
1527 pWnd = ValidateHwnd(hWnd);
1528 if (!pWnd) return 0;
1529 isai = (pWnd->state & WNDS_ACTIVEFRAME) != 0;
1530 return isai;
1531 }
1532
1533 case WM_NOTIFYFORMAT:
1534 {
1535 if (lParam == NF_QUERY)
1536 return IsWindowUnicode(hWnd) ? NFR_UNICODE : NFR_ANSI;
1537 break;
1538 }
1539
1540 case WM_SETICON:
1541 {
1542 INT Index = (wParam != 0) ? GCL_HICON : GCL_HICONSM;
1543 HICON hOldIcon = (HICON)GetClassLongPtrW(hWnd, Index);
1544 SetClassLongPtrW(hWnd, Index, lParam);
1545 SetWindowPos(hWnd, 0, 0, 0, 0, 0,
1546 SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
1547 SWP_NOACTIVATE | SWP_NOZORDER);
1548 return ((LRESULT)hOldIcon);
1549 }
1550
1551 case WM_GETICON:
1552 {
1553 INT Index = (wParam == ICON_BIG) ? GCL_HICON : GCL_HICONSM;
1554 return (GetClassLongPtrW(hWnd, Index));
1555 }
1556
1557 case WM_HELP:
1558 {
1559 if (bUnicode)
1560 {
1561 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
1562 }
1563 else
1564 {
1565 SendMessageA(GetParent(hWnd), Msg, wParam, lParam);
1566 }
1567 break;
1568 }
1569
1570 case WM_SYSTIMER:
1571 {
1572 THRDCARETINFO CaretInfo;
1573 switch(wParam)
1574 {
1575 case 0xffff: /* Caret timer */
1576 /* switch showing byte in win32k and get information about the caret */
1577 if(NtUserSwitchCaretShowing(&CaretInfo) && (CaretInfo.hWnd == hWnd))
1578 {
1579 DrawCaret(hWnd, &CaretInfo);
1580 }
1581 break;
1582 }
1583 break;
1584 }
1585
1586 case WM_QUERYOPEN:
1587 case WM_QUERYENDSESSION:
1588 {
1589 return (1);
1590 }
1591
1592 case WM_INPUTLANGCHANGEREQUEST:
1593 {
1594 HKL NewHkl;
1595
1596 if(wParam & INPUTLANGCHANGE_BACKWARD
1597 && wParam & INPUTLANGCHANGE_FORWARD)
1598 {
1599 return FALSE;
1600 }
1601
1602 //FIXME: What to do with INPUTLANGCHANGE_SYSCHARSET ?
1603
1604 if(wParam & INPUTLANGCHANGE_BACKWARD) NewHkl = (HKL) HKL_PREV;
1605 else if(wParam & INPUTLANGCHANGE_FORWARD) NewHkl = (HKL) HKL_NEXT;
1606 else NewHkl = (HKL) lParam;
1607
1608 NtUserActivateKeyboardLayout(NewHkl, 0);
1609
1610 return TRUE;
1611 }
1612
1613 case WM_INPUTLANGCHANGE:
1614 {
1615 int count = 0;
1616 HWND *win_array = WIN_ListChildren( hWnd );
1617
1618 if (!win_array)
1619 break;
1620 while (win_array[count])
1621 SendMessageW( win_array[count++], WM_INPUTLANGCHANGE, wParam, lParam);
1622 HeapFree(GetProcessHeap(),0,win_array);
1623 break;
1624 }
1625
1626 case WM_QUERYUISTATE:
1627 {
1628 LRESULT Ret = 0;
1629 PWND Wnd = ValidateHwnd(hWnd);
1630 if (Wnd != NULL)
1631 {
1632 if (Wnd->HideFocus)
1633 Ret |= UISF_HIDEFOCUS;
1634 if (Wnd->HideAccel)
1635 Ret |= UISF_HIDEACCEL;
1636 }
1637 return Ret;
1638 }
1639
1640 case WM_CHANGEUISTATE:
1641 {
1642 BOOL AlwaysShowCues = FALSE;
1643 WORD Action = LOWORD(wParam);
1644 WORD Flags = HIWORD(wParam);
1645 PWND Wnd;
1646
1647 SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0);
1648 if (AlwaysShowCues)
1649 break;
1650
1651 Wnd= ValidateHwnd(hWnd);
1652 if (!Wnd || lParam != 0)
1653 break;
1654
1655 if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE))
1656 break;
1657
1658 if (Flags & UISF_ACTIVE)
1659 {
1660 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n");
1661 }
1662
1663 if (Action == UIS_INITIALIZE)
1664 {
1665 PDESKTOPINFO Desk = GetThreadDesktopInfo();
1666 if (Desk == NULL)
1667 break;
1668
1669 Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET;
1670 Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL;
1671
1672 /* We need to update wParam in case we need to send out messages */
1673 wParam = MAKEWPARAM(Action, Flags);
1674 }
1675
1676 switch (Action)
1677 {
1678 case UIS_SET:
1679 /* See if we actually need to change something */
1680 if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus)
1681 break;
1682 if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel)
1683 break;
1684
1685 /* Don't need to do anything... */
1686 return 0;
1687
1688 case UIS_CLEAR:
1689 /* See if we actually need to change something */
1690 if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus)
1691 break;
1692 if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel)
1693 break;
1694
1695 /* Don't need to do anything... */
1696 return 0;
1697
1698 default:
1699 WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action);
1700 break;
1701 }
1702
1703 if ((Wnd->style & WS_CHILD) && Wnd->spwndParent != NULL)
1704 {
1705 /* We're a child window and we need to pass this message down until
1706 we reach the root */
1707 hWnd = UserHMGetHandle((PWND)DesktopPtrToUser(Wnd->spwndParent));
1708 }
1709 else
1710 {
1711 /* We're a top level window, we need to change the UI state */
1712 Msg = WM_UPDATEUISTATE;
1713 }
1714
1715 if (bUnicode)
1716 return SendMessageW(hWnd, Msg, wParam, lParam);
1717 else
1718 return SendMessageA(hWnd, Msg, wParam, lParam);
1719 }
1720
1721 case WM_UPDATEUISTATE:
1722 {
1723 BOOL Change = TRUE;
1724 BOOL AlwaysShowCues = FALSE;
1725 WORD Action = LOWORD(wParam);
1726 WORD Flags = HIWORD(wParam);
1727 PWND Wnd;
1728
1729 SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0);
1730 if (AlwaysShowCues)
1731 break;
1732
1733 Wnd = ValidateHwnd(hWnd);
1734 if (!Wnd || lParam != 0)
1735 break;
1736
1737 if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE))
1738 break;
1739
1740 if (Flags & UISF_ACTIVE)
1741 {
1742 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n");
1743 }
1744
1745 if (Action == UIS_INITIALIZE)
1746 {
1747 PDESKTOPINFO Desk = GetThreadDesktopInfo();
1748 if (Desk == NULL)
1749 break;
1750
1751 Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET;
1752 Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL;
1753
1754 /* We need to update wParam for broadcasting the update */
1755 wParam = MAKEWPARAM(Action, Flags);
1756 }
1757
1758 switch (Action)
1759 {
1760 case UIS_SET:
1761 /* See if we actually need to change something */
1762 if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus)
1763 break;
1764 if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel)
1765 break;
1766
1767 /* Don't need to do anything... */
1768 Change = FALSE;
1769 break;
1770
1771 case UIS_CLEAR:
1772 /* See if we actually need to change something */
1773 if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus)
1774 break;
1775 if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel)
1776 break;
1777
1778 /* Don't need to do anything... */
1779 Change = FALSE;
1780 break;
1781
1782 default:
1783 WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action);
1784 return 0;
1785 }
1786
1787 /* Pack the information and call win32k */
1788 if (Change)
1789 {
1790 if (!NtUserCallTwoParam((DWORD)hWnd, (DWORD)Flags | ((DWORD)Action << 3), TWOPARAM_ROUTINE_ROS_UPDATEUISTATE))
1791 break;
1792 }
1793
1794 /* Always broadcast the update to all children */
1795 EnumChildWindows(hWnd,
1796 UserSendUiUpdateMsg,
1797 (LPARAM)wParam);
1798
1799 break;
1800 }
1801
1802 }
1803 return 0;
1804 }
1805
1806
1807 /*
1808 * helpers for calling IMM32 (from Wine 10/22/2008)
1809 *
1810 * WM_IME_* messages are generated only by IMM32,
1811 * so I assume imm32 is already LoadLibrary-ed.
1812 */
1813 static HWND
1814 DefWndImmGetDefaultIMEWnd(HWND hwnd)
1815 {
1816 HINSTANCE hInstIMM = GetModuleHandleW(L"imm32\0");
1817 HWND (WINAPI *pFunc)(HWND);
1818 HWND hwndRet = 0;
1819
1820 if (!hInstIMM)
1821 {
1822 ERR("cannot get IMM32 handle\n");
1823 return 0;
1824 }
1825
1826 pFunc = (void*) GetProcAddress(hInstIMM, "ImmGetDefaultIMEWnd");
1827 if (pFunc != NULL)
1828 hwndRet = (*pFunc)(hwnd);
1829
1830 return hwndRet;
1831 }
1832
1833
1834 static BOOL
1835 DefWndImmIsUIMessageA(HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1836 {
1837 HINSTANCE hInstIMM = GetModuleHandleW(L"imm32\0");
1838 BOOL (WINAPI *pFunc)(HWND,UINT,WPARAM,LPARAM);
1839 BOOL fRet = FALSE;
1840
1841 if (!hInstIMM)
1842 {
1843 ERR("cannot get IMM32 handle\n");
1844 return FALSE;
1845 }
1846
1847 pFunc = (void*) GetProcAddress(hInstIMM, "ImmIsUIMessageA");
1848 if (pFunc != NULL)
1849 fRet = (*pFunc)(hwndIME, msg, wParam, lParam);
1850
1851 return fRet;
1852 }
1853
1854
1855 static BOOL
1856 DefWndImmIsUIMessageW(HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1857 {
1858 HINSTANCE hInstIMM = GetModuleHandleW(L"imm32\0");
1859 BOOL (WINAPI *pFunc)(HWND,UINT,WPARAM,LPARAM);
1860 BOOL fRet = FALSE;
1861
1862 if (!hInstIMM)
1863 {
1864 ERR("cannot get IMM32 handle\n");
1865 return FALSE;
1866 }
1867
1868 pFunc = (void*) GetProcAddress(hInstIMM, "ImmIsUIMessageW");
1869 if (pFunc != NULL)
1870 fRet = (*pFunc)(hwndIME, msg, wParam, lParam);
1871
1872 return fRet;
1873 }
1874
1875
1876 LRESULT WINAPI
1877 RealDefWindowProcA(HWND hWnd,
1878 UINT Msg,
1879 WPARAM wParam,
1880 LPARAM lParam)
1881 {
1882 LRESULT Result = 0;
1883 PWND Wnd;
1884
1885 SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam);
1886 switch (Msg)
1887 {
1888 case WM_NCCREATE:
1889 {
1890 if (lParam)
1891 {
1892 LPCREATESTRUCTA cs = (LPCREATESTRUCTA)lParam;
1893 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1894 * may have child window IDs instead of window name */
1895 if (HIWORD(cs->lpszName))
1896 {
1897 DefSetText(hWnd, (PCWSTR)cs->lpszName, TRUE);
1898 }
1899 Result = 1;
1900 }
1901 break;
1902 }
1903
1904 case WM_GETTEXTLENGTH:
1905 {
1906 PWSTR buf;
1907 ULONG len;
1908
1909 Wnd = ValidateHwnd(hWnd);
1910 if (Wnd != NULL && Wnd->strName.Length != 0)
1911 {
1912 buf = DesktopPtrToUser(Wnd->strName.Buffer);
1913 if (buf != NULL &&
1914 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len,
1915 buf,
1916 Wnd->strName.Length)))
1917 {
1918 Result = (LRESULT) len;
1919 }
1920 }
1921 else Result = 0L;
1922
1923 break;
1924 }
1925
1926 case WM_GETTEXT:
1927 {
1928 PWSTR buf = NULL;
1929 PSTR outbuf = (PSTR)lParam;
1930 UINT copy;
1931
1932 Wnd = ValidateHwnd(hWnd);
1933 if (Wnd != NULL && wParam != 0)
1934 {
1935 if (Wnd->strName.Buffer != NULL)
1936 buf = DesktopPtrToUser(Wnd->strName.Buffer);
1937 else
1938 outbuf[0] = L'\0';
1939
1940 if (buf != NULL)
1941 {
1942 if (Wnd->strName.Length != 0)
1943 {
1944 copy = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1);
1945 Result = WideCharToMultiByte(CP_ACP,
1946 0,
1947 buf,
1948 copy,
1949 outbuf,
1950 wParam,
1951 NULL,
1952 NULL);
1953 outbuf[Result] = '\0';
1954 }
1955 else
1956 outbuf[0] = '\0';
1957 }
1958 }
1959 break;
1960 }
1961
1962 case WM_SETTEXT:
1963 {
1964 DefSetText(hWnd, (PCWSTR)lParam, TRUE);
1965
1966 if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1967 {
1968 DefWndNCPaint(hWnd, (HRGN)1, -1);
1969 }
1970
1971 Result = 1;
1972 break;
1973 }
1974
1975 case WM_IME_KEYDOWN:
1976 {
1977 Result = PostMessageA(hWnd, WM_KEYDOWN, wParam, lParam);
1978 break;
1979 }
1980
1981 case WM_IME_KEYUP:
1982 {
1983 Result = PostMessageA(hWnd, WM_KEYUP, wParam, lParam);
1984 break;
1985 }
1986
1987 case WM_IME_CHAR:
1988 {
1989 if (HIBYTE(wParam))
1990 PostMessageA(hWnd, WM_CHAR, HIBYTE(wParam), lParam);
1991 PostMessageA(hWnd, WM_CHAR, LOBYTE(wParam), lParam);
1992 break;
1993 }
1994
1995 case WM_IME_STARTCOMPOSITION:
1996 case WM_IME_COMPOSITION:
1997 case WM_IME_ENDCOMPOSITION:
1998 case WM_IME_SELECT:
1999 case WM_IME_NOTIFY:
2000 {
2001 HWND hwndIME;
2002
2003 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
2004 if (hwndIME)
2005 Result = SendMessageA(hwndIME, Msg, wParam, lParam);
2006 break;
2007 }
2008
2009 case WM_IME_SETCONTEXT:
2010 {
2011 HWND hwndIME;
2012
2013 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
2014 if (hwndIME)
2015 Result = DefWndImmIsUIMessageA(hwndIME, Msg, wParam, lParam);
2016 break;
2017 }
2018
2019 /* fall through */
2020 default:
2021 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, FALSE);
2022 }
2023
2024 SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam);
2025 return Result;
2026 }
2027
2028
2029 LRESULT WINAPI
2030 RealDefWindowProcW(HWND hWnd,
2031 UINT Msg,
2032 WPARAM wParam,
2033 LPARAM lParam)
2034 {
2035 LRESULT Result = 0;
2036 PWND Wnd;
2037
2038 SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam);
2039 switch (Msg)
2040 {
2041 case WM_NCCREATE:
2042 {
2043 if (lParam)
2044 {
2045 LPCREATESTRUCTW cs = (LPCREATESTRUCTW)lParam;
2046 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
2047 * may have child window IDs instead of window name */
2048
2049 if (HIWORD(cs->lpszName))
2050 {
2051 DefSetText(hWnd, cs->lpszName, FALSE);
2052 }
2053 Result = 1;
2054 }
2055 break;
2056 }
2057
2058 case WM_GETTEXTLENGTH:
2059 {
2060 PWSTR buf;
2061 ULONG len;
2062
2063 Wnd = ValidateHwnd(hWnd);
2064 if (Wnd != NULL && Wnd->strName.Length != 0)
2065 {
2066 buf = DesktopPtrToUser(Wnd->strName.Buffer);
2067 if (buf != NULL &&
2068 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len,
2069 buf,
2070 Wnd->strName.Length)))
2071 {
2072 Result = (LRESULT) (Wnd->strName.Length / sizeof(WCHAR));
2073 }
2074 }
2075 else Result = 0L;
2076
2077 break;
2078 }
2079
2080 case WM_GETTEXT:
2081 {
2082 PWSTR buf = NULL;
2083 PWSTR outbuf = (PWSTR)lParam;
2084
2085 Wnd = ValidateHwnd(hWnd);
2086 if (Wnd != NULL && wParam != 0)
2087 {
2088 if (Wnd->strName.Buffer != NULL)
2089 buf = DesktopPtrToUser(Wnd->strName.Buffer);
2090 else
2091 outbuf[0] = L'\0';
2092
2093 if (buf != NULL)
2094 {
2095 if (Wnd->strName.Length != 0)
2096 {
2097 Result = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1);
2098 RtlCopyMemory(outbuf,
2099 buf,
2100 Result * sizeof(WCHAR));
2101 outbuf[Result] = L'\0';
2102 }
2103 else
2104 outbuf[0] = L'\0';
2105 }
2106 }
2107 break;
2108 }
2109
2110 case WM_SETTEXT:
2111 {
2112 DefSetText(hWnd, (PCWSTR)lParam, FALSE);
2113
2114 if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
2115 {
2116 DefWndNCPaint(hWnd, (HRGN)1, -1);
2117 }
2118 Result = 1;
2119 break;
2120 }
2121
2122 case WM_IME_CHAR:
2123 {
2124 PostMessageW(hWnd, WM_CHAR, wParam, lParam);
2125 Result = 0;
2126 break;
2127 }
2128
2129 case WM_IME_KEYDOWN:
2130 {
2131 Result = PostMessageW(hWnd, WM_KEYDOWN, wParam, lParam);
2132 break;
2133 }
2134
2135 case WM_IME_KEYUP:
2136 {
2137 Result = PostMessageW(hWnd, WM_KEYUP, wParam, lParam);
2138 break;
2139 }
2140
2141 case WM_IME_STARTCOMPOSITION:
2142 case WM_IME_COMPOSITION:
2143 case WM_IME_ENDCOMPOSITION:
2144 case WM_IME_SELECT:
2145 case WM_IME_NOTIFY:
2146 {
2147 HWND hwndIME;
2148
2149 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
2150 if (hwndIME)
2151 Result = SendMessageW(hwndIME, Msg, wParam, lParam);
2152 break;
2153 }
2154
2155 case WM_IME_SETCONTEXT:
2156 {
2157 HWND hwndIME;
2158
2159 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
2160 if (hwndIME)
2161 Result = DefWndImmIsUIMessageW(hwndIME, Msg, wParam, lParam);
2162 break;
2163 }
2164
2165 default:
2166 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, TRUE);
2167 }
2168 SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam);
2169
2170 return Result;
2171 }
2172
2173 LRESULT WINAPI
2174 DefWindowProcA(HWND hWnd,
2175 UINT Msg,
2176 WPARAM wParam,
2177 LPARAM lParam)
2178 {
2179 BOOL Hook, msgOverride = FALSE;
2180 LRESULT Result = 0;
2181
2182 LOADUSERAPIHOOK
2183
2184 Hook = BeginIfHookedUserApiHook();
2185 if (Hook)
2186 msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray);
2187
2188 /* Bypass SEH and go direct. */
2189 if (!Hook || !msgOverride)
2190 return RealDefWindowProcA(hWnd, Msg, wParam, lParam);
2191
2192 _SEH2_TRY
2193 {
2194 Result = guah.DefWindowProcA(hWnd, Msg, wParam, lParam);
2195 }
2196 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2197 {
2198 }
2199 _SEH2_END;
2200
2201 EndUserApiHook();
2202
2203 return Result;
2204 }
2205
2206 LRESULT WINAPI
2207 DefWindowProcW(HWND hWnd,
2208 UINT Msg,
2209 WPARAM wParam,
2210 LPARAM lParam)
2211 {
2212 BOOL Hook, msgOverride = FALSE;
2213 LRESULT Result = 0;
2214
2215 LOADUSERAPIHOOK
2216
2217 Hook = BeginIfHookedUserApiHook();
2218 if (Hook)
2219 msgOverride = IsMsgOverride(Msg, &guah.DefWndProcArray);
2220
2221 /* Bypass SEH and go direct. */
2222 if (!Hook || !msgOverride)
2223 return RealDefWindowProcW(hWnd, Msg, wParam, lParam);
2224
2225 _SEH2_TRY
2226 {
2227 Result = guah.DefWindowProcW(hWnd, Msg, wParam, lParam);
2228 }
2229 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2230 {
2231 }
2232 _SEH2_END;
2233
2234 EndUserApiHook();
2235
2236 return Result;
2237 }