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