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