2 * Non-client area window functions
4 * Copyright 1994 Alexandre Julliard
10 #include "wine/winuser16.h"
17 #include "cursoricon.h"
20 #include "nonclient.h"
21 #include "debugtools.h"
25 DEFAULT_DEBUG_CHANNEL(nonclient
);
26 DECLARE_DEBUG_CHANNEL(shell
);
28 BOOL
NC_DrawGrayButton(HDC hdc
, int x
, int y
);
30 static HBITMAP hbitmapClose
;
31 static HBITMAP hbitmapMinimize
;
32 static HBITMAP hbitmapMinimizeD
;
33 static HBITMAP hbitmapMaximize
;
34 static HBITMAP hbitmapMaximizeD
;
35 static HBITMAP hbitmapRestore
;
36 static HBITMAP hbitmapRestoreD
;
38 static const BYTE lpGrayMask
[] = { 0xAA, 0xA0,
49 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
50 #define SC_PUTMARK (SC_SCREENSAVE+2)
52 /* Some useful macros */
53 #define HAS_DLGFRAME(style,exStyle) \
54 (((exStyle) & WS_EX_DLGMODALFRAME) || \
55 (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
57 #define HAS_THICKFRAME(style,exStyle) \
58 (((style) & WS_THICKFRAME) && \
59 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
61 #define HAS_THINFRAME(style) \
62 (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
64 #define HAS_BIGFRAME(style,exStyle) \
65 (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
66 ((exStyle) & WS_EX_DLGMODALFRAME))
68 #define HAS_STATICOUTERFRAME(style,exStyle) \
69 (((exStyle) & (WS_EX_STATICEDGE|WS_EX_DLGMODALFRAME)) == \
72 #define HAS_ANYFRAME(style,exStyle) \
73 (((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
74 ((exStyle) & WS_EX_DLGMODALFRAME) || \
75 !((style) & (WS_CHILD | WS_POPUP)))
77 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
80 /***********************************************************************
83 * Compute the size of the window rectangle from the size of the
86 static void NC_AdjustRect( LPRECT rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
88 if (TWEAK_WineLook
> WIN31_LOOK
)
89 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
91 if(style
& WS_ICONIC
) return;
93 if (HAS_THICKFRAME( style
, exStyle
))
94 InflateRect( rect
, GetSystemMetrics(SM_CXFRAME
), GetSystemMetrics(SM_CYFRAME
) );
95 else if (HAS_DLGFRAME( style
, exStyle
))
96 InflateRect( rect
, GetSystemMetrics(SM_CXDLGFRAME
), GetSystemMetrics(SM_CYDLGFRAME
) );
97 else if (HAS_THINFRAME( style
))
98 InflateRect( rect
, GetSystemMetrics(SM_CXBORDER
), GetSystemMetrics(SM_CYBORDER
));
100 if ((style
& WS_CAPTION
) == WS_CAPTION
)
101 rect
->top
-= GetSystemMetrics(SM_CYCAPTION
) - GetSystemMetrics(SM_CYBORDER
);
103 if (menu
) rect
->top
-= GetSystemMetrics(SM_CYMENU
) + GetSystemMetrics(SM_CYBORDER
);
105 if (style
& WS_VSCROLL
) {
106 rect
->right
+= GetSystemMetrics(SM_CXVSCROLL
) - 1;
107 if(!HAS_ANYFRAME( style
, exStyle
))
111 if (style
& WS_HSCROLL
) {
112 rect
->bottom
+= GetSystemMetrics(SM_CYHSCROLL
) - 1;
113 if(!HAS_ANYFRAME( style
, exStyle
))
119 /******************************************************************************
120 * NC_AdjustRectOuter95
122 * Computes the size of the "outside" parts of the window based on the
123 * parameters of the client area.
132 * "Outer" parts of a window means the whole window frame, caption and
133 * menu bar. It does not include "inner" parts of the frame like client
134 * edge, static edge or scroll bars.
137 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
138 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
140 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
141 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
142 * NC_AdjustRectInner95 and added handling of Win95 styles.
144 * 28-Jul-1999 Ove Kåven (ovek@arcticnet.no)
145 * Streamlined window style checks.
147 *****************************************************************************/
150 NC_AdjustRectOuter95 (LPRECT rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
153 if(style
& WS_ICONIC
) return;
155 if ((exStyle
& (WS_EX_STATICEDGE
|WS_EX_DLGMODALFRAME
)) ==
158 adjust
= 1; /* for the outer frame always present */
163 if ((exStyle
& WS_EX_DLGMODALFRAME
) ||
164 (style
& (WS_THICKFRAME
|WS_DLGFRAME
))) adjust
= 2; /* outer */
166 if (style
& WS_THICKFRAME
)
167 adjust
+= ( GetSystemMetrics (SM_CXFRAME
)
168 - GetSystemMetrics (SM_CXDLGFRAME
)); /* The resize border */
169 if ((style
& (WS_BORDER
|WS_DLGFRAME
)) ||
170 (exStyle
& WS_EX_DLGMODALFRAME
))
171 adjust
++; /* The other border */
173 InflateRect (rect
, adjust
, adjust
);
175 if ((style
& WS_CAPTION
) == WS_CAPTION
)
177 if (exStyle
& WS_EX_TOOLWINDOW
)
178 rect
->top
-= GetSystemMetrics(SM_CYSMCAPTION
);
180 rect
->top
-= GetSystemMetrics(SM_CYCAPTION
);
182 if (menu
) rect
->top
-= GetSystemMetrics(SM_CYMENU
);
186 /******************************************************************************
187 * NC_AdjustRectInner95
189 * Computes the size of the "inside" part of the window based on the
190 * parameters of the client area.
198 * "Inner" part of a window means the window frame inside of the flat
199 * window frame. It includes the client edge, the static edge and the
203 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
204 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
206 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
207 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
208 * NC_AdjustRectInner95 and added handling of Win95 styles.
210 *****************************************************************************/
213 NC_AdjustRectInner95 (LPRECT rect
, DWORD style
, DWORD exStyle
)
215 if(style
& WS_ICONIC
) return;
217 if (exStyle
& WS_EX_CLIENTEDGE
)
218 InflateRect(rect
, GetSystemMetrics(SM_CXEDGE
), GetSystemMetrics(SM_CYEDGE
));
220 if (style
& WS_VSCROLL
) rect
->right
+= GetSystemMetrics(SM_CXVSCROLL
);
221 if (style
& WS_HSCROLL
) rect
->bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
226 static HICON
NC_IconForWindow( HWND hwnd
)
228 HICON hIcon
= (HICON
) GetClassLongA( hwnd
, GCL_HICONSM
);
229 if (!hIcon
) hIcon
= (HICON
) GetClassLongA( hwnd
, GCL_HICON
);
231 /* If there is no hIcon specified and this is a modal dialog,
232 * get the default one.
234 if (!hIcon
&& (GetWindowLongA( hwnd
, GWL_STYLE
) & DS_MODALFRAME
))
235 hIcon
= LoadImageA(0, IDI_WINLOGOA
, IMAGE_ICON
, 0, 0, LR_DEFAULTCOLOR
);
239 /***********************************************************************
240 * DrawCaption (USER32.@) Draws a caption bar
254 DrawCaption (HWND hwnd
, HDC hdc
, const RECT
*lpRect
, UINT uFlags
)
256 return DrawCaptionTempA (hwnd
, hdc
, lpRect
, 0, 0, NULL
, uFlags
& 0x1F);
260 /***********************************************************************
261 * DrawCaptionTempA (USER32.@)
271 DrawCaptionTempA (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
272 HICON hIcon
, LPCSTR str
, UINT uFlags
)
276 TRACE("(%08x,%08x,%p,%08x,%08x,\"%s\",%08x)\n",
277 hwnd
, hdc
, rect
, hFont
, hIcon
, str
, uFlags
);
279 /* drawing background */
280 if (uFlags
& DC_INBUTTON
) {
281 FillRect (hdc
, &rc
, GetSysColorBrush (COLOR_3DFACE
));
283 if (uFlags
& DC_ACTIVE
) {
284 HBRUSH hbr
= SelectObject (hdc
, CACHE_GetPattern55AABrush ());
285 PatBlt (hdc
, rc
.left
, rc
.top
,
286 rc
.right
-rc
.left
, rc
.bottom
-rc
.top
, 0xFA0089);
287 SelectObject (hdc
, hbr
);
291 FillRect (hdc
, &rc
, GetSysColorBrush ((uFlags
& DC_ACTIVE
) ?
292 COLOR_ACTIVECAPTION
: COLOR_INACTIVECAPTION
));
297 if ((uFlags
& DC_ICON
) && !(uFlags
& DC_SMALLCAP
)) {
301 pt
.y
= (rc
.bottom
+ rc
.top
- GetSystemMetrics(SM_CYSMICON
)) / 2;
303 if (!hIcon
) hIcon
= NC_IconForWindow(hwnd
);
304 DrawIconEx (hdc
, pt
.x
, pt
.y
, hIcon
, GetSystemMetrics(SM_CXSMICON
),
305 GetSystemMetrics(SM_CYSMICON
), 0, 0, DI_NORMAL
);
306 rc
.left
+= (rc
.bottom
- rc
.top
);
310 if (uFlags
& DC_TEXT
) {
313 if (uFlags
& DC_INBUTTON
)
314 SetTextColor (hdc
, GetSysColor (COLOR_BTNTEXT
));
315 else if (uFlags
& DC_ACTIVE
)
316 SetTextColor (hdc
, GetSysColor (COLOR_CAPTIONTEXT
));
318 SetTextColor (hdc
, GetSysColor (COLOR_INACTIVECAPTIONTEXT
));
320 SetBkMode (hdc
, TRANSPARENT
);
323 hOldFont
= SelectObject (hdc
, hFont
);
325 NONCLIENTMETRICSA nclm
;
327 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
328 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
329 hNewFont
= CreateFontIndirectA ((uFlags
& DC_SMALLCAP
) ?
330 &nclm
.lfSmCaptionFont
: &nclm
.lfCaptionFont
);
331 hOldFont
= SelectObject (hdc
, hNewFont
);
335 DrawTextA (hdc
, str
, -1, &rc
,
336 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
340 nLen
= GetWindowTextA (hwnd
, szText
, 128);
341 DrawTextA (hdc
, szText
, nLen
, &rc
,
342 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
346 SelectObject (hdc
, hOldFont
);
348 DeleteObject (SelectObject (hdc
, hOldFont
));
351 /* drawing focus ??? */
353 FIXME("undocumented flag (0x2000)!\n");
359 /***********************************************************************
360 * DrawCaptionTempW (USER32.@)
370 DrawCaptionTempW (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
371 HICON hIcon
, LPCWSTR str
, UINT uFlags
)
373 LPSTR p
= HEAP_strdupWtoA (GetProcessHeap (), 0, str
);
374 BOOL res
= DrawCaptionTempA (hwnd
, hdc
, rect
, hFont
, hIcon
, p
, uFlags
);
375 HeapFree (GetProcessHeap (), 0, p
);
380 /***********************************************************************
381 * AdjustWindowRect (USER.102)
383 BOOL16 WINAPI
AdjustWindowRect16( LPRECT16 rect
, DWORD style
, BOOL16 menu
)
385 return AdjustWindowRectEx16( rect
, style
, menu
, 0 );
389 /***********************************************************************
390 * AdjustWindowRect (USER32.@)
392 BOOL WINAPI
AdjustWindowRect( LPRECT rect
, DWORD style
, BOOL menu
)
394 return AdjustWindowRectEx( rect
, style
, menu
, 0 );
398 /***********************************************************************
399 * AdjustWindowRectEx (USER.454)
401 BOOL16 WINAPI
AdjustWindowRectEx16( LPRECT16 rect
, DWORD style
,
402 BOOL16 menu
, DWORD exStyle
)
407 CONV_RECT16TO32( rect
, &rect32
);
408 ret
= AdjustWindowRectEx( &rect32
, style
, menu
, exStyle
);
409 CONV_RECT32TO16( &rect32
, rect
);
414 /***********************************************************************
415 * AdjustWindowRectEx (USER32.@)
417 BOOL WINAPI
AdjustWindowRectEx( LPRECT rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
419 /* Correct the window style */
421 if (!(style
& (WS_POPUP
| WS_CHILD
))) style
|= WS_CAPTION
; /* Overlapped window */
422 style
&= (WS_DLGFRAME
| WS_BORDER
| WS_THICKFRAME
| WS_CHILD
);
423 exStyle
&= (WS_EX_DLGMODALFRAME
| WS_EX_CLIENTEDGE
|
424 WS_EX_STATICEDGE
| WS_EX_TOOLWINDOW
);
425 if (exStyle
& WS_EX_DLGMODALFRAME
) style
&= ~WS_THICKFRAME
;
427 TRACE("(%d,%d)-(%d,%d) %08lx %d %08lx\n",
428 rect
->left
, rect
->top
, rect
->right
, rect
->bottom
,
429 style
, menu
, exStyle
);
431 if (TWEAK_WineLook
== WIN31_LOOK
)
432 NC_AdjustRect( rect
, style
, menu
, exStyle
);
435 NC_AdjustRectOuter95( rect
, style
, menu
, exStyle
);
436 NC_AdjustRectInner95( rect
, style
, exStyle
);
442 /***********************************************************************
443 * NC_HandleNCCalcSize
445 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
447 LONG
NC_HandleNCCalcSize( HWND hwnd
, RECT
*winRect
)
449 RECT tmpRect
= { 0, 0, 0, 0 };
451 LONG cls_style
= GetClassLongA(hwnd
, GCL_STYLE
);
452 LONG style
= GetWindowLongA( hwnd
, GWL_STYLE
);
453 LONG exStyle
= GetWindowLongA( hwnd
, GWL_EXSTYLE
);
455 if (cls_style
& CS_VREDRAW
) result
|= WVR_VREDRAW
;
456 if (cls_style
& CS_HREDRAW
) result
|= WVR_HREDRAW
;
460 if (TWEAK_WineLook
== WIN31_LOOK
)
461 NC_AdjustRect( &tmpRect
, style
, FALSE
, exStyle
);
463 NC_AdjustRectOuter95( &tmpRect
, style
, FALSE
, exStyle
);
465 winRect
->left
-= tmpRect
.left
;
466 winRect
->top
-= tmpRect
.top
;
467 winRect
->right
-= tmpRect
.right
;
468 winRect
->bottom
-= tmpRect
.bottom
;
470 if (!(style
& WS_CHILD
) && GetMenu(hwnd
))
472 TRACE("Calling GetMenuBarHeight with HWND 0x%x, width %d, "
473 "at (%d, %d).\n", hwnd
,
474 winRect
->right
- winRect
->left
,
475 -tmpRect
.left
, -tmpRect
.top
);
478 MENU_GetMenuBarHeight( hwnd
,
479 winRect
->right
- winRect
->left
,
480 -tmpRect
.left
, -tmpRect
.top
) + 1;
483 if (TWEAK_WineLook
> WIN31_LOOK
) {
484 SetRect(&tmpRect
, 0, 0, 0, 0);
485 NC_AdjustRectInner95 (&tmpRect
, style
, exStyle
);
486 winRect
->left
-= tmpRect
.left
;
487 winRect
->top
-= tmpRect
.top
;
488 winRect
->right
-= tmpRect
.right
;
489 winRect
->bottom
-= tmpRect
.bottom
;
492 if (winRect
->top
> winRect
->bottom
)
493 winRect
->bottom
= winRect
->top
;
495 if (winRect
->left
> winRect
->right
)
496 winRect
->right
= winRect
->left
;
502 /***********************************************************************
505 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
506 * but without the borders (if any).
507 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
509 void NC_GetInsideRect( HWND hwnd
, RECT
*rect
)
511 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
513 rect
->top
= rect
->left
= 0;
514 rect
->right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
515 rect
->bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
517 if (wndPtr
->dwStyle
& WS_ICONIC
) goto END
;
519 /* Remove frame from rectangle */
520 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
522 InflateRect( rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
524 else if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
526 InflateRect( rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
527 /* FIXME: this isn't in NC_AdjustRect? why not? */
528 if ((TWEAK_WineLook
== WIN31_LOOK
) && (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
))
529 InflateRect( rect
, -1, 0 );
531 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
533 InflateRect( rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
) );
536 /* We have additional border information if the window
537 * is a child (but not an MDI child) */
538 if (TWEAK_WineLook
!= WIN31_LOOK
)
540 if ( (wndPtr
->dwStyle
& WS_CHILD
) &&
541 ( (wndPtr
->dwExStyle
& WS_EX_MDICHILD
) == 0 ) )
543 if (wndPtr
->dwExStyle
& WS_EX_CLIENTEDGE
)
544 InflateRect (rect
, -GetSystemMetrics(SM_CXEDGE
), -GetSystemMetrics(SM_CYEDGE
));
545 if (wndPtr
->dwExStyle
& WS_EX_STATICEDGE
)
546 InflateRect (rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
551 WIN_ReleaseWndPtr(wndPtr
);
556 /***********************************************************************
559 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
562 static LONG
NC_DoNCHitTest (WND
*wndPtr
, POINT pt
)
566 TRACE("hwnd=%04x pt=%ld,%ld\n", wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
568 GetWindowRect(wndPtr
->hwndSelf
, &rect
);
569 if (!PtInRect( &rect
, pt
)) return HTNOWHERE
;
571 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
574 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
576 InflateRect( &rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
577 if (!PtInRect( &rect
, pt
))
579 /* Check top sizing border */
582 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
583 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
586 /* Check bottom sizing border */
587 if (pt
.y
>= rect
.bottom
)
589 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
590 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
593 /* Check left sizing border */
594 if (pt
.x
< rect
.left
)
596 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
597 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
600 /* Check right sizing border */
601 if (pt
.x
>= rect
.right
)
603 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
604 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
609 else /* No thick frame */
611 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
612 InflateRect(&rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
613 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
614 InflateRect(&rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
615 if (!PtInRect( &rect
, pt
)) return HTBORDER
;
620 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
622 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
) - GetSystemMetrics(SM_CYBORDER
);
623 if (!PtInRect( &rect
, pt
))
625 /* Check system menu */
626 if ((wndPtr
->dwStyle
& WS_SYSMENU
) && !(wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
))
627 rect
.left
+= GetSystemMetrics(SM_CXSIZE
);
628 if (pt
.x
<= rect
.left
) return HTSYSMENU
;
630 /* Check maximize box */
631 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
632 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
634 if (pt
.x
>= rect
.right
) return HTMAXBUTTON
;
635 /* Check minimize box */
636 if (wndPtr
->dwStyle
& WS_MINIMIZEBOX
)
637 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
638 if (pt
.x
>= rect
.right
) return HTMINBUTTON
;
643 /* Check client area */
645 ScreenToClient( wndPtr
->hwndSelf
, &pt
);
646 GetClientRect( wndPtr
->hwndSelf
, &rect
);
647 if (PtInRect( &rect
, pt
)) return HTCLIENT
;
649 /* Check vertical scroll bar */
651 if (wndPtr
->dwStyle
& WS_VSCROLL
)
653 rect
.right
+= GetSystemMetrics(SM_CXVSCROLL
);
654 if (PtInRect( &rect
, pt
)) return HTVSCROLL
;
657 /* Check horizontal scroll bar */
659 if (wndPtr
->dwStyle
& WS_HSCROLL
)
661 rect
.bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
662 if (PtInRect( &rect
, pt
))
665 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
666 (pt
.x
>= rect
.right
- GetSystemMetrics(SM_CXVSCROLL
)))
674 if (HAS_MENU(wndPtr
))
676 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
680 /* Has to return HTNOWHERE if nothing was found
681 Could happen when a window has a customized non client area */
686 /***********************************************************************
689 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
691 * FIXME: Just a modified copy of the Win 3.1 version.
694 static LONG
NC_DoNCHitTest95 (WND
*wndPtr
, POINT pt
)
698 TRACE("hwnd=%04x pt=%ld,%ld\n", wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
700 GetWindowRect(wndPtr
->hwndSelf
, &rect
);
701 if (!PtInRect( &rect
, pt
)) return HTNOWHERE
;
703 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
706 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
708 InflateRect( &rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
709 if (!PtInRect( &rect
, pt
))
711 /* Check top sizing border */
714 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
715 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
718 /* Check bottom sizing border */
719 if (pt
.y
>= rect
.bottom
)
721 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
722 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
725 /* Check left sizing border */
726 if (pt
.x
< rect
.left
)
728 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
729 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
732 /* Check right sizing border */
733 if (pt
.x
>= rect
.right
)
735 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
736 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
741 else /* No thick frame */
743 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
744 InflateRect(&rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
745 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
746 InflateRect(&rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
747 if (!PtInRect( &rect
, pt
)) return HTBORDER
;
752 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
754 if (wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
)
755 rect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
) - 1;
757 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
758 if (!PtInRect( &rect
, pt
))
760 /* Check system menu */
761 if ((wndPtr
->dwStyle
& WS_SYSMENU
) && !(wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
))
763 if (NC_IconForWindow(wndPtr
->hwndSelf
))
764 rect
.left
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
766 if (pt
.x
< rect
.left
) return HTSYSMENU
;
768 /* Check close button */
769 if (wndPtr
->dwStyle
& WS_SYSMENU
)
770 rect
.right
-= GetSystemMetrics(SM_CYCAPTION
) - 1;
771 if (pt
.x
> rect
.right
) return HTCLOSE
;
773 /* Check maximize box */
774 /* In win95 there is automatically a Maximize button when there is a minimize one*/
775 if ((wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)|| (wndPtr
->dwStyle
& WS_MINIMIZEBOX
))
776 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
777 if (pt
.x
> rect
.right
) return HTMAXBUTTON
;
779 /* Check minimize box */
780 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
781 if ((wndPtr
->dwStyle
& WS_MINIMIZEBOX
)||(wndPtr
->dwStyle
& WS_MAXIMIZEBOX
))
782 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
784 if (pt
.x
> rect
.right
) return HTMINBUTTON
;
789 /* Check client area */
791 ScreenToClient( wndPtr
->hwndSelf
, &pt
);
792 GetClientRect( wndPtr
->hwndSelf
, &rect
);
793 if (PtInRect( &rect
, pt
)) return HTCLIENT
;
795 /* Check vertical scroll bar */
797 if (wndPtr
->dwStyle
& WS_VSCROLL
)
799 rect
.right
+= GetSystemMetrics(SM_CXVSCROLL
);
800 if (PtInRect( &rect
, pt
)) return HTVSCROLL
;
803 /* Check horizontal scroll bar */
805 if (wndPtr
->dwStyle
& WS_HSCROLL
)
807 rect
.bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
808 if (PtInRect( &rect
, pt
))
811 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
812 (pt
.x
>= rect
.right
- GetSystemMetrics(SM_CXVSCROLL
)))
820 if (HAS_MENU(wndPtr
))
822 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
826 /* Has to return HTNOWHERE if nothing was found
827 Could happen when a window has a customized non client area */
832 /***********************************************************************
835 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
837 LONG
NC_HandleNCHitTest (HWND hwnd
, POINT pt
)
840 WND
*wndPtr
= WIN_FindWndPtr (hwnd
);
845 if (TWEAK_WineLook
== WIN31_LOOK
)
846 retvalue
= NC_DoNCHitTest (wndPtr
, pt
);
848 retvalue
= NC_DoNCHitTest95 (wndPtr
, pt
);
849 WIN_ReleaseWndPtr(wndPtr
);
854 /***********************************************************************
857 void NC_DrawSysButton( HWND hwnd
, HDC hdc
, BOOL down
)
863 NC_GetInsideRect( hwnd
, &rect
);
864 hdcMem
= CreateCompatibleDC( hdc
);
865 hbitmap
= SelectObject( hdcMem
, hbitmapClose
);
866 BitBlt(hdc
, rect
.left
, rect
.top
, GetSystemMetrics(SM_CXSIZE
), GetSystemMetrics(SM_CYSIZE
),
867 hdcMem
, (GetWindowLongA(hwnd
,GWL_STYLE
) & WS_CHILD
) ? GetSystemMetrics(SM_CXSIZE
) : 0, 0,
868 down
? NOTSRCCOPY
: SRCCOPY
);
869 SelectObject( hdcMem
, hbitmap
);
874 /***********************************************************************
877 static void NC_DrawMaxButton( HWND hwnd
, HDC16 hdc
, BOOL down
)
882 NC_GetInsideRect( hwnd
, &rect
);
883 hdcMem
= CreateCompatibleDC( hdc
);
884 SelectObject( hdcMem
, (IsZoomed(hwnd
)
885 ? (down
? hbitmapRestoreD
: hbitmapRestore
)
886 : (down
? hbitmapMaximizeD
: hbitmapMaximize
)) );
887 BitBlt( hdc
, rect
.right
- GetSystemMetrics(SM_CXSIZE
) - 1, rect
.top
,
888 GetSystemMetrics(SM_CXSIZE
) + 1, GetSystemMetrics(SM_CYSIZE
), hdcMem
, 0, 0,
895 /***********************************************************************
898 static void NC_DrawMinButton( HWND hwnd
, HDC16 hdc
, BOOL down
)
903 NC_GetInsideRect( hwnd
, &rect
);
904 hdcMem
= CreateCompatibleDC( hdc
);
905 SelectObject( hdcMem
, (down
? hbitmapMinimizeD
: hbitmapMinimize
) );
906 if (GetWindowLongA(hwnd
,GWL_STYLE
) & WS_MAXIMIZEBOX
)
907 rect
.right
-= GetSystemMetrics(SM_CXSIZE
)+1;
908 BitBlt( hdc
, rect
.right
- GetSystemMetrics(SM_CXSIZE
) - 1, rect
.top
,
909 GetSystemMetrics(SM_CXSIZE
) + 1, GetSystemMetrics(SM_CYSIZE
), hdcMem
, 0, 0,
915 /******************************************************************************
917 * void NC_DrawSysButton95(
922 * Draws the Win95 system icon.
925 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
926 * Original implementation from NC_DrawSysButton source.
927 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
930 *****************************************************************************/
933 NC_DrawSysButton95 (HWND hwnd
, HDC hdc
, BOOL down
)
935 HICON hIcon
= NC_IconForWindow( hwnd
);
940 NC_GetInsideRect( hwnd
, &rect
);
941 DrawIconEx (hdc
, rect
.left
+ 2, rect
.top
+ 2, hIcon
,
942 GetSystemMetrics(SM_CXSMICON
),
943 GetSystemMetrics(SM_CYSMICON
), 0, 0, DI_NORMAL
);
949 /******************************************************************************
951 * void NC_DrawCloseButton95(
957 * Draws the Win95 close button.
959 * If bGrayed is true, then draw a disabled Close button
962 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
963 * Original implementation from NC_DrawSysButton95 source.
965 *****************************************************************************/
967 static void NC_DrawCloseButton95 (HWND hwnd
, HDC hdc
, BOOL down
, BOOL bGrayed
)
971 NC_GetInsideRect( hwnd
, &rect
);
973 /* A tool window has a smaller Close button */
974 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_TOOLWINDOW
)
976 INT iBmpHeight
= 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
977 INT iBmpWidth
= 11; /* it uses 11x11 for the close button in tool window */
978 INT iCaptionHeight
= GetSystemMetrics(SM_CYSMCAPTION
);
980 rect
.top
= rect
.top
+ (iCaptionHeight
- 1 - iBmpHeight
) / 2;
981 rect
.left
= rect
.right
- (iCaptionHeight
+ 1 + iBmpWidth
) / 2;
982 rect
.bottom
= rect
.top
+ iBmpHeight
;
983 rect
.right
= rect
.left
+ iBmpWidth
;
987 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
) - 1;
988 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
992 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
,
994 (down
? DFCS_PUSHED
: 0) |
995 (bGrayed
? DFCS_INACTIVE
: 0)) );
998 /******************************************************************************
1001 * Draws the maximize button for Win95 style windows.
1002 * If bGrayed is true, then draw a disabled Maximize button
1004 static void NC_DrawMaxButton95(HWND hwnd
,HDC16 hdc
,BOOL down
, BOOL bGrayed
)
1007 UINT flags
= IsZoomed(hwnd
) ? DFCS_CAPTIONRESTORE
: DFCS_CAPTIONMAX
;
1009 NC_GetInsideRect( hwnd
, &rect
);
1010 if (GetWindowLongA( hwnd
, GWL_STYLE
) & WS_SYSMENU
)
1011 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1012 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
);
1013 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1016 if (down
) flags
|= DFCS_PUSHED
;
1017 if (bGrayed
) flags
|= DFCS_INACTIVE
;
1018 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
1021 /******************************************************************************
1022 * NC_DrawMinButton95
1024 * Draws the minimize button for Win95 style windows.
1025 * If bGrayed is true, then draw a disabled Minimize button
1027 static void NC_DrawMinButton95(HWND hwnd
,HDC16 hdc
,BOOL down
, BOOL bGrayed
)
1030 UINT flags
= DFCS_CAPTIONMIN
;
1031 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
1033 NC_GetInsideRect( hwnd
, &rect
);
1034 if (style
& WS_SYSMENU
)
1035 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1036 if (style
& (WS_MAXIMIZEBOX
|WS_MINIMIZEBOX
))
1037 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) - 2;
1038 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
);
1039 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1042 if (down
) flags
|= DFCS_PUSHED
;
1043 if (bGrayed
) flags
|= DFCS_INACTIVE
;
1044 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
1047 /***********************************************************************
1050 * Draw a window frame inside the given rectangle, and update the rectangle.
1051 * The correct pen for the frame must be selected in the DC.
1053 static void NC_DrawFrame( HDC hdc
, RECT
*rect
, BOOL dlgFrame
,
1058 if (TWEAK_WineLook
!= WIN31_LOOK
)
1059 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
1063 width
= GetSystemMetrics(SM_CXDLGFRAME
) - 1;
1064 height
= GetSystemMetrics(SM_CYDLGFRAME
) - 1;
1065 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1066 COLOR_INACTIVECAPTION
) );
1070 width
= GetSystemMetrics(SM_CXFRAME
) - 2;
1071 height
= GetSystemMetrics(SM_CYFRAME
) - 2;
1072 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1073 COLOR_INACTIVEBORDER
) );
1077 PatBlt( hdc
, rect
->left
, rect
->top
,
1078 rect
->right
- rect
->left
, height
, PATCOPY
);
1079 PatBlt( hdc
, rect
->left
, rect
->top
,
1080 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1081 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1082 rect
->right
- rect
->left
, -height
, PATCOPY
);
1083 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1084 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1088 InflateRect( rect
, -width
, -height
);
1092 INT decYOff
= GetSystemMetrics(SM_CXFRAME
) + GetSystemMetrics(SM_CXSIZE
) - 1;
1093 INT decXOff
= GetSystemMetrics(SM_CYFRAME
) + GetSystemMetrics(SM_CYSIZE
) - 1;
1095 /* Draw inner rectangle */
1097 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1098 Rectangle( hdc
, rect
->left
+ width
, rect
->top
+ height
,
1099 rect
->right
- width
, rect
->bottom
- height
);
1101 /* Draw the decorations */
1103 MoveToEx( hdc
, rect
->left
, rect
->top
+ decYOff
, NULL
);
1104 LineTo( hdc
, rect
->left
+ width
, rect
->top
+ decYOff
);
1105 MoveToEx( hdc
, rect
->right
- 1, rect
->top
+ decYOff
, NULL
);
1106 LineTo( hdc
, rect
->right
- width
- 1, rect
->top
+ decYOff
);
1107 MoveToEx( hdc
, rect
->left
, rect
->bottom
- decYOff
, NULL
);
1108 LineTo( hdc
, rect
->left
+ width
, rect
->bottom
- decYOff
);
1109 MoveToEx( hdc
, rect
->right
- 1, rect
->bottom
- decYOff
, NULL
);
1110 LineTo( hdc
, rect
->right
- width
- 1, rect
->bottom
- decYOff
);
1112 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->top
, NULL
);
1113 LineTo( hdc
, rect
->left
+ decXOff
, rect
->top
+ height
);
1114 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->bottom
- 1, NULL
);
1115 LineTo( hdc
, rect
->left
+ decXOff
, rect
->bottom
- height
- 1 );
1116 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->top
, NULL
);
1117 LineTo( hdc
, rect
->right
- decXOff
, rect
->top
+ height
);
1118 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->bottom
- 1, NULL
);
1119 LineTo( hdc
, rect
->right
- decXOff
, rect
->bottom
- height
- 1 );
1121 InflateRect( rect
, -width
- 1, -height
- 1 );
1126 /******************************************************************************
1128 * void NC_DrawFrame95(
1135 * Draw a window frame inside the given rectangle, and update the rectangle.
1138 * Many. First, just what IS a frame in Win95? Note that the 3D look
1139 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1140 * edge. The inner rectangle just inside the frame is handled by the
1143 * In short, for most people, this function should be a nop (unless
1144 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1145 * them lately, but just to get this code right). Even so, it doesn't
1146 * appear to be so. It's being worked on...
1149 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1150 * Original implementation (based on NC_DrawFrame)
1151 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1153 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1154 * Fixed a fix or something.
1156 *****************************************************************************/
1158 static void NC_DrawFrame95(
1167 /* Firstly the "thick" frame */
1168 if (style
& WS_THICKFRAME
)
1170 width
= GetSystemMetrics(SM_CXFRAME
) - GetSystemMetrics(SM_CXDLGFRAME
);
1171 height
= GetSystemMetrics(SM_CYFRAME
) - GetSystemMetrics(SM_CYDLGFRAME
);
1173 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1174 COLOR_INACTIVEBORDER
) );
1176 PatBlt( hdc
, rect
->left
, rect
->top
,
1177 rect
->right
- rect
->left
, height
, PATCOPY
);
1178 PatBlt( hdc
, rect
->left
, rect
->top
,
1179 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1180 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1181 rect
->right
- rect
->left
, -height
, PATCOPY
);
1182 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1183 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1185 InflateRect( rect
, -width
, -height
);
1188 /* Now the other bit of the frame */
1189 if ((style
& (WS_BORDER
|WS_DLGFRAME
)) ||
1190 (exStyle
& WS_EX_DLGMODALFRAME
))
1192 width
= GetSystemMetrics(SM_CXDLGFRAME
) - GetSystemMetrics(SM_CXEDGE
);
1193 height
= GetSystemMetrics(SM_CYDLGFRAME
) - GetSystemMetrics(SM_CYEDGE
);
1194 /* This should give a value of 1 that should also work for a border */
1196 SelectObject( hdc
, GetSysColorBrush(
1197 (exStyle
& (WS_EX_DLGMODALFRAME
|WS_EX_CLIENTEDGE
)) ?
1199 (exStyle
& WS_EX_STATICEDGE
) ?
1201 (style
& (WS_DLGFRAME
|WS_THICKFRAME
)) ?
1204 COLOR_WINDOWFRAME
));
1207 PatBlt( hdc
, rect
->left
, rect
->top
,
1208 rect
->right
- rect
->left
, height
, PATCOPY
);
1209 PatBlt( hdc
, rect
->left
, rect
->top
,
1210 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1211 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1212 rect
->right
- rect
->left
, -height
, PATCOPY
);
1213 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1214 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1216 InflateRect( rect
, -width
, -height
);
1221 /***********************************************************************
1224 * Draw the window caption.
1225 * The correct pen for the window frame must be selected in the DC.
1227 static void NC_DrawCaption( HDC hdc
, RECT
*rect
, HWND hwnd
,
1228 DWORD style
, BOOL active
)
1235 if (!(hbitmapClose
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_CLOSE
) ))) return;
1236 hbitmapMinimize
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_REDUCE
) );
1237 hbitmapMinimizeD
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_REDUCED
) );
1238 hbitmapMaximize
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_ZOOM
) );
1239 hbitmapMaximizeD
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_ZOOMD
) );
1240 hbitmapRestore
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RESTORE
) );
1241 hbitmapRestoreD
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RESTORED
) );
1244 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_DLGMODALFRAME
)
1246 HBRUSH hbrushOld
= SelectObject(hdc
, GetSysColorBrush(COLOR_WINDOW
) );
1247 PatBlt( hdc
, r
.left
, r
.top
, 1, r
.bottom
-r
.top
+1,PATCOPY
);
1248 PatBlt( hdc
, r
.right
-1, r
.top
, 1, r
.bottom
-r
.top
+1, PATCOPY
);
1249 PatBlt( hdc
, r
.left
, r
.top
-1, r
.right
-r
.left
, 1, PATCOPY
);
1252 SelectObject( hdc
, hbrushOld
);
1254 MoveToEx( hdc
, r
.left
, r
.bottom
, NULL
);
1255 LineTo( hdc
, r
.right
, r
.bottom
);
1257 if (style
& WS_SYSMENU
)
1259 NC_DrawSysButton( hwnd
, hdc
, FALSE
);
1260 r
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
1261 MoveToEx( hdc
, r
.left
- 1, r
.top
, NULL
);
1262 LineTo( hdc
, r
.left
- 1, r
.bottom
);
1264 if (style
& WS_MAXIMIZEBOX
)
1266 NC_DrawMaxButton( hwnd
, hdc
, FALSE
);
1267 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1269 if (style
& WS_MINIMIZEBOX
)
1271 NC_DrawMinButton( hwnd
, hdc
, FALSE
);
1272 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1275 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1276 COLOR_INACTIVECAPTION
) );
1278 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) ))
1280 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1281 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1282 SetBkMode( hdc
, TRANSPARENT
);
1283 DrawTextA( hdc
, buffer
, -1, &r
,
1284 DT_SINGLELINE
| DT_CENTER
| DT_VCENTER
| DT_NOPREFIX
);
1289 /******************************************************************************
1298 * Draw the window caption for Win95 style windows.
1299 * The correct pen for the window frame must be selected in the DC.
1302 * Hey, a function that finally works! Well, almost.
1303 * It's being worked on.
1306 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1307 * Original implementation.
1308 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1311 *****************************************************************************/
1313 static void NC_DrawCaption95(
1326 hPrevPen
= SelectObject( hdc
, GetSysColorPen(
1327 ((exStyle
& (WS_EX_STATICEDGE
|WS_EX_CLIENTEDGE
|
1328 WS_EX_DLGMODALFRAME
)) == WS_EX_STATICEDGE
) ?
1329 COLOR_WINDOWFRAME
: COLOR_3DFACE
) );
1330 MoveToEx( hdc
, r
.left
, r
.bottom
- 1, NULL
);
1331 LineTo( hdc
, r
.right
, r
.bottom
- 1 );
1332 SelectObject( hdc
, hPrevPen
);
1335 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1336 COLOR_INACTIVECAPTION
) );
1338 if ((style
& WS_SYSMENU
) && !(exStyle
& WS_EX_TOOLWINDOW
)) {
1339 if (NC_DrawSysButton95 (hwnd
, hdc
, FALSE
))
1340 r
.left
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
1343 if (style
& WS_SYSMENU
)
1347 /* Go get the sysmenu */
1348 hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1349 state
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
);
1351 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1352 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
,
1353 ((((state
& MF_DISABLED
) || (state
& MF_GRAYED
))) && (state
!= 0xFFFFFFFF)));
1354 r
.right
-= GetSystemMetrics(SM_CYCAPTION
) - 1;
1356 if ((style
& WS_MAXIMIZEBOX
) || (style
& WS_MINIMIZEBOX
))
1358 /* In win95 the two buttons are always there */
1359 /* But if the menu item is not in the menu they're disabled*/
1361 NC_DrawMaxButton95( hwnd
, hdc
, FALSE
, (!(style
& WS_MAXIMIZEBOX
)));
1362 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1364 NC_DrawMinButton95( hwnd
, hdc
, FALSE
, (!(style
& WS_MINIMIZEBOX
)));
1365 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1369 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) )) {
1370 NONCLIENTMETRICSA nclm
;
1371 HFONT hFont
, hOldFont
;
1372 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
1373 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
1374 if (exStyle
& WS_EX_TOOLWINDOW
)
1375 hFont
= CreateFontIndirectA (&nclm
.lfSmCaptionFont
);
1377 hFont
= CreateFontIndirectA (&nclm
.lfCaptionFont
);
1378 hOldFont
= SelectObject (hdc
, hFont
);
1379 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1380 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1381 SetBkMode( hdc
, TRANSPARENT
);
1383 DrawTextA( hdc
, buffer
, -1, &r
,
1384 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
1385 DeleteObject (SelectObject (hdc
, hOldFont
));
1391 /***********************************************************************
1394 * Paint the non-client area. clip is currently unused.
1396 static void NC_DoNCPaint( WND
* wndPtr
, HRGN clip
, BOOL suppress_menupaint
)
1401 HWND hwnd
= wndPtr
->hwndSelf
;
1403 if ( wndPtr
->dwStyle
& WS_MINIMIZE
||
1404 !WIN_IsWindowDrawable( wndPtr
, 0 )) return; /* Nothing to do */
1406 active
= wndPtr
->flags
& WIN_NCACTIVATED
;
1408 TRACE("%04x %d\n", hwnd
, active
);
1410 if (!(hdc
= GetDCEx( hwnd
, (clip
> 1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
1411 ((clip
> 1) ? (DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
): 0) ))) return;
1413 if (ExcludeVisRect16( hdc
, wndPtr
->rectClient
.left
-wndPtr
->rectWindow
.left
,
1414 wndPtr
->rectClient
.top
-wndPtr
->rectWindow
.top
,
1415 wndPtr
->rectClient
.right
-wndPtr
->rectWindow
.left
,
1416 wndPtr
->rectClient
.bottom
-wndPtr
->rectWindow
.top
)
1419 ReleaseDC( hwnd
, hdc
);
1423 rect
.top
= rect
.left
= 0;
1424 rect
.right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
1425 rect
.bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
1427 SelectObject( hdc
, GetSysColorPen(COLOR_WINDOWFRAME
) );
1429 if (HAS_ANYFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1431 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1432 Rectangle( hdc
, 0, 0, rect
.right
, rect
.bottom
);
1433 InflateRect( &rect
, -1, -1 );
1436 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1437 NC_DrawFrame(hdc
, &rect
, FALSE
, active
);
1438 else if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1439 NC_DrawFrame( hdc
, &rect
, TRUE
, active
);
1441 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1444 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
);
1445 rect
.top
+= GetSystemMetrics(SM_CYSIZE
) + GetSystemMetrics(SM_CYBORDER
);
1446 NC_DrawCaption( hdc
, &r
, hwnd
, wndPtr
->dwStyle
, active
);
1449 if (HAS_MENU(wndPtr
))
1452 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYMENU
); /* default height */
1453 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
);
1456 /* Draw the scroll-bars */
1458 if (wndPtr
->dwStyle
& WS_VSCROLL
)
1459 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1460 if (wndPtr
->dwStyle
& WS_HSCROLL
)
1461 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1463 /* Draw the "size-box" */
1465 if ((wndPtr
->dwStyle
& WS_VSCROLL
) && (wndPtr
->dwStyle
& WS_HSCROLL
))
1468 r
.left
= r
.right
- GetSystemMetrics(SM_CXVSCROLL
) + 1;
1469 r
.top
= r
.bottom
- GetSystemMetrics(SM_CYHSCROLL
) + 1;
1470 if(wndPtr
->dwStyle
& WS_BORDER
) {
1474 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1477 ReleaseDC( hwnd
, hdc
);
1481 /******************************************************************************
1483 * void NC_DoNCPaint95(
1486 * BOOL suppress_menupaint )
1488 * Paint the non-client area for Win95 windows. The clip region is
1489 * currently ignored.
1492 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1493 * misc/tweak.c controls/menu.c # :-)
1496 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1497 * Original implementation
1498 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1500 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1501 * Streamlined window style checks.
1503 *****************************************************************************/
1505 static void NC_DoNCPaint95(
1508 BOOL suppress_menupaint
)
1511 RECT rfuzz
, rect
, rectClip
;
1513 HWND hwnd
= wndPtr
->hwndSelf
;
1515 if ( wndPtr
->dwStyle
& WS_MINIMIZE
||
1516 !WIN_IsWindowDrawable( wndPtr
, 0 )) return; /* Nothing to do */
1518 active
= wndPtr
->flags
& WIN_NCACTIVATED
;
1520 TRACE("%04x %d\n", hwnd
, active
);
1522 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1523 the call to GetDCEx implying that it is allowed not to use it either.
1524 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1525 will cause clipRgn to be deleted after ReleaseDC().
1526 Now, how is the "system" supposed to tell what happened?
1529 if (!(hdc
= GetDCEx( hwnd
, (clip
> 1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
1530 ((clip
> 1) ?(DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
) : 0) ))) return;
1533 if (ExcludeVisRect16( hdc
, wndPtr
->rectClient
.left
-wndPtr
->rectWindow
.left
,
1534 wndPtr
->rectClient
.top
-wndPtr
->rectWindow
.top
,
1535 wndPtr
->rectClient
.right
-wndPtr
->rectWindow
.left
,
1536 wndPtr
->rectClient
.bottom
-wndPtr
->rectWindow
.top
)
1539 ReleaseDC( hwnd
, hdc
);
1543 rect
.top
= rect
.left
= 0;
1544 rect
.right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
1545 rect
.bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
1548 GetRgnBox( clip
, &rectClip
);
1555 SelectObject( hdc
, GetSysColorPen(COLOR_WINDOWFRAME
) );
1557 if (HAS_STATICOUTERFRAME(wndPtr
->dwStyle
, wndPtr
->dwExStyle
)) {
1558 DrawEdge (hdc
, &rect
, BDR_SUNKENOUTER
, BF_RECT
| BF_ADJUST
);
1560 else if (HAS_BIGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
)) {
1561 DrawEdge (hdc
, &rect
, EDGE_RAISED
, BF_RECT
| BF_ADJUST
);
1564 NC_DrawFrame95(hdc
, &rect
, active
, wndPtr
->dwStyle
, wndPtr
->dwExStyle
);
1566 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1569 if (wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
) {
1570 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSMCAPTION
);
1571 rect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
);
1574 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYCAPTION
);
1575 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
);
1577 if( !clip
|| IntersectRect( &rfuzz
, &r
, &rectClip
) )
1578 NC_DrawCaption95 (hdc
, &r
, hwnd
, wndPtr
->dwStyle
,
1579 wndPtr
->dwExStyle
, active
);
1582 if (HAS_MENU(wndPtr
))
1585 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYMENU
);
1587 TRACE("Calling DrawMenuBar with rect (%d, %d)-(%d, %d)\n",
1588 r
.left
, r
.top
, r
.right
, r
.bottom
);
1590 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
) + 1;
1593 TRACE("After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1594 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1596 if (wndPtr
->dwExStyle
& WS_EX_CLIENTEDGE
)
1597 DrawEdge (hdc
, &rect
, EDGE_SUNKEN
, BF_RECT
| BF_ADJUST
);
1599 /* Draw the scroll-bars */
1601 if (wndPtr
->dwStyle
& WS_VSCROLL
)
1602 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1603 if (wndPtr
->dwStyle
& WS_HSCROLL
)
1604 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1606 /* Draw the "size-box" */
1607 if ((wndPtr
->dwStyle
& WS_VSCROLL
) && (wndPtr
->dwStyle
& WS_HSCROLL
))
1610 r
.left
= r
.right
- GetSystemMetrics(SM_CXVSCROLL
) + 1;
1611 r
.top
= r
.bottom
- GetSystemMetrics(SM_CYHSCROLL
) + 1;
1612 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1615 ReleaseDC( hwnd
, hdc
);
1621 /***********************************************************************
1624 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1626 LONG
NC_HandleNCPaint( HWND hwnd
, HRGN clip
)
1628 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1630 if( wndPtr
&& wndPtr
->dwStyle
& WS_VISIBLE
)
1632 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
1633 WINPOS_RedrawIconTitle( hwnd
);
1634 else if (TWEAK_WineLook
== WIN31_LOOK
)
1635 NC_DoNCPaint( wndPtr
, clip
, FALSE
);
1637 NC_DoNCPaint95( wndPtr
, clip
, FALSE
);
1639 WIN_ReleaseWndPtr(wndPtr
);
1644 /***********************************************************************
1645 * NC_HandleNCActivate
1647 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1649 LONG
NC_HandleNCActivate( HWND hwnd
, WPARAM wParam
)
1651 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1653 /* Lotus Notes draws menu descriptions in the caption of its main
1654 * window. When it wants to restore original "system" view, it just
1655 * sends WM_NCACTIVATE message to itself. Any optimizations here in
1656 * attempt to minimize redrawings lead to a not restored caption.
1660 if (wParam
) wndPtr
->flags
|= WIN_NCACTIVATED
;
1661 else wndPtr
->flags
&= ~WIN_NCACTIVATED
;
1663 if (IsIconic(hwnd
)) WINPOS_RedrawIconTitle( hwnd
);
1664 else if (TWEAK_WineLook
== WIN31_LOOK
)
1665 NC_DoNCPaint( wndPtr
, (HRGN
)1, FALSE
);
1667 NC_DoNCPaint95( wndPtr
, (HRGN
)1, FALSE
);
1668 WIN_ReleaseWndPtr(wndPtr
);
1674 /***********************************************************************
1675 * NC_HandleSetCursor
1677 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1679 LONG
NC_HandleSetCursor( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1681 if (hwnd
!= WIN_GetFullHandle( (HWND
)wParam
))
1682 return 0; /* Don't set the cursor for child windows */
1684 switch(LOWORD(lParam
))
1688 WORD msg
= HIWORD( lParam
);
1689 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_MBUTTONDOWN
) ||
1690 (msg
== WM_RBUTTONDOWN
))
1697 HCURSOR hCursor
= GetClassLongA(hwnd
, GCL_HCURSOR
);
1707 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZEWEA
) );
1711 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENSA
) );
1715 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENWSEA
) );
1719 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENESWA
) );
1722 /* Default cursor: arrow */
1723 return (LONG
)SetCursor( LoadCursorA( 0, IDC_ARROWA
) );
1726 /***********************************************************************
1729 void NC_GetSysPopupPos( HWND hwnd
, RECT
* rect
)
1731 if (IsIconic(hwnd
)) GetWindowRect( hwnd
, rect
);
1734 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1735 if (!wndPtr
) return;
1737 NC_GetInsideRect( hwnd
, rect
);
1738 OffsetRect( rect
, wndPtr
->rectWindow
.left
, wndPtr
->rectWindow
.top
);
1739 if (wndPtr
->dwStyle
& WS_CHILD
)
1740 ClientToScreen( GetParent(hwnd
), (POINT
*)rect
);
1741 if (TWEAK_WineLook
== WIN31_LOOK
) {
1742 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CXSIZE
);
1743 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYSIZE
);
1746 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
1747 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
1749 WIN_ReleaseWndPtr( wndPtr
);
1753 /***********************************************************************
1754 * NC_TrackMinMaxBox95
1756 * Track a mouse button press on the minimize or maximize box.
1758 * The big difference between 3.1 and 95 is the disabled button state.
1759 * In win95 the system button can be disabled, so it can ignore the mouse
1763 static void NC_TrackMinMaxBox95( HWND hwnd
, WORD wParam
)
1766 HDC hdc
= GetWindowDC( hwnd
);
1767 BOOL pressed
= TRUE
;
1769 DWORD wndStyle
= GetWindowLongA( hwnd
, GWL_STYLE
);
1770 HMENU hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1772 void (*paintButton
)(HWND
, HDC16
, BOOL
, BOOL
);
1774 if (wParam
== HTMINBUTTON
)
1776 /* If the style is not present, do nothing */
1777 if (!(wndStyle
& WS_MINIMIZEBOX
))
1780 /* Check if the sysmenu item for minimize is there */
1781 state
= GetMenuState(hSysMenu
, SC_MINIMIZE
, MF_BYCOMMAND
);
1783 paintButton
= &NC_DrawMinButton95
;
1787 /* If the style is not present, do nothing */
1788 if (!(wndStyle
& WS_MAXIMIZEBOX
))
1791 /* Check if the sysmenu item for maximize is there */
1792 state
= GetMenuState(hSysMenu
, SC_MAXIMIZE
, MF_BYCOMMAND
);
1794 paintButton
= &NC_DrawMaxButton95
;
1799 (*paintButton
)( hwnd
, hdc
, TRUE
, FALSE
);
1803 BOOL oldstate
= pressed
;
1805 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1806 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1808 if(msg
.message
== WM_LBUTTONUP
)
1811 if(msg
.message
!= WM_MOUSEMOVE
)
1814 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1815 if (pressed
!= oldstate
)
1816 (*paintButton
)( hwnd
, hdc
, pressed
, FALSE
);
1820 (*paintButton
)(hwnd
, hdc
, FALSE
, FALSE
);
1823 ReleaseDC( hwnd
, hdc
);
1825 /* If the item minimize or maximize of the sysmenu are not there */
1826 /* or if the style is not present, do nothing */
1827 if ((!pressed
) || (state
== 0xFFFFFFFF))
1830 if (wParam
== HTMINBUTTON
)
1831 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1833 SendMessageA( hwnd
, WM_SYSCOMMAND
,
1834 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1837 /***********************************************************************
1840 * Track a mouse button press on the minimize or maximize box.
1842 static void NC_TrackMinMaxBox( HWND hwnd
, WORD wParam
)
1845 HDC hdc
= GetWindowDC( hwnd
);
1846 BOOL pressed
= TRUE
;
1847 void (*paintButton
)(HWND
, HDC16
, BOOL
);
1851 if (wParam
== HTMINBUTTON
)
1852 paintButton
= &NC_DrawMinButton
;
1854 paintButton
= &NC_DrawMaxButton
;
1856 (*paintButton
)( hwnd
, hdc
, TRUE
);
1860 BOOL oldstate
= pressed
;
1862 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1863 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1865 if(msg
.message
== WM_LBUTTONUP
)
1868 if(msg
.message
!= WM_MOUSEMOVE
)
1871 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1872 if (pressed
!= oldstate
)
1873 (*paintButton
)( hwnd
, hdc
, pressed
);
1877 (*paintButton
)( hwnd
, hdc
, FALSE
);
1880 ReleaseDC( hwnd
, hdc
);
1882 if (!pressed
) return;
1884 if (wParam
== HTMINBUTTON
)
1885 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1887 SendMessageA( hwnd
, WM_SYSCOMMAND
,
1888 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1892 /***********************************************************************
1893 * NC_TrackCloseButton95
1895 * Track a mouse button press on the Win95 close button.
1898 NC_TrackCloseButton95 (HWND hwnd
, WORD wParam
)
1902 BOOL pressed
= TRUE
;
1903 HMENU hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1909 state
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
);
1911 /* If the item close of the sysmenu is disabled or not there do nothing */
1912 if((state
& MF_DISABLED
) || (state
& MF_GRAYED
) || (state
== 0xFFFFFFFF))
1915 hdc
= GetWindowDC( hwnd
);
1919 NC_DrawCloseButton95 (hwnd
, hdc
, TRUE
, FALSE
);
1923 BOOL oldstate
= pressed
;
1925 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1926 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1928 if(msg
.message
== WM_LBUTTONUP
)
1931 if(msg
.message
!= WM_MOUSEMOVE
)
1934 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1935 if (pressed
!= oldstate
)
1936 NC_DrawCloseButton95 (hwnd
, hdc
, pressed
, FALSE
);
1940 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
, FALSE
);
1943 ReleaseDC( hwnd
, hdc
);
1944 if (!pressed
) return;
1946 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1950 /***********************************************************************
1953 * Track a mouse button press on the horizontal or vertical scroll-bar.
1955 static void NC_TrackScrollBar( HWND hwnd
, WPARAM wParam
, POINT pt
)
1959 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1961 if ((wParam
& 0xfff0) == SC_HSCROLL
)
1963 if ((wParam
& 0x0f) != HTHSCROLL
) goto END
;
1964 scrollbar
= SB_HORZ
;
1966 else /* SC_VSCROLL */
1968 if ((wParam
& 0x0f) != HTVSCROLL
) goto END
;
1969 scrollbar
= SB_VERT
;
1972 pt
.x
-= wndPtr
->rectWindow
.left
;
1973 pt
.y
-= wndPtr
->rectWindow
.top
;
1975 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, WM_LBUTTONDOWN
, pt
);
1979 if (!GetMessageW( &msg
, 0, 0, 0 )) break;
1980 if (CallMsgFilterW( &msg
, MSGF_SCROLLBAR
)) continue;
1986 pt
.x
= LOWORD(msg
.lParam
) + wndPtr
->rectClient
.left
- wndPtr
->rectWindow
.left
;
1987 pt
.y
= HIWORD(msg
.lParam
) + wndPtr
->rectClient
.top
- wndPtr
->rectWindow
.top
;
1988 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, msg
.message
, pt
);
1991 TranslateMessage( &msg
);
1992 DispatchMessageW( &msg
);
1995 if (!IsWindow( hwnd
))
2000 } while (msg
.message
!= WM_LBUTTONUP
);
2002 WIN_ReleaseWndPtr(wndPtr
);
2005 /***********************************************************************
2006 * NC_HandleNCLButtonDown
2008 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2010 LONG
NC_HandleNCLButtonDown( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2012 LONG style
= GetWindowLongA( hwnd
, GWL_STYLE
);
2014 switch(wParam
) /* Hit test */
2018 HWND top
= GetAncestor( hwnd
, GA_ROOT
);
2020 if( WINPOS_SetActiveWindow(top
, TRUE
, TRUE
) || (GetActiveWindow() == top
) )
2021 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOVE
+ HTCAPTION
, lParam
);
2026 if( style
& WS_SYSMENU
)
2028 if( !(style
& WS_MINIMIZE
) )
2030 HDC hDC
= GetWindowDC(hwnd
);
2031 if (TWEAK_WineLook
== WIN31_LOOK
)
2032 NC_DrawSysButton( hwnd
, hDC
, TRUE
);
2034 NC_DrawSysButton95( hwnd
, hDC
, TRUE
);
2035 ReleaseDC( hwnd
, hDC
);
2037 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
+ HTSYSMENU
, lParam
);
2042 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
, lParam
);
2046 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
2050 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
2055 if (TWEAK_WineLook
== WIN31_LOOK
)
2056 NC_TrackMinMaxBox( hwnd
, wParam
);
2058 NC_TrackMinMaxBox95( hwnd
, wParam
);
2062 if (TWEAK_WineLook
>= WIN95_LOOK
)
2063 NC_TrackCloseButton95 (hwnd
, wParam
);
2074 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2075 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_SIZE
+ wParam
- 2, lParam
);
2085 /***********************************************************************
2086 * NC_HandleNCLButtonDblClk
2088 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2090 LONG
NC_HandleNCLButtonDblClk( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2093 * if this is an icon, send a restore since we are handling
2098 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_RESTORE
, lParam
);
2102 switch(wParam
) /* Hit test */
2105 /* stop processing if WS_MAXIMIZEBOX is missing */
2106 if (GetWindowLongA( hwnd
, GWL_STYLE
) & WS_MAXIMIZEBOX
)
2107 SendMessageW( hwnd
, WM_SYSCOMMAND
,
2108 IsZoomed(hwnd
) ? SC_RESTORE
: SC_MAXIMIZE
, lParam
);
2112 if (!(GetClassLongW(hwnd
, GCL_STYLE
) & CS_NOCLOSE
))
2113 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, lParam
);
2117 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
2121 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
2128 /***********************************************************************
2129 * NC_HandleSysCommand
2131 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2133 LONG
NC_HandleSysCommand( HWND hwnd
, WPARAM wParam
, POINT pt
)
2135 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
2136 UINT16 uCommand
= wParam
& 0xFFF0;
2138 TRACE("Handling WM_SYSCOMMAND %x %ld,%ld\n", wParam
, pt
.x
, pt
.y
);
2140 if (uCommand
!= SC_KEYMENU
)
2142 HWND parent
= GetAncestor( hwnd
, GA_PARENT
);
2143 if (parent
!= GetDesktopWindow()) ScreenToClient( parent
, &pt
);
2150 if (USER_Driver
.pSysCommandSizeMove
)
2151 USER_Driver
.pSysCommandSizeMove( hwnd
, wParam
);
2155 if (hwnd
== GetForegroundWindow())
2156 ShowOwnedPopups(hwnd
,FALSE
);
2157 ShowWindow( hwnd
, SW_MINIMIZE
);
2161 if (IsIconic(hwnd
) && hwnd
== GetForegroundWindow())
2162 ShowOwnedPopups(hwnd
,TRUE
);
2163 ShowWindow( hwnd
, SW_MAXIMIZE
);
2167 if (IsIconic(hwnd
) && hwnd
== GetForegroundWindow())
2168 ShowOwnedPopups(hwnd
,TRUE
);
2169 ShowWindow( hwnd
, SW_RESTORE
);
2173 WIN_ReleaseWndPtr(wndPtr
);
2174 return SendMessageA( hwnd
, WM_CLOSE
, 0, 0 );
2178 NC_TrackScrollBar( hwnd
, wParam
, pt
);
2182 MENU_TrackMouseMenuBar( hwnd
, wParam
& 0x000F, pt
);
2186 MENU_TrackKbdMenuBar( hwnd
, wParam
, pt
.x
);
2190 WinExec( "taskman.exe", SW_SHOWNORMAL
);
2194 if (wParam
== SC_ABOUTWINE
)
2196 HMODULE hmodule
= LoadLibraryA( "shell32.dll" );
2199 FARPROC aboutproc
= GetProcAddress( hmodule
, "ShellAboutA" );
2200 if (aboutproc
) aboutproc( hwnd
, "Wine", WINE_RELEASE_INFO
, 0 );
2201 FreeLibrary( hmodule
);
2205 if (wParam
== SC_PUTMARK
)
2206 TRACE_(shell
)("Mark requested by user\n");
2213 FIXME("unimplemented!\n");
2216 WIN_ReleaseWndPtr(wndPtr
);
2220 /*************************************************************
2223 * Stub for the grayed button of the caption
2225 *************************************************************/
2227 BOOL
NC_DrawGrayButton(HDC hdc
, int x
, int y
)
2230 HDC hdcMask
= CreateCompatibleDC (0);
2233 hMaskBmp
= CreateBitmap (12, 10, 1, 1, lpGrayMask
);
2238 SelectObject (hdcMask
, hMaskBmp
);
2240 /* Draw the grayed bitmap using the mask */
2241 hOldBrush
= SelectObject (hdc
, RGB(128, 128, 128));
2242 BitBlt (hdc
, x
, y
, 12, 10,
2243 hdcMask
, 0, 0, 0xB8074A);
2246 SelectObject (hdc
, hOldBrush
);
2247 DeleteObject(hMaskBmp
);