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