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