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"
31 #include "cursoricon.h"
33 #include "nonclient.h"
36 #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("(%p,%p,%p,%p,%p,%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 NONCLIENTMETRICSW nclm
;
350 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
351 SystemParametersInfoW (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
352 hNewFont
= CreateFontIndirectW ((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 %p, width %d, at (%d, %d).\n",
473 hwnd
, winRect
->right
- winRect
->left
, -tmpRect
.left
, -tmpRect
.top
);
476 MENU_GetMenuBarHeight( hwnd
,
477 winRect
->right
- winRect
->left
,
478 -tmpRect
.left
, -tmpRect
.top
) + 1;
481 if (TWEAK_WineLook
> WIN31_LOOK
) {
482 SetRect(&tmpRect
, 0, 0, 0, 0);
483 NC_AdjustRectInner95 (&tmpRect
, style
, exStyle
);
484 winRect
->left
-= tmpRect
.left
;
485 winRect
->top
-= tmpRect
.top
;
486 winRect
->right
-= tmpRect
.right
;
487 winRect
->bottom
-= tmpRect
.bottom
;
490 if (winRect
->top
> winRect
->bottom
)
491 winRect
->bottom
= winRect
->top
;
493 if (winRect
->left
> winRect
->right
)
494 winRect
->right
= winRect
->left
;
500 /***********************************************************************
503 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
504 * but without the borders (if any).
505 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
507 void NC_GetInsideRect( HWND hwnd
, RECT
*rect
)
509 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
511 rect
->top
= rect
->left
= 0;
512 rect
->right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
513 rect
->bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
515 if (wndPtr
->dwStyle
& WS_ICONIC
) goto END
;
517 /* Remove frame from rectangle */
518 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
520 InflateRect( rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
522 else if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
524 InflateRect( rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
525 /* FIXME: this isn't in NC_AdjustRect? why not? */
526 if ((TWEAK_WineLook
== WIN31_LOOK
) && (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
))
527 InflateRect( rect
, -1, 0 );
529 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
531 InflateRect( rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
) );
534 /* We have additional border information if the window
535 * is a child (but not an MDI child) */
536 if (TWEAK_WineLook
!= WIN31_LOOK
)
538 if ( (wndPtr
->dwStyle
& WS_CHILD
) &&
539 ( (wndPtr
->dwExStyle
& WS_EX_MDICHILD
) == 0 ) )
541 if (wndPtr
->dwExStyle
& WS_EX_CLIENTEDGE
)
542 InflateRect (rect
, -GetSystemMetrics(SM_CXEDGE
), -GetSystemMetrics(SM_CYEDGE
));
543 if (wndPtr
->dwExStyle
& WS_EX_STATICEDGE
)
544 InflateRect (rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
549 WIN_ReleaseWndPtr(wndPtr
);
554 /***********************************************************************
557 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
560 static LONG
NC_DoNCHitTest (WND
*wndPtr
, POINT pt
)
564 TRACE("hwnd=%p pt=%ld,%ld\n", wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
566 GetWindowRect(wndPtr
->hwndSelf
, &rect
);
567 if (!PtInRect( &rect
, pt
)) return HTNOWHERE
;
569 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
572 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
574 InflateRect( &rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
575 if (!PtInRect( &rect
, pt
))
577 /* Check top sizing border */
580 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
581 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
584 /* Check bottom sizing border */
585 if (pt
.y
>= rect
.bottom
)
587 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
588 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
591 /* Check left sizing border */
592 if (pt
.x
< rect
.left
)
594 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
595 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
598 /* Check right sizing border */
599 if (pt
.x
>= rect
.right
)
601 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
602 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
607 else /* No thick frame */
609 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
610 InflateRect(&rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
611 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
612 InflateRect(&rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
613 if (!PtInRect( &rect
, pt
)) return HTBORDER
;
618 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
620 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
) - GetSystemMetrics(SM_CYBORDER
);
621 if (!PtInRect( &rect
, pt
))
623 /* Check system menu */
624 if ((wndPtr
->dwStyle
& WS_SYSMENU
) && !(wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
))
625 rect
.left
+= GetSystemMetrics(SM_CXSIZE
);
626 if (pt
.x
<= rect
.left
) return HTSYSMENU
;
628 /* Check maximize box */
629 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
630 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
632 if (pt
.x
>= rect
.right
) return HTMAXBUTTON
;
633 /* Check minimize box */
634 if (wndPtr
->dwStyle
& WS_MINIMIZEBOX
)
635 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
636 if (pt
.x
>= rect
.right
) return HTMINBUTTON
;
641 /* Check client area */
643 ScreenToClient( wndPtr
->hwndSelf
, &pt
);
644 GetClientRect( wndPtr
->hwndSelf
, &rect
);
645 if (PtInRect( &rect
, pt
)) return HTCLIENT
;
647 /* Check vertical scroll bar */
649 if (wndPtr
->dwStyle
& WS_VSCROLL
)
651 rect
.right
+= GetSystemMetrics(SM_CXVSCROLL
);
652 if (PtInRect( &rect
, pt
)) return HTVSCROLL
;
655 /* Check horizontal scroll bar */
657 if (wndPtr
->dwStyle
& WS_HSCROLL
)
659 rect
.bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
660 if (PtInRect( &rect
, pt
))
663 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
664 (pt
.x
>= rect
.right
- GetSystemMetrics(SM_CXVSCROLL
)))
672 if (HAS_MENU(wndPtr
))
674 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
678 /* Has to return HTNOWHERE if nothing was found
679 Could happen when a window has a customized non client area */
684 /***********************************************************************
687 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
689 * FIXME: Just a modified copy of the Win 3.1 version.
692 static LONG
NC_DoNCHitTest95 (WND
*wndPtr
, POINT pt
)
696 TRACE("hwnd=%p pt=%ld,%ld\n", wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
698 GetWindowRect(wndPtr
->hwndSelf
, &rect
);
699 if (!PtInRect( &rect
, pt
)) return HTNOWHERE
;
701 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
704 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
706 InflateRect( &rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
707 if (!PtInRect( &rect
, pt
))
709 /* Check top sizing border */
712 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
713 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
716 /* Check bottom sizing border */
717 if (pt
.y
>= rect
.bottom
)
719 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
720 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
723 /* Check left sizing border */
724 if (pt
.x
< rect
.left
)
726 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
727 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
730 /* Check right sizing border */
731 if (pt
.x
>= rect
.right
)
733 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
734 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
739 else /* No thick frame */
741 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
742 InflateRect(&rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
743 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
744 InflateRect(&rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
745 if (!PtInRect( &rect
, pt
)) return HTBORDER
;
750 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
752 if (wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
)
753 rect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
) - 1;
755 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
756 if (!PtInRect( &rect
, pt
))
758 /* Check system menu */
759 if ((wndPtr
->dwStyle
& WS_SYSMENU
) && !(wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
))
761 if (NC_IconForWindow(wndPtr
->hwndSelf
))
762 rect
.left
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
764 if (pt
.x
< rect
.left
) return HTSYSMENU
;
766 /* Check close button */
767 if (wndPtr
->dwStyle
& WS_SYSMENU
)
768 rect
.right
-= GetSystemMetrics(SM_CYCAPTION
) - 1;
769 if (pt
.x
> rect
.right
) return HTCLOSE
;
771 /* Check maximize box */
772 /* In win95 there is automatically a Maximize button when there is a minimize one*/
773 if ((wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)|| (wndPtr
->dwStyle
& WS_MINIMIZEBOX
))
774 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
775 if (pt
.x
> rect
.right
) return HTMAXBUTTON
;
777 /* Check minimize box */
778 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
779 if ((wndPtr
->dwStyle
& WS_MINIMIZEBOX
)||(wndPtr
->dwStyle
& WS_MAXIMIZEBOX
))
780 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
782 if (pt
.x
> rect
.right
) return HTMINBUTTON
;
787 /* Check client area */
789 ScreenToClient( wndPtr
->hwndSelf
, &pt
);
790 GetClientRect( wndPtr
->hwndSelf
, &rect
);
791 if (PtInRect( &rect
, pt
)) return HTCLIENT
;
793 /* Check vertical scroll bar */
795 if (wndPtr
->dwStyle
& WS_VSCROLL
)
797 rect
.right
+= GetSystemMetrics(SM_CXVSCROLL
);
798 if (PtInRect( &rect
, pt
)) return HTVSCROLL
;
801 /* Check horizontal scroll bar */
803 if (wndPtr
->dwStyle
& WS_HSCROLL
)
805 rect
.bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
806 if (PtInRect( &rect
, pt
))
809 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
810 (pt
.x
>= rect
.right
- GetSystemMetrics(SM_CXVSCROLL
)))
818 if (HAS_MENU(wndPtr
))
820 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
824 /* Has to return HTNOWHERE if nothing was found
825 Could happen when a window has a customized non client area */
830 /***********************************************************************
833 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
835 LONG
NC_HandleNCHitTest (HWND hwnd
, POINT pt
)
838 WND
*wndPtr
= WIN_FindWndPtr (hwnd
);
843 if (TWEAK_WineLook
== WIN31_LOOK
)
844 retvalue
= NC_DoNCHitTest (wndPtr
, pt
);
846 retvalue
= NC_DoNCHitTest95 (wndPtr
, pt
);
847 WIN_ReleaseWndPtr(wndPtr
);
852 /***********************************************************************
855 void NC_DrawSysButton( HWND hwnd
, HDC hdc
, BOOL down
)
861 NC_GetInsideRect( hwnd
, &rect
);
862 hdcMem
= CreateCompatibleDC( hdc
);
863 hbitmap
= SelectObject( hdcMem
, hbitmapClose
);
864 BitBlt(hdc
, rect
.left
, rect
.top
, GetSystemMetrics(SM_CXSIZE
), GetSystemMetrics(SM_CYSIZE
),
865 hdcMem
, (GetWindowLongA(hwnd
,GWL_STYLE
) & WS_CHILD
) ? GetSystemMetrics(SM_CXSIZE
) : 0, 0,
866 down
? NOTSRCCOPY
: SRCCOPY
);
867 SelectObject( hdcMem
, hbitmap
);
872 /***********************************************************************
875 static void NC_DrawMaxButton( HWND hwnd
, HDC hdc
, BOOL down
)
878 UINT flags
= IsZoomed(hwnd
) ? DFCS_CAPTIONRESTORE
: DFCS_CAPTIONMAX
;
880 NC_GetInsideRect( hwnd
, &rect
);
881 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
) + 1;
882 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
885 if (down
) flags
|= DFCS_PUSHED
;
886 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
890 /***********************************************************************
893 static void NC_DrawMinButton( HWND hwnd
, HDC hdc
, BOOL down
)
896 UINT flags
= DFCS_CAPTIONMIN
;
897 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
899 NC_GetInsideRect( hwnd
, &rect
);
900 if (style
& (WS_MAXIMIZEBOX
|WS_MINIMIZEBOX
))
901 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) - 2;
902 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
) + 1;
903 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
906 if (down
) flags
|= DFCS_PUSHED
;
907 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
911 /******************************************************************************
913 * void NC_DrawSysButton95(
918 * Draws the Win95 system icon.
921 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
922 * Original implementation from NC_DrawSysButton source.
923 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
926 *****************************************************************************/
929 NC_DrawSysButton95 (HWND hwnd
, HDC hdc
, BOOL down
)
931 HICON hIcon
= NC_IconForWindow( hwnd
);
936 NC_GetInsideRect( hwnd
, &rect
);
937 DrawIconEx (hdc
, rect
.left
+ 1, rect
.top
+ 1, hIcon
,
938 GetSystemMetrics(SM_CXSIZE
) - 1,
939 GetSystemMetrics(SM_CYSIZE
) - 1, 0, 0, DI_NORMAL
);
945 /******************************************************************************
947 * void NC_DrawCloseButton95(
953 * Draws the Win95 close button.
955 * If bGrayed is true, then draw a disabled Close button
958 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
959 * Original implementation from NC_DrawSysButton95 source.
961 *****************************************************************************/
963 static void NC_DrawCloseButton95 (HWND hwnd
, HDC hdc
, BOOL down
, BOOL bGrayed
)
967 NC_GetInsideRect( hwnd
, &rect
);
969 /* A tool window has a smaller Close button */
970 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_TOOLWINDOW
)
972 INT iBmpHeight
= 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
973 INT iBmpWidth
= 11; /* it uses 11x11 for the close button in tool window */
974 INT iCaptionHeight
= GetSystemMetrics(SM_CYSMCAPTION
);
976 rect
.top
= rect
.top
+ (iCaptionHeight
- 1 - iBmpHeight
) / 2;
977 rect
.left
= rect
.right
- (iCaptionHeight
+ 1 + iBmpWidth
) / 2;
978 rect
.bottom
= rect
.top
+ iBmpHeight
;
979 rect
.right
= rect
.left
+ iBmpWidth
;
983 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
) - 1;
984 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
988 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
,
990 (down
? DFCS_PUSHED
: 0) |
991 (bGrayed
? DFCS_INACTIVE
: 0)) );
994 /******************************************************************************
997 * Draws the maximize button for Win95 style windows.
998 * If bGrayed is true, then draw a disabled Maximize button
1000 static void NC_DrawMaxButton95(HWND hwnd
,HDC hdc
,BOOL down
, BOOL bGrayed
)
1003 UINT flags
= IsZoomed(hwnd
) ? DFCS_CAPTIONRESTORE
: DFCS_CAPTIONMAX
;
1005 NC_GetInsideRect( hwnd
, &rect
);
1006 if (GetWindowLongA( hwnd
, GWL_STYLE
) & WS_SYSMENU
)
1007 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1008 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
);
1009 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1012 if (down
) flags
|= DFCS_PUSHED
;
1013 if (bGrayed
) flags
|= DFCS_INACTIVE
;
1014 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
1017 /******************************************************************************
1018 * NC_DrawMinButton95
1020 * Draws the minimize button for Win95 style windows.
1021 * If bGrayed is true, then draw a disabled Minimize button
1023 static void NC_DrawMinButton95(HWND hwnd
,HDC hdc
,BOOL down
, BOOL bGrayed
)
1026 UINT flags
= DFCS_CAPTIONMIN
;
1027 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
1029 NC_GetInsideRect( hwnd
, &rect
);
1030 if (style
& WS_SYSMENU
)
1031 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1032 if (style
& (WS_MAXIMIZEBOX
|WS_MINIMIZEBOX
))
1033 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) - 2;
1034 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
);
1035 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1038 if (down
) flags
|= DFCS_PUSHED
;
1039 if (bGrayed
) flags
|= DFCS_INACTIVE
;
1040 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
1043 /***********************************************************************
1046 * Draw a window frame inside the given rectangle, and update the rectangle.
1047 * The correct pen for the frame must be selected in the DC.
1049 static void NC_DrawFrame( HDC hdc
, RECT
*rect
, BOOL dlgFrame
,
1054 if (TWEAK_WineLook
!= WIN31_LOOK
)
1055 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
1059 width
= GetSystemMetrics(SM_CXDLGFRAME
) - 1;
1060 height
= GetSystemMetrics(SM_CYDLGFRAME
) - 1;
1061 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1062 COLOR_INACTIVECAPTION
) );
1066 width
= GetSystemMetrics(SM_CXFRAME
) - 2;
1067 height
= GetSystemMetrics(SM_CYFRAME
) - 2;
1068 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1069 COLOR_INACTIVEBORDER
) );
1073 PatBlt( hdc
, rect
->left
, rect
->top
,
1074 rect
->right
- rect
->left
, height
, PATCOPY
);
1075 PatBlt( hdc
, rect
->left
, rect
->top
,
1076 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1077 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1078 rect
->right
- rect
->left
, -height
, PATCOPY
);
1079 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1080 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1084 InflateRect( rect
, -width
, -height
);
1088 INT decYOff
= GetSystemMetrics(SM_CXFRAME
) + GetSystemMetrics(SM_CXSIZE
) - 1;
1089 INT decXOff
= GetSystemMetrics(SM_CYFRAME
) + GetSystemMetrics(SM_CYSIZE
) - 1;
1091 /* Draw inner rectangle */
1093 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1094 Rectangle( hdc
, rect
->left
+ width
, rect
->top
+ height
,
1095 rect
->right
- width
, rect
->bottom
- height
);
1097 /* Draw the decorations */
1099 MoveToEx( hdc
, rect
->left
, rect
->top
+ decYOff
, NULL
);
1100 LineTo( hdc
, rect
->left
+ width
, rect
->top
+ decYOff
);
1101 MoveToEx( hdc
, rect
->right
- 1, rect
->top
+ decYOff
, NULL
);
1102 LineTo( hdc
, rect
->right
- width
- 1, rect
->top
+ decYOff
);
1103 MoveToEx( hdc
, rect
->left
, rect
->bottom
- decYOff
, NULL
);
1104 LineTo( hdc
, rect
->left
+ width
, rect
->bottom
- decYOff
);
1105 MoveToEx( hdc
, rect
->right
- 1, rect
->bottom
- decYOff
, NULL
);
1106 LineTo( hdc
, rect
->right
- width
- 1, rect
->bottom
- decYOff
);
1108 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->top
, NULL
);
1109 LineTo( hdc
, rect
->left
+ decXOff
, rect
->top
+ height
);
1110 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->bottom
- 1, NULL
);
1111 LineTo( hdc
, rect
->left
+ decXOff
, rect
->bottom
- height
- 1 );
1112 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->top
, NULL
);
1113 LineTo( hdc
, rect
->right
- decXOff
, rect
->top
+ height
);
1114 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->bottom
- 1, NULL
);
1115 LineTo( hdc
, rect
->right
- decXOff
, rect
->bottom
- height
- 1 );
1117 InflateRect( rect
, -width
- 1, -height
- 1 );
1122 /******************************************************************************
1124 * void NC_DrawFrame95(
1131 * Draw a window frame inside the given rectangle, and update the rectangle.
1134 * Many. First, just what IS a frame in Win95? Note that the 3D look
1135 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1136 * edge. The inner rectangle just inside the frame is handled by the
1139 * In short, for most people, this function should be a nop (unless
1140 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1141 * them lately, but just to get this code right). Even so, it doesn't
1142 * appear to be so. It's being worked on...
1145 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1146 * Original implementation (based on NC_DrawFrame)
1147 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1149 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1150 * Fixed a fix or something.
1152 *****************************************************************************/
1154 static void NC_DrawFrame95(
1163 /* Firstly the "thick" frame */
1164 if (style
& WS_THICKFRAME
)
1166 width
= GetSystemMetrics(SM_CXFRAME
) - GetSystemMetrics(SM_CXDLGFRAME
);
1167 height
= GetSystemMetrics(SM_CYFRAME
) - GetSystemMetrics(SM_CYDLGFRAME
);
1169 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1170 COLOR_INACTIVEBORDER
) );
1172 PatBlt( hdc
, rect
->left
, rect
->top
,
1173 rect
->right
- rect
->left
, height
, PATCOPY
);
1174 PatBlt( hdc
, rect
->left
, rect
->top
,
1175 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1176 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1177 rect
->right
- rect
->left
, -height
, PATCOPY
);
1178 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1179 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1181 InflateRect( rect
, -width
, -height
);
1184 /* Now the other bit of the frame */
1185 if ((style
& (WS_BORDER
|WS_DLGFRAME
)) ||
1186 (exStyle
& WS_EX_DLGMODALFRAME
))
1188 width
= GetSystemMetrics(SM_CXDLGFRAME
) - GetSystemMetrics(SM_CXEDGE
);
1189 height
= GetSystemMetrics(SM_CYDLGFRAME
) - GetSystemMetrics(SM_CYEDGE
);
1190 /* This should give a value of 1 that should also work for a border */
1192 SelectObject( hdc
, GetSysColorBrush(
1193 (exStyle
& (WS_EX_DLGMODALFRAME
|WS_EX_CLIENTEDGE
)) ?
1195 (exStyle
& WS_EX_STATICEDGE
) ?
1197 (style
& (WS_DLGFRAME
|WS_THICKFRAME
)) ?
1200 COLOR_WINDOWFRAME
));
1203 PatBlt( hdc
, rect
->left
, rect
->top
,
1204 rect
->right
- rect
->left
, height
, PATCOPY
);
1205 PatBlt( hdc
, rect
->left
, rect
->top
,
1206 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1207 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1208 rect
->right
- rect
->left
, -height
, PATCOPY
);
1209 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1210 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1212 InflateRect( rect
, -width
, -height
);
1217 /***********************************************************************
1220 * Draw the window caption.
1221 * The correct pen for the window frame must be selected in the DC.
1223 static void NC_DrawCaption( HDC hdc
, RECT
*rect
, HWND hwnd
,
1224 DWORD style
, BOOL active
)
1231 if (!(hbitmapClose
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_OLD_CLOSE
) ))) return;
1234 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_DLGMODALFRAME
)
1236 HBRUSH hbrushOld
= SelectObject(hdc
, GetSysColorBrush(COLOR_WINDOW
) );
1237 PatBlt( hdc
, r
.left
, r
.top
, 1, r
.bottom
-r
.top
+1,PATCOPY
);
1238 PatBlt( hdc
, r
.right
-1, r
.top
, 1, r
.bottom
-r
.top
+1, PATCOPY
);
1239 PatBlt( hdc
, r
.left
, r
.top
-1, r
.right
-r
.left
, 1, PATCOPY
);
1242 SelectObject( hdc
, hbrushOld
);
1244 MoveToEx( hdc
, r
.left
, r
.bottom
, NULL
);
1245 LineTo( hdc
, r
.right
, r
.bottom
);
1247 if (style
& WS_SYSMENU
)
1249 NC_DrawSysButton( hwnd
, hdc
, FALSE
);
1250 r
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
1251 MoveToEx( hdc
, r
.left
- 1, r
.top
, NULL
);
1252 LineTo( hdc
, r
.left
- 1, r
.bottom
);
1254 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
: COLOR_INACTIVECAPTION
) );
1255 if (style
& WS_MAXIMIZEBOX
)
1257 NC_DrawMaxButton( hwnd
, hdc
, FALSE
);
1258 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1260 if (style
& WS_MINIMIZEBOX
)
1262 NC_DrawMinButton( hwnd
, hdc
, FALSE
);
1263 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1266 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) ))
1268 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1269 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1270 SetBkMode( hdc
, TRANSPARENT
);
1271 DrawTextA( hdc
, buffer
, -1, &r
,
1272 DT_SINGLELINE
| DT_CENTER
| DT_VCENTER
| DT_NOPREFIX
);
1277 /******************************************************************************
1286 * Draw the window caption for Win95 style windows.
1287 * The correct pen for the window frame must be selected in the DC.
1290 * Hey, a function that finally works! Well, almost.
1291 * It's being worked on.
1294 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1295 * Original implementation.
1296 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1299 *****************************************************************************/
1301 static void NC_DrawCaption95(
1314 hPrevPen
= SelectObject( hdc
, SYSCOLOR_GetPen(
1315 ((exStyle
& (WS_EX_STATICEDGE
|WS_EX_CLIENTEDGE
|
1316 WS_EX_DLGMODALFRAME
)) == WS_EX_STATICEDGE
) ?
1317 COLOR_WINDOWFRAME
: COLOR_3DFACE
) );
1318 MoveToEx( hdc
, r
.left
, r
.bottom
- 1, NULL
);
1319 LineTo( hdc
, r
.right
, r
.bottom
- 1 );
1320 SelectObject( hdc
, hPrevPen
);
1323 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1324 COLOR_INACTIVECAPTION
) );
1326 if ((style
& WS_SYSMENU
) && !(exStyle
& WS_EX_TOOLWINDOW
)) {
1327 if (NC_DrawSysButton95 (hwnd
, hdc
, FALSE
))
1328 r
.left
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
1331 if (style
& WS_SYSMENU
)
1335 /* Go get the sysmenu */
1336 hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1337 state
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
);
1339 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1340 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
,
1341 ((((state
& MF_DISABLED
) || (state
& MF_GRAYED
))) && (state
!= 0xFFFFFFFF)));
1342 r
.right
-= GetSystemMetrics(SM_CYCAPTION
) - 1;
1344 if ((style
& WS_MAXIMIZEBOX
) || (style
& WS_MINIMIZEBOX
))
1346 /* In win95 the two buttons are always there */
1347 /* But if the menu item is not in the menu they're disabled*/
1349 NC_DrawMaxButton95( hwnd
, hdc
, FALSE
, (!(style
& WS_MAXIMIZEBOX
)));
1350 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1352 NC_DrawMinButton95( hwnd
, hdc
, FALSE
, (!(style
& WS_MINIMIZEBOX
)));
1353 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1357 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) )) {
1358 NONCLIENTMETRICSA nclm
;
1359 HFONT hFont
, hOldFont
;
1360 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
1361 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
1362 if (exStyle
& WS_EX_TOOLWINDOW
)
1363 hFont
= CreateFontIndirectA (&nclm
.lfSmCaptionFont
);
1365 hFont
= CreateFontIndirectA (&nclm
.lfCaptionFont
);
1366 hOldFont
= SelectObject (hdc
, hFont
);
1367 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1368 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1369 SetBkMode( hdc
, TRANSPARENT
);
1371 DrawTextA( hdc
, buffer
, -1, &r
,
1372 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
1373 DeleteObject (SelectObject (hdc
, hOldFont
));
1379 /***********************************************************************
1382 * Paint the non-client area. clip is currently unused.
1384 static void NC_DoNCPaint( HWND hwnd
, HRGN clip
, BOOL suppress_menupaint
)
1390 DWORD dwStyle
, dwExStyle
;
1392 RECT rectClient
, rectWindow
;
1395 if (!(wndPtr
= WIN_GetPtr( hwnd
)) || wndPtr
== WND_OTHER_PROCESS
) return;
1396 has_menu
= HAS_MENU(wndPtr
);
1397 dwStyle
= wndPtr
->dwStyle
;
1398 dwExStyle
= wndPtr
->dwExStyle
;
1399 flags
= wndPtr
->flags
;
1400 rectClient
= wndPtr
->rectClient
;
1401 rectWindow
= wndPtr
->rectWindow
;
1402 WIN_ReleasePtr( wndPtr
);
1404 if ( dwStyle
& WS_MINIMIZE
||
1405 !WIN_IsWindowDrawable( hwnd
, 0 )) return; /* Nothing to do */
1407 active
= flags
& WIN_NCACTIVATED
;
1409 TRACE("%p %d\n", hwnd
, active
);
1411 if (!(hdc
= GetDCEx( hwnd
, (clip
> (HRGN
)1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
1412 ((clip
> (HRGN
)1) ? (DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
): 0) ))) return;
1414 if (ExcludeVisRect16( HDC_16(hdc
), rectClient
.left
-rectWindow
.left
,
1415 rectClient
.top
-rectWindow
.top
,
1416 rectClient
.right
-rectWindow
.left
,
1417 rectClient
.bottom
-rectWindow
.top
)
1420 ReleaseDC( hwnd
, hdc
);
1424 rect
.top
= rect
.left
= 0;
1425 rect
.right
= rectWindow
.right
- rectWindow
.left
;
1426 rect
.bottom
= rectWindow
.bottom
- rectWindow
.top
;
1428 SelectObject( hdc
, SYSCOLOR_GetPen(COLOR_WINDOWFRAME
) );
1430 if (HAS_ANYFRAME( dwStyle
, dwExStyle
))
1432 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1433 Rectangle( hdc
, 0, 0, rect
.right
, rect
.bottom
);
1434 InflateRect( &rect
, -1, -1 );
1437 if (HAS_THICKFRAME( dwStyle
, dwExStyle
))
1438 NC_DrawFrame(hdc
, &rect
, FALSE
, active
);
1439 else if (HAS_DLGFRAME( dwStyle
, dwExStyle
))
1440 NC_DrawFrame( hdc
, &rect
, TRUE
, active
);
1442 if ((dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1445 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
);
1446 rect
.top
+= GetSystemMetrics(SM_CYSIZE
) + GetSystemMetrics(SM_CYBORDER
);
1447 NC_DrawCaption( hdc
, &r
, hwnd
, dwStyle
, active
);
1453 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYMENU
); /* default height */
1454 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
);
1457 /* Draw the scroll-bars */
1459 if (dwStyle
& WS_VSCROLL
)
1460 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1461 if (dwStyle
& WS_HSCROLL
)
1462 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1464 /* Draw the "size-box" */
1466 if ((dwStyle
& WS_VSCROLL
) && (dwStyle
& WS_HSCROLL
))
1469 r
.left
= r
.right
- GetSystemMetrics(SM_CXVSCROLL
) + 1;
1470 r
.top
= r
.bottom
- GetSystemMetrics(SM_CYHSCROLL
) + 1;
1471 if(wndPtr
->dwStyle
& WS_BORDER
) {
1475 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1478 ReleaseDC( hwnd
, hdc
);
1482 /******************************************************************************
1484 * void NC_DoNCPaint95(
1487 * BOOL suppress_menupaint )
1489 * Paint the non-client area for Win95 windows. The clip region is
1490 * currently ignored.
1493 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1494 * misc/tweak.c controls/menu.c # :-)
1497 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1498 * Original implementation
1499 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1501 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1502 * Streamlined window style checks.
1504 *****************************************************************************/
1506 static void NC_DoNCPaint95(
1509 BOOL suppress_menupaint
)
1512 RECT rfuzz
, rect
, rectClip
;
1515 DWORD dwStyle
, dwExStyle
;
1517 RECT rectClient
, rectWindow
;
1520 if (!(wndPtr
= WIN_GetPtr( hwnd
)) || wndPtr
== WND_OTHER_PROCESS
) return;
1521 has_menu
= HAS_MENU(wndPtr
);
1522 dwStyle
= wndPtr
->dwStyle
;
1523 dwExStyle
= wndPtr
->dwExStyle
;
1524 flags
= wndPtr
->flags
;
1525 rectClient
= wndPtr
->rectClient
;
1526 rectWindow
= wndPtr
->rectWindow
;
1527 WIN_ReleasePtr( wndPtr
);
1529 if ( dwStyle
& WS_MINIMIZE
||
1530 !WIN_IsWindowDrawable( hwnd
, 0 )) return; /* Nothing to do */
1532 active
= flags
& WIN_NCACTIVATED
;
1534 TRACE("%p %d\n", hwnd
, active
);
1536 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1537 the call to GetDCEx implying that it is allowed not to use it either.
1538 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1539 will cause clipRgn to be deleted after ReleaseDC().
1540 Now, how is the "system" supposed to tell what happened?
1543 if (!(hdc
= GetDCEx( hwnd
, (clip
> (HRGN
)1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
1544 ((clip
> (HRGN
)1) ?(DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
) : 0) ))) return;
1547 if (ExcludeVisRect16( HDC_16(hdc
), rectClient
.left
-rectWindow
.left
,
1548 rectClient
.top
-rectWindow
.top
,
1549 rectClient
.right
-rectWindow
.left
,
1550 rectClient
.bottom
-rectWindow
.top
)
1553 ReleaseDC( hwnd
, hdc
);
1557 rect
.top
= rect
.left
= 0;
1558 rect
.right
= rectWindow
.right
- rectWindow
.left
;
1559 rect
.bottom
= rectWindow
.bottom
- rectWindow
.top
;
1561 if( clip
> (HRGN
)1 )
1562 GetRgnBox( clip
, &rectClip
);
1569 SelectObject( hdc
, SYSCOLOR_GetPen(COLOR_WINDOWFRAME
) );
1571 if (HAS_STATICOUTERFRAME(dwStyle
, dwExStyle
)) {
1572 DrawEdge (hdc
, &rect
, BDR_SUNKENOUTER
, BF_RECT
| BF_ADJUST
);
1574 else if (HAS_BIGFRAME( dwStyle
, dwExStyle
)) {
1575 DrawEdge (hdc
, &rect
, EDGE_RAISED
, BF_RECT
| BF_ADJUST
);
1578 NC_DrawFrame95(hdc
, &rect
, active
, dwStyle
, dwExStyle
);
1580 if ((dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1583 if (dwExStyle
& WS_EX_TOOLWINDOW
) {
1584 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSMCAPTION
);
1585 rect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
);
1588 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYCAPTION
);
1589 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
);
1591 if( !clip
|| IntersectRect( &rfuzz
, &r
, &rectClip
) )
1592 NC_DrawCaption95 (hdc
, &r
, hwnd
, dwStyle
,
1599 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYMENU
);
1601 TRACE("Calling DrawMenuBar with rect (%d, %d)-(%d, %d)\n",
1602 r
.left
, r
.top
, r
.right
, r
.bottom
);
1604 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
) + 1;
1607 TRACE("After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1608 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1610 if (dwExStyle
& WS_EX_CLIENTEDGE
)
1611 DrawEdge (hdc
, &rect
, EDGE_SUNKEN
, BF_RECT
| BF_ADJUST
);
1613 /* Draw the scroll-bars */
1615 if (dwStyle
& WS_VSCROLL
)
1616 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1617 if (dwStyle
& WS_HSCROLL
)
1618 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1620 /* Draw the "size-box" */
1621 if ((dwStyle
& WS_VSCROLL
) && (dwStyle
& WS_HSCROLL
))
1624 r
.left
= r
.right
- GetSystemMetrics(SM_CXVSCROLL
) + 1;
1625 r
.top
= r
.bottom
- GetSystemMetrics(SM_CYHSCROLL
) + 1;
1626 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1629 ReleaseDC( hwnd
, hdc
);
1635 /***********************************************************************
1638 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1640 LONG
NC_HandleNCPaint( HWND hwnd
, HRGN clip
)
1642 DWORD dwStyle
= GetWindowLongW( hwnd
, GWL_STYLE
);
1644 if( dwStyle
& WS_VISIBLE
)
1646 if( dwStyle
& WS_MINIMIZE
)
1647 WINPOS_RedrawIconTitle( hwnd
);
1648 else if (TWEAK_WineLook
== WIN31_LOOK
)
1649 NC_DoNCPaint( hwnd
, clip
, FALSE
);
1651 NC_DoNCPaint95( hwnd
, clip
, FALSE
);
1657 /***********************************************************************
1658 * NC_HandleNCActivate
1660 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1662 LONG
NC_HandleNCActivate( HWND hwnd
, WPARAM wParam
)
1664 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1666 /* Lotus Notes draws menu descriptions in the caption of its main
1667 * window. When it wants to restore original "system" view, it just
1668 * sends WM_NCACTIVATE message to itself. Any optimizations here in
1669 * attempt to minimize redrawings lead to a not restored caption.
1673 if (wParam
) wndPtr
->flags
|= WIN_NCACTIVATED
;
1674 else wndPtr
->flags
&= ~WIN_NCACTIVATED
;
1675 WIN_ReleaseWndPtr(wndPtr
);
1677 if (IsIconic(hwnd
)) WINPOS_RedrawIconTitle( hwnd
);
1678 else if (TWEAK_WineLook
== WIN31_LOOK
)
1679 NC_DoNCPaint( hwnd
, (HRGN
)1, FALSE
);
1681 NC_DoNCPaint95( hwnd
, (HRGN
)1, FALSE
);
1687 /***********************************************************************
1688 * NC_HandleSetCursor
1690 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1692 LONG
NC_HandleSetCursor( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1694 hwnd
= WIN_GetFullHandle( (HWND
)wParam
);
1696 switch(LOWORD(lParam
))
1700 WORD msg
= HIWORD( lParam
);
1701 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_MBUTTONDOWN
) ||
1702 (msg
== WM_RBUTTONDOWN
))
1709 HCURSOR hCursor
= (HCURSOR
)GetClassLongA(hwnd
, GCL_HCURSOR
);
1719 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZEWEA
) );
1723 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENSA
) );
1727 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENWSEA
) );
1731 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENESWA
) );
1734 /* Default cursor: arrow */
1735 return (LONG
)SetCursor( LoadCursorA( 0, IDC_ARROWA
) );
1738 /***********************************************************************
1741 void NC_GetSysPopupPos( HWND hwnd
, RECT
* rect
)
1743 if (IsIconic(hwnd
)) GetWindowRect( hwnd
, rect
);
1746 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1747 if (!wndPtr
) return;
1749 NC_GetInsideRect( hwnd
, rect
);
1750 OffsetRect( rect
, wndPtr
->rectWindow
.left
, wndPtr
->rectWindow
.top
);
1751 if (wndPtr
->dwStyle
& WS_CHILD
)
1752 ClientToScreen( GetParent(hwnd
), (POINT
*)rect
);
1753 if (TWEAK_WineLook
== WIN31_LOOK
) {
1754 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CXSIZE
);
1755 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYSIZE
);
1758 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
1759 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
1761 WIN_ReleaseWndPtr( wndPtr
);
1765 /***********************************************************************
1766 * NC_TrackMinMaxBox95
1768 * Track a mouse button press on the minimize or maximize box.
1770 * The big difference between 3.1 and 95 is the disabled button state.
1771 * In win95 the system button can be disabled, so it can ignore the mouse
1775 static void NC_TrackMinMaxBox95( HWND hwnd
, WORD wParam
)
1778 HDC hdc
= GetWindowDC( hwnd
);
1779 BOOL pressed
= TRUE
;
1781 DWORD wndStyle
= GetWindowLongA( hwnd
, GWL_STYLE
);
1782 HMENU hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1784 void (*paintButton
)(HWND
, HDC
, BOOL
, BOOL
);
1786 if (wParam
== HTMINBUTTON
)
1788 /* If the style is not present, do nothing */
1789 if (!(wndStyle
& WS_MINIMIZEBOX
))
1792 /* Check if the sysmenu item for minimize is there */
1793 state
= GetMenuState(hSysMenu
, SC_MINIMIZE
, MF_BYCOMMAND
);
1795 paintButton
= &NC_DrawMinButton95
;
1799 /* If the style is not present, do nothing */
1800 if (!(wndStyle
& WS_MAXIMIZEBOX
))
1803 /* Check if the sysmenu item for maximize is there */
1804 state
= GetMenuState(hSysMenu
, SC_MAXIMIZE
, MF_BYCOMMAND
);
1806 paintButton
= &NC_DrawMaxButton95
;
1811 (*paintButton
)( hwnd
, hdc
, TRUE
, FALSE
);
1815 BOOL oldstate
= pressed
;
1817 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1818 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1820 if(msg
.message
== WM_LBUTTONUP
)
1823 if(msg
.message
!= WM_MOUSEMOVE
)
1826 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1827 if (pressed
!= oldstate
)
1828 (*paintButton
)( hwnd
, hdc
, pressed
, FALSE
);
1832 (*paintButton
)(hwnd
, hdc
, FALSE
, FALSE
);
1835 ReleaseDC( hwnd
, hdc
);
1837 /* If the item minimize or maximize of the sysmenu are not there */
1838 /* or if the style is not present, do nothing */
1839 if ((!pressed
) || (state
== 0xFFFFFFFF))
1842 if (wParam
== HTMINBUTTON
)
1843 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1845 SendMessageA( hwnd
, WM_SYSCOMMAND
,
1846 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1849 /***********************************************************************
1852 * Track a mouse button press on the minimize or maximize box.
1854 static void NC_TrackMinMaxBox( HWND hwnd
, WORD wParam
)
1857 HDC hdc
= GetWindowDC( hwnd
);
1858 BOOL pressed
= TRUE
;
1859 void (*paintButton
)(HWND
, HDC
, BOOL
);
1863 if (wParam
== HTMINBUTTON
)
1864 paintButton
= &NC_DrawMinButton
;
1866 paintButton
= &NC_DrawMaxButton
;
1868 (*paintButton
)( hwnd
, hdc
, TRUE
);
1872 BOOL oldstate
= pressed
;
1874 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1875 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1877 if(msg
.message
== WM_LBUTTONUP
)
1880 if(msg
.message
!= WM_MOUSEMOVE
)
1883 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1884 if (pressed
!= oldstate
)
1885 (*paintButton
)( hwnd
, hdc
, pressed
);
1889 (*paintButton
)( hwnd
, hdc
, FALSE
);
1892 ReleaseDC( hwnd
, hdc
);
1894 if (!pressed
) return;
1896 if (wParam
== HTMINBUTTON
)
1897 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1899 SendMessageA( hwnd
, WM_SYSCOMMAND
,
1900 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1904 /***********************************************************************
1905 * NC_TrackCloseButton95
1907 * Track a mouse button press on the Win95 close button.
1910 NC_TrackCloseButton95 (HWND hwnd
, WORD wParam
)
1914 BOOL pressed
= TRUE
;
1915 HMENU hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1921 state
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
);
1923 /* If the item close of the sysmenu is disabled or not there do nothing */
1924 if((state
& MF_DISABLED
) || (state
& MF_GRAYED
) || (state
== 0xFFFFFFFF))
1927 hdc
= GetWindowDC( hwnd
);
1931 NC_DrawCloseButton95 (hwnd
, hdc
, TRUE
, FALSE
);
1935 BOOL oldstate
= pressed
;
1937 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1938 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1940 if(msg
.message
== WM_LBUTTONUP
)
1943 if(msg
.message
!= WM_MOUSEMOVE
)
1946 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1947 if (pressed
!= oldstate
)
1948 NC_DrawCloseButton95 (hwnd
, hdc
, pressed
, FALSE
);
1952 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
, FALSE
);
1955 ReleaseDC( hwnd
, hdc
);
1956 if (!pressed
) return;
1958 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1962 /***********************************************************************
1965 * Track a mouse button press on the horizontal or vertical scroll-bar.
1967 static void NC_TrackScrollBar( HWND hwnd
, WPARAM wParam
, POINT pt
)
1971 if ((wParam
& 0xfff0) == SC_HSCROLL
)
1973 if ((wParam
& 0x0f) != HTHSCROLL
) return;
1974 scrollbar
= SB_HORZ
;
1976 else /* SC_VSCROLL */
1978 if ((wParam
& 0x0f) != HTVSCROLL
) return;
1979 scrollbar
= SB_VERT
;
1981 SCROLL_TrackScrollBar( hwnd
, scrollbar
, pt
);
1985 /***********************************************************************
1986 * NC_HandleNCLButtonDown
1988 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
1990 LONG
NC_HandleNCLButtonDown( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1992 LONG style
= GetWindowLongA( hwnd
, GWL_STYLE
);
1994 switch(wParam
) /* Hit test */
1998 HWND top
= GetAncestor( hwnd
, GA_ROOT
);
2000 if (FOCUS_MouseActivate( top
) || (GetActiveWindow() == top
))
2001 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOVE
+ HTCAPTION
, lParam
);
2006 if( style
& WS_SYSMENU
)
2008 if( !(style
& WS_MINIMIZE
) )
2010 HDC hDC
= GetWindowDC(hwnd
);
2011 if (TWEAK_WineLook
== WIN31_LOOK
)
2012 NC_DrawSysButton( hwnd
, hDC
, TRUE
);
2014 NC_DrawSysButton95( hwnd
, hDC
, TRUE
);
2015 ReleaseDC( hwnd
, hDC
);
2017 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
+ HTSYSMENU
, lParam
);
2022 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
, lParam
);
2026 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
2030 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
2035 if (TWEAK_WineLook
== WIN31_LOOK
)
2036 NC_TrackMinMaxBox( hwnd
, wParam
);
2038 NC_TrackMinMaxBox95( hwnd
, wParam
);
2042 if (TWEAK_WineLook
>= WIN95_LOOK
)
2043 NC_TrackCloseButton95 (hwnd
, wParam
);
2054 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2055 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_SIZE
+ wParam
- 2, lParam
);
2065 /***********************************************************************
2066 * NC_HandleNCLButtonDblClk
2068 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2070 LONG
NC_HandleNCLButtonDblClk( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2073 * if this is an icon, send a restore since we are handling
2078 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_RESTORE
, lParam
);
2082 switch(wParam
) /* Hit test */
2085 /* stop processing if WS_MAXIMIZEBOX is missing */
2086 if (GetWindowLongA( hwnd
, GWL_STYLE
) & WS_MAXIMIZEBOX
)
2087 SendMessageW( hwnd
, WM_SYSCOMMAND
,
2088 IsZoomed(hwnd
) ? SC_RESTORE
: SC_MAXIMIZE
, lParam
);
2092 if (!(GetClassLongW(hwnd
, GCL_STYLE
) & CS_NOCLOSE
))
2093 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, lParam
);
2097 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
2101 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
2108 /***********************************************************************
2109 * NC_HandleSysCommand
2111 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2113 LONG
NC_HandleSysCommand( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2115 TRACE("Handling WM_SYSCOMMAND %x %lx\n", wParam
, lParam
);
2117 switch (wParam
& 0xfff0)
2121 if (USER_Driver
.pSysCommandSizeMove
)
2122 USER_Driver
.pSysCommandSizeMove( hwnd
, wParam
);
2126 if (hwnd
== GetForegroundWindow())
2127 ShowOwnedPopups(hwnd
,FALSE
);
2128 ShowWindow( hwnd
, SW_MINIMIZE
);
2132 if (IsIconic(hwnd
) && hwnd
== GetForegroundWindow())
2133 ShowOwnedPopups(hwnd
,TRUE
);
2134 ShowWindow( hwnd
, SW_MAXIMIZE
);
2138 if (IsIconic(hwnd
) && hwnd
== GetForegroundWindow())
2139 ShowOwnedPopups(hwnd
,TRUE
);
2140 ShowWindow( hwnd
, SW_RESTORE
);
2144 return SendMessageA( hwnd
, WM_CLOSE
, 0, 0 );
2150 pt
.x
= SLOWORD(lParam
);
2151 pt
.y
= SHIWORD(lParam
);
2152 NC_TrackScrollBar( hwnd
, wParam
, pt
);
2159 pt
.x
= SLOWORD(lParam
);
2160 pt
.y
= SHIWORD(lParam
);
2161 MENU_TrackMouseMenuBar( hwnd
, wParam
& 0x000F, pt
);
2166 MENU_TrackKbdMenuBar( hwnd
, wParam
, LOWORD(lParam
) );
2170 WinExec( "taskman.exe", SW_SHOWNORMAL
);
2174 if (wParam
== SC_ABOUTWINE
)
2176 HMODULE hmodule
= LoadLibraryA( "shell32.dll" );
2179 FARPROC aboutproc
= GetProcAddress( hmodule
, "ShellAboutA" );
2180 if (aboutproc
) aboutproc( hwnd
, PACKAGE_NAME
, PACKAGE_STRING
, 0 );
2181 FreeLibrary( hmodule
);
2185 if (wParam
== SC_PUTMARK
)
2186 TRACE_(shell
)("Mark requested by user\n");
2193 FIXME("unimplemented!\n");
2199 /*************************************************************
2202 * Stub for the grayed button of the caption
2204 *************************************************************/
2206 BOOL
NC_DrawGrayButton(HDC hdc
, int x
, int y
)
2212 hMaskBmp
= CreateBitmap (12, 10, 1, 1, lpGrayMask
);
2217 hdcMask
= CreateCompatibleDC (0);
2218 SelectObject (hdcMask
, hMaskBmp
);
2220 /* Draw the grayed bitmap using the mask */
2221 hOldBrush
= SelectObject (hdc
, (HGDIOBJ
)RGB(128, 128, 128));
2222 BitBlt (hdc
, x
, y
, 12, 10,
2223 hdcMask
, 0, 0, 0xB8074A);
2226 SelectObject (hdc
, hOldBrush
);
2227 DeleteObject(hMaskBmp
);