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