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