Patch by Aric Stewart : user32: Implement handling of WM_INPUTLANGCHANGE. Updated...
[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->SysColors[nIndex];
67 }
68
69 SetLastError(ERROR_INVALID_PARAMETER);
70 return 0;
71 }
72
73 /*
74 * @implemented
75 */
76 HPEN WINAPI
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 WINAPI
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 WINAPI
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 WINAPI
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 int count = 0;
1578 HWND *win_array = WIN_ListChildren( hWnd );
1579
1580 if (!win_array)
1581 break;
1582 while (win_array[count])
1583 SendMessageW( win_array[count++], WM_INPUTLANGCHANGE, wParam, lParam);
1584 HeapFree(GetProcessHeap(),0,win_array);
1585 break;
1586 }
1587
1588 case WM_ENDSESSION:
1589 if (wParam) PostQuitMessage(0);
1590 return 0;
1591
1592 case WM_QUERYUISTATE:
1593 {
1594 LRESULT Ret = 0;
1595 PWINDOW Wnd = ValidateHwnd(hWnd);
1596 if (Wnd != NULL)
1597 {
1598 if (Wnd->HideFocus)
1599 Ret |= UISF_HIDEFOCUS;
1600 if (Wnd->HideAccel)
1601 Ret |= UISF_HIDEACCEL;
1602 }
1603 return Ret;
1604 }
1605
1606 case WM_CHANGEUISTATE:
1607 {
1608 BOOL AlwaysShowCues = TRUE;
1609 WORD Action = LOWORD(wParam);
1610 WORD Flags = HIWORD(wParam);
1611 PWINDOW Wnd;
1612
1613 SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0);
1614 if (AlwaysShowCues)
1615 break;
1616
1617 Wnd= ValidateHwnd(hWnd);
1618 if (!Wnd || lParam != 0)
1619 break;
1620
1621 if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE))
1622 break;
1623
1624 if (Flags & UISF_ACTIVE)
1625 {
1626 WARN("WM_CHANGEUISTATE does not yet support UISF_ACTIVE!\n");
1627 }
1628
1629 if (Action == UIS_INITIALIZE)
1630 {
1631 PDESKTOPINFO Desk = GetThreadDesktopInfo();
1632 if (Desk == NULL)
1633 break;
1634
1635 Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET;
1636 Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL;
1637
1638 /* We need to update wParam in case we need to send out messages */
1639 wParam = MAKEWPARAM(Action, Flags);
1640 }
1641
1642 switch (Action)
1643 {
1644 case UIS_SET:
1645 /* See if we actually need to change something */
1646 if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus)
1647 break;
1648 if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel)
1649 break;
1650
1651 /* Don't need to do anything... */
1652 return 0;
1653
1654 case UIS_CLEAR:
1655 /* See if we actually need to change something */
1656 if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus)
1657 break;
1658 if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel)
1659 break;
1660
1661 /* Don't need to do anything... */
1662 return 0;
1663
1664 default:
1665 WARN("WM_CHANGEUISTATE: Unsupported Action 0x%x\n", Action);
1666 break;
1667 }
1668
1669 if ((Wnd->Style & WS_CHILD) && Wnd->Parent != NULL)
1670 {
1671 /* We're a child window and we need to pass this message down until
1672 we reach the root */
1673 hWnd = UserHMGetHandle((PWINDOW)DesktopPtrToUser(Wnd->Parent));
1674 }
1675 else
1676 {
1677 /* We're a top level window, we need to change the UI state */
1678 Msg = WM_UPDATEUISTATE;
1679 }
1680
1681 if (bUnicode)
1682 return SendMessageW(hWnd, Msg, wParam, lParam);
1683 else
1684 return SendMessageA(hWnd, Msg, wParam, lParam);
1685 }
1686
1687 case WM_UPDATEUISTATE:
1688 {
1689 BOOL Change = TRUE;
1690 BOOL AlwaysShowCues = TRUE;
1691 WORD Action = LOWORD(wParam);
1692 WORD Flags = HIWORD(wParam);
1693 PWINDOW Wnd;
1694
1695 SystemParametersInfoW(SPI_GETKEYBOARDCUES, 0, &AlwaysShowCues, 0);
1696 if (AlwaysShowCues)
1697 break;
1698
1699 Wnd = ValidateHwnd(hWnd);
1700 if (!Wnd || lParam != 0)
1701 break;
1702
1703 if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE))
1704 break;
1705
1706 if (Flags & UISF_ACTIVE)
1707 {
1708 WARN("WM_UPDATEUISTATE does not yet support UISF_ACTIVE!\n");
1709 }
1710
1711 if (Action == UIS_INITIALIZE)
1712 {
1713 PDESKTOPINFO Desk = GetThreadDesktopInfo();
1714 if (Desk == NULL)
1715 break;
1716
1717 Action = Desk->LastInputWasKbd ? UIS_CLEAR : UIS_SET;
1718 Flags = UISF_HIDEFOCUS | UISF_HIDEACCEL;
1719
1720 /* We need to update wParam for broadcasting the update */
1721 wParam = MAKEWPARAM(Action, Flags);
1722 }
1723
1724 switch (Action)
1725 {
1726 case UIS_SET:
1727 /* See if we actually need to change something */
1728 if ((Flags & UISF_HIDEFOCUS) && !Wnd->HideFocus)
1729 break;
1730 if ((Flags & UISF_HIDEACCEL) && !Wnd->HideAccel)
1731 break;
1732
1733 /* Don't need to do anything... */
1734 Change = FALSE;
1735 break;
1736
1737 case UIS_CLEAR:
1738 /* See if we actually need to change something */
1739 if ((Flags & UISF_HIDEFOCUS) && Wnd->HideFocus)
1740 break;
1741 if ((Flags & UISF_HIDEACCEL) && Wnd->HideAccel)
1742 break;
1743
1744 /* Don't need to do anything... */
1745 Change = FALSE;
1746 break;
1747
1748 default:
1749 WARN("WM_UPDATEUISTATE: Unsupported Action 0x%x\n", Action);
1750 return 0;
1751 }
1752
1753 /* Pack the information and call win32k */
1754 if (Change)
1755 {
1756 if (!NtUserCallTwoParam((DWORD)hWnd, (DWORD)Flags | ((DWORD)Action << 3), TWOPARAM_ROUTINE_ROS_UPDATEUISTATE))
1757 break;
1758 }
1759
1760 /* Always broadcast the update to all children */
1761 EnumChildWindows(hWnd,
1762 UserSendUiUpdateMsg,
1763 (LPARAM)wParam);
1764
1765 break;
1766 }
1767
1768 }
1769 return 0;
1770 }
1771
1772
1773 /*
1774 * helpers for calling IMM32 (from Wine 10/22/2008)
1775 *
1776 * WM_IME_* messages are generated only by IMM32,
1777 * so I assume imm32 is already LoadLibrary-ed.
1778 */
1779 static HWND
1780 DefWndImmGetDefaultIMEWnd(HWND hwnd)
1781 {
1782 HINSTANCE hInstIMM = GetModuleHandleW(L"imm32\0");
1783 HWND (WINAPI *pFunc)(HWND);
1784 HWND hwndRet = 0;
1785
1786 if (!hInstIMM)
1787 {
1788 ERR("cannot get IMM32 handle\n");
1789 return 0;
1790 }
1791
1792 pFunc = (void*) GetProcAddress(hInstIMM, "ImmGetDefaultIMEWnd");
1793 if (pFunc != NULL)
1794 hwndRet = (*pFunc)(hwnd);
1795
1796 return hwndRet;
1797 }
1798
1799
1800 static BOOL
1801 DefWndImmIsUIMessageA(HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1802 {
1803 HINSTANCE hInstIMM = GetModuleHandleW(L"imm32\0");
1804 BOOL (WINAPI *pFunc)(HWND,UINT,WPARAM,LPARAM);
1805 BOOL fRet = FALSE;
1806
1807 if (!hInstIMM)
1808 {
1809 ERR("cannot get IMM32 handle\n");
1810 return FALSE;
1811 }
1812
1813 pFunc = (void*) GetProcAddress(hInstIMM, "ImmIsUIMessageA");
1814 if (pFunc != NULL)
1815 fRet = (*pFunc)(hwndIME, msg, wParam, lParam);
1816
1817 return fRet;
1818 }
1819
1820
1821 static BOOL
1822 DefWndImmIsUIMessageW(HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam)
1823 {
1824 HINSTANCE hInstIMM = GetModuleHandleW(L"imm32\0");
1825 BOOL (WINAPI *pFunc)(HWND,UINT,WPARAM,LPARAM);
1826 BOOL fRet = FALSE;
1827
1828 if (!hInstIMM)
1829 {
1830 ERR("cannot get IMM32 handle\n");
1831 return FALSE;
1832 }
1833
1834 pFunc = (void*) GetProcAddress(hInstIMM, "ImmIsUIMessageW");
1835 if (pFunc != NULL)
1836 fRet = (*pFunc)(hwndIME, msg, wParam, lParam);
1837
1838 return fRet;
1839 }
1840
1841
1842 LRESULT WINAPI
1843 DefWindowProcA(HWND hWnd,
1844 UINT Msg,
1845 WPARAM wParam,
1846 LPARAM lParam)
1847 {
1848 LRESULT Result = 0;
1849 PWINDOW Wnd;
1850
1851 SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam);
1852 switch (Msg)
1853 {
1854 case WM_NCCREATE:
1855 {
1856 ANSI_STRING AnsiString;
1857 UNICODE_STRING UnicodeString;
1858 LPCREATESTRUCTA cs = (LPCREATESTRUCTA)lParam;
1859 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
1860 * may have child window IDs instead of window name */
1861
1862 if(cs->lpszName)
1863 {
1864 RtlInitAnsiString(&AnsiString, (LPSTR)cs->lpszName);
1865 RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
1866 NtUserDefSetText(hWnd, &UnicodeString);
1867 RtlFreeUnicodeString(&UnicodeString);
1868 }
1869 else
1870 NtUserDefSetText(hWnd, NULL);
1871
1872 Result = 1;
1873 break;
1874 }
1875
1876 case WM_GETTEXTLENGTH:
1877 {
1878 PWSTR buf;
1879 ULONG len;
1880
1881 Wnd = ValidateHwnd(hWnd);
1882 if (Wnd != NULL && Wnd->WindowName.Length != 0)
1883 {
1884 buf = DesktopPtrToUser(Wnd->WindowName.Buffer);
1885 if (buf != NULL &&
1886 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len,
1887 buf,
1888 Wnd->WindowName.Length)))
1889 {
1890 Result = (LRESULT) len;
1891 }
1892 }
1893 else Result = 0L;
1894
1895 break;
1896 }
1897
1898 case WM_GETTEXT:
1899 {
1900 PWSTR buf = NULL;
1901 PSTR outbuf = (PSTR)lParam;
1902 UINT copy;
1903
1904 Wnd = ValidateHwnd(hWnd);
1905 if (Wnd != NULL && wParam != 0)
1906 {
1907 if (Wnd->WindowName.Buffer != NULL)
1908 buf = DesktopPtrToUser(Wnd->WindowName.Buffer);
1909 else
1910 outbuf[0] = L'\0';
1911
1912 if (buf != NULL)
1913 {
1914 if (Wnd->WindowName.Length != 0)
1915 {
1916 copy = min(Wnd->WindowName.Length / sizeof(WCHAR), wParam - 1);
1917 Result = WideCharToMultiByte(CP_ACP,
1918 0,
1919 buf,
1920 copy,
1921 outbuf,
1922 wParam,
1923 NULL,
1924 NULL);
1925 outbuf[Result] = '\0';
1926 }
1927 else
1928 outbuf[0] = '\0';
1929 }
1930 }
1931 break;
1932 }
1933
1934 case WM_SETTEXT:
1935 {
1936 ANSI_STRING AnsiString;
1937 UNICODE_STRING UnicodeString;
1938
1939 if(lParam)
1940 {
1941 RtlInitAnsiString(&AnsiString, (LPSTR)lParam);
1942 RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
1943 NtUserDefSetText(hWnd, &UnicodeString);
1944 RtlFreeUnicodeString(&UnicodeString);
1945 }
1946 else
1947 NtUserDefSetText(hWnd, NULL);
1948
1949 if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1950 {
1951 DefWndNCPaint(hWnd, (HRGN)1, -1);
1952 }
1953
1954 Result = 1;
1955 break;
1956 }
1957
1958 case WM_IME_KEYDOWN:
1959 {
1960 Result = PostMessageA(hWnd, WM_KEYDOWN, wParam, lParam);
1961 break;
1962 }
1963
1964 case WM_IME_KEYUP:
1965 {
1966 Result = PostMessageA(hWnd, WM_KEYUP, wParam, lParam);
1967 break;
1968 }
1969
1970 case WM_IME_CHAR:
1971 {
1972 if (HIBYTE(wParam))
1973 PostMessageA(hWnd, WM_CHAR, HIBYTE(wParam), lParam);
1974 PostMessageA(hWnd, WM_CHAR, LOBYTE(wParam), lParam);
1975 break;
1976 }
1977
1978 case WM_IME_STARTCOMPOSITION:
1979 case WM_IME_COMPOSITION:
1980 case WM_IME_ENDCOMPOSITION:
1981 case WM_IME_SELECT:
1982 case WM_IME_NOTIFY:
1983 {
1984 HWND hwndIME;
1985
1986 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
1987 if (hwndIME)
1988 Result = SendMessageA(hwndIME, Msg, wParam, lParam);
1989 break;
1990 }
1991
1992 case WM_IME_SETCONTEXT:
1993 {
1994 HWND hwndIME;
1995
1996 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
1997 if (hwndIME)
1998 Result = DefWndImmIsUIMessageA(hwndIME, Msg, wParam, lParam);
1999 break;
2000 }
2001
2002 /* fall through */
2003 default:
2004 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, FALSE);
2005 }
2006
2007 SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam);
2008 return Result;
2009 }
2010
2011
2012 LRESULT WINAPI
2013 DefWindowProcW(HWND hWnd,
2014 UINT Msg,
2015 WPARAM wParam,
2016 LPARAM lParam)
2017 {
2018 LRESULT Result = 0;
2019 PWINDOW Wnd;
2020
2021 SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam);
2022 switch (Msg)
2023 {
2024 case WM_NCCREATE:
2025 {
2026 UNICODE_STRING UnicodeString;
2027 LPCREATESTRUCTW cs = (LPCREATESTRUCTW)lParam;
2028 /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP)
2029 * may have child window IDs instead of window name */
2030
2031 if(cs->lpszName)
2032 RtlInitUnicodeString(&UnicodeString, (LPWSTR)cs->lpszName);
2033
2034 NtUserDefSetText(hWnd, (cs->lpszName ? &UnicodeString : NULL));
2035 Result = 1;
2036 break;
2037 }
2038
2039 case WM_GETTEXTLENGTH:
2040 {
2041 PWSTR buf;
2042 ULONG len;
2043
2044 Wnd = ValidateHwnd(hWnd);
2045 if (Wnd != NULL && Wnd->WindowName.Length != 0)
2046 {
2047 buf = DesktopPtrToUser(Wnd->WindowName.Buffer);
2048 if (buf != NULL &&
2049 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len,
2050 buf,
2051 Wnd->WindowName.Length)))
2052 {
2053 Result = (LRESULT) (Wnd->WindowName.Length / sizeof(WCHAR));
2054 }
2055 }
2056 else Result = 0L;
2057
2058 break;
2059 }
2060
2061 case WM_GETTEXT:
2062 {
2063 PWSTR buf = NULL;
2064 PWSTR outbuf = (PWSTR)lParam;
2065
2066 Wnd = ValidateHwnd(hWnd);
2067 if (Wnd != NULL && wParam != 0)
2068 {
2069 if (Wnd->WindowName.Buffer != NULL)
2070 buf = DesktopPtrToUser(Wnd->WindowName.Buffer);
2071 else
2072 outbuf[0] = L'\0';
2073
2074 if (buf != NULL)
2075 {
2076 if (Wnd->WindowName.Length != 0)
2077 {
2078 Result = min(Wnd->WindowName.Length / sizeof(WCHAR), wParam - 1);
2079 RtlCopyMemory(outbuf,
2080 buf,
2081 Result * sizeof(WCHAR));
2082 outbuf[Result] = L'\0';
2083 }
2084 else
2085 outbuf[0] = L'\0';
2086 }
2087 }
2088 break;
2089 }
2090
2091 case WM_SETTEXT:
2092 {
2093 UNICODE_STRING UnicodeString;
2094
2095 if(lParam)
2096 RtlInitUnicodeString(&UnicodeString, (LPWSTR)lParam);
2097
2098 NtUserDefSetText(hWnd, (lParam ? &UnicodeString : NULL));
2099
2100 if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
2101 {
2102 DefWndNCPaint(hWnd, (HRGN)1, -1);
2103 }
2104 Result = 1;
2105 break;
2106 }
2107
2108 case WM_IME_CHAR:
2109 {
2110 PostMessageW(hWnd, WM_CHAR, wParam, lParam);
2111 Result = 0;
2112 break;
2113 }
2114
2115 case WM_IME_KEYDOWN:
2116 {
2117 Result = PostMessageW(hWnd, WM_KEYDOWN, wParam, lParam);
2118 break;
2119 }
2120
2121 case WM_IME_KEYUP:
2122 {
2123 Result = PostMessageW(hWnd, WM_KEYUP, wParam, lParam);
2124 break;
2125 }
2126
2127 case WM_IME_STARTCOMPOSITION:
2128 case WM_IME_COMPOSITION:
2129 case WM_IME_ENDCOMPOSITION:
2130 case WM_IME_SELECT:
2131 case WM_IME_NOTIFY:
2132 {
2133 HWND hwndIME;
2134
2135 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
2136 if (hwndIME)
2137 Result = SendMessageW(hwndIME, Msg, wParam, lParam);
2138 break;
2139 }
2140
2141 case WM_IME_SETCONTEXT:
2142 {
2143 HWND hwndIME;
2144
2145 hwndIME = DefWndImmGetDefaultIMEWnd(hWnd);
2146 if (hwndIME)
2147 Result = DefWndImmIsUIMessageW(hwndIME, Msg, wParam, lParam);
2148 break;
2149 }
2150
2151 default:
2152 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, TRUE);
2153 }
2154 SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam);
2155
2156 return Result;
2157 }
2158