2 * Non-client area window functions
4 * Copyright 1994 Alexandre Julliard
10 #include "wine/winuser16.h"
18 #include "cursoricon.h"
21 #include "nonclient.h"
22 #include "debugtools.h"
27 DEFAULT_DEBUG_CHANNEL(nonclient
);
28 DECLARE_DEBUG_CHANNEL(shell
);
30 BOOL
NC_DrawGrayButton(HDC hdc
, int x
, int y
);
32 static HBITMAP hbitmapClose
;
33 static HBITMAP hbitmapMinimize
;
34 static HBITMAP hbitmapMinimizeD
;
35 static HBITMAP hbitmapMaximize
;
36 static HBITMAP hbitmapMaximizeD
;
37 static HBITMAP hbitmapRestore
;
38 static HBITMAP hbitmapRestoreD
;
40 static const BYTE lpGrayMask
[] = { 0xAA, 0xA0,
51 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
52 #define SC_PUTMARK (SC_SCREENSAVE+2)
54 /* Some useful macros */
55 #define HAS_DLGFRAME(style,exStyle) \
56 (((exStyle) & WS_EX_DLGMODALFRAME) || \
57 (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
59 #define HAS_THICKFRAME(style,exStyle) \
60 (((style) & WS_THICKFRAME) && \
61 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
63 #define HAS_THINFRAME(style) \
64 (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
66 #define HAS_BIGFRAME(style,exStyle) \
67 (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
68 ((exStyle) & WS_EX_DLGMODALFRAME))
70 #define HAS_ANYFRAME(style,exStyle) \
71 (((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
72 ((exStyle) & WS_EX_DLGMODALFRAME) || \
73 !((style) & (WS_CHILD | WS_POPUP)))
75 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
78 /***********************************************************************
81 * Compute the size of the window rectangle from the size of the
84 static void NC_AdjustRect( LPRECT rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
86 if (TWEAK_WineLook
> WIN31_LOOK
)
87 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
89 if(style
& WS_ICONIC
) return;
91 if (HAS_THICKFRAME( style
, exStyle
))
92 InflateRect( rect
, GetSystemMetrics(SM_CXFRAME
), GetSystemMetrics(SM_CYFRAME
) );
93 else if (HAS_DLGFRAME( style
, exStyle
))
94 InflateRect( rect
, GetSystemMetrics(SM_CXDLGFRAME
), GetSystemMetrics(SM_CYDLGFRAME
) );
95 else if (HAS_THINFRAME( style
))
96 InflateRect( rect
, GetSystemMetrics(SM_CXBORDER
), GetSystemMetrics(SM_CYBORDER
));
98 if ((style
& WS_CAPTION
) == WS_CAPTION
)
99 rect
->top
-= GetSystemMetrics(SM_CYCAPTION
) - GetSystemMetrics(SM_CYBORDER
);
101 if (menu
) rect
->top
-= GetSystemMetrics(SM_CYMENU
) + GetSystemMetrics(SM_CYBORDER
);
103 if (style
& WS_VSCROLL
) {
104 rect
->right
+= GetSystemMetrics(SM_CXVSCROLL
) - 1;
105 if(!HAS_ANYFRAME( style
, exStyle
))
109 if (style
& WS_HSCROLL
) {
110 rect
->bottom
+= GetSystemMetrics(SM_CYHSCROLL
) - 1;
111 if(!HAS_ANYFRAME( style
, exStyle
))
117 /******************************************************************************
118 * NC_AdjustRectOuter95
120 * Computes the size of the "outside" parts of the window based on the
121 * parameters of the client area.
130 * "Outer" parts of a window means the whole window frame, caption and
131 * menu bar. It does not include "inner" parts of the frame like client
132 * edge, static edge or scroll bars.
135 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
136 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
138 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
139 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
140 * NC_AdjustRectInner95 and added handling of Win95 styles.
142 * 28-Jul-1999 Ove Kåven (ovek@arcticnet.no)
143 * Streamlined window style checks.
145 *****************************************************************************/
148 NC_AdjustRectOuter95 (LPRECT rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
150 if(style
& WS_ICONIC
) return;
152 if (HAS_THICKFRAME( style
, exStyle
))
153 InflateRect( rect
, GetSystemMetrics(SM_CXFRAME
), GetSystemMetrics(SM_CYFRAME
) );
154 else if (HAS_DLGFRAME( style
, exStyle
))
155 InflateRect(rect
, GetSystemMetrics(SM_CXDLGFRAME
), GetSystemMetrics(SM_CYDLGFRAME
) );
156 else if (HAS_THINFRAME( style
))
157 InflateRect( rect
, GetSystemMetrics(SM_CXBORDER
), GetSystemMetrics(SM_CYBORDER
));
159 if ((style
& WS_CAPTION
) == WS_CAPTION
)
161 if (exStyle
& WS_EX_TOOLWINDOW
)
162 rect
->top
-= GetSystemMetrics(SM_CYSMCAPTION
);
164 rect
->top
-= GetSystemMetrics(SM_CYCAPTION
);
166 if (menu
) rect
->top
-= GetSystemMetrics(SM_CYMENU
);
170 /******************************************************************************
171 * NC_AdjustRectInner95
173 * Computes the size of the "inside" part of the window based on the
174 * parameters of the client area.
182 * "Inner" part of a window means the window frame inside of the flat
183 * window frame. It includes the client edge, the static edge and the
187 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
188 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
190 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
191 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
192 * NC_AdjustRectInner95 and added handling of Win95 styles.
194 *****************************************************************************/
197 NC_AdjustRectInner95 (LPRECT rect
, DWORD style
, DWORD exStyle
)
199 if(style
& WS_ICONIC
) return;
201 if (exStyle
& WS_EX_CLIENTEDGE
)
202 InflateRect(rect
, GetSystemMetrics(SM_CXEDGE
), GetSystemMetrics(SM_CYEDGE
));
204 if (exStyle
& WS_EX_STATICEDGE
)
205 InflateRect(rect
, GetSystemMetrics(SM_CXBORDER
), GetSystemMetrics(SM_CYBORDER
));
207 if (style
& WS_VSCROLL
) rect
->right
+= GetSystemMetrics(SM_CXVSCROLL
);
208 if (style
& WS_HSCROLL
) rect
->bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
213 static HICON
NC_IconForWindow( HWND hwnd
)
215 HICON hIcon
= (HICON
) GetClassLongA( hwnd
, GCL_HICONSM
);
216 if (!hIcon
) hIcon
= (HICON
) GetClassLongA( hwnd
, GCL_HICON
);
218 /* If there is no hIcon specified and this is a modal dialog,
219 * get the default one.
221 if (!hIcon
&& (GetWindowLongA( hwnd
, GWL_STYLE
) & DS_MODALFRAME
))
222 hIcon
= LoadImageA(0, IDI_WINLOGOA
, IMAGE_ICON
, 0, 0, LR_DEFAULTCOLOR
);
226 /***********************************************************************
227 * DrawCaption (USER.660) Draws a caption bar
241 DrawCaption16 (HWND16 hwnd
, HDC16 hdc
, const RECT16
*rect
, UINT16 uFlags
)
246 CONV_RECT16TO32 (rect
, &rect32
);
248 return (BOOL16
)DrawCaptionTempA (hwnd
, hdc
, rect
? &rect32
: NULL
,
249 0, 0, NULL
, uFlags
& 0x1F);
253 /***********************************************************************
254 * DrawCaption (USER32.@) Draws a caption bar
268 DrawCaption (HWND hwnd
, HDC hdc
, const RECT
*lpRect
, UINT uFlags
)
270 return DrawCaptionTempA (hwnd
, hdc
, lpRect
, 0, 0, NULL
, uFlags
& 0x1F);
274 /***********************************************************************
275 * DrawCaptionTemp (USER.657)
285 DrawCaptionTemp16 (HWND16 hwnd
, HDC16 hdc
, const RECT16
*rect
, HFONT16 hFont
,
286 HICON16 hIcon
, LPCSTR str
, UINT16 uFlags
)
291 CONV_RECT16TO32(rect
,&rect32
);
293 return (BOOL16
)DrawCaptionTempA (hwnd
, hdc
, rect
?&rect32
:NULL
, hFont
,
294 hIcon
, str
, uFlags
& 0x1F);
298 /***********************************************************************
299 * DrawCaptionTempA (USER32.@)
309 DrawCaptionTempA (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
310 HICON hIcon
, LPCSTR str
, UINT uFlags
)
314 TRACE("(%08x,%08x,%p,%08x,%08x,\"%s\",%08x)\n",
315 hwnd
, hdc
, rect
, hFont
, hIcon
, str
, uFlags
);
317 /* drawing background */
318 if (uFlags
& DC_INBUTTON
) {
319 FillRect (hdc
, &rc
, GetSysColorBrush (COLOR_3DFACE
));
321 if (uFlags
& DC_ACTIVE
) {
322 HBRUSH hbr
= SelectObject (hdc
, CACHE_GetPattern55AABrush ());
323 PatBlt (hdc
, rc
.left
, rc
.top
,
324 rc
.right
-rc
.left
, rc
.bottom
-rc
.top
, 0xFA0089);
325 SelectObject (hdc
, hbr
);
329 FillRect (hdc
, &rc
, GetSysColorBrush ((uFlags
& DC_ACTIVE
) ?
330 COLOR_ACTIVECAPTION
: COLOR_INACTIVECAPTION
));
335 if ((uFlags
& DC_ICON
) && !(uFlags
& DC_SMALLCAP
)) {
339 pt
.y
= (rc
.bottom
+ rc
.top
- GetSystemMetrics(SM_CYSMICON
)) / 2;
341 if (!hIcon
) hIcon
= NC_IconForWindow(hwnd
);
342 DrawIconEx (hdc
, pt
.x
, pt
.y
, hIcon
, GetSystemMetrics(SM_CXSMICON
),
343 GetSystemMetrics(SM_CYSMICON
), 0, 0, DI_NORMAL
);
344 rc
.left
+= (rc
.bottom
- rc
.top
);
348 if (uFlags
& DC_TEXT
) {
351 if (uFlags
& DC_INBUTTON
)
352 SetTextColor (hdc
, GetSysColor (COLOR_BTNTEXT
));
353 else if (uFlags
& DC_ACTIVE
)
354 SetTextColor (hdc
, GetSysColor (COLOR_CAPTIONTEXT
));
356 SetTextColor (hdc
, GetSysColor (COLOR_INACTIVECAPTIONTEXT
));
358 SetBkMode (hdc
, TRANSPARENT
);
361 hOldFont
= SelectObject (hdc
, hFont
);
363 NONCLIENTMETRICSA nclm
;
365 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
366 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
367 hNewFont
= CreateFontIndirectA ((uFlags
& DC_SMALLCAP
) ?
368 &nclm
.lfSmCaptionFont
: &nclm
.lfCaptionFont
);
369 hOldFont
= SelectObject (hdc
, hNewFont
);
373 DrawTextA (hdc
, str
, -1, &rc
,
374 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
378 nLen
= GetWindowTextA (hwnd
, szText
, 128);
379 DrawTextA (hdc
, szText
, nLen
, &rc
,
380 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
384 SelectObject (hdc
, hOldFont
);
386 DeleteObject (SelectObject (hdc
, hOldFont
));
389 /* drawing focus ??? */
391 FIXME("undocumented flag (0x2000)!\n");
397 /***********************************************************************
398 * DrawCaptionTempW (USER32.@)
408 DrawCaptionTempW (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
409 HICON hIcon
, LPCWSTR str
, UINT uFlags
)
411 LPSTR p
= HEAP_strdupWtoA (GetProcessHeap (), 0, str
);
412 BOOL res
= DrawCaptionTempA (hwnd
, hdc
, rect
, hFont
, hIcon
, p
, uFlags
);
413 HeapFree (GetProcessHeap (), 0, p
);
418 /***********************************************************************
419 * AdjustWindowRect (USER.102)
421 BOOL16 WINAPI
AdjustWindowRect16( LPRECT16 rect
, DWORD style
, BOOL16 menu
)
423 return AdjustWindowRectEx16( rect
, style
, menu
, 0 );
427 /***********************************************************************
428 * AdjustWindowRect (USER32.@)
430 BOOL WINAPI
AdjustWindowRect( LPRECT rect
, DWORD style
, BOOL menu
)
432 return AdjustWindowRectEx( rect
, style
, menu
, 0 );
436 /***********************************************************************
437 * AdjustWindowRectEx (USER.454)
439 BOOL16 WINAPI
AdjustWindowRectEx16( LPRECT16 rect
, DWORD style
,
440 BOOL16 menu
, DWORD exStyle
)
445 CONV_RECT16TO32( rect
, &rect32
);
446 ret
= AdjustWindowRectEx( &rect32
, style
, menu
, exStyle
);
447 CONV_RECT32TO16( &rect32
, rect
);
452 /***********************************************************************
453 * AdjustWindowRectEx (USER32.@)
455 BOOL WINAPI
AdjustWindowRectEx( LPRECT rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
457 /* Correct the window style */
459 if (!(style
& (WS_POPUP
| WS_CHILD
))) style
|= WS_CAPTION
; /* Overlapped window */
460 style
&= (WS_DLGFRAME
| WS_BORDER
| WS_THICKFRAME
| WS_CHILD
);
461 exStyle
&= (WS_EX_DLGMODALFRAME
| WS_EX_CLIENTEDGE
|
462 WS_EX_STATICEDGE
| WS_EX_TOOLWINDOW
);
463 if (exStyle
& WS_EX_DLGMODALFRAME
) style
&= ~WS_THICKFRAME
;
465 TRACE("(%d,%d)-(%d,%d) %08lx %d %08lx\n",
466 rect
->left
, rect
->top
, rect
->right
, rect
->bottom
,
467 style
, menu
, exStyle
);
469 if (TWEAK_WineLook
== WIN31_LOOK
)
470 NC_AdjustRect( rect
, style
, menu
, exStyle
);
473 NC_AdjustRectOuter95( rect
, style
, menu
, exStyle
);
474 NC_AdjustRectInner95( rect
, style
, exStyle
);
480 /***********************************************************************
481 * NC_HandleNCCalcSize
483 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
485 LONG
NC_HandleNCCalcSize( WND
*pWnd
, RECT
*winRect
)
487 RECT tmpRect
= { 0, 0, 0, 0 };
489 UINT style
= (UINT
) GetClassLongA(pWnd
->hwndSelf
, GCL_STYLE
);
491 if (style
& CS_VREDRAW
) result
|= WVR_VREDRAW
;
492 if (style
& CS_HREDRAW
) result
|= WVR_HREDRAW
;
494 if( !( pWnd
->dwStyle
& WS_MINIMIZE
) ) {
495 if (TWEAK_WineLook
== WIN31_LOOK
)
496 NC_AdjustRect( &tmpRect
, pWnd
->dwStyle
, FALSE
, pWnd
->dwExStyle
);
498 NC_AdjustRectOuter95( &tmpRect
, pWnd
->dwStyle
, FALSE
, pWnd
->dwExStyle
);
500 winRect
->left
-= tmpRect
.left
;
501 winRect
->top
-= tmpRect
.top
;
502 winRect
->right
-= tmpRect
.right
;
503 winRect
->bottom
-= tmpRect
.bottom
;
505 if (HAS_MENU(pWnd
)) {
506 TRACE("Calling GetMenuBarHeight with HWND 0x%x, width %d, "
507 "at (%d, %d).\n", pWnd
->hwndSelf
,
508 winRect
->right
- winRect
->left
,
509 -tmpRect
.left
, -tmpRect
.top
);
512 MENU_GetMenuBarHeight( pWnd
->hwndSelf
,
513 winRect
->right
- winRect
->left
,
514 -tmpRect
.left
, -tmpRect
.top
) + 1;
517 if (TWEAK_WineLook
> WIN31_LOOK
) {
518 SetRect(&tmpRect
, 0, 0, 0, 0);
519 NC_AdjustRectInner95 (&tmpRect
, pWnd
->dwStyle
, pWnd
->dwExStyle
);
520 winRect
->left
-= tmpRect
.left
;
521 winRect
->top
-= tmpRect
.top
;
522 winRect
->right
-= tmpRect
.right
;
523 winRect
->bottom
-= tmpRect
.bottom
;
526 if (winRect
->top
> winRect
->bottom
)
527 winRect
->bottom
= winRect
->top
;
529 if (winRect
->left
> winRect
->right
)
530 winRect
->right
= winRect
->left
;
536 /***********************************************************************
539 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
540 * but without the borders (if any).
541 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
543 void NC_GetInsideRect( HWND hwnd
, RECT
*rect
)
545 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
547 rect
->top
= rect
->left
= 0;
548 rect
->right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
549 rect
->bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
551 if (wndPtr
->dwStyle
& WS_ICONIC
) goto END
;
553 /* Remove frame from rectangle */
554 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
556 InflateRect( rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
558 else if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
560 InflateRect( rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
561 /* FIXME: this isn't in NC_AdjustRect? why not? */
562 if ((TWEAK_WineLook
== WIN31_LOOK
) && (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
))
563 InflateRect( rect
, -1, 0 );
565 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
567 InflateRect( rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
) );
570 /* We have additional border information if the window
571 * is a child (but not an MDI child) */
572 if (TWEAK_WineLook
!= WIN31_LOOK
)
574 if ( (wndPtr
->dwStyle
& WS_CHILD
) &&
575 ( (wndPtr
->dwExStyle
& WS_EX_MDICHILD
) == 0 ) )
577 if (wndPtr
->dwExStyle
& WS_EX_CLIENTEDGE
)
578 InflateRect (rect
, -GetSystemMetrics(SM_CXEDGE
), -GetSystemMetrics(SM_CYEDGE
));
579 if (wndPtr
->dwExStyle
& WS_EX_STATICEDGE
)
580 InflateRect (rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
585 WIN_ReleaseWndPtr(wndPtr
);
590 /***********************************************************************
593 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
596 static LONG
NC_DoNCHitTest (WND
*wndPtr
, POINT pt
)
600 TRACE("hwnd=%04x pt=%ld,%ld\n", wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
602 GetWindowRect(wndPtr
->hwndSelf
, &rect
);
603 if (!PtInRect( &rect
, pt
)) return HTNOWHERE
;
605 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
608 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
610 InflateRect( &rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
611 if (!PtInRect( &rect
, pt
))
613 /* Check top sizing border */
616 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
617 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
620 /* Check bottom sizing border */
621 if (pt
.y
>= rect
.bottom
)
623 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
624 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
627 /* Check left sizing border */
628 if (pt
.x
< rect
.left
)
630 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
631 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
634 /* Check right sizing border */
635 if (pt
.x
>= rect
.right
)
637 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
638 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
643 else /* No thick frame */
645 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
646 InflateRect(&rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
647 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
648 InflateRect(&rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
649 if (!PtInRect( &rect
, pt
)) return HTBORDER
;
654 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
656 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
) - GetSystemMetrics(SM_CYBORDER
);
657 if (!PtInRect( &rect
, pt
))
659 /* Check system menu */
660 if ((wndPtr
->dwStyle
& WS_SYSMENU
) && !(wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
))
661 rect
.left
+= GetSystemMetrics(SM_CXSIZE
);
662 if (pt
.x
<= rect
.left
) return HTSYSMENU
;
664 /* Check maximize box */
665 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
666 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
668 if (pt
.x
>= rect
.right
) return HTMAXBUTTON
;
669 /* Check minimize box */
670 if (wndPtr
->dwStyle
& WS_MINIMIZEBOX
)
671 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
672 if (pt
.x
>= rect
.right
) return HTMINBUTTON
;
677 /* Check client area */
679 ScreenToClient( wndPtr
->hwndSelf
, &pt
);
680 GetClientRect( wndPtr
->hwndSelf
, &rect
);
681 if (PtInRect( &rect
, pt
)) return HTCLIENT
;
683 /* Check vertical scroll bar */
685 if (wndPtr
->dwStyle
& WS_VSCROLL
)
687 rect
.right
+= GetSystemMetrics(SM_CXVSCROLL
);
688 if (PtInRect( &rect
, pt
)) return HTVSCROLL
;
691 /* Check horizontal scroll bar */
693 if (wndPtr
->dwStyle
& WS_HSCROLL
)
695 rect
.bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
696 if (PtInRect( &rect
, pt
))
699 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
700 (pt
.x
>= rect
.right
- GetSystemMetrics(SM_CXVSCROLL
)))
708 if (HAS_MENU(wndPtr
))
710 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
714 /* Has to return HTNOWHERE if nothing was found
715 Could happen when a window has a customized non client area */
720 /***********************************************************************
723 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
725 * FIXME: Just a modified copy of the Win 3.1 version.
728 static LONG
NC_DoNCHitTest95 (WND
*wndPtr
, POINT pt
)
732 TRACE("hwnd=%04x pt=%ld,%ld\n", wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
734 GetWindowRect(wndPtr
->hwndSelf
, &rect
);
735 if (!PtInRect( &rect
, pt
)) return HTNOWHERE
;
737 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
740 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
742 InflateRect( &rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
743 if (!PtInRect( &rect
, pt
))
745 /* Check top sizing border */
748 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
749 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
752 /* Check bottom sizing border */
753 if (pt
.y
>= rect
.bottom
)
755 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
756 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
759 /* Check left sizing border */
760 if (pt
.x
< rect
.left
)
762 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
763 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
766 /* Check right sizing border */
767 if (pt
.x
>= rect
.right
)
769 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
770 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
775 else /* No thick frame */
777 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
778 InflateRect(&rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
779 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
780 InflateRect(&rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
781 if (!PtInRect( &rect
, pt
)) return HTBORDER
;
786 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
788 if (wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
)
789 rect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
) - 1;
791 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
792 if (!PtInRect( &rect
, pt
))
794 /* Check system menu */
795 if ((wndPtr
->dwStyle
& WS_SYSMENU
) && !(wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
))
797 if (NC_IconForWindow(wndPtr
->hwndSelf
))
798 rect
.left
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
800 if (pt
.x
< rect
.left
) return HTSYSMENU
;
802 /* Check close button */
803 if (wndPtr
->dwStyle
& WS_SYSMENU
)
804 rect
.right
-= GetSystemMetrics(SM_CYCAPTION
) - 1;
805 if (pt
.x
> rect
.right
) return HTCLOSE
;
807 /* Check maximize box */
808 /* In win95 there is automatically a Maximize button when there is a minimize one*/
809 if ((wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)|| (wndPtr
->dwStyle
& WS_MINIMIZEBOX
))
810 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
811 if (pt
.x
> rect
.right
) return HTMAXBUTTON
;
813 /* Check minimize box */
814 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
815 if ((wndPtr
->dwStyle
& WS_MINIMIZEBOX
)||(wndPtr
->dwStyle
& WS_MAXIMIZEBOX
))
816 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
818 if (pt
.x
> rect
.right
) return HTMINBUTTON
;
823 /* Check client area */
825 ScreenToClient( wndPtr
->hwndSelf
, &pt
);
826 GetClientRect( wndPtr
->hwndSelf
, &rect
);
827 if (PtInRect( &rect
, pt
)) return HTCLIENT
;
829 /* Check vertical scroll bar */
831 if (wndPtr
->dwStyle
& WS_VSCROLL
)
833 rect
.right
+= GetSystemMetrics(SM_CXVSCROLL
);
834 if (PtInRect( &rect
, pt
)) return HTVSCROLL
;
837 /* Check horizontal scroll bar */
839 if (wndPtr
->dwStyle
& WS_HSCROLL
)
841 rect
.bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
842 if (PtInRect( &rect
, pt
))
845 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
846 (pt
.x
>= rect
.right
- GetSystemMetrics(SM_CXVSCROLL
)))
854 if (HAS_MENU(wndPtr
))
856 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
860 /* Has to return HTNOWHERE if nothing was found
861 Could happen when a window has a customized non client area */
866 /***********************************************************************
869 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
871 LONG
NC_HandleNCHitTest (HWND hwnd
, POINT pt
)
874 WND
*wndPtr
= WIN_FindWndPtr (hwnd
);
879 if (TWEAK_WineLook
== WIN31_LOOK
)
880 retvalue
= NC_DoNCHitTest (wndPtr
, pt
);
882 retvalue
= NC_DoNCHitTest95 (wndPtr
, pt
);
883 WIN_ReleaseWndPtr(wndPtr
);
888 /***********************************************************************
891 void NC_DrawSysButton( HWND hwnd
, HDC hdc
, BOOL down
)
897 NC_GetInsideRect( hwnd
, &rect
);
898 hdcMem
= CreateCompatibleDC( hdc
);
899 hbitmap
= SelectObject( hdcMem
, hbitmapClose
);
900 BitBlt(hdc
, rect
.left
, rect
.top
, GetSystemMetrics(SM_CXSIZE
), GetSystemMetrics(SM_CYSIZE
),
901 hdcMem
, (GetWindowLongA(hwnd
,GWL_STYLE
) & WS_CHILD
) ? GetSystemMetrics(SM_CXSIZE
) : 0, 0,
902 down
? NOTSRCCOPY
: SRCCOPY
);
903 SelectObject( hdcMem
, hbitmap
);
908 /***********************************************************************
911 static void NC_DrawMaxButton( HWND hwnd
, HDC16 hdc
, BOOL down
)
916 NC_GetInsideRect( hwnd
, &rect
);
917 hdcMem
= CreateCompatibleDC( hdc
);
918 SelectObject( hdcMem
, (IsZoomed(hwnd
)
919 ? (down
? hbitmapRestoreD
: hbitmapRestore
)
920 : (down
? hbitmapMaximizeD
: hbitmapMaximize
)) );
921 BitBlt( hdc
, rect
.right
- GetSystemMetrics(SM_CXSIZE
) - 1, rect
.top
,
922 GetSystemMetrics(SM_CXSIZE
) + 1, GetSystemMetrics(SM_CYSIZE
), hdcMem
, 0, 0,
929 /***********************************************************************
932 static void NC_DrawMinButton( HWND hwnd
, HDC16 hdc
, BOOL down
)
937 NC_GetInsideRect( hwnd
, &rect
);
938 hdcMem
= CreateCompatibleDC( hdc
);
939 SelectObject( hdcMem
, (down
? hbitmapMinimizeD
: hbitmapMinimize
) );
940 if (GetWindowLongA(hwnd
,GWL_STYLE
) & WS_MAXIMIZEBOX
)
941 rect
.right
-= GetSystemMetrics(SM_CXSIZE
)+1;
942 BitBlt( hdc
, rect
.right
- GetSystemMetrics(SM_CXSIZE
) - 1, rect
.top
,
943 GetSystemMetrics(SM_CXSIZE
) + 1, GetSystemMetrics(SM_CYSIZE
), hdcMem
, 0, 0,
949 /******************************************************************************
951 * void NC_DrawSysButton95(
956 * Draws the Win95 system icon.
959 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
960 * Original implementation from NC_DrawSysButton source.
961 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
964 *****************************************************************************/
967 NC_DrawSysButton95 (HWND hwnd
, HDC hdc
, BOOL down
)
969 HICON hIcon
= NC_IconForWindow( hwnd
);
974 NC_GetInsideRect( hwnd
, &rect
);
975 DrawIconEx (hdc
, rect
.left
+ 2, rect
.top
+ 2, hIcon
,
976 GetSystemMetrics(SM_CXSMICON
),
977 GetSystemMetrics(SM_CYSMICON
), 0, 0, DI_NORMAL
);
983 /******************************************************************************
985 * void NC_DrawCloseButton95(
991 * Draws the Win95 close button.
993 * If bGrayed is true, then draw a disabled Close button
996 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
997 * Original implementation from NC_DrawSysButton95 source.
999 *****************************************************************************/
1001 static void NC_DrawCloseButton95 (HWND hwnd
, HDC hdc
, BOOL down
, BOOL bGrayed
)
1005 NC_GetInsideRect( hwnd
, &rect
);
1007 /* A tool window has a smaller Close button */
1008 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_TOOLWINDOW
)
1010 INT iBmpHeight
= 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
1011 INT iBmpWidth
= 11; /* it uses 11x11 for the close button in tool window */
1012 INT iCaptionHeight
= GetSystemMetrics(SM_CYSMCAPTION
);
1014 rect
.top
= rect
.top
+ (iCaptionHeight
- 1 - iBmpHeight
) / 2;
1015 rect
.left
= rect
.right
- (iCaptionHeight
+ 1 + iBmpWidth
) / 2;
1016 rect
.bottom
= rect
.top
+ iBmpHeight
;
1017 rect
.right
= rect
.left
+ iBmpWidth
;
1021 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
) - 1;
1022 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1026 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
,
1027 (DFCS_CAPTIONCLOSE
|
1028 (down
? DFCS_PUSHED
: 0) |
1029 (bGrayed
? DFCS_INACTIVE
: 0)) );
1032 /******************************************************************************
1033 * NC_DrawMaxButton95
1035 * Draws the maximize button for Win95 style windows.
1036 * If bGrayed is true, then draw a disabled Maximize button
1038 static void NC_DrawMaxButton95(HWND hwnd
,HDC16 hdc
,BOOL down
, BOOL bGrayed
)
1041 UINT flags
= IsZoomed(hwnd
) ? DFCS_CAPTIONRESTORE
: DFCS_CAPTIONMAX
;
1043 NC_GetInsideRect( hwnd
, &rect
);
1044 if (GetWindowLongA( hwnd
, GWL_STYLE
) & WS_SYSMENU
)
1045 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1046 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
);
1047 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1050 if (down
) flags
|= DFCS_PUSHED
;
1051 if (bGrayed
) flags
|= DFCS_INACTIVE
;
1052 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
1055 /******************************************************************************
1056 * NC_DrawMinButton95
1058 * Draws the minimize button for Win95 style windows.
1059 * If bGrayed is true, then draw a disabled Minimize button
1061 static void NC_DrawMinButton95(HWND hwnd
,HDC16 hdc
,BOOL down
, BOOL bGrayed
)
1064 UINT flags
= DFCS_CAPTIONMIN
;
1065 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
1067 NC_GetInsideRect( hwnd
, &rect
);
1068 if (style
& WS_SYSMENU
)
1069 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1070 if (style
& (WS_MAXIMIZEBOX
|WS_MINIMIZEBOX
))
1071 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) - 2;
1072 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
);
1073 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1076 if (down
) flags
|= DFCS_PUSHED
;
1077 if (bGrayed
) flags
|= DFCS_INACTIVE
;
1078 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
1081 /***********************************************************************
1084 * Draw a window frame inside the given rectangle, and update the rectangle.
1085 * The correct pen for the frame must be selected in the DC.
1087 static void NC_DrawFrame( HDC hdc
, RECT
*rect
, BOOL dlgFrame
,
1092 if (TWEAK_WineLook
!= WIN31_LOOK
)
1093 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
1097 width
= GetSystemMetrics(SM_CXDLGFRAME
) - 1;
1098 height
= GetSystemMetrics(SM_CYDLGFRAME
) - 1;
1099 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1100 COLOR_INACTIVECAPTION
) );
1104 width
= GetSystemMetrics(SM_CXFRAME
) - 2;
1105 height
= GetSystemMetrics(SM_CYFRAME
) - 2;
1106 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1107 COLOR_INACTIVEBORDER
) );
1111 PatBlt( hdc
, rect
->left
, rect
->top
,
1112 rect
->right
- rect
->left
, height
, PATCOPY
);
1113 PatBlt( hdc
, rect
->left
, rect
->top
,
1114 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1115 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1116 rect
->right
- rect
->left
, -height
, PATCOPY
);
1117 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1118 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1122 InflateRect( rect
, -width
, -height
);
1126 INT decYOff
= GetSystemMetrics(SM_CXFRAME
) + GetSystemMetrics(SM_CXSIZE
) - 1;
1127 INT decXOff
= GetSystemMetrics(SM_CYFRAME
) + GetSystemMetrics(SM_CYSIZE
) - 1;
1129 /* Draw inner rectangle */
1131 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1132 Rectangle( hdc
, rect
->left
+ width
, rect
->top
+ height
,
1133 rect
->right
- width
, rect
->bottom
- height
);
1135 /* Draw the decorations */
1137 MoveToEx( hdc
, rect
->left
, rect
->top
+ decYOff
, NULL
);
1138 LineTo( hdc
, rect
->left
+ width
, rect
->top
+ decYOff
);
1139 MoveToEx( hdc
, rect
->right
- 1, rect
->top
+ decYOff
, NULL
);
1140 LineTo( hdc
, rect
->right
- width
- 1, rect
->top
+ decYOff
);
1141 MoveToEx( hdc
, rect
->left
, rect
->bottom
- decYOff
, NULL
);
1142 LineTo( hdc
, rect
->left
+ width
, rect
->bottom
- decYOff
);
1143 MoveToEx( hdc
, rect
->right
- 1, rect
->bottom
- decYOff
, NULL
);
1144 LineTo( hdc
, rect
->right
- width
- 1, rect
->bottom
- decYOff
);
1146 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->top
, NULL
);
1147 LineTo( hdc
, rect
->left
+ decXOff
, rect
->top
+ height
);
1148 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->bottom
- 1, NULL
);
1149 LineTo( hdc
, rect
->left
+ decXOff
, rect
->bottom
- height
- 1 );
1150 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->top
, NULL
);
1151 LineTo( hdc
, rect
->right
- decXOff
, rect
->top
+ height
);
1152 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->bottom
- 1, NULL
);
1153 LineTo( hdc
, rect
->right
- decXOff
, rect
->bottom
- height
- 1 );
1155 InflateRect( rect
, -width
- 1, -height
- 1 );
1160 /******************************************************************************
1162 * void NC_DrawFrame95(
1168 * Draw a window frame inside the given rectangle, and update the rectangle.
1169 * The correct pen for the frame must be selected in the DC.
1172 * Many. First, just what IS a frame in Win95? Note that the 3D look
1173 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1174 * edge. The inner rectangle just inside the frame is handled by the
1177 * In short, for most people, this function should be a nop (unless
1178 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1179 * them lately, but just to get this code right). Even so, it doesn't
1180 * appear to be so. It's being worked on...
1183 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1184 * Original implementation (based on NC_DrawFrame)
1185 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1187 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1188 * Fixed a fix or something.
1190 *****************************************************************************/
1192 static void NC_DrawFrame95(
1202 width
= GetSystemMetrics(SM_CXDLGFRAME
) - GetSystemMetrics(SM_CXEDGE
);
1203 height
= GetSystemMetrics(SM_CYDLGFRAME
) - GetSystemMetrics(SM_CYEDGE
);
1207 width
= GetSystemMetrics(SM_CXFRAME
) - GetSystemMetrics(SM_CXEDGE
);
1208 height
= GetSystemMetrics(SM_CYFRAME
) - GetSystemMetrics(SM_CYEDGE
);
1211 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1212 COLOR_INACTIVEBORDER
) );
1215 PatBlt( hdc
, rect
->left
, rect
->top
,
1216 rect
->right
- rect
->left
, height
, PATCOPY
);
1217 PatBlt( hdc
, rect
->left
, rect
->top
,
1218 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1219 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1220 rect
->right
- rect
->left
, -height
, PATCOPY
);
1221 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1222 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1224 InflateRect( rect
, -width
, -height
);
1228 /***********************************************************************
1231 * Draw the window caption.
1232 * The correct pen for the window frame must be selected in the DC.
1234 static void NC_DrawCaption( HDC hdc
, RECT
*rect
, HWND hwnd
,
1235 DWORD style
, BOOL active
)
1242 if (!(hbitmapClose
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_CLOSE
) ))) return;
1243 hbitmapMinimize
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_REDUCE
) );
1244 hbitmapMinimizeD
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_REDUCED
) );
1245 hbitmapMaximize
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_ZOOM
) );
1246 hbitmapMaximizeD
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_ZOOMD
) );
1247 hbitmapRestore
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RESTORE
) );
1248 hbitmapRestoreD
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RESTORED
) );
1251 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_DLGMODALFRAME
)
1253 HBRUSH hbrushOld
= SelectObject(hdc
, GetSysColorBrush(COLOR_WINDOW
) );
1254 PatBlt( hdc
, r
.left
, r
.top
, 1, r
.bottom
-r
.top
+1,PATCOPY
);
1255 PatBlt( hdc
, r
.right
-1, r
.top
, 1, r
.bottom
-r
.top
+1, PATCOPY
);
1256 PatBlt( hdc
, r
.left
, r
.top
-1, r
.right
-r
.left
, 1, PATCOPY
);
1259 SelectObject( hdc
, hbrushOld
);
1261 MoveToEx( hdc
, r
.left
, r
.bottom
, NULL
);
1262 LineTo( hdc
, r
.right
, r
.bottom
);
1264 if (style
& WS_SYSMENU
)
1266 NC_DrawSysButton( hwnd
, hdc
, FALSE
);
1267 r
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
1268 MoveToEx( hdc
, r
.left
- 1, r
.top
, NULL
);
1269 LineTo( hdc
, r
.left
- 1, r
.bottom
);
1271 if (style
& WS_MAXIMIZEBOX
)
1273 NC_DrawMaxButton( hwnd
, hdc
, FALSE
);
1274 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1276 if (style
& WS_MINIMIZEBOX
)
1278 NC_DrawMinButton( hwnd
, hdc
, FALSE
);
1279 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1282 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1283 COLOR_INACTIVECAPTION
) );
1285 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) ))
1287 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1288 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1289 SetBkMode( hdc
, TRANSPARENT
);
1290 DrawTextA( hdc
, buffer
, -1, &r
,
1291 DT_SINGLELINE
| DT_CENTER
| DT_VCENTER
| DT_NOPREFIX
);
1296 /******************************************************************************
1305 * Draw the window caption for Win95 style windows.
1306 * The correct pen for the window frame must be selected in the DC.
1309 * Hey, a function that finally works! Well, almost.
1310 * It's being worked on.
1313 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1314 * Original implementation.
1315 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1318 *****************************************************************************/
1320 static void NC_DrawCaption95(
1333 hPrevPen
= SelectObject( hdc
, GetSysColorPen(COLOR_3DFACE
) );
1334 MoveToEx( hdc
, r
.left
, r
.bottom
- 1, NULL
);
1335 LineTo( hdc
, r
.right
, r
.bottom
- 1 );
1336 SelectObject( hdc
, hPrevPen
);
1339 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1340 COLOR_INACTIVECAPTION
) );
1342 if ((style
& WS_SYSMENU
) && !(exStyle
& WS_EX_TOOLWINDOW
)) {
1343 if (NC_DrawSysButton95 (hwnd
, hdc
, FALSE
))
1344 r
.left
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
1347 if (style
& WS_SYSMENU
)
1351 /* Go get the sysmenu */
1352 hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1353 state
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
);
1355 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1356 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
,
1357 ((((state
& MF_DISABLED
) || (state
& MF_GRAYED
))) && (state
!= 0xFFFFFFFF)));
1358 r
.right
-= GetSystemMetrics(SM_CYCAPTION
) - 1;
1360 if ((style
& WS_MAXIMIZEBOX
) || (style
& WS_MINIMIZEBOX
))
1362 /* In win95 the two buttons are always there */
1363 /* But if the menu item is not in the menu they're disabled*/
1365 NC_DrawMaxButton95( hwnd
, hdc
, FALSE
, (!(style
& WS_MAXIMIZEBOX
)));
1366 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1368 NC_DrawMinButton95( hwnd
, hdc
, FALSE
, (!(style
& WS_MINIMIZEBOX
)));
1369 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1373 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) )) {
1374 NONCLIENTMETRICSA nclm
;
1375 HFONT hFont
, hOldFont
;
1376 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
1377 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
1378 if (exStyle
& WS_EX_TOOLWINDOW
)
1379 hFont
= CreateFontIndirectA (&nclm
.lfSmCaptionFont
);
1381 hFont
= CreateFontIndirectA (&nclm
.lfCaptionFont
);
1382 hOldFont
= SelectObject (hdc
, hFont
);
1383 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1384 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1385 SetBkMode( hdc
, TRANSPARENT
);
1387 DrawTextA( hdc
, buffer
, -1, &r
,
1388 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
1389 DeleteObject (SelectObject (hdc
, hOldFont
));
1395 /***********************************************************************
1398 * Paint the non-client area. clip is currently unused.
1400 static void NC_DoNCPaint( WND
* wndPtr
, HRGN clip
, BOOL suppress_menupaint
)
1405 HWND hwnd
= wndPtr
->hwndSelf
;
1407 if ( wndPtr
->dwStyle
& WS_MINIMIZE
||
1408 !WIN_IsWindowDrawable( wndPtr
, 0 )) return; /* Nothing to do */
1410 active
= wndPtr
->flags
& WIN_NCACTIVATED
;
1412 TRACE("%04x %d\n", hwnd
, active
);
1414 if (!(hdc
= GetDCEx( hwnd
, (clip
> 1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
1415 ((clip
> 1) ? (DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
): 0) ))) return;
1417 if (ExcludeVisRect16( hdc
, wndPtr
->rectClient
.left
-wndPtr
->rectWindow
.left
,
1418 wndPtr
->rectClient
.top
-wndPtr
->rectWindow
.top
,
1419 wndPtr
->rectClient
.right
-wndPtr
->rectWindow
.left
,
1420 wndPtr
->rectClient
.bottom
-wndPtr
->rectWindow
.top
)
1423 ReleaseDC( hwnd
, hdc
);
1427 rect
.top
= rect
.left
= 0;
1428 rect
.right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
1429 rect
.bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
1431 SelectObject( hdc
, GetSysColorPen(COLOR_WINDOWFRAME
) );
1433 if (HAS_ANYFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1435 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1436 Rectangle( hdc
, 0, 0, rect
.right
, rect
.bottom
);
1437 InflateRect( &rect
, -1, -1 );
1440 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1441 NC_DrawFrame(hdc
, &rect
, FALSE
, active
);
1442 else if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1443 NC_DrawFrame( hdc
, &rect
, TRUE
, active
);
1445 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1448 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
);
1449 rect
.top
+= GetSystemMetrics(SM_CYSIZE
) + GetSystemMetrics(SM_CYBORDER
);
1450 NC_DrawCaption( hdc
, &r
, hwnd
, wndPtr
->dwStyle
, active
);
1453 if (HAS_MENU(wndPtr
))
1456 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYMENU
); /* default height */
1457 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
);
1460 /* Draw the scroll-bars */
1462 if (wndPtr
->dwStyle
& WS_VSCROLL
)
1463 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1464 if (wndPtr
->dwStyle
& WS_HSCROLL
)
1465 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1467 /* Draw the "size-box" */
1469 if ((wndPtr
->dwStyle
& WS_VSCROLL
) && (wndPtr
->dwStyle
& WS_HSCROLL
))
1472 r
.left
= r
.right
- GetSystemMetrics(SM_CXVSCROLL
) + 1;
1473 r
.top
= r
.bottom
- GetSystemMetrics(SM_CYHSCROLL
) + 1;
1474 if(wndPtr
->dwStyle
& WS_BORDER
) {
1478 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1481 ReleaseDC( hwnd
, hdc
);
1485 /******************************************************************************
1487 * void NC_DoNCPaint95(
1490 * BOOL suppress_menupaint )
1492 * Paint the non-client area for Win95 windows. The clip region is
1493 * currently ignored.
1496 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1497 * misc/tweak.c controls/menu.c # :-)
1500 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1501 * Original implementation
1502 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1504 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1505 * Streamlined window style checks.
1507 *****************************************************************************/
1509 static void NC_DoNCPaint95(
1512 BOOL suppress_menupaint
)
1515 RECT rfuzz
, rect
, rectClip
;
1517 HWND hwnd
= wndPtr
->hwndSelf
;
1519 if ( wndPtr
->dwStyle
& WS_MINIMIZE
||
1520 !WIN_IsWindowDrawable( wndPtr
, 0 )) return; /* Nothing to do */
1522 active
= wndPtr
->flags
& WIN_NCACTIVATED
;
1524 TRACE("%04x %d\n", hwnd
, active
);
1526 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1527 the call to GetDCEx implying that it is allowed not to use it either.
1528 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1529 will cause clipRgn to be deleted after ReleaseDC().
1530 Now, how is the "system" supposed to tell what happened?
1533 if (!(hdc
= GetDCEx( hwnd
, (clip
> 1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
1534 ((clip
> 1) ?(DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
) : 0) ))) return;
1537 if (ExcludeVisRect16( hdc
, wndPtr
->rectClient
.left
-wndPtr
->rectWindow
.left
,
1538 wndPtr
->rectClient
.top
-wndPtr
->rectWindow
.top
,
1539 wndPtr
->rectClient
.right
-wndPtr
->rectWindow
.left
,
1540 wndPtr
->rectClient
.bottom
-wndPtr
->rectWindow
.top
)
1543 ReleaseDC( hwnd
, hdc
);
1547 rect
.top
= rect
.left
= 0;
1548 rect
.right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
1549 rect
.bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
1552 GetRgnBox( clip
, &rectClip
);
1559 SelectObject( hdc
, GetSysColorPen(COLOR_WINDOWFRAME
) );
1561 if (HAS_BIGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
)) {
1562 DrawEdge (hdc
, &rect
, EDGE_RAISED
, BF_RECT
| BF_ADJUST
);
1564 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1565 NC_DrawFrame95(hdc
, &rect
, FALSE
, active
);
1566 else if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1567 NC_DrawFrame95( hdc
, &rect
, TRUE
, active
);
1568 else if (HAS_THINFRAME( wndPtr
->dwStyle
)) {
1569 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1570 Rectangle( hdc
, 0, 0, rect
.right
, rect
.bottom
);
1573 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1576 if (wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
) {
1577 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSMCAPTION
);
1578 rect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
);
1581 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYCAPTION
);
1582 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
);
1584 if( !clip
|| IntersectRect( &rfuzz
, &r
, &rectClip
) )
1585 NC_DrawCaption95 (hdc
, &r
, hwnd
, wndPtr
->dwStyle
,
1586 wndPtr
->dwExStyle
, active
);
1589 if (HAS_MENU(wndPtr
))
1592 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYMENU
);
1594 TRACE("Calling DrawMenuBar with rect (%d, %d)-(%d, %d)\n",
1595 r
.left
, r
.top
, r
.right
, r
.bottom
);
1597 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
) + 1;
1600 TRACE("After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1601 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1603 if (wndPtr
->dwExStyle
& WS_EX_CLIENTEDGE
)
1604 DrawEdge (hdc
, &rect
, EDGE_SUNKEN
, BF_RECT
| BF_ADJUST
);
1606 if (wndPtr
->dwExStyle
& WS_EX_STATICEDGE
)
1607 DrawEdge (hdc
, &rect
, BDR_SUNKENOUTER
, BF_RECT
| BF_ADJUST
);
1609 /* Draw the scroll-bars */
1611 if (wndPtr
->dwStyle
& WS_VSCROLL
)
1612 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1613 if (wndPtr
->dwStyle
& WS_HSCROLL
)
1614 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1616 /* Draw the "size-box" */
1617 if ((wndPtr
->dwStyle
& WS_VSCROLL
) && (wndPtr
->dwStyle
& WS_HSCROLL
))
1620 r
.left
= r
.right
- GetSystemMetrics(SM_CXVSCROLL
) + 1;
1621 r
.top
= r
.bottom
- GetSystemMetrics(SM_CYHSCROLL
) + 1;
1622 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1625 ReleaseDC( hwnd
, hdc
);
1631 /***********************************************************************
1634 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1636 LONG
NC_HandleNCPaint( HWND hwnd
, HRGN clip
)
1638 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1640 if( wndPtr
&& wndPtr
->dwStyle
& WS_VISIBLE
)
1642 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
1643 WINPOS_RedrawIconTitle( hwnd
);
1644 else if (TWEAK_WineLook
== WIN31_LOOK
)
1645 NC_DoNCPaint( wndPtr
, clip
, FALSE
);
1647 NC_DoNCPaint95( wndPtr
, clip
, FALSE
);
1649 WIN_ReleaseWndPtr(wndPtr
);
1654 /***********************************************************************
1655 * NC_HandleNCActivate
1657 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1659 LONG
NC_HandleNCActivate( WND
*wndPtr
, WPARAM16 wParam
)
1661 /* Lotus Notes draws menu descriptions in the caption of its main
1662 * window. When it wants to restore original "system" view, it just
1663 * sends WM_NCACTIVATE message to itself. Any optimizations here in
1664 * attempt to minimize redrawings lead to a not restored caption.
1667 if (wParam
) wndPtr
->flags
|= WIN_NCACTIVATED
;
1668 else wndPtr
->flags
&= ~WIN_NCACTIVATED
;
1670 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
1671 WINPOS_RedrawIconTitle( wndPtr
->hwndSelf
);
1672 else if (TWEAK_WineLook
== WIN31_LOOK
)
1673 NC_DoNCPaint( wndPtr
, (HRGN
)1, FALSE
);
1675 NC_DoNCPaint95( wndPtr
, (HRGN
)1, FALSE
);
1681 /***********************************************************************
1682 * NC_HandleSetCursor
1684 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1686 LONG
NC_HandleSetCursor( HWND hwnd
, WPARAM16 wParam
, LPARAM lParam
)
1688 if (hwnd
!= (HWND
)wParam
) return 0; /* Don't set the cursor for child windows */
1690 switch(LOWORD(lParam
))
1694 WORD msg
= HIWORD( lParam
);
1695 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_MBUTTONDOWN
) ||
1696 (msg
== WM_RBUTTONDOWN
))
1703 HICON16 hCursor
= (HICON16
) GetClassWord(hwnd
, GCW_HCURSOR
);
1705 SetCursor16(hCursor
);
1713 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZEWEA
) );
1717 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENSA
) );
1721 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENWSEA
) );
1725 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENESWA
) );
1728 /* Default cursor: arrow */
1729 return (LONG
)SetCursor( LoadCursorA( 0, IDC_ARROWA
) );
1732 /***********************************************************************
1735 BOOL
NC_GetSysPopupPos( WND
* wndPtr
, RECT
* rect
)
1737 if( wndPtr
->hSysMenu
)
1739 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
1740 GetWindowRect( wndPtr
->hwndSelf
, rect
);
1743 NC_GetInsideRect( wndPtr
->hwndSelf
, rect
);
1744 OffsetRect( rect
, wndPtr
->rectWindow
.left
, wndPtr
->rectWindow
.top
);
1745 if (wndPtr
->dwStyle
& WS_CHILD
)
1746 ClientToScreen( wndPtr
->parent
->hwndSelf
, (POINT
*)rect
);
1747 if (TWEAK_WineLook
== WIN31_LOOK
) {
1748 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CXSIZE
);
1749 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYSIZE
);
1752 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
1753 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
1761 /***********************************************************************
1762 * NC_TrackMinMaxBox95
1764 * Track a mouse button press on the minimize or maximize box.
1766 * The big difference between 3.1 and 95 is the disabled button state.
1767 * In win95 the system button can be disabled, so it can ignore the mouse
1771 static void NC_TrackMinMaxBox95( HWND hwnd
, WORD wParam
)
1774 HDC hdc
= GetWindowDC( hwnd
);
1775 BOOL pressed
= TRUE
;
1777 DWORD wndStyle
= GetWindowLongA( hwnd
, GWL_STYLE
);
1778 HMENU hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1780 void (*paintButton
)(HWND
, HDC16
, BOOL
, BOOL
);
1782 if (wParam
== HTMINBUTTON
)
1784 /* If the style is not present, do nothing */
1785 if (!(wndStyle
& WS_MINIMIZEBOX
))
1788 /* Check if the sysmenu item for minimize is there */
1789 state
= GetMenuState(hSysMenu
, SC_MINIMIZE
, MF_BYCOMMAND
);
1791 paintButton
= &NC_DrawMinButton95
;
1795 /* If the style is not present, do nothing */
1796 if (!(wndStyle
& WS_MAXIMIZEBOX
))
1799 /* Check if the sysmenu item for maximize is there */
1800 state
= GetMenuState(hSysMenu
, SC_MAXIMIZE
, MF_BYCOMMAND
);
1802 paintButton
= &NC_DrawMaxButton95
;
1807 (*paintButton
)( hwnd
, hdc
, TRUE
, FALSE
);
1811 BOOL oldstate
= pressed
;
1812 MSG_InternalGetMessage( &msg
, 0, 0, WM_MOUSEFIRST
, WM_MOUSELAST
,
1813 0, PM_REMOVE
, FALSE
, NULL
);
1815 if(msg
.message
== WM_LBUTTONUP
)
1818 if(msg
.message
!= WM_MOUSEMOVE
)
1821 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1822 if (pressed
!= oldstate
)
1823 (*paintButton
)( hwnd
, hdc
, pressed
, FALSE
);
1827 (*paintButton
)(hwnd
, hdc
, FALSE
, FALSE
);
1830 ReleaseDC( hwnd
, hdc
);
1832 /* If the item minimize or maximize of the sysmenu are not there */
1833 /* or if the style is not present, do nothing */
1834 if ((!pressed
) || (state
== 0xFFFFFFFF))
1837 if (wParam
== HTMINBUTTON
)
1838 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1840 SendMessageA( hwnd
, WM_SYSCOMMAND
,
1841 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1844 /***********************************************************************
1847 * Track a mouse button press on the minimize or maximize box.
1849 static void NC_TrackMinMaxBox( HWND hwnd
, WORD wParam
)
1852 HDC hdc
= GetWindowDC( hwnd
);
1853 BOOL pressed
= TRUE
;
1854 void (*paintButton
)(HWND
, HDC16
, BOOL
);
1858 if (wParam
== HTMINBUTTON
)
1859 paintButton
= &NC_DrawMinButton
;
1861 paintButton
= &NC_DrawMaxButton
;
1863 (*paintButton
)( hwnd
, hdc
, TRUE
);
1867 BOOL oldstate
= pressed
;
1868 MSG_InternalGetMessage( &msg
, 0, 0, WM_MOUSEFIRST
, WM_MOUSELAST
,
1869 0, PM_REMOVE
, FALSE
, NULL
);
1871 if(msg
.message
== WM_LBUTTONUP
)
1874 if(msg
.message
!= WM_MOUSEMOVE
)
1877 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1878 if (pressed
!= oldstate
)
1879 (*paintButton
)( hwnd
, hdc
, pressed
);
1883 (*paintButton
)( hwnd
, hdc
, FALSE
);
1886 ReleaseDC( hwnd
, hdc
);
1888 if (!pressed
) return;
1890 if (wParam
== HTMINBUTTON
)
1891 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1893 SendMessageA( hwnd
, WM_SYSCOMMAND
,
1894 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1898 /***********************************************************************
1899 * NC_TrackCloseButton95
1901 * Track a mouse button press on the Win95 close button.
1904 NC_TrackCloseButton95 (HWND hwnd
, WORD wParam
)
1908 BOOL pressed
= TRUE
;
1909 HMENU hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1915 state
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
);
1917 /* If the item close of the sysmenu is disabled or not there do nothing */
1918 if((state
& MF_DISABLED
) || (state
& MF_GRAYED
) || (state
== 0xFFFFFFFF))
1921 hdc
= GetWindowDC( hwnd
);
1925 NC_DrawCloseButton95 (hwnd
, hdc
, TRUE
, FALSE
);
1929 BOOL oldstate
= pressed
;
1930 MSG_InternalGetMessage( &msg
, 0, 0, WM_MOUSEFIRST
, WM_MOUSELAST
,
1931 0, PM_REMOVE
, FALSE
, NULL
);
1933 if(msg
.message
== WM_LBUTTONUP
)
1936 if(msg
.message
!= WM_MOUSEMOVE
)
1939 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1940 if (pressed
!= oldstate
)
1941 NC_DrawCloseButton95 (hwnd
, hdc
, pressed
, FALSE
);
1945 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
, FALSE
);
1948 ReleaseDC( hwnd
, hdc
);
1949 if (!pressed
) return;
1951 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1955 /***********************************************************************
1958 * Track a mouse button press on the horizontal or vertical scroll-bar.
1960 static void NC_TrackScrollBar( HWND hwnd
, WPARAM wParam
, POINT pt
)
1964 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1966 if ((wParam
& 0xfff0) == SC_HSCROLL
)
1968 if ((wParam
& 0x0f) != HTHSCROLL
) goto END
;
1969 scrollbar
= SB_HORZ
;
1971 else /* SC_VSCROLL */
1973 if ((wParam
& 0x0f) != HTVSCROLL
) goto END
;
1974 scrollbar
= SB_VERT
;
1977 if (!(msg
= SEGPTR_NEW(MSG16
))) goto END
;
1978 pt
.x
-= wndPtr
->rectWindow
.left
;
1979 pt
.y
-= wndPtr
->rectWindow
.top
;
1981 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, WM_LBUTTONDOWN
, pt
);
1985 GetMessage16( SEGPTR_GET(msg
), 0, 0, 0 );
1986 switch(msg
->message
)
1991 pt
.x
= LOWORD(msg
->lParam
) + wndPtr
->rectClient
.left
-
1992 wndPtr
->rectWindow
.left
;
1993 pt
.y
= HIWORD(msg
->lParam
) + wndPtr
->rectClient
.top
-
1994 wndPtr
->rectWindow
.top
;
1995 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, msg
->message
, pt
);
1998 TranslateMessage16( msg
);
1999 DispatchMessage16( msg
);
2002 if (!IsWindow( hwnd
))
2007 } while (msg
->message
!= WM_LBUTTONUP
);
2010 WIN_ReleaseWndPtr(wndPtr
);
2013 /***********************************************************************
2014 * NC_HandleNCLButtonDown
2016 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2018 LONG
NC_HandleNCLButtonDown( WND
* pWnd
, WPARAM16 wParam
, LPARAM lParam
)
2020 HWND hwnd
= pWnd
->hwndSelf
;
2022 switch(wParam
) /* Hit test */
2025 hwnd
= WIN_GetTopParent(hwnd
);
2027 if( WINPOS_SetActiveWindow(hwnd
, TRUE
, TRUE
) || (GetActiveWindow() == hwnd
) )
2028 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_MOVE
+ HTCAPTION
, lParam
);
2032 if( pWnd
->dwStyle
& WS_SYSMENU
)
2034 if( !(pWnd
->dwStyle
& WS_MINIMIZE
) )
2036 HDC hDC
= GetWindowDC(hwnd
);
2037 if (TWEAK_WineLook
== WIN31_LOOK
)
2038 NC_DrawSysButton( hwnd
, hDC
, TRUE
);
2040 NC_DrawSysButton95( hwnd
, hDC
, TRUE
);
2041 ReleaseDC( hwnd
, hDC
);
2043 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
+ HTSYSMENU
, lParam
);
2048 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
, lParam
);
2052 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
2056 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
2061 if (TWEAK_WineLook
== WIN31_LOOK
)
2062 NC_TrackMinMaxBox( hwnd
, wParam
);
2064 NC_TrackMinMaxBox95( hwnd
, wParam
);
2068 if (TWEAK_WineLook
>= WIN95_LOOK
)
2069 NC_TrackCloseButton95 (hwnd
, wParam
);
2080 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2081 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_SIZE
+ wParam
- 2, lParam
);
2091 /***********************************************************************
2092 * NC_HandleNCLButtonDblClk
2094 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2096 LONG
NC_HandleNCLButtonDblClk( WND
*pWnd
, WPARAM16 wParam
, LPARAM lParam
)
2099 * if this is an icon, send a restore since we are handling
2102 if (pWnd
->dwStyle
& WS_MINIMIZE
)
2104 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_RESTORE
, lParam
);
2108 switch(wParam
) /* Hit test */
2111 /* stop processing if WS_MAXIMIZEBOX is missing */
2112 if (pWnd
->dwStyle
& WS_MAXIMIZEBOX
)
2113 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
,
2114 (pWnd
->dwStyle
& WS_MAXIMIZE
) ? SC_RESTORE
: SC_MAXIMIZE
,
2119 if (!(GetClassWord(pWnd
->hwndSelf
, GCW_STYLE
) & CS_NOCLOSE
))
2120 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_CLOSE
, lParam
);
2124 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
,
2129 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
,
2137 /***********************************************************************
2138 * NC_HandleSysCommand
2140 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2142 LONG
NC_HandleSysCommand( HWND hwnd
, WPARAM wParam
, POINT pt
)
2144 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
2145 UINT16 uCommand
= wParam
& 0xFFF0;
2147 TRACE("Handling WM_SYSCOMMAND %x %ld,%ld\n", wParam
, pt
.x
, pt
.y
);
2149 if (wndPtr
->parent
&& (uCommand
!= SC_KEYMENU
))
2150 ScreenToClient( wndPtr
->parent
->hwndSelf
, &pt
);
2156 if (USER_Driver
.pSysCommandSizeMove
)
2157 USER_Driver
.pSysCommandSizeMove( hwnd
, wParam
);
2161 if (hwnd
== GetForegroundWindow())
2162 ShowOwnedPopups(hwnd
,FALSE
);
2163 ShowWindow( hwnd
, SW_MINIMIZE
);
2167 if (IsIconic(hwnd
) && hwnd
== GetForegroundWindow())
2168 ShowOwnedPopups(hwnd
,TRUE
);
2169 ShowWindow( hwnd
, SW_MAXIMIZE
);
2173 if (IsIconic(hwnd
) && hwnd
== GetForegroundWindow())
2174 ShowOwnedPopups(hwnd
,TRUE
);
2175 ShowWindow( hwnd
, SW_RESTORE
);
2179 WIN_ReleaseWndPtr(wndPtr
);
2180 return SendMessageA( hwnd
, WM_CLOSE
, 0, 0 );
2184 NC_TrackScrollBar( hwnd
, wParam
, pt
);
2188 MENU_TrackMouseMenuBar( wndPtr
, wParam
& 0x000F, pt
);
2192 MENU_TrackKbdMenuBar( wndPtr
, wParam
, pt
.x
);
2196 WinExec( "taskman.exe", SW_SHOWNORMAL
);
2200 if (wParam
== SC_ABOUTWINE
)
2202 HMODULE hmodule
= LoadLibraryA( "shell32.dll" );
2205 FARPROC aboutproc
= GetProcAddress( hmodule
, "ShellAboutA" );
2206 if (aboutproc
) aboutproc( hwnd
, "Wine", WINE_RELEASE_INFO
, 0 );
2207 FreeLibrary( hmodule
);
2211 if (wParam
== SC_PUTMARK
)
2212 TRACE_(shell
)("Mark requested by user\n");
2219 FIXME("unimplemented!\n");
2222 WIN_ReleaseWndPtr(wndPtr
);
2226 /*************************************************************
2229 * Stub for the grayed button of the caption
2231 *************************************************************/
2233 BOOL
NC_DrawGrayButton(HDC hdc
, int x
, int y
)
2236 HDC hdcMask
= CreateCompatibleDC (0);
2239 hMaskBmp
= CreateBitmap (12, 10, 1, 1, lpGrayMask
);
2244 SelectObject (hdcMask
, hMaskBmp
);
2246 /* Draw the grayed bitmap using the mask */
2247 hOldBrush
= SelectObject (hdc
, RGB(128, 128, 128));
2248 BitBlt (hdc
, x
, y
, 12, 10,
2249 hdcMask
, 0, 0, 0xB8074A);
2252 SelectObject (hdc
, hOldBrush
);
2253 DeleteObject(hMaskBmp
);