Merge 13831:14550 from trunk
[reactos.git] / reactos / lib / user32 / windows / defwnd.c
1 /* $Id$
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 #include <windowsx.h>
16 #include <window.h>
17 #include <user32/wininternal.h>
18 #include <string.h>
19 #include <cursor.h>
20 #include <menu.h>
21 #include <scroll.h>
22 #include <winpos.h>
23
24 #define NDEBUG
25 #include <debug.h>
26
27 #ifndef WM_SETVISIBLE
28 #define WM_SETVISIBLE 9
29 #endif
30 #ifndef WM_QUERYDROPOBJECT
31 #define WM_QUERYDROPOBJECT 0x022B
32 #endif
33
34 LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active);
35 LRESULT DefWndNCCalcSize(HWND hWnd, BOOL CalcSizeStruct, RECT *Rect);
36 LRESULT DefWndNCActivate(HWND hWnd, WPARAM wParam);
37 LRESULT DefWndNCHitTest(HWND hWnd, POINT Point);
38 LRESULT DefWndNCLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam);
39 LRESULT DefWndNCLButtonDblClk(HWND hWnd, WPARAM wParam, LPARAM lParam);
40 void FASTCALL MenuInitSysMenuPopup(HMENU Menu, DWORD Style, DWORD ClsStyle, LONG HitTest );
41
42 /* GLOBALS *******************************************************************/
43
44 COLORREF SysColors[NUM_SYSCOLORS] = {0};
45 HPEN SysPens[NUM_SYSCOLORS] = {0};
46 HBRUSH SysBrushes[NUM_SYSCOLORS] = {0};
47
48 /* Bits in the dwKeyData */
49 #define KEYDATA_ALT 0x2000
50
51 /* FUNCTIONS *****************************************************************/
52
53 void
54 InitStockObjects(void)
55 {
56 /* FIXME - Instead of copying the stuff to usermode we should map the tables to
57 userland. The current implementation has one big flaw: the system color
58 table doesn't get updated when another process changes them. That's why
59 we should rather map the table into usermode. But it only affects the
60 SysColors table - the pens, brushes and stock objects are not affected
61 as their handles never change. But it'd be faster to map them, too. */
62 if(SysBrushes[0] == NULL)
63 {
64 /* only initialize once */
65 NtUserGetSysColors(SysColors, NUM_SYSCOLORS);
66 NtUserGetSysColorPens(SysPens, NUM_SYSCOLORS);
67 NtUserGetSysColorBrushes(SysBrushes, NUM_SYSCOLORS);
68 }
69 }
70
71 /*
72 * @implemented
73 */
74 DWORD STDCALL
75 GetSysColor(int nIndex)
76 {
77 if(nIndex >= 0 && nIndex <= NUM_SYSCOLORS)
78 {
79 return SysColors[nIndex];
80 }
81
82 SetLastError(ERROR_INVALID_PARAMETER);
83 return 0;
84 }
85
86 /*
87 * @implemented
88 */
89 HPEN STDCALL
90 GetSysColorPen(int nIndex)
91 {
92 if(nIndex >= 0 && nIndex <= NUM_SYSCOLORS)
93 {
94 return SysPens[nIndex];
95 }
96
97 SetLastError(ERROR_INVALID_PARAMETER);
98 return NULL;
99 }
100
101 /*
102 * @implemented
103 */
104 HBRUSH STDCALL
105 GetSysColorBrush(int nIndex)
106 {
107 if(nIndex >= 0 && nIndex <= NUM_SYSCOLORS)
108 {
109 return SysBrushes[nIndex];
110 }
111
112 SetLastError(ERROR_INVALID_PARAMETER);
113 return NULL;
114 }
115
116 /*
117 * @implemented
118 */
119 BOOL
120 STDCALL
121 SetSysColors(
122 int cElements,
123 CONST INT *lpaElements,
124 CONST COLORREF *lpaRgbValues)
125 {
126 BOOL Ret;
127 struct
128 {
129 INT *Elements;
130 COLORREF *Colors;
131 } ChangeSysColors;
132
133 ChangeSysColors.Elements = (INT*)lpaElements;
134 ChangeSysColors.Colors = (COLORREF*)lpaRgbValues;
135
136 if(cElements > 0)
137 {
138 Ret = NtUserSetSysColors(&ChangeSysColors, cElements);
139 if(Ret)
140 {
141 /* FIXME - just change it in the usermode structure, too, instead of asking win32k again */
142 NtUserGetSysColors(SysColors, NUM_SYSCOLORS);
143 }
144 }
145 else
146 {
147 SetLastError(ERROR_INVALID_PARAMETER);
148 Ret = FALSE;
149 }
150
151 return Ret;
152 }
153
154 void
155 UserGetInsideRectNC(HWND hWnd, RECT *rect)
156 {
157 RECT WindowRect;
158 ULONG Style;
159 ULONG ExStyle;
160
161 Style = GetWindowLongW(hWnd, GWL_STYLE);
162 ExStyle = GetWindowLongW(hWnd, GWL_EXSTYLE);
163 GetWindowRect(hWnd, &WindowRect);
164 rect->top = rect->left = 0;
165 rect->right = WindowRect.right - WindowRect.left;
166 rect->bottom = WindowRect.bottom - WindowRect.top;
167
168 if (Style & WS_ICONIC)
169 {
170 return;
171 }
172
173 /* Remove frame from rectangle */
174 if (UserHasThickFrameStyle(Style, ExStyle ))
175 {
176 InflateRect(rect, -GetSystemMetrics(SM_CXFRAME),
177 -GetSystemMetrics(SM_CYFRAME));
178 }
179 else
180 {
181 if (UserHasDlgFrameStyle(Style, ExStyle ))
182 {
183 InflateRect(rect, -GetSystemMetrics(SM_CXDLGFRAME),
184 -GetSystemMetrics(SM_CYDLGFRAME));
185 /* FIXME: this isn't in NC_AdjustRect? why not? */
186 if (ExStyle & WS_EX_DLGMODALFRAME)
187 InflateRect( rect, -1, 0 );
188 }
189 else
190 {
191 if (UserHasThinFrameStyle(Style, ExStyle))
192 {
193 InflateRect(rect, -GetSystemMetrics(SM_CXBORDER),
194 -GetSystemMetrics(SM_CYBORDER));
195 }
196 }
197 }
198 }
199
200
201 VOID
202 DefWndSetRedraw(HWND hWnd, WPARAM wParam)
203 {
204 if ((BOOL) wParam && 0 == (GetWindowLong(hWnd, GWL_STYLE) & WS_VISIBLE))
205 {
206 ShowWindow(hWnd, SW_NORMAL);
207 }
208
209 UNIMPLEMENTED;
210 }
211
212
213 LRESULT
214 DefWndHandleSetCursor(HWND hWnd, WPARAM wParam, LPARAM lParam, ULONG Style)
215 {
216 /* Not for child windows. */
217 if (hWnd != (HWND)wParam)
218 {
219 return(0);
220 }
221
222 switch((INT_PTR) LOWORD(lParam))
223 {
224 case HTERROR:
225 {
226 WORD Msg = HIWORD(lParam);
227 if (Msg == WM_LBUTTONDOWN || Msg == WM_MBUTTONDOWN ||
228 Msg == WM_RBUTTONDOWN || Msg == WM_XBUTTONDOWN)
229 {
230 MessageBeep(0);
231 }
232 break;
233 }
234
235 case HTCLIENT:
236 {
237 HICON hCursor = (HICON)GetClassLongW(hWnd, GCL_HCURSOR);
238 if (hCursor)
239 {
240 SetCursor(hCursor);
241 return(TRUE);
242 }
243 return(FALSE);
244 }
245
246 case HTLEFT:
247 case HTRIGHT:
248 {
249 if (Style & WS_MAXIMIZE)
250 {
251 break;
252 }
253 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZEWE)));
254 }
255
256 case HTTOP:
257 case HTBOTTOM:
258 {
259 if (Style & WS_MAXIMIZE)
260 {
261 break;
262 }
263 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENS)));
264 }
265
266 case HTTOPLEFT:
267 case HTBOTTOMRIGHT:
268 {
269 if (Style & WS_MAXIMIZE)
270 {
271 break;
272 }
273 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENWSE)));
274 }
275
276 case HTBOTTOMLEFT:
277 case HTTOPRIGHT:
278 {
279 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_MAXIMIZE)
280 {
281 break;
282 }
283 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENESW)));
284 }
285 }
286 return((LRESULT)SetCursor(LoadCursorW(0, IDC_ARROW)));
287 }
288
289 static LONG
290 DefWndStartSizeMove(HWND hWnd, WPARAM wParam, POINT *capturePoint)
291 {
292 LONG hittest = 0;
293 POINT pt;
294 MSG msg;
295 RECT rectWindow;
296 ULONG Style = GetWindowLongW(hWnd, GWL_STYLE);
297
298 GetWindowRect(hWnd, &rectWindow);
299
300 if ((wParam & 0xfff0) == SC_MOVE)
301 {
302 /* Move pointer at the center of the caption */
303 RECT rect;
304 UserGetInsideRectNC(hWnd, &rect);
305 if (Style & WS_SYSMENU)
306 rect.left += GetSystemMetrics(SM_CXSIZE) + 1;
307 if (Style & WS_MINIMIZEBOX)
308 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
309 if (Style & WS_MAXIMIZEBOX)
310 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
311 pt.x = rectWindow.left + (rect.right - rect.left) / 2;
312 pt.y = rectWindow.top + rect.top + GetSystemMetrics(SM_CYSIZE)/2;
313 hittest = HTCAPTION;
314 *capturePoint = pt;
315 }
316 else /* SC_SIZE */
317 {
318 while(!hittest)
319 {
320 if (GetMessageW(&msg, NULL, 0, 0) <= 0)
321 break;
322 switch(msg.message)
323 {
324 case WM_MOUSEMOVE:
325 hittest = DefWndNCHitTest(hWnd, msg.pt);
326 if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
327 hittest = 0;
328 break;
329
330 case WM_LBUTTONUP:
331 return 0;
332
333 case WM_KEYDOWN:
334 switch(msg.wParam)
335 {
336 case VK_UP:
337 hittest = HTTOP;
338 pt.x =(rectWindow.left+rectWindow.right)/2;
339 pt.y = rectWindow.top + GetSystemMetrics(SM_CYFRAME) / 2;
340 break;
341 case VK_DOWN:
342 hittest = HTBOTTOM;
343 pt.x =(rectWindow.left+rectWindow.right)/2;
344 pt.y = rectWindow.bottom - GetSystemMetrics(SM_CYFRAME) / 2;
345 break;
346 case VK_LEFT:
347 hittest = HTLEFT;
348 pt.x = rectWindow.left + GetSystemMetrics(SM_CXFRAME) / 2;
349 pt.y =(rectWindow.top+rectWindow.bottom)/2;
350 break;
351 case VK_RIGHT:
352 hittest = HTRIGHT;
353 pt.x = rectWindow.right - GetSystemMetrics(SM_CXFRAME) / 2;
354 pt.y =(rectWindow.top+rectWindow.bottom)/2;
355 break;
356 case VK_RETURN:
357 case VK_ESCAPE: return 0;
358 }
359 }
360 }
361 *capturePoint = pt;
362 }
363 SetCursorPos( pt.x, pt.y );
364 DefWndHandleSetCursor(hWnd, (WPARAM)hWnd, MAKELONG(hittest, WM_MOUSEMOVE), Style);
365 return hittest;
366 }
367
368 #define ON_LEFT_BORDER(hit) \
369 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
370 #define ON_RIGHT_BORDER(hit) \
371 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
372 #define ON_TOP_BORDER(hit) \
373 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
374 #define ON_BOTTOM_BORDER(hit) \
375 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
376
377 VOID STATIC
378 UserDrawWindowFrame(HDC hdc, const RECT *rect,
379 ULONG width, ULONG height)
380 {
381 static HBRUSH hDraggingRectBrush = NULL;
382
383 if(!hDraggingRectBrush)
384 {
385 static HBITMAP hDraggingPattern = NULL;
386 const DWORD Pattern[4] = {0x5555AAAA, 0x5555AAAA, 0x5555AAAA, 0x5555AAAA};
387
388 hDraggingPattern = CreateBitmap(8, 8, 1, 1, Pattern);
389 hDraggingRectBrush = CreatePatternBrush(hDraggingPattern);
390 }
391
392 HBRUSH hbrush = SelectObject( hdc, hDraggingRectBrush );
393 PatBlt( hdc, rect->left, rect->top,
394 rect->right - rect->left - width, height, PATINVERT );
395 PatBlt( hdc, rect->left, rect->top + height, width,
396 rect->bottom - rect->top - height, PATINVERT );
397 PatBlt( hdc, rect->left + width, rect->bottom - 1,
398 rect->right - rect->left - width, -height, PATINVERT );
399 PatBlt( hdc, rect->right - 1, rect->top, -width,
400 rect->bottom - rect->top - height, PATINVERT );
401 SelectObject( hdc, hbrush );
402 }
403
404 VOID STATIC
405 UserDrawMovingFrame(HDC hdc, RECT *rect, BOOL thickframe)
406 {
407 if(thickframe)
408 {
409 UserDrawWindowFrame(hdc, rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME));
410 }
411 else
412 {
413 UserDrawWindowFrame(hdc, rect, 1, 1);
414 }
415 }
416
417 VOID STATIC
418 DefWndDoSizeMove(HWND hwnd, WORD wParam)
419 {
420 HRGN DesktopRgn;
421 MSG msg;
422 RECT sizingRect, mouseRect, origRect, clipRect, unmodRect;
423 HDC hdc;
424 LONG hittest = (LONG)(wParam & 0x0f);
425 HCURSOR hDragCursor = 0, hOldCursor = 0;
426 POINT minTrack, maxTrack;
427 POINT capturePoint, pt;
428 ULONG Style = GetWindowLongW(hwnd, GWL_STYLE);
429 ULONG ExStyle = GetWindowLongW(hwnd, GWL_EXSTYLE);
430 BOOL thickframe;
431 BOOL iconic = Style & WS_MINIMIZE;
432 BOOL moved = FALSE;
433 DWORD dwPoint = GetMessagePos();
434 BOOL DragFullWindows = FALSE;
435 HWND hWndParent = NULL;
436
437 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS, 0, &DragFullWindows, 0);
438
439 pt.x = GET_X_LPARAM(dwPoint);
440 pt.y = GET_Y_LPARAM(dwPoint);
441 capturePoint = pt;
442
443 if (IsZoomed(hwnd) || !IsWindowVisible(hwnd))
444 {
445 return;
446 }
447
448 thickframe = UserHasThickFrameStyle(Style, ExStyle) && !(Style & WS_MINIMIZE);
449 if ((wParam & 0xfff0) == SC_MOVE)
450 {
451 if (!hittest)
452 {
453 hittest = DefWndStartSizeMove(hwnd, wParam, &capturePoint);
454 }
455 if (!hittest)
456 {
457 return;
458 }
459 }
460 else /* SC_SIZE */
461 {
462 if (!thickframe)
463 {
464 return;
465 }
466 if (hittest && ((wParam & 0xfff0) != SC_MOUSEMENU))
467 {
468 hittest += (HTLEFT - WMSZ_LEFT);
469 }
470 else
471 {
472 SetCapture(hwnd);
473 hittest = DefWndStartSizeMove(hwnd, wParam, &capturePoint);
474 if (!hittest)
475 {
476 ReleaseCapture();
477 return;
478 }
479 }
480 }
481
482 if (Style & WS_CHILD)
483 {
484 hWndParent = GetParent(hwnd);
485 }
486
487 /* Get min/max info */
488
489 WinPosGetMinMaxInfo(hwnd, NULL, NULL, &minTrack, &maxTrack);
490 GetWindowRect(hwnd, &sizingRect);
491 unmodRect = sizingRect;
492 if (Style & WS_CHILD)
493 {
494 MapWindowPoints( 0, hWndParent, (LPPOINT)&sizingRect, 2 );
495 GetClientRect(hWndParent, &mouseRect );
496 clipRect = mouseRect;
497 MapWindowPoints(hWndParent, HWND_DESKTOP, (LPPOINT)&clipRect, 2);
498 }
499 else
500 {
501 if(!(ExStyle & WS_EX_TOPMOST))
502 {
503 SystemParametersInfoW(SPI_GETWORKAREA, 0, &clipRect, 0);
504 mouseRect = clipRect;
505 }
506 else
507 {
508 SetRect(&mouseRect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
509 clipRect = mouseRect;
510 }
511 }
512 ClipCursor(&clipRect);
513
514 origRect = sizingRect;
515 if (ON_LEFT_BORDER(hittest))
516 {
517 mouseRect.left = max( mouseRect.left, sizingRect.right-maxTrack.x );
518 mouseRect.right = min( mouseRect.right, sizingRect.right-minTrack.x );
519 }
520 else if (ON_RIGHT_BORDER(hittest))
521 {
522 mouseRect.left = max( mouseRect.left, sizingRect.left+minTrack.x );
523 mouseRect.right = min( mouseRect.right, sizingRect.left+maxTrack.x );
524 }
525 if (ON_TOP_BORDER(hittest))
526 {
527 mouseRect.top = max( mouseRect.top, sizingRect.bottom-maxTrack.y );
528 mouseRect.bottom = min( mouseRect.bottom,sizingRect.bottom-minTrack.y);
529 }
530 else if (ON_BOTTOM_BORDER(hittest))
531 {
532 mouseRect.top = max( mouseRect.top, sizingRect.top+minTrack.y );
533 mouseRect.bottom = min( mouseRect.bottom, sizingRect.top+maxTrack.y );
534 }
535 if (Style & WS_CHILD)
536 {
537 MapWindowPoints( hWndParent, 0, (LPPOINT)&mouseRect, 2 );
538 }
539
540 SendMessageA( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
541 NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE, hwnd);
542 if (GetCapture() != hwnd) SetCapture( hwnd );
543
544 if (Style & WS_CHILD)
545 {
546 /* Retrieve a default cache DC (without using the window style) */
547 hdc = GetDCEx(hWndParent, 0, DCX_CACHE);
548 DesktopRgn = NULL;
549 }
550 else
551 {
552 hdc = GetDC( 0 );
553 DesktopRgn = CreateRectRgnIndirect(&clipRect);
554 }
555
556 SelectObject(hdc, DesktopRgn);
557
558 if( iconic ) /* create a cursor for dragging */
559 {
560 HICON hIcon = (HICON)GetClassLongW(hwnd, GCL_HICON);
561 if(!hIcon) hIcon = (HICON)SendMessageW( hwnd, WM_QUERYDRAGICON, 0, 0L);
562 if( hIcon ) hDragCursor = CursorIconToCursor( hIcon, TRUE );
563 if( !hDragCursor ) iconic = FALSE;
564 }
565
566 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
567 if( !iconic && !DragFullWindows)
568 {
569 UserDrawMovingFrame( hdc, &sizingRect, thickframe);
570 }
571
572 for(;;)
573 {
574 int dx = 0, dy = 0;
575
576 if (GetMessageW(&msg, 0, 0, 0) <= 0)
577 break;
578
579 /* Exit on button-up, Return, or Esc */
580 if ((msg.message == WM_LBUTTONUP) ||
581 ((msg.message == WM_KEYDOWN) &&
582 ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
583
584 if (msg.message == WM_PAINT)
585 {
586 if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
587 UpdateWindow( msg.hwnd );
588 if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
589 continue;
590 }
591
592 if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
593 continue; /* We are not interested in other messages */
594
595 pt = msg.pt;
596
597 if (msg.message == WM_KEYDOWN) switch(msg.wParam)
598 {
599 case VK_UP: pt.y -= 8; break;
600 case VK_DOWN: pt.y += 8; break;
601 case VK_LEFT: pt.x -= 8; break;
602 case VK_RIGHT: pt.x += 8; break;
603 }
604
605 pt.x = max( pt.x, mouseRect.left );
606 pt.x = min( pt.x, mouseRect.right );
607 pt.y = max( pt.y, mouseRect.top );
608 pt.y = min( pt.y, mouseRect.bottom );
609
610 dx = pt.x - capturePoint.x;
611 dy = pt.y - capturePoint.y;
612
613 if (dx || dy)
614 {
615 if( !moved )
616 {
617 moved = TRUE;
618
619 if( iconic ) /* ok, no system popup tracking */
620 {
621 hOldCursor = SetCursor(hDragCursor);
622 ShowCursor( TRUE );
623 }
624 }
625
626 if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
627 else
628 {
629 RECT newRect = unmodRect;
630 WPARAM wpSizingHit = 0;
631
632 if (hittest == HTCAPTION) OffsetRect( &newRect, dx, dy );
633 if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
634 else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
635 if (ON_TOP_BORDER(hittest)) newRect.top += dy;
636 else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
637 if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
638 capturePoint = pt;
639
640 /* determine the hit location */
641 if (hittest >= HTLEFT && hittest <= HTBOTTOMRIGHT)
642 wpSizingHit = WMSZ_LEFT + (hittest - HTLEFT);
643 unmodRect = newRect;
644 SendMessageA( hwnd, WM_SIZING, wpSizingHit, (LPARAM)&newRect );
645
646 if (!iconic)
647 {
648 if(!DragFullWindows)
649 UserDrawMovingFrame( hdc, &newRect, thickframe );
650 else {
651 /* To avoid any deadlocks, all the locks on the windows
652 structures must be suspended before the SetWindowPos */
653 SetWindowPos( hwnd, 0, newRect.left, newRect.top,
654 newRect.right - newRect.left,
655 newRect.bottom - newRect.top,
656 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
657 }
658 }
659 sizingRect = newRect;
660 }
661 }
662 }
663
664 ReleaseCapture();
665 ClipCursor(NULL);
666 if( iconic )
667 {
668 if( moved ) /* restore cursors, show icon title later on */
669 {
670 ShowCursor( FALSE );
671 SetCursor( hOldCursor );
672 }
673 DestroyCursor( hDragCursor );
674 }
675 else if(!DragFullWindows)
676 UserDrawMovingFrame( hdc, &sizingRect, thickframe );
677
678 if (Style & WS_CHILD)
679 ReleaseDC( hWndParent, hdc );
680 else
681 {
682 ReleaseDC( 0, hdc );
683 if(DesktopRgn)
684 {
685 DeleteObject(DesktopRgn);
686 }
687 }
688 NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE, NULL);
689 SendMessageA( hwnd, WM_EXITSIZEMOVE, 0, 0 );
690 SendMessageA( hwnd, WM_SETVISIBLE, !IsIconic(hwnd), 0L);
691
692 /* window moved or resized */
693 if (moved)
694 {
695 /* if the moving/resizing isn't canceled call SetWindowPos
696 * with the new position or the new size of the window
697 */
698 if (!((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
699 {
700 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
701 if(!DragFullWindows)
702 SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top,
703 sizingRect.right - sizingRect.left,
704 sizingRect.bottom - sizingRect.top,
705 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
706 }
707 else { /* restore previous size/position */
708 if(DragFullWindows)
709 SetWindowPos( hwnd, 0, origRect.left, origRect.top,
710 origRect.right - origRect.left,
711 origRect.bottom - origRect.top,
712 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
713 }
714 }
715
716 if( IsWindow(hwnd) )
717 if( Style & WS_MINIMIZE )
718 {
719 /* Single click brings up the system menu when iconized */
720
721 if( !moved )
722 {
723 if( Style & WS_SYSMENU )
724 SendMessageA( hwnd, WM_SYSCOMMAND,
725 SC_MOUSEMENU + HTSYSMENU, MAKELONG(pt.x,pt.y));
726 }
727 }
728 }
729
730
731 /***********************************************************************
732 * DefWndTrackScrollBar
733 *
734 * Track a mouse button press on the horizontal or vertical scroll-bar.
735 */
736 STATIC VOID
737 DefWndTrackScrollBar(HWND Wnd, WPARAM wParam, POINT Pt)
738 {
739 INT ScrollBar;
740
741 if (SC_HSCROLL == (wParam & 0xfff0))
742 {
743 if (HTHSCROLL != (wParam & 0x0f))
744 {
745 return;
746 }
747 ScrollBar = SB_HORZ;
748 }
749 else /* SC_VSCROLL */
750 {
751 if (HTVSCROLL != (wParam & 0x0f))
752 {
753 return;
754 }
755 ScrollBar = SB_VERT;
756 }
757 ScrollTrackScrollBar(Wnd, ScrollBar, Pt );
758 }
759
760
761 LRESULT
762 DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, POINT Pt)
763 {
764 WINDOWPLACEMENT wp;
765
766 switch (wParam & 0xfff0)
767 {
768 case SC_MOVE:
769 case SC_SIZE:
770 DefWndDoSizeMove(hWnd, wParam);
771 break;
772 case SC_MINIMIZE:
773 wp.length = sizeof(WINDOWPLACEMENT);
774 if(GetWindowPlacement(hWnd, &wp))
775 {
776 wp.showCmd = SW_MINIMIZE;
777 SetWindowPlacement(hWnd, &wp);
778 }
779 break;
780 case SC_MAXIMIZE:
781 wp.length = sizeof(WINDOWPLACEMENT);
782 if(GetWindowPlacement(hWnd, &wp))
783 {
784 wp.showCmd = SW_MAXIMIZE;
785 SetWindowPlacement(hWnd, &wp);
786 }
787 break;
788 case SC_RESTORE:
789 wp.length = sizeof(WINDOWPLACEMENT);
790 if(GetWindowPlacement(hWnd, &wp))
791 {
792 wp.showCmd = SW_RESTORE;
793 SetWindowPlacement(hWnd, &wp);
794 }
795 break;
796 case SC_CLOSE:
797 SendMessageA(hWnd, WM_CLOSE, 0, 0);
798 break;
799 case SC_MOUSEMENU:
800 MenuTrackMouseMenuBar(hWnd, wParam & 0x000f, Pt);
801 break;
802 case SC_KEYMENU:
803 MenuTrackKbdMenuBar(hWnd, wParam, Pt.x);
804 break;
805 case SC_VSCROLL:
806 case SC_HSCROLL:
807 DefWndTrackScrollBar(hWnd, wParam, Pt);
808 break;
809
810 default:
811 /* FIXME: Implement */
812 UNIMPLEMENTED;
813 break;
814 }
815
816 return(0);
817 }
818
819 LRESULT
820 DefWndHandleWindowPosChanging(HWND hWnd, WINDOWPOS* Pos)
821 {
822 POINT maxSize, minTrack;
823 LONG style = GetWindowLongA(hWnd, GWL_STYLE);
824
825 if (Pos->flags & SWP_NOSIZE) return 0;
826 if ((style & WS_THICKFRAME) || ((style & (WS_POPUP | WS_CHILD)) == 0))
827 {
828 WinPosGetMinMaxInfo(hWnd, &maxSize, NULL, &minTrack, NULL);
829 Pos->cx = min(Pos->cx, maxSize.x);
830 Pos->cy = min(Pos->cy, maxSize.y);
831 if (!(style & WS_MINIMIZE))
832 {
833 if (Pos->cx < minTrack.x) Pos->cx = minTrack.x;
834 if (Pos->cy < minTrack.y) Pos->cy = minTrack.y;
835 }
836 }
837 else
838 {
839 Pos->cx = max(Pos->cx, 0);
840 Pos->cy = max(Pos->cy, 0);
841 }
842 return 0;
843 }
844
845 /* Undocumented flags. */
846 #define SWP_NOCLIENTMOVE 0x0800
847 #define SWP_NOCLIENTSIZE 0x1000
848
849 LRESULT
850 DefWndHandleWindowPosChanged(HWND hWnd, WINDOWPOS* Pos)
851 {
852 RECT Rect;
853
854 GetClientRect(hWnd, &Rect);
855 MapWindowPoints(hWnd, (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD ?
856 GetParent(hWnd) : NULL), (LPPOINT) &Rect, 2);
857
858 if (! (Pos->flags & SWP_NOCLIENTMOVE))
859 {
860 SendMessageW(hWnd, WM_MOVE, 0, MAKELONG(Rect.left, Rect.top));
861 }
862
863 if (! (Pos->flags & SWP_NOCLIENTSIZE))
864 {
865 WPARAM wp = SIZE_RESTORED;
866 if (IsZoomed(hWnd))
867 {
868 wp = SIZE_MAXIMIZED;
869 }
870 else if (IsIconic(hWnd))
871 {
872 wp = SIZE_MINIMIZED;
873 }
874 SendMessageW(hWnd, WM_SIZE, wp,
875 MAKELONG(Rect.right - Rect.left, Rect.bottom - Rect.top));
876 }
877
878 return 0;
879 }
880
881 /***********************************************************************
882 * DefWndControlColor
883 *
884 * Default colors for control painting.
885 */
886 HBRUSH
887 DefWndControlColor(HDC hDC, UINT ctlType)
888 {
889 if (CTLCOLOR_SCROLLBAR == ctlType)
890 {
891 HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR);
892 COLORREF bk = GetSysColor(COLOR_3DHILIGHT);
893 SetTextColor(hDC, GetSysColor(COLOR_3DFACE));
894 SetBkColor(hDC, bk);
895
896 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
897 * we better use 0x55aa bitmap brush to make scrollbar's background
898 * look different from the window background.
899 */
900 if (bk == GetSysColor(COLOR_WINDOW))
901 {
902 static const WORD wPattern55AA[] =
903 {
904 0x5555, 0xaaaa, 0x5555, 0xaaaa,
905 0x5555, 0xaaaa, 0x5555, 0xaaaa
906 };
907 static HBITMAP hPattern55AABitmap = NULL;
908 static HBRUSH hPattern55AABrush = NULL;
909 if (hPattern55AABrush == NULL)
910 {
911 hPattern55AABitmap = CreateBitmap(8, 8, 1, 1, wPattern55AA);
912 hPattern55AABrush = CreatePatternBrush(hPattern55AABitmap);
913 }
914 return hPattern55AABrush;
915 }
916 UnrealizeObject(hb);
917 return hb;
918 }
919
920 SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
921
922 if ((CTLCOLOR_EDIT == ctlType) || (CTLCOLOR_LISTBOX == ctlType))
923 {
924 SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
925 }
926 else
927 {
928 SetBkColor(hDC, GetSysColor(COLOR_3DFACE));
929 return GetSysColorBrush(COLOR_3DFACE);
930 }
931
932 return GetSysColorBrush(COLOR_WINDOW);
933 }
934
935 VOID FASTCALL
936 DefWndScreenshot(HWND hWnd)
937 {
938
939 }
940
941 LRESULT STDCALL
942 User32DefWindowProc(HWND hWnd,
943 UINT Msg,
944 WPARAM wParam,
945 LPARAM lParam,
946 BOOL bUnicode)
947 {
948 switch (Msg)
949 {
950 case WM_NCPAINT:
951 {
952 return DefWndNCPaint(hWnd, (HRGN)wParam, -1);
953 }
954
955 case WM_NCCALCSIZE:
956 {
957 return DefWndNCCalcSize(hWnd, (BOOL)wParam, (RECT*)lParam);
958 }
959
960 case WM_NCACTIVATE:
961 {
962 return DefWndNCActivate(hWnd, wParam);
963 }
964
965 case WM_NCHITTEST:
966 {
967 POINT Point;
968 Point.x = GET_X_LPARAM(lParam);
969 Point.y = GET_Y_LPARAM(lParam);
970 return (DefWndNCHitTest(hWnd, Point));
971 }
972
973 case WM_NCLBUTTONDOWN:
974 {
975 return (DefWndNCLButtonDown(hWnd, wParam, lParam));
976 }
977
978 case WM_NCLBUTTONDBLCLK:
979 {
980 return (DefWndNCLButtonDblClk(hWnd, wParam, lParam));
981 }
982
983 case WM_WINDOWPOSCHANGING:
984 {
985 return (DefWndHandleWindowPosChanging(hWnd, (WINDOWPOS*)lParam));
986 }
987
988 case WM_WINDOWPOSCHANGED:
989 {
990 return (DefWndHandleWindowPosChanged(hWnd, (WINDOWPOS*)lParam));
991 }
992
993 case WM_RBUTTONUP:
994 {
995 POINT Pt;
996 if (hWnd == GetCapture())
997 {
998 ReleaseCapture();
999 }
1000 Pt.x = GET_X_LPARAM(lParam);
1001 Pt.y = GET_Y_LPARAM(lParam);
1002 ClientToScreen(hWnd, &Pt);
1003 lParam = MAKELPARAM(Pt.x, Pt.y);
1004 if (bUnicode)
1005 {
1006 SendMessageW(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
1007 }
1008 else
1009 {
1010 SendMessageA(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
1011 }
1012 break;
1013 }
1014
1015 case WM_CONTEXTMENU:
1016 {
1017 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD)
1018 {
1019 if (bUnicode)
1020 {
1021 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
1022 }
1023 else
1024 {
1025 SendMessageA(GetParent(hWnd), WM_CONTEXTMENU, wParam, lParam);
1026 }
1027 }
1028 else
1029 {
1030 POINT Pt;
1031 DWORD Style;
1032 LONG HitCode;
1033
1034 Style = GetWindowLongW(hWnd, GWL_STYLE);
1035
1036 Pt.x = GET_X_LPARAM(lParam);
1037 Pt.y = GET_Y_LPARAM(lParam);
1038 if (Style & WS_CHILD)
1039 {
1040 ScreenToClient(GetParent(hWnd), &Pt);
1041 }
1042
1043 HitCode = DefWndNCHitTest(hWnd, Pt);
1044
1045 if (HitCode == HTCAPTION || HitCode == HTSYSMENU)
1046 {
1047 HMENU SystemMenu;
1048 UINT Flags;
1049
1050 if((SystemMenu = GetSystemMenu(hWnd, FALSE)))
1051 {
1052 MenuInitSysMenuPopup(SystemMenu, GetWindowLongW(hWnd, GWL_STYLE),
1053 GetClassLongW(hWnd, GCL_STYLE), HitCode);
1054
1055 if(HitCode == HTCAPTION)
1056 Flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON;
1057 else
1058 Flags = TPM_LEFTBUTTON;
1059
1060 TrackPopupMenu(SystemMenu, Flags,
1061 Pt.x, Pt.y, 0, hWnd, NULL);
1062 }
1063 }
1064 }
1065 break;
1066 }
1067
1068 case WM_PRINT:
1069 {
1070 /* FIXME: Implement. */
1071 return (0);
1072 }
1073
1074 case WM_PAINTICON:
1075 case WM_PAINT:
1076 {
1077 PAINTSTRUCT Ps;
1078 HDC hDC = BeginPaint(hWnd, &Ps);
1079 if (hDC)
1080 {
1081 HICON hIcon;
1082 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE &&
1083 (hIcon = (HICON)GetClassLongW(hWnd, GCL_HICON)) != NULL)
1084 {
1085 RECT ClientRect;
1086 INT x, y;
1087 GetClientRect(hWnd, &ClientRect);
1088 x = (ClientRect.right - ClientRect.left -
1089 GetSystemMetrics(SM_CXICON)) / 2;
1090 y = (ClientRect.bottom - ClientRect.top -
1091 GetSystemMetrics(SM_CYICON)) / 2;
1092 DrawIcon(hDC, x, y, hIcon);
1093 }
1094 EndPaint(hWnd, &Ps);
1095 }
1096 return (0);
1097 }
1098
1099 case WM_SYNCPAINT:
1100 {
1101 HRGN hRgn;
1102 hRgn = CreateRectRgn(0, 0, 0, 0);
1103 if (GetUpdateRgn(hWnd, hRgn, FALSE) != NULLREGION)
1104 {
1105 RedrawWindow(hWnd, NULL, hRgn,
1106 RDW_ERASENOW | RDW_ERASE | RDW_FRAME |
1107 RDW_ALLCHILDREN);
1108 }
1109 DeleteObject(hRgn);
1110 return (0);
1111 }
1112
1113 case WM_SETREDRAW:
1114 {
1115 DefWndSetRedraw(hWnd, wParam);
1116 return (0);
1117 }
1118
1119 case WM_CLOSE:
1120 {
1121 DestroyWindow(hWnd);
1122 return (0);
1123 }
1124
1125 case WM_MOUSEACTIVATE:
1126 {
1127 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD)
1128 {
1129 LONG Ret;
1130 if (bUnicode)
1131 {
1132 Ret = SendMessageW(GetParent(hWnd), WM_MOUSEACTIVATE,
1133 wParam, lParam);
1134 }
1135 else
1136 {
1137 Ret = SendMessageA(GetParent(hWnd), WM_MOUSEACTIVATE,
1138 wParam, lParam);
1139 }
1140 if (Ret)
1141 {
1142 return (Ret);
1143 }
1144 }
1145 return ((LOWORD(lParam) >= HTCLIENT) ? MA_ACTIVATE : MA_NOACTIVATE);
1146 }
1147
1148 case WM_ACTIVATE:
1149 {
1150 /* Check if the window is minimized. */
1151 if (LOWORD(wParam) != WA_INACTIVE &&
1152 !(GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE))
1153 {
1154 SetFocus(hWnd);
1155 }
1156 break;
1157 }
1158
1159 case WM_MOUSEWHEEL:
1160 {
1161 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD)
1162 {
1163 if (bUnicode)
1164 {
1165 return (SendMessageW(GetParent(hWnd), WM_MOUSEWHEEL,
1166 wParam, lParam));
1167 }
1168 else
1169 {
1170 return (SendMessageA(GetParent(hWnd), WM_MOUSEWHEEL,
1171 wParam, lParam));
1172 }
1173 }
1174 break;
1175 }
1176
1177 case WM_ERASEBKGND:
1178 case WM_ICONERASEBKGND:
1179 {
1180 RECT Rect;
1181 HBRUSH hBrush = (HBRUSH)GetClassLongW(hWnd, GCL_HBRBACKGROUND);
1182
1183 if (NULL == hBrush)
1184 {
1185 return 0;
1186 }
1187 if (GetClassLongW(hWnd, GCL_STYLE) & CS_PARENTDC)
1188 {
1189 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1190 GetClientRect(hWnd, &Rect);
1191 DPtoLP((HDC)wParam, (LPPOINT)&Rect, 2);
1192 }
1193 else
1194 {
1195 GetClipBox((HDC)wParam, &Rect);
1196 }
1197 FillRect((HDC)wParam, &Rect, hBrush);
1198 return (1);
1199 }
1200
1201 case WM_CTLCOLORMSGBOX:
1202 case WM_CTLCOLOREDIT:
1203 case WM_CTLCOLORLISTBOX:
1204 case WM_CTLCOLORBTN:
1205 case WM_CTLCOLORDLG:
1206 case WM_CTLCOLORSTATIC:
1207 case WM_CTLCOLORSCROLLBAR:
1208 return (LRESULT) DefWndControlColor((HDC)wParam, Msg - WM_CTLCOLORMSGBOX);
1209
1210 case WM_SETCURSOR:
1211 {
1212 ULONG Style = GetWindowLongW(hWnd, GWL_STYLE);
1213
1214 if (Style & WS_CHILD)
1215 {
1216 if (LOWORD(lParam) < HTLEFT || LOWORD(lParam) > HTBOTTOMRIGHT)
1217 {
1218 BOOL bResult;
1219 if (bUnicode)
1220 {
1221 bResult = SendMessageW(GetParent(hWnd), WM_SETCURSOR,
1222 wParam, lParam);
1223 }
1224 else
1225 {
1226 bResult = SendMessageA(GetParent(hWnd), WM_SETCURSOR,
1227 wParam, lParam);
1228 }
1229 if (bResult)
1230 {
1231 return(TRUE);
1232 }
1233 }
1234 }
1235 return (DefWndHandleSetCursor(hWnd, wParam, lParam, Style));
1236 }
1237
1238 case WM_SYSCOMMAND:
1239 {
1240 POINT Pt;
1241 Pt.x = GET_X_LPARAM(lParam);
1242 Pt.y = GET_Y_LPARAM(lParam);
1243 return (DefWndHandleSysCommand(hWnd, wParam, Pt));
1244 }
1245
1246 /* FIXME: Handle key messages. */
1247 /*
1248 case WM_KEYDOWN:
1249 case WM_KEYUP:
1250 case WM_SYSKEYUP:
1251 case WM_SYSCHAR:
1252 */
1253
1254 /* FIXME: This is also incomplete. */
1255 case WM_SYSKEYDOWN:
1256 {
1257 if (HIWORD(lParam) & KEYDATA_ALT)
1258 {
1259 if (wParam == VK_F4) /* Try to close the window */
1260 {
1261 HWND top = GetAncestor(hWnd, GA_ROOT);
1262 if (!(GetClassLongW(top, GCL_STYLE) & CS_NOCLOSE))
1263 {
1264 if (bUnicode)
1265 PostMessageW(top, WM_SYSCOMMAND, SC_CLOSE, 0);
1266 else
1267 PostMessageA(top, WM_SYSCOMMAND, SC_CLOSE, 0);
1268 }
1269 }
1270 else if (wParam == VK_SNAPSHOT)
1271 {
1272 DefWndScreenshot(hWnd);
1273 }
1274 }
1275 break;
1276 }
1277
1278 case WM_SHOWWINDOW:
1279 {
1280 LONG Style;
1281
1282 if (!lParam)
1283 return 0;
1284 Style = GetWindowLongW(hWnd, GWL_STYLE);
1285 if (!(Style & WS_POPUP))
1286 return 0;
1287 if ((Style & WS_VISIBLE) && wParam)
1288 return 0;
1289 if (!(Style & WS_VISIBLE) && !wParam)
1290 return 0;
1291 if (!GetWindow(hWnd, GW_OWNER))
1292 return 0;
1293 ShowWindow(hWnd, wParam ? SW_SHOWNA : SW_HIDE);
1294 break;
1295 }
1296
1297 case WM_CANCELMODE:
1298 {
1299 /* FIXME: Check for a desktop. */
1300 if (GetCapture() == hWnd)
1301 {
1302 ReleaseCapture();
1303 }
1304 break;
1305 }
1306
1307 case WM_VKEYTOITEM:
1308 case WM_CHARTOITEM:
1309 return (-1);
1310 /*
1311 case WM_DROPOBJECT:
1312
1313 break;
1314 */
1315 case WM_QUERYDROPOBJECT:
1316 {
1317 if (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_ACCEPTFILES)
1318 {
1319 return(1);
1320 }
1321 break;
1322 }
1323
1324 case WM_QUERYDRAGICON:
1325 {
1326 UINT Len;
1327 HICON hIcon;
1328
1329 hIcon = (HICON)GetClassLongW(hWnd, GCL_HICON);
1330 if (hIcon)
1331 {
1332 return ((LRESULT)hIcon);
1333 }
1334 for (Len = 1; Len < 64; Len++)
1335 {
1336 if ((hIcon = LoadIconW(NULL, MAKEINTRESOURCEW(Len))) != NULL)
1337 {
1338 return((LRESULT)hIcon);
1339 }
1340 }
1341 return ((LRESULT)LoadIconW(0, IDI_APPLICATION));
1342 }
1343
1344 /* FIXME: WM_ISACTIVEICON */
1345
1346 case WM_NOTIFYFORMAT:
1347 {
1348 if (IsWindowUnicode(hWnd))
1349 {
1350 return(NFR_UNICODE);
1351 }
1352 else
1353 {
1354 return(NFR_ANSI);
1355 }
1356 }
1357
1358 case WM_SETICON:
1359 {
1360 INT Index = (wParam != 0) ? GCL_HICON : GCL_HICONSM;
1361 HICON hOldIcon = (HICON)GetClassLongW(hWnd, Index);
1362 SetClassLongW(hWnd, Index, lParam);
1363 SetWindowPos(hWnd, 0, 0, 0, 0, 0,
1364 SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
1365 SWP_NOACTIVATE | SWP_NOZORDER);
1366 return ((LRESULT)hOldIcon);
1367 }
1368
1369 case WM_GETICON:
1370 {
1371 INT Index = (wParam == ICON_BIG) ? GCL_HICON : GCL_HICONSM;
1372 return (GetClassLongW(hWnd, Index));
1373 }
1374
1375 case WM_HELP:
1376 {
1377 if (bUnicode)
1378 {
1379 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
1380 }
1381 else
1382 {
1383 SendMessageA(GetParent(hWnd), Msg, wParam, lParam);
1384 }
1385 break;
1386 }
1387
1388 case WM_SYSTIMER:
1389 {
1390 THRDCARETINFO CaretInfo;
1391 switch(wParam)
1392 {
1393 case 0xffff: /* Caret timer */
1394 /* switch showing byte in win32k and get information about the caret */
1395 if(NtUserSwitchCaretShowing(&CaretInfo) && (CaretInfo.hWnd == hWnd))
1396 {
1397 DrawCaret(hWnd, &CaretInfo);
1398 }
1399 break;
1400 }
1401 break;
1402 }
1403
1404 case WM_QUERYOPEN:
1405 case WM_QUERYENDSESSION:
1406 {
1407 return (1);
1408 }
1409 }
1410 return 0;
1411 }
1412
1413
1414 LRESULT STDCALL
1415 DefWindowProcA(HWND hWnd,
1416 UINT Msg,
1417 WPARAM wParam,
1418 LPARAM lParam)
1419 {
1420 switch (Msg)
1421 {
1422 case WM_NCCREATE:
1423 {
1424 return TRUE;
1425 }
1426
1427 case WM_GETTEXTLENGTH:
1428 {
1429 return (LRESULT)NtUserInternalGetWindowText(hWnd, NULL, 0);
1430 }
1431
1432 case WM_GETTEXT:
1433 {
1434 LPWSTR Buffer;
1435 LPSTR AnsiBuffer = (LPSTR)lParam;
1436 INT Length;
1437
1438 if (wParam > 1)
1439 {
1440 *((PWSTR)lParam) = '\0';
1441 }
1442 Buffer = HeapAlloc(GetProcessHeap(), 0, wParam * sizeof(WCHAR));
1443 if (!Buffer)
1444 return FALSE;
1445 Length = NtUserInternalGetWindowText(hWnd, Buffer, wParam);
1446 if (Length > 0 && wParam > 0 &&
1447 !WideCharToMultiByte(CP_ACP, 0, Buffer, -1,
1448 AnsiBuffer, wParam, NULL, NULL))
1449 {
1450 AnsiBuffer[0] = '\0';
1451 }
1452
1453 HeapFree(GetProcessHeap(), 0, Buffer);
1454
1455 return (LRESULT)Length;
1456 }
1457
1458 case WM_SETTEXT:
1459 {
1460 ANSI_STRING AnsiString;
1461 UNICODE_STRING UnicodeString;
1462
1463 if(lParam)
1464 {
1465 RtlInitAnsiString(&AnsiString, (LPSTR)lParam);
1466 RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
1467 NtUserDefSetText(hWnd, &UnicodeString);
1468 RtlFreeUnicodeString(&UnicodeString);
1469 }
1470 else
1471 NtUserDefSetText(hWnd, NULL);
1472
1473 if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1474 {
1475 DefWndNCPaint(hWnd, (HRGN)1, -1);
1476 }
1477 return TRUE;
1478 }
1479
1480 /*
1481 FIXME: Implement these.
1482 case WM_IME_CHAR:
1483 case WM_IME_KEYDOWN:
1484 case WM_IME_KEYUP:
1485 case WM_IME_STARTCOMPOSITION:
1486 case WM_IME_COMPOSITION:
1487 case WM_IME_ENDCOMPOSITION:
1488 case WM_IME_SELECT:
1489 case WM_IME_SETCONTEXT:
1490 */
1491 }
1492
1493 return User32DefWindowProc(hWnd, Msg, wParam, lParam, FALSE);
1494 }
1495
1496
1497 LRESULT STDCALL
1498 DefWindowProcW(HWND hWnd,
1499 UINT Msg,
1500 WPARAM wParam,
1501 LPARAM lParam)
1502 {
1503 switch (Msg)
1504 {
1505 case WM_NCCREATE:
1506 {
1507 return TRUE;
1508 }
1509
1510 case WM_GETTEXTLENGTH:
1511 {
1512 return (LRESULT)NtUserInternalGetWindowText(hWnd, NULL, 0);
1513 }
1514
1515 case WM_GETTEXT:
1516 {
1517 if (wParam > 1)
1518 {
1519 *((PWSTR)lParam) = L'\0';
1520 }
1521 return (LRESULT)NtUserInternalGetWindowText(hWnd, (PWSTR)lParam, wParam);
1522 }
1523
1524 case WM_SETTEXT:
1525 {
1526 UNICODE_STRING UnicodeString;
1527
1528 if(lParam)
1529 RtlInitUnicodeString(&UnicodeString, (LPWSTR)lParam);
1530
1531 NtUserDefSetText(hWnd, (lParam ? &UnicodeString : NULL));
1532
1533 if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1534 {
1535 DefWndNCPaint(hWnd, (HRGN)1, -1);
1536 }
1537 return (1);
1538 }
1539
1540 case WM_IME_CHAR:
1541 {
1542 SendMessageW(hWnd, WM_CHAR, wParam, lParam);
1543 return (0);
1544 }
1545
1546 case WM_IME_SETCONTEXT:
1547 {
1548 /* FIXME */
1549 return (0);
1550 }
1551 }
1552
1553 return User32DefWindowProc(hWnd, Msg, wParam, lParam, TRUE);
1554 }
1555