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
25 #include "wine/winuser16.h"
30 #include "cursoricon.h"
33 #include "nonclient.h"
34 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(nonclient
);
39 WINE_DECLARE_DEBUG_CHANNEL(shell
);
41 BOOL
NC_DrawGrayButton(HDC hdc
, int x
, int y
);
43 static HBITMAP hbitmapClose
;
45 static const BYTE lpGrayMask
[] = { 0xAA, 0xA0,
56 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
57 #define SC_PUTMARK (SC_SCREENSAVE+2)
59 /* Some useful macros */
60 #define HAS_DLGFRAME(style,exStyle) \
61 (((exStyle) & WS_EX_DLGMODALFRAME) || \
62 (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
64 #define HAS_THICKFRAME(style,exStyle) \
65 (((style) & WS_THICKFRAME) && \
66 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
68 #define HAS_THINFRAME(style) \
69 (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
71 #define HAS_BIGFRAME(style,exStyle) \
72 (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
73 ((exStyle) & WS_EX_DLGMODALFRAME))
75 #define HAS_STATICOUTERFRAME(style,exStyle) \
76 (((exStyle) & (WS_EX_STATICEDGE|WS_EX_DLGMODALFRAME)) == \
79 #define HAS_ANYFRAME(style,exStyle) \
80 (((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
81 ((exStyle) & WS_EX_DLGMODALFRAME) || \
82 !((style) & (WS_CHILD | WS_POPUP)))
84 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
87 /***********************************************************************
90 * Compute the size of the window rectangle from the size of the
93 static void NC_AdjustRect( LPRECT rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
95 if (TWEAK_WineLook
> WIN31_LOOK
)
96 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
98 if(style
& WS_ICONIC
) return;
100 if (HAS_THICKFRAME( style
, exStyle
))
101 InflateRect( rect
, GetSystemMetrics(SM_CXFRAME
), GetSystemMetrics(SM_CYFRAME
) );
102 else if (HAS_DLGFRAME( style
, exStyle
))
103 InflateRect( rect
, GetSystemMetrics(SM_CXDLGFRAME
), GetSystemMetrics(SM_CYDLGFRAME
) );
104 else if (HAS_THINFRAME( style
))
105 InflateRect( rect
, GetSystemMetrics(SM_CXBORDER
), GetSystemMetrics(SM_CYBORDER
));
107 if ((style
& WS_CAPTION
) == WS_CAPTION
)
108 rect
->top
-= GetSystemMetrics(SM_CYCAPTION
) - GetSystemMetrics(SM_CYBORDER
);
110 if (menu
) rect
->top
-= GetSystemMetrics(SM_CYMENU
) + GetSystemMetrics(SM_CYBORDER
);
112 if (style
& WS_VSCROLL
) {
113 rect
->right
+= GetSystemMetrics(SM_CXVSCROLL
) - 1;
114 if(!HAS_ANYFRAME( style
, exStyle
))
118 if (style
& WS_HSCROLL
) {
119 rect
->bottom
+= GetSystemMetrics(SM_CYHSCROLL
) - 1;
120 if(!HAS_ANYFRAME( style
, exStyle
))
126 /******************************************************************************
127 * NC_AdjustRectOuter95
129 * Computes the size of the "outside" parts of the window based on the
130 * parameters of the client area.
139 * "Outer" parts of a window means the whole window frame, caption and
140 * menu bar. It does not include "inner" parts of the frame like client
141 * edge, static edge or scroll bars.
144 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
145 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
147 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
148 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
149 * NC_AdjustRectInner95 and added handling of Win95 styles.
151 * 28-Jul-1999 Ove Kåven (ovek@arcticnet.no)
152 * Streamlined window style checks.
154 *****************************************************************************/
157 NC_AdjustRectOuter95 (LPRECT rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
160 if(style
& WS_ICONIC
) return;
162 if ((exStyle
& (WS_EX_STATICEDGE
|WS_EX_DLGMODALFRAME
)) ==
165 adjust
= 1; /* for the outer frame always present */
170 if ((exStyle
& WS_EX_DLGMODALFRAME
) ||
171 (style
& (WS_THICKFRAME
|WS_DLGFRAME
))) adjust
= 2; /* outer */
173 if (style
& WS_THICKFRAME
)
174 adjust
+= ( GetSystemMetrics (SM_CXFRAME
)
175 - GetSystemMetrics (SM_CXDLGFRAME
)); /* The resize border */
176 if ((style
& (WS_BORDER
|WS_DLGFRAME
)) ||
177 (exStyle
& WS_EX_DLGMODALFRAME
))
178 adjust
++; /* The other border */
180 InflateRect (rect
, adjust
, adjust
);
182 if ((style
& WS_CAPTION
) == WS_CAPTION
)
184 if (exStyle
& WS_EX_TOOLWINDOW
)
185 rect
->top
-= GetSystemMetrics(SM_CYSMCAPTION
);
187 rect
->top
-= GetSystemMetrics(SM_CYCAPTION
);
189 if (menu
) rect
->top
-= GetSystemMetrics(SM_CYMENU
);
193 /******************************************************************************
194 * NC_AdjustRectInner95
196 * Computes the size of the "inside" part of the window based on the
197 * parameters of the client area.
205 * "Inner" part of a window means the window frame inside of the flat
206 * window frame. It includes the client edge, the static edge and the
210 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
211 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
213 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
214 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
215 * NC_AdjustRectInner95 and added handling of Win95 styles.
217 *****************************************************************************/
220 NC_AdjustRectInner95 (LPRECT rect
, DWORD style
, DWORD exStyle
)
222 if(style
& WS_ICONIC
) return;
224 if (exStyle
& WS_EX_CLIENTEDGE
)
225 InflateRect(rect
, GetSystemMetrics(SM_CXEDGE
), GetSystemMetrics(SM_CYEDGE
));
227 if (style
& WS_VSCROLL
) rect
->right
+= GetSystemMetrics(SM_CXVSCROLL
);
228 if (style
& WS_HSCROLL
) rect
->bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
233 static HICON
NC_IconForWindow( HWND hwnd
)
235 HICON hIcon
= (HICON
) GetClassLongA( hwnd
, GCL_HICONSM
);
236 if (!hIcon
) hIcon
= (HICON
) GetClassLongA( hwnd
, GCL_HICON
);
238 /* If there is no hIcon specified and this is a modal dialog,
239 * get the default one.
241 if (!hIcon
&& (GetWindowLongA( hwnd
, GWL_STYLE
) & DS_MODALFRAME
))
242 hIcon
= LoadImageA(0, IDI_WINLOGOA
, IMAGE_ICON
, 0, 0, LR_DEFAULTCOLOR
);
246 /***********************************************************************
247 * DrawCaption (USER32.@) Draws a caption bar
261 DrawCaption (HWND hwnd
, HDC hdc
, const RECT
*lpRect
, UINT uFlags
)
263 return DrawCaptionTempA (hwnd
, hdc
, lpRect
, 0, 0, NULL
, uFlags
& 0x1F);
267 /***********************************************************************
268 * DrawCaptionTempA (USER32.@)
270 BOOL WINAPI
DrawCaptionTempA (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
271 HICON hIcon
, LPCSTR str
, UINT uFlags
)
277 if (!(uFlags
& DC_TEXT
) || !str
)
278 return DrawCaptionTempW( hwnd
, hdc
, rect
, hFont
, hIcon
, NULL
, uFlags
);
280 len
= MultiByteToWideChar( CP_ACP
, 0, str
, -1, NULL
, 0 );
281 if ((strW
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) )))
283 MultiByteToWideChar( CP_ACP
, 0, str
, -1, strW
, len
);
284 ret
= DrawCaptionTempW (hwnd
, hdc
, rect
, hFont
, hIcon
, strW
, uFlags
);
285 HeapFree( GetProcessHeap (), 0, strW
);
291 /***********************************************************************
292 * DrawCaptionTempW (USER32.@)
294 BOOL WINAPI
DrawCaptionTempW (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
295 HICON hIcon
, LPCWSTR str
, UINT uFlags
)
299 TRACE("(%08x,%08x,%p,%08x,%08x,%s,%08x)\n",
300 hwnd
, hdc
, rect
, hFont
, hIcon
, debugstr_w(str
), uFlags
);
302 /* drawing background */
303 if (uFlags
& DC_INBUTTON
) {
304 FillRect (hdc
, &rc
, GetSysColorBrush (COLOR_3DFACE
));
306 if (uFlags
& DC_ACTIVE
) {
307 HBRUSH hbr
= SelectObject (hdc
, CACHE_GetPattern55AABrush ());
308 PatBlt (hdc
, rc
.left
, rc
.top
,
309 rc
.right
-rc
.left
, rc
.bottom
-rc
.top
, 0xFA0089);
310 SelectObject (hdc
, hbr
);
314 FillRect (hdc
, &rc
, GetSysColorBrush ((uFlags
& DC_ACTIVE
) ?
315 COLOR_ACTIVECAPTION
: COLOR_INACTIVECAPTION
));
320 if ((uFlags
& DC_ICON
) && !(uFlags
& DC_SMALLCAP
)) {
324 pt
.y
= (rc
.bottom
+ rc
.top
- GetSystemMetrics(SM_CYSMICON
)) / 2;
326 if (!hIcon
) hIcon
= NC_IconForWindow(hwnd
);
327 DrawIconEx (hdc
, pt
.x
, pt
.y
, hIcon
, GetSystemMetrics(SM_CXSMICON
),
328 GetSystemMetrics(SM_CYSMICON
), 0, 0, DI_NORMAL
);
329 rc
.left
+= (rc
.bottom
- rc
.top
);
333 if (uFlags
& DC_TEXT
) {
336 if (uFlags
& DC_INBUTTON
)
337 SetTextColor (hdc
, GetSysColor (COLOR_BTNTEXT
));
338 else if (uFlags
& DC_ACTIVE
)
339 SetTextColor (hdc
, GetSysColor (COLOR_CAPTIONTEXT
));
341 SetTextColor (hdc
, GetSysColor (COLOR_INACTIVECAPTIONTEXT
));
343 SetBkMode (hdc
, TRANSPARENT
);
346 hOldFont
= SelectObject (hdc
, hFont
);
348 NONCLIENTMETRICSA nclm
;
350 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
351 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
352 hNewFont
= CreateFontIndirectA ((uFlags
& DC_SMALLCAP
) ?
353 &nclm
.lfSmCaptionFont
: &nclm
.lfCaptionFont
);
354 hOldFont
= SelectObject (hdc
, hNewFont
);
358 DrawTextW (hdc
, str
, -1, &rc
,
359 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
363 nLen
= GetWindowTextW (hwnd
, szText
, 128);
364 DrawTextW (hdc
, szText
, nLen
, &rc
,
365 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
369 SelectObject (hdc
, hOldFont
);
371 DeleteObject (SelectObject (hdc
, hOldFont
));
374 /* drawing focus ??? */
376 FIXME("undocumented flag (0x2000)!\n");
382 /***********************************************************************
383 * AdjustWindowRect (USER.102)
385 BOOL16 WINAPI
AdjustWindowRect16( LPRECT16 rect
, DWORD style
, BOOL16 menu
)
387 return AdjustWindowRectEx16( rect
, style
, menu
, 0 );
391 /***********************************************************************
392 * AdjustWindowRect (USER32.@)
394 BOOL WINAPI
AdjustWindowRect( LPRECT rect
, DWORD style
, BOOL menu
)
396 return AdjustWindowRectEx( rect
, style
, menu
, 0 );
400 /***********************************************************************
401 * AdjustWindowRectEx (USER.454)
403 BOOL16 WINAPI
AdjustWindowRectEx16( LPRECT16 rect
, DWORD style
,
404 BOOL16 menu
, DWORD exStyle
)
409 CONV_RECT16TO32( rect
, &rect32
);
410 ret
= AdjustWindowRectEx( &rect32
, style
, menu
, exStyle
);
411 CONV_RECT32TO16( &rect32
, rect
);
416 /***********************************************************************
417 * AdjustWindowRectEx (USER32.@)
419 BOOL WINAPI
AdjustWindowRectEx( LPRECT rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
421 /* Correct the window style */
422 style
&= (WS_DLGFRAME
| WS_BORDER
| WS_THICKFRAME
| WS_CHILD
);
423 exStyle
&= (WS_EX_DLGMODALFRAME
| WS_EX_CLIENTEDGE
|
424 WS_EX_STATICEDGE
| WS_EX_TOOLWINDOW
);
425 if (exStyle
& WS_EX_DLGMODALFRAME
) style
&= ~WS_THICKFRAME
;
427 TRACE("(%d,%d)-(%d,%d) %08lx %d %08lx\n",
428 rect
->left
, rect
->top
, rect
->right
, rect
->bottom
,
429 style
, menu
, exStyle
);
431 if (TWEAK_WineLook
== WIN31_LOOK
)
432 NC_AdjustRect( rect
, style
, menu
, exStyle
);
435 NC_AdjustRectOuter95( rect
, style
, menu
, exStyle
);
436 NC_AdjustRectInner95( rect
, style
, exStyle
);
442 /***********************************************************************
443 * NC_HandleNCCalcSize
445 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
447 LONG
NC_HandleNCCalcSize( HWND hwnd
, RECT
*winRect
)
449 RECT tmpRect
= { 0, 0, 0, 0 };
451 LONG cls_style
= GetClassLongA(hwnd
, GCL_STYLE
);
452 LONG style
= GetWindowLongA( hwnd
, GWL_STYLE
);
453 LONG exStyle
= GetWindowLongA( hwnd
, GWL_EXSTYLE
);
455 if (cls_style
& CS_VREDRAW
) result
|= WVR_VREDRAW
;
456 if (cls_style
& CS_HREDRAW
) result
|= WVR_HREDRAW
;
460 if (TWEAK_WineLook
== WIN31_LOOK
)
461 NC_AdjustRect( &tmpRect
, style
, FALSE
, exStyle
);
463 NC_AdjustRectOuter95( &tmpRect
, style
, FALSE
, exStyle
);
465 winRect
->left
-= tmpRect
.left
;
466 winRect
->top
-= tmpRect
.top
;
467 winRect
->right
-= tmpRect
.right
;
468 winRect
->bottom
-= tmpRect
.bottom
;
470 if (!(style
& WS_CHILD
) && GetMenu(hwnd
))
472 TRACE("Calling GetMenuBarHeight with HWND 0x%x, width %d, "
473 "at (%d, %d).\n", hwnd
,
474 winRect
->right
- winRect
->left
,
475 -tmpRect
.left
, -tmpRect
.top
);
478 MENU_GetMenuBarHeight( hwnd
,
479 winRect
->right
- winRect
->left
,
480 -tmpRect
.left
, -tmpRect
.top
) + 1;
483 if (TWEAK_WineLook
> WIN31_LOOK
) {
484 SetRect(&tmpRect
, 0, 0, 0, 0);
485 NC_AdjustRectInner95 (&tmpRect
, style
, exStyle
);
486 winRect
->left
-= tmpRect
.left
;
487 winRect
->top
-= tmpRect
.top
;
488 winRect
->right
-= tmpRect
.right
;
489 winRect
->bottom
-= tmpRect
.bottom
;
492 if (winRect
->top
> winRect
->bottom
)
493 winRect
->bottom
= winRect
->top
;
495 if (winRect
->left
> winRect
->right
)
496 winRect
->right
= winRect
->left
;
502 /***********************************************************************
505 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
506 * but without the borders (if any).
507 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
509 void NC_GetInsideRect( HWND hwnd
, RECT
*rect
)
511 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
513 rect
->top
= rect
->left
= 0;
514 rect
->right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
515 rect
->bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
517 if (wndPtr
->dwStyle
& WS_ICONIC
) goto END
;
519 /* Remove frame from rectangle */
520 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
522 InflateRect( rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
524 else if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
526 InflateRect( rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
527 /* FIXME: this isn't in NC_AdjustRect? why not? */
528 if ((TWEAK_WineLook
== WIN31_LOOK
) && (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
))
529 InflateRect( rect
, -1, 0 );
531 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
533 InflateRect( rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
) );
536 /* We have additional border information if the window
537 * is a child (but not an MDI child) */
538 if (TWEAK_WineLook
!= WIN31_LOOK
)
540 if ( (wndPtr
->dwStyle
& WS_CHILD
) &&
541 ( (wndPtr
->dwExStyle
& WS_EX_MDICHILD
) == 0 ) )
543 if (wndPtr
->dwExStyle
& WS_EX_CLIENTEDGE
)
544 InflateRect (rect
, -GetSystemMetrics(SM_CXEDGE
), -GetSystemMetrics(SM_CYEDGE
));
545 if (wndPtr
->dwExStyle
& WS_EX_STATICEDGE
)
546 InflateRect (rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
551 WIN_ReleaseWndPtr(wndPtr
);
556 /***********************************************************************
559 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
562 static LONG
NC_DoNCHitTest (WND
*wndPtr
, POINT pt
)
566 TRACE("hwnd=%04x pt=%ld,%ld\n", wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
568 GetWindowRect(wndPtr
->hwndSelf
, &rect
);
569 if (!PtInRect( &rect
, pt
)) return HTNOWHERE
;
571 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
574 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
576 InflateRect( &rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
577 if (!PtInRect( &rect
, pt
))
579 /* Check top sizing border */
582 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
583 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
586 /* Check bottom sizing border */
587 if (pt
.y
>= rect
.bottom
)
589 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
590 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
593 /* Check left sizing border */
594 if (pt
.x
< rect
.left
)
596 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
597 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
600 /* Check right sizing border */
601 if (pt
.x
>= rect
.right
)
603 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
604 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
609 else /* No thick frame */
611 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
612 InflateRect(&rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
613 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
614 InflateRect(&rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
615 if (!PtInRect( &rect
, pt
)) return HTBORDER
;
620 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
622 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
) - GetSystemMetrics(SM_CYBORDER
);
623 if (!PtInRect( &rect
, pt
))
625 /* Check system menu */
626 if ((wndPtr
->dwStyle
& WS_SYSMENU
) && !(wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
))
627 rect
.left
+= GetSystemMetrics(SM_CXSIZE
);
628 if (pt
.x
<= rect
.left
) return HTSYSMENU
;
630 /* Check maximize box */
631 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
632 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
634 if (pt
.x
>= rect
.right
) return HTMAXBUTTON
;
635 /* Check minimize box */
636 if (wndPtr
->dwStyle
& WS_MINIMIZEBOX
)
637 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
638 if (pt
.x
>= rect
.right
) return HTMINBUTTON
;
643 /* Check client area */
645 ScreenToClient( wndPtr
->hwndSelf
, &pt
);
646 GetClientRect( wndPtr
->hwndSelf
, &rect
);
647 if (PtInRect( &rect
, pt
)) return HTCLIENT
;
649 /* Check vertical scroll bar */
651 if (wndPtr
->dwStyle
& WS_VSCROLL
)
653 rect
.right
+= GetSystemMetrics(SM_CXVSCROLL
);
654 if (PtInRect( &rect
, pt
)) return HTVSCROLL
;
657 /* Check horizontal scroll bar */
659 if (wndPtr
->dwStyle
& WS_HSCROLL
)
661 rect
.bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
662 if (PtInRect( &rect
, pt
))
665 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
666 (pt
.x
>= rect
.right
- GetSystemMetrics(SM_CXVSCROLL
)))
674 if (HAS_MENU(wndPtr
))
676 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
680 /* Has to return HTNOWHERE if nothing was found
681 Could happen when a window has a customized non client area */
686 /***********************************************************************
689 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
691 * FIXME: Just a modified copy of the Win 3.1 version.
694 static LONG
NC_DoNCHitTest95 (WND
*wndPtr
, POINT pt
)
698 TRACE("hwnd=%04x pt=%ld,%ld\n", wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
700 GetWindowRect(wndPtr
->hwndSelf
, &rect
);
701 if (!PtInRect( &rect
, pt
)) return HTNOWHERE
;
703 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
706 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
708 InflateRect( &rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
709 if (!PtInRect( &rect
, pt
))
711 /* Check top sizing border */
714 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
715 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
718 /* Check bottom sizing border */
719 if (pt
.y
>= rect
.bottom
)
721 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
722 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
725 /* Check left sizing border */
726 if (pt
.x
< rect
.left
)
728 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
729 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
732 /* Check right sizing border */
733 if (pt
.x
>= rect
.right
)
735 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
736 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
741 else /* No thick frame */
743 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
744 InflateRect(&rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
745 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
746 InflateRect(&rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
747 if (!PtInRect( &rect
, pt
)) return HTBORDER
;
752 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
754 if (wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
)
755 rect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
) - 1;
757 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
758 if (!PtInRect( &rect
, pt
))
760 /* Check system menu */
761 if ((wndPtr
->dwStyle
& WS_SYSMENU
) && !(wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
))
763 if (NC_IconForWindow(wndPtr
->hwndSelf
))
764 rect
.left
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
766 if (pt
.x
< rect
.left
) return HTSYSMENU
;
768 /* Check close button */
769 if (wndPtr
->dwStyle
& WS_SYSMENU
)
770 rect
.right
-= GetSystemMetrics(SM_CYCAPTION
) - 1;
771 if (pt
.x
> rect
.right
) return HTCLOSE
;
773 /* Check maximize box */
774 /* In win95 there is automatically a Maximize button when there is a minimize one*/
775 if ((wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)|| (wndPtr
->dwStyle
& WS_MINIMIZEBOX
))
776 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
777 if (pt
.x
> rect
.right
) return HTMAXBUTTON
;
779 /* Check minimize box */
780 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
781 if ((wndPtr
->dwStyle
& WS_MINIMIZEBOX
)||(wndPtr
->dwStyle
& WS_MAXIMIZEBOX
))
782 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
784 if (pt
.x
> rect
.right
) return HTMINBUTTON
;
789 /* Check client area */
791 ScreenToClient( wndPtr
->hwndSelf
, &pt
);
792 GetClientRect( wndPtr
->hwndSelf
, &rect
);
793 if (PtInRect( &rect
, pt
)) return HTCLIENT
;
795 /* Check vertical scroll bar */
797 if (wndPtr
->dwStyle
& WS_VSCROLL
)
799 rect
.right
+= GetSystemMetrics(SM_CXVSCROLL
);
800 if (PtInRect( &rect
, pt
)) return HTVSCROLL
;
803 /* Check horizontal scroll bar */
805 if (wndPtr
->dwStyle
& WS_HSCROLL
)
807 rect
.bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
808 if (PtInRect( &rect
, pt
))
811 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
812 (pt
.x
>= rect
.right
- GetSystemMetrics(SM_CXVSCROLL
)))
820 if (HAS_MENU(wndPtr
))
822 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
826 /* Has to return HTNOWHERE if nothing was found
827 Could happen when a window has a customized non client area */
832 /***********************************************************************
835 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
837 LONG
NC_HandleNCHitTest (HWND hwnd
, POINT pt
)
840 WND
*wndPtr
= WIN_FindWndPtr (hwnd
);
845 if (TWEAK_WineLook
== WIN31_LOOK
)
846 retvalue
= NC_DoNCHitTest (wndPtr
, pt
);
848 retvalue
= NC_DoNCHitTest95 (wndPtr
, pt
);
849 WIN_ReleaseWndPtr(wndPtr
);
854 /***********************************************************************
857 void NC_DrawSysButton( HWND hwnd
, HDC hdc
, BOOL down
)
863 NC_GetInsideRect( hwnd
, &rect
);
864 hdcMem
= CreateCompatibleDC( hdc
);
865 hbitmap
= SelectObject( hdcMem
, hbitmapClose
);
866 BitBlt(hdc
, rect
.left
, rect
.top
, GetSystemMetrics(SM_CXSIZE
), GetSystemMetrics(SM_CYSIZE
),
867 hdcMem
, (GetWindowLongA(hwnd
,GWL_STYLE
) & WS_CHILD
) ? GetSystemMetrics(SM_CXSIZE
) : 0, 0,
868 down
? NOTSRCCOPY
: SRCCOPY
);
869 SelectObject( hdcMem
, hbitmap
);
874 /***********************************************************************
877 static void NC_DrawMaxButton( HWND hwnd
, HDC16 hdc
, BOOL down
)
880 UINT flags
= IsZoomed(hwnd
) ? DFCS_CAPTIONRESTORE
: DFCS_CAPTIONMAX
;
882 NC_GetInsideRect( hwnd
, &rect
);
883 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
) + 1;
884 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
887 if (down
) flags
|= DFCS_PUSHED
;
888 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
892 /***********************************************************************
895 static void NC_DrawMinButton( HWND hwnd
, HDC16 hdc
, BOOL down
)
898 UINT flags
= DFCS_CAPTIONMIN
;
899 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
901 NC_GetInsideRect( hwnd
, &rect
);
902 if (style
& (WS_MAXIMIZEBOX
|WS_MINIMIZEBOX
))
903 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) - 2;
904 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
) + 1;
905 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
908 if (down
) flags
|= DFCS_PUSHED
;
909 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
913 /******************************************************************************
915 * void NC_DrawSysButton95(
920 * Draws the Win95 system icon.
923 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
924 * Original implementation from NC_DrawSysButton source.
925 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
928 *****************************************************************************/
931 NC_DrawSysButton95 (HWND hwnd
, HDC hdc
, BOOL down
)
933 HICON hIcon
= NC_IconForWindow( hwnd
);
938 NC_GetInsideRect( hwnd
, &rect
);
939 DrawIconEx (hdc
, rect
.left
+ 2, rect
.top
+ 2, hIcon
,
940 GetSystemMetrics(SM_CXSMICON
),
941 GetSystemMetrics(SM_CYSMICON
), 0, 0, DI_NORMAL
);
947 /******************************************************************************
949 * void NC_DrawCloseButton95(
955 * Draws the Win95 close button.
957 * If bGrayed is true, then draw a disabled Close button
960 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
961 * Original implementation from NC_DrawSysButton95 source.
963 *****************************************************************************/
965 static void NC_DrawCloseButton95 (HWND hwnd
, HDC hdc
, BOOL down
, BOOL bGrayed
)
969 NC_GetInsideRect( hwnd
, &rect
);
971 /* A tool window has a smaller Close button */
972 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_TOOLWINDOW
)
974 INT iBmpHeight
= 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
975 INT iBmpWidth
= 11; /* it uses 11x11 for the close button in tool window */
976 INT iCaptionHeight
= GetSystemMetrics(SM_CYSMCAPTION
);
978 rect
.top
= rect
.top
+ (iCaptionHeight
- 1 - iBmpHeight
) / 2;
979 rect
.left
= rect
.right
- (iCaptionHeight
+ 1 + iBmpWidth
) / 2;
980 rect
.bottom
= rect
.top
+ iBmpHeight
;
981 rect
.right
= rect
.left
+ iBmpWidth
;
985 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
) - 1;
986 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
990 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
,
992 (down
? DFCS_PUSHED
: 0) |
993 (bGrayed
? DFCS_INACTIVE
: 0)) );
996 /******************************************************************************
999 * Draws the maximize button for Win95 style windows.
1000 * If bGrayed is true, then draw a disabled Maximize button
1002 static void NC_DrawMaxButton95(HWND hwnd
,HDC16 hdc
,BOOL down
, BOOL bGrayed
)
1005 UINT flags
= IsZoomed(hwnd
) ? DFCS_CAPTIONRESTORE
: DFCS_CAPTIONMAX
;
1007 NC_GetInsideRect( hwnd
, &rect
);
1008 if (GetWindowLongA( hwnd
, GWL_STYLE
) & WS_SYSMENU
)
1009 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1010 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
);
1011 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1014 if (down
) flags
|= DFCS_PUSHED
;
1015 if (bGrayed
) flags
|= DFCS_INACTIVE
;
1016 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
1019 /******************************************************************************
1020 * NC_DrawMinButton95
1022 * Draws the minimize button for Win95 style windows.
1023 * If bGrayed is true, then draw a disabled Minimize button
1025 static void NC_DrawMinButton95(HWND hwnd
,HDC16 hdc
,BOOL down
, BOOL bGrayed
)
1028 UINT flags
= DFCS_CAPTIONMIN
;
1029 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
1031 NC_GetInsideRect( hwnd
, &rect
);
1032 if (style
& WS_SYSMENU
)
1033 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1034 if (style
& (WS_MAXIMIZEBOX
|WS_MINIMIZEBOX
))
1035 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) - 2;
1036 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
);
1037 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1040 if (down
) flags
|= DFCS_PUSHED
;
1041 if (bGrayed
) flags
|= DFCS_INACTIVE
;
1042 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
1045 /***********************************************************************
1048 * Draw a window frame inside the given rectangle, and update the rectangle.
1049 * The correct pen for the frame must be selected in the DC.
1051 static void NC_DrawFrame( HDC hdc
, RECT
*rect
, BOOL dlgFrame
,
1056 if (TWEAK_WineLook
!= WIN31_LOOK
)
1057 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
1061 width
= GetSystemMetrics(SM_CXDLGFRAME
) - 1;
1062 height
= GetSystemMetrics(SM_CYDLGFRAME
) - 1;
1063 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1064 COLOR_INACTIVECAPTION
) );
1068 width
= GetSystemMetrics(SM_CXFRAME
) - 2;
1069 height
= GetSystemMetrics(SM_CYFRAME
) - 2;
1070 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1071 COLOR_INACTIVEBORDER
) );
1075 PatBlt( hdc
, rect
->left
, rect
->top
,
1076 rect
->right
- rect
->left
, height
, PATCOPY
);
1077 PatBlt( hdc
, rect
->left
, rect
->top
,
1078 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1079 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1080 rect
->right
- rect
->left
, -height
, PATCOPY
);
1081 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1082 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1086 InflateRect( rect
, -width
, -height
);
1090 INT decYOff
= GetSystemMetrics(SM_CXFRAME
) + GetSystemMetrics(SM_CXSIZE
) - 1;
1091 INT decXOff
= GetSystemMetrics(SM_CYFRAME
) + GetSystemMetrics(SM_CYSIZE
) - 1;
1093 /* Draw inner rectangle */
1095 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1096 Rectangle( hdc
, rect
->left
+ width
, rect
->top
+ height
,
1097 rect
->right
- width
, rect
->bottom
- height
);
1099 /* Draw the decorations */
1101 MoveToEx( hdc
, rect
->left
, rect
->top
+ decYOff
, NULL
);
1102 LineTo( hdc
, rect
->left
+ width
, rect
->top
+ decYOff
);
1103 MoveToEx( hdc
, rect
->right
- 1, rect
->top
+ decYOff
, NULL
);
1104 LineTo( hdc
, rect
->right
- width
- 1, rect
->top
+ decYOff
);
1105 MoveToEx( hdc
, rect
->left
, rect
->bottom
- decYOff
, NULL
);
1106 LineTo( hdc
, rect
->left
+ width
, rect
->bottom
- decYOff
);
1107 MoveToEx( hdc
, rect
->right
- 1, rect
->bottom
- decYOff
, NULL
);
1108 LineTo( hdc
, rect
->right
- width
- 1, rect
->bottom
- decYOff
);
1110 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->top
, NULL
);
1111 LineTo( hdc
, rect
->left
+ decXOff
, rect
->top
+ height
);
1112 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->bottom
- 1, NULL
);
1113 LineTo( hdc
, rect
->left
+ decXOff
, rect
->bottom
- height
- 1 );
1114 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->top
, NULL
);
1115 LineTo( hdc
, rect
->right
- decXOff
, rect
->top
+ height
);
1116 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->bottom
- 1, NULL
);
1117 LineTo( hdc
, rect
->right
- decXOff
, rect
->bottom
- height
- 1 );
1119 InflateRect( rect
, -width
- 1, -height
- 1 );
1124 /******************************************************************************
1126 * void NC_DrawFrame95(
1133 * Draw a window frame inside the given rectangle, and update the rectangle.
1136 * Many. First, just what IS a frame in Win95? Note that the 3D look
1137 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1138 * edge. The inner rectangle just inside the frame is handled by the
1141 * In short, for most people, this function should be a nop (unless
1142 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1143 * them lately, but just to get this code right). Even so, it doesn't
1144 * appear to be so. It's being worked on...
1147 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1148 * Original implementation (based on NC_DrawFrame)
1149 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1151 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1152 * Fixed a fix or something.
1154 *****************************************************************************/
1156 static void NC_DrawFrame95(
1165 /* Firstly the "thick" frame */
1166 if (style
& WS_THICKFRAME
)
1168 width
= GetSystemMetrics(SM_CXFRAME
) - GetSystemMetrics(SM_CXDLGFRAME
);
1169 height
= GetSystemMetrics(SM_CYFRAME
) - GetSystemMetrics(SM_CYDLGFRAME
);
1171 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1172 COLOR_INACTIVEBORDER
) );
1174 PatBlt( hdc
, rect
->left
, rect
->top
,
1175 rect
->right
- rect
->left
, height
, PATCOPY
);
1176 PatBlt( hdc
, rect
->left
, rect
->top
,
1177 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1178 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1179 rect
->right
- rect
->left
, -height
, PATCOPY
);
1180 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1181 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1183 InflateRect( rect
, -width
, -height
);
1186 /* Now the other bit of the frame */
1187 if ((style
& (WS_BORDER
|WS_DLGFRAME
)) ||
1188 (exStyle
& WS_EX_DLGMODALFRAME
))
1190 width
= GetSystemMetrics(SM_CXDLGFRAME
) - GetSystemMetrics(SM_CXEDGE
);
1191 height
= GetSystemMetrics(SM_CYDLGFRAME
) - GetSystemMetrics(SM_CYEDGE
);
1192 /* This should give a value of 1 that should also work for a border */
1194 SelectObject( hdc
, GetSysColorBrush(
1195 (exStyle
& (WS_EX_DLGMODALFRAME
|WS_EX_CLIENTEDGE
)) ?
1197 (exStyle
& WS_EX_STATICEDGE
) ?
1199 (style
& (WS_DLGFRAME
|WS_THICKFRAME
)) ?
1202 COLOR_WINDOWFRAME
));
1205 PatBlt( hdc
, rect
->left
, rect
->top
,
1206 rect
->right
- rect
->left
, height
, PATCOPY
);
1207 PatBlt( hdc
, rect
->left
, rect
->top
,
1208 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1209 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1210 rect
->right
- rect
->left
, -height
, PATCOPY
);
1211 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1212 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1214 InflateRect( rect
, -width
, -height
);
1219 /***********************************************************************
1222 * Draw the window caption.
1223 * The correct pen for the window frame must be selected in the DC.
1225 static void NC_DrawCaption( HDC hdc
, RECT
*rect
, HWND hwnd
,
1226 DWORD style
, BOOL active
)
1233 if (!(hbitmapClose
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_OLD_CLOSE
) ))) return;
1236 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_DLGMODALFRAME
)
1238 HBRUSH hbrushOld
= SelectObject(hdc
, GetSysColorBrush(COLOR_WINDOW
) );
1239 PatBlt( hdc
, r
.left
, r
.top
, 1, r
.bottom
-r
.top
+1,PATCOPY
);
1240 PatBlt( hdc
, r
.right
-1, r
.top
, 1, r
.bottom
-r
.top
+1, PATCOPY
);
1241 PatBlt( hdc
, r
.left
, r
.top
-1, r
.right
-r
.left
, 1, PATCOPY
);
1244 SelectObject( hdc
, hbrushOld
);
1246 MoveToEx( hdc
, r
.left
, r
.bottom
, NULL
);
1247 LineTo( hdc
, r
.right
, r
.bottom
);
1249 if (style
& WS_SYSMENU
)
1251 NC_DrawSysButton( hwnd
, hdc
, FALSE
);
1252 r
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
1253 MoveToEx( hdc
, r
.left
- 1, r
.top
, NULL
);
1254 LineTo( hdc
, r
.left
- 1, r
.bottom
);
1256 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
: COLOR_INACTIVECAPTION
) );
1257 if (style
& WS_MAXIMIZEBOX
)
1259 NC_DrawMaxButton( hwnd
, hdc
, FALSE
);
1260 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1262 if (style
& WS_MINIMIZEBOX
)
1264 NC_DrawMinButton( hwnd
, hdc
, FALSE
);
1265 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1268 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) ))
1270 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1271 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1272 SetBkMode( hdc
, TRANSPARENT
);
1273 DrawTextA( hdc
, buffer
, -1, &r
,
1274 DT_SINGLELINE
| DT_CENTER
| DT_VCENTER
| DT_NOPREFIX
);
1279 /******************************************************************************
1288 * Draw the window caption for Win95 style windows.
1289 * The correct pen for the window frame must be selected in the DC.
1292 * Hey, a function that finally works! Well, almost.
1293 * It's being worked on.
1296 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1297 * Original implementation.
1298 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1301 *****************************************************************************/
1303 static void NC_DrawCaption95(
1316 hPrevPen
= SelectObject( hdc
, SYSCOLOR_GetPen(
1317 ((exStyle
& (WS_EX_STATICEDGE
|WS_EX_CLIENTEDGE
|
1318 WS_EX_DLGMODALFRAME
)) == WS_EX_STATICEDGE
) ?
1319 COLOR_WINDOWFRAME
: COLOR_3DFACE
) );
1320 MoveToEx( hdc
, r
.left
, r
.bottom
- 1, NULL
);
1321 LineTo( hdc
, r
.right
, r
.bottom
- 1 );
1322 SelectObject( hdc
, hPrevPen
);
1325 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1326 COLOR_INACTIVECAPTION
) );
1328 if ((style
& WS_SYSMENU
) && !(exStyle
& WS_EX_TOOLWINDOW
)) {
1329 if (NC_DrawSysButton95 (hwnd
, hdc
, FALSE
))
1330 r
.left
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
1333 if (style
& WS_SYSMENU
)
1337 /* Go get the sysmenu */
1338 hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1339 state
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
);
1341 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1342 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
,
1343 ((((state
& MF_DISABLED
) || (state
& MF_GRAYED
))) && (state
!= 0xFFFFFFFF)));
1344 r
.right
-= GetSystemMetrics(SM_CYCAPTION
) - 1;
1346 if ((style
& WS_MAXIMIZEBOX
) || (style
& WS_MINIMIZEBOX
))
1348 /* In win95 the two buttons are always there */
1349 /* But if the menu item is not in the menu they're disabled*/
1351 NC_DrawMaxButton95( hwnd
, hdc
, FALSE
, (!(style
& WS_MAXIMIZEBOX
)));
1352 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1354 NC_DrawMinButton95( hwnd
, hdc
, FALSE
, (!(style
& WS_MINIMIZEBOX
)));
1355 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1359 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) )) {
1360 NONCLIENTMETRICSA nclm
;
1361 HFONT hFont
, hOldFont
;
1362 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
1363 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
1364 if (exStyle
& WS_EX_TOOLWINDOW
)
1365 hFont
= CreateFontIndirectA (&nclm
.lfSmCaptionFont
);
1367 hFont
= CreateFontIndirectA (&nclm
.lfCaptionFont
);
1368 hOldFont
= SelectObject (hdc
, hFont
);
1369 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1370 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1371 SetBkMode( hdc
, TRANSPARENT
);
1373 DrawTextA( hdc
, buffer
, -1, &r
,
1374 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
1375 DeleteObject (SelectObject (hdc
, hOldFont
));
1381 /***********************************************************************
1384 * Paint the non-client area. clip is currently unused.
1386 static void NC_DoNCPaint( HWND hwnd
, HRGN clip
, BOOL suppress_menupaint
)
1392 DWORD dwStyle
, dwExStyle
;
1394 RECT rectClient
, rectWindow
;
1397 if (!(wndPtr
= WIN_GetPtr( hwnd
)) || wndPtr
== WND_OTHER_PROCESS
) return;
1398 has_menu
= HAS_MENU(wndPtr
);
1399 dwStyle
= wndPtr
->dwStyle
;
1400 dwExStyle
= wndPtr
->dwExStyle
;
1401 flags
= wndPtr
->flags
;
1402 rectClient
= wndPtr
->rectClient
;
1403 rectWindow
= wndPtr
->rectWindow
;
1404 WIN_ReleasePtr( wndPtr
);
1406 if ( dwStyle
& WS_MINIMIZE
||
1407 !WIN_IsWindowDrawable( hwnd
, 0 )) return; /* Nothing to do */
1409 active
= flags
& WIN_NCACTIVATED
;
1411 TRACE("%04x %d\n", hwnd
, active
);
1413 if (!(hdc
= GetDCEx( hwnd
, (clip
> 1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
1414 ((clip
> 1) ? (DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
): 0) ))) return;
1416 if (ExcludeVisRect16( hdc
, rectClient
.left
-rectWindow
.left
,
1417 rectClient
.top
-rectWindow
.top
,
1418 rectClient
.right
-rectWindow
.left
,
1419 rectClient
.bottom
-rectWindow
.top
)
1422 ReleaseDC( hwnd
, hdc
);
1426 rect
.top
= rect
.left
= 0;
1427 rect
.right
= rectWindow
.right
- rectWindow
.left
;
1428 rect
.bottom
= rectWindow
.bottom
- rectWindow
.top
;
1430 SelectObject( hdc
, SYSCOLOR_GetPen(COLOR_WINDOWFRAME
) );
1432 if (HAS_ANYFRAME( dwStyle
, dwExStyle
))
1434 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1435 Rectangle( hdc
, 0, 0, rect
.right
, rect
.bottom
);
1436 InflateRect( &rect
, -1, -1 );
1439 if (HAS_THICKFRAME( dwStyle
, dwExStyle
))
1440 NC_DrawFrame(hdc
, &rect
, FALSE
, active
);
1441 else if (HAS_DLGFRAME( dwStyle
, dwExStyle
))
1442 NC_DrawFrame( hdc
, &rect
, TRUE
, active
);
1444 if ((dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1447 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
);
1448 rect
.top
+= GetSystemMetrics(SM_CYSIZE
) + GetSystemMetrics(SM_CYBORDER
);
1449 NC_DrawCaption( hdc
, &r
, hwnd
, dwStyle
, active
);
1455 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYMENU
); /* default height */
1456 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
);
1459 /* Draw the scroll-bars */
1461 if (dwStyle
& WS_VSCROLL
)
1462 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1463 if (dwStyle
& WS_HSCROLL
)
1464 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1466 /* Draw the "size-box" */
1468 if ((dwStyle
& WS_VSCROLL
) && (dwStyle
& WS_HSCROLL
))
1471 r
.left
= r
.right
- GetSystemMetrics(SM_CXVSCROLL
) + 1;
1472 r
.top
= r
.bottom
- GetSystemMetrics(SM_CYHSCROLL
) + 1;
1473 if(wndPtr
->dwStyle
& WS_BORDER
) {
1477 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1480 ReleaseDC( hwnd
, hdc
);
1484 /******************************************************************************
1486 * void NC_DoNCPaint95(
1489 * BOOL suppress_menupaint )
1491 * Paint the non-client area for Win95 windows. The clip region is
1492 * currently ignored.
1495 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1496 * misc/tweak.c controls/menu.c # :-)
1499 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1500 * Original implementation
1501 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1503 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1504 * Streamlined window style checks.
1506 *****************************************************************************/
1508 static void NC_DoNCPaint95(
1511 BOOL suppress_menupaint
)
1514 RECT rfuzz
, rect
, rectClip
;
1517 DWORD dwStyle
, dwExStyle
;
1519 RECT rectClient
, rectWindow
;
1522 if (!(wndPtr
= WIN_GetPtr( hwnd
)) || wndPtr
== WND_OTHER_PROCESS
) return;
1523 has_menu
= HAS_MENU(wndPtr
);
1524 dwStyle
= wndPtr
->dwStyle
;
1525 dwExStyle
= wndPtr
->dwExStyle
;
1526 flags
= wndPtr
->flags
;
1527 rectClient
= wndPtr
->rectClient
;
1528 rectWindow
= wndPtr
->rectWindow
;
1529 WIN_ReleasePtr( wndPtr
);
1531 if ( dwStyle
& WS_MINIMIZE
||
1532 !WIN_IsWindowDrawable( hwnd
, 0 )) return; /* Nothing to do */
1534 active
= flags
& WIN_NCACTIVATED
;
1536 TRACE("%04x %d\n", hwnd
, active
);
1538 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1539 the call to GetDCEx implying that it is allowed not to use it either.
1540 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1541 will cause clipRgn to be deleted after ReleaseDC().
1542 Now, how is the "system" supposed to tell what happened?
1545 if (!(hdc
= GetDCEx( hwnd
, (clip
> 1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
1546 ((clip
> 1) ?(DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
) : 0) ))) return;
1549 if (ExcludeVisRect16( hdc
, rectClient
.left
-rectWindow
.left
,
1550 rectClient
.top
-rectWindow
.top
,
1551 rectClient
.right
-rectWindow
.left
,
1552 rectClient
.bottom
-rectWindow
.top
)
1555 ReleaseDC( hwnd
, hdc
);
1559 rect
.top
= rect
.left
= 0;
1560 rect
.right
= rectWindow
.right
- rectWindow
.left
;
1561 rect
.bottom
= rectWindow
.bottom
- rectWindow
.top
;
1564 GetRgnBox( clip
, &rectClip
);
1571 SelectObject( hdc
, SYSCOLOR_GetPen(COLOR_WINDOWFRAME
) );
1573 if (HAS_STATICOUTERFRAME(dwStyle
, dwExStyle
)) {
1574 DrawEdge (hdc
, &rect
, BDR_SUNKENOUTER
, BF_RECT
| BF_ADJUST
);
1576 else if (HAS_BIGFRAME( dwStyle
, dwExStyle
)) {
1577 DrawEdge (hdc
, &rect
, EDGE_RAISED
, BF_RECT
| BF_ADJUST
);
1580 NC_DrawFrame95(hdc
, &rect
, active
, dwStyle
, dwExStyle
);
1582 if ((dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1585 if (dwExStyle
& WS_EX_TOOLWINDOW
) {
1586 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSMCAPTION
);
1587 rect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
);
1590 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYCAPTION
);
1591 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
);
1593 if( !clip
|| IntersectRect( &rfuzz
, &r
, &rectClip
) )
1594 NC_DrawCaption95 (hdc
, &r
, hwnd
, dwStyle
,
1601 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYMENU
);
1603 TRACE("Calling DrawMenuBar with rect (%d, %d)-(%d, %d)\n",
1604 r
.left
, r
.top
, r
.right
, r
.bottom
);
1606 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
) + 1;
1609 TRACE("After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1610 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1612 if (dwExStyle
& WS_EX_CLIENTEDGE
)
1613 DrawEdge (hdc
, &rect
, EDGE_SUNKEN
, BF_RECT
| BF_ADJUST
);
1615 /* Draw the scroll-bars */
1617 if (dwStyle
& WS_VSCROLL
)
1618 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1619 if (dwStyle
& WS_HSCROLL
)
1620 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1622 /* Draw the "size-box" */
1623 if ((dwStyle
& WS_VSCROLL
) && (dwStyle
& WS_HSCROLL
))
1626 r
.left
= r
.right
- GetSystemMetrics(SM_CXVSCROLL
) + 1;
1627 r
.top
= r
.bottom
- GetSystemMetrics(SM_CYHSCROLL
) + 1;
1628 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1631 ReleaseDC( hwnd
, hdc
);
1637 /***********************************************************************
1640 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1642 LONG
NC_HandleNCPaint( HWND hwnd
, HRGN clip
)
1644 DWORD dwStyle
= GetWindowLongW( hwnd
, GWL_STYLE
);
1646 if( dwStyle
& WS_VISIBLE
)
1648 if( dwStyle
& WS_MINIMIZE
)
1649 WINPOS_RedrawIconTitle( hwnd
);
1650 else if (TWEAK_WineLook
== WIN31_LOOK
)
1651 NC_DoNCPaint( hwnd
, clip
, FALSE
);
1653 NC_DoNCPaint95( hwnd
, clip
, FALSE
);
1659 /***********************************************************************
1660 * NC_HandleNCActivate
1662 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1664 LONG
NC_HandleNCActivate( HWND hwnd
, WPARAM wParam
)
1666 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1668 /* Lotus Notes draws menu descriptions in the caption of its main
1669 * window. When it wants to restore original "system" view, it just
1670 * sends WM_NCACTIVATE message to itself. Any optimizations here in
1671 * attempt to minimize redrawings lead to a not restored caption.
1675 if (wParam
) wndPtr
->flags
|= WIN_NCACTIVATED
;
1676 else wndPtr
->flags
&= ~WIN_NCACTIVATED
;
1677 WIN_ReleaseWndPtr(wndPtr
);
1679 if (IsIconic(hwnd
)) WINPOS_RedrawIconTitle( hwnd
);
1680 else if (TWEAK_WineLook
== WIN31_LOOK
)
1681 NC_DoNCPaint( hwnd
, (HRGN
)1, FALSE
);
1683 NC_DoNCPaint95( hwnd
, (HRGN
)1, FALSE
);
1689 /***********************************************************************
1690 * NC_HandleSetCursor
1692 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1694 LONG
NC_HandleSetCursor( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1696 hwnd
= WIN_GetFullHandle( (HWND
)wParam
);
1698 switch(LOWORD(lParam
))
1702 WORD msg
= HIWORD( lParam
);
1703 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_MBUTTONDOWN
) ||
1704 (msg
== WM_RBUTTONDOWN
))
1711 HCURSOR hCursor
= GetClassLongA(hwnd
, GCL_HCURSOR
);
1721 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZEWEA
) );
1725 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENSA
) );
1729 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENWSEA
) );
1733 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENESWA
) );
1736 /* Default cursor: arrow */
1737 return (LONG
)SetCursor( LoadCursorA( 0, IDC_ARROWA
) );
1740 /***********************************************************************
1743 void NC_GetSysPopupPos( HWND hwnd
, RECT
* rect
)
1745 if (IsIconic(hwnd
)) GetWindowRect( hwnd
, rect
);
1748 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1749 if (!wndPtr
) return;
1751 NC_GetInsideRect( hwnd
, rect
);
1752 OffsetRect( rect
, wndPtr
->rectWindow
.left
, wndPtr
->rectWindow
.top
);
1753 if (wndPtr
->dwStyle
& WS_CHILD
)
1754 ClientToScreen( GetParent(hwnd
), (POINT
*)rect
);
1755 if (TWEAK_WineLook
== WIN31_LOOK
) {
1756 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CXSIZE
);
1757 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYSIZE
);
1760 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
1761 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
1763 WIN_ReleaseWndPtr( wndPtr
);
1767 /***********************************************************************
1768 * NC_TrackMinMaxBox95
1770 * Track a mouse button press on the minimize or maximize box.
1772 * The big difference between 3.1 and 95 is the disabled button state.
1773 * In win95 the system button can be disabled, so it can ignore the mouse
1777 static void NC_TrackMinMaxBox95( HWND hwnd
, WORD wParam
)
1780 HDC hdc
= GetWindowDC( hwnd
);
1781 BOOL pressed
= TRUE
;
1783 DWORD wndStyle
= GetWindowLongA( hwnd
, GWL_STYLE
);
1784 HMENU hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1786 void (*paintButton
)(HWND
, HDC16
, BOOL
, BOOL
);
1788 if (wParam
== HTMINBUTTON
)
1790 /* If the style is not present, do nothing */
1791 if (!(wndStyle
& WS_MINIMIZEBOX
))
1794 /* Check if the sysmenu item for minimize is there */
1795 state
= GetMenuState(hSysMenu
, SC_MINIMIZE
, MF_BYCOMMAND
);
1797 paintButton
= &NC_DrawMinButton95
;
1801 /* If the style is not present, do nothing */
1802 if (!(wndStyle
& WS_MAXIMIZEBOX
))
1805 /* Check if the sysmenu item for maximize is there */
1806 state
= GetMenuState(hSysMenu
, SC_MAXIMIZE
, MF_BYCOMMAND
);
1808 paintButton
= &NC_DrawMaxButton95
;
1813 (*paintButton
)( hwnd
, hdc
, TRUE
, FALSE
);
1817 BOOL oldstate
= pressed
;
1819 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1820 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1822 if(msg
.message
== WM_LBUTTONUP
)
1825 if(msg
.message
!= WM_MOUSEMOVE
)
1828 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1829 if (pressed
!= oldstate
)
1830 (*paintButton
)( hwnd
, hdc
, pressed
, FALSE
);
1834 (*paintButton
)(hwnd
, hdc
, FALSE
, FALSE
);
1837 ReleaseDC( hwnd
, hdc
);
1839 /* If the item minimize or maximize of the sysmenu are not there */
1840 /* or if the style is not present, do nothing */
1841 if ((!pressed
) || (state
== 0xFFFFFFFF))
1844 if (wParam
== HTMINBUTTON
)
1845 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1847 SendMessageA( hwnd
, WM_SYSCOMMAND
,
1848 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1851 /***********************************************************************
1854 * Track a mouse button press on the minimize or maximize box.
1856 static void NC_TrackMinMaxBox( HWND hwnd
, WORD wParam
)
1859 HDC hdc
= GetWindowDC( hwnd
);
1860 BOOL pressed
= TRUE
;
1861 void (*paintButton
)(HWND
, HDC16
, BOOL
);
1865 if (wParam
== HTMINBUTTON
)
1866 paintButton
= &NC_DrawMinButton
;
1868 paintButton
= &NC_DrawMaxButton
;
1870 (*paintButton
)( hwnd
, hdc
, TRUE
);
1874 BOOL oldstate
= pressed
;
1876 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1877 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1879 if(msg
.message
== WM_LBUTTONUP
)
1882 if(msg
.message
!= WM_MOUSEMOVE
)
1885 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1886 if (pressed
!= oldstate
)
1887 (*paintButton
)( hwnd
, hdc
, pressed
);
1891 (*paintButton
)( hwnd
, hdc
, FALSE
);
1894 ReleaseDC( hwnd
, hdc
);
1896 if (!pressed
) return;
1898 if (wParam
== HTMINBUTTON
)
1899 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1901 SendMessageA( hwnd
, WM_SYSCOMMAND
,
1902 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1906 /***********************************************************************
1907 * NC_TrackCloseButton95
1909 * Track a mouse button press on the Win95 close button.
1912 NC_TrackCloseButton95 (HWND hwnd
, WORD wParam
)
1916 BOOL pressed
= TRUE
;
1917 HMENU hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1923 state
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
);
1925 /* If the item close of the sysmenu is disabled or not there do nothing */
1926 if((state
& MF_DISABLED
) || (state
& MF_GRAYED
) || (state
== 0xFFFFFFFF))
1929 hdc
= GetWindowDC( hwnd
);
1933 NC_DrawCloseButton95 (hwnd
, hdc
, TRUE
, FALSE
);
1937 BOOL oldstate
= pressed
;
1939 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1940 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1942 if(msg
.message
== WM_LBUTTONUP
)
1945 if(msg
.message
!= WM_MOUSEMOVE
)
1948 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1949 if (pressed
!= oldstate
)
1950 NC_DrawCloseButton95 (hwnd
, hdc
, pressed
, FALSE
);
1954 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
, FALSE
);
1957 ReleaseDC( hwnd
, hdc
);
1958 if (!pressed
) return;
1960 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1964 /***********************************************************************
1967 * Track a mouse button press on the horizontal or vertical scroll-bar.
1969 static void NC_TrackScrollBar( HWND hwnd
, WPARAM wParam
, POINT pt
)
1973 if ((wParam
& 0xfff0) == SC_HSCROLL
)
1975 if ((wParam
& 0x0f) != HTHSCROLL
) return;
1976 scrollbar
= SB_HORZ
;
1978 else /* SC_VSCROLL */
1980 if ((wParam
& 0x0f) != HTVSCROLL
) return;
1981 scrollbar
= SB_VERT
;
1983 SCROLL_TrackScrollBar( hwnd
, scrollbar
, pt
);
1987 /***********************************************************************
1988 * NC_HandleNCLButtonDown
1990 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
1992 LONG
NC_HandleNCLButtonDown( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1994 LONG style
= GetWindowLongA( hwnd
, GWL_STYLE
);
1996 switch(wParam
) /* Hit test */
2000 HWND top
= GetAncestor( hwnd
, GA_ROOT
);
2002 if( WINPOS_SetActiveWindow(top
, TRUE
, TRUE
) || (GetActiveWindow() == top
) )
2003 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOVE
+ HTCAPTION
, lParam
);
2008 if( style
& WS_SYSMENU
)
2010 if( !(style
& WS_MINIMIZE
) )
2012 HDC hDC
= GetWindowDC(hwnd
);
2013 if (TWEAK_WineLook
== WIN31_LOOK
)
2014 NC_DrawSysButton( hwnd
, hDC
, TRUE
);
2016 NC_DrawSysButton95( hwnd
, hDC
, TRUE
);
2017 ReleaseDC( hwnd
, hDC
);
2019 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
+ HTSYSMENU
, lParam
);
2024 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
, lParam
);
2028 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
2032 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
2037 if (TWEAK_WineLook
== WIN31_LOOK
)
2038 NC_TrackMinMaxBox( hwnd
, wParam
);
2040 NC_TrackMinMaxBox95( hwnd
, wParam
);
2044 if (TWEAK_WineLook
>= WIN95_LOOK
)
2045 NC_TrackCloseButton95 (hwnd
, wParam
);
2056 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2057 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_SIZE
+ wParam
- 2, lParam
);
2067 /***********************************************************************
2068 * NC_HandleNCLButtonDblClk
2070 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2072 LONG
NC_HandleNCLButtonDblClk( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2075 * if this is an icon, send a restore since we are handling
2080 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_RESTORE
, lParam
);
2084 switch(wParam
) /* Hit test */
2087 /* stop processing if WS_MAXIMIZEBOX is missing */
2088 if (GetWindowLongA( hwnd
, GWL_STYLE
) & WS_MAXIMIZEBOX
)
2089 SendMessageW( hwnd
, WM_SYSCOMMAND
,
2090 IsZoomed(hwnd
) ? SC_RESTORE
: SC_MAXIMIZE
, lParam
);
2094 if (!(GetClassLongW(hwnd
, GCL_STYLE
) & CS_NOCLOSE
))
2095 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, lParam
);
2099 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
2103 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
2110 /***********************************************************************
2111 * NC_HandleSysCommand
2113 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2115 LONG
NC_HandleSysCommand( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2117 TRACE("Handling WM_SYSCOMMAND %x %lx\n", wParam
, lParam
);
2119 switch (wParam
& 0xfff0)
2123 if (USER_Driver
.pSysCommandSizeMove
)
2124 USER_Driver
.pSysCommandSizeMove( hwnd
, wParam
);
2128 if (hwnd
== GetForegroundWindow())
2129 ShowOwnedPopups(hwnd
,FALSE
);
2130 ShowWindow( hwnd
, SW_MINIMIZE
);
2134 if (IsIconic(hwnd
) && hwnd
== GetForegroundWindow())
2135 ShowOwnedPopups(hwnd
,TRUE
);
2136 ShowWindow( hwnd
, SW_MAXIMIZE
);
2140 if (IsIconic(hwnd
) && hwnd
== GetForegroundWindow())
2141 ShowOwnedPopups(hwnd
,TRUE
);
2142 ShowWindow( hwnd
, SW_RESTORE
);
2146 return SendMessageA( hwnd
, WM_CLOSE
, 0, 0 );
2152 pt
.x
= SLOWORD(lParam
);
2153 pt
.y
= SHIWORD(lParam
);
2154 NC_TrackScrollBar( hwnd
, wParam
, pt
);
2161 pt
.x
= SLOWORD(lParam
);
2162 pt
.y
= SHIWORD(lParam
);
2163 MENU_TrackMouseMenuBar( hwnd
, wParam
& 0x000F, pt
);
2168 MENU_TrackKbdMenuBar( hwnd
, wParam
, LOWORD(lParam
) );
2172 WinExec( "taskman.exe", SW_SHOWNORMAL
);
2176 if (wParam
== SC_ABOUTWINE
)
2178 HMODULE hmodule
= LoadLibraryA( "shell32.dll" );
2181 FARPROC aboutproc
= GetProcAddress( hmodule
, "ShellAboutA" );
2182 if (aboutproc
) aboutproc( hwnd
, PACKAGE_NAME
, PACKAGE_STRING
, 0 );
2183 FreeLibrary( hmodule
);
2187 if (wParam
== SC_PUTMARK
)
2188 TRACE_(shell
)("Mark requested by user\n");
2195 FIXME("unimplemented!\n");
2201 /*************************************************************
2204 * Stub for the grayed button of the caption
2206 *************************************************************/
2208 BOOL
NC_DrawGrayButton(HDC hdc
, int x
, int y
)
2211 HDC hdcMask
= CreateCompatibleDC (0);
2214 hMaskBmp
= CreateBitmap (12, 10, 1, 1, lpGrayMask
);
2219 SelectObject (hdcMask
, hMaskBmp
);
2221 /* Draw the grayed bitmap using the mask */
2222 hOldBrush
= SelectObject (hdc
, RGB(128, 128, 128));
2223 BitBlt (hdc
, x
, y
, 12, 10,
2224 hdcMask
, 0, 0, 0xB8074A);
2227 SelectObject (hdc
, hOldBrush
);
2228 DeleteObject(hMaskBmp
);