2 * Non-client area window functions
4 * Copyright 1994 Alexandre Julliard
10 #include "wine/winuser16.h"
16 #include "cursoricon.h"
19 #include "nonclient.h"
20 #include "debugtools.h"
24 DEFAULT_DEBUG_CHANNEL(nonclient
);
25 DECLARE_DEBUG_CHANNEL(shell
);
27 BOOL
NC_DrawGrayButton(HDC hdc
, int x
, int y
);
29 static HBITMAP hbitmapClose
;
31 static const BYTE lpGrayMask
[] = { 0xAA, 0xA0,
42 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
43 #define SC_PUTMARK (SC_SCREENSAVE+2)
45 /* Some useful macros */
46 #define HAS_DLGFRAME(style,exStyle) \
47 (((exStyle) & WS_EX_DLGMODALFRAME) || \
48 (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
50 #define HAS_THICKFRAME(style,exStyle) \
51 (((style) & WS_THICKFRAME) && \
52 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
54 #define HAS_THINFRAME(style) \
55 (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
57 #define HAS_BIGFRAME(style,exStyle) \
58 (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
59 ((exStyle) & WS_EX_DLGMODALFRAME))
61 #define HAS_STATICOUTERFRAME(style,exStyle) \
62 (((exStyle) & (WS_EX_STATICEDGE|WS_EX_DLGMODALFRAME)) == \
65 #define HAS_ANYFRAME(style,exStyle) \
66 (((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
67 ((exStyle) & WS_EX_DLGMODALFRAME) || \
68 !((style) & (WS_CHILD | WS_POPUP)))
70 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
73 /***********************************************************************
76 * Compute the size of the window rectangle from the size of the
79 static void NC_AdjustRect( LPRECT rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
81 if (TWEAK_WineLook
> WIN31_LOOK
)
82 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
84 if(style
& WS_ICONIC
) return;
86 if (HAS_THICKFRAME( style
, exStyle
))
87 InflateRect( rect
, GetSystemMetrics(SM_CXFRAME
), GetSystemMetrics(SM_CYFRAME
) );
88 else if (HAS_DLGFRAME( style
, exStyle
))
89 InflateRect( rect
, GetSystemMetrics(SM_CXDLGFRAME
), GetSystemMetrics(SM_CYDLGFRAME
) );
90 else if (HAS_THINFRAME( style
))
91 InflateRect( rect
, GetSystemMetrics(SM_CXBORDER
), GetSystemMetrics(SM_CYBORDER
));
93 if ((style
& WS_CAPTION
) == WS_CAPTION
)
94 rect
->top
-= GetSystemMetrics(SM_CYCAPTION
) - GetSystemMetrics(SM_CYBORDER
);
96 if (menu
) rect
->top
-= GetSystemMetrics(SM_CYMENU
) + GetSystemMetrics(SM_CYBORDER
);
98 if (style
& WS_VSCROLL
) {
99 rect
->right
+= GetSystemMetrics(SM_CXVSCROLL
) - 1;
100 if(!HAS_ANYFRAME( style
, exStyle
))
104 if (style
& WS_HSCROLL
) {
105 rect
->bottom
+= GetSystemMetrics(SM_CYHSCROLL
) - 1;
106 if(!HAS_ANYFRAME( style
, exStyle
))
112 /******************************************************************************
113 * NC_AdjustRectOuter95
115 * Computes the size of the "outside" parts of the window based on the
116 * parameters of the client area.
125 * "Outer" parts of a window means the whole window frame, caption and
126 * menu bar. It does not include "inner" parts of the frame like client
127 * edge, static edge or scroll bars.
130 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
131 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
133 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
134 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
135 * NC_AdjustRectInner95 and added handling of Win95 styles.
137 * 28-Jul-1999 Ove Kåven (ovek@arcticnet.no)
138 * Streamlined window style checks.
140 *****************************************************************************/
143 NC_AdjustRectOuter95 (LPRECT rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
146 if(style
& WS_ICONIC
) return;
148 if ((exStyle
& (WS_EX_STATICEDGE
|WS_EX_DLGMODALFRAME
)) ==
151 adjust
= 1; /* for the outer frame always present */
156 if ((exStyle
& WS_EX_DLGMODALFRAME
) ||
157 (style
& (WS_THICKFRAME
|WS_DLGFRAME
))) adjust
= 2; /* outer */
159 if (style
& WS_THICKFRAME
)
160 adjust
+= ( GetSystemMetrics (SM_CXFRAME
)
161 - GetSystemMetrics (SM_CXDLGFRAME
)); /* The resize border */
162 if ((style
& (WS_BORDER
|WS_DLGFRAME
)) ||
163 (exStyle
& WS_EX_DLGMODALFRAME
))
164 adjust
++; /* The other border */
166 InflateRect (rect
, adjust
, adjust
);
168 if ((style
& WS_CAPTION
) == WS_CAPTION
)
170 if (exStyle
& WS_EX_TOOLWINDOW
)
171 rect
->top
-= GetSystemMetrics(SM_CYSMCAPTION
);
173 rect
->top
-= GetSystemMetrics(SM_CYCAPTION
);
175 if (menu
) rect
->top
-= GetSystemMetrics(SM_CYMENU
);
179 /******************************************************************************
180 * NC_AdjustRectInner95
182 * Computes the size of the "inside" part of the window based on the
183 * parameters of the client area.
191 * "Inner" part of a window means the window frame inside of the flat
192 * window frame. It includes the client edge, the static edge and the
196 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
197 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
199 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
200 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
201 * NC_AdjustRectInner95 and added handling of Win95 styles.
203 *****************************************************************************/
206 NC_AdjustRectInner95 (LPRECT rect
, DWORD style
, DWORD exStyle
)
208 if(style
& WS_ICONIC
) return;
210 if (exStyle
& WS_EX_CLIENTEDGE
)
211 InflateRect(rect
, GetSystemMetrics(SM_CXEDGE
), GetSystemMetrics(SM_CYEDGE
));
213 if (style
& WS_VSCROLL
) rect
->right
+= GetSystemMetrics(SM_CXVSCROLL
);
214 if (style
& WS_HSCROLL
) rect
->bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
219 static HICON
NC_IconForWindow( HWND hwnd
)
221 HICON hIcon
= (HICON
) GetClassLongA( hwnd
, GCL_HICONSM
);
222 if (!hIcon
) hIcon
= (HICON
) GetClassLongA( hwnd
, GCL_HICON
);
224 /* If there is no hIcon specified and this is a modal dialog,
225 * get the default one.
227 if (!hIcon
&& (GetWindowLongA( hwnd
, GWL_STYLE
) & DS_MODALFRAME
))
228 hIcon
= LoadImageA(0, IDI_WINLOGOA
, IMAGE_ICON
, 0, 0, LR_DEFAULTCOLOR
);
232 /***********************************************************************
233 * DrawCaption (USER32.@) Draws a caption bar
247 DrawCaption (HWND hwnd
, HDC hdc
, const RECT
*lpRect
, UINT uFlags
)
249 return DrawCaptionTempA (hwnd
, hdc
, lpRect
, 0, 0, NULL
, uFlags
& 0x1F);
253 /***********************************************************************
254 * DrawCaptionTempA (USER32.@)
256 BOOL WINAPI
DrawCaptionTempA (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
257 HICON hIcon
, LPCSTR str
, UINT uFlags
)
263 if (!(uFlags
& DC_TEXT
) || !str
)
264 return DrawCaptionTempW( hwnd
, hdc
, rect
, hFont
, hIcon
, NULL
, uFlags
);
266 len
= MultiByteToWideChar( CP_ACP
, 0, str
, -1, NULL
, 0 );
267 if ((strW
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) )))
269 MultiByteToWideChar( CP_ACP
, 0, str
, -1, strW
, len
);
270 ret
= DrawCaptionTempW (hwnd
, hdc
, rect
, hFont
, hIcon
, strW
, uFlags
);
271 HeapFree( GetProcessHeap (), 0, strW
);
277 /***********************************************************************
278 * DrawCaptionTempW (USER32.@)
280 BOOL WINAPI
DrawCaptionTempW (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
281 HICON hIcon
, LPCWSTR str
, UINT uFlags
)
285 TRACE("(%08x,%08x,%p,%08x,%08x,%s,%08x)\n",
286 hwnd
, hdc
, rect
, hFont
, hIcon
, debugstr_w(str
), uFlags
);
288 /* drawing background */
289 if (uFlags
& DC_INBUTTON
) {
290 FillRect (hdc
, &rc
, GetSysColorBrush (COLOR_3DFACE
));
292 if (uFlags
& DC_ACTIVE
) {
293 HBRUSH hbr
= SelectObject (hdc
, CACHE_GetPattern55AABrush ());
294 PatBlt (hdc
, rc
.left
, rc
.top
,
295 rc
.right
-rc
.left
, rc
.bottom
-rc
.top
, 0xFA0089);
296 SelectObject (hdc
, hbr
);
300 FillRect (hdc
, &rc
, GetSysColorBrush ((uFlags
& DC_ACTIVE
) ?
301 COLOR_ACTIVECAPTION
: COLOR_INACTIVECAPTION
));
306 if ((uFlags
& DC_ICON
) && !(uFlags
& DC_SMALLCAP
)) {
310 pt
.y
= (rc
.bottom
+ rc
.top
- GetSystemMetrics(SM_CYSMICON
)) / 2;
312 if (!hIcon
) hIcon
= NC_IconForWindow(hwnd
);
313 DrawIconEx (hdc
, pt
.x
, pt
.y
, hIcon
, GetSystemMetrics(SM_CXSMICON
),
314 GetSystemMetrics(SM_CYSMICON
), 0, 0, DI_NORMAL
);
315 rc
.left
+= (rc
.bottom
- rc
.top
);
319 if (uFlags
& DC_TEXT
) {
322 if (uFlags
& DC_INBUTTON
)
323 SetTextColor (hdc
, GetSysColor (COLOR_BTNTEXT
));
324 else if (uFlags
& DC_ACTIVE
)
325 SetTextColor (hdc
, GetSysColor (COLOR_CAPTIONTEXT
));
327 SetTextColor (hdc
, GetSysColor (COLOR_INACTIVECAPTIONTEXT
));
329 SetBkMode (hdc
, TRANSPARENT
);
332 hOldFont
= SelectObject (hdc
, hFont
);
334 NONCLIENTMETRICSA nclm
;
336 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
337 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
338 hNewFont
= CreateFontIndirectA ((uFlags
& DC_SMALLCAP
) ?
339 &nclm
.lfSmCaptionFont
: &nclm
.lfCaptionFont
);
340 hOldFont
= SelectObject (hdc
, hNewFont
);
344 DrawTextW (hdc
, str
, -1, &rc
,
345 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
349 nLen
= GetWindowTextW (hwnd
, szText
, 128);
350 DrawTextW (hdc
, szText
, nLen
, &rc
,
351 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
355 SelectObject (hdc
, hOldFont
);
357 DeleteObject (SelectObject (hdc
, hOldFont
));
360 /* drawing focus ??? */
362 FIXME("undocumented flag (0x2000)!\n");
368 /***********************************************************************
369 * AdjustWindowRect (USER.102)
371 BOOL16 WINAPI
AdjustWindowRect16( LPRECT16 rect
, DWORD style
, BOOL16 menu
)
373 return AdjustWindowRectEx16( rect
, style
, menu
, 0 );
377 /***********************************************************************
378 * AdjustWindowRect (USER32.@)
380 BOOL WINAPI
AdjustWindowRect( LPRECT rect
, DWORD style
, BOOL menu
)
382 return AdjustWindowRectEx( rect
, style
, menu
, 0 );
386 /***********************************************************************
387 * AdjustWindowRectEx (USER.454)
389 BOOL16 WINAPI
AdjustWindowRectEx16( LPRECT16 rect
, DWORD style
,
390 BOOL16 menu
, DWORD exStyle
)
395 CONV_RECT16TO32( rect
, &rect32
);
396 ret
= AdjustWindowRectEx( &rect32
, style
, menu
, exStyle
);
397 CONV_RECT32TO16( &rect32
, rect
);
402 /***********************************************************************
403 * AdjustWindowRectEx (USER32.@)
405 BOOL WINAPI
AdjustWindowRectEx( LPRECT rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
407 /* Correct the window style */
409 if (!(style
& (WS_POPUP
| WS_CHILD
))) style
|= WS_CAPTION
; /* Overlapped window */
410 style
&= (WS_DLGFRAME
| WS_BORDER
| WS_THICKFRAME
| WS_CHILD
);
411 exStyle
&= (WS_EX_DLGMODALFRAME
| WS_EX_CLIENTEDGE
|
412 WS_EX_STATICEDGE
| WS_EX_TOOLWINDOW
);
413 if (exStyle
& WS_EX_DLGMODALFRAME
) style
&= ~WS_THICKFRAME
;
415 TRACE("(%d,%d)-(%d,%d) %08lx %d %08lx\n",
416 rect
->left
, rect
->top
, rect
->right
, rect
->bottom
,
417 style
, menu
, exStyle
);
419 if (TWEAK_WineLook
== WIN31_LOOK
)
420 NC_AdjustRect( rect
, style
, menu
, exStyle
);
423 NC_AdjustRectOuter95( rect
, style
, menu
, exStyle
);
424 NC_AdjustRectInner95( rect
, style
, exStyle
);
430 /***********************************************************************
431 * NC_HandleNCCalcSize
433 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
435 LONG
NC_HandleNCCalcSize( HWND hwnd
, RECT
*winRect
)
437 RECT tmpRect
= { 0, 0, 0, 0 };
439 LONG cls_style
= GetClassLongA(hwnd
, GCL_STYLE
);
440 LONG style
= GetWindowLongA( hwnd
, GWL_STYLE
);
441 LONG exStyle
= GetWindowLongA( hwnd
, GWL_EXSTYLE
);
443 if (cls_style
& CS_VREDRAW
) result
|= WVR_VREDRAW
;
444 if (cls_style
& CS_HREDRAW
) result
|= WVR_HREDRAW
;
448 if (TWEAK_WineLook
== WIN31_LOOK
)
449 NC_AdjustRect( &tmpRect
, style
, FALSE
, exStyle
);
451 NC_AdjustRectOuter95( &tmpRect
, style
, FALSE
, exStyle
);
453 winRect
->left
-= tmpRect
.left
;
454 winRect
->top
-= tmpRect
.top
;
455 winRect
->right
-= tmpRect
.right
;
456 winRect
->bottom
-= tmpRect
.bottom
;
458 if (!(style
& WS_CHILD
) && GetMenu(hwnd
))
460 TRACE("Calling GetMenuBarHeight with HWND 0x%x, width %d, "
461 "at (%d, %d).\n", hwnd
,
462 winRect
->right
- winRect
->left
,
463 -tmpRect
.left
, -tmpRect
.top
);
466 MENU_GetMenuBarHeight( hwnd
,
467 winRect
->right
- winRect
->left
,
468 -tmpRect
.left
, -tmpRect
.top
) + 1;
471 if (TWEAK_WineLook
> WIN31_LOOK
) {
472 SetRect(&tmpRect
, 0, 0, 0, 0);
473 NC_AdjustRectInner95 (&tmpRect
, style
, exStyle
);
474 winRect
->left
-= tmpRect
.left
;
475 winRect
->top
-= tmpRect
.top
;
476 winRect
->right
-= tmpRect
.right
;
477 winRect
->bottom
-= tmpRect
.bottom
;
480 if (winRect
->top
> winRect
->bottom
)
481 winRect
->bottom
= winRect
->top
;
483 if (winRect
->left
> winRect
->right
)
484 winRect
->right
= winRect
->left
;
490 /***********************************************************************
493 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
494 * but without the borders (if any).
495 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
497 void NC_GetInsideRect( HWND hwnd
, RECT
*rect
)
499 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
501 rect
->top
= rect
->left
= 0;
502 rect
->right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
503 rect
->bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
505 if (wndPtr
->dwStyle
& WS_ICONIC
) goto END
;
507 /* Remove frame from rectangle */
508 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
510 InflateRect( rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
512 else if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
514 InflateRect( rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
515 /* FIXME: this isn't in NC_AdjustRect? why not? */
516 if ((TWEAK_WineLook
== WIN31_LOOK
) && (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
))
517 InflateRect( rect
, -1, 0 );
519 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
521 InflateRect( rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
) );
524 /* We have additional border information if the window
525 * is a child (but not an MDI child) */
526 if (TWEAK_WineLook
!= WIN31_LOOK
)
528 if ( (wndPtr
->dwStyle
& WS_CHILD
) &&
529 ( (wndPtr
->dwExStyle
& WS_EX_MDICHILD
) == 0 ) )
531 if (wndPtr
->dwExStyle
& WS_EX_CLIENTEDGE
)
532 InflateRect (rect
, -GetSystemMetrics(SM_CXEDGE
), -GetSystemMetrics(SM_CYEDGE
));
533 if (wndPtr
->dwExStyle
& WS_EX_STATICEDGE
)
534 InflateRect (rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
539 WIN_ReleaseWndPtr(wndPtr
);
544 /***********************************************************************
547 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
550 static LONG
NC_DoNCHitTest (WND
*wndPtr
, POINT pt
)
554 TRACE("hwnd=%04x pt=%ld,%ld\n", wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
556 GetWindowRect(wndPtr
->hwndSelf
, &rect
);
557 if (!PtInRect( &rect
, pt
)) return HTNOWHERE
;
559 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
562 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
564 InflateRect( &rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
565 if (!PtInRect( &rect
, pt
))
567 /* Check top sizing border */
570 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
571 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
574 /* Check bottom sizing border */
575 if (pt
.y
>= rect
.bottom
)
577 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
578 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
581 /* Check left sizing border */
582 if (pt
.x
< rect
.left
)
584 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
585 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
588 /* Check right sizing border */
589 if (pt
.x
>= rect
.right
)
591 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
592 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
597 else /* No thick frame */
599 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
600 InflateRect(&rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
601 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
602 InflateRect(&rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
603 if (!PtInRect( &rect
, pt
)) return HTBORDER
;
608 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
610 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
) - GetSystemMetrics(SM_CYBORDER
);
611 if (!PtInRect( &rect
, pt
))
613 /* Check system menu */
614 if ((wndPtr
->dwStyle
& WS_SYSMENU
) && !(wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
))
615 rect
.left
+= GetSystemMetrics(SM_CXSIZE
);
616 if (pt
.x
<= rect
.left
) return HTSYSMENU
;
618 /* Check maximize box */
619 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
620 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
622 if (pt
.x
>= rect
.right
) return HTMAXBUTTON
;
623 /* Check minimize box */
624 if (wndPtr
->dwStyle
& WS_MINIMIZEBOX
)
625 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
626 if (pt
.x
>= rect
.right
) return HTMINBUTTON
;
631 /* Check client area */
633 ScreenToClient( wndPtr
->hwndSelf
, &pt
);
634 GetClientRect( wndPtr
->hwndSelf
, &rect
);
635 if (PtInRect( &rect
, pt
)) return HTCLIENT
;
637 /* Check vertical scroll bar */
639 if (wndPtr
->dwStyle
& WS_VSCROLL
)
641 rect
.right
+= GetSystemMetrics(SM_CXVSCROLL
);
642 if (PtInRect( &rect
, pt
)) return HTVSCROLL
;
645 /* Check horizontal scroll bar */
647 if (wndPtr
->dwStyle
& WS_HSCROLL
)
649 rect
.bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
650 if (PtInRect( &rect
, pt
))
653 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
654 (pt
.x
>= rect
.right
- GetSystemMetrics(SM_CXVSCROLL
)))
662 if (HAS_MENU(wndPtr
))
664 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
668 /* Has to return HTNOWHERE if nothing was found
669 Could happen when a window has a customized non client area */
674 /***********************************************************************
677 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
679 * FIXME: Just a modified copy of the Win 3.1 version.
682 static LONG
NC_DoNCHitTest95 (WND
*wndPtr
, POINT pt
)
686 TRACE("hwnd=%04x pt=%ld,%ld\n", wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
688 GetWindowRect(wndPtr
->hwndSelf
, &rect
);
689 if (!PtInRect( &rect
, pt
)) return HTNOWHERE
;
691 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
694 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
696 InflateRect( &rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
697 if (!PtInRect( &rect
, pt
))
699 /* Check top sizing border */
702 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
703 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
706 /* Check bottom sizing border */
707 if (pt
.y
>= rect
.bottom
)
709 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
710 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
713 /* Check left sizing border */
714 if (pt
.x
< rect
.left
)
716 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
717 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
720 /* Check right sizing border */
721 if (pt
.x
>= rect
.right
)
723 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
724 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
729 else /* No thick frame */
731 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
732 InflateRect(&rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
733 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
734 InflateRect(&rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
735 if (!PtInRect( &rect
, pt
)) return HTBORDER
;
740 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
742 if (wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
)
743 rect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
) - 1;
745 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
746 if (!PtInRect( &rect
, pt
))
748 /* Check system menu */
749 if ((wndPtr
->dwStyle
& WS_SYSMENU
) && !(wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
))
751 if (NC_IconForWindow(wndPtr
->hwndSelf
))
752 rect
.left
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
754 if (pt
.x
< rect
.left
) return HTSYSMENU
;
756 /* Check close button */
757 if (wndPtr
->dwStyle
& WS_SYSMENU
)
758 rect
.right
-= GetSystemMetrics(SM_CYCAPTION
) - 1;
759 if (pt
.x
> rect
.right
) return HTCLOSE
;
761 /* Check maximize box */
762 /* In win95 there is automatically a Maximize button when there is a minimize one*/
763 if ((wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)|| (wndPtr
->dwStyle
& WS_MINIMIZEBOX
))
764 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
765 if (pt
.x
> rect
.right
) return HTMAXBUTTON
;
767 /* Check minimize box */
768 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
769 if ((wndPtr
->dwStyle
& WS_MINIMIZEBOX
)||(wndPtr
->dwStyle
& WS_MAXIMIZEBOX
))
770 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
772 if (pt
.x
> rect
.right
) return HTMINBUTTON
;
777 /* Check client area */
779 ScreenToClient( wndPtr
->hwndSelf
, &pt
);
780 GetClientRect( wndPtr
->hwndSelf
, &rect
);
781 if (PtInRect( &rect
, pt
)) return HTCLIENT
;
783 /* Check vertical scroll bar */
785 if (wndPtr
->dwStyle
& WS_VSCROLL
)
787 rect
.right
+= GetSystemMetrics(SM_CXVSCROLL
);
788 if (PtInRect( &rect
, pt
)) return HTVSCROLL
;
791 /* Check horizontal scroll bar */
793 if (wndPtr
->dwStyle
& WS_HSCROLL
)
795 rect
.bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
796 if (PtInRect( &rect
, pt
))
799 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
800 (pt
.x
>= rect
.right
- GetSystemMetrics(SM_CXVSCROLL
)))
808 if (HAS_MENU(wndPtr
))
810 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
814 /* Has to return HTNOWHERE if nothing was found
815 Could happen when a window has a customized non client area */
820 /***********************************************************************
823 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
825 LONG
NC_HandleNCHitTest (HWND hwnd
, POINT pt
)
828 WND
*wndPtr
= WIN_FindWndPtr (hwnd
);
833 if (TWEAK_WineLook
== WIN31_LOOK
)
834 retvalue
= NC_DoNCHitTest (wndPtr
, pt
);
836 retvalue
= NC_DoNCHitTest95 (wndPtr
, pt
);
837 WIN_ReleaseWndPtr(wndPtr
);
842 /***********************************************************************
845 void NC_DrawSysButton( HWND hwnd
, HDC hdc
, BOOL down
)
851 NC_GetInsideRect( hwnd
, &rect
);
852 hdcMem
= CreateCompatibleDC( hdc
);
853 hbitmap
= SelectObject( hdcMem
, hbitmapClose
);
854 BitBlt(hdc
, rect
.left
, rect
.top
, GetSystemMetrics(SM_CXSIZE
), GetSystemMetrics(SM_CYSIZE
),
855 hdcMem
, (GetWindowLongA(hwnd
,GWL_STYLE
) & WS_CHILD
) ? GetSystemMetrics(SM_CXSIZE
) : 0, 0,
856 down
? NOTSRCCOPY
: SRCCOPY
);
857 SelectObject( hdcMem
, hbitmap
);
862 /***********************************************************************
865 static void NC_DrawMaxButton( HWND hwnd
, HDC16 hdc
, BOOL down
)
868 UINT flags
= IsZoomed(hwnd
) ? DFCS_CAPTIONRESTORE
: DFCS_CAPTIONMAX
;
870 NC_GetInsideRect( hwnd
, &rect
);
871 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
) + 1;
872 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
875 if (down
) flags
|= DFCS_PUSHED
;
876 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
880 /***********************************************************************
883 static void NC_DrawMinButton( HWND hwnd
, HDC16 hdc
, BOOL down
)
886 UINT flags
= DFCS_CAPTIONMIN
;
887 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
889 NC_GetInsideRect( hwnd
, &rect
);
890 if (style
& (WS_MAXIMIZEBOX
|WS_MINIMIZEBOX
))
891 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) - 2;
892 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
) + 1;
893 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
896 if (down
) flags
|= DFCS_PUSHED
;
897 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
901 /******************************************************************************
903 * void NC_DrawSysButton95(
908 * Draws the Win95 system icon.
911 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
912 * Original implementation from NC_DrawSysButton source.
913 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
916 *****************************************************************************/
919 NC_DrawSysButton95 (HWND hwnd
, HDC hdc
, BOOL down
)
921 HICON hIcon
= NC_IconForWindow( hwnd
);
926 NC_GetInsideRect( hwnd
, &rect
);
927 DrawIconEx (hdc
, rect
.left
+ 2, rect
.top
+ 2, hIcon
,
928 GetSystemMetrics(SM_CXSMICON
),
929 GetSystemMetrics(SM_CYSMICON
), 0, 0, DI_NORMAL
);
935 /******************************************************************************
937 * void NC_DrawCloseButton95(
943 * Draws the Win95 close button.
945 * If bGrayed is true, then draw a disabled Close button
948 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
949 * Original implementation from NC_DrawSysButton95 source.
951 *****************************************************************************/
953 static void NC_DrawCloseButton95 (HWND hwnd
, HDC hdc
, BOOL down
, BOOL bGrayed
)
957 NC_GetInsideRect( hwnd
, &rect
);
959 /* A tool window has a smaller Close button */
960 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_TOOLWINDOW
)
962 INT iBmpHeight
= 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
963 INT iBmpWidth
= 11; /* it uses 11x11 for the close button in tool window */
964 INT iCaptionHeight
= GetSystemMetrics(SM_CYSMCAPTION
);
966 rect
.top
= rect
.top
+ (iCaptionHeight
- 1 - iBmpHeight
) / 2;
967 rect
.left
= rect
.right
- (iCaptionHeight
+ 1 + iBmpWidth
) / 2;
968 rect
.bottom
= rect
.top
+ iBmpHeight
;
969 rect
.right
= rect
.left
+ iBmpWidth
;
973 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
) - 1;
974 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
978 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
,
980 (down
? DFCS_PUSHED
: 0) |
981 (bGrayed
? DFCS_INACTIVE
: 0)) );
984 /******************************************************************************
987 * Draws the maximize button for Win95 style windows.
988 * If bGrayed is true, then draw a disabled Maximize button
990 static void NC_DrawMaxButton95(HWND hwnd
,HDC16 hdc
,BOOL down
, BOOL bGrayed
)
993 UINT flags
= IsZoomed(hwnd
) ? DFCS_CAPTIONRESTORE
: DFCS_CAPTIONMAX
;
995 NC_GetInsideRect( hwnd
, &rect
);
996 if (GetWindowLongA( hwnd
, GWL_STYLE
) & WS_SYSMENU
)
997 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
998 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
);
999 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1002 if (down
) flags
|= DFCS_PUSHED
;
1003 if (bGrayed
) flags
|= DFCS_INACTIVE
;
1004 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
1007 /******************************************************************************
1008 * NC_DrawMinButton95
1010 * Draws the minimize button for Win95 style windows.
1011 * If bGrayed is true, then draw a disabled Minimize button
1013 static void NC_DrawMinButton95(HWND hwnd
,HDC16 hdc
,BOOL down
, BOOL bGrayed
)
1016 UINT flags
= DFCS_CAPTIONMIN
;
1017 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
1019 NC_GetInsideRect( hwnd
, &rect
);
1020 if (style
& WS_SYSMENU
)
1021 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1022 if (style
& (WS_MAXIMIZEBOX
|WS_MINIMIZEBOX
))
1023 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) - 2;
1024 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
);
1025 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1028 if (down
) flags
|= DFCS_PUSHED
;
1029 if (bGrayed
) flags
|= DFCS_INACTIVE
;
1030 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
1033 /***********************************************************************
1036 * Draw a window frame inside the given rectangle, and update the rectangle.
1037 * The correct pen for the frame must be selected in the DC.
1039 static void NC_DrawFrame( HDC hdc
, RECT
*rect
, BOOL dlgFrame
,
1044 if (TWEAK_WineLook
!= WIN31_LOOK
)
1045 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
1049 width
= GetSystemMetrics(SM_CXDLGFRAME
) - 1;
1050 height
= GetSystemMetrics(SM_CYDLGFRAME
) - 1;
1051 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1052 COLOR_INACTIVECAPTION
) );
1056 width
= GetSystemMetrics(SM_CXFRAME
) - 2;
1057 height
= GetSystemMetrics(SM_CYFRAME
) - 2;
1058 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1059 COLOR_INACTIVEBORDER
) );
1063 PatBlt( hdc
, rect
->left
, rect
->top
,
1064 rect
->right
- rect
->left
, height
, PATCOPY
);
1065 PatBlt( hdc
, rect
->left
, rect
->top
,
1066 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1067 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1068 rect
->right
- rect
->left
, -height
, PATCOPY
);
1069 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1070 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1074 InflateRect( rect
, -width
, -height
);
1078 INT decYOff
= GetSystemMetrics(SM_CXFRAME
) + GetSystemMetrics(SM_CXSIZE
) - 1;
1079 INT decXOff
= GetSystemMetrics(SM_CYFRAME
) + GetSystemMetrics(SM_CYSIZE
) - 1;
1081 /* Draw inner rectangle */
1083 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1084 Rectangle( hdc
, rect
->left
+ width
, rect
->top
+ height
,
1085 rect
->right
- width
, rect
->bottom
- height
);
1087 /* Draw the decorations */
1089 MoveToEx( hdc
, rect
->left
, rect
->top
+ decYOff
, NULL
);
1090 LineTo( hdc
, rect
->left
+ width
, rect
->top
+ decYOff
);
1091 MoveToEx( hdc
, rect
->right
- 1, rect
->top
+ decYOff
, NULL
);
1092 LineTo( hdc
, rect
->right
- width
- 1, rect
->top
+ decYOff
);
1093 MoveToEx( hdc
, rect
->left
, rect
->bottom
- decYOff
, NULL
);
1094 LineTo( hdc
, rect
->left
+ width
, rect
->bottom
- decYOff
);
1095 MoveToEx( hdc
, rect
->right
- 1, rect
->bottom
- decYOff
, NULL
);
1096 LineTo( hdc
, rect
->right
- width
- 1, rect
->bottom
- decYOff
);
1098 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->top
, NULL
);
1099 LineTo( hdc
, rect
->left
+ decXOff
, rect
->top
+ height
);
1100 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->bottom
- 1, NULL
);
1101 LineTo( hdc
, rect
->left
+ decXOff
, rect
->bottom
- height
- 1 );
1102 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->top
, NULL
);
1103 LineTo( hdc
, rect
->right
- decXOff
, rect
->top
+ height
);
1104 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->bottom
- 1, NULL
);
1105 LineTo( hdc
, rect
->right
- decXOff
, rect
->bottom
- height
- 1 );
1107 InflateRect( rect
, -width
- 1, -height
- 1 );
1112 /******************************************************************************
1114 * void NC_DrawFrame95(
1121 * Draw a window frame inside the given rectangle, and update the rectangle.
1124 * Many. First, just what IS a frame in Win95? Note that the 3D look
1125 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1126 * edge. The inner rectangle just inside the frame is handled by the
1129 * In short, for most people, this function should be a nop (unless
1130 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1131 * them lately, but just to get this code right). Even so, it doesn't
1132 * appear to be so. It's being worked on...
1135 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1136 * Original implementation (based on NC_DrawFrame)
1137 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1139 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1140 * Fixed a fix or something.
1142 *****************************************************************************/
1144 static void NC_DrawFrame95(
1153 /* Firstly the "thick" frame */
1154 if (style
& WS_THICKFRAME
)
1156 width
= GetSystemMetrics(SM_CXFRAME
) - GetSystemMetrics(SM_CXDLGFRAME
);
1157 height
= GetSystemMetrics(SM_CYFRAME
) - GetSystemMetrics(SM_CYDLGFRAME
);
1159 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1160 COLOR_INACTIVEBORDER
) );
1162 PatBlt( hdc
, rect
->left
, rect
->top
,
1163 rect
->right
- rect
->left
, height
, PATCOPY
);
1164 PatBlt( hdc
, rect
->left
, rect
->top
,
1165 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1166 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1167 rect
->right
- rect
->left
, -height
, PATCOPY
);
1168 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1169 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1171 InflateRect( rect
, -width
, -height
);
1174 /* Now the other bit of the frame */
1175 if ((style
& (WS_BORDER
|WS_DLGFRAME
)) ||
1176 (exStyle
& WS_EX_DLGMODALFRAME
))
1178 width
= GetSystemMetrics(SM_CXDLGFRAME
) - GetSystemMetrics(SM_CXEDGE
);
1179 height
= GetSystemMetrics(SM_CYDLGFRAME
) - GetSystemMetrics(SM_CYEDGE
);
1180 /* This should give a value of 1 that should also work for a border */
1182 SelectObject( hdc
, GetSysColorBrush(
1183 (exStyle
& (WS_EX_DLGMODALFRAME
|WS_EX_CLIENTEDGE
)) ?
1185 (exStyle
& WS_EX_STATICEDGE
) ?
1187 (style
& (WS_DLGFRAME
|WS_THICKFRAME
)) ?
1190 COLOR_WINDOWFRAME
));
1193 PatBlt( hdc
, rect
->left
, rect
->top
,
1194 rect
->right
- rect
->left
, height
, PATCOPY
);
1195 PatBlt( hdc
, rect
->left
, rect
->top
,
1196 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1197 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1198 rect
->right
- rect
->left
, -height
, PATCOPY
);
1199 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1200 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1202 InflateRect( rect
, -width
, -height
);
1207 /***********************************************************************
1210 * Draw the window caption.
1211 * The correct pen for the window frame must be selected in the DC.
1213 static void NC_DrawCaption( HDC hdc
, RECT
*rect
, HWND hwnd
,
1214 DWORD style
, BOOL active
)
1221 if (!(hbitmapClose
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_OLD_CLOSE
) ))) return;
1224 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_DLGMODALFRAME
)
1226 HBRUSH hbrushOld
= SelectObject(hdc
, GetSysColorBrush(COLOR_WINDOW
) );
1227 PatBlt( hdc
, r
.left
, r
.top
, 1, r
.bottom
-r
.top
+1,PATCOPY
);
1228 PatBlt( hdc
, r
.right
-1, r
.top
, 1, r
.bottom
-r
.top
+1, PATCOPY
);
1229 PatBlt( hdc
, r
.left
, r
.top
-1, r
.right
-r
.left
, 1, PATCOPY
);
1232 SelectObject( hdc
, hbrushOld
);
1234 MoveToEx( hdc
, r
.left
, r
.bottom
, NULL
);
1235 LineTo( hdc
, r
.right
, r
.bottom
);
1237 if (style
& WS_SYSMENU
)
1239 NC_DrawSysButton( hwnd
, hdc
, FALSE
);
1240 r
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
1241 MoveToEx( hdc
, r
.left
- 1, r
.top
, NULL
);
1242 LineTo( hdc
, r
.left
- 1, r
.bottom
);
1244 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
: COLOR_INACTIVECAPTION
) );
1245 if (style
& WS_MAXIMIZEBOX
)
1247 NC_DrawMaxButton( hwnd
, hdc
, FALSE
);
1248 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1250 if (style
& WS_MINIMIZEBOX
)
1252 NC_DrawMinButton( hwnd
, hdc
, FALSE
);
1253 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1256 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) ))
1258 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1259 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1260 SetBkMode( hdc
, TRANSPARENT
);
1261 DrawTextA( hdc
, buffer
, -1, &r
,
1262 DT_SINGLELINE
| DT_CENTER
| DT_VCENTER
| DT_NOPREFIX
);
1267 /******************************************************************************
1276 * Draw the window caption for Win95 style windows.
1277 * The correct pen for the window frame must be selected in the DC.
1280 * Hey, a function that finally works! Well, almost.
1281 * It's being worked on.
1284 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1285 * Original implementation.
1286 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1289 *****************************************************************************/
1291 static void NC_DrawCaption95(
1304 hPrevPen
= SelectObject( hdc
, GetSysColorPen(
1305 ((exStyle
& (WS_EX_STATICEDGE
|WS_EX_CLIENTEDGE
|
1306 WS_EX_DLGMODALFRAME
)) == WS_EX_STATICEDGE
) ?
1307 COLOR_WINDOWFRAME
: COLOR_3DFACE
) );
1308 MoveToEx( hdc
, r
.left
, r
.bottom
- 1, NULL
);
1309 LineTo( hdc
, r
.right
, r
.bottom
- 1 );
1310 SelectObject( hdc
, hPrevPen
);
1313 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1314 COLOR_INACTIVECAPTION
) );
1316 if ((style
& WS_SYSMENU
) && !(exStyle
& WS_EX_TOOLWINDOW
)) {
1317 if (NC_DrawSysButton95 (hwnd
, hdc
, FALSE
))
1318 r
.left
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
1321 if (style
& WS_SYSMENU
)
1325 /* Go get the sysmenu */
1326 hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1327 state
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
);
1329 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1330 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
,
1331 ((((state
& MF_DISABLED
) || (state
& MF_GRAYED
))) && (state
!= 0xFFFFFFFF)));
1332 r
.right
-= GetSystemMetrics(SM_CYCAPTION
) - 1;
1334 if ((style
& WS_MAXIMIZEBOX
) || (style
& WS_MINIMIZEBOX
))
1336 /* In win95 the two buttons are always there */
1337 /* But if the menu item is not in the menu they're disabled*/
1339 NC_DrawMaxButton95( hwnd
, hdc
, FALSE
, (!(style
& WS_MAXIMIZEBOX
)));
1340 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1342 NC_DrawMinButton95( hwnd
, hdc
, FALSE
, (!(style
& WS_MINIMIZEBOX
)));
1343 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1347 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) )) {
1348 NONCLIENTMETRICSA nclm
;
1349 HFONT hFont
, hOldFont
;
1350 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
1351 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
1352 if (exStyle
& WS_EX_TOOLWINDOW
)
1353 hFont
= CreateFontIndirectA (&nclm
.lfSmCaptionFont
);
1355 hFont
= CreateFontIndirectA (&nclm
.lfCaptionFont
);
1356 hOldFont
= SelectObject (hdc
, hFont
);
1357 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1358 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1359 SetBkMode( hdc
, TRANSPARENT
);
1361 DrawTextA( hdc
, buffer
, -1, &r
,
1362 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
1363 DeleteObject (SelectObject (hdc
, hOldFont
));
1369 /***********************************************************************
1372 * Paint the non-client area. clip is currently unused.
1374 static void NC_DoNCPaint( HWND hwnd
, HRGN clip
, BOOL suppress_menupaint
)
1380 DWORD dwStyle
, dwExStyle
;
1382 RECT rectClient
, rectWindow
;
1385 if (!(wndPtr
= WIN_GetPtr( hwnd
)) || wndPtr
== WND_OTHER_PROCESS
) return;
1386 has_menu
= HAS_MENU(wndPtr
);
1387 dwStyle
= wndPtr
->dwStyle
;
1388 dwExStyle
= wndPtr
->dwExStyle
;
1389 flags
= wndPtr
->flags
;
1390 rectClient
= wndPtr
->rectClient
;
1391 rectWindow
= wndPtr
->rectWindow
;
1392 WIN_ReleasePtr( wndPtr
);
1394 if ( dwStyle
& WS_MINIMIZE
||
1395 !WIN_IsWindowDrawable( hwnd
, 0 )) return; /* Nothing to do */
1397 active
= flags
& WIN_NCACTIVATED
;
1399 TRACE("%04x %d\n", hwnd
, active
);
1401 if (!(hdc
= GetDCEx( hwnd
, (clip
> 1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
1402 ((clip
> 1) ? (DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
): 0) ))) return;
1404 if (ExcludeVisRect16( hdc
, rectClient
.left
-rectWindow
.left
,
1405 rectClient
.top
-rectWindow
.top
,
1406 rectClient
.right
-rectWindow
.left
,
1407 rectClient
.bottom
-rectWindow
.top
)
1410 ReleaseDC( hwnd
, hdc
);
1414 rect
.top
= rect
.left
= 0;
1415 rect
.right
= rectWindow
.right
- rectWindow
.left
;
1416 rect
.bottom
= rectWindow
.bottom
- rectWindow
.top
;
1418 SelectObject( hdc
, GetSysColorPen(COLOR_WINDOWFRAME
) );
1420 if (HAS_ANYFRAME( dwStyle
, dwExStyle
))
1422 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1423 Rectangle( hdc
, 0, 0, rect
.right
, rect
.bottom
);
1424 InflateRect( &rect
, -1, -1 );
1427 if (HAS_THICKFRAME( dwStyle
, dwExStyle
))
1428 NC_DrawFrame(hdc
, &rect
, FALSE
, active
);
1429 else if (HAS_DLGFRAME( dwStyle
, dwExStyle
))
1430 NC_DrawFrame( hdc
, &rect
, TRUE
, active
);
1432 if ((dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1435 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
);
1436 rect
.top
+= GetSystemMetrics(SM_CYSIZE
) + GetSystemMetrics(SM_CYBORDER
);
1437 NC_DrawCaption( hdc
, &r
, hwnd
, dwStyle
, active
);
1443 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYMENU
); /* default height */
1444 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
);
1447 /* Draw the scroll-bars */
1449 if (dwStyle
& WS_VSCROLL
)
1450 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1451 if (dwStyle
& WS_HSCROLL
)
1452 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1454 /* Draw the "size-box" */
1456 if ((dwStyle
& WS_VSCROLL
) && (dwStyle
& WS_HSCROLL
))
1459 r
.left
= r
.right
- GetSystemMetrics(SM_CXVSCROLL
) + 1;
1460 r
.top
= r
.bottom
- GetSystemMetrics(SM_CYHSCROLL
) + 1;
1461 if(wndPtr
->dwStyle
& WS_BORDER
) {
1465 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1468 ReleaseDC( hwnd
, hdc
);
1472 /******************************************************************************
1474 * void NC_DoNCPaint95(
1477 * BOOL suppress_menupaint )
1479 * Paint the non-client area for Win95 windows. The clip region is
1480 * currently ignored.
1483 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1484 * misc/tweak.c controls/menu.c # :-)
1487 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1488 * Original implementation
1489 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1491 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1492 * Streamlined window style checks.
1494 *****************************************************************************/
1496 static void NC_DoNCPaint95(
1499 BOOL suppress_menupaint
)
1502 RECT rfuzz
, rect
, rectClip
;
1505 DWORD dwStyle
, dwExStyle
;
1507 RECT rectClient
, rectWindow
;
1510 if (!(wndPtr
= WIN_GetPtr( hwnd
)) || wndPtr
== WND_OTHER_PROCESS
) return;
1511 has_menu
= HAS_MENU(wndPtr
);
1512 dwStyle
= wndPtr
->dwStyle
;
1513 dwExStyle
= wndPtr
->dwExStyle
;
1514 flags
= wndPtr
->flags
;
1515 rectClient
= wndPtr
->rectClient
;
1516 rectWindow
= wndPtr
->rectWindow
;
1517 WIN_ReleasePtr( wndPtr
);
1519 if ( dwStyle
& WS_MINIMIZE
||
1520 !WIN_IsWindowDrawable( hwnd
, 0 )) return; /* Nothing to do */
1522 active
= 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
, rectClient
.left
-rectWindow
.left
,
1538 rectClient
.top
-rectWindow
.top
,
1539 rectClient
.right
-rectWindow
.left
,
1540 rectClient
.bottom
-rectWindow
.top
)
1543 ReleaseDC( hwnd
, hdc
);
1547 rect
.top
= rect
.left
= 0;
1548 rect
.right
= rectWindow
.right
- rectWindow
.left
;
1549 rect
.bottom
= rectWindow
.bottom
- rectWindow
.top
;
1552 GetRgnBox( clip
, &rectClip
);
1559 SelectObject( hdc
, GetSysColorPen(COLOR_WINDOWFRAME
) );
1561 if (HAS_STATICOUTERFRAME(dwStyle
, dwExStyle
)) {
1562 DrawEdge (hdc
, &rect
, BDR_SUNKENOUTER
, BF_RECT
| BF_ADJUST
);
1564 else if (HAS_BIGFRAME( dwStyle
, dwExStyle
)) {
1565 DrawEdge (hdc
, &rect
, EDGE_RAISED
, BF_RECT
| BF_ADJUST
);
1568 NC_DrawFrame95(hdc
, &rect
, active
, dwStyle
, dwExStyle
);
1570 if ((dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1573 if (dwExStyle
& WS_EX_TOOLWINDOW
) {
1574 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSMCAPTION
);
1575 rect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
);
1578 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYCAPTION
);
1579 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
);
1581 if( !clip
|| IntersectRect( &rfuzz
, &r
, &rectClip
) )
1582 NC_DrawCaption95 (hdc
, &r
, hwnd
, dwStyle
,
1589 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYMENU
);
1591 TRACE("Calling DrawMenuBar with rect (%d, %d)-(%d, %d)\n",
1592 r
.left
, r
.top
, r
.right
, r
.bottom
);
1594 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
) + 1;
1597 TRACE("After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1598 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1600 if (dwExStyle
& WS_EX_CLIENTEDGE
)
1601 DrawEdge (hdc
, &rect
, EDGE_SUNKEN
, BF_RECT
| BF_ADJUST
);
1603 /* Draw the scroll-bars */
1605 if (dwStyle
& WS_VSCROLL
)
1606 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1607 if (dwStyle
& WS_HSCROLL
)
1608 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1610 /* Draw the "size-box" */
1611 if ((dwStyle
& WS_VSCROLL
) && (dwStyle
& WS_HSCROLL
))
1614 r
.left
= r
.right
- GetSystemMetrics(SM_CXVSCROLL
) + 1;
1615 r
.top
= r
.bottom
- GetSystemMetrics(SM_CYHSCROLL
) + 1;
1616 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1619 ReleaseDC( hwnd
, hdc
);
1625 /***********************************************************************
1628 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1630 LONG
NC_HandleNCPaint( HWND hwnd
, HRGN clip
)
1632 DWORD dwStyle
= GetWindowLongW( hwnd
, GWL_STYLE
);
1634 if( dwStyle
& WS_VISIBLE
)
1636 if( dwStyle
& WS_MINIMIZE
)
1637 WINPOS_RedrawIconTitle( hwnd
);
1638 else if (TWEAK_WineLook
== WIN31_LOOK
)
1639 NC_DoNCPaint( hwnd
, clip
, FALSE
);
1641 NC_DoNCPaint95( hwnd
, clip
, FALSE
);
1647 /***********************************************************************
1648 * NC_HandleNCActivate
1650 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1652 LONG
NC_HandleNCActivate( HWND hwnd
, WPARAM wParam
)
1654 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1656 /* Lotus Notes draws menu descriptions in the caption of its main
1657 * window. When it wants to restore original "system" view, it just
1658 * sends WM_NCACTIVATE message to itself. Any optimizations here in
1659 * attempt to minimize redrawings lead to a not restored caption.
1663 if (wParam
) wndPtr
->flags
|= WIN_NCACTIVATED
;
1664 else wndPtr
->flags
&= ~WIN_NCACTIVATED
;
1665 WIN_ReleaseWndPtr(wndPtr
);
1667 if (IsIconic(hwnd
)) WINPOS_RedrawIconTitle( hwnd
);
1668 else if (TWEAK_WineLook
== WIN31_LOOK
)
1669 NC_DoNCPaint( hwnd
, (HRGN
)1, FALSE
);
1671 NC_DoNCPaint95( hwnd
, (HRGN
)1, FALSE
);
1677 /***********************************************************************
1678 * NC_HandleSetCursor
1680 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1682 LONG
NC_HandleSetCursor( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1684 if (hwnd
!= WIN_GetFullHandle( (HWND
)wParam
))
1685 return 0; /* Don't set the cursor for child windows */
1687 switch(LOWORD(lParam
))
1691 WORD msg
= HIWORD( lParam
);
1692 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_MBUTTONDOWN
) ||
1693 (msg
== WM_RBUTTONDOWN
))
1700 HCURSOR hCursor
= GetClassLongA(hwnd
, GCL_HCURSOR
);
1710 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZEWEA
) );
1714 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENSA
) );
1718 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENWSEA
) );
1722 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENESWA
) );
1725 /* Default cursor: arrow */
1726 return (LONG
)SetCursor( LoadCursorA( 0, IDC_ARROWA
) );
1729 /***********************************************************************
1732 void NC_GetSysPopupPos( HWND hwnd
, RECT
* rect
)
1734 if (IsIconic(hwnd
)) GetWindowRect( hwnd
, rect
);
1737 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1738 if (!wndPtr
) return;
1740 NC_GetInsideRect( hwnd
, rect
);
1741 OffsetRect( rect
, wndPtr
->rectWindow
.left
, wndPtr
->rectWindow
.top
);
1742 if (wndPtr
->dwStyle
& WS_CHILD
)
1743 ClientToScreen( GetParent(hwnd
), (POINT
*)rect
);
1744 if (TWEAK_WineLook
== WIN31_LOOK
) {
1745 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CXSIZE
);
1746 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYSIZE
);
1749 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
1750 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
1752 WIN_ReleaseWndPtr( wndPtr
);
1756 /***********************************************************************
1757 * NC_TrackMinMaxBox95
1759 * Track a mouse button press on the minimize or maximize box.
1761 * The big difference between 3.1 and 95 is the disabled button state.
1762 * In win95 the system button can be disabled, so it can ignore the mouse
1766 static void NC_TrackMinMaxBox95( HWND hwnd
, WORD wParam
)
1769 HDC hdc
= GetWindowDC( hwnd
);
1770 BOOL pressed
= TRUE
;
1772 DWORD wndStyle
= GetWindowLongA( hwnd
, GWL_STYLE
);
1773 HMENU hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1775 void (*paintButton
)(HWND
, HDC16
, BOOL
, BOOL
);
1777 if (wParam
== HTMINBUTTON
)
1779 /* If the style is not present, do nothing */
1780 if (!(wndStyle
& WS_MINIMIZEBOX
))
1783 /* Check if the sysmenu item for minimize is there */
1784 state
= GetMenuState(hSysMenu
, SC_MINIMIZE
, MF_BYCOMMAND
);
1786 paintButton
= &NC_DrawMinButton95
;
1790 /* If the style is not present, do nothing */
1791 if (!(wndStyle
& WS_MAXIMIZEBOX
))
1794 /* Check if the sysmenu item for maximize is there */
1795 state
= GetMenuState(hSysMenu
, SC_MAXIMIZE
, MF_BYCOMMAND
);
1797 paintButton
= &NC_DrawMaxButton95
;
1802 (*paintButton
)( hwnd
, hdc
, TRUE
, FALSE
);
1806 BOOL oldstate
= pressed
;
1808 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1809 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1811 if(msg
.message
== WM_LBUTTONUP
)
1814 if(msg
.message
!= WM_MOUSEMOVE
)
1817 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1818 if (pressed
!= oldstate
)
1819 (*paintButton
)( hwnd
, hdc
, pressed
, FALSE
);
1823 (*paintButton
)(hwnd
, hdc
, FALSE
, FALSE
);
1826 ReleaseDC( hwnd
, hdc
);
1828 /* If the item minimize or maximize of the sysmenu are not there */
1829 /* or if the style is not present, do nothing */
1830 if ((!pressed
) || (state
== 0xFFFFFFFF))
1833 if (wParam
== HTMINBUTTON
)
1834 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1836 SendMessageA( hwnd
, WM_SYSCOMMAND
,
1837 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1840 /***********************************************************************
1843 * Track a mouse button press on the minimize or maximize box.
1845 static void NC_TrackMinMaxBox( HWND hwnd
, WORD wParam
)
1848 HDC hdc
= GetWindowDC( hwnd
);
1849 BOOL pressed
= TRUE
;
1850 void (*paintButton
)(HWND
, HDC16
, BOOL
);
1854 if (wParam
== HTMINBUTTON
)
1855 paintButton
= &NC_DrawMinButton
;
1857 paintButton
= &NC_DrawMaxButton
;
1859 (*paintButton
)( hwnd
, hdc
, TRUE
);
1863 BOOL oldstate
= pressed
;
1865 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1866 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1868 if(msg
.message
== WM_LBUTTONUP
)
1871 if(msg
.message
!= WM_MOUSEMOVE
)
1874 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1875 if (pressed
!= oldstate
)
1876 (*paintButton
)( hwnd
, hdc
, pressed
);
1880 (*paintButton
)( hwnd
, hdc
, FALSE
);
1883 ReleaseDC( hwnd
, hdc
);
1885 if (!pressed
) return;
1887 if (wParam
== HTMINBUTTON
)
1888 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1890 SendMessageA( hwnd
, WM_SYSCOMMAND
,
1891 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1895 /***********************************************************************
1896 * NC_TrackCloseButton95
1898 * Track a mouse button press on the Win95 close button.
1901 NC_TrackCloseButton95 (HWND hwnd
, WORD wParam
)
1905 BOOL pressed
= TRUE
;
1906 HMENU hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1912 state
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
);
1914 /* If the item close of the sysmenu is disabled or not there do nothing */
1915 if((state
& MF_DISABLED
) || (state
& MF_GRAYED
) || (state
== 0xFFFFFFFF))
1918 hdc
= GetWindowDC( hwnd
);
1922 NC_DrawCloseButton95 (hwnd
, hdc
, TRUE
, FALSE
);
1926 BOOL oldstate
= pressed
;
1928 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1929 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1931 if(msg
.message
== WM_LBUTTONUP
)
1934 if(msg
.message
!= WM_MOUSEMOVE
)
1937 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1938 if (pressed
!= oldstate
)
1939 NC_DrawCloseButton95 (hwnd
, hdc
, pressed
, FALSE
);
1943 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
, FALSE
);
1946 ReleaseDC( hwnd
, hdc
);
1947 if (!pressed
) return;
1949 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1953 /***********************************************************************
1956 * Track a mouse button press on the horizontal or vertical scroll-bar.
1958 static void NC_TrackScrollBar( HWND hwnd
, WPARAM wParam
, POINT pt
)
1962 if ((wParam
& 0xfff0) == SC_HSCROLL
)
1964 if ((wParam
& 0x0f) != HTHSCROLL
) return;
1965 scrollbar
= SB_HORZ
;
1967 else /* SC_VSCROLL */
1969 if ((wParam
& 0x0f) != HTVSCROLL
) return;
1970 scrollbar
= SB_VERT
;
1972 SCROLL_TrackScrollBar( hwnd
, scrollbar
, pt
);
1976 /***********************************************************************
1977 * NC_HandleNCLButtonDown
1979 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
1981 LONG
NC_HandleNCLButtonDown( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1983 LONG style
= GetWindowLongA( hwnd
, GWL_STYLE
);
1985 switch(wParam
) /* Hit test */
1989 HWND top
= GetAncestor( hwnd
, GA_ROOT
);
1991 if( WINPOS_SetActiveWindow(top
, TRUE
, TRUE
) || (GetActiveWindow() == top
) )
1992 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOVE
+ HTCAPTION
, lParam
);
1997 if( style
& WS_SYSMENU
)
1999 if( !(style
& WS_MINIMIZE
) )
2001 HDC hDC
= GetWindowDC(hwnd
);
2002 if (TWEAK_WineLook
== WIN31_LOOK
)
2003 NC_DrawSysButton( hwnd
, hDC
, TRUE
);
2005 NC_DrawSysButton95( hwnd
, hDC
, TRUE
);
2006 ReleaseDC( hwnd
, hDC
);
2008 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
+ HTSYSMENU
, lParam
);
2013 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
, lParam
);
2017 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
2021 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
2026 if (TWEAK_WineLook
== WIN31_LOOK
)
2027 NC_TrackMinMaxBox( hwnd
, wParam
);
2029 NC_TrackMinMaxBox95( hwnd
, wParam
);
2033 if (TWEAK_WineLook
>= WIN95_LOOK
)
2034 NC_TrackCloseButton95 (hwnd
, wParam
);
2045 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2046 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_SIZE
+ wParam
- 2, lParam
);
2056 /***********************************************************************
2057 * NC_HandleNCLButtonDblClk
2059 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2061 LONG
NC_HandleNCLButtonDblClk( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2064 * if this is an icon, send a restore since we are handling
2069 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_RESTORE
, lParam
);
2073 switch(wParam
) /* Hit test */
2076 /* stop processing if WS_MAXIMIZEBOX is missing */
2077 if (GetWindowLongA( hwnd
, GWL_STYLE
) & WS_MAXIMIZEBOX
)
2078 SendMessageW( hwnd
, WM_SYSCOMMAND
,
2079 IsZoomed(hwnd
) ? SC_RESTORE
: SC_MAXIMIZE
, lParam
);
2083 if (!(GetClassLongW(hwnd
, GCL_STYLE
) & CS_NOCLOSE
))
2084 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, lParam
);
2088 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
2092 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
2099 /***********************************************************************
2100 * NC_HandleSysCommand
2102 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2104 LONG
NC_HandleSysCommand( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2106 TRACE("Handling WM_SYSCOMMAND %x %lx\n", wParam
, lParam
);
2108 switch (wParam
& 0xfff0)
2112 if (USER_Driver
.pSysCommandSizeMove
)
2113 USER_Driver
.pSysCommandSizeMove( hwnd
, wParam
);
2117 if (hwnd
== GetForegroundWindow())
2118 ShowOwnedPopups(hwnd
,FALSE
);
2119 ShowWindow( hwnd
, SW_MINIMIZE
);
2123 if (IsIconic(hwnd
) && hwnd
== GetForegroundWindow())
2124 ShowOwnedPopups(hwnd
,TRUE
);
2125 ShowWindow( hwnd
, SW_MAXIMIZE
);
2129 if (IsIconic(hwnd
) && hwnd
== GetForegroundWindow())
2130 ShowOwnedPopups(hwnd
,TRUE
);
2131 ShowWindow( hwnd
, SW_RESTORE
);
2135 return SendMessageA( hwnd
, WM_CLOSE
, 0, 0 );
2141 pt
.x
= SLOWORD(lParam
);
2142 pt
.y
= SHIWORD(lParam
);
2143 NC_TrackScrollBar( hwnd
, wParam
, pt
);
2150 pt
.x
= SLOWORD(lParam
);
2151 pt
.y
= SHIWORD(lParam
);
2152 MENU_TrackMouseMenuBar( hwnd
, wParam
& 0x000F, pt
);
2157 MENU_TrackKbdMenuBar( hwnd
, wParam
, LOWORD(lParam
) );
2161 WinExec( "taskman.exe", SW_SHOWNORMAL
);
2165 if (wParam
== SC_ABOUTWINE
)
2167 HMODULE hmodule
= LoadLibraryA( "shell32.dll" );
2170 FARPROC aboutproc
= GetProcAddress( hmodule
, "ShellAboutA" );
2171 if (aboutproc
) aboutproc( hwnd
, "Wine", WINE_RELEASE_INFO
, 0 );
2172 FreeLibrary( hmodule
);
2176 if (wParam
== SC_PUTMARK
)
2177 TRACE_(shell
)("Mark requested by user\n");
2184 FIXME("unimplemented!\n");
2190 /*************************************************************
2193 * Stub for the grayed button of the caption
2195 *************************************************************/
2197 BOOL
NC_DrawGrayButton(HDC hdc
, int x
, int y
)
2200 HDC hdcMask
= CreateCompatibleDC (0);
2203 hMaskBmp
= CreateBitmap (12, 10, 1, 1, lpGrayMask
);
2208 SelectObject (hdcMask
, hMaskBmp
);
2210 /* Draw the grayed bitmap using the mask */
2211 hOldBrush
= SelectObject (hdc
, RGB(128, 128, 128));
2212 BitBlt (hdc
, x
, y
, 12, 10,
2213 hdcMask
, 0, 0, 0xB8074A);
2216 SelectObject (hdc
, hOldBrush
);
2217 DeleteObject(hMaskBmp
);