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