2 * Non-client area window functions
4 * Copyright 1994 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "wine/winuser16.h"
34 #include "cursoricon.h"
36 #include "nonclient.h"
38 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(nonclient
);
41 WINE_DECLARE_DEBUG_CHANNEL(shell
);
43 BOOL
NC_DrawGrayButton(HDC hdc
, int x
, int y
);
45 static HBITMAP hbitmapClose
;
47 static const BYTE lpGrayMask
[] = { 0xAA, 0xA0,
58 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
59 #define SC_PUTMARK (SC_SCREENSAVE+2)
61 /* Some useful macros */
62 #define HAS_DLGFRAME(style,exStyle) \
63 (((exStyle) & WS_EX_DLGMODALFRAME) || \
64 (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
66 #define HAS_THICKFRAME(style,exStyle) \
67 (((style) & WS_THICKFRAME) && \
68 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
70 #define HAS_THINFRAME(style) \
71 (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
73 #define HAS_BIGFRAME(style,exStyle) \
74 (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
75 ((exStyle) & WS_EX_DLGMODALFRAME))
77 #define HAS_STATICOUTERFRAME(style,exStyle) \
78 (((exStyle) & (WS_EX_STATICEDGE|WS_EX_DLGMODALFRAME)) == \
81 #define HAS_ANYFRAME(style,exStyle) \
82 (((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
83 ((exStyle) & WS_EX_DLGMODALFRAME) || \
84 !((style) & (WS_CHILD | WS_POPUP)))
86 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
89 /***********************************************************************
92 * Compute the size of the window rectangle from the size of the
95 static void NC_AdjustRect( LPRECT rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
97 if (TWEAK_WineLook
> WIN31_LOOK
)
98 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
100 if(style
& WS_ICONIC
) return;
102 if (HAS_THICKFRAME( style
, exStyle
))
103 InflateRect( rect
, GetSystemMetrics(SM_CXFRAME
), GetSystemMetrics(SM_CYFRAME
) );
104 else if (HAS_DLGFRAME( style
, exStyle
))
105 InflateRect( rect
, GetSystemMetrics(SM_CXDLGFRAME
), GetSystemMetrics(SM_CYDLGFRAME
) );
106 else if (HAS_THINFRAME( style
))
107 InflateRect( rect
, GetSystemMetrics(SM_CXBORDER
), GetSystemMetrics(SM_CYBORDER
));
109 if ((style
& WS_CAPTION
) == WS_CAPTION
)
110 rect
->top
-= GetSystemMetrics(SM_CYCAPTION
) - GetSystemMetrics(SM_CYBORDER
);
112 if (menu
) rect
->top
-= GetSystemMetrics(SM_CYMENU
) + GetSystemMetrics(SM_CYBORDER
);
114 if (style
& WS_VSCROLL
) {
115 rect
->right
+= GetSystemMetrics(SM_CXVSCROLL
) - 1;
116 if(!HAS_ANYFRAME( style
, exStyle
))
120 if (style
& WS_HSCROLL
) {
121 rect
->bottom
+= GetSystemMetrics(SM_CYHSCROLL
) - 1;
122 if(!HAS_ANYFRAME( style
, exStyle
))
128 /******************************************************************************
129 * NC_AdjustRectOuter95
131 * Computes the size of the "outside" parts of the window based on the
132 * parameters of the client area.
141 * "Outer" parts of a window means the whole window frame, caption and
142 * menu bar. It does not include "inner" parts of the frame like client
143 * edge, static edge or scroll bars.
146 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
147 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
149 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
150 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
151 * NC_AdjustRectInner95 and added handling of Win95 styles.
153 * 28-Jul-1999 Ove Kåven (ovek@arcticnet.no)
154 * Streamlined window style checks.
156 *****************************************************************************/
159 NC_AdjustRectOuter95 (LPRECT rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
162 if(style
& WS_ICONIC
) return;
164 if ((exStyle
& (WS_EX_STATICEDGE
|WS_EX_DLGMODALFRAME
)) ==
167 adjust
= 1; /* for the outer frame always present */
172 if ((exStyle
& WS_EX_DLGMODALFRAME
) ||
173 (style
& (WS_THICKFRAME
|WS_DLGFRAME
))) adjust
= 2; /* outer */
175 if (style
& WS_THICKFRAME
)
176 adjust
+= ( GetSystemMetrics (SM_CXFRAME
)
177 - GetSystemMetrics (SM_CXDLGFRAME
)); /* The resize border */
178 if ((style
& (WS_BORDER
|WS_DLGFRAME
)) ||
179 (exStyle
& WS_EX_DLGMODALFRAME
))
180 adjust
++; /* The other border */
182 InflateRect (rect
, adjust
, adjust
);
184 if ((style
& WS_CAPTION
) == WS_CAPTION
)
186 if (exStyle
& WS_EX_TOOLWINDOW
)
187 rect
->top
-= GetSystemMetrics(SM_CYSMCAPTION
);
189 rect
->top
-= GetSystemMetrics(SM_CYCAPTION
);
191 if (menu
) rect
->top
-= GetSystemMetrics(SM_CYMENU
);
195 /******************************************************************************
196 * NC_AdjustRectInner95
198 * Computes the size of the "inside" part of the window based on the
199 * parameters of the client area.
207 * "Inner" part of a window means the window frame inside of the flat
208 * window frame. It includes the client edge, the static edge and the
212 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
213 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
215 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
216 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
217 * NC_AdjustRectInner95 and added handling of Win95 styles.
219 *****************************************************************************/
222 NC_AdjustRectInner95 (LPRECT rect
, DWORD style
, DWORD exStyle
)
224 if(style
& WS_ICONIC
) return;
226 if (exStyle
& WS_EX_CLIENTEDGE
)
227 InflateRect(rect
, GetSystemMetrics(SM_CXEDGE
), GetSystemMetrics(SM_CYEDGE
));
229 if (style
& WS_VSCROLL
)
231 if((exStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
232 rect
->left
-= GetSystemMetrics(SM_CXVSCROLL
);
234 rect
->right
+= GetSystemMetrics(SM_CXVSCROLL
);
236 if (style
& WS_HSCROLL
) rect
->bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
241 static HICON
NC_IconForWindow( HWND hwnd
)
244 WND
*wndPtr
= WIN_GetPtr( hwnd
);
246 if (wndPtr
&& wndPtr
!= WND_OTHER_PROCESS
)
248 hIcon
= wndPtr
->hIconSmall
;
249 if (!hIcon
) hIcon
= wndPtr
->hIcon
;
250 WIN_ReleasePtr( wndPtr
);
252 if (!hIcon
) hIcon
= (HICON
) GetClassLongA( hwnd
, GCL_HICONSM
);
253 if (!hIcon
) hIcon
= (HICON
) GetClassLongA( hwnd
, GCL_HICON
);
255 /* If there is no hIcon specified and this is a modal dialog,
256 * get the default one.
258 if (!hIcon
&& (GetWindowLongA( hwnd
, GWL_STYLE
) & DS_MODALFRAME
))
259 hIcon
= LoadImageA(0, (LPSTR
)IDI_WINLOGO
, IMAGE_ICON
, 0, 0, LR_DEFAULTCOLOR
);
263 /***********************************************************************
264 * DrawCaption (USER32.@) Draws a caption bar
278 DrawCaption (HWND hwnd
, HDC hdc
, const RECT
*lpRect
, UINT uFlags
)
280 return DrawCaptionTempA (hwnd
, hdc
, lpRect
, 0, 0, NULL
, uFlags
& 0x1F);
284 /***********************************************************************
285 * DrawCaptionTempA (USER32.@)
287 BOOL WINAPI
DrawCaptionTempA (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
288 HICON hIcon
, LPCSTR str
, UINT uFlags
)
294 if (!(uFlags
& DC_TEXT
) || !str
)
295 return DrawCaptionTempW( hwnd
, hdc
, rect
, hFont
, hIcon
, NULL
, uFlags
);
297 len
= MultiByteToWideChar( CP_ACP
, 0, str
, -1, NULL
, 0 );
298 if ((strW
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) )))
300 MultiByteToWideChar( CP_ACP
, 0, str
, -1, strW
, len
);
301 ret
= DrawCaptionTempW (hwnd
, hdc
, rect
, hFont
, hIcon
, strW
, uFlags
);
302 HeapFree( GetProcessHeap (), 0, strW
);
308 /***********************************************************************
309 * DrawCaptionTempW (USER32.@)
311 BOOL WINAPI
DrawCaptionTempW (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
312 HICON hIcon
, LPCWSTR str
, UINT uFlags
)
316 TRACE("(%p,%p,%p,%p,%p,%s,%08x)\n",
317 hwnd
, hdc
, rect
, hFont
, hIcon
, debugstr_w(str
), uFlags
);
319 /* drawing background */
320 if (uFlags
& DC_INBUTTON
) {
321 FillRect (hdc
, &rc
, GetSysColorBrush (COLOR_3DFACE
));
323 if (uFlags
& DC_ACTIVE
) {
324 HBRUSH hbr
= SelectObject (hdc
, CACHE_GetPattern55AABrush ());
325 PatBlt (hdc
, rc
.left
, rc
.top
,
326 rc
.right
-rc
.left
, rc
.bottom
-rc
.top
, 0xFA0089);
327 SelectObject (hdc
, hbr
);
331 FillRect (hdc
, &rc
, GetSysColorBrush ((uFlags
& DC_ACTIVE
) ?
332 COLOR_ACTIVECAPTION
: COLOR_INACTIVECAPTION
));
337 if ((uFlags
& DC_ICON
) && !(uFlags
& DC_SMALLCAP
)) {
341 pt
.y
= (rc
.bottom
+ rc
.top
- GetSystemMetrics(SM_CYSMICON
)) / 2;
343 if (!hIcon
) hIcon
= NC_IconForWindow(hwnd
);
344 DrawIconEx (hdc
, pt
.x
, pt
.y
, hIcon
, GetSystemMetrics(SM_CXSMICON
),
345 GetSystemMetrics(SM_CYSMICON
), 0, 0, DI_NORMAL
);
346 rc
.left
+= (rc
.bottom
- rc
.top
);
350 if (uFlags
& DC_TEXT
) {
353 if (uFlags
& DC_INBUTTON
)
354 SetTextColor (hdc
, GetSysColor (COLOR_BTNTEXT
));
355 else if (uFlags
& DC_ACTIVE
)
356 SetTextColor (hdc
, GetSysColor (COLOR_CAPTIONTEXT
));
358 SetTextColor (hdc
, GetSysColor (COLOR_INACTIVECAPTIONTEXT
));
360 SetBkMode (hdc
, TRANSPARENT
);
363 hOldFont
= SelectObject (hdc
, hFont
);
365 NONCLIENTMETRICSW nclm
;
367 nclm
.cbSize
= sizeof(NONCLIENTMETRICSW
);
368 SystemParametersInfoW (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
369 hNewFont
= CreateFontIndirectW ((uFlags
& DC_SMALLCAP
) ?
370 &nclm
.lfSmCaptionFont
: &nclm
.lfCaptionFont
);
371 hOldFont
= SelectObject (hdc
, hNewFont
);
375 DrawTextW (hdc
, str
, -1, &rc
,
376 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
380 nLen
= GetWindowTextW (hwnd
, szText
, 128);
381 DrawTextW (hdc
, szText
, nLen
, &rc
,
382 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
386 SelectObject (hdc
, hOldFont
);
388 DeleteObject (SelectObject (hdc
, hOldFont
));
391 /* drawing focus ??? */
393 FIXME("undocumented flag (0x2000)!\n");
399 /***********************************************************************
400 * AdjustWindowRect (USER.102)
402 BOOL16 WINAPI
AdjustWindowRect16( LPRECT16 rect
, DWORD style
, BOOL16 menu
)
404 return AdjustWindowRectEx16( rect
, style
, menu
, 0 );
408 /***********************************************************************
409 * AdjustWindowRect (USER32.@)
411 BOOL WINAPI
AdjustWindowRect( LPRECT rect
, DWORD style
, BOOL menu
)
413 return AdjustWindowRectEx( rect
, style
, menu
, 0 );
417 /***********************************************************************
418 * AdjustWindowRectEx (USER.454)
420 BOOL16 WINAPI
AdjustWindowRectEx16( LPRECT16 rect
, DWORD style
,
421 BOOL16 menu
, DWORD exStyle
)
426 CONV_RECT16TO32( rect
, &rect32
);
427 ret
= AdjustWindowRectEx( &rect32
, style
, menu
, exStyle
);
428 CONV_RECT32TO16( &rect32
, rect
);
433 /***********************************************************************
434 * AdjustWindowRectEx (USER32.@)
436 BOOL WINAPI
AdjustWindowRectEx( LPRECT rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
438 /* Correct the window style */
439 style
&= (WS_DLGFRAME
| WS_BORDER
| WS_THICKFRAME
| WS_CHILD
);
440 exStyle
&= (WS_EX_DLGMODALFRAME
| WS_EX_CLIENTEDGE
|
441 WS_EX_STATICEDGE
| WS_EX_TOOLWINDOW
);
442 if (exStyle
& WS_EX_DLGMODALFRAME
) style
&= ~WS_THICKFRAME
;
444 TRACE("(%ld,%ld)-(%ld,%ld) %08lx %d %08lx\n",
445 rect
->left
, rect
->top
, rect
->right
, rect
->bottom
,
446 style
, menu
, exStyle
);
448 if (TWEAK_WineLook
== WIN31_LOOK
)
449 NC_AdjustRect( rect
, style
, menu
, exStyle
);
452 NC_AdjustRectOuter95( rect
, style
, menu
, exStyle
);
453 NC_AdjustRectInner95( rect
, style
, exStyle
);
459 /***********************************************************************
460 * NC_HandleNCCalcSize
462 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
464 LONG
NC_HandleNCCalcSize( HWND hwnd
, RECT
*winRect
)
466 RECT tmpRect
= { 0, 0, 0, 0 };
468 LONG cls_style
= GetClassLongA(hwnd
, GCL_STYLE
);
469 LONG style
= GetWindowLongA( hwnd
, GWL_STYLE
);
470 LONG exStyle
= GetWindowLongA( hwnd
, GWL_EXSTYLE
);
472 if (cls_style
& CS_VREDRAW
) result
|= WVR_VREDRAW
;
473 if (cls_style
& CS_HREDRAW
) result
|= WVR_HREDRAW
;
477 if (TWEAK_WineLook
== WIN31_LOOK
)
478 NC_AdjustRect( &tmpRect
, style
, FALSE
, exStyle
);
480 NC_AdjustRectOuter95( &tmpRect
, style
, FALSE
, exStyle
);
482 winRect
->left
-= tmpRect
.left
;
483 winRect
->top
-= tmpRect
.top
;
484 winRect
->right
-= tmpRect
.right
;
485 winRect
->bottom
-= tmpRect
.bottom
;
487 if (!(style
& WS_CHILD
) && GetMenu(hwnd
))
489 TRACE("Calling GetMenuBarHeight with hwnd %p, width %ld, at (%ld, %ld).\n",
490 hwnd
, winRect
->right
- winRect
->left
, -tmpRect
.left
, -tmpRect
.top
);
493 MENU_GetMenuBarHeight( hwnd
,
494 winRect
->right
- winRect
->left
,
495 -tmpRect
.left
, -tmpRect
.top
) + 1;
498 if (TWEAK_WineLook
> WIN31_LOOK
) {
499 SetRect(&tmpRect
, 0, 0, 0, 0);
500 NC_AdjustRectInner95 (&tmpRect
, style
, exStyle
);
501 winRect
->left
-= tmpRect
.left
;
502 winRect
->top
-= tmpRect
.top
;
503 winRect
->right
-= tmpRect
.right
;
504 winRect
->bottom
-= tmpRect
.bottom
;
507 if (winRect
->top
> winRect
->bottom
)
508 winRect
->bottom
= winRect
->top
;
510 if (winRect
->left
> winRect
->right
)
511 winRect
->right
= winRect
->left
;
517 /***********************************************************************
520 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
521 * but without the borders (if any).
522 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
524 void NC_GetInsideRect( HWND hwnd
, RECT
*rect
)
526 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
528 rect
->top
= rect
->left
= 0;
529 rect
->right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
530 rect
->bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
532 if (wndPtr
->dwStyle
& WS_ICONIC
) goto END
;
534 /* Remove frame from rectangle */
535 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
537 InflateRect( rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
539 else if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
541 InflateRect( rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
542 /* FIXME: this isn't in NC_AdjustRect? why not? */
543 if ((TWEAK_WineLook
== WIN31_LOOK
) && (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
))
544 InflateRect( rect
, -1, 0 );
546 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
548 InflateRect( rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
) );
551 /* We have additional border information if the window
552 * is a child (but not an MDI child) */
553 if (TWEAK_WineLook
!= WIN31_LOOK
)
555 if ( (wndPtr
->dwStyle
& WS_CHILD
) &&
556 ( (wndPtr
->dwExStyle
& WS_EX_MDICHILD
) == 0 ) )
558 if (wndPtr
->dwExStyle
& WS_EX_CLIENTEDGE
)
559 InflateRect (rect
, -GetSystemMetrics(SM_CXEDGE
), -GetSystemMetrics(SM_CYEDGE
));
560 if (wndPtr
->dwExStyle
& WS_EX_STATICEDGE
)
561 InflateRect (rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
566 WIN_ReleaseWndPtr(wndPtr
);
571 /***********************************************************************
574 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
577 static LONG
NC_DoNCHitTest (WND
*wndPtr
, POINT pt
)
581 TRACE("hwnd=%p pt=%ld,%ld\n", wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
583 GetWindowRect(wndPtr
->hwndSelf
, &rect
);
584 if (!PtInRect( &rect
, pt
)) return HTNOWHERE
;
586 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
589 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
591 InflateRect( &rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
592 if (!PtInRect( &rect
, pt
))
594 /* Check top sizing border */
597 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
598 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
601 /* Check bottom sizing border */
602 if (pt
.y
>= rect
.bottom
)
604 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
605 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
608 /* Check left sizing border */
609 if (pt
.x
< rect
.left
)
611 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
612 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
615 /* Check right sizing border */
616 if (pt
.x
>= rect
.right
)
618 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
619 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
624 else /* No thick frame */
626 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
627 InflateRect(&rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
628 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
629 InflateRect(&rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
630 if (!PtInRect( &rect
, pt
)) return HTBORDER
;
635 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
637 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
) - GetSystemMetrics(SM_CYBORDER
);
638 if (!PtInRect( &rect
, pt
))
640 /* Check system menu */
641 if ((wndPtr
->dwStyle
& WS_SYSMENU
) && !(wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
))
642 rect
.left
+= GetSystemMetrics(SM_CXSIZE
);
643 if (pt
.x
<= rect
.left
) return HTSYSMENU
;
645 /* Check maximize box */
646 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
647 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
649 if (pt
.x
>= rect
.right
) return HTMAXBUTTON
;
650 /* Check minimize box */
651 if (wndPtr
->dwStyle
& WS_MINIMIZEBOX
)
652 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
653 if (pt
.x
>= rect
.right
) return HTMINBUTTON
;
658 /* Check client area */
660 ScreenToClient( wndPtr
->hwndSelf
, &pt
);
661 GetClientRect( wndPtr
->hwndSelf
, &rect
);
662 if (PtInRect( &rect
, pt
)) return HTCLIENT
;
664 /* Check vertical scroll bar */
666 if (wndPtr
->dwStyle
& WS_VSCROLL
)
668 if((wndPtr
->dwExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
669 rect
.left
-= GetSystemMetrics(SM_CXVSCROLL
);
671 rect
.right
+= GetSystemMetrics(SM_CXVSCROLL
);
672 if (PtInRect( &rect
, pt
)) return HTVSCROLL
;
675 /* Check horizontal scroll bar */
677 if (wndPtr
->dwStyle
& WS_HSCROLL
)
679 rect
.bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
680 if (PtInRect( &rect
, pt
))
683 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
684 ((((wndPtr
->dwExStyle
& WS_EX_LEFTSCROLLBAR
) != 0) && (pt
.x
<= rect
.left
+ GetSystemMetrics(SM_CXVSCROLL
))) ||
685 (((wndPtr
->dwExStyle
& WS_EX_LEFTSCROLLBAR
) == 0) && (pt
.x
>= rect
.right
- GetSystemMetrics(SM_CXVSCROLL
)))))
693 if (HAS_MENU(wndPtr
))
695 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
699 /* Has to return HTNOWHERE if nothing was found
700 Could happen when a window has a customized non client area */
705 /***********************************************************************
708 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
710 * FIXME: Just a modified copy of the Win 3.1 version.
713 static LONG
NC_DoNCHitTest95 (WND
*wndPtr
, POINT pt
)
717 TRACE("hwnd=%p pt=%ld,%ld\n", wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
719 GetWindowRect(wndPtr
->hwndSelf
, &rect
);
720 if (!PtInRect( &rect
, pt
)) return HTNOWHERE
;
722 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
725 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
727 InflateRect( &rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
728 if (!PtInRect( &rect
, pt
))
730 /* Check top sizing border */
733 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
734 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
737 /* Check bottom sizing border */
738 if (pt
.y
>= rect
.bottom
)
740 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
741 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
744 /* Check left sizing border */
745 if (pt
.x
< rect
.left
)
747 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
748 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
751 /* Check right sizing border */
752 if (pt
.x
>= rect
.right
)
754 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
755 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
760 else /* No thick frame */
762 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
763 InflateRect(&rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
764 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
765 InflateRect(&rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
766 if (!PtInRect( &rect
, pt
)) return HTBORDER
;
771 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
773 if (wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
)
774 rect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
) - 1;
776 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
777 if (!PtInRect( &rect
, pt
))
779 /* Check system menu */
780 if ((wndPtr
->dwStyle
& WS_SYSMENU
) && !(wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
))
782 if (NC_IconForWindow(wndPtr
->hwndSelf
))
783 rect
.left
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
785 if (pt
.x
< rect
.left
) return HTSYSMENU
;
787 /* Check close button */
788 if (wndPtr
->dwStyle
& WS_SYSMENU
)
789 rect
.right
-= GetSystemMetrics(SM_CYCAPTION
) - 1;
790 if (pt
.x
> rect
.right
) return HTCLOSE
;
792 /* Check maximize box */
793 /* In win95 there is automatically a Maximize button when there is a minimize one*/
794 if ((wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)|| (wndPtr
->dwStyle
& WS_MINIMIZEBOX
))
795 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
796 if (pt
.x
> rect
.right
) return HTMAXBUTTON
;
798 /* Check minimize box */
799 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
800 if ((wndPtr
->dwStyle
& WS_MINIMIZEBOX
)||(wndPtr
->dwStyle
& WS_MAXIMIZEBOX
))
801 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
803 if (pt
.x
> rect
.right
) return HTMINBUTTON
;
808 /* Check client area */
810 ScreenToClient( wndPtr
->hwndSelf
, &pt
);
811 GetClientRect( wndPtr
->hwndSelf
, &rect
);
812 if (PtInRect( &rect
, pt
)) return HTCLIENT
;
814 /* Check vertical scroll bar */
816 if (wndPtr
->dwStyle
& WS_VSCROLL
)
818 if((wndPtr
->dwExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
819 rect
.left
-= GetSystemMetrics(SM_CXVSCROLL
);
821 rect
.right
+= GetSystemMetrics(SM_CXVSCROLL
);
822 if (PtInRect( &rect
, pt
)) return HTVSCROLL
;
825 /* Check horizontal scroll bar */
827 if (wndPtr
->dwStyle
& WS_HSCROLL
)
829 rect
.bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
830 if (PtInRect( &rect
, pt
))
833 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
834 ((((wndPtr
->dwExStyle
& WS_EX_LEFTSCROLLBAR
) != 0) && (pt
.x
<= rect
.left
+ GetSystemMetrics(SM_CXVSCROLL
))) ||
835 (((wndPtr
->dwExStyle
& WS_EX_LEFTSCROLLBAR
) == 0) && (pt
.x
>= rect
.right
- GetSystemMetrics(SM_CXVSCROLL
)))))
843 if (HAS_MENU(wndPtr
))
845 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
849 /* Has to return HTNOWHERE if nothing was found
850 Could happen when a window has a customized non client area */
855 /***********************************************************************
858 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
860 LONG
NC_HandleNCHitTest (HWND hwnd
, POINT pt
)
863 WND
*wndPtr
= WIN_FindWndPtr (hwnd
);
868 if (TWEAK_WineLook
== WIN31_LOOK
)
869 retvalue
= NC_DoNCHitTest (wndPtr
, pt
);
871 retvalue
= NC_DoNCHitTest95 (wndPtr
, pt
);
872 WIN_ReleaseWndPtr(wndPtr
);
877 /***********************************************************************
880 void NC_DrawSysButton( HWND hwnd
, HDC hdc
, BOOL down
)
886 NC_GetInsideRect( hwnd
, &rect
);
887 hdcMem
= CreateCompatibleDC( hdc
);
888 hbitmap
= SelectObject( hdcMem
, hbitmapClose
);
889 BitBlt(hdc
, rect
.left
, rect
.top
, GetSystemMetrics(SM_CXSIZE
), GetSystemMetrics(SM_CYSIZE
),
890 hdcMem
, (GetWindowLongA(hwnd
,GWL_STYLE
) & WS_CHILD
) ? GetSystemMetrics(SM_CXSIZE
) : 0, 0,
891 down
? NOTSRCCOPY
: SRCCOPY
);
892 SelectObject( hdcMem
, hbitmap
);
897 /***********************************************************************
900 static void NC_DrawMaxButton( HWND hwnd
, HDC hdc
, BOOL down
)
903 UINT flags
= IsZoomed(hwnd
) ? DFCS_CAPTIONRESTORE
: DFCS_CAPTIONMAX
;
905 NC_GetInsideRect( hwnd
, &rect
);
906 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
) + 1;
907 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
910 if (down
) flags
|= DFCS_PUSHED
;
911 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
915 /***********************************************************************
918 static void NC_DrawMinButton( HWND hwnd
, HDC hdc
, BOOL down
)
921 UINT flags
= DFCS_CAPTIONMIN
;
922 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
924 NC_GetInsideRect( hwnd
, &rect
);
925 if (style
& (WS_MAXIMIZEBOX
|WS_MINIMIZEBOX
))
926 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) - 2;
927 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
) + 1;
928 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
931 if (down
) flags
|= DFCS_PUSHED
;
932 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
936 /******************************************************************************
938 * void NC_DrawSysButton95(
943 * Draws the Win95 system icon.
946 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
947 * Original implementation from NC_DrawSysButton source.
948 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
951 *****************************************************************************/
954 NC_DrawSysButton95 (HWND hwnd
, HDC hdc
, BOOL down
)
956 HICON hIcon
= NC_IconForWindow( hwnd
);
961 NC_GetInsideRect( hwnd
, &rect
);
962 DrawIconEx (hdc
, rect
.left
+ 1, rect
.top
+ 1, hIcon
,
963 GetSystemMetrics(SM_CXSIZE
) - 1,
964 GetSystemMetrics(SM_CYSIZE
) - 1, 0, 0, DI_NORMAL
);
970 /******************************************************************************
972 * void NC_DrawCloseButton95(
978 * Draws the Win95 close button.
980 * If bGrayed is true, then draw a disabled Close button
983 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
984 * Original implementation from NC_DrawSysButton95 source.
986 *****************************************************************************/
988 static void NC_DrawCloseButton95 (HWND hwnd
, HDC hdc
, BOOL down
, BOOL bGrayed
)
992 NC_GetInsideRect( hwnd
, &rect
);
994 /* A tool window has a smaller Close button */
995 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_TOOLWINDOW
)
997 INT iBmpHeight
= 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
998 INT iBmpWidth
= 11; /* it uses 11x11 for the close button in tool window */
999 INT iCaptionHeight
= GetSystemMetrics(SM_CYSMCAPTION
);
1001 rect
.top
= rect
.top
+ (iCaptionHeight
- 1 - iBmpHeight
) / 2;
1002 rect
.left
= rect
.right
- (iCaptionHeight
+ 1 + iBmpWidth
) / 2;
1003 rect
.bottom
= rect
.top
+ iBmpHeight
;
1004 rect
.right
= rect
.left
+ iBmpWidth
;
1008 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
) - 1;
1009 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1013 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
,
1014 (DFCS_CAPTIONCLOSE
|
1015 (down
? DFCS_PUSHED
: 0) |
1016 (bGrayed
? DFCS_INACTIVE
: 0)) );
1019 /******************************************************************************
1020 * NC_DrawMaxButton95
1022 * Draws the maximize button for Win95 style windows.
1023 * If bGrayed is true, then draw a disabled Maximize button
1025 static void NC_DrawMaxButton95(HWND hwnd
,HDC hdc
,BOOL down
, BOOL bGrayed
)
1028 UINT flags
= IsZoomed(hwnd
) ? DFCS_CAPTIONRESTORE
: DFCS_CAPTIONMAX
;
1030 NC_GetInsideRect( hwnd
, &rect
);
1031 if (GetWindowLongA( hwnd
, GWL_STYLE
) & WS_SYSMENU
)
1032 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1033 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
);
1034 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1037 if (down
) flags
|= DFCS_PUSHED
;
1038 if (bGrayed
) flags
|= DFCS_INACTIVE
;
1039 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
1042 /******************************************************************************
1043 * NC_DrawMinButton95
1045 * Draws the minimize button for Win95 style windows.
1046 * If bGrayed is true, then draw a disabled Minimize button
1048 static void NC_DrawMinButton95(HWND hwnd
,HDC hdc
,BOOL down
, BOOL bGrayed
)
1051 UINT flags
= DFCS_CAPTIONMIN
;
1052 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
1054 NC_GetInsideRect( hwnd
, &rect
);
1055 if (style
& WS_SYSMENU
)
1056 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1057 if (style
& (WS_MAXIMIZEBOX
|WS_MINIMIZEBOX
))
1058 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) - 2;
1059 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
);
1060 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1063 if (down
) flags
|= DFCS_PUSHED
;
1064 if (bGrayed
) flags
|= DFCS_INACTIVE
;
1065 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
1068 /***********************************************************************
1071 * Draw a window frame inside the given rectangle, and update the rectangle.
1072 * The correct pen for the frame must be selected in the DC.
1074 static void NC_DrawFrame( HDC hdc
, RECT
*rect
, BOOL dlgFrame
,
1079 if (TWEAK_WineLook
!= WIN31_LOOK
)
1080 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
1084 width
= GetSystemMetrics(SM_CXDLGFRAME
) - 1;
1085 height
= GetSystemMetrics(SM_CYDLGFRAME
) - 1;
1086 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1087 COLOR_INACTIVECAPTION
) );
1091 width
= GetSystemMetrics(SM_CXFRAME
) - 2;
1092 height
= GetSystemMetrics(SM_CYFRAME
) - 2;
1093 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1094 COLOR_INACTIVEBORDER
) );
1098 PatBlt( hdc
, rect
->left
, rect
->top
,
1099 rect
->right
- rect
->left
, height
, PATCOPY
);
1100 PatBlt( hdc
, rect
->left
, rect
->top
,
1101 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1102 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1103 rect
->right
- rect
->left
, -height
, PATCOPY
);
1104 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1105 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1109 InflateRect( rect
, -width
, -height
);
1113 INT decYOff
= GetSystemMetrics(SM_CXFRAME
) + GetSystemMetrics(SM_CXSIZE
) - 1;
1114 INT decXOff
= GetSystemMetrics(SM_CYFRAME
) + GetSystemMetrics(SM_CYSIZE
) - 1;
1116 /* Draw inner rectangle */
1118 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1119 Rectangle( hdc
, rect
->left
+ width
, rect
->top
+ height
,
1120 rect
->right
- width
, rect
->bottom
- height
);
1122 /* Draw the decorations */
1124 MoveToEx( hdc
, rect
->left
, rect
->top
+ decYOff
, NULL
);
1125 LineTo( hdc
, rect
->left
+ width
, rect
->top
+ decYOff
);
1126 MoveToEx( hdc
, rect
->right
- 1, rect
->top
+ decYOff
, NULL
);
1127 LineTo( hdc
, rect
->right
- width
- 1, rect
->top
+ decYOff
);
1128 MoveToEx( hdc
, rect
->left
, rect
->bottom
- decYOff
, NULL
);
1129 LineTo( hdc
, rect
->left
+ width
, rect
->bottom
- decYOff
);
1130 MoveToEx( hdc
, rect
->right
- 1, rect
->bottom
- decYOff
, NULL
);
1131 LineTo( hdc
, rect
->right
- width
- 1, rect
->bottom
- decYOff
);
1133 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->top
, NULL
);
1134 LineTo( hdc
, rect
->left
+ decXOff
, rect
->top
+ height
);
1135 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->bottom
- 1, NULL
);
1136 LineTo( hdc
, rect
->left
+ decXOff
, rect
->bottom
- height
- 1 );
1137 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->top
, NULL
);
1138 LineTo( hdc
, rect
->right
- decXOff
, rect
->top
+ height
);
1139 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->bottom
- 1, NULL
);
1140 LineTo( hdc
, rect
->right
- decXOff
, rect
->bottom
- height
- 1 );
1142 InflateRect( rect
, -width
- 1, -height
- 1 );
1147 /******************************************************************************
1149 * void NC_DrawFrame95(
1156 * Draw a window frame inside the given rectangle, and update the rectangle.
1159 * Many. First, just what IS a frame in Win95? Note that the 3D look
1160 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1161 * edge. The inner rectangle just inside the frame is handled by the
1164 * In short, for most people, this function should be a nop (unless
1165 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1166 * them lately, but just to get this code right). Even so, it doesn't
1167 * appear to be so. It's being worked on...
1170 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1171 * Original implementation (based on NC_DrawFrame)
1172 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1174 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1175 * Fixed a fix or something.
1177 *****************************************************************************/
1179 static void NC_DrawFrame95(
1188 /* Firstly the "thick" frame */
1189 if (style
& WS_THICKFRAME
)
1191 width
= GetSystemMetrics(SM_CXFRAME
) - GetSystemMetrics(SM_CXDLGFRAME
);
1192 height
= GetSystemMetrics(SM_CYFRAME
) - GetSystemMetrics(SM_CYDLGFRAME
);
1194 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1195 COLOR_INACTIVEBORDER
) );
1197 PatBlt( hdc
, rect
->left
, rect
->top
,
1198 rect
->right
- rect
->left
, height
, PATCOPY
);
1199 PatBlt( hdc
, rect
->left
, rect
->top
,
1200 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1201 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1202 rect
->right
- rect
->left
, -height
, PATCOPY
);
1203 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1204 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1206 InflateRect( rect
, -width
, -height
);
1209 /* Now the other bit of the frame */
1210 if ((style
& (WS_BORDER
|WS_DLGFRAME
)) ||
1211 (exStyle
& WS_EX_DLGMODALFRAME
))
1213 width
= GetSystemMetrics(SM_CXDLGFRAME
) - GetSystemMetrics(SM_CXEDGE
);
1214 height
= GetSystemMetrics(SM_CYDLGFRAME
) - GetSystemMetrics(SM_CYEDGE
);
1215 /* This should give a value of 1 that should also work for a border */
1217 SelectObject( hdc
, GetSysColorBrush(
1218 (exStyle
& (WS_EX_DLGMODALFRAME
|WS_EX_CLIENTEDGE
)) ?
1220 (exStyle
& WS_EX_STATICEDGE
) ?
1222 (style
& (WS_DLGFRAME
|WS_THICKFRAME
)) ?
1225 COLOR_WINDOWFRAME
));
1228 PatBlt( hdc
, rect
->left
, rect
->top
,
1229 rect
->right
- rect
->left
, height
, PATCOPY
);
1230 PatBlt( hdc
, rect
->left
, rect
->top
,
1231 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1232 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1233 rect
->right
- rect
->left
, -height
, PATCOPY
);
1234 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1235 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1237 InflateRect( rect
, -width
, -height
);
1242 /***********************************************************************
1245 * Draw the window caption.
1246 * The correct pen for the window frame must be selected in the DC.
1248 static void NC_DrawCaption( HDC hdc
, RECT
*rect
, HWND hwnd
,
1249 DWORD style
, BOOL active
)
1256 if (!(hbitmapClose
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_OLD_CLOSE
) ))) return;
1259 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_DLGMODALFRAME
)
1261 HBRUSH hbrushOld
= SelectObject(hdc
, GetSysColorBrush(COLOR_WINDOW
) );
1262 PatBlt( hdc
, r
.left
, r
.top
, 1, r
.bottom
-r
.top
+1,PATCOPY
);
1263 PatBlt( hdc
, r
.right
-1, r
.top
, 1, r
.bottom
-r
.top
+1, PATCOPY
);
1264 PatBlt( hdc
, r
.left
, r
.top
-1, r
.right
-r
.left
, 1, PATCOPY
);
1267 SelectObject( hdc
, hbrushOld
);
1269 MoveToEx( hdc
, r
.left
, r
.bottom
, NULL
);
1270 LineTo( hdc
, r
.right
, r
.bottom
);
1272 if (style
& WS_SYSMENU
)
1274 NC_DrawSysButton( hwnd
, hdc
, FALSE
);
1275 r
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
1276 MoveToEx( hdc
, r
.left
- 1, r
.top
, NULL
);
1277 LineTo( hdc
, r
.left
- 1, r
.bottom
);
1279 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
: COLOR_INACTIVECAPTION
) );
1280 if (style
& WS_MAXIMIZEBOX
)
1282 NC_DrawMaxButton( hwnd
, hdc
, FALSE
);
1283 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1285 if (style
& WS_MINIMIZEBOX
)
1287 NC_DrawMinButton( hwnd
, hdc
, FALSE
);
1288 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1291 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) ))
1293 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1294 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1295 SetBkMode( hdc
, TRANSPARENT
);
1296 DrawTextA( hdc
, buffer
, -1, &r
,
1297 DT_SINGLELINE
| DT_CENTER
| DT_VCENTER
| DT_NOPREFIX
);
1302 /******************************************************************************
1311 * Draw the window caption for Win95 style windows.
1312 * The correct pen for the window frame must be selected in the DC.
1315 * Hey, a function that finally works! Well, almost.
1316 * It's being worked on.
1319 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1320 * Original implementation.
1321 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1324 *****************************************************************************/
1326 static void NC_DrawCaption95(
1339 hPrevPen
= SelectObject( hdc
, SYSCOLOR_GetPen(
1340 ((exStyle
& (WS_EX_STATICEDGE
|WS_EX_CLIENTEDGE
|
1341 WS_EX_DLGMODALFRAME
)) == WS_EX_STATICEDGE
) ?
1342 COLOR_WINDOWFRAME
: COLOR_3DFACE
) );
1343 MoveToEx( hdc
, r
.left
, r
.bottom
- 1, NULL
);
1344 LineTo( hdc
, r
.right
, r
.bottom
- 1 );
1345 SelectObject( hdc
, hPrevPen
);
1348 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1349 COLOR_INACTIVECAPTION
) );
1351 if ((style
& WS_SYSMENU
) && !(exStyle
& WS_EX_TOOLWINDOW
)) {
1352 if (NC_DrawSysButton95 (hwnd
, hdc
, FALSE
))
1353 r
.left
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
1356 if (style
& WS_SYSMENU
)
1360 /* Go get the sysmenu */
1361 hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1362 state
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
);
1364 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1365 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
,
1366 ((((state
& MF_DISABLED
) || (state
& MF_GRAYED
))) && (state
!= 0xFFFFFFFF)));
1367 r
.right
-= GetSystemMetrics(SM_CYCAPTION
) - 1;
1369 if ((style
& WS_MAXIMIZEBOX
) || (style
& WS_MINIMIZEBOX
))
1371 /* In win95 the two buttons are always there */
1372 /* But if the menu item is not in the menu they're disabled*/
1374 NC_DrawMaxButton95( hwnd
, hdc
, FALSE
, (!(style
& WS_MAXIMIZEBOX
)));
1375 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1377 NC_DrawMinButton95( hwnd
, hdc
, FALSE
, (!(style
& WS_MINIMIZEBOX
)));
1378 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1382 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) )) {
1383 NONCLIENTMETRICSA nclm
;
1384 HFONT hFont
, hOldFont
;
1385 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
1386 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
1387 if (exStyle
& WS_EX_TOOLWINDOW
)
1388 hFont
= CreateFontIndirectA (&nclm
.lfSmCaptionFont
);
1390 hFont
= CreateFontIndirectA (&nclm
.lfCaptionFont
);
1391 hOldFont
= SelectObject (hdc
, hFont
);
1392 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1393 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1394 SetBkMode( hdc
, TRANSPARENT
);
1396 DrawTextA( hdc
, buffer
, -1, &r
,
1397 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
1398 DeleteObject (SelectObject (hdc
, hOldFont
));
1404 /***********************************************************************
1407 * Paint the non-client area. clip is currently unused.
1409 static void NC_DoNCPaint( HWND hwnd
, HRGN clip
, BOOL suppress_menupaint
)
1415 DWORD dwStyle
, dwExStyle
;
1417 RECT rectClient
, rectWindow
;
1420 if (!(wndPtr
= WIN_GetPtr( hwnd
)) || wndPtr
== WND_OTHER_PROCESS
) return;
1421 has_menu
= HAS_MENU(wndPtr
);
1422 dwStyle
= wndPtr
->dwStyle
;
1423 dwExStyle
= wndPtr
->dwExStyle
;
1424 flags
= wndPtr
->flags
;
1425 rectClient
= wndPtr
->rectClient
;
1426 rectWindow
= wndPtr
->rectWindow
;
1427 WIN_ReleasePtr( wndPtr
);
1429 if ( dwStyle
& WS_MINIMIZE
||
1430 !WIN_IsWindowDrawable( hwnd
, 0 )) return; /* Nothing to do */
1432 active
= flags
& WIN_NCACTIVATED
;
1434 TRACE("%p %d\n", hwnd
, active
);
1436 if (!(hdc
= GetDCEx( hwnd
, (clip
> (HRGN
)1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
1437 ((clip
> (HRGN
)1) ? (DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
): 0) ))) return;
1439 if (ExcludeVisRect16( HDC_16(hdc
), rectClient
.left
-rectWindow
.left
,
1440 rectClient
.top
-rectWindow
.top
,
1441 rectClient
.right
-rectWindow
.left
,
1442 rectClient
.bottom
-rectWindow
.top
)
1445 ReleaseDC( hwnd
, hdc
);
1449 rect
.top
= rect
.left
= 0;
1450 rect
.right
= rectWindow
.right
- rectWindow
.left
;
1451 rect
.bottom
= rectWindow
.bottom
- rectWindow
.top
;
1453 SelectObject( hdc
, SYSCOLOR_GetPen(COLOR_WINDOWFRAME
) );
1455 if (HAS_ANYFRAME( dwStyle
, dwExStyle
))
1457 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1458 Rectangle( hdc
, 0, 0, rect
.right
, rect
.bottom
);
1459 InflateRect( &rect
, -1, -1 );
1462 if (HAS_THICKFRAME( dwStyle
, dwExStyle
))
1463 NC_DrawFrame(hdc
, &rect
, FALSE
, active
);
1464 else if (HAS_DLGFRAME( dwStyle
, dwExStyle
))
1465 NC_DrawFrame( hdc
, &rect
, TRUE
, active
);
1467 if ((dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1470 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
);
1471 rect
.top
+= GetSystemMetrics(SM_CYSIZE
) + GetSystemMetrics(SM_CYBORDER
);
1472 NC_DrawCaption( hdc
, &r
, hwnd
, dwStyle
, active
);
1478 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYMENU
); /* default height */
1479 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
);
1482 /* Draw the scroll-bars */
1484 if (dwStyle
& WS_VSCROLL
)
1485 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1486 if (dwStyle
& WS_HSCROLL
)
1487 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1489 /* Draw the "size-box" */
1491 if ((dwStyle
& WS_VSCROLL
) && (dwStyle
& WS_HSCROLL
))
1494 if((dwExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
1495 r
.right
= r
.left
+ GetSystemMetrics(SM_CXVSCROLL
) + 1;
1497 r
.left
= r
.right
- GetSystemMetrics(SM_CXVSCROLL
) + 1;
1498 r
.top
= r
.bottom
- GetSystemMetrics(SM_CYHSCROLL
) + 1;
1499 if(wndPtr
->dwStyle
& WS_BORDER
) {
1503 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1506 ReleaseDC( hwnd
, hdc
);
1510 /******************************************************************************
1512 * void NC_DoNCPaint95(
1515 * BOOL suppress_menupaint )
1517 * Paint the non-client area for Win95 windows. The clip region is
1518 * currently ignored.
1521 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1522 * misc/tweak.c controls/menu.c # :-)
1525 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1526 * Original implementation
1527 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1529 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1530 * Streamlined window style checks.
1532 *****************************************************************************/
1534 static void NC_DoNCPaint95(
1537 BOOL suppress_menupaint
)
1540 RECT rfuzz
, rect
, rectClip
;
1543 DWORD dwStyle
, dwExStyle
;
1545 RECT rectClient
, rectWindow
;
1548 if (!(wndPtr
= WIN_GetPtr( hwnd
)) || wndPtr
== WND_OTHER_PROCESS
) return;
1549 has_menu
= HAS_MENU(wndPtr
);
1550 dwStyle
= wndPtr
->dwStyle
;
1551 dwExStyle
= wndPtr
->dwExStyle
;
1552 flags
= wndPtr
->flags
;
1553 rectClient
= wndPtr
->rectClient
;
1554 rectWindow
= wndPtr
->rectWindow
;
1555 WIN_ReleasePtr( wndPtr
);
1557 if ( dwStyle
& WS_MINIMIZE
||
1558 !WIN_IsWindowDrawable( hwnd
, 0 )) return; /* Nothing to do */
1560 active
= flags
& WIN_NCACTIVATED
;
1562 TRACE("%p %d\n", hwnd
, active
);
1564 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1565 the call to GetDCEx implying that it is allowed not to use it either.
1566 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1567 will cause clipRgn to be deleted after ReleaseDC().
1568 Now, how is the "system" supposed to tell what happened?
1571 if (!(hdc
= GetDCEx( hwnd
, (clip
> (HRGN
)1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
1572 ((clip
> (HRGN
)1) ?(DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
) : 0) ))) return;
1575 if (ExcludeVisRect16( HDC_16(hdc
), rectClient
.left
-rectWindow
.left
,
1576 rectClient
.top
-rectWindow
.top
,
1577 rectClient
.right
-rectWindow
.left
,
1578 rectClient
.bottom
-rectWindow
.top
)
1581 ReleaseDC( hwnd
, hdc
);
1585 rect
.top
= rect
.left
= 0;
1586 rect
.right
= rectWindow
.right
- rectWindow
.left
;
1587 rect
.bottom
= rectWindow
.bottom
- rectWindow
.top
;
1589 if( clip
> (HRGN
)1 )
1590 GetRgnBox( clip
, &rectClip
);
1597 SelectObject( hdc
, SYSCOLOR_GetPen(COLOR_WINDOWFRAME
) );
1599 if (HAS_STATICOUTERFRAME(dwStyle
, dwExStyle
)) {
1600 DrawEdge (hdc
, &rect
, BDR_SUNKENOUTER
, BF_RECT
| BF_ADJUST
);
1602 else if (HAS_BIGFRAME( dwStyle
, dwExStyle
)) {
1603 DrawEdge (hdc
, &rect
, EDGE_RAISED
, BF_RECT
| BF_ADJUST
);
1606 NC_DrawFrame95(hdc
, &rect
, active
, dwStyle
, dwExStyle
);
1608 if ((dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1611 if (dwExStyle
& WS_EX_TOOLWINDOW
) {
1612 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSMCAPTION
);
1613 rect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
);
1616 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYCAPTION
);
1617 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
);
1619 if( !clip
|| IntersectRect( &rfuzz
, &r
, &rectClip
) )
1620 NC_DrawCaption95 (hdc
, &r
, hwnd
, dwStyle
,
1627 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYMENU
);
1629 TRACE("Calling DrawMenuBar with rect (%ld, %ld)-(%ld, %ld)\n",
1630 r
.left
, r
.top
, r
.right
, r
.bottom
);
1632 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
) + 1;
1635 TRACE("After MenuBar, rect is (%ld, %ld)-(%ld, %ld).\n",
1636 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1638 if (dwExStyle
& WS_EX_CLIENTEDGE
)
1639 DrawEdge (hdc
, &rect
, EDGE_SUNKEN
, BF_RECT
| BF_ADJUST
);
1641 /* Draw the scroll-bars */
1643 if (dwStyle
& WS_VSCROLL
)
1644 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1645 if (dwStyle
& WS_HSCROLL
)
1646 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1648 /* Draw the "size-box" */
1649 if ((dwStyle
& WS_VSCROLL
) && (dwStyle
& WS_HSCROLL
))
1652 if((dwExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
1653 r
.right
= r
.left
+ GetSystemMetrics(SM_CXVSCROLL
) + 1;
1655 r
.left
= r
.right
- GetSystemMetrics(SM_CXVSCROLL
) + 1;
1656 r
.top
= r
.bottom
- GetSystemMetrics(SM_CYHSCROLL
) + 1;
1657 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1660 ReleaseDC( hwnd
, hdc
);
1666 /***********************************************************************
1669 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1671 LONG
NC_HandleNCPaint( HWND hwnd
, HRGN clip
)
1673 DWORD dwStyle
= GetWindowLongW( hwnd
, GWL_STYLE
);
1675 if( dwStyle
& WS_VISIBLE
)
1677 if( dwStyle
& WS_MINIMIZE
)
1678 WINPOS_RedrawIconTitle( hwnd
);
1679 else if (TWEAK_WineLook
== WIN31_LOOK
)
1680 NC_DoNCPaint( hwnd
, clip
, FALSE
);
1682 NC_DoNCPaint95( hwnd
, clip
, FALSE
);
1688 /***********************************************************************
1689 * NC_HandleNCActivate
1691 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1693 LONG
NC_HandleNCActivate( HWND hwnd
, WPARAM wParam
)
1695 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1697 /* Lotus Notes draws menu descriptions in the caption of its main
1698 * window. When it wants to restore original "system" view, it just
1699 * sends WM_NCACTIVATE message to itself. Any optimizations here in
1700 * attempt to minimize redrawings lead to a not restored caption.
1704 if (wParam
) wndPtr
->flags
|= WIN_NCACTIVATED
;
1705 else wndPtr
->flags
&= ~WIN_NCACTIVATED
;
1706 WIN_ReleaseWndPtr(wndPtr
);
1708 if (IsIconic(hwnd
)) WINPOS_RedrawIconTitle( hwnd
);
1709 else if (TWEAK_WineLook
== WIN31_LOOK
)
1710 NC_DoNCPaint( hwnd
, (HRGN
)1, FALSE
);
1712 NC_DoNCPaint95( hwnd
, (HRGN
)1, FALSE
);
1718 /***********************************************************************
1719 * NC_HandleSetCursor
1721 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1723 LONG
NC_HandleSetCursor( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1725 hwnd
= WIN_GetFullHandle( (HWND
)wParam
);
1727 switch(LOWORD(lParam
))
1731 WORD msg
= HIWORD( lParam
);
1732 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_MBUTTONDOWN
) ||
1733 (msg
== WM_RBUTTONDOWN
))
1740 HCURSOR hCursor
= (HCURSOR
)GetClassLongA(hwnd
, GCL_HCURSOR
);
1750 return (LONG
)SetCursor( LoadCursorA( 0, (LPSTR
)IDC_SIZEWE
) );
1754 return (LONG
)SetCursor( LoadCursorA( 0, (LPSTR
)IDC_SIZENS
) );
1758 return (LONG
)SetCursor( LoadCursorA( 0, (LPSTR
)IDC_SIZENWSE
) );
1762 return (LONG
)SetCursor( LoadCursorA( 0, (LPSTR
)IDC_SIZENESW
) );
1765 /* Default cursor: arrow */
1766 return (LONG
)SetCursor( LoadCursorA( 0, (LPSTR
)IDC_ARROW
) );
1769 /***********************************************************************
1772 void NC_GetSysPopupPos( HWND hwnd
, RECT
* rect
)
1774 if (IsIconic(hwnd
)) GetWindowRect( hwnd
, rect
);
1777 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1778 if (!wndPtr
) return;
1780 NC_GetInsideRect( hwnd
, rect
);
1781 OffsetRect( rect
, wndPtr
->rectWindow
.left
, wndPtr
->rectWindow
.top
);
1782 if (wndPtr
->dwStyle
& WS_CHILD
)
1783 ClientToScreen( GetParent(hwnd
), (POINT
*)rect
);
1784 if (TWEAK_WineLook
== WIN31_LOOK
) {
1785 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CXSIZE
);
1786 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYSIZE
);
1789 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
1790 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
1792 WIN_ReleaseWndPtr( wndPtr
);
1796 /***********************************************************************
1797 * NC_TrackMinMaxBox95
1799 * Track a mouse button press on the minimize or maximize box.
1801 * The big difference between 3.1 and 95 is the disabled button state.
1802 * In win95 the system button can be disabled, so it can ignore the mouse
1806 static void NC_TrackMinMaxBox95( HWND hwnd
, WORD wParam
)
1809 HDC hdc
= GetWindowDC( hwnd
);
1810 BOOL pressed
= TRUE
;
1812 DWORD wndStyle
= GetWindowLongA( hwnd
, GWL_STYLE
);
1813 HMENU hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1815 void (*paintButton
)(HWND
, HDC
, BOOL
, BOOL
);
1817 if (wParam
== HTMINBUTTON
)
1819 /* If the style is not present, do nothing */
1820 if (!(wndStyle
& WS_MINIMIZEBOX
))
1823 /* Check if the sysmenu item for minimize is there */
1824 state
= GetMenuState(hSysMenu
, SC_MINIMIZE
, MF_BYCOMMAND
);
1826 paintButton
= &NC_DrawMinButton95
;
1830 /* If the style is not present, do nothing */
1831 if (!(wndStyle
& WS_MAXIMIZEBOX
))
1834 /* Check if the sysmenu item for maximize is there */
1835 state
= GetMenuState(hSysMenu
, SC_MAXIMIZE
, MF_BYCOMMAND
);
1837 paintButton
= &NC_DrawMaxButton95
;
1842 (*paintButton
)( hwnd
, hdc
, TRUE
, FALSE
);
1846 BOOL oldstate
= pressed
;
1848 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1849 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1851 if(msg
.message
== WM_LBUTTONUP
)
1854 if(msg
.message
!= WM_MOUSEMOVE
)
1857 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1858 if (pressed
!= oldstate
)
1859 (*paintButton
)( hwnd
, hdc
, pressed
, FALSE
);
1863 (*paintButton
)(hwnd
, hdc
, FALSE
, FALSE
);
1866 ReleaseDC( hwnd
, hdc
);
1868 /* If the item minimize or maximize of the sysmenu are not there */
1869 /* or if the style is not present, do nothing */
1870 if ((!pressed
) || (state
== 0xFFFFFFFF))
1873 if (wParam
== HTMINBUTTON
)
1874 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1876 SendMessageA( hwnd
, WM_SYSCOMMAND
,
1877 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1880 /***********************************************************************
1883 * Track a mouse button press on the minimize or maximize box.
1885 static void NC_TrackMinMaxBox( HWND hwnd
, WORD wParam
)
1888 HDC hdc
= GetWindowDC( hwnd
);
1889 BOOL pressed
= TRUE
;
1890 void (*paintButton
)(HWND
, HDC
, BOOL
);
1894 if (wParam
== HTMINBUTTON
)
1895 paintButton
= &NC_DrawMinButton
;
1897 paintButton
= &NC_DrawMaxButton
;
1899 (*paintButton
)( hwnd
, hdc
, TRUE
);
1903 BOOL oldstate
= pressed
;
1905 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1906 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1908 if(msg
.message
== WM_LBUTTONUP
)
1911 if(msg
.message
!= WM_MOUSEMOVE
)
1914 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1915 if (pressed
!= oldstate
)
1916 (*paintButton
)( hwnd
, hdc
, pressed
);
1920 (*paintButton
)( hwnd
, hdc
, FALSE
);
1923 ReleaseDC( hwnd
, hdc
);
1925 if (!pressed
) return;
1927 if (wParam
== HTMINBUTTON
)
1928 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1930 SendMessageA( hwnd
, WM_SYSCOMMAND
,
1931 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1935 /***********************************************************************
1936 * NC_TrackCloseButton95
1938 * Track a mouse button press on the Win95 close button.
1941 NC_TrackCloseButton95 (HWND hwnd
, WORD wParam
)
1945 BOOL pressed
= TRUE
;
1946 HMENU hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1952 state
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
);
1954 /* If the item close of the sysmenu is disabled or not there do nothing */
1955 if((state
& MF_DISABLED
) || (state
& MF_GRAYED
) || (state
== 0xFFFFFFFF))
1958 hdc
= GetWindowDC( hwnd
);
1962 NC_DrawCloseButton95 (hwnd
, hdc
, TRUE
, FALSE
);
1966 BOOL oldstate
= pressed
;
1968 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1969 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1971 if(msg
.message
== WM_LBUTTONUP
)
1974 if(msg
.message
!= WM_MOUSEMOVE
)
1977 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1978 if (pressed
!= oldstate
)
1979 NC_DrawCloseButton95 (hwnd
, hdc
, pressed
, FALSE
);
1983 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
, FALSE
);
1986 ReleaseDC( hwnd
, hdc
);
1987 if (!pressed
) return;
1989 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1993 /***********************************************************************
1996 * Track a mouse button press on the horizontal or vertical scroll-bar.
1998 static void NC_TrackScrollBar( HWND hwnd
, WPARAM wParam
, POINT pt
)
2002 if ((wParam
& 0xfff0) == SC_HSCROLL
)
2004 if ((wParam
& 0x0f) != HTHSCROLL
) return;
2005 scrollbar
= SB_HORZ
;
2007 else /* SC_VSCROLL */
2009 if ((wParam
& 0x0f) != HTVSCROLL
) return;
2010 scrollbar
= SB_VERT
;
2012 SCROLL_TrackScrollBar( hwnd
, scrollbar
, pt
);
2016 /***********************************************************************
2017 * NC_HandleNCLButtonDown
2019 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2021 LONG
NC_HandleNCLButtonDown( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2023 LONG style
= GetWindowLongA( hwnd
, GWL_STYLE
);
2025 switch(wParam
) /* Hit test */
2029 HWND top
= GetAncestor( hwnd
, GA_ROOT
);
2031 if (FOCUS_MouseActivate( top
) || (GetActiveWindow() == top
))
2032 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOVE
+ HTCAPTION
, lParam
);
2037 if( style
& WS_SYSMENU
)
2039 if( !(style
& WS_MINIMIZE
) )
2041 HDC hDC
= GetWindowDC(hwnd
);
2042 if (TWEAK_WineLook
== WIN31_LOOK
)
2043 NC_DrawSysButton( hwnd
, hDC
, TRUE
);
2045 NC_DrawSysButton95( hwnd
, hDC
, TRUE
);
2046 ReleaseDC( hwnd
, hDC
);
2048 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
+ HTSYSMENU
, lParam
);
2053 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
, lParam
);
2057 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
2061 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
2066 if (TWEAK_WineLook
== WIN31_LOOK
)
2067 NC_TrackMinMaxBox( hwnd
, wParam
);
2069 NC_TrackMinMaxBox95( hwnd
, wParam
);
2073 if (TWEAK_WineLook
>= WIN95_LOOK
)
2074 NC_TrackCloseButton95 (hwnd
, wParam
);
2086 * "make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU"
2087 * This was previously done by setting wParam=SC_SIZE + wParam - 2
2089 /* But that is not what WinNT does. Instead it sends this. This
2090 * is easy to differentiate from HTSYSMENU, because HTSYSMENU adds
2091 * SC_MOUSEMENU into wParam.
2093 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_SIZE
+ wParam
- (HTLEFT
-WMSZ_LEFT
), lParam
);
2103 /***********************************************************************
2104 * NC_HandleNCLButtonDblClk
2106 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2108 LONG
NC_HandleNCLButtonDblClk( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2111 * if this is an icon, send a restore since we are handling
2116 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_RESTORE
, lParam
);
2120 switch(wParam
) /* Hit test */
2123 /* stop processing if WS_MAXIMIZEBOX is missing */
2124 if (GetWindowLongA( hwnd
, GWL_STYLE
) & WS_MAXIMIZEBOX
)
2125 SendMessageW( hwnd
, WM_SYSCOMMAND
,
2126 IsZoomed(hwnd
) ? SC_RESTORE
: SC_MAXIMIZE
, lParam
);
2130 if (!(GetClassLongW(hwnd
, GCL_STYLE
) & CS_NOCLOSE
))
2131 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, lParam
);
2135 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
2139 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
2146 /***********************************************************************
2147 * NC_HandleSysCommand
2149 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2151 LONG
NC_HandleSysCommand( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2153 TRACE("Handling WM_SYSCOMMAND %x %lx\n", wParam
, lParam
);
2155 switch (wParam
& 0xfff0)
2159 if (USER_Driver
.pSysCommandSizeMove
)
2160 USER_Driver
.pSysCommandSizeMove( hwnd
, wParam
);
2164 if (hwnd
== GetForegroundWindow())
2165 ShowOwnedPopups(hwnd
,FALSE
);
2166 ShowWindow( hwnd
, SW_MINIMIZE
);
2170 if (IsIconic(hwnd
) && hwnd
== GetForegroundWindow())
2171 ShowOwnedPopups(hwnd
,TRUE
);
2172 ShowWindow( hwnd
, SW_MAXIMIZE
);
2176 if (IsIconic(hwnd
) && hwnd
== GetForegroundWindow())
2177 ShowOwnedPopups(hwnd
,TRUE
);
2178 ShowWindow( hwnd
, SW_RESTORE
);
2182 return SendMessageA( hwnd
, WM_CLOSE
, 0, 0 );
2188 pt
.x
= (short)LOWORD(lParam
);
2189 pt
.y
= (short)HIWORD(lParam
);
2190 NC_TrackScrollBar( hwnd
, wParam
, pt
);
2197 pt
.x
= (short)LOWORD(lParam
);
2198 pt
.y
= (short)HIWORD(lParam
);
2199 MENU_TrackMouseMenuBar( hwnd
, wParam
& 0x000F, pt
);
2204 MENU_TrackKbdMenuBar( hwnd
, wParam
, (WCHAR
)lParam
);
2208 WinExec( "taskman.exe", SW_SHOWNORMAL
);
2212 if (wParam
== SC_ABOUTWINE
)
2214 HMODULE hmodule
= LoadLibraryA( "shell32.dll" );
2217 FARPROC aboutproc
= GetProcAddress( hmodule
, "ShellAboutA" );
2218 if (aboutproc
) aboutproc( hwnd
, PACKAGE_NAME
, PACKAGE_STRING
, 0 );
2219 FreeLibrary( hmodule
);
2223 if (wParam
== SC_PUTMARK
)
2224 DPRINTF("Debug mark requested by user\n");
2231 FIXME("unimplemented!\n");
2237 /*************************************************************
2240 * Stub for the grayed button of the caption
2242 *************************************************************/
2244 BOOL
NC_DrawGrayButton(HDC hdc
, int x
, int y
)
2250 hMaskBmp
= CreateBitmap (12, 10, 1, 1, lpGrayMask
);
2255 hdcMask
= CreateCompatibleDC (0);
2256 SelectObject (hdcMask
, hMaskBmp
);
2258 /* Draw the grayed bitmap using the mask */
2259 hOldBrush
= SelectObject (hdc
, (HGDIOBJ
)RGB(128, 128, 128));
2260 BitBlt (hdc
, x
, y
, 12, 10,
2261 hdcMask
, 0, 0, 0xB8074A);
2264 SelectObject (hdc
, hOldBrush
);
2265 DeleteObject(hMaskBmp
);
2271 /***********************************************************************
2272 * GetTitleBarInfo (USER32.@)
2273 * TODO: Handle STATE_SYSTEM_PRESSED
2275 BOOL WINAPI
GetTitleBarInfo(HWND hwnd
, PTITLEBARINFO tbi
) {
2280 TRACE("(%p %p)\n", hwnd
, tbi
);
2282 if(tbi
->cbSize
!= sizeof(TITLEBARINFO
)) {
2283 TRACE("Invalid TITLEBARINFO size: %ld\n", tbi
->cbSize
);
2284 SetLastError(ERROR_INVALID_PARAMETER
);
2287 dwStyle
= GetWindowLongW(hwnd
, GWL_STYLE
);
2288 dwExStyle
= GetWindowLongW(hwnd
, GWL_EXSTYLE
);
2289 NC_GetInsideRect(hwnd
, &tbi
->rcTitleBar
);
2291 GetWindowRect(hwnd
, &wndRect
);
2293 tbi
->rcTitleBar
.top
+= wndRect
.top
;
2294 tbi
->rcTitleBar
.left
+= wndRect
.left
;
2295 tbi
->rcTitleBar
.right
+= wndRect
.left
;
2297 tbi
->rcTitleBar
.bottom
= tbi
->rcTitleBar
.top
;
2298 if(dwExStyle
& WS_EX_TOOLWINDOW
)
2299 tbi
->rcTitleBar
.bottom
+= GetSystemMetrics(SM_CYSMCAPTION
);
2301 tbi
->rcTitleBar
.bottom
+= GetSystemMetrics(SM_CYCAPTION
);
2302 tbi
->rcTitleBar
.left
+= GetSystemMetrics(SM_CXSIZE
);
2305 ZeroMemory(&tbi
->rgstate
, sizeof(tbi
->rgstate
));
2306 /* Does the title bar always have STATE_SYSTEM_FOCUSABLE?
2307 * Under XP it seems to
2309 tbi
->rgstate
[0] = STATE_SYSTEM_FOCUSABLE
;
2310 if(dwStyle
& WS_CAPTION
) {
2311 tbi
->rgstate
[1] = STATE_SYSTEM_INVISIBLE
;
2312 if(dwStyle
& WS_SYSMENU
) {
2313 if(!(dwStyle
& (WS_MINIMIZEBOX
|WS_MAXIMIZEBOX
))) {
2314 tbi
->rgstate
[2] = STATE_SYSTEM_INVISIBLE
;
2315 tbi
->rgstate
[3] = STATE_SYSTEM_INVISIBLE
;
2318 if(!(dwStyle
& WS_MINIMIZEBOX
))
2319 tbi
->rgstate
[2] = STATE_SYSTEM_UNAVAILABLE
;
2320 if(!(dwStyle
& WS_MAXIMIZEBOX
))
2321 tbi
->rgstate
[3] = STATE_SYSTEM_UNAVAILABLE
;
2323 if(!(dwExStyle
& WS_EX_CONTEXTHELP
))
2324 tbi
->rgstate
[4] = STATE_SYSTEM_INVISIBLE
;
2325 if(GetClassLongW(hwnd
, GCL_STYLE
) & CS_NOCLOSE
)
2326 tbi
->rgstate
[5] = STATE_SYSTEM_UNAVAILABLE
;
2329 tbi
->rgstate
[2] = STATE_SYSTEM_INVISIBLE
;
2330 tbi
->rgstate
[3] = STATE_SYSTEM_INVISIBLE
;
2331 tbi
->rgstate
[4] = STATE_SYSTEM_INVISIBLE
;
2332 tbi
->rgstate
[5] = STATE_SYSTEM_INVISIBLE
;
2336 tbi
->rgstate
[0] |= STATE_SYSTEM_INVISIBLE
;