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)
9 * 06-06-2001 CSH Created
12 /* INCLUDES ******************************************************************/
17 #include <user32/wininternal.h>
26 /* GLOBALS *******************************************************************/
28 static HBITMAP hbSysMenu;
29 /* TODO: widgets will be cached here.
30 static HBITMAP hbClose;
31 static HBITMAP hbCloseD;
32 static HBITMAP hbMinimize;
33 static HBITMAP hbMinimizeD;
34 static HBITMAP hbRestore;
35 static HBITMAP hbRestoreD;
36 static HBITMAP hbMaximize;
37 static HBITMAP hbScrUp;
38 static HBITMAP hbScrDwn;
39 static HBITMAP hbScrLeft;
40 static HBITMAP hbScrRight;
44 static COLORREF SysColours[29] =
46 RGB(224, 224, 224) /* COLOR_SCROLLBAR */,
47 RGB(58, 110, 165) /* COLOR_BACKGROUND */,
48 RGB(0, 0, 128) /* COLOR_ACTIVECAPTION */,
49 RGB(128, 128, 128) /* COLOR_INACTIVECAPTION */,
50 RGB(192, 192, 192) /* COLOR_MENU */,
51 RGB(255, 255, 255) /* COLOR_WINDOW */,
52 RGB(0, 0, 0) /* COLOR_WINDOWFRAME */,
53 RGB(0, 0, 0) /* COLOR_MENUTEXT */,
54 RGB(0, 0, 0) /* COLOR_WINDOWTEXT */,
55 RGB(255, 255, 255) /* COLOR_CAPTIONTEXT */,
56 RGB(128, 128, 128) /* COLOR_ACTIVEBORDER */,
57 RGB(255, 255, 255) /* COLOR_INACTIVEBORDER */,
58 RGB(255, 255, 232) /* COLOR_APPWORKSPACE */,
59 RGB(224, 224, 224) /* COLOR_HILIGHT */,
60 RGB(0, 0, 128) /* COLOR_HILIGHTTEXT */,
61 RGB(192, 192, 192) /* COLOR_BTNFACE */,
62 RGB(128, 128, 128) /* COLOR_BTNSHADOW */,
63 RGB(192, 192, 192) /* COLOR_GRAYTEXT */,
64 RGB(0, 0, 0) /* COLOR_BTNTEXT */,
65 RGB(192, 192, 192) /* COLOR_INACTIVECAPTIONTEXT */,
66 RGB(255, 255, 255) /* COLOR_BTNHILIGHT */,
67 RGB(32, 32, 32) /* COLOR_3DDKSHADOW */,
68 RGB(192, 192, 192) /* COLOR_3DLIGHT */,
69 RGB(0, 0, 0) /* COLOR_INFOTEXT */,
70 RGB(255, 255, 192) /* COLOR_INFOBK */,
71 RGB(184, 180, 184) /* COLOR_ALTERNATEBTNFACE */,
72 RGB(0, 0, 255) /* COLOR_HOTLIGHT */,
73 RGB(16, 132, 208) /* COLOR_GRADIENTACTIVECAPTION */,
74 RGB(181, 181, 181) /* COLOR_GRADIENTINACTIVECAPTION */,
77 static ATOM AtomInternalPos;
79 /* Bits in the dwKeyData */
80 #define KEYDATA_ALT 0x2000
82 /* FUNCTIONS *****************************************************************/
85 IsMaxBoxActive(HWND hWnd)
87 ULONG uStyle = GetWindowLongW(hWnd, GWL_STYLE);
88 return (uStyle & WS_MAXIMIZEBOX);
92 IsCloseBoxActive(HWND hWnd)
94 ULONG uStyle = GetWindowLongW(hWnd, GWL_STYLE);
95 return (uStyle & WS_SYSMENU);
99 IsMinBoxActive(HWND hWnd)
101 ULONG uStyle = GetWindowLongW(hWnd, GWL_STYLE);
102 return (uStyle & WS_MINIMIZEBOX);
106 UIGetFrameSizeX(HWND hWnd)
108 ULONG uStyle = GetWindowLongW(hWnd, GWL_STYLE);
110 if ( uStyle & WS_THICKFRAME )
111 return GetSystemMetrics(SM_CXSIZEFRAME);
113 return GetSystemMetrics(SM_CXFRAME);
117 UIGetFrameSizeY(HWND hWnd)
119 ULONG uStyle = GetWindowLongW(hWnd, GWL_STYLE);
121 if (uStyle & WS_THICKFRAME)
122 return GetSystemMetrics(SM_CYSIZEFRAME);
124 return GetSystemMetrics(SM_CYFRAME);
128 UserSetupInternalPos(VOID)
131 AtomInternalPos = GlobalAddAtomA(Str);
138 GetSysColor(int nIndex)
140 return SysColours[nIndex];
147 GetSysColorPen(int nIndex)
149 return CreatePen(PS_SOLID, 1, SysColours[nIndex]);
156 GetSysColorBrush(int nIndex)
158 return CreateSolidBrush(SysColours[nIndex]);
165 DefFrameProcA( HWND hWnd,
179 DefFrameProcW(HWND hWnd,
190 UserGetInternalPos(HWND hWnd)
193 lpPos = (PINTERNALPOS)GetPropA(hWnd, (LPSTR)(DWORD)AtomInternalPos);
198 DefWndRedrawIconTitle(HWND hWnd)
200 PINTERNALPOS lpPos = (PINTERNALPOS)GetPropA(hWnd, (LPSTR)(DWORD)AtomInternalPos);
204 if (lpPos->IconTitle != NULL)
206 SendMessageA(lpPos->IconTitle, WM_SHOWWINDOW, TRUE, 0);
207 InvalidateRect(lpPos->IconTitle, NULL, TRUE);
215 UserHasMenu(HWND hWnd, ULONG Style)
217 return (!(Style & WS_CHILD) && GetMenu(hWnd) != 0);
221 UserHasAnyFrameStyle(ULONG Style, ULONG ExStyle)
223 return ((Style & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) ||
224 (ExStyle & WS_EX_DLGMODALFRAME) ||
225 (!(Style & (WS_CHILD | WS_POPUP))));
229 UserHasDlgFrameStyle(ULONG Style, ULONG ExStyle)
231 return ((ExStyle & WS_EX_DLGMODALFRAME) ||
232 ((Style & WS_DLGFRAME) && (!(Style & WS_THICKFRAME))));
236 UserHasThickFrameStyle(ULONG Style, ULONG ExStyle)
238 return ((Style & WS_THICKFRAME) &&
239 (!((Style & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)));
243 UserHasThinFrameStyle(ULONG Style, ULONG ExStyle)
245 return ((Style & WS_BORDER) || (!(Style & (WS_CHILD | WS_POPUP))));
249 UserHasBigFrameStyle(ULONG Style, ULONG ExStyle)
251 return ((Style & (WS_THICKFRAME | WS_DLGFRAME)) ||
252 (ExStyle & WS_EX_DLGMODALFRAME));
256 UserGetInsideRectNC(HWND hWnd, RECT *rect)
262 Style = GetWindowLongW(hWnd, GWL_STYLE);
263 ExStyle = GetWindowLongW(hWnd, GWL_EXSTYLE);
264 GetWindowRect(hWnd, &WindowRect);
265 rect->top = rect->left = 0;
266 rect->right = WindowRect.right - WindowRect.left;
267 rect->bottom = WindowRect.bottom - WindowRect.top;
269 if (Style & WS_ICONIC)
274 /* Remove frame from rectangle */
275 if (UserHasThickFrameStyle(Style, ExStyle ))
277 InflateRect(rect, -GetSystemMetrics(SM_CXFRAME),
278 -GetSystemMetrics(SM_CYFRAME));
282 if (UserHasDlgFrameStyle(Style, ExStyle ))
284 InflateRect(rect, -GetSystemMetrics(SM_CXDLGFRAME),
285 -GetSystemMetrics(SM_CYDLGFRAME));
286 /* FIXME: this isn't in NC_AdjustRect? why not? */
287 if (ExStyle & WS_EX_DLGMODALFRAME)
288 InflateRect( rect, -1, 0 );
292 if (UserHasThinFrameStyle(Style, ExStyle))
294 InflateRect(rect, -GetSystemMetrics(SM_CXBORDER),
295 -GetSystemMetrics(SM_CYBORDER));
302 UserDrawSysMenuButton(HWND hWnd, HDC hDC, LPRECT Rect, BOOL down)
305 HBITMAP hSavedBitmap;
309 hbSysMenu = (HBITMAP)LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CLOSE));
311 hDcMem = CreateCompatibleDC(hDC);
316 hSavedBitmap = SelectObject(hDcMem, hbSysMenu);
323 BitBlt(hDC, Rect->left + 2, Rect->top + 3, 16, 14, hDcMem,
324 (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD) ?
325 GetSystemMetrics(SM_CXSIZE): 0, 0, SRCCOPY);
327 SelectObject(hDcMem, hSavedBitmap);
334 * Cache bitmaps, then just bitblt instead of calling DFC() (and
335 * wasting precious CPU cycles) every time
338 UserDrawCaptionButton(HWND hWnd, HDC hDC, BOOL bDown, ULONG Type)
341 INT iBmpWidth = GetSystemMetrics(SM_CXSIZE) - 2;
342 INT iBmpHeight = GetSystemMetrics(SM_CYSIZE) - 4;
343 INT OffsetX = UIGetFrameSizeX(hWnd);
344 INT OffsetY = UIGetFrameSizeY(hWnd);
346 if (!(GetWindowLongW(hWnd, GWL_STYLE) & WS_SYSMENU))
351 GetWindowRect(hWnd, &rect);
353 rect.right = rect.right - rect.left;
354 rect.bottom = rect.bottom - rect.top;
355 rect.left = rect.top = 0;
359 case DFCS_CAPTIONMIN:
361 if ((GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW) == TRUE)
362 return; /* ToolWindows don't have min/max buttons */
364 SetRect(&rect, rect.right - OffsetX - (iBmpWidth * 3) - 5,
365 OffsetY + 2, rect.right - (iBmpWidth * 2) - OffsetX - 5,
366 rect.top + iBmpHeight + OffsetY + 2);
367 DrawFrameControl(hDC, &rect, DFC_CAPTION,
368 DFCS_CAPTIONMIN | (bDown ? DFCS_PUSHED : 0) |
369 (IsMinBoxActive(hWnd) ? 0 : DFCS_INACTIVE));
372 case DFCS_CAPTIONMAX:
374 if ((GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW) == TRUE)
375 return; /* ToolWindows don't have min/max buttons */
377 SetRect(&rect, rect.right - OffsetX - (iBmpWidth * 2) - 5,
378 OffsetY + 2, rect.right - iBmpWidth - OffsetX - 5,
379 rect.top + iBmpHeight + OffsetY + 2);
380 DrawFrameControl(hDC, &rect, DFC_CAPTION,
381 (IsZoomed(hWnd) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMAX) |
382 (bDown ? DFCS_PUSHED : 0) |
383 (IsMaxBoxActive(hWnd) ? 0 : DFCS_INACTIVE));
386 case DFCS_CAPTIONCLOSE:
388 SetRect(&rect, rect.right - OffsetX - iBmpWidth - 3,
389 OffsetY + 2, rect.right - OffsetX - 3,
390 rect.top + iBmpHeight + OffsetY + 2 );
391 DrawFrameControl(hDC, &rect, DFC_CAPTION,
392 (DFCS_CAPTIONCLOSE | (bDown ? DFCS_PUSHED : 0) |
393 (IsCloseBoxActive(hWnd) ? 0 : DFCS_INACTIVE)));
399 // Enabling this will cause captions to draw smoother, but slower:
400 // #define DOUBLE_BUFFER_CAPTION
401 // NOTE: Double buffering appears to be broken for this at the moment
413 NONCLIENTMETRICSW nclm;
416 UINT VCenter = 0, Padding = 0, Height;
419 HFONT hOldFont = NULL;
420 HBRUSH OldBrush = NULL;
424 #ifdef DOUBLE_BUFFER_CAPTION
425 HBITMAP MemBMP = NULL, OldBMP = NULL;
427 MemDC = CreateCompatibleDC(hDC);
428 if (! MemDC) goto cleanup;
429 MemBMP = CreateCompatibleBitmap(hDC, lprc->right - lprc->left, lprc->bottom - lprc->top);
430 if (! MemBMP) goto cleanup;
431 OldBMP = SelectObject(MemDC, MemBMP);
432 if (! OldBMP) goto cleanup;
436 OffsetViewportOrgEx(MemDC, lprc->left, lprc->top, NULL);
439 // If DC_GRADIENT is specified, a Win 98/2000 style caption gradient should
440 // be painted. For now, that flag is ignored:
441 // Windows 98/Me, Windows 2000/XP: When this flag is set, the function uses
442 // COLOR_GRADIENTACTIVECAPTION (if the DC_ACTIVE flag was set) or
443 // COLOR_GRADIENTINACTIVECAPTION for the title-bar color.
445 // Draw the caption background
446 if (uFlags & DC_INBUTTON)
448 OldBrush = SelectObject(MemDC, GetSysColorBrush(uFlags & DC_ACTIVE ? COLOR_BTNFACE : COLOR_BTNSHADOW) );
449 if (! OldBrush) goto cleanup;
450 if (! PatBlt(MemDC, 0, 0, lprc->right - lprc->left, lprc->bottom - lprc->top, PATCOPY )) goto cleanup;
454 // DC_GRADIENT check should go here somewhere
455 OldBrush = SelectObject(MemDC, GetSysColorBrush(uFlags & DC_ACTIVE ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION) );
456 if (! OldBrush) goto cleanup;
457 if (! PatBlt(MemDC, 0, 0, lprc->right - lprc->left, lprc->bottom - lprc->top, PATCOPY )) goto cleanup;
460 /* Windows behaves like this */
461 Height = GetSystemMetrics(SM_CYCAPTION) - 1;
463 VCenter = (lprc->bottom - lprc->top) / 2;
464 Padding = VCenter - (Height / 2);
467 r.right = r.left + (lprc->right - lprc->left);
469 r.bottom = r.top + (Height / 2);
471 if (uFlags & DC_ICON)
473 // For some reason the icon isn't centered correctly...
475 UserDrawSysMenuButton(hWnd, MemDC, &r, FALSE);
482 if ((uFlags & DC_TEXT) && (GetWindowTextW( hWnd, buffer, sizeof(buffer)/sizeof(buffer[0]) )))
484 // Duplicate odd behaviour from Windows:
485 if ((! uFlags & DC_SMALLCAP) || (uFlags & DC_ICON) || (uFlags & DC_INBUTTON) ||
486 (! uFlags & DC_ACTIVE))
487 r.left += GetSystemMetrics(SM_CXSIZE) + Padding;
489 r.right = (lprc->right - lprc->left);
490 ButtonWidth = GetSystemMetrics(SM_CXSIZE) - 2;
491 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_SYSMENU)
493 r.right -= 3 + ButtonWidth;
494 if (! (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
496 r.right -= 2 + 2 * ButtonWidth;
501 nclm.cbSize = sizeof(nclm);
502 if (! SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW), &nclm, 0)) goto cleanup;
504 if (uFlags & DC_INBUTTON)
505 SetTextColor(MemDC, SysColours[ uFlags & DC_ACTIVE ? COLOR_BTNTEXT : COLOR_GRAYTEXT]);
507 SetTextColor(MemDC, SysColours[ uFlags & DC_ACTIVE ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT]);
509 SetBkMode( MemDC, TRANSPARENT );
510 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_EX_TOOLWINDOW)
511 // if (uFlags & DC_SMALLCAP) // incorrect
512 hFont = CreateFontIndirectW(&nclm.lfSmCaptionFont);
514 hFont = CreateFontIndirectW(&nclm.lfCaptionFont);
516 if (! hFont) goto cleanup;
518 hOldFont = SelectObject(MemDC, hFont);
519 if (! hOldFont) goto cleanup;
521 DrawTextW(MemDC, buffer, wcslen(buffer), &r, DT_VCENTER | DT_END_ELLIPSIS);
523 // TextOutW(hDC, r.left + (GetSystemMetrics(SM_CXDLGFRAME) * 2), lprc->top + (nclm.lfCaptionFont.lfHeight / 2), buffer, wcslen(buffer));
526 if (uFlags & DC_BUTTONS)
528 // Windows XP draws the caption buttons with DC_BUTTONS
529 // r.left += GetSystemMetrics(SM_CXSIZE) + 1;
530 // UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONCLOSE);
531 // r.right -= GetSystemMetrics(SM_CXSMSIZE) + 1;
532 // UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMIN);
533 // UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMAX);
536 #ifdef DOUBLE_BUFFER_CAPTION
537 if (! BitBlt(hDC, lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top,
538 MemDC, 0, 0, SRCCOPY)) goto cleanup;
546 if (OldBrush) SelectObject(MemDC, OldBrush);
547 if (hOldFont) SelectObject(MemDC, hOldFont);
548 if (hFont) DeleteObject(hFont);
549 #ifdef DOUBLE_BUFFER_CAPTION
550 if (OldBMP) SelectObject(MemDC, OldBMP);
551 if (MemBMP) DeleteObject(MemBMP);
554 OffsetViewportOrgEx(MemDC, -lprc->left, -lprc->top, NULL);
576 capflags = DC_ICON | DC_TEXT;
577 capflags |= (active & DC_ACTIVE);
579 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_EX_TOOLWINDOW)
580 capflags |= DC_SMALLCAP;
583 // PatBlt(hDC,rect->left + GetSystemMetrics(SM_CXFRAME), rect->top +
584 // GetSystemMetrics(SM_CYFRAME), rect->right - (GetSystemMetrics(SM_CXFRAME) * 2), (rect->top +
585 // GetSystemMetrics(SM_CYCAPTION)) - 1, PATCOPY );
587 r.left += GetSystemMetrics(SM_CXFRAME);
588 r.top += GetSystemMetrics(SM_CYFRAME);
589 r.right -= GetSystemMetrics(SM_CXFRAME);
590 r.bottom = r.top + GetSystemMetrics(SM_CYCAPTION) - 1;
591 // GetSystemMetrics(SM_CYCAPTION)) - 1, PATCOPY );
593 DrawCaption(hWnd, hDC, &r, capflags);
595 /* draw line below caption */
596 lPen = GetSysColorPen(COLOR_MENU);
597 oPen = SelectObject(hDC, lPen);
598 MoveToEx(hDC, r.left, r.bottom, &OldPos);
599 LineTo(hDC, r.right, r.bottom);
600 MoveToEx(hDC, OldPos.x, OldPos.y, NULL);
601 SelectObject(hDC, oPen);
604 if (style & WS_SYSMENU)
606 // UserDrawSysMenuButton( hWnd, hDC, FALSE);
607 r.left += GetSystemMetrics(SM_CXSIZE) + 1;
608 UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONCLOSE);
609 r.right -= GetSystemMetrics(SM_CXSMSIZE) + 1;
610 UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMIN);
611 UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMAX);
617 UserDrawFrameNC(HDC hDC, RECT* rect, BOOL dlgFrame, BOOL active)
619 DrawEdge(hDC, rect,EDGE_RAISED, BF_RECT | BF_MIDDLE);
624 SCROLL_DrawScrollBar (HWND hWnd, HDC hDC, INT nBar, BOOL arrows, BOOL interior);
627 DefWndDoPaintNC(HWND hWnd, HRGN clip)
636 if (GetActiveWindow() == hWnd) Active = TRUE;
637 Style = GetWindowLongW(hWnd, GWL_STYLE);
638 ExStyle = GetWindowLongW(hWnd, GWL_EXSTYLE);
640 hDC = GetDCEx(hWnd, (clip > (HRGN)1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
641 ((clip > (HRGN)1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0));
647 /* FIXME: Test whether we need to draw anything at all. */
649 GetWindowRect(hWnd, &rect);
650 rect.right = rect.right - rect.left;
651 rect.bottom = rect.bottom - rect.top;
652 rect.top = rect.left = 0;
653 SelectObject(hDC, GetSysColorPen(COLOR_WINDOWFRAME));
654 if (UserHasThickFrameStyle(Style, ExStyle))
656 UserDrawFrameNC(hDC, &rect, FALSE, Active);
657 wFrame = GetSystemMetrics(SM_CXSIZEFRAME);
659 else if (UserHasDlgFrameStyle(Style, ExStyle))
661 UserDrawFrameNC(hDC, &rect, TRUE, Active);
662 wFrame = GetSystemMetrics(SM_CXDLGFRAME);
664 if (Style & WS_CAPTION)
667 r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
668 rect.top += GetSystemMetrics(SM_CYSIZE) +
669 GetSystemMetrics(SM_CYBORDER);
670 UserDrawCaptionNC(hDC, &r, hWnd, Style, Active);
674 if (UserHasMenu(hWnd, Style))
677 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
680 rect.top += MenuDrawMenuBar(hDC, &r, hWnd, FALSE);
683 /* Draw scrollbars */
684 if (Style & WS_VSCROLL)
685 SCROLL_DrawScrollBar(hWnd, hDC, SB_VERT, TRUE, TRUE);
686 if (Style & WS_HSCROLL)
687 SCROLL_DrawScrollBar(hWnd, hDC, SB_HORZ, TRUE, TRUE);
689 /* FIXME: Draw size box.*/
691 ReleaseDC(hWnd, hDC);
696 DefWndPaintNC(HWND hWnd, HRGN clip)
698 if (IsWindowVisible(hWnd))
702 DefWndRedrawIconTitle(hWnd);
706 DefWndDoPaintNC(hWnd, clip);
714 DefWndHitTestNC(HWND hWnd, POINT Point)
717 ULONG Style = GetWindowLongW(hWnd, GWL_STYLE);
718 ULONG ExStyle = GetWindowLongW(hWnd, GWL_EXSTYLE);
720 GetWindowRect(hWnd, &WindowRect);
721 if (!PtInRect(&WindowRect, Point))
725 if (Style & WS_MINIMIZE)
729 if (UserHasThickFrameStyle(Style, ExStyle))
731 InflateRect(&WindowRect, -GetSystemMetrics(SM_CXFRAME),
732 -GetSystemMetrics(SM_CYFRAME));
733 if (!PtInRect(&WindowRect, Point))
735 if (Point.y < WindowRect.top)
737 if (Point.x < (WindowRect.left + GetSystemMetrics(SM_CXSIZE)))
741 if (Point.x >= (WindowRect.right - GetSystemMetrics(SM_CXSIZE)))
747 if (Point.y >= WindowRect.bottom)
749 if (Point.x < (WindowRect.left + GetSystemMetrics(SM_CXSIZE)))
751 return(HTBOTTOMLEFT);
753 if (Point.x >= (WindowRect.right - GetSystemMetrics(SM_CXSIZE)))
755 return(HTBOTTOMRIGHT);
759 if (Point.x < WindowRect.left)
761 if (Point.y < (WindowRect.top + GetSystemMetrics(SM_CYSIZE)))
765 if (Point.y >= (WindowRect.bottom - GetSystemMetrics(SM_CYSIZE)))
767 return(HTBOTTOMLEFT);
771 if (Point.x >= WindowRect.right)
773 if (Point.y < (WindowRect.top + GetSystemMetrics(SM_CYSIZE)))
777 if (Point.y >= (WindowRect.bottom - GetSystemMetrics(SM_CYSIZE)))
779 return(HTBOTTOMRIGHT);
787 if (UserHasDlgFrameStyle(Style, ExStyle))
789 InflateRect(&WindowRect, -GetSystemMetrics(SM_CXDLGFRAME),
790 -GetSystemMetrics(SM_CYDLGFRAME));
792 else if (UserHasThinFrameStyle(Style, ExStyle))
794 InflateRect(&WindowRect, -GetSystemMetrics(SM_CXBORDER),
795 -GetSystemMetrics(SM_CYBORDER));
797 if (!PtInRect(&WindowRect, Point))
803 if ((Style & WS_CAPTION) == WS_CAPTION)
805 WindowRect.top += (GetSystemMetrics(SM_CYCAPTION) -
806 GetSystemMetrics(SM_CYBORDER));
807 if (!PtInRect(&WindowRect, Point))
809 if ((Style & WS_SYSMENU) && !(ExStyle & WS_EX_TOOLWINDOW))
811 WindowRect.left += GetSystemMetrics(SM_CXSIZE);
812 WindowRect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
814 if (Point.x <= WindowRect.left)
818 if (WindowRect.right <= Point.x)
823 if (Style & WS_MAXIMIZEBOX || Style & WS_MINIMIZEBOX)
825 WindowRect.right -= GetSystemMetrics(SM_CXSIZE);
827 if (Point.x >= WindowRect.right)
832 if (Style & WS_MINIMIZEBOX)
834 WindowRect.right -= GetSystemMetrics(SM_CXSIZE);
836 if (Point.x >= WindowRect.right)
844 ScreenToClient(hWnd, &Point);
845 GetClientRect(hWnd, &WindowRect);
847 if (PtInRect(&WindowRect, Point))
852 if (Style & WS_VSCROLL)
854 WindowRect.right += GetSystemMetrics(SM_CXVSCROLL);
855 if (PtInRect(&WindowRect, Point))
861 if (Style & WS_HSCROLL)
863 WindowRect.bottom += GetSystemMetrics(SM_CYHSCROLL);
864 if (PtInRect(&WindowRect, Point))
866 if ((Style & WS_VSCROLL) &&
867 (Point.x >= (WindowRect.right - GetSystemMetrics(SM_CXVSCROLL))))
869 return(HTBOTTOMRIGHT);
875 if (UserHasMenu(hWnd, Style))
877 if (Point.y < 0 && Point.x >= 0 && Point.x <= WindowRect.right)
887 DefWndDoButton(HWND hWnd, WPARAM wParam)
890 BOOL InBtn = TRUE, HasBtn = FALSE;
892 WPARAM SCMsg, CurBtn = wParam, OrigBtn = wParam;
897 Btn = DFCS_CAPTIONCLOSE;
899 HasBtn = IsCloseBoxActive(hWnd);
902 Btn = DFCS_CAPTIONMIN;
904 HasBtn = IsMinBoxActive(hWnd);
907 Btn = DFCS_CAPTIONMAX;
909 HasBtn = IsMaxBoxActive(hWnd);
919 UserDrawCaptionButton( hWnd, GetWindowDC(hWnd), HasBtn , Btn);
923 GetMessageW(&Msg, 0, 0, 0);
937 CurBtn = DefWndHitTestNC(hWnd, Msg.pt);
938 if(InBtn != (CurBtn == OrigBtn))
940 UserDrawCaptionButton( hWnd, GetWindowDC(hWnd), (CurBtn == OrigBtn) , Btn);
942 InBtn = CurBtn == OrigBtn;
948 UserDrawCaptionButton( hWnd, GetWindowDC(hWnd), FALSE , Btn);
950 SendMessageA(hWnd, WM_SYSCOMMAND, SCMsg, 0);
955 DefWndDoScrollBarDown(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
959 Point.x = SLOWORD(lParam);
960 Point.y = SHIWORD(lParam);
962 hit = SCROLL_HitTest(hWnd, (wParam == HTHSCROLL) ? SB_HORZ : SB_VERT, Point, FALSE);
965 DbgPrint("SCROLL_HitTest() == 0x%x\n", hit);
967 SendMessageA(hWnd, WM_SYSCOMMAND, Msg + (UINT)wParam, lParam);
971 DefWndHandleLButtonDownNC(HWND hWnd, WPARAM wParam, LPARAM lParam)
977 HWND hTopWnd = GetAncestor(hWnd, GA_ROOT);
978 if (SetActiveWindow(hTopWnd) || GetActiveWindow() == hTopWnd)
980 SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam);
986 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_SYSMENU)
988 if (!(GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE))
990 HDC hDC = GetWindowDC(hWnd);
991 // UserDrawSysMenuButton(hWnd, hDC, TRUE);
992 ReleaseDC(hWnd, hDC);
994 SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU,
1001 SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTMENU, lParam);
1006 DefWndDoScrollBarDown(hWnd, SC_HSCROLL, HTHSCROLL, lParam);
1007 //SendMessageA(hWnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam);
1012 DefWndDoScrollBarDown(hWnd, SC_VSCROLL, HTVSCROLL, lParam);
1013 //SendMessageA(hWnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam);
1020 DefWndDoButton(hWnd, wParam);
1032 SendMessageA(hWnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam);
1041 DefWndHandleLButtonDblClkNC(HWND hWnd, WPARAM wParam, LPARAM lParam)
1049 DefWndHandleLButtonUpNC(HWND hWnd, WPARAM wParam, LPARAM lParam)
1057 DefWndHandleActiveNC(HWND hWnd, WPARAM wParam)
1065 DefWndSetRedraw(HWND hWnd, WPARAM wParam)
1072 DefWndHandleSetCursor(HWND hWnd, WPARAM wParam, LPARAM lParam)
1074 /* Not for child windows. */
1075 if (hWnd != (HWND)wParam)
1080 switch(LOWORD(lParam))
1084 WORD Msg = HIWORD(lParam);
1085 if (Msg == WM_LBUTTONDOWN || Msg == WM_MBUTTONDOWN ||
1086 Msg == WM_RBUTTONDOWN)
1095 HICON hCursor = (HICON)GetClassLongW(hWnd, GCL_HCURSOR);
1107 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZEWE)));
1113 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENS)));
1119 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENWSE)));
1125 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENESW)));
1128 return((LRESULT)SetCursor(LoadCursorW(0, IDC_ARROW)));
1132 DefWndStartSizeMove(HWND hWnd, WPARAM wParam, POINT *capturePoint)
1138 ULONG Style = GetWindowLongW(hWnd, GWL_STYLE);
1140 GetWindowRect(hWnd, &rectWindow);
1142 if ((wParam & 0xfff0) == SC_MOVE)
1144 /* Move pointer at the center of the caption */
1146 UserGetInsideRectNC(hWnd, &rect);
1147 if (Style & WS_SYSMENU)
1148 rect.left += GetSystemMetrics(SM_CXSIZE) + 1;
1149 if (Style & WS_MINIMIZEBOX)
1150 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1151 if (Style & WS_MAXIMIZEBOX)
1152 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1153 pt.x = rectWindow.left + (rect.right - rect.left) / 2;
1154 pt.y = rectWindow.top + rect.top + GetSystemMetrics(SM_CYSIZE)/2;
1155 hittest = HTCAPTION;
1162 GetMessageW(&msg, NULL, 0, 0);
1166 hittest = DefWndHitTestNC(hWnd, msg.pt);
1167 if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
1179 pt.x =(rectWindow.left+rectWindow.right)/2;
1180 pt.y = rectWindow.top + GetSystemMetrics(SM_CYFRAME) / 2;
1184 pt.x =(rectWindow.left+rectWindow.right)/2;
1185 pt.y = rectWindow.bottom - GetSystemMetrics(SM_CYFRAME) / 2;
1189 pt.x = rectWindow.left + GetSystemMetrics(SM_CXFRAME) / 2;
1190 pt.y =(rectWindow.top+rectWindow.bottom)/2;
1194 pt.x = rectWindow.right - GetSystemMetrics(SM_CXFRAME) / 2;
1195 pt.y =(rectWindow.top+rectWindow.bottom)/2;
1198 case VK_ESCAPE: return 0;
1204 SetCursorPos( pt.x, pt.y );
1205 DefWndHandleSetCursor(hWnd, (WPARAM)hWnd, MAKELONG(hittest, WM_MOUSEMOVE));
1209 #define ON_LEFT_BORDER(hit) \
1210 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
1211 #define ON_RIGHT_BORDER(hit) \
1212 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
1213 #define ON_TOP_BORDER(hit) \
1214 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
1215 #define ON_BOTTOM_BORDER(hit) \
1216 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
1219 UserDrawWindowFrame(HDC hdc, const RECT *rect,
1220 ULONG width, ULONG height, DWORD rop )
1222 HBRUSH hbrush = SelectObject( hdc, GetStockObject( GRAY_BRUSH ) );
1223 PatBlt( hdc, rect->left, rect->top,
1224 rect->right - rect->left - width, height, rop );
1225 PatBlt( hdc, rect->left, rect->top + height, width,
1226 rect->bottom - rect->top - height, rop );
1227 PatBlt( hdc, rect->left + width, rect->bottom - 1,
1228 rect->right - rect->left - width, -height, rop );
1229 PatBlt( hdc, rect->right - 1, rect->top, -width,
1230 rect->bottom - rect->top - height, rop );
1231 SelectObject( hdc, hbrush );
1235 UserDrawMovingFrame(HDC hdc, RECT *rect, BOOL thickframe)
1239 UserDrawWindowFrame(hdc, rect, GetSystemMetrics(SM_CXFRAME),
1240 GetSystemMetrics(SM_CYFRAME), PATINVERT );
1242 else DrawFocusRect( hdc, rect );
1246 DefWndDoSizeMove(HWND hwnd, WORD wParam)
1249 RECT sizingRect, mouseRect, origRect;
1251 LONG hittest = (LONG)(wParam & 0x0f);
1252 HCURSOR hDragCursor = 0, hOldCursor = 0;
1253 POINT minTrack, maxTrack;
1254 POINT capturePoint, pt;
1255 ULONG Style = GetWindowLongW(hwnd, GWL_STYLE);
1256 ULONG ExStyle = GetWindowLongW(hwnd, GWL_EXSTYLE);
1257 BOOL thickframe = UserHasThickFrameStyle(Style, ExStyle);
1258 BOOL iconic = Style & WS_MINIMIZE;
1260 DWORD dwPoint = GetMessagePos();
1261 BOOL DragFullWindows = FALSE;
1264 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS, 0, &DragFullWindows, 0);
1266 pt.x = SLOWORD(dwPoint);
1267 pt.y = SHIWORD(dwPoint);
1270 if (IsZoomed(hwnd) || !IsWindowVisible(hwnd))
1275 if ((wParam & 0xfff0) == SC_MOVE)
1279 hittest = DefWndStartSizeMove(hwnd, wParam, &capturePoint);
1292 if (hittest && hittest != HTSYSMENU)
1299 hittest = DefWndStartSizeMove(hwnd, wParam, &capturePoint);
1308 if (Style & WS_CHILD)
1310 hWndParent = GetParent(hwnd);
1313 /* Get min/max info */
1315 WinPosGetMinMaxInfo(hwnd, NULL, NULL, &minTrack, &maxTrack);
1316 GetWindowRect(hwnd, &sizingRect);
1317 origRect = sizingRect;
1318 if (Style & WS_CHILD)
1320 GetClientRect(hWndParent, &mouseRect );
1324 SetRect(&mouseRect, 0, 0, GetSystemMetrics(SM_CXSCREEN),
1325 GetSystemMetrics(SM_CYSCREEN));
1327 if (ON_LEFT_BORDER(hittest))
1329 mouseRect.left = max( mouseRect.left, sizingRect.right-maxTrack.x );
1330 mouseRect.right = min( mouseRect.right, sizingRect.right-minTrack.x );
1332 else if (ON_RIGHT_BORDER(hittest))
1334 mouseRect.left = max( mouseRect.left, sizingRect.left+minTrack.x );
1335 mouseRect.right = min( mouseRect.right, sizingRect.left+maxTrack.x );
1337 if (ON_TOP_BORDER(hittest))
1339 mouseRect.top = max( mouseRect.top, sizingRect.bottom-maxTrack.y );
1340 mouseRect.bottom = min( mouseRect.bottom,sizingRect.bottom-minTrack.y);
1342 else if (ON_BOTTOM_BORDER(hittest))
1344 mouseRect.top = max( mouseRect.top, sizingRect.top+minTrack.y );
1345 mouseRect.bottom = min( mouseRect.bottom, sizingRect.top+maxTrack.y );
1347 if (Style & WS_CHILD)
1349 MapWindowPoints( hWndParent, 0, (LPPOINT)&mouseRect, 2 );
1351 SendMessageA( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
1353 if (GetCapture() != hwnd) SetCapture( hwnd );
1355 if (Style & WS_CHILD)
1357 /* Retrieve a default cache DC (without using the window style) */
1358 hdc = GetDCEx(hWndParent, 0, DCX_CACHE);
1365 if( iconic ) /* create a cursor for dragging */
1367 HICON hIcon = (HICON)GetClassLongW(hwnd, GCL_HICON);
1368 if(!hIcon) hIcon = (HICON)SendMessageW( hwnd, WM_QUERYDRAGICON, 0, 0L);
1369 if( hIcon ) hDragCursor = CursorIconToCursor( hIcon, TRUE );
1370 if( !hDragCursor ) iconic = FALSE;
1373 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
1374 if( !iconic && !DragFullWindows)
1376 UserDrawMovingFrame( hdc, &sizingRect, thickframe );
1383 GetMessageW(&msg, 0, 0, 0);
1385 /* Exit on button-up, Return, or Esc */
1386 if ((msg.message == WM_LBUTTONUP) ||
1387 ((msg.message == WM_KEYDOWN) &&
1388 ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
1390 if (msg.message == WM_PAINT)
1392 if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
1393 UpdateWindow( msg.hwnd );
1394 if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
1398 if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
1399 continue; /* We are not interested in other messages */
1403 if (msg.message == WM_KEYDOWN) switch(msg.wParam)
1405 case VK_UP: pt.y -= 8; break;
1406 case VK_DOWN: pt.y += 8; break;
1407 case VK_LEFT: pt.x -= 8; break;
1408 case VK_RIGHT: pt.x += 8; break;
1411 pt.x = max( pt.x, mouseRect.left );
1412 pt.x = min( pt.x, mouseRect.right );
1413 pt.y = max( pt.y, mouseRect.top );
1414 pt.y = min( pt.y, mouseRect.bottom );
1416 dx = pt.x - capturePoint.x;
1417 dy = pt.y - capturePoint.y;
1425 if( iconic ) /* ok, no system popup tracking */
1427 hOldCursor = SetCursor(hDragCursor);
1429 WinPosShowIconTitle( hwnd, FALSE );
1433 if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
1436 RECT newRect = sizingRect;
1437 WPARAM wpSizingHit = 0;
1439 if (hittest == HTCAPTION) OffsetRect( &newRect, dx, dy );
1440 if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
1441 else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
1442 if (ON_TOP_BORDER(hittest)) newRect.top += dy;
1443 else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
1444 if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
1447 /* determine the hit location */
1448 if (hittest >= HTLEFT && hittest <= HTBOTTOMRIGHT)
1449 wpSizingHit = WMSZ_LEFT + (hittest - HTLEFT);
1450 SendMessageA( hwnd, WM_SIZING, wpSizingHit, (LPARAM)&newRect );
1454 if(!DragFullWindows)
1455 UserDrawMovingFrame( hdc, &newRect, thickframe );
1457 /* To avoid any deadlocks, all the locks on the windows
1458 structures must be suspended before the SetWindowPos */
1459 SetWindowPos( hwnd, 0, newRect.left, newRect.top,
1460 newRect.right - newRect.left,
1461 newRect.bottom - newRect.top,
1462 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
1465 sizingRect = newRect;
1473 if( moved ) /* restore cursors, show icon title later on */
1475 ShowCursor( FALSE );
1476 SetCursor( hOldCursor );
1478 DestroyCursor( hDragCursor );
1480 else if(!DragFullWindows)
1481 UserDrawMovingFrame( hdc, &sizingRect, thickframe );
1483 if (Style & WS_CHILD)
1484 ReleaseDC( hWndParent, hdc );
1486 ReleaseDC( 0, hdc );
1488 SendMessageA( hwnd, WM_EXITSIZEMOVE, 0, 0 );
1489 SendMessageA( hwnd, WM_SETVISIBLE, !IsIconic(hwnd), 0L);
1491 /* window moved or resized */
1494 /* if the moving/resizing isn't canceled call SetWindowPos
1495 * with the new position or the new size of the window
1497 if (!((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
1499 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
1500 if(!DragFullWindows)
1501 SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top,
1502 sizingRect.right - sizingRect.left,
1503 sizingRect.bottom - sizingRect.top,
1504 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
1506 else { /* restore previous size/position */
1508 SetWindowPos( hwnd, 0, origRect.left, origRect.top,
1509 origRect.right - origRect.left,
1510 origRect.bottom - origRect.top,
1511 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
1515 if( IsWindow(hwnd) )
1516 if( Style & WS_MINIMIZE )
1518 /* Single click brings up the system menu when iconized */
1522 if( Style & WS_SYSMENU )
1523 SendMessageA( hwnd, WM_SYSCOMMAND,
1524 SC_MOUSEMENU + HTSYSMENU, MAKELONG(pt.x,pt.y));
1526 else WinPosShowIconTitle( hwnd, TRUE );
1532 DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, POINT Pt)
1534 switch (wParam & 0xfff0)
1538 DefWndDoSizeMove(hWnd, wParam);
1541 SendMessageA(hWnd, WM_CLOSE, 0, 0);
1544 MenuTrackMouseMenuBar(hWnd, wParam, Pt);
1547 MenuTrackKbdMenuBar(hWnd, wParam, Pt.x);
1550 /* FIXME: Implement */
1560 DefWndAdjustRect(RECT* Rect, ULONG Style, BOOL Menu, ULONG ExStyle)
1562 if (Style & WS_ICONIC)
1567 if (UserHasThickFrameStyle(Style, ExStyle))
1569 InflateRect(Rect, GetSystemMetrics(SM_CXFRAME),
1570 GetSystemMetrics(SM_CYFRAME));
1572 else if (UserHasDlgFrameStyle(Style, ExStyle))
1574 InflateRect(Rect, GetSystemMetrics(SM_CXDLGFRAME),
1575 GetSystemMetrics(SM_CYDLGFRAME));
1577 else if (UserHasThinFrameStyle(Style, ExStyle))
1579 InflateRect(Rect, GetSystemMetrics(SM_CXBORDER),
1580 GetSystemMetrics(SM_CYBORDER));
1582 if (Style & WS_CAPTION)
1584 Rect->top -= (GetSystemMetrics(SM_CYCAPTION) -
1585 GetSystemMetrics(SM_CYBORDER)) + 1;
1589 Rect->top -= GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYBORDER);
1591 if (Style & WS_VSCROLL)
1593 Rect->right += GetSystemMetrics(SM_CXVSCROLL) - 1;
1594 if (UserHasAnyFrameStyle(Style, ExStyle))
1599 if (Style & WS_HSCROLL)
1601 Rect->bottom += GetSystemMetrics(SM_CYHSCROLL) - 1;
1602 if (UserHasAnyFrameStyle(Style, ExStyle))
1610 DefWndNCCalcSize(HWND hWnd, RECT* Rect)
1613 LONG Style = GetClassLongW(hWnd, GCL_STYLE);
1614 RECT TmpRect = {0, 0, 0, 0};
1616 if (Style & CS_VREDRAW)
1618 Result |= WVR_VREDRAW;
1620 if (Style & CS_HREDRAW)
1622 Result |= WVR_HREDRAW;
1625 if (!(GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE))
1627 DefWndAdjustRect(&TmpRect, GetWindowLongW(hWnd, GWL_STYLE),
1628 FALSE, GetWindowLongW(hWnd, GWL_EXSTYLE));
1629 Rect->left -= TmpRect.left;
1630 Rect->top -= TmpRect.top;
1631 Rect->right -= TmpRect.right;
1632 Rect->bottom -= TmpRect.bottom;
1633 if (UserHasMenu(hWnd, GetWindowLongW(hWnd, GWL_STYLE)))
1635 Rect->top += MenuGetMenuBarHeight(hWnd, Rect->right - Rect->left,
1636 -TmpRect.left, -TmpRect.top) + 1;
1638 if (Rect->top > Rect->bottom)
1639 Rect->bottom = Rect->top;
1640 if (Rect->left > Rect->right)
1641 Rect->right = Rect->left;
1648 DefWndHandleWindowPosChanging(HWND hWnd, WINDOWPOS* Pos)
1650 POINT maxSize, minTrack;
1651 LONG style = GetWindowLongA(hWnd, GWL_STYLE);
1653 if (Pos->flags & SWP_NOSIZE) return 0;
1654 if ((style & WS_THICKFRAME) || ((style & (WS_POPUP | WS_CHILD)) == 0))
1656 WinPosGetMinMaxInfo(hWnd, &maxSize, NULL, &minTrack, NULL);
1657 Pos->cx = min(Pos->cx, maxSize.x);
1658 Pos->cy = min(Pos->cy, maxSize.y);
1659 if (!(style & WS_MINIMIZE))
1661 if (Pos->cx < minTrack.x) Pos->cx = minTrack.x;
1662 if (Pos->cy < minTrack.y) Pos->cy = minTrack.y;
1668 /* Undocumented flags. */
1669 #define SWP_NOCLIENTMOVE 0x0800
1670 #define SWP_NOCLIENTSIZE 0x1000
1673 DefWndHandleWindowPosChanged(HWND hWnd, WINDOWPOS* Pos)
1677 GetClientRect(hWnd, &rect);
1679 if (!(Pos->flags & SWP_NOCLIENTMOVE))
1680 SendMessageW(hWnd, WM_MOVE, 0, MAKELONG(rect.left, rect.top));
1682 if (!(Pos->flags & SWP_NOCLIENTSIZE))
1684 WPARAM wp = SIZE_RESTORED;
1685 if (IsZoomed(hWnd)) wp = SIZE_MAXIMIZED;
1686 else if (IsIconic(hWnd)) wp = SIZE_MINIMIZED;
1687 SendMessageW(hWnd, WM_SIZE, wp,
1688 MAKELONG(rect.right - rect.left, rect.bottom - rect.top));
1694 /***********************************************************************
1695 * DefWndControlColor
1697 * Default colors for control painting.
1700 DefWndControlColor(HDC hDC, UINT ctlType)
1702 if (CTLCOLOR_SCROLLBAR == ctlType)
1704 HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR);
1705 COLORREF bk = GetSysColor(COLOR_3DHILIGHT);
1706 SetTextColor(hDC, GetSysColor(COLOR_3DFACE));
1707 SetBkColor(hDC, bk);
1709 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
1710 * we better use 0x55aa bitmap brush to make scrollbar's background
1711 * look different from the window background.
1713 if (bk == GetSysColor(COLOR_WINDOW))
1716 return CACHE_GetPattern55AABrush();
1721 UnrealizeObject(hb);
1725 SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
1727 if ((CTLCOLOR_EDIT == ctlType) || (CTLCOLOR_LISTBOX == ctlType))
1729 SetBkColor(hDC, GetSysColor(COLOR_WINDOW));
1733 SetBkColor(hDC, GetSysColor(COLOR_3DFACE));
1734 return GetSysColorBrush(COLOR_3DFACE);
1737 return GetSysColorBrush(COLOR_WINDOW);
1742 User32DefWindowProc(HWND hWnd,
1752 return (DefWndPaintNC(hWnd, (HRGN)wParam));
1757 return (DefWndNCCalcSize(hWnd, (RECT*)lParam));
1760 case WM_WINDOWPOSCHANGING:
1762 return (DefWndHandleWindowPosChanging(hWnd, (WINDOWPOS*)lParam));
1765 case WM_WINDOWPOSCHANGED:
1767 return (DefWndHandleWindowPosChanged(hWnd, (WINDOWPOS*)lParam));
1773 Point.x = SLOWORD(lParam);
1774 Point.y = SHIWORD(lParam);
1775 return (DefWndHitTestNC(hWnd, Point));
1778 case WM_NCLBUTTONDOWN:
1780 return (DefWndHandleLButtonDownNC(hWnd, wParam, lParam));
1783 case WM_NCLBUTTONUP:
1785 return (DefWndHandleLButtonUpNC(hWnd, wParam, lParam));
1788 case WM_LBUTTONDBLCLK:
1789 case WM_NCLBUTTONDBLCLK:
1791 return (DefWndHandleLButtonDblClkNC(hWnd, wParam, lParam));
1794 case WM_NCRBUTTONDOWN:
1796 if (wParam == HTCAPTION)
1806 if (hWnd == GetCapture())
1810 Pt.x = SLOWORD(lParam);
1811 Pt.y = SHIWORD(lParam);
1812 ClientToScreen(hWnd, &Pt);
1813 lParam = MAKELPARAM(Pt.x, Pt.y);
1816 SendMessageW(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
1820 SendMessageA(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
1825 case WM_CONTEXTMENU:
1827 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD)
1831 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
1835 SendMessageA(GetParent(hWnd), WM_CONTEXTMENU, wParam, lParam);
1843 Pt.x = SLOWORD(lParam);
1844 Pt.y = SHIWORD(lParam);
1845 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD)
1847 ScreenToClient(GetParent(hWnd), &Pt);
1850 HitCode = DefWndHitTestNC(hWnd, Pt);
1852 if (HitCode == HTCAPTION || HitCode == HTSYSMENU)
1854 TrackPopupMenu(GetSystemMenu(hWnd, FALSE),
1855 TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
1856 Pt.x, Pt.y, 0, hWnd, NULL);
1864 return (DefWndHandleActiveNC(hWnd, wParam));
1869 /* FIXME: Implement. */
1877 HDC hDC = BeginPaint(hWnd, &Ps);
1881 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE &&
1882 (hIcon = (HICON)GetClassLongW(hWnd, GCL_HICON)) != NULL)
1886 GetWindowRect(hWnd, &WindowRect);
1887 x = (WindowRect.right - WindowRect.left -
1888 GetSystemMetrics(SM_CXICON)) / 2;
1889 y = (WindowRect.bottom - WindowRect.top -
1890 GetSystemMetrics(SM_CYICON)) / 2;
1891 DrawIcon(hDC, x, y, hIcon);
1893 if (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_CLIENTEDGE)
1896 GetClientRect(hWnd, &WindowRect);
1897 DrawEdge(hDC, &WindowRect, EDGE_SUNKEN, BF_RECT);
1899 EndPaint(hWnd, &Ps);
1907 hRgn = CreateRectRgn(0, 0, 0, 0);
1908 if (GetUpdateRgn(hWnd, hRgn, FALSE) != NULLREGION)
1910 RedrawWindow(hWnd, NULL, hRgn,
1911 RDW_ERASENOW | RDW_ERASE | RDW_FRAME |
1920 DefWndSetRedraw(hWnd, wParam);
1926 DestroyWindow(hWnd);
1930 case WM_MOUSEACTIVATE:
1932 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD)
1937 Ret = SendMessageW(GetParent(hWnd), WM_MOUSEACTIVATE,
1942 Ret = SendMessageA(GetParent(hWnd), WM_MOUSEACTIVATE,
1950 return ((LOWORD(lParam) >= HTCLIENT) ? MA_ACTIVATE : MA_NOACTIVATE);
1955 /* Check if the window is minimized. */
1956 if (LOWORD(lParam) != WA_INACTIVE &&
1957 !(GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE))
1966 if (GetWindowLongW(hWnd, GWL_STYLE & WS_CHILD))
1970 return (SendMessageW(GetParent(hWnd), WM_MOUSEWHEEL,
1975 return (SendMessageA(GetParent(hWnd), WM_MOUSEWHEEL,
1983 case WM_ICONERASEBKGND:
1986 HBRUSH hBrush = (HBRUSH)GetClassLongW(hWnd, GCL_HBRBACKGROUND);
1992 if (0 == (((DWORD) hBrush) & 0xffff0000))
1994 hBrush = GetSysColorBrush((DWORD) hBrush - 1);
1996 GetClipBox((HDC)wParam, &Rect);
1997 FillRect((HDC)wParam, &Rect, hBrush);
2001 case WM_CTLCOLORMSGBOX:
2002 case WM_CTLCOLOREDIT:
2003 case WM_CTLCOLORLISTBOX:
2004 case WM_CTLCOLORBTN:
2005 case WM_CTLCOLORDLG:
2006 case WM_CTLCOLORSTATIC:
2007 case WM_CTLCOLORSCROLLBAR:
2008 return (LRESULT) DefWndControlColor((HDC)wParam, Msg - WM_CTLCOLORMSGBOX);
2012 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD)
2014 if (LOWORD(lParam) < HTLEFT || LOWORD(lParam) > HTBOTTOMRIGHT)
2019 bResult = SendMessageW(GetParent(hWnd), WM_SETCURSOR,
2024 bResult = SendMessageA(GetParent(hWnd), WM_SETCURSOR,
2033 return (DefWndHandleSetCursor(hWnd, wParam, lParam));
2039 Pt.x = SLOWORD(lParam);
2040 Pt.y = SHIWORD(lParam);
2041 return (DefWndHandleSysCommand(hWnd, wParam, Pt));
2044 /* FIXME: Handle key messages. */
2052 /* FIXME: This is also incomplete. */
2055 if (HIWORD(lParam) & KEYDATA_ALT)
2057 if (wParam == VK_F4) /* Try to close the window */
2059 HWND top = GetAncestor(hWnd, GA_ROOT);
2060 if (!(GetClassLongW(top, GCL_STYLE) & CS_NOCLOSE))
2063 PostMessageW(top, WM_SYSCOMMAND, SC_CLOSE, 0);
2065 PostMessageA(top, WM_SYSCOMMAND, SC_CLOSE, 0);
2078 Style = GetWindowLongW(hWnd, GWL_STYLE);
2079 if (!(Style & WS_POPUP))
2081 if ((Style & WS_VISIBLE) && wParam)
2083 if (!(Style & WS_VISIBLE) && !wParam)
2085 if (!GetWindow(hWnd, GW_OWNER))
2087 ShowWindow(hWnd, wParam ? SW_SHOWNA : SW_HIDE);
2093 /* FIXME: Check for a desktop. */
2094 if (GetCapture() == hWnd)
2106 /* FIXME: Implement this. */
2109 case WM_QUERYDROPOBJECT:
2111 if (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_ACCEPTFILES)
2118 case WM_QUERYDRAGICON:
2123 hIcon = (HICON)GetClassLongW(hWnd, GCL_HICON);
2126 return ((LRESULT)hIcon);
2128 for (Len = 1; Len < 64; Len++)
2130 if ((hIcon = LoadIconW(NULL, MAKEINTRESOURCEW(Len))) != NULL)
2132 return((LRESULT)hIcon);
2135 return ((LRESULT)LoadIconW(0, IDI_APPLICATION));
2138 /* FIXME: WM_ISACTIVEICON */
2140 case WM_NOTIFYFORMAT:
2142 if (IsWindowUnicode(hWnd))
2144 return(NFR_UNICODE);
2154 INT Index = (wParam != 0) ? GCL_HICON : GCL_HICONSM;
2155 HICON hOldIcon = (HICON)GetClassLongW(hWnd, Index);
2156 SetClassLongW(hWnd, Index, lParam);
2157 SetWindowPos(hWnd, 0, 0, 0, 0, 0,
2158 SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
2159 SWP_NOACTIVATE | SWP_NOZORDER);
2160 return ((LRESULT)hOldIcon);
2165 INT Index = (wParam != 0) ? GCL_HICON : GCL_HICONSM;
2166 return (GetClassLongW(hWnd, Index));
2173 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
2177 SendMessageA(GetParent(hWnd), Msg, wParam, lParam);
2183 case WM_QUERYENDSESSION:
2193 DefWindowProcA(HWND hWnd,
2198 static LPSTR WindowTextAtom = 0;
2205 CREATESTRUCTA *Cs = (CREATESTRUCTA*)lParam;
2206 if (HIWORD(Cs->lpszName))
2208 if (0 == WindowTextAtom)
2211 (LPSTR)(ULONG)GlobalAddAtomA("USER32!WindowTextAtomA");
2213 WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
2214 strlen(Cs->lpszName) * sizeof(CHAR));
2215 strcpy(WindowText, Cs->lpszName);
2216 SetPropA(hWnd, WindowTextAtom, WindowText);
2221 case WM_GETTEXTLENGTH:
2223 if (WindowTextAtom == 0 ||
2224 (WindowText = GetPropA(hWnd, WindowTextAtom)) == NULL)
2228 return (strlen(WindowText));
2233 if (WindowTextAtom == 0 ||
2234 (WindowText = GetPropA(hWnd, WindowTextAtom)) == NULL)
2238 *((PSTR)lParam) = '\0';
2242 strncpy((LPSTR)lParam, WindowText, wParam);
2243 return (min(wParam, strlen(WindowText)));
2248 if (0 == WindowTextAtom)
2251 (LPSTR)(DWORD)GlobalAddAtomA("USER32!WindowTextAtomA");
2253 if (WindowTextAtom != 0 &&
2254 (WindowText = GetPropA(hWnd, WindowTextAtom)) == NULL)
2256 RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText);
2258 WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
2259 (strlen((PSTR)lParam) + 1) * sizeof(CHAR));
2260 strcpy(WindowText, (PSTR)lParam);
2261 SetPropA(hWnd, WindowTextAtom, WindowText);
2262 if (0 != (GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION))
2264 DefWndPaintNC(hWnd, (HRGN) 1);
2270 FIXME: Implement these.
2272 case WM_IME_KEYDOWN:
2274 case WM_IME_STARTCOMPOSITION:
2275 case WM_IME_COMPOSITION:
2276 case WM_IME_ENDCOMPOSITION:
2278 case WM_IME_SETCONTEXT:
2283 if (WindowTextAtom != 0 &&
2284 (WindowText = RemovePropA(hWnd, WindowTextAtom)) == NULL)
2286 RtlFreeHeap(GetProcessHeap(), 0, WindowText);
2292 return User32DefWindowProc(hWnd, Msg, wParam, lParam, FALSE);
2297 DefWindowProcW(HWND hWnd,
2302 static LPWSTR WindowTextAtom = 0;
2309 CREATESTRUCTW* CreateStruct = (CREATESTRUCTW*)lParam;
2310 if (HIWORD(CreateStruct->lpszName))
2312 if (0 == WindowTextAtom)
2315 (LPWSTR)(DWORD)GlobalAddAtomW(L"USER32!WindowTextAtomW");
2317 WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
2318 wcslen(CreateStruct->lpszName) * sizeof(WCHAR));
2319 wcscpy(WindowText, CreateStruct->lpszName);
2320 SetPropW(hWnd, WindowTextAtom, WindowText);
2325 case WM_GETTEXTLENGTH:
2327 if (WindowTextAtom == 0 ||
2328 (WindowText = GetPropW(hWnd, WindowTextAtom)) == NULL)
2332 return (wcslen(WindowText));
2337 if (WindowTextAtom == 0 ||
2338 (WindowText = GetPropW(hWnd, WindowTextAtom)) == NULL)
2342 ((PWSTR)lParam) = '\0';
2346 wcsncpy((PWSTR)lParam, WindowText, wParam);
2347 return (min(wParam, wcslen(WindowText)));
2352 if (WindowTextAtom == 0)
2355 (LPWSTR)(DWORD)GlobalAddAtomW(L"USER32!WindowTextAtomW");
2357 if (WindowTextAtom != 0 &&
2358 (WindowText = GetPropW(hWnd, WindowTextAtom)) == NULL)
2360 RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText);
2362 WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
2363 (wcslen((PWSTR)lParam) + 1) * sizeof(WCHAR));
2364 wcscpy(WindowText, (PWSTR)lParam);
2365 SetPropW(hWnd, WindowTextAtom, WindowText);
2366 if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION)
2368 DefWndPaintNC(hWnd, (HRGN)1);
2375 SendMessageW(hWnd, WM_CHAR, wParam, lParam);
2379 case WM_IME_SETCONTEXT:
2387 if (WindowTextAtom != 0 &&
2388 (WindowText = RemovePropW(hWnd, WindowTextAtom)) == NULL)
2390 RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText);
2396 return User32DefWindowProc(hWnd, Msg, wParam, lParam, TRUE);