70632b9095e9db403ae1130169c172c92c234023
[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 /* Get min/max info */
483
484 WinPosGetMinMaxInfo(hwnd, NULL, NULL, &minTrack, &maxTrack);
485 GetWindowRect(hwnd, &sizingRect);
486 if (Style & WS_CHILD)
487 {
488 hWndParent = GetParent(hwnd);
489 MapWindowPoints( 0, hWndParent, (LPPOINT)&sizingRect, 2 );
490 unmodRect = sizingRect;
491 GetClientRect(hWndParent, &mouseRect );
492 clipRect = mouseRect;
493 MapWindowPoints(hWndParent, HWND_DESKTOP, (LPPOINT)&clipRect, 2);
494 }
495 else
496 {
497 if(!(ExStyle & WS_EX_TOPMOST))
498 {
499 SystemParametersInfoW(SPI_GETWORKAREA, 0, &clipRect, 0);
500 mouseRect = clipRect;
501 }
502 else
503 {
504 SetRect(&mouseRect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
505 clipRect = mouseRect;
506 }
507 unmodRect = sizingRect;
508 }
509 ClipCursor(&clipRect);
510
511 origRect = sizingRect;
512 if (ON_LEFT_BORDER(hittest))
513 {
514 mouseRect.left = max( mouseRect.left, sizingRect.right-maxTrack.x );
515 mouseRect.right = min( mouseRect.right, sizingRect.right-minTrack.x );
516 }
517 else if (ON_RIGHT_BORDER(hittest))
518 {
519 mouseRect.left = max( mouseRect.left, sizingRect.left+minTrack.x );
520 mouseRect.right = min( mouseRect.right, sizingRect.left+maxTrack.x );
521 }
522 if (ON_TOP_BORDER(hittest))
523 {
524 mouseRect.top = max( mouseRect.top, sizingRect.bottom-maxTrack.y );
525 mouseRect.bottom = min( mouseRect.bottom,sizingRect.bottom-minTrack.y);
526 }
527 else if (ON_BOTTOM_BORDER(hittest))
528 {
529 mouseRect.top = max( mouseRect.top, sizingRect.top+minTrack.y );
530 mouseRect.bottom = min( mouseRect.bottom, sizingRect.top+maxTrack.y );
531 }
532 if (Style & WS_CHILD)
533 {
534 MapWindowPoints( hWndParent, 0, (LPPOINT)&mouseRect, 2 );
535 }
536
537 SendMessageA( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
538 NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE, hwnd);
539 if (GetCapture() != hwnd) SetCapture( hwnd );
540
541 if (Style & WS_CHILD)
542 {
543 /* Retrieve a default cache DC (without using the window style) */
544 hdc = GetDCEx(hWndParent, 0, DCX_CACHE);
545 DesktopRgn = NULL;
546 }
547 else
548 {
549 hdc = GetDC( 0 );
550 DesktopRgn = CreateRectRgnIndirect(&clipRect);
551 }
552
553 SelectObject(hdc, DesktopRgn);
554
555 if( iconic ) /* create a cursor for dragging */
556 {
557 HICON hIcon = (HICON)GetClassLongW(hwnd, GCL_HICON);
558 if(!hIcon) hIcon = (HICON)SendMessageW( hwnd, WM_QUERYDRAGICON, 0, 0L);
559 if( hIcon ) hDragCursor = CursorIconToCursor( hIcon, TRUE );
560 if( !hDragCursor ) iconic = FALSE;
561 }
562
563 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
564 if( !iconic && !DragFullWindows)
565 {
566 UserDrawMovingFrame( hdc, &sizingRect, thickframe);
567 }
568
569 for(;;)
570 {
571 int dx = 0, dy = 0;
572
573 if (GetMessageW(&msg, 0, 0, 0) <= 0)
574 break;
575
576 /* Exit on button-up, Return, or Esc */
577 if ((msg.message == WM_LBUTTONUP) ||
578 ((msg.message == WM_KEYDOWN) &&
579 ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
580
581 if (msg.message == WM_PAINT)
582 {
583 if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
584 UpdateWindow( msg.hwnd );
585 if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
586 continue;
587 }
588
589 if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
590 continue; /* We are not interested in other messages */
591
592 pt = msg.pt;
593
594 if (msg.message == WM_KEYDOWN) switch(msg.wParam)
595 {
596 case VK_UP: pt.y -= 8; break;
597 case VK_DOWN: pt.y += 8; break;
598 case VK_LEFT: pt.x -= 8; break;
599 case VK_RIGHT: pt.x += 8; break;
600 }
601
602 pt.x = max( pt.x, mouseRect.left );
603 pt.x = min( pt.x, mouseRect.right );
604 pt.y = max( pt.y, mouseRect.top );
605 pt.y = min( pt.y, mouseRect.bottom );
606
607 dx = pt.x - capturePoint.x;
608 dy = pt.y - capturePoint.y;
609
610 if (dx || dy)
611 {
612 if( !moved )
613 {
614 moved = TRUE;
615
616 if( iconic ) /* ok, no system popup tracking */
617 {
618 hOldCursor = SetCursor(hDragCursor);
619 ShowCursor( TRUE );
620 }
621 }
622
623 if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
624 else
625 {
626 RECT newRect = unmodRect;
627 WPARAM wpSizingHit = 0;
628
629 if (hittest == HTCAPTION) OffsetRect( &newRect, dx, dy );
630 if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
631 else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
632 if (ON_TOP_BORDER(hittest)) newRect.top += dy;
633 else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
634 if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
635 capturePoint = pt;
636
637 /* determine the hit location */
638 if (hittest >= HTLEFT && hittest <= HTBOTTOMRIGHT)
639 wpSizingHit = WMSZ_LEFT + (hittest - HTLEFT);
640 unmodRect = newRect;
641 SendMessageA( hwnd, WM_SIZING, wpSizingHit, (LPARAM)&newRect );
642
643 if (!iconic)
644 {
645 if(!DragFullWindows)
646 UserDrawMovingFrame( hdc, &newRect, thickframe );
647 else {
648 /* To avoid any deadlocks, all the locks on the windows
649 structures must be suspended before the SetWindowPos */
650 SetWindowPos( hwnd, 0, newRect.left, newRect.top,
651 newRect.right - newRect.left,
652 newRect.bottom - newRect.top,
653 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
654 }
655 }
656 sizingRect = newRect;
657 }
658 }
659 }
660
661 ReleaseCapture();
662 ClipCursor(NULL);
663 if( iconic )
664 {
665 if( moved ) /* restore cursors, show icon title later on */
666 {
667 ShowCursor( FALSE );
668 SetCursor( hOldCursor );
669 }
670 DestroyCursor( hDragCursor );
671 }
672 else if(!DragFullWindows)
673 UserDrawMovingFrame( hdc, &sizingRect, thickframe );
674
675 if (Style & WS_CHILD)
676 ReleaseDC( hWndParent, hdc );
677 else
678 {
679 ReleaseDC( 0, hdc );
680 if(DesktopRgn)
681 {
682 DeleteObject(DesktopRgn);
683 }
684 }
685 NtUserSetGUIThreadHandle(MSQ_STATE_MOVESIZE, NULL);
686 SendMessageA( hwnd, WM_EXITSIZEMOVE, 0, 0 );
687 SendMessageA( hwnd, WM_SETVISIBLE, !IsIconic(hwnd), 0L);
688
689 /* window moved or resized */
690 if (moved)
691 {
692 /* if the moving/resizing isn't canceled call SetWindowPos
693 * with the new position or the new size of the window
694 */
695 if (!((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
696 {
697 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
698 if(!DragFullWindows)
699 SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top,
700 sizingRect.right - sizingRect.left,
701 sizingRect.bottom - sizingRect.top,
702 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
703 }
704 else { /* restore previous size/position */
705 if(DragFullWindows)
706 SetWindowPos( hwnd, 0, origRect.left, origRect.top,
707 origRect.right - origRect.left,
708 origRect.bottom - origRect.top,
709 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
710 }
711 }
712
713 if( IsWindow(hwnd) )
714 if( Style & WS_MINIMIZE )
715 {
716 /* Single click brings up the system menu when iconized */
717
718 if( !moved )
719 {
720 if( Style & WS_SYSMENU )
721 SendMessageA( hwnd, WM_SYSCOMMAND,
722 SC_MOUSEMENU + HTSYSMENU, MAKELONG(pt.x,pt.y));
723 }
724 }
725 }
726
727
728 /***********************************************************************
729 * DefWndTrackScrollBar
730 *
731 * Track a mouse button press on the horizontal or vertical scroll-bar.
732 */
733 STATIC VOID
734 DefWndTrackScrollBar(HWND Wnd, WPARAM wParam, POINT Pt)
735 {
736 INT ScrollBar;
737
738 if (SC_HSCROLL == (wParam & 0xfff0))
739 {
740 if (HTHSCROLL != (wParam & 0x0f))
741 {
742 return;
743 }
744 ScrollBar = SB_HORZ;
745 }
746 else /* SC_VSCROLL */
747 {
748 if (HTVSCROLL != (wParam & 0x0f))
749 {
750 return;
751 }
752 ScrollBar = SB_VERT;
753 }
754 ScrollTrackScrollBar(Wnd, ScrollBar, Pt );
755 }
756
757
758 LRESULT
759 DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, POINT Pt)
760 {
761 WINDOWPLACEMENT wp;
762
763 switch (wParam & 0xfff0)
764 {
765 case SC_MOVE:
766 case SC_SIZE:
767 DefWndDoSizeMove(hWnd, wParam);
768 break;
769 case SC_MINIMIZE:
770 wp.length = sizeof(WINDOWPLACEMENT);
771 if(GetWindowPlacement(hWnd, &wp))
772 {
773 wp.showCmd = SW_MINIMIZE;
774 SetWindowPlacement(hWnd, &wp);
775 }
776 break;
777 case SC_MAXIMIZE:
778 wp.length = sizeof(WINDOWPLACEMENT);
779 if(GetWindowPlacement(hWnd, &wp))
780 {
781 wp.showCmd = SW_MAXIMIZE;
782 SetWindowPlacement(hWnd, &wp);
783 }
784 break;
785 case SC_RESTORE:
786 wp.length = sizeof(WINDOWPLACEMENT);
787 if(GetWindowPlacement(hWnd, &wp))
788 {
789 wp.showCmd = SW_RESTORE;
790 SetWindowPlacement(hWnd, &wp);
791 }
792 break;
793 case SC_CLOSE:
794 SendMessageA(hWnd, WM_CLOSE, 0, 0);
795 break;
796 case SC_MOUSEMENU:
797 MenuTrackMouseMenuBar(hWnd, wParam & 0x000f, Pt);
798 break;
799 case SC_KEYMENU:
800 MenuTrackKbdMenuBar(hWnd, wParam, Pt.x);
801 break;
802 case SC_VSCROLL:
803 case SC_HSCROLL:
804 DefWndTrackScrollBar(hWnd, wParam, Pt);
805 break;
806
807 default:
808 /* FIXME: Implement */
809 UNIMPLEMENTED;
810 break;
811 }
812
813 return(0);
814 }
815
816 LRESULT
817 DefWndHandleWindowPosChanging(HWND hWnd, WINDOWPOS* Pos)
818 {
819 POINT maxSize, minTrack;
820 LONG style = GetWindowLongA(hWnd, GWL_STYLE);
821
822 if (Pos->flags & SWP_NOSIZE) return 0;
823 if ((style & WS_THICKFRAME) || ((style & (WS_POPUP | WS_CHILD)) == 0))
824 {
825 WinPosGetMinMaxInfo(hWnd, &maxSize, NULL, &minTrack, NULL);
826 Pos->cx = min(Pos->cx, maxSize.x);
827 Pos->cy = min(Pos->cy, maxSize.y);
828 if (!(style & WS_MINIMIZE))
829 {
830 if (Pos->cx < minTrack.x) Pos->cx = minTrack.x;
831 if (Pos->cy < minTrack.y) Pos->cy = minTrack.y;
832 }
833 }
834 else
835 {
836 Pos->cx = max(Pos->cx, 0);
837 Pos->cy = max(Pos->cy, 0);
838 }
839 return 0;
840 }
841
842 /* Undocumented flags. */
843 #define SWP_NOCLIENTMOVE 0x0800
844 #define SWP_NOCLIENTSIZE 0x1000
845
846 LRESULT
847 DefWndHandleWindowPosChanged(HWND hWnd, WINDOWPOS* Pos)
848 {
849 RECT Rect;
850
851 GetClientRect(hWnd, &Rect);
852 MapWindowPoints(hWnd, (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD ?
853 GetParent(hWnd) : NULL), (LPPOINT) &Rect, 2);
854
855 if (! (Pos->flags & SWP_NOCLIENTMOVE))
856 {
857 SendMessageW(hWnd, WM_MOVE, 0, MAKELONG(Rect.left, Rect.top));
858 }
859
860 if (! (Pos->flags & SWP_NOCLIENTSIZE))
861 {
862 WPARAM wp = SIZE_RESTORED;
863 if (IsZoomed(hWnd))
864 {
865 wp = SIZE_MAXIMIZED;
866 }
867 else if (IsIconic(hWnd))
868 {
869 wp = SIZE_MINIMIZED;
870 }
871 SendMessageW(hWnd, WM_SIZE, wp,
872 MAKELONG(Rect.right - Rect.left, Rect.bottom - Rect.top));
873 }
874
875 return 0;
876 }
877
878 /***********************************************************************
879 * DefWndControlColor
880 *
881 * Default colors for control painting.
882 */
883 HBRUSH
884 DefWndControlColor(HDC hDC, UINT ctlType)
885 {
886 if (CTLCOLOR_SCROLLBAR == ctlType)
887 {
888 HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR);
889 COLORREF bk = GetSysColor(COLOR_3DHILIGHT);
890 SetTextColor(hDC, GetSysColor(COLOR_3DFACE));
891 SetBkColor(hDC, bk);
892
893 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
894 * we better use 0x55aa bitmap brush to make scrollbar's background
895 * look different from the window background.
896 */
897 if (bk == GetSysColor(COLOR_WINDOW))
898 {
899 static const WORD wPattern55AA[] =
900 {
901 0x5555, 0xaaaa, 0x5555, 0xaaaa,
902 0x5555, 0xaaaa, 0x5555, 0xaaaa
903 };
904 static HBITMAP hPattern55AABitmap = NULL;
905 static HBRUSH hPattern55AABrush = NULL;
906 if (hPattern55AABrush == NULL)
907 {
908 hPattern55AABitmap = CreateBitmap(8, 8, 1, 1, wPattern55AA);
909 hPattern55AABrush = CreatePatternBrush(hPattern55AABitmap);
910 }
911 return hPattern55AABrush;
912 }
913 UnrealizeObject(hb);
914 return hb;
915 }
916
917 SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
918
919 if ((CTLCOLOR_EDIT == ctlType) || (CTLCOLOR_LISTBOX == ctlType))
920 {
921 SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
922 }
923 else
924 {
925 SetBkColor(hDC, GetSysColor(COLOR_3DFACE));
926 return GetSysColorBrush(COLOR_3DFACE);
927 }
928
929 return GetSysColorBrush(COLOR_WINDOW);
930 }
931
932 VOID FASTCALL
933 DefWndScreenshot(HWND hWnd)
934 {
935
936 }
937
938 LRESULT STDCALL
939 User32DefWindowProc(HWND hWnd,
940 UINT Msg,
941 WPARAM wParam,
942 LPARAM lParam,
943 BOOL bUnicode)
944 {
945 switch (Msg)
946 {
947 case WM_NCPAINT:
948 {
949 return DefWndNCPaint(hWnd, (HRGN)wParam, -1);
950 }
951
952 case WM_NCCALCSIZE:
953 {
954 return DefWndNCCalcSize(hWnd, (BOOL)wParam, (RECT*)lParam);
955 }
956
957 case WM_NCACTIVATE:
958 {
959 return DefWndNCActivate(hWnd, wParam);
960 }
961
962 case WM_NCHITTEST:
963 {
964 POINT Point;
965 Point.x = GET_X_LPARAM(lParam);
966 Point.y = GET_Y_LPARAM(lParam);
967 return (DefWndNCHitTest(hWnd, Point));
968 }
969
970 case WM_NCLBUTTONDOWN:
971 {
972 return (DefWndNCLButtonDown(hWnd, wParam, lParam));
973 }
974
975 case WM_NCLBUTTONDBLCLK:
976 {
977 return (DefWndNCLButtonDblClk(hWnd, wParam, lParam));
978 }
979
980 case WM_WINDOWPOSCHANGING:
981 {
982 return (DefWndHandleWindowPosChanging(hWnd, (WINDOWPOS*)lParam));
983 }
984
985 case WM_WINDOWPOSCHANGED:
986 {
987 return (DefWndHandleWindowPosChanged(hWnd, (WINDOWPOS*)lParam));
988 }
989
990 case WM_RBUTTONUP:
991 {
992 POINT Pt;
993 if (hWnd == GetCapture())
994 {
995 ReleaseCapture();
996 }
997 Pt.x = GET_X_LPARAM(lParam);
998 Pt.y = GET_Y_LPARAM(lParam);
999 ClientToScreen(hWnd, &Pt);
1000 lParam = MAKELPARAM(Pt.x, Pt.y);
1001 if (bUnicode)
1002 {
1003 SendMessageW(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
1004 }
1005 else
1006 {
1007 SendMessageA(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
1008 }
1009 break;
1010 }
1011
1012 case WM_CONTEXTMENU:
1013 {
1014 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD)
1015 {
1016 if (bUnicode)
1017 {
1018 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
1019 }
1020 else
1021 {
1022 SendMessageA(GetParent(hWnd), WM_CONTEXTMENU, wParam, lParam);
1023 }
1024 }
1025 else
1026 {
1027 POINT Pt;
1028 DWORD Style;
1029 LONG HitCode;
1030
1031 Style = GetWindowLongW(hWnd, GWL_STYLE);
1032
1033 Pt.x = GET_X_LPARAM(lParam);
1034 Pt.y = GET_Y_LPARAM(lParam);
1035 if (Style & WS_CHILD)
1036 {
1037 ScreenToClient(GetParent(hWnd), &Pt);
1038 }
1039
1040 HitCode = DefWndNCHitTest(hWnd, Pt);
1041
1042 if (HitCode == HTCAPTION || HitCode == HTSYSMENU)
1043 {
1044 HMENU SystemMenu;
1045 UINT Flags;
1046
1047 if((SystemMenu = GetSystemMenu(hWnd, FALSE)))
1048 {
1049 MenuInitSysMenuPopup(SystemMenu, GetWindowLongW(hWnd, GWL_STYLE),
1050 GetClassLongW(hWnd, GCL_STYLE), HitCode);
1051
1052 if(HitCode == HTCAPTION)
1053 Flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON;
1054 else
1055 Flags = TPM_LEFTBUTTON;
1056
1057 TrackPopupMenu(SystemMenu, Flags,
1058 Pt.x, Pt.y, 0, hWnd, NULL);
1059 }
1060 }
1061 }
1062 break;
1063 }
1064
1065 case WM_PRINT:
1066 {
1067 /* FIXME: Implement. */
1068 return (0);
1069 }
1070
1071 case WM_PAINTICON:
1072 case WM_PAINT:
1073 {
1074 PAINTSTRUCT Ps;
1075 HDC hDC = BeginPaint(hWnd, &Ps);
1076 if (hDC)
1077 {
1078 HICON hIcon;
1079 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE &&
1080 (hIcon = (HICON)GetClassLongW(hWnd, GCL_HICON)) != NULL)
1081 {
1082 RECT ClientRect;
1083 INT x, y;
1084 GetClientRect(hWnd, &ClientRect);
1085 x = (ClientRect.right - ClientRect.left -
1086 GetSystemMetrics(SM_CXICON)) / 2;
1087 y = (ClientRect.bottom - ClientRect.top -
1088 GetSystemMetrics(SM_CYICON)) / 2;
1089 DrawIcon(hDC, x, y, hIcon);
1090 }
1091 EndPaint(hWnd, &Ps);
1092 }
1093 return (0);
1094 }
1095
1096 case WM_SYNCPAINT:
1097 {
1098 HRGN hRgn;
1099 hRgn = CreateRectRgn(0, 0, 0, 0);
1100 if (GetUpdateRgn(hWnd, hRgn, FALSE) != NULLREGION)
1101 {
1102 RedrawWindow(hWnd, NULL, hRgn,
1103 RDW_ERASENOW | RDW_ERASE | RDW_FRAME |
1104 RDW_ALLCHILDREN);
1105 }
1106 DeleteObject(hRgn);
1107 return (0);
1108 }
1109
1110 case WM_SETREDRAW:
1111 {
1112 DefWndSetRedraw(hWnd, wParam);
1113 return (0);
1114 }
1115
1116 case WM_CLOSE:
1117 {
1118 DestroyWindow(hWnd);
1119 return (0);
1120 }
1121
1122 case WM_MOUSEACTIVATE:
1123 {
1124 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD)
1125 {
1126 LONG Ret;
1127 if (bUnicode)
1128 {
1129 Ret = SendMessageW(GetParent(hWnd), WM_MOUSEACTIVATE,
1130 wParam, lParam);
1131 }
1132 else
1133 {
1134 Ret = SendMessageA(GetParent(hWnd), WM_MOUSEACTIVATE,
1135 wParam, lParam);
1136 }
1137 if (Ret)
1138 {
1139 return (Ret);
1140 }
1141 }
1142 return ((LOWORD(lParam) >= HTCLIENT) ? MA_ACTIVATE : MA_NOACTIVATE);
1143 }
1144
1145 case WM_ACTIVATE:
1146 {
1147 /* Check if the window is minimized. */
1148 if (LOWORD(wParam) != WA_INACTIVE &&
1149 !(GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE))
1150 {
1151 SetFocus(hWnd);
1152 }
1153 break;
1154 }
1155
1156 case WM_MOUSEWHEEL:
1157 {
1158 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD)
1159 {
1160 if (bUnicode)
1161 {
1162 return (SendMessageW(GetParent(hWnd), WM_MOUSEWHEEL,
1163 wParam, lParam));
1164 }
1165 else
1166 {
1167 return (SendMessageA(GetParent(hWnd), WM_MOUSEWHEEL,
1168 wParam, lParam));
1169 }
1170 }
1171 break;
1172 }
1173
1174 case WM_ERASEBKGND:
1175 case WM_ICONERASEBKGND:
1176 {
1177 RECT Rect;
1178 HBRUSH hBrush = (HBRUSH)GetClassLongW(hWnd, GCL_HBRBACKGROUND);
1179
1180 if (NULL == hBrush)
1181 {
1182 return 0;
1183 }
1184 if (GetClassLongW(hWnd, GCL_STYLE) & CS_PARENTDC)
1185 {
1186 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1187 GetClientRect(hWnd, &Rect);
1188 DPtoLP((HDC)wParam, (LPPOINT)&Rect, 2);
1189 }
1190 else
1191 {
1192 GetClipBox((HDC)wParam, &Rect);
1193 }
1194 FillRect((HDC)wParam, &Rect, hBrush);
1195 return (1);
1196 }
1197
1198 case WM_CTLCOLORMSGBOX:
1199 case WM_CTLCOLOREDIT:
1200 case WM_CTLCOLORLISTBOX:
1201 case WM_CTLCOLORBTN:
1202 case WM_CTLCOLORDLG:
1203 case WM_CTLCOLORSTATIC:
1204 case WM_CTLCOLORSCROLLBAR:
1205 return (LRESULT) DefWndControlColor((HDC)wParam, Msg - WM_CTLCOLORMSGBOX);
1206
1207 case WM_SETCURSOR:
1208 {
1209 ULONG Style = GetWindowLongW(hWnd, GWL_STYLE);
1210
1211 if (Style & WS_CHILD)
1212 {
1213 if (LOWORD(lParam) < HTLEFT || LOWORD(lParam) > HTBOTTOMRIGHT)
1214 {
1215 BOOL bResult;
1216 if (bUnicode)
1217 {
1218 bResult = SendMessageW(GetParent(hWnd), WM_SETCURSOR,
1219 wParam, lParam);
1220 }
1221 else
1222 {
1223 bResult = SendMessageA(GetParent(hWnd), WM_SETCURSOR,
1224 wParam, lParam);
1225 }
1226 if (bResult)
1227 {
1228 return(TRUE);
1229 }
1230 }
1231 }
1232 return (DefWndHandleSetCursor(hWnd, wParam, lParam, Style));
1233 }
1234
1235 case WM_SYSCOMMAND:
1236 {
1237 POINT Pt;
1238 Pt.x = GET_X_LPARAM(lParam);
1239 Pt.y = GET_Y_LPARAM(lParam);
1240 return (DefWndHandleSysCommand(hWnd, wParam, Pt));
1241 }
1242
1243 /* FIXME: Handle key messages. */
1244 /*
1245 case WM_KEYDOWN:
1246 case WM_KEYUP:
1247 case WM_SYSKEYUP:
1248 case WM_SYSCHAR:
1249 */
1250
1251 /* FIXME: This is also incomplete. */
1252 case WM_SYSKEYDOWN:
1253 {
1254 if (HIWORD(lParam) & KEYDATA_ALT)
1255 {
1256 if (wParam == VK_F4) /* Try to close the window */
1257 {
1258 HWND top = GetAncestor(hWnd, GA_ROOT);
1259 if (!(GetClassLongW(top, GCL_STYLE) & CS_NOCLOSE))
1260 {
1261 if (bUnicode)
1262 PostMessageW(top, WM_SYSCOMMAND, SC_CLOSE, 0);
1263 else
1264 PostMessageA(top, WM_SYSCOMMAND, SC_CLOSE, 0);
1265 }
1266 }
1267 else if (wParam == VK_SNAPSHOT)
1268 {
1269 DefWndScreenshot(hWnd);
1270 }
1271 }
1272 break;
1273 }
1274
1275 case WM_SHOWWINDOW:
1276 {
1277 LONG Style;
1278
1279 if (!lParam)
1280 return 0;
1281 Style = GetWindowLongW(hWnd, GWL_STYLE);
1282 if (!(Style & WS_POPUP))
1283 return 0;
1284 if ((Style & WS_VISIBLE) && wParam)
1285 return 0;
1286 if (!(Style & WS_VISIBLE) && !wParam)
1287 return 0;
1288 if (!GetWindow(hWnd, GW_OWNER))
1289 return 0;
1290 ShowWindow(hWnd, wParam ? SW_SHOWNA : SW_HIDE);
1291 break;
1292 }
1293
1294 case WM_CANCELMODE:
1295 {
1296 /* FIXME: Check for a desktop. */
1297 if (GetCapture() == hWnd)
1298 {
1299 ReleaseCapture();
1300 }
1301 break;
1302 }
1303
1304 case WM_VKEYTOITEM:
1305 case WM_CHARTOITEM:
1306 return (-1);
1307 /*
1308 case WM_DROPOBJECT:
1309
1310 break;
1311 */
1312 case WM_QUERYDROPOBJECT:
1313 {
1314 if (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_ACCEPTFILES)
1315 {
1316 return(1);
1317 }
1318 break;
1319 }
1320
1321 case WM_QUERYDRAGICON:
1322 {
1323 UINT Len;
1324 HICON hIcon;
1325
1326 hIcon = (HICON)GetClassLongW(hWnd, GCL_HICON);
1327 if (hIcon)
1328 {
1329 return ((LRESULT)hIcon);
1330 }
1331 for (Len = 1; Len < 64; Len++)
1332 {
1333 if ((hIcon = LoadIconW(NULL, MAKEINTRESOURCEW(Len))) != NULL)
1334 {
1335 return((LRESULT)hIcon);
1336 }
1337 }
1338 return ((LRESULT)LoadIconW(0, IDI_APPLICATION));
1339 }
1340
1341 /* FIXME: WM_ISACTIVEICON */
1342
1343 case WM_NOTIFYFORMAT:
1344 {
1345 if (IsWindowUnicode(hWnd))
1346 {
1347 return(NFR_UNICODE);
1348 }
1349 else
1350 {
1351 return(NFR_ANSI);
1352 }
1353 }
1354
1355 case WM_SETICON:
1356 {
1357 INT Index = (wParam != 0) ? GCL_HICON : GCL_HICONSM;
1358 HICON hOldIcon = (HICON)GetClassLongW(hWnd, Index);
1359 SetClassLongW(hWnd, Index, lParam);
1360 SetWindowPos(hWnd, 0, 0, 0, 0, 0,
1361 SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
1362 SWP_NOACTIVATE | SWP_NOZORDER);
1363 return ((LRESULT)hOldIcon);
1364 }
1365
1366 case WM_GETICON:
1367 {
1368 INT Index = (wParam == ICON_BIG) ? GCL_HICON : GCL_HICONSM;
1369 return (GetClassLongW(hWnd, Index));
1370 }
1371
1372 case WM_HELP:
1373 {
1374 if (bUnicode)
1375 {
1376 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
1377 }
1378 else
1379 {
1380 SendMessageA(GetParent(hWnd), Msg, wParam, lParam);
1381 }
1382 break;
1383 }
1384
1385 case WM_SYSTIMER:
1386 {
1387 THRDCARETINFO CaretInfo;
1388 switch(wParam)
1389 {
1390 case 0xffff: /* Caret timer */
1391 /* switch showing byte in win32k and get information about the caret */
1392 if(NtUserSwitchCaretShowing(&CaretInfo) && (CaretInfo.hWnd == hWnd))
1393 {
1394 DrawCaret(hWnd, &CaretInfo);
1395 }
1396 break;
1397 }
1398 break;
1399 }
1400
1401 case WM_QUERYOPEN:
1402 case WM_QUERYENDSESSION:
1403 {
1404 return (1);
1405 }
1406 }
1407 return 0;
1408 }
1409
1410
1411 LRESULT STDCALL
1412 DefWindowProcA(HWND hWnd,
1413 UINT Msg,
1414 WPARAM wParam,
1415 LPARAM lParam)
1416 {
1417 switch (Msg)
1418 {
1419 case WM_NCCREATE:
1420 {
1421 return TRUE;
1422 }
1423
1424 case WM_GETTEXTLENGTH:
1425 {
1426 return (LRESULT)NtUserInternalGetWindowText(hWnd, NULL, 0);
1427 }
1428
1429 case WM_GETTEXT:
1430 {
1431 LPWSTR Buffer;
1432 LPSTR AnsiBuffer = (LPSTR)lParam;
1433 INT Length;
1434
1435 if (wParam > 1)
1436 {
1437 *((PWSTR)lParam) = '\0';
1438 }
1439 Buffer = HeapAlloc(GetProcessHeap(), 0, wParam * sizeof(WCHAR));
1440 if (!Buffer)
1441 return FALSE;
1442 Length = NtUserInternalGetWindowText(hWnd, Buffer, wParam);
1443 if (Length > 0 && wParam > 0 &&
1444 !WideCharToMultiByte(CP_ACP, 0, Buffer, -1,
1445 AnsiBuffer, wParam, NULL, NULL))
1446 {
1447 AnsiBuffer[0] = '\0';
1448 }
1449
1450 HeapFree(GetProcessHeap(), 0, Buffer);
1451
1452 return (LRESULT)Length;
1453 }
1454
1455 case WM_SETTEXT:
1456 {
1457 ANSI_STRING AnsiString;
1458 UNICODE_STRING UnicodeString;
1459
1460 if(lParam)
1461 {
1462 RtlInitAnsiString(&AnsiString, (LPSTR)lParam);
1463 RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
1464 NtUserDefSetText(hWnd, &UnicodeString);
1465 RtlFreeUnicodeString(&UnicodeString);
1466 }
1467 else
1468 NtUserDefSetText(hWnd, NULL);
1469
1470 if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1471 {
1472 DefWndNCPaint(hWnd, (HRGN)1, -1);
1473 }
1474 return TRUE;
1475 }
1476
1477 /*
1478 FIXME: Implement these.
1479 case WM_IME_CHAR:
1480 case WM_IME_KEYDOWN:
1481 case WM_IME_KEYUP:
1482 case WM_IME_STARTCOMPOSITION:
1483 case WM_IME_COMPOSITION:
1484 case WM_IME_ENDCOMPOSITION:
1485 case WM_IME_SELECT:
1486 case WM_IME_SETCONTEXT:
1487 */
1488 }
1489
1490 return User32DefWindowProc(hWnd, Msg, wParam, lParam, FALSE);
1491 }
1492
1493
1494 LRESULT STDCALL
1495 DefWindowProcW(HWND hWnd,
1496 UINT Msg,
1497 WPARAM wParam,
1498 LPARAM lParam)
1499 {
1500 switch (Msg)
1501 {
1502 case WM_NCCREATE:
1503 {
1504 return TRUE;
1505 }
1506
1507 case WM_GETTEXTLENGTH:
1508 {
1509 return (LRESULT)NtUserInternalGetWindowText(hWnd, NULL, 0);
1510 }
1511
1512 case WM_GETTEXT:
1513 {
1514 if (wParam > 1)
1515 {
1516 *((PWSTR)lParam) = L'\0';
1517 }
1518 return (LRESULT)NtUserInternalGetWindowText(hWnd, (PWSTR)lParam, wParam);
1519 }
1520
1521 case WM_SETTEXT:
1522 {
1523 UNICODE_STRING UnicodeString;
1524
1525 if(lParam)
1526 RtlInitUnicodeString(&UnicodeString, (LPWSTR)lParam);
1527
1528 NtUserDefSetText(hWnd, (lParam ? &UnicodeString : NULL));
1529
1530 if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
1531 {
1532 DefWndNCPaint(hWnd, (HRGN)1, -1);
1533 }
1534 return (1);
1535 }
1536
1537 case WM_IME_CHAR:
1538 {
1539 SendMessageW(hWnd, WM_CHAR, wParam, lParam);
1540 return (0);
1541 }
1542
1543 case WM_IME_SETCONTEXT:
1544 {
1545 /* FIXME */
1546 return (0);
1547 }
1548 }
1549
1550 return User32DefWindowProc(hWnd, Msg, wParam, lParam, TRUE);
1551 }
1552