1 /* $Id: defwnd.c,v 1.54 2003/07/05 17:57:22 chorns Exp $
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>
23 /* GLOBALS *******************************************************************/
25 static HBITMAP hbSysMenu
;
26 /* TODO: widgets will be cached here.
27 static HBITMAP hbClose;
28 static HBITMAP hbCloseD;
29 static HBITMAP hbMinimize;
30 static HBITMAP hbMinimizeD;
31 static HBITMAP hbRestore;
32 static HBITMAP hbRestoreD;
33 static HBITMAP hbMaximize;
34 static HBITMAP hbScrUp;
35 static HBITMAP hbScrDwn;
36 static HBITMAP hbScrLeft;
37 static HBITMAP hbScrRight;
39 static COLORREF SysColours
[] =
41 RGB(224, 224, 224) /* COLOR_SCROLLBAR */,
42 RGB(58, 110, 165) /* COLOR_BACKGROUND */,
43 RGB(0, 0, 128) /* COLOR_ACTIVECAPTION */,
44 RGB(128, 128, 128) /* COLOR_INACTIVECAPTION */,
45 RGB(192, 192, 192) /* COLOR_MENU */,
46 RGB(192, 192, 192) /* COLOR_WINDOW */,
47 RGB(192, 192, 192) /* COLOR_WINDOWFRAME */,
48 RGB(0, 0, 0) /* COLOR_MENUTEXT */,
49 RGB(0, 0, 0) /* COLOR_WINDOWTEXT */,
50 RGB(255, 255, 255) /* COLOR_CAPTIONTEXT */,
51 RGB(128, 128, 128) /* COLOR_ACTIVEBORDER */,
52 RGB(255, 255, 255) /* COLOR_INACTIVEBORDER */,
53 RGB(255, 255, 232) /* COLOR_APPWORKSPACE */,
54 RGB(224, 224, 224) /* COLOR_HILIGHT */,
55 RGB(0, 0, 128) /* COLOR_HILIGHTTEXT */,
56 RGB(192, 192, 192) /* COLOR_BTNFACE */,
57 RGB(128, 128, 128) /* COLOR_BTNSHADOW */,
58 RGB(192, 192, 192) /* COLOR_GRAYTEXT */,
59 RGB(0, 0, 0) /* COLOR_BTNTEXT */,
60 RGB(192, 192, 192) /* COLOR_INACTIVECAPTIONTEXT */,
61 RGB(255, 255, 255) /* COLOR_BTNHILIGHT */,
62 RGB(32, 32, 32) /* COLOR_3DDKSHADOW */,
63 RGB(192, 192, 192) /* COLOR_3DLIGHT */,
64 RGB(0, 0, 0) /* COLOR_INFOTEXT */,
65 RGB(255, 255, 192) /* COLOR_INFOBK */,
66 RGB(184, 180, 184) /* COLOR_ALTERNATEBTNFACE */,
67 RGB(0, 0, 255) /* COLOR_HOTLIGHT */,
68 RGB(16, 132, 208) /* COLOR_GRADIENTACTIVECAPTION */,
69 RGB(181, 181, 181) /* COLOR_GRADIENTINACTIVECAPTION */,
72 static ATOM AtomInternalPos
;
74 /* Bits in the dwKeyData */
75 #define KEYDATA_ALT 0x2000
77 /* FUNCTIONS *****************************************************************/
79 BOOL
IsMaxBoxActive(HWND hWnd
)
81 ULONG uStyle
= GetWindowLong( hWnd
, GWL_STYLE
);
82 return (uStyle
& WS_MAXIMIZEBOX
);
85 BOOL
IsCloseBoxActive( HWND hWnd
)
87 ULONG uStyle
= GetWindowLong(hWnd
, GWL_STYLE
);
88 return ( uStyle
& WS_SYSMENU
);
91 BOOL
IsMinBoxActive( HWND hWnd
)
93 ULONG uStyle
= GetWindowLong( hWnd
, GWL_STYLE
);
94 return (uStyle
& WS_MINIMIZEBOX
);
97 INT
UIGetFrameSizeX( HWND hWnd
)
99 ULONG uStyle
= GetWindowLong( hWnd
, GWL_STYLE
);
101 if ( uStyle
& WS_THICKFRAME
)
102 return GetSystemMetrics( SM_CXSIZEFRAME
);
104 return GetSystemMetrics( SM_CXFRAME
);
107 INT
UIGetFrameSizeY( HWND hWnd
)
109 ULONG uStyle
= GetWindowLong( hWnd
, GWL_STYLE
);
111 if ( uStyle
& WS_THICKFRAME
)
112 return GetSystemMetrics( SM_CYSIZEFRAME
);
114 return GetSystemMetrics( SM_CYFRAME
);
118 UserSetupInternalPos( VOID
)
121 AtomInternalPos
= GlobalAddAtomA(Str
);
125 GetSysColor(int nIndex
)
127 return SysColours
[nIndex
];
131 GetSysColorPen( int nIndex
)
133 return(CreatePen(PS_SOLID
, 1, SysColours
[nIndex
]));
137 GetSysColorBrush( int nIndex
)
139 return(CreateSolidBrush(SysColours
[nIndex
]));
144 DefFrameProcA( HWND hWnd
,
155 DefFrameProcW(HWND hWnd
,
167 DefWndRedrawIconTitle(HWND hWnd
)
169 PINTERNALPOS lpPos
= (PINTERNALPOS
)GetPropA(hWnd
,
170 (LPSTR
)(DWORD
)AtomInternalPos
);
173 if (lpPos
->IconTitle
!= NULL
)
175 SendMessageA(lpPos
->IconTitle
, WM_SHOWWINDOW
, TRUE
, 0);
176 InvalidateRect(lpPos
->IconTitle
, NULL
, TRUE
);
184 UserHasMenu(HWND hWnd
, ULONG Style
)
186 return(!(Style
& WS_CHILD
) && GetWindowLong(hWnd
, GWL_ID
) != 0);
190 UserHasAnyFrameStyle(ULONG Style
, ULONG ExStyle
)
192 return((Style
& (WS_THICKFRAME
| WS_DLGFRAME
| WS_BORDER
)) ||
193 (ExStyle
& WS_EX_DLGMODALFRAME
) ||
194 (!(Style
& (WS_CHILD
| WS_POPUP
))));
198 UserHasDlgFrameStyle(ULONG Style
, ULONG ExStyle
)
200 return((ExStyle
& WS_EX_DLGMODALFRAME
) ||
201 ((Style
& WS_DLGFRAME
) && (!(Style
& WS_THICKFRAME
))));
205 UserHasThickFrameStyle(ULONG Style
, ULONG ExStyle
)
207 return((Style
& WS_THICKFRAME
) &&
208 (!((Style
& (WS_DLGFRAME
| WS_BORDER
)) == WS_DLGFRAME
)));
212 UserHasThinFrameStyle(ULONG Style
, ULONG ExStyle
)
214 return((Style
& WS_BORDER
) ||
215 (!(Style
& (WS_CHILD
| WS_POPUP
))));
219 UserHasBigFrameStyle(ULONG Style
, ULONG ExStyle
)
221 return((Style
& (WS_THICKFRAME
| WS_DLGFRAME
)) ||
222 (ExStyle
& WS_EX_DLGMODALFRAME
));
225 void UserGetInsideRectNC( HWND hWnd
, RECT
*rect
)
231 Style
= GetWindowLong(hWnd
, GWL_STYLE
);
232 ExStyle
= GetWindowLong(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
;
238 if (Style
& WS_ICONIC
)
243 /* Remove frame from rectangle */
244 if (UserHasThickFrameStyle(Style
, ExStyle
))
246 InflateRect( rect
, -GetSystemMetrics(SM_CXFRAME
),
247 -GetSystemMetrics(SM_CYFRAME
) );
251 if (UserHasDlgFrameStyle(Style
, ExStyle
))
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 );
261 if (UserHasThinFrameStyle(Style
, ExStyle
))
263 InflateRect(rect
, -GetSystemMetrics(SM_CXBORDER
),
264 -GetSystemMetrics(SM_CYBORDER
));
270 void UserDrawSysMenuButton( HWND hWnd
, HDC hDC
, BOOL down
)
274 HBITMAP hSavedBitmap
;
276 hbSysMenu
= LoadBitmap(0, MAKEINTRESOURCE(OBM_CLOSE
));
277 UserGetInsideRectNC(hWnd
, &Rect
);
278 hDcMem
= CreateCompatibleDC(hDC
);
279 hSavedBitmap
= SelectObject(hDcMem
, hbSysMenu
);
280 BitBlt(hDC
, Rect
.left
+ 2, Rect
.top
+
282 (GetWindowLong(hWnd
, GWL_STYLE
) & WS_CHILD
) ?
283 GetSystemMetrics(SM_CXSIZE
): 0, 0, SRCCOPY
);
284 SelectObject(hDcMem
, hSavedBitmap
);
288 /* FIXME: Cache bitmaps, then just bitblt instead of calling DFC() (and
289 wasting precious CPU cycles) every time */
291 static void UserDrawCloseButton ( HWND hWnd
, HDC hDC
, BOOL bDown
)
295 BOOL bToolWindow
= GetWindowLongA( hWnd
, GWL_EXSTYLE
) & WS_EX_TOOLWINDOW
;
296 INT iBmpWidth
= (bToolWindow
? GetSystemMetrics(SM_CXSMSIZE
) :
297 GetSystemMetrics(SM_CXSIZE
)) - 2;
298 INT iBmpHeight
= (bToolWindow
? GetSystemMetrics(SM_CYSMSIZE
) :
299 GetSystemMetrics(SM_CYSIZE
) - 4);
300 INT OffsetX
= UIGetFrameSizeY( hWnd
);
301 INT OffsetY
= UIGetFrameSizeY( hWnd
);
304 if(!(GetWindowLong( hWnd
, GWL_STYLE
) & WS_SYSMENU
))
308 GetWindowRect( hWnd
, &rect
);
310 rect
.right
= rect
.right
- rect
.left
;
311 rect
.bottom
= rect
.bottom
- rect
.top
;
312 rect
.left
= rect
.top
= 0;
314 rect
.right
- OffsetX
- iBmpWidth
- 3,
316 rect
.right
- OffsetX
- 3,
317 rect
.top
+ iBmpHeight
+ OffsetY
+ 2 );
319 DrawFrameControl( hDC
, &rect
, DFC_CAPTION
,
321 (bDown
? DFCS_PUSHED
: 0) |
322 (IsCloseBoxActive(hWnd
) ? 0 : DFCS_INACTIVE
)) );
325 static void UserDrawMaxButton( HWND hWnd
, HDC hDC
, BOOL bDown
)
329 INT iBmpWidth
= GetSystemMetrics(SM_CXSIZE
) - 2;
330 INT iBmpHeight
= GetSystemMetrics(SM_CYSIZE
) - 4;
332 INT OffsetX
= UIGetFrameSizeY( hWnd
);
333 INT OffsetY
= UIGetFrameSizeY( hWnd
);
335 GetWindowRect( hWnd
, &rect
);
337 if (!IsMinBoxActive(hWnd
) && !IsMaxBoxActive(hWnd
))
339 if ((GetWindowLongA( hWnd
, GWL_EXSTYLE
) & WS_EX_TOOLWINDOW
) == TRUE
)
340 return; /* ToolWindows don't have min/max buttons */
342 rect
.right
= rect
.right
- rect
.left
;
343 rect
.bottom
= rect
.bottom
- rect
.top
;
344 rect
.left
= rect
.top
= 0;
346 rect
.right
- OffsetX
- (iBmpWidth
*2) - 5,
348 rect
.right
- iBmpWidth
- OffsetX
- 5,
349 rect
.top
+ iBmpHeight
+ OffsetY
+ 2 );
351 DrawFrameControl( hDC
, &rect
, DFC_CAPTION
,
352 (IsZoomed(hWnd
) ? DFCS_CAPTIONRESTORE
: DFCS_CAPTIONMAX
) |
353 (bDown
? DFCS_PUSHED
: 0) |
354 (IsMaxBoxActive(hWnd
) ? 0 : DFCS_INACTIVE
) );
358 static void UserDrawMinButton( HWND hWnd
, HDC hDC
, BOOL bDown
)
362 INT iBmpWidth
= GetSystemMetrics(SM_CXSIZE
) - 2;
363 INT iBmpHeight
= GetSystemMetrics(SM_CYSIZE
) - 4;
365 INT OffsetX
= UIGetFrameSizeX( hWnd
);
366 INT OffsetY
= UIGetFrameSizeY( hWnd
);
368 GetWindowRect( hWnd
, &rect
);
370 if (!IsMinBoxActive(hWnd
) && !IsMaxBoxActive(hWnd
))
372 if ((GetWindowLongA( hWnd
, GWL_EXSTYLE
) & WS_EX_TOOLWINDOW
) == TRUE
)
373 return; /* ToolWindows don't have min/max buttons */
375 rect
.right
= rect
.right
- rect
.left
;
376 rect
.bottom
= rect
.bottom
- rect
.top
;
377 rect
.left
= rect
.top
= 0;
379 rect
.right
- OffsetX
- (iBmpWidth
*3) - 5,
381 rect
.right
- (iBmpWidth
* 2) - OffsetX
- 5,
382 rect
.top
+ iBmpHeight
+ OffsetY
+ 2 );
383 DrawFrameControl( hDC
, &rect
, DFC_CAPTION
,
384 DFCS_CAPTIONMIN
| (bDown
? DFCS_PUSHED
: 0) |
385 (IsMinBoxActive(hWnd
) ? 0 : DFCS_INACTIVE
) );
388 static void UserDrawCaptionNC( HDC hDC
, RECT
*rect
, HWND hWnd
,
389 DWORD style
, BOOL active
)
393 /* FIXME: Implement and Use DrawCaption() */
394 SelectObject( hDC
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
: COLOR_INACTIVECAPTION
) );
396 PatBlt(hDC
,rect
->left
+ GetSystemMetrics(SM_CXFRAME
), rect
->top
+
397 GetSystemMetrics(SM_CYFRAME
), rect
->right
- (GetSystemMetrics(SM_CXFRAME
) * 2), (rect
->top
+
398 GetSystemMetrics(SM_CYCAPTION
)) - 1, PATCOPY
);
400 if (style
& WS_SYSMENU
)
402 UserDrawSysMenuButton( hWnd
, hDC
, FALSE
);
403 r
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
404 UserDrawCloseButton( hWnd
, hDC
, FALSE
);
405 r
.right
-= GetSystemMetrics(SM_CXSMSIZE
) + 1;
406 UserDrawMinButton(hWnd
, hDC
, FALSE
);
407 UserDrawMaxButton(hWnd
, hDC
, FALSE
);
409 if (GetWindowTextA( hWnd
, buffer
, sizeof(buffer
) ))
411 NONCLIENTMETRICS nclm
;
412 HFONT hFont
, hOldFont
;
414 nclm
.cbSize
= sizeof(NONCLIENTMETRICS
);
415 SystemParametersInfoW(SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
416 SetTextColor(hDC
, SysColours
[ active
? COLOR_CAPTIONTEXT
: COLOR_INACTIVECAPTIONTEXT
]);
417 SetBkMode( hDC
, TRANSPARENT
);
418 if (style
& WS_EX_TOOLWINDOW
)
419 hFont
= CreateFontIndirectW(&nclm
.lfSmCaptionFont
);
421 hFont
= CreateFontIndirectW(&nclm
.lfCaptionFont
);
422 hOldFont
= SelectObject(hDC
, hFont
);
423 TextOutA(hDC
, r
.left
+ (GetSystemMetrics(SM_CXDLGFRAME
) * 2), rect
->top
+ (nclm
.lfCaptionFont
.lfHeight
/ 2), buffer
, strlen(buffer
));
424 DeleteObject (SelectObject (hDC
, hOldFont
));
429 UserDrawFrameNC(HWND hWnd
, RECT
* rect
, BOOL dlgFrame
, BOOL active
)
431 HDC hDC
= GetWindowDC(hWnd
);
432 SelectObject( hDC
, GetSysColorBrush(COLOR_WINDOW
) );
433 DrawEdge(hDC
, rect
,EDGE_RAISED
, BF_RECT
| BF_MIDDLE
);
436 void SCROLL_DrawScrollBar (HWND hWnd
, HDC hDC
, INT nBar
, BOOL arrows
, BOOL interior
);
439 DefWndDoPaintNC(HWND hWnd
, HRGN clip
)
446 Active
= GetWindowLongW(hWnd
, GWL_STYLE
) & WIN_NCACTIVATED
;
447 Style
= GetWindowLong(hWnd
, GWL_STYLE
);
448 ExStyle
= GetWindowLong(hWnd
, GWL_EXSTYLE
);
450 hDC
= GetDCEx(hWnd
, (clip
> (HRGN
)1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
451 ((clip
> (HRGN
)1) ? (DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
) : 0));
457 /* FIXME: Test whether we need to draw anything at all. */
459 GetWindowRect(hWnd
, &rect
);
460 rect
.right
= rect
.right
- rect
.left
;
461 rect
.bottom
= rect
.bottom
- rect
.top
;
462 rect
.top
= rect
.left
= 0;
463 SelectObject(hDC
, GetSysColorPen(COLOR_WINDOWFRAME
));
464 if (UserHasThickFrameStyle(Style
, ExStyle
))
466 UserDrawFrameNC(hWnd
, &rect
, FALSE
, Active
);
468 else if (UserHasDlgFrameStyle(Style
, ExStyle
))
470 UserDrawFrameNC(hWnd
, &rect
, TRUE
, Active
);
472 if (Style
& WS_CAPTION
)
475 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
);
476 rect
.top
+= GetSystemMetrics(SM_CYSIZE
) +
477 GetSystemMetrics(SM_CYBORDER
);
478 UserDrawCaptionNC(hDC
, &r
, hWnd
, Style
, Active
);
481 /* FIXME: Draw menu bar. */
483 DPRINT("drawing scrollbars..\n");
484 /* Draw scrollbars */
485 if (Style
& WS_VSCROLL
)
486 SCROLL_DrawScrollBar(hWnd
, hDC
, SB_VERT
, TRUE
, TRUE
);
487 if (Style
& WS_HSCROLL
)
488 SCROLL_DrawScrollBar(hWnd
, hDC
, SB_HORZ
, TRUE
, TRUE
);
490 /* FIXME: Draw size box.*/
492 ReleaseDC(hWnd
, hDC
);
497 DefWndPaintNC(HWND hWnd
, HRGN clip
)
499 if (IsWindowVisible(hWnd
))
503 DefWndRedrawIconTitle(hWnd
);
507 DefWndDoPaintNC(hWnd
, clip
);
514 DefWndHitTestNC(HWND hWnd
, POINT Point
)
517 ULONG Style
= GetWindowLong(hWnd
, GWL_STYLE
);
518 ULONG ExStyle
= GetWindowLong(hWnd
, GWL_EXSTYLE
);
520 GetWindowRect(hWnd
, &WindowRect
);
521 if (!PtInRect(&WindowRect
, Point
))
526 if (Style
& WS_MINIMIZE
)
530 if (UserHasThickFrameStyle(Style
, ExStyle
))
532 InflateRect(&WindowRect
, -GetSystemMetrics(SM_CXFRAME
),
533 -GetSystemMetrics(SM_CYFRAME
));
534 if (!PtInRect(&WindowRect
, Point
))
536 if (Point
.y
< WindowRect
.top
)
538 if (Point
.x
< (WindowRect
.left
+ GetSystemMetrics(SM_CXSIZE
)))
542 if (Point
.x
>= (WindowRect
.right
- GetSystemMetrics(SM_CXSIZE
)))
548 if (Point
.y
>= WindowRect
.bottom
)
550 if (Point
.x
< (WindowRect
.left
+ GetSystemMetrics(SM_CXSIZE
)))
552 return(HTBOTTOMLEFT
);
554 if (Point
.x
>= (WindowRect
.right
- GetSystemMetrics(SM_CXSIZE
)))
556 return(HTBOTTOMRIGHT
);
560 if (Point
.x
< WindowRect
.left
)
562 if (Point
.y
< (WindowRect
.top
+ GetSystemMetrics(SM_CYSIZE
)))
566 if (Point
.y
>= (WindowRect
.bottom
- GetSystemMetrics(SM_CYSIZE
)))
568 return(HTBOTTOMLEFT
);
572 if (Point
.x
>= WindowRect
.right
)
574 if (Point
.y
< (WindowRect
.top
+ GetSystemMetrics(SM_CYSIZE
)))
578 if (Point
.y
>= (WindowRect
.bottom
- GetSystemMetrics(SM_CYSIZE
)))
580 return(HTBOTTOMRIGHT
);
588 if (UserHasDlgFrameStyle(Style
, ExStyle
))
590 InflateRect(&WindowRect
, -GetSystemMetrics(SM_CXDLGFRAME
),
591 -GetSystemMetrics(SM_CYDLGFRAME
));
593 else if (UserHasThinFrameStyle(Style
, ExStyle
))
595 InflateRect(&WindowRect
, -GetSystemMetrics(SM_CXBORDER
),
596 -GetSystemMetrics(SM_CYBORDER
));
598 if (!PtInRect(&WindowRect
, Point
))
604 if ((Style
& WS_CAPTION
) == WS_CAPTION
)
606 WindowRect
.top
+= (GetSystemMetrics(SM_CYCAPTION
) -
607 GetSystemMetrics(SM_CYBORDER
));
608 if (!PtInRect(&WindowRect
, Point
))
610 if ((Style
& WS_SYSMENU
) && !(ExStyle
& WS_EX_TOOLWINDOW
))
612 WindowRect
.left
+= GetSystemMetrics(SM_CXSIZE
);
613 WindowRect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
615 if (Point
.x
<= WindowRect
.left
)
619 if (WindowRect
.right
<= Point
.x
)
624 if (Style
& WS_MAXIMIZEBOX
|| Style
& WS_MINIMIZEBOX
)
626 WindowRect
.right
-= GetSystemMetrics(SM_CXSIZE
) - 2;
628 if (Point
.x
>= WindowRect
.right
)
633 if (Style
& WS_MINIMIZEBOX
)
635 WindowRect
.right
-= GetSystemMetrics(SM_CXSIZE
) - 2;
637 if (Point
.x
>= WindowRect
.right
)
645 ScreenToClient(hWnd
, &Point
);
646 GetClientRect(hWnd
, &WindowRect
);
648 if (PtInRect(&WindowRect
, Point
))
653 if (Style
& WS_VSCROLL
)
655 WindowRect
.right
+= GetSystemMetrics(SM_CXVSCROLL
);
656 if (PtInRect(&WindowRect
, Point
))
662 if (Style
& WS_HSCROLL
)
664 WindowRect
.bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
665 if (PtInRect(&WindowRect
, Point
))
667 if ((Style
& WS_VSCROLL
) &&
668 (Point
.x
>= (WindowRect
.right
- GetSystemMetrics(SM_CXVSCROLL
))))
676 if (UserHasMenu(hWnd
, Style
))
678 if (Point
.y
< 0 && Point
.x
>= 0 && Point
.x
<= WindowRect
.right
)
688 DefWndDrawSysButton(HWND hWnd
, HDC hDC
, BOOL Down
)
694 DefWndHandleLButtonDownNC(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
700 HWND hTopWnd
= GetAncestor(hWnd
, GA_ROOT
);
701 if (SetActiveWindow(hTopWnd
) || GetActiveWindow() == hTopWnd
)
703 SendMessageA(hWnd
, WM_SYSCOMMAND
, SC_MOVE
+ HTCAPTION
, lParam
);
709 if (GetWindowLong(hWnd
, GWL_STYLE
) & WS_SYSMENU
)
711 if (!(GetWindowLong(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
713 HDC hDC
= GetWindowDC(hWnd
);
714 DefWndDrawSysButton(hWnd
, hDC
, TRUE
);
715 ReleaseDC(hWnd
, hDC
);
717 SendMessageA(hWnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
+ HTSYSMENU
,
724 SendMessageA(hWnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
, lParam
);
729 SendMessageA(hWnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
734 SendMessageA(hWnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
739 UserDrawMinButton(hWnd
, GetWindowDC(hWnd
), IsMinBoxActive(hWnd
) );
744 UserDrawMaxButton(hWnd
,GetWindowDC(hWnd
), IsMaxBoxActive(hWnd
) );
749 UserDrawCloseButton(hWnd
,GetWindowDC(hWnd
),TRUE
);
761 SendMessageA(hWnd
, WM_SYSCOMMAND
, SC_SIZE
+ wParam
- 2, lParam
);
769 DefWndHandleLButtonDblClkNC(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
776 DefWndHandleLButtonUpNC(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
778 UserDrawMinButton(hWnd
,GetWindowDC(hWnd
),FALSE
);
779 UserDrawMaxButton(hWnd
,GetWindowDC(hWnd
),FALSE
);
780 UserDrawCloseButton(hWnd
,GetWindowDC(hWnd
),FALSE
);
785 SendMessageA(hWnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
790 SendMessageA(hWnd
, WM_SYSCOMMAND
, SC_MAXIMIZE
, 0);
795 SendMessageA(hWnd
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
803 DefWndHandleActiveNC(HWND hWnd
, WPARAM wParam
)
810 DefWndSetRedraw(HWND hWnd
, WPARAM wParam
)
816 DefWndHandleSetCursor(HWND hWnd
, WPARAM wParam
, LPARAM lParam
)
818 /* Not for child windows. */
819 if (hWnd
!= (HWND
)wParam
)
824 switch(LOWORD(lParam
))
828 WORD Msg
= HIWORD(lParam
);
829 if (Msg
== WM_LBUTTONDOWN
|| Msg
== WM_MBUTTONDOWN
||
830 Msg
== WM_RBUTTONDOWN
)
839 HICON hCursor
= (HICON
)GetClassLong(hWnd
, GCL_HCURSOR
);
851 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZEWE
)));
857 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENS
)));
863 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENWSE
)));
869 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_SIZENESW
)));
872 return((LRESULT
)SetCursor(LoadCursorW(0, IDC_ARROW
)));
876 DefWndHandleSysCommand(HWND hWnd
, WPARAM wParam
, POINT Pt
)
881 SendMessageA(hWnd
, WM_CLOSE
, 0, 0);
884 /* FIXME: Implement */
893 DefWndAdjustRect(RECT
* Rect
, ULONG Style
, BOOL Menu
, ULONG ExStyle
)
895 if (Style
& WS_ICONIC
)
900 if (UserHasThickFrameStyle(Style
, ExStyle
))
902 InflateRect(Rect
, GetSystemMetrics(SM_CXFRAME
),
903 GetSystemMetrics(SM_CYFRAME
));
905 else if (UserHasDlgFrameStyle(Style
, ExStyle
))
907 InflateRect(Rect
, GetSystemMetrics(SM_CXDLGFRAME
),
908 GetSystemMetrics(SM_CYDLGFRAME
));
910 else if (UserHasThinFrameStyle(Style
, ExStyle
))
912 InflateRect(Rect
, GetSystemMetrics(SM_CXBORDER
),
913 GetSystemMetrics(SM_CYBORDER
));
915 if (Style
& WS_CAPTION
)
917 Rect
->top
-= (GetSystemMetrics(SM_CYCAPTION
) -
918 GetSystemMetrics(SM_CYBORDER
)) + 1;
922 Rect
->top
-= GetSystemMetrics(SM_CYMENU
) + GetSystemMetrics(SM_CYBORDER
);
924 if (Style
& WS_VSCROLL
)
926 Rect
->right
+= GetSystemMetrics(SM_CXVSCROLL
) - 1;
927 if (UserHasAnyFrameStyle(Style
, ExStyle
))
932 if (Style
& WS_HSCROLL
)
934 Rect
->bottom
+= GetSystemMetrics(SM_CYHSCROLL
) - 1;
935 if (UserHasAnyFrameStyle(Style
, ExStyle
))
943 DefWndNCCalcSize(HWND hWnd
, RECT
* Rect
)
946 LONG Style
= GetClassLongW(hWnd
, GCL_STYLE
);
947 RECT TmpRect
= {0, 0, 0, 0};
949 if (Style
& CS_VREDRAW
)
951 Result
|= WVR_VREDRAW
;
953 if (Style
& CS_HREDRAW
)
955 Result
|= WVR_HREDRAW
;
958 if (!(GetWindowLong(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
960 DefWndAdjustRect(&TmpRect
, GetWindowLong(hWnd
, GWL_STYLE
),
961 FALSE
, GetWindowLong(hWnd
, GWL_EXSTYLE
));
962 Rect
->left
-= TmpRect
.left
;
963 Rect
->top
-= TmpRect
.top
;
964 Rect
->right
-= TmpRect
.right
;
965 Rect
->bottom
-= TmpRect
.bottom
;
966 /* FIXME: Adjust if the window has a menu. */
967 Rect
->bottom
= max(Rect
->top
, Rect
->bottom
);
968 Rect
->right
= max(Rect
->left
, Rect
->right
);
974 DefWndHandleWindowPosChanging(HWND hWnd
, WINDOWPOS
* Pos
)
981 User32DefWindowProc(HWND hWnd
,
991 return(DefWndPaintNC(hWnd
, (HRGN
)wParam
));
993 case WM_WINDOWPOSCHANGING
:
995 DbgPrint("WM_WINDOWPOSCHANGING\n\n");
1001 Point
.x
= SLOWORD(lParam
);
1002 Point
.y
= SHIWORD(lParam
);
1003 return(DefWndHitTestNC(hWnd
, Point
));
1006 case WM_NCLBUTTONDOWN
:
1008 return(DefWndHandleLButtonDownNC(hWnd
, wParam
, lParam
));
1011 case WM_NCLBUTTONUP
:
1013 return(DefWndHandleLButtonUpNC(hWnd
, wParam
, lParam
));
1016 case WM_LBUTTONDBLCLK
:
1017 case WM_NCLBUTTONDBLCLK
:
1019 return(DefWndHandleLButtonDblClkNC(hWnd
, wParam
, lParam
));
1022 case WM_NCRBUTTONDOWN
:
1024 if (wParam
== HTCAPTION
)
1037 if (hWnd
== GetCapture())
1041 Pt
.x
= SLOWORD(lParam
);
1042 Pt
.y
= SHIWORD(lParam
);
1043 ClientToScreen(hWnd
, &Pt
);
1044 lParam
= MAKELPARAM(Pt
.x
, Pt
.y
);
1047 SendMessageW(hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1051 SendMessageA (hWnd
, WM_CONTEXTMENU
, (WPARAM
)hWnd
, lParam
);
1056 case WM_NCRBUTTONUP
:
1058 /* Wine does nothing here. */
1062 case WM_CONTEXTMENU
:
1064 if (GetWindowLong(hWnd
, GWL_STYLE
) & WS_CHILD
)
1068 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1072 SendMessageA(hWnd
, WM_CONTEXTMENU
, wParam
, lParam
);
1080 Pt
.x
= SLOWORD(lParam
);
1081 Pt
.y
= SHIWORD(lParam
);
1083 if (GetWindowLong(hWnd
, GWL_STYLE
) & WS_CHILD
)
1085 ScreenToClient(GetParent(hWnd
), &Pt
);
1088 HitCode
= DefWndHitTestNC(hWnd
, Pt
);
1090 if (HitCode
== HTCAPTION
|| HitCode
== HTSYSMENU
)
1092 TrackPopupMenu(GetSystemMenu(hWnd
, FALSE
),
1093 TPM_LEFTBUTTON
| TPM_RIGHTBUTTON
,
1094 Pt
.x
, Pt
.y
, 0, hWnd
, NULL
);
1102 return(DefWndHandleActiveNC(hWnd
, wParam
));
1119 HDC hDC
= BeginPaint(hWnd
, &Ps
);
1124 if (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_MINIMIZE
&&
1125 (hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
)) != NULL
)
1129 GetWindowRect(hWnd
, &WindowRect
);
1130 x
= (WindowRect
.right
- WindowRect
.left
-
1131 GetSystemMetrics(SM_CXICON
)) / 2;
1132 y
= (WindowRect
.bottom
- WindowRect
.top
-
1133 GetSystemMetrics(SM_CYICON
)) / 2;
1134 DrawIcon(hDC
, x
, y
, hIcon
);
1136 if(GetWindowLong(hWnd
, GWL_EXSTYLE
) & WS_EX_CLIENTEDGE
)
1139 GetClientRect(hWnd
, &WindowRect
);
1140 DrawEdge(hDC
, &WindowRect
, EDGE_SUNKEN
, BF_RECT
);
1142 EndPaint(hWnd
, &Ps
);
1150 hRgn
= CreateRectRgn(0, 0, 0, 0);
1151 if (GetUpdateRgn(hWnd
, hRgn
, FALSE
) != NULLREGION
)
1153 RedrawWindow(hWnd
, NULL
, hRgn
,
1154 RDW_ERASENOW
| RDW_ERASE
| RDW_FRAME
|
1163 DefWndSetRedraw(hWnd
, wParam
);
1169 DestroyWindow(hWnd
);
1173 case WM_MOUSEACTIVATE
:
1175 if (GetWindowLong(hWnd
, GWL_STYLE
) & WS_CHILD
)
1180 Ret
= SendMessageW(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1185 Ret
= SendMessageA(GetParent(hWnd
), WM_MOUSEACTIVATE
,
1193 return((LOWORD(lParam
) >= HTCLIENT
) ? MA_ACTIVATE
: MA_NOACTIVATE
);
1198 /* Check if the window is minimized. */
1199 if (LOWORD(lParam
) != WA_INACTIVE
&&
1200 !(GetWindowLong(hWnd
, GWL_STYLE
) & WS_MINIMIZE
))
1209 if (GetWindowLong(hWnd
, GWL_STYLE
& WS_CHILD
))
1213 return(SendMessageW(GetParent(hWnd
), WM_MOUSEWHEEL
,
1218 return(SendMessageA(GetParent(hWnd
), WM_MOUSEWHEEL
,
1226 case WM_ICONERASEBKGND
:
1230 HBRUSH hBrush
= (HBRUSH
)GetClassLongW(hWnd
, GCL_HBRBACKGROUND
);
1231 GetClipBox((HDC
)wParam
, &Rect
);
1232 FillRect((HDC
)wParam
, &Rect
, hBrush
);
1241 /* FIXME: Implement colour controls. */
1245 if (GetWindowLong(hWnd
, GWL_STYLE
) & WS_CHILD
)
1247 if (LOWORD(lParam
) < HTLEFT
|| LOWORD(lParam
) > HTBOTTOMRIGHT
)
1252 bResult
= SendMessageW(GetParent(hWnd
), WM_SETCURSOR
,
1257 bResult
= SendMessageA(GetParent(hWnd
), WM_SETCURSOR
,
1266 return(DefWndHandleSetCursor(hWnd
, wParam
, lParam
));
1272 Pt
.x
= SLOWORD(lParam
);
1273 Pt
.y
= SHIWORD(lParam
);
1274 return(DefWndHandleSysCommand(hWnd
, wParam
, Pt
));
1277 /* FIXME: Handle key messages. */
1285 /* FIXME: Not done correctly */
1286 if ((GetWindowLongW(hWnd
, GWL_STYLE
) & WS_VISIBLE
&& !wParam
) ||
1287 (!(GetWindowLongW(hWnd
, GWL_STYLE
) & WS_VISIBLE
) && wParam
))
1291 ShowWindow(hWnd
, wParam
? SW_SHOWNA
: SW_HIDE
);
1297 /* FIXME: Check for a desktop. */
1298 if (GetCapture() == hWnd
)
1310 /* FIXME: Implement this. */
1313 case WM_QUERYDROPOBJECT
:
1315 if (GetWindowLongW(hWnd
, GWL_EXSTYLE
) & WS_EX_ACCEPTFILES
)
1322 case WM_QUERYDRAGICON
:
1327 hIcon
= (HICON
)GetClassLongW(hWnd
, GCL_HICON
);
1330 return((LRESULT
)hIcon
);
1332 for (Len
= 1; Len
< 64; Len
++)
1334 if ((hIcon
= LoadIconW(NULL
, MAKEINTRESOURCE(Len
))) != NULL
)
1336 return((LRESULT
)hIcon
);
1339 return((LRESULT
)LoadIconW(0, IDI_APPLICATION
));
1342 /* FIXME: WM_ISACTIVEICON */
1344 case WM_NOTIFYFORMAT
:
1346 if (IsWindowUnicode(hWnd
))
1348 return(NFR_UNICODE
);
1358 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1359 HICON hOldIcon
= (HICON
)GetClassLongW(hWnd
, Index
);
1360 SetClassLongW(hWnd
, Index
, lParam
);
1361 SetWindowPos(hWnd
, 0, 0, 0, 0, 0,
1362 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1363 SWP_NOACTIVATE
| SWP_NOZORDER
);
1364 return((LRESULT
)hOldIcon
);
1369 INT Index
= (wParam
!= 0) ? GCL_HICON
: GCL_HICONSM
;
1370 return(GetClassLongW(hWnd
, Index
));
1377 SendMessageW(GetParent(hWnd
), Msg
, wParam
, lParam
);
1381 SendMessageA(GetParent(hWnd
), Msg
, wParam
, lParam
);
1387 if (HIWORD(lParam
) & KEYDATA_ALT
)
1389 if (wParam
== VK_F4
) /* Try to close the window */
1391 //HWND hTopWnd = GetAncestor(hWnd, GA_ROOT);
1392 HWND hTopWnd
= hWnd
;
1393 if (!(GetClassLongW(hTopWnd
, GCL_STYLE
) & CS_NOCLOSE
))
1397 PostMessageW(hTopWnd
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1401 PostMessageA(hTopWnd
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
1412 DefWindowProcA(HWND hWnd
,
1418 static LPSTR WindowTextAtom
= 0;
1425 CREATESTRUCTA
* Cs
= (CREATESTRUCTA
*)lParam
;
1426 if (HIWORD(Cs
->lpszName
))
1428 if (0 == WindowTextAtom
)
1431 (LPSTR
)(ULONG
)GlobalAddAtomA("USER32!WindowTextAtomA");
1433 WindowText
= RtlAllocateHeap(RtlGetProcessHeap(), 0,
1434 strlen(Cs
->lpszName
) * sizeof(CHAR
));
1435 strcpy(WindowText
, Cs
->lpszName
);
1436 SetPropA(hWnd
, WindowTextAtom
, WindowText
);
1443 return(DefWndNCCalcSize(hWnd
, (RECT
*)lParam
));
1446 case WM_WINDOWPOSCHANGING
:
1448 return(DefWndHandleWindowPosChanging(hWnd
, (WINDOWPOS
*)lParam
));
1451 case WM_GETTEXTLENGTH
:
1453 if (WindowTextAtom
== 0 ||
1454 (WindowText
= GetPropA(hWnd
, WindowTextAtom
)) == NULL
)
1458 return(strlen(WindowText
));
1463 if (WindowTextAtom
== 0 ||
1464 (WindowText
= GetPropA(hWnd
, WindowTextAtom
)) == NULL
)
1468 *((PSTR
)lParam
) = '\0';
1472 strncpy((LPSTR
)lParam
, WindowText
, wParam
);
1473 return(min(wParam
, strlen(WindowText
)));
1478 if (0 == WindowTextAtom
)
1481 (LPSTR
)(DWORD
)GlobalAddAtomA("USER32!WindowTextAtomW");
1483 if (WindowTextAtom
!= 0 &&
1484 (WindowText
= GetPropA(hWnd
, WindowTextAtom
)) == NULL
)
1486 RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText
);
1488 WindowText
= RtlAllocateHeap(RtlGetProcessHeap(), 0,
1489 strlen((PSTR
)lParam
) * sizeof(CHAR
));
1490 strcpy(WindowText
, (PSTR
)lParam
);
1491 SetPropA(hWnd
, WindowTextAtom
, WindowText
);
1492 if (0 != (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
))
1494 DefWndPaintNC(hWnd
, (HRGN
) 1);
1496 Result
= (LPARAM
) TRUE
;
1502 if (WindowTextAtom
!= 0 &&
1503 (WindowText
= RemovePropA(hWnd
, WindowTextAtom
)) == NULL
)
1505 RtlFreeHeap(GetProcessHeap(), 0, WindowText
);
1511 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, FALSE
);
1519 DefWindowProcW(HWND hWnd
,
1525 static LPWSTR WindowTextAtom
= 0;
1532 CREATESTRUCTW
* Cs
= (CREATESTRUCTW
*)lParam
;
1533 if (HIWORD(Cs
->lpszName
))
1535 if (0 == WindowTextAtom
)
1538 (LPWSTR
)(DWORD
)GlobalAddAtomW(L
"USER32!WindowTextAtomW");
1540 WindowText
= RtlAllocateHeap(RtlGetProcessHeap(), 0,
1541 wcslen(Cs
->lpszName
) * sizeof(WCHAR
));
1542 wcscpy(WindowText
, Cs
->lpszName
);
1543 SetPropW(hWnd
, WindowTextAtom
, WindowText
);
1550 return(DefWndNCCalcSize(hWnd
, (RECT
*)lParam
));
1553 case WM_WINDOWPOSCHANGING
:
1555 return(DefWndHandleWindowPosChanging(hWnd
, (WINDOWPOS
*)lParam
));
1558 case WM_GETTEXTLENGTH
:
1560 if (WindowTextAtom
== 0 ||
1561 (WindowText
= GetPropW(hWnd
, WindowTextAtom
)) == NULL
)
1565 return(wcslen(WindowText
));
1570 if (WindowTextAtom
== 0 ||
1571 (WindowText
= GetPropW(hWnd
, WindowTextAtom
)) == NULL
)
1575 ((PWSTR
)lParam
) = '\0';
1579 wcsncpy((PWSTR
)lParam
, WindowText
, wParam
);
1580 return(min(wParam
, wcslen(WindowText
)));
1585 if (WindowTextAtom
!= 0)
1588 (LPWSTR
)(DWORD
)GlobalAddAtom(L
"USER32!WindowTextAtomW");
1590 if (WindowTextAtom
!= 0 &&
1591 (WindowText
= GetPropW(hWnd
, WindowTextAtom
)) == NULL
)
1593 RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText
);
1595 WindowText
= RtlAllocateHeap(RtlGetProcessHeap(), 0,
1596 wcslen((PWSTR
)lParam
) * sizeof(WCHAR
));
1597 wcscpy(WindowText
, (PWSTR
)lParam
);
1598 SetPropW(hWnd
, WindowTextAtom
, WindowText
);
1599 if (0 != (GetWindowLongW(hWnd
, GWL_STYLE
) & WS_CAPTION
))
1601 DefWndPaintNC(hWnd
, (HRGN
) 1);
1603 Result
= (LPARAM
) TRUE
;
1609 if (WindowTextAtom
!= 0 &&
1610 (WindowText
= RemovePropW(hWnd
, WindowTextAtom
)) == NULL
)
1612 RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText
);
1618 Result
= User32DefWindowProc(hWnd
, Msg
, wParam
, lParam
, TRUE
);