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