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