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