2 * Non-client area window functions
4 * Copyright 1994 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "wine/winuser16.h"
34 #include "cursoricon.h"
36 #include "nonclient.h"
39 #include "wine/debug.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(nonclient
);
42 WINE_DECLARE_DEBUG_CHANNEL(shell
);
44 BOOL
NC_DrawGrayButton(HDC hdc
, int x
, int y
);
46 static HBITMAP hbitmapClose
;
48 static const BYTE lpGrayMask
[] = { 0xAA, 0xA0,
59 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
60 #define SC_PUTMARK (SC_SCREENSAVE+2)
62 /* Some useful macros */
63 #define HAS_DLGFRAME(style,exStyle) \
64 (((exStyle) & WS_EX_DLGMODALFRAME) || \
65 (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
67 #define HAS_THICKFRAME(style,exStyle) \
68 (((style) & WS_THICKFRAME) && \
69 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
71 #define HAS_THINFRAME(style) \
72 (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
74 #define HAS_BIGFRAME(style,exStyle) \
75 (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
76 ((exStyle) & WS_EX_DLGMODALFRAME))
78 #define HAS_STATICOUTERFRAME(style,exStyle) \
79 (((exStyle) & (WS_EX_STATICEDGE|WS_EX_DLGMODALFRAME)) == \
82 #define HAS_ANYFRAME(style,exStyle) \
83 (((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
84 ((exStyle) & WS_EX_DLGMODALFRAME) || \
85 !((style) & (WS_CHILD | WS_POPUP)))
87 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
90 /***********************************************************************
93 * Compute the size of the window rectangle from the size of the
96 static void NC_AdjustRect( LPRECT rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
98 if (TWEAK_WineLook
> WIN31_LOOK
)
99 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
101 if(style
& WS_ICONIC
) return;
103 if (HAS_THICKFRAME( style
, exStyle
))
104 InflateRect( rect
, GetSystemMetrics(SM_CXFRAME
), GetSystemMetrics(SM_CYFRAME
) );
105 else if (HAS_DLGFRAME( style
, exStyle
))
106 InflateRect( rect
, GetSystemMetrics(SM_CXDLGFRAME
), GetSystemMetrics(SM_CYDLGFRAME
) );
107 else if (HAS_THINFRAME( style
))
108 InflateRect( rect
, GetSystemMetrics(SM_CXBORDER
), GetSystemMetrics(SM_CYBORDER
));
110 if ((style
& WS_CAPTION
) == WS_CAPTION
)
111 rect
->top
-= GetSystemMetrics(SM_CYCAPTION
) - GetSystemMetrics(SM_CYBORDER
);
113 if (menu
) rect
->top
-= GetSystemMetrics(SM_CYMENU
) + GetSystemMetrics(SM_CYBORDER
);
115 if (style
& WS_VSCROLL
) {
116 rect
->right
+= GetSystemMetrics(SM_CXVSCROLL
) - 1;
117 if(!HAS_ANYFRAME( style
, exStyle
))
121 if (style
& WS_HSCROLL
) {
122 rect
->bottom
+= GetSystemMetrics(SM_CYHSCROLL
) - 1;
123 if(!HAS_ANYFRAME( style
, exStyle
))
129 /******************************************************************************
130 * NC_AdjustRectOuter95
132 * Computes the size of the "outside" parts of the window based on the
133 * parameters of the client area.
142 * "Outer" parts of a window means the whole window frame, caption and
143 * menu bar. It does not include "inner" parts of the frame like client
144 * edge, static edge or scroll bars.
147 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
148 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
150 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
151 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
152 * NC_AdjustRectInner95 and added handling of Win95 styles.
154 * 28-Jul-1999 Ove Kåven (ovek@arcticnet.no)
155 * Streamlined window style checks.
157 *****************************************************************************/
160 NC_AdjustRectOuter95 (LPRECT rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
163 if(style
& WS_ICONIC
) return;
165 if ((exStyle
& (WS_EX_STATICEDGE
|WS_EX_DLGMODALFRAME
)) ==
168 adjust
= 1; /* for the outer frame always present */
173 if ((exStyle
& WS_EX_DLGMODALFRAME
) ||
174 (style
& (WS_THICKFRAME
|WS_DLGFRAME
))) adjust
= 2; /* outer */
176 if (style
& WS_THICKFRAME
)
177 adjust
+= ( GetSystemMetrics (SM_CXFRAME
)
178 - GetSystemMetrics (SM_CXDLGFRAME
)); /* The resize border */
179 if ((style
& (WS_BORDER
|WS_DLGFRAME
)) ||
180 (exStyle
& WS_EX_DLGMODALFRAME
))
181 adjust
++; /* The other border */
183 InflateRect (rect
, adjust
, adjust
);
185 if ((style
& WS_CAPTION
) == WS_CAPTION
)
187 if (exStyle
& WS_EX_TOOLWINDOW
)
188 rect
->top
-= GetSystemMetrics(SM_CYSMCAPTION
);
190 rect
->top
-= GetSystemMetrics(SM_CYCAPTION
);
192 if (menu
) rect
->top
-= GetSystemMetrics(SM_CYMENU
);
196 /******************************************************************************
197 * NC_AdjustRectInner95
199 * Computes the size of the "inside" part of the window based on the
200 * parameters of the client area.
208 * "Inner" part of a window means the window frame inside of the flat
209 * window frame. It includes the client edge, the static edge and the
213 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
214 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
216 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
217 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
218 * NC_AdjustRectInner95 and added handling of Win95 styles.
220 *****************************************************************************/
223 NC_AdjustRectInner95 (LPRECT rect
, DWORD style
, DWORD exStyle
)
225 if(style
& WS_ICONIC
) return;
227 if (exStyle
& WS_EX_CLIENTEDGE
)
228 InflateRect(rect
, GetSystemMetrics(SM_CXEDGE
), GetSystemMetrics(SM_CYEDGE
));
230 if (style
& WS_VSCROLL
)
232 if((exStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
233 rect
->left
-= GetSystemMetrics(SM_CXVSCROLL
);
235 rect
->right
+= GetSystemMetrics(SM_CXVSCROLL
);
237 if (style
& WS_HSCROLL
) rect
->bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
242 static HICON
NC_IconForWindow( HWND hwnd
)
245 WND
*wndPtr
= WIN_GetPtr( hwnd
);
247 if (wndPtr
&& wndPtr
!= WND_OTHER_PROCESS
)
249 hIcon
= wndPtr
->hIconSmall
;
250 if (!hIcon
) hIcon
= wndPtr
->hIcon
;
251 WIN_ReleasePtr( wndPtr
);
253 if (!hIcon
) hIcon
= (HICON
) GetClassLongA( hwnd
, GCL_HICONSM
);
254 if (!hIcon
) hIcon
= (HICON
) GetClassLongA( hwnd
, GCL_HICON
);
256 /* If there is no hIcon specified and this is a modal dialog,
257 * get the default one.
259 if (!hIcon
&& (GetWindowLongA( hwnd
, GWL_STYLE
) & DS_MODALFRAME
))
260 hIcon
= LoadImageA(0, (LPSTR
)IDI_WINLOGO
, IMAGE_ICON
, 0, 0, LR_DEFAULTCOLOR
);
264 /***********************************************************************
265 * DrawCaption (USER32.@) Draws a caption bar
279 DrawCaption (HWND hwnd
, HDC hdc
, const RECT
*lpRect
, UINT uFlags
)
281 return DrawCaptionTempA (hwnd
, hdc
, lpRect
, 0, 0, NULL
, uFlags
& 0x1F);
285 /***********************************************************************
286 * DrawCaptionTempA (USER32.@)
288 BOOL WINAPI
DrawCaptionTempA (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
289 HICON hIcon
, LPCSTR str
, UINT uFlags
)
295 if (!(uFlags
& DC_TEXT
) || !str
)
296 return DrawCaptionTempW( hwnd
, hdc
, rect
, hFont
, hIcon
, NULL
, uFlags
);
298 len
= MultiByteToWideChar( CP_ACP
, 0, str
, -1, NULL
, 0 );
299 if ((strW
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) )))
301 MultiByteToWideChar( CP_ACP
, 0, str
, -1, strW
, len
);
302 ret
= DrawCaptionTempW (hwnd
, hdc
, rect
, hFont
, hIcon
, strW
, uFlags
);
303 HeapFree( GetProcessHeap (), 0, strW
);
309 /***********************************************************************
310 * DrawCaptionTempW (USER32.@)
312 BOOL WINAPI
DrawCaptionTempW (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
313 HICON hIcon
, LPCWSTR str
, UINT uFlags
)
317 TRACE("(%p,%p,%p,%p,%p,%s,%08x)\n",
318 hwnd
, hdc
, rect
, hFont
, hIcon
, debugstr_w(str
), uFlags
);
320 /* drawing background */
321 if (uFlags
& DC_INBUTTON
) {
322 FillRect (hdc
, &rc
, GetSysColorBrush (COLOR_3DFACE
));
324 if (uFlags
& DC_ACTIVE
) {
325 HBRUSH hbr
= SelectObject (hdc
, CACHE_GetPattern55AABrush ());
326 PatBlt (hdc
, rc
.left
, rc
.top
,
327 rc
.right
-rc
.left
, rc
.bottom
-rc
.top
, 0xFA0089);
328 SelectObject (hdc
, hbr
);
332 FillRect (hdc
, &rc
, GetSysColorBrush ((uFlags
& DC_ACTIVE
) ?
333 COLOR_ACTIVECAPTION
: COLOR_INACTIVECAPTION
));
338 if ((uFlags
& DC_ICON
) && !(uFlags
& DC_SMALLCAP
)) {
342 pt
.y
= (rc
.bottom
+ rc
.top
- GetSystemMetrics(SM_CYSMICON
)) / 2;
344 if (!hIcon
) hIcon
= NC_IconForWindow(hwnd
);
345 DrawIconEx (hdc
, pt
.x
, pt
.y
, hIcon
, GetSystemMetrics(SM_CXSMICON
),
346 GetSystemMetrics(SM_CYSMICON
), 0, 0, DI_NORMAL
);
347 rc
.left
+= (rc
.bottom
- rc
.top
);
351 if (uFlags
& DC_TEXT
) {
354 if (uFlags
& DC_INBUTTON
)
355 SetTextColor (hdc
, GetSysColor (COLOR_BTNTEXT
));
356 else if (uFlags
& DC_ACTIVE
)
357 SetTextColor (hdc
, GetSysColor (COLOR_CAPTIONTEXT
));
359 SetTextColor (hdc
, GetSysColor (COLOR_INACTIVECAPTIONTEXT
));
361 SetBkMode (hdc
, TRANSPARENT
);
364 hOldFont
= SelectObject (hdc
, hFont
);
366 NONCLIENTMETRICSW nclm
;
368 nclm
.cbSize
= sizeof(NONCLIENTMETRICSW
);
369 SystemParametersInfoW (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
370 hNewFont
= CreateFontIndirectW ((uFlags
& DC_SMALLCAP
) ?
371 &nclm
.lfSmCaptionFont
: &nclm
.lfCaptionFont
);
372 hOldFont
= SelectObject (hdc
, hNewFont
);
376 DrawTextW (hdc
, str
, -1, &rc
,
377 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
381 nLen
= GetWindowTextW (hwnd
, szText
, 128);
382 DrawTextW (hdc
, szText
, nLen
, &rc
,
383 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
387 SelectObject (hdc
, hOldFont
);
389 DeleteObject (SelectObject (hdc
, hOldFont
));
392 /* drawing focus ??? */
394 FIXME("undocumented flag (0x2000)!\n");
400 /***********************************************************************
401 * AdjustWindowRect (USER.102)
403 BOOL16 WINAPI
AdjustWindowRect16( LPRECT16 rect
, DWORD style
, BOOL16 menu
)
405 return AdjustWindowRectEx16( rect
, style
, menu
, 0 );
409 /***********************************************************************
410 * AdjustWindowRect (USER32.@)
412 BOOL WINAPI
AdjustWindowRect( LPRECT rect
, DWORD style
, BOOL menu
)
414 return AdjustWindowRectEx( rect
, style
, menu
, 0 );
418 /***********************************************************************
419 * AdjustWindowRectEx (USER.454)
421 BOOL16 WINAPI
AdjustWindowRectEx16( LPRECT16 rect
, DWORD style
,
422 BOOL16 menu
, DWORD exStyle
)
427 CONV_RECT16TO32( rect
, &rect32
);
428 ret
= AdjustWindowRectEx( &rect32
, style
, menu
, exStyle
);
429 CONV_RECT32TO16( &rect32
, rect
);
434 /***********************************************************************
435 * AdjustWindowRectEx (USER32.@)
437 BOOL WINAPI
AdjustWindowRectEx( LPRECT rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
439 /* Correct the window style */
440 style
&= (WS_DLGFRAME
| WS_BORDER
| WS_THICKFRAME
| WS_CHILD
);
441 exStyle
&= (WS_EX_DLGMODALFRAME
| WS_EX_CLIENTEDGE
|
442 WS_EX_STATICEDGE
| WS_EX_TOOLWINDOW
);
443 if (exStyle
& WS_EX_DLGMODALFRAME
) style
&= ~WS_THICKFRAME
;
445 TRACE("(%ld,%ld)-(%ld,%ld) %08lx %d %08lx\n",
446 rect
->left
, rect
->top
, rect
->right
, rect
->bottom
,
447 style
, menu
, exStyle
);
449 if (TWEAK_WineLook
== WIN31_LOOK
)
450 NC_AdjustRect( rect
, style
, menu
, exStyle
);
453 NC_AdjustRectOuter95( rect
, style
, menu
, exStyle
);
454 NC_AdjustRectInner95( rect
, style
, exStyle
);
460 /***********************************************************************
461 * NC_HandleNCCalcSize
463 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
465 LONG
NC_HandleNCCalcSize( HWND hwnd
, RECT
*winRect
)
467 RECT tmpRect
= { 0, 0, 0, 0 };
469 LONG cls_style
= GetClassLongA(hwnd
, GCL_STYLE
);
470 LONG style
= GetWindowLongA( hwnd
, GWL_STYLE
);
471 LONG exStyle
= GetWindowLongA( hwnd
, GWL_EXSTYLE
);
473 if (cls_style
& CS_VREDRAW
) result
|= WVR_VREDRAW
;
474 if (cls_style
& CS_HREDRAW
) result
|= WVR_HREDRAW
;
478 if (TWEAK_WineLook
== WIN31_LOOK
)
479 NC_AdjustRect( &tmpRect
, style
, FALSE
, exStyle
);
481 NC_AdjustRectOuter95( &tmpRect
, style
, FALSE
, exStyle
);
483 winRect
->left
-= tmpRect
.left
;
484 winRect
->top
-= tmpRect
.top
;
485 winRect
->right
-= tmpRect
.right
;
486 winRect
->bottom
-= tmpRect
.bottom
;
488 if (!(style
& WS_CHILD
) && GetMenu(hwnd
))
490 TRACE("Calling GetMenuBarHeight with hwnd %p, width %ld, at (%ld, %ld).\n",
491 hwnd
, winRect
->right
- winRect
->left
, -tmpRect
.left
, -tmpRect
.top
);
494 MENU_GetMenuBarHeight( hwnd
,
495 winRect
->right
- winRect
->left
,
496 -tmpRect
.left
, -tmpRect
.top
) + 1;
499 if (TWEAK_WineLook
> WIN31_LOOK
) {
500 SetRect(&tmpRect
, 0, 0, 0, 0);
501 NC_AdjustRectInner95 (&tmpRect
, style
, exStyle
);
502 winRect
->left
-= tmpRect
.left
;
503 winRect
->top
-= tmpRect
.top
;
504 winRect
->right
-= tmpRect
.right
;
505 winRect
->bottom
-= tmpRect
.bottom
;
508 if (winRect
->top
> winRect
->bottom
)
509 winRect
->bottom
= winRect
->top
;
511 if (winRect
->left
> winRect
->right
)
512 winRect
->right
= winRect
->left
;
518 /***********************************************************************
521 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
522 * but without the borders (if any).
523 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
525 void NC_GetInsideRect( HWND hwnd
, RECT
*rect
)
527 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
529 rect
->top
= rect
->left
= 0;
530 rect
->right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
531 rect
->bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
533 if (wndPtr
->dwStyle
& WS_ICONIC
) goto END
;
535 /* Remove frame from rectangle */
536 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
538 InflateRect( rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
540 else if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
542 InflateRect( rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
543 /* FIXME: this isn't in NC_AdjustRect? why not? */
544 if ((TWEAK_WineLook
== WIN31_LOOK
) && (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
))
545 InflateRect( rect
, -1, 0 );
547 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
549 InflateRect( rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
) );
552 /* We have additional border information if the window
553 * is a child (but not an MDI child) */
554 if (TWEAK_WineLook
!= WIN31_LOOK
)
556 if ( (wndPtr
->dwStyle
& WS_CHILD
) &&
557 ( (wndPtr
->dwExStyle
& WS_EX_MDICHILD
) == 0 ) )
559 if (wndPtr
->dwExStyle
& WS_EX_CLIENTEDGE
)
560 InflateRect (rect
, -GetSystemMetrics(SM_CXEDGE
), -GetSystemMetrics(SM_CYEDGE
));
561 if (wndPtr
->dwExStyle
& WS_EX_STATICEDGE
)
562 InflateRect (rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
567 WIN_ReleaseWndPtr(wndPtr
);
572 /***********************************************************************
575 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
578 static LONG
NC_DoNCHitTest (WND
*wndPtr
, POINT pt
)
582 TRACE("hwnd=%p pt=%ld,%ld\n", wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
584 GetWindowRect(wndPtr
->hwndSelf
, &rect
);
585 if (!PtInRect( &rect
, pt
)) return HTNOWHERE
;
587 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
590 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
592 InflateRect( &rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
593 if (!PtInRect( &rect
, pt
))
595 /* Check top sizing border */
598 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
599 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
602 /* Check bottom sizing border */
603 if (pt
.y
>= rect
.bottom
)
605 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
606 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
609 /* Check left sizing border */
610 if (pt
.x
< rect
.left
)
612 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
613 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
616 /* Check right sizing border */
617 if (pt
.x
>= rect
.right
)
619 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
620 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
625 else /* No thick frame */
627 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
628 InflateRect(&rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
629 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
630 InflateRect(&rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
631 if (!PtInRect( &rect
, pt
)) return HTBORDER
;
636 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
638 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
) - GetSystemMetrics(SM_CYBORDER
);
639 if (!PtInRect( &rect
, pt
))
641 /* Check system menu */
642 if ((wndPtr
->dwStyle
& WS_SYSMENU
) && !(wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
))
643 rect
.left
+= GetSystemMetrics(SM_CXSIZE
);
644 if (pt
.x
<= rect
.left
) return HTSYSMENU
;
646 /* Check maximize box */
647 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
648 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
650 if (pt
.x
>= rect
.right
) return HTMAXBUTTON
;
651 /* Check minimize box */
652 if (wndPtr
->dwStyle
& WS_MINIMIZEBOX
)
653 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
654 if (pt
.x
>= rect
.right
) return HTMINBUTTON
;
659 /* Check client area */
661 ScreenToClient( wndPtr
->hwndSelf
, &pt
);
662 GetClientRect( wndPtr
->hwndSelf
, &rect
);
663 if (PtInRect( &rect
, pt
)) return HTCLIENT
;
665 /* Check vertical scroll bar */
667 if (wndPtr
->dwStyle
& WS_VSCROLL
)
669 if((wndPtr
->dwExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
670 rect
.left
-= GetSystemMetrics(SM_CXVSCROLL
);
672 rect
.right
+= GetSystemMetrics(SM_CXVSCROLL
);
673 if (PtInRect( &rect
, pt
)) return HTVSCROLL
;
676 /* Check horizontal scroll bar */
678 if (wndPtr
->dwStyle
& WS_HSCROLL
)
680 rect
.bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
681 if (PtInRect( &rect
, pt
))
684 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
685 ((((wndPtr
->dwExStyle
& WS_EX_LEFTSCROLLBAR
) != 0) && (pt
.x
<= rect
.left
+ GetSystemMetrics(SM_CXVSCROLL
))) ||
686 (((wndPtr
->dwExStyle
& WS_EX_LEFTSCROLLBAR
) == 0) && (pt
.x
>= rect
.right
- GetSystemMetrics(SM_CXVSCROLL
)))))
694 if (HAS_MENU(wndPtr
))
696 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
700 /* Has to return HTNOWHERE if nothing was found
701 Could happen when a window has a customized non client area */
706 /***********************************************************************
709 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
711 * FIXME: Just a modified copy of the Win 3.1 version.
714 static LONG
NC_DoNCHitTest95 (WND
*wndPtr
, POINT pt
)
718 TRACE("hwnd=%p pt=%ld,%ld\n", wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
720 GetWindowRect(wndPtr
->hwndSelf
, &rect
);
721 if (!PtInRect( &rect
, pt
)) return HTNOWHERE
;
723 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
726 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
728 InflateRect( &rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
729 if (!PtInRect( &rect
, pt
))
731 /* Check top sizing border */
734 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
735 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
738 /* Check bottom sizing border */
739 if (pt
.y
>= rect
.bottom
)
741 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
742 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
745 /* Check left sizing border */
746 if (pt
.x
< rect
.left
)
748 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
749 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
752 /* Check right sizing border */
753 if (pt
.x
>= rect
.right
)
755 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
756 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
761 else /* No thick frame */
763 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
764 InflateRect(&rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
765 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
766 InflateRect(&rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
767 if (!PtInRect( &rect
, pt
)) return HTBORDER
;
772 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
774 if (wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
)
775 rect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
) - 1;
777 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
778 if (!PtInRect( &rect
, pt
))
780 /* Check system menu */
781 if ((wndPtr
->dwStyle
& WS_SYSMENU
) && !(wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
))
783 if (NC_IconForWindow(wndPtr
->hwndSelf
))
784 rect
.left
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
786 if (pt
.x
< rect
.left
) return HTSYSMENU
;
788 /* Check close button */
789 if (wndPtr
->dwStyle
& WS_SYSMENU
)
790 rect
.right
-= GetSystemMetrics(SM_CYCAPTION
) - 1;
791 if (pt
.x
> rect
.right
) return HTCLOSE
;
793 /* Check maximize box */
794 /* In win95 there is automatically a Maximize button when there is a minimize one*/
795 if ((wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)|| (wndPtr
->dwStyle
& WS_MINIMIZEBOX
))
796 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
797 if (pt
.x
> rect
.right
) return HTMAXBUTTON
;
799 /* Check minimize box */
800 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
801 if ((wndPtr
->dwStyle
& WS_MINIMIZEBOX
)||(wndPtr
->dwStyle
& WS_MAXIMIZEBOX
))
802 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
804 if (pt
.x
> rect
.right
) return HTMINBUTTON
;
809 /* Check client area */
811 ScreenToClient( wndPtr
->hwndSelf
, &pt
);
812 GetClientRect( wndPtr
->hwndSelf
, &rect
);
813 if (PtInRect( &rect
, pt
)) return HTCLIENT
;
815 /* Check vertical scroll bar */
817 if (wndPtr
->dwStyle
& WS_VSCROLL
)
819 if((wndPtr
->dwExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
820 rect
.left
-= GetSystemMetrics(SM_CXVSCROLL
);
822 rect
.right
+= GetSystemMetrics(SM_CXVSCROLL
);
823 if (PtInRect( &rect
, pt
)) return HTVSCROLL
;
826 /* Check horizontal scroll bar */
828 if (wndPtr
->dwStyle
& WS_HSCROLL
)
830 rect
.bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
831 if (PtInRect( &rect
, pt
))
834 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
835 ((((wndPtr
->dwExStyle
& WS_EX_LEFTSCROLLBAR
) != 0) && (pt
.x
<= rect
.left
+ GetSystemMetrics(SM_CXVSCROLL
))) ||
836 (((wndPtr
->dwExStyle
& WS_EX_LEFTSCROLLBAR
) == 0) && (pt
.x
>= rect
.right
- GetSystemMetrics(SM_CXVSCROLL
)))))
844 if (HAS_MENU(wndPtr
))
846 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
850 /* Has to return HTNOWHERE if nothing was found
851 Could happen when a window has a customized non client area */
856 /***********************************************************************
859 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
861 LONG
NC_HandleNCHitTest (HWND hwnd
, POINT pt
)
864 WND
*wndPtr
= WIN_FindWndPtr (hwnd
);
869 if (TWEAK_WineLook
== WIN31_LOOK
)
870 retvalue
= NC_DoNCHitTest (wndPtr
, pt
);
872 retvalue
= NC_DoNCHitTest95 (wndPtr
, pt
);
873 WIN_ReleaseWndPtr(wndPtr
);
878 /***********************************************************************
881 void NC_DrawSysButton( HWND hwnd
, HDC hdc
, BOOL down
)
887 NC_GetInsideRect( hwnd
, &rect
);
888 hdcMem
= CreateCompatibleDC( hdc
);
889 hbitmap
= SelectObject( hdcMem
, hbitmapClose
);
890 BitBlt(hdc
, rect
.left
, rect
.top
, GetSystemMetrics(SM_CXSIZE
), GetSystemMetrics(SM_CYSIZE
),
891 hdcMem
, (GetWindowLongA(hwnd
,GWL_STYLE
) & WS_CHILD
) ? GetSystemMetrics(SM_CXSIZE
) : 0, 0,
892 down
? NOTSRCCOPY
: SRCCOPY
);
893 SelectObject( hdcMem
, hbitmap
);
898 /***********************************************************************
901 static void NC_DrawMaxButton( HWND hwnd
, HDC hdc
, BOOL down
)
904 UINT flags
= IsZoomed(hwnd
) ? DFCS_CAPTIONRESTORE
: DFCS_CAPTIONMAX
;
906 NC_GetInsideRect( hwnd
, &rect
);
907 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
) + 1;
908 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
911 if (down
) flags
|= DFCS_PUSHED
;
912 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
916 /***********************************************************************
919 static void NC_DrawMinButton( HWND hwnd
, HDC hdc
, BOOL down
)
922 UINT flags
= DFCS_CAPTIONMIN
;
923 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
925 NC_GetInsideRect( hwnd
, &rect
);
926 if (style
& (WS_MAXIMIZEBOX
|WS_MINIMIZEBOX
))
927 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) - 2;
928 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
) + 1;
929 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
932 if (down
) flags
|= DFCS_PUSHED
;
933 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
937 /******************************************************************************
939 * void NC_DrawSysButton95(
944 * Draws the Win95 system icon.
947 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
948 * Original implementation from NC_DrawSysButton source.
949 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
952 *****************************************************************************/
955 NC_DrawSysButton95 (HWND hwnd
, HDC hdc
, BOOL down
)
957 HICON hIcon
= NC_IconForWindow( hwnd
);
962 NC_GetInsideRect( hwnd
, &rect
);
963 DrawIconEx (hdc
, rect
.left
+ 1, rect
.top
+ 1, hIcon
,
964 GetSystemMetrics(SM_CXSIZE
) - 1,
965 GetSystemMetrics(SM_CYSIZE
) - 1, 0, 0, DI_NORMAL
);
971 /******************************************************************************
973 * void NC_DrawCloseButton95(
979 * Draws the Win95 close button.
981 * If bGrayed is true, then draw a disabled Close button
984 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
985 * Original implementation from NC_DrawSysButton95 source.
987 *****************************************************************************/
989 static void NC_DrawCloseButton95 (HWND hwnd
, HDC hdc
, BOOL down
, BOOL bGrayed
)
993 NC_GetInsideRect( hwnd
, &rect
);
995 /* A tool window has a smaller Close button */
996 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_TOOLWINDOW
)
998 INT iBmpHeight
= 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
999 INT iBmpWidth
= 11; /* it uses 11x11 for the close button in tool window */
1000 INT iCaptionHeight
= GetSystemMetrics(SM_CYSMCAPTION
);
1002 rect
.top
= rect
.top
+ (iCaptionHeight
- 1 - iBmpHeight
) / 2;
1003 rect
.left
= rect
.right
- (iCaptionHeight
+ 1 + iBmpWidth
) / 2;
1004 rect
.bottom
= rect
.top
+ iBmpHeight
;
1005 rect
.right
= rect
.left
+ iBmpWidth
;
1009 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
) - 1;
1010 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1014 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
,
1015 (DFCS_CAPTIONCLOSE
|
1016 (down
? DFCS_PUSHED
: 0) |
1017 (bGrayed
? DFCS_INACTIVE
: 0)) );
1020 /******************************************************************************
1021 * NC_DrawMaxButton95
1023 * Draws the maximize button for Win95 style windows.
1024 * If bGrayed is true, then draw a disabled Maximize button
1026 static void NC_DrawMaxButton95(HWND hwnd
,HDC hdc
,BOOL down
, BOOL bGrayed
)
1029 UINT flags
= IsZoomed(hwnd
) ? DFCS_CAPTIONRESTORE
: DFCS_CAPTIONMAX
;
1031 NC_GetInsideRect( hwnd
, &rect
);
1032 if (GetWindowLongA( hwnd
, GWL_STYLE
) & WS_SYSMENU
)
1033 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
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 /******************************************************************************
1044 * NC_DrawMinButton95
1046 * Draws the minimize button for Win95 style windows.
1047 * If bGrayed is true, then draw a disabled Minimize button
1049 static void NC_DrawMinButton95(HWND hwnd
,HDC hdc
,BOOL down
, BOOL bGrayed
)
1052 UINT flags
= DFCS_CAPTIONMIN
;
1053 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
1055 NC_GetInsideRect( hwnd
, &rect
);
1056 if (style
& WS_SYSMENU
)
1057 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1058 if (style
& (WS_MAXIMIZEBOX
|WS_MINIMIZEBOX
))
1059 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) - 2;
1060 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
);
1061 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1064 if (down
) flags
|= DFCS_PUSHED
;
1065 if (bGrayed
) flags
|= DFCS_INACTIVE
;
1066 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
1069 /***********************************************************************
1072 * Draw a window frame inside the given rectangle, and update the rectangle.
1073 * The correct pen for the frame must be selected in the DC.
1075 static void NC_DrawFrame( HDC hdc
, RECT
*rect
, BOOL dlgFrame
,
1080 if (TWEAK_WineLook
!= WIN31_LOOK
)
1081 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
1085 width
= GetSystemMetrics(SM_CXDLGFRAME
) - 1;
1086 height
= GetSystemMetrics(SM_CYDLGFRAME
) - 1;
1087 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1088 COLOR_INACTIVECAPTION
) );
1092 width
= GetSystemMetrics(SM_CXFRAME
) - 2;
1093 height
= GetSystemMetrics(SM_CYFRAME
) - 2;
1094 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1095 COLOR_INACTIVEBORDER
) );
1099 PatBlt( hdc
, rect
->left
, rect
->top
,
1100 rect
->right
- rect
->left
, height
, PATCOPY
);
1101 PatBlt( hdc
, rect
->left
, rect
->top
,
1102 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1103 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1104 rect
->right
- rect
->left
, -height
, PATCOPY
);
1105 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1106 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1110 InflateRect( rect
, -width
, -height
);
1114 INT decYOff
= GetSystemMetrics(SM_CXFRAME
) + GetSystemMetrics(SM_CXSIZE
) - 1;
1115 INT decXOff
= GetSystemMetrics(SM_CYFRAME
) + GetSystemMetrics(SM_CYSIZE
) - 1;
1117 /* Draw inner rectangle */
1119 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1120 Rectangle( hdc
, rect
->left
+ width
, rect
->top
+ height
,
1121 rect
->right
- width
, rect
->bottom
- height
);
1123 /* Draw the decorations */
1125 MoveToEx( hdc
, rect
->left
, rect
->top
+ decYOff
, NULL
);
1126 LineTo( hdc
, rect
->left
+ width
, rect
->top
+ decYOff
);
1127 MoveToEx( hdc
, rect
->right
- 1, rect
->top
+ decYOff
, NULL
);
1128 LineTo( hdc
, rect
->right
- width
- 1, rect
->top
+ decYOff
);
1129 MoveToEx( hdc
, rect
->left
, rect
->bottom
- decYOff
, NULL
);
1130 LineTo( hdc
, rect
->left
+ width
, rect
->bottom
- decYOff
);
1131 MoveToEx( hdc
, rect
->right
- 1, rect
->bottom
- decYOff
, NULL
);
1132 LineTo( hdc
, rect
->right
- width
- 1, rect
->bottom
- decYOff
);
1134 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->top
, NULL
);
1135 LineTo( hdc
, rect
->left
+ decXOff
, rect
->top
+ height
);
1136 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->bottom
- 1, NULL
);
1137 LineTo( hdc
, rect
->left
+ decXOff
, rect
->bottom
- height
- 1 );
1138 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->top
, NULL
);
1139 LineTo( hdc
, rect
->right
- decXOff
, rect
->top
+ height
);
1140 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->bottom
- 1, NULL
);
1141 LineTo( hdc
, rect
->right
- decXOff
, rect
->bottom
- height
- 1 );
1143 InflateRect( rect
, -width
- 1, -height
- 1 );
1148 /******************************************************************************
1150 * void NC_DrawFrame95(
1157 * Draw a window frame inside the given rectangle, and update the rectangle.
1160 * Many. First, just what IS a frame in Win95? Note that the 3D look
1161 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1162 * edge. The inner rectangle just inside the frame is handled by the
1165 * In short, for most people, this function should be a nop (unless
1166 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1167 * them lately, but just to get this code right). Even so, it doesn't
1168 * appear to be so. It's being worked on...
1171 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1172 * Original implementation (based on NC_DrawFrame)
1173 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1175 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1176 * Fixed a fix or something.
1178 *****************************************************************************/
1180 static void NC_DrawFrame95(
1189 /* Firstly the "thick" frame */
1190 if (style
& WS_THICKFRAME
)
1192 width
= GetSystemMetrics(SM_CXFRAME
) - GetSystemMetrics(SM_CXDLGFRAME
);
1193 height
= GetSystemMetrics(SM_CYFRAME
) - GetSystemMetrics(SM_CYDLGFRAME
);
1195 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1196 COLOR_INACTIVEBORDER
) );
1198 PatBlt( hdc
, rect
->left
, rect
->top
,
1199 rect
->right
- rect
->left
, height
, PATCOPY
);
1200 PatBlt( hdc
, rect
->left
, rect
->top
,
1201 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1202 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1203 rect
->right
- rect
->left
, -height
, PATCOPY
);
1204 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1205 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1207 InflateRect( rect
, -width
, -height
);
1210 /* Now the other bit of the frame */
1211 if ((style
& (WS_BORDER
|WS_DLGFRAME
)) ||
1212 (exStyle
& WS_EX_DLGMODALFRAME
))
1214 width
= GetSystemMetrics(SM_CXDLGFRAME
) - GetSystemMetrics(SM_CXEDGE
);
1215 height
= GetSystemMetrics(SM_CYDLGFRAME
) - GetSystemMetrics(SM_CYEDGE
);
1216 /* This should give a value of 1 that should also work for a border */
1218 SelectObject( hdc
, GetSysColorBrush(
1219 (exStyle
& (WS_EX_DLGMODALFRAME
|WS_EX_CLIENTEDGE
)) ?
1221 (exStyle
& WS_EX_STATICEDGE
) ?
1223 (style
& (WS_DLGFRAME
|WS_THICKFRAME
)) ?
1226 COLOR_WINDOWFRAME
));
1229 PatBlt( hdc
, rect
->left
, rect
->top
,
1230 rect
->right
- rect
->left
, height
, PATCOPY
);
1231 PatBlt( hdc
, rect
->left
, rect
->top
,
1232 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1233 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1234 rect
->right
- rect
->left
, -height
, PATCOPY
);
1235 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1236 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1238 InflateRect( rect
, -width
, -height
);
1243 /***********************************************************************
1246 * Draw the window caption.
1247 * The correct pen for the window frame must be selected in the DC.
1249 static void NC_DrawCaption( HDC hdc
, RECT
*rect
, HWND hwnd
,
1250 DWORD style
, BOOL active
)
1257 if (!(hbitmapClose
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_OLD_CLOSE
) ))) return;
1260 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_DLGMODALFRAME
)
1262 HBRUSH hbrushOld
= SelectObject(hdc
, GetSysColorBrush(COLOR_WINDOW
) );
1263 PatBlt( hdc
, r
.left
, r
.top
, 1, r
.bottom
-r
.top
+1,PATCOPY
);
1264 PatBlt( hdc
, r
.right
-1, r
.top
, 1, r
.bottom
-r
.top
+1, PATCOPY
);
1265 PatBlt( hdc
, r
.left
, r
.top
-1, r
.right
-r
.left
, 1, PATCOPY
);
1268 SelectObject( hdc
, hbrushOld
);
1270 MoveToEx( hdc
, r
.left
, r
.bottom
, NULL
);
1271 LineTo( hdc
, r
.right
, r
.bottom
);
1273 if (style
& WS_SYSMENU
)
1275 NC_DrawSysButton( hwnd
, hdc
, FALSE
);
1276 r
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
1277 MoveToEx( hdc
, r
.left
- 1, r
.top
, NULL
);
1278 LineTo( hdc
, r
.left
- 1, r
.bottom
);
1280 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
: COLOR_INACTIVECAPTION
) );
1281 if (style
& WS_MAXIMIZEBOX
)
1283 NC_DrawMaxButton( hwnd
, hdc
, FALSE
);
1284 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1286 if (style
& WS_MINIMIZEBOX
)
1288 NC_DrawMinButton( hwnd
, hdc
, FALSE
);
1289 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1292 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) ))
1294 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1295 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1296 SetBkMode( hdc
, TRANSPARENT
);
1297 DrawTextA( hdc
, buffer
, -1, &r
,
1298 DT_SINGLELINE
| DT_CENTER
| DT_VCENTER
| DT_NOPREFIX
);
1303 /******************************************************************************
1312 * Draw the window caption for Win95 style windows.
1313 * The correct pen for the window frame must be selected in the DC.
1316 * Hey, a function that finally works! Well, almost.
1317 * It's being worked on.
1320 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1321 * Original implementation.
1322 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1325 *****************************************************************************/
1327 static void NC_DrawCaption95(
1340 hPrevPen
= SelectObject( hdc
, SYSCOLOR_GetPen(
1341 ((exStyle
& (WS_EX_STATICEDGE
|WS_EX_CLIENTEDGE
|
1342 WS_EX_DLGMODALFRAME
)) == WS_EX_STATICEDGE
) ?
1343 COLOR_WINDOWFRAME
: COLOR_3DFACE
) );
1344 MoveToEx( hdc
, r
.left
, r
.bottom
- 1, NULL
);
1345 LineTo( hdc
, r
.right
, r
.bottom
- 1 );
1346 SelectObject( hdc
, hPrevPen
);
1349 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1350 COLOR_INACTIVECAPTION
) );
1352 if ((style
& WS_SYSMENU
) && !(exStyle
& WS_EX_TOOLWINDOW
)) {
1353 if (NC_DrawSysButton95 (hwnd
, hdc
, FALSE
))
1354 r
.left
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
1357 if (style
& WS_SYSMENU
)
1361 /* Go get the sysmenu */
1362 hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1363 state
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
);
1365 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1366 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
,
1367 ((((state
& MF_DISABLED
) || (state
& MF_GRAYED
))) && (state
!= 0xFFFFFFFF)));
1368 r
.right
-= GetSystemMetrics(SM_CYCAPTION
) - 1;
1370 if ((style
& WS_MAXIMIZEBOX
) || (style
& WS_MINIMIZEBOX
))
1372 /* In win95 the two buttons are always there */
1373 /* But if the menu item is not in the menu they're disabled*/
1375 NC_DrawMaxButton95( hwnd
, hdc
, FALSE
, (!(style
& WS_MAXIMIZEBOX
)));
1376 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1378 NC_DrawMinButton95( hwnd
, hdc
, FALSE
, (!(style
& WS_MINIMIZEBOX
)));
1379 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1383 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) )) {
1384 NONCLIENTMETRICSA nclm
;
1385 HFONT hFont
, hOldFont
;
1386 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
1387 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
1388 if (exStyle
& WS_EX_TOOLWINDOW
)
1389 hFont
= CreateFontIndirectA (&nclm
.lfSmCaptionFont
);
1391 hFont
= CreateFontIndirectA (&nclm
.lfCaptionFont
);
1392 hOldFont
= SelectObject (hdc
, hFont
);
1393 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1394 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1395 SetBkMode( hdc
, TRANSPARENT
);
1397 DrawTextA( hdc
, buffer
, -1, &r
,
1398 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
1399 DeleteObject (SelectObject (hdc
, hOldFont
));
1405 /***********************************************************************
1408 * Paint the non-client area. clip is currently unused.
1410 static void NC_DoNCPaint( HWND hwnd
, HRGN clip
, BOOL suppress_menupaint
)
1416 DWORD dwStyle
, dwExStyle
;
1418 RECT rectClient
, rectWindow
;
1421 if (!(wndPtr
= WIN_GetPtr( hwnd
)) || wndPtr
== WND_OTHER_PROCESS
) return;
1422 has_menu
= HAS_MENU(wndPtr
);
1423 dwStyle
= wndPtr
->dwStyle
;
1424 dwExStyle
= wndPtr
->dwExStyle
;
1425 flags
= wndPtr
->flags
;
1426 rectClient
= wndPtr
->rectClient
;
1427 rectWindow
= wndPtr
->rectWindow
;
1428 WIN_ReleasePtr( wndPtr
);
1430 if ( dwStyle
& WS_MINIMIZE
||
1431 !WIN_IsWindowDrawable( hwnd
, 0 )) return; /* Nothing to do */
1433 active
= flags
& WIN_NCACTIVATED
;
1435 TRACE("%p %d\n", hwnd
, active
);
1437 if (!(hdc
= GetDCEx( hwnd
, (clip
> (HRGN
)1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
1438 ((clip
> (HRGN
)1) ? (DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
): 0) ))) return;
1440 if (ExcludeVisRect16( HDC_16(hdc
), rectClient
.left
-rectWindow
.left
,
1441 rectClient
.top
-rectWindow
.top
,
1442 rectClient
.right
-rectWindow
.left
,
1443 rectClient
.bottom
-rectWindow
.top
)
1446 ReleaseDC( hwnd
, hdc
);
1450 rect
.top
= rect
.left
= 0;
1451 rect
.right
= rectWindow
.right
- rectWindow
.left
;
1452 rect
.bottom
= rectWindow
.bottom
- rectWindow
.top
;
1454 SelectObject( hdc
, SYSCOLOR_GetPen(COLOR_WINDOWFRAME
) );
1456 if (HAS_ANYFRAME( dwStyle
, dwExStyle
))
1458 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1459 Rectangle( hdc
, 0, 0, rect
.right
, rect
.bottom
);
1460 InflateRect( &rect
, -1, -1 );
1463 if (HAS_THICKFRAME( dwStyle
, dwExStyle
))
1464 NC_DrawFrame(hdc
, &rect
, FALSE
, active
);
1465 else if (HAS_DLGFRAME( dwStyle
, dwExStyle
))
1466 NC_DrawFrame( hdc
, &rect
, TRUE
, active
);
1468 if ((dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1471 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
);
1472 rect
.top
+= GetSystemMetrics(SM_CYSIZE
) + GetSystemMetrics(SM_CYBORDER
);
1473 NC_DrawCaption( hdc
, &r
, hwnd
, dwStyle
, active
);
1479 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYMENU
); /* default height */
1480 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
);
1483 /* Draw the scroll-bars */
1485 if (dwStyle
& WS_VSCROLL
)
1486 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1487 if (dwStyle
& WS_HSCROLL
)
1488 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1490 /* Draw the "size-box" */
1492 if ((dwStyle
& WS_VSCROLL
) && (dwStyle
& WS_HSCROLL
))
1495 if((dwExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
1496 r
.right
= r
.left
+ GetSystemMetrics(SM_CXVSCROLL
) + 1;
1498 r
.left
= r
.right
- GetSystemMetrics(SM_CXVSCROLL
) + 1;
1499 r
.top
= r
.bottom
- GetSystemMetrics(SM_CYHSCROLL
) + 1;
1500 if(wndPtr
->dwStyle
& WS_BORDER
) {
1504 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1507 ReleaseDC( hwnd
, hdc
);
1511 /******************************************************************************
1513 * void NC_DoNCPaint95(
1516 * BOOL suppress_menupaint )
1518 * Paint the non-client area for Win95 windows. The clip region is
1519 * currently ignored.
1522 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1523 * misc/tweak.c controls/menu.c # :-)
1526 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1527 * Original implementation
1528 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1530 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1531 * Streamlined window style checks.
1533 *****************************************************************************/
1535 static void NC_DoNCPaint95(
1538 BOOL suppress_menupaint
)
1541 RECT rfuzz
, rect
, rectClip
;
1544 DWORD dwStyle
, dwExStyle
;
1546 RECT rectClient
, rectWindow
;
1549 if (!(wndPtr
= WIN_GetPtr( hwnd
)) || wndPtr
== WND_OTHER_PROCESS
) return;
1550 has_menu
= HAS_MENU(wndPtr
);
1551 dwStyle
= wndPtr
->dwStyle
;
1552 dwExStyle
= wndPtr
->dwExStyle
;
1553 flags
= wndPtr
->flags
;
1554 rectClient
= wndPtr
->rectClient
;
1555 rectWindow
= wndPtr
->rectWindow
;
1556 WIN_ReleasePtr( wndPtr
);
1558 if ( dwStyle
& WS_MINIMIZE
||
1559 !WIN_IsWindowDrawable( hwnd
, 0 )) return; /* Nothing to do */
1561 active
= flags
& WIN_NCACTIVATED
;
1563 TRACE("%p %d\n", hwnd
, active
);
1565 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1566 the call to GetDCEx implying that it is allowed not to use it either.
1567 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1568 will cause clipRgn to be deleted after ReleaseDC().
1569 Now, how is the "system" supposed to tell what happened?
1572 if (!(hdc
= GetDCEx( hwnd
, (clip
> (HRGN
)1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
1573 ((clip
> (HRGN
)1) ?(DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
) : 0) ))) return;
1576 if (ExcludeVisRect16( HDC_16(hdc
), rectClient
.left
-rectWindow
.left
,
1577 rectClient
.top
-rectWindow
.top
,
1578 rectClient
.right
-rectWindow
.left
,
1579 rectClient
.bottom
-rectWindow
.top
)
1582 ReleaseDC( hwnd
, hdc
);
1586 rect
.top
= rect
.left
= 0;
1587 rect
.right
= rectWindow
.right
- rectWindow
.left
;
1588 rect
.bottom
= rectWindow
.bottom
- rectWindow
.top
;
1590 if( clip
> (HRGN
)1 )
1591 GetRgnBox( clip
, &rectClip
);
1598 SelectObject( hdc
, SYSCOLOR_GetPen(COLOR_WINDOWFRAME
) );
1600 if (HAS_STATICOUTERFRAME(dwStyle
, dwExStyle
)) {
1601 DrawEdge (hdc
, &rect
, BDR_SUNKENOUTER
, BF_RECT
| BF_ADJUST
);
1603 else if (HAS_BIGFRAME( dwStyle
, dwExStyle
)) {
1604 DrawEdge (hdc
, &rect
, EDGE_RAISED
, BF_RECT
| BF_ADJUST
);
1607 NC_DrawFrame95(hdc
, &rect
, active
, dwStyle
, dwExStyle
);
1609 if ((dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1612 if (dwExStyle
& WS_EX_TOOLWINDOW
) {
1613 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSMCAPTION
);
1614 rect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
);
1617 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYCAPTION
);
1618 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
);
1620 if( !clip
|| IntersectRect( &rfuzz
, &r
, &rectClip
) )
1621 NC_DrawCaption95 (hdc
, &r
, hwnd
, dwStyle
,
1628 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYMENU
);
1630 TRACE("Calling DrawMenuBar with rect (%ld, %ld)-(%ld, %ld)\n",
1631 r
.left
, r
.top
, r
.right
, r
.bottom
);
1633 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
) + 1;
1636 TRACE("After MenuBar, rect is (%ld, %ld)-(%ld, %ld).\n",
1637 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1639 if (dwExStyle
& WS_EX_CLIENTEDGE
)
1640 DrawEdge (hdc
, &rect
, EDGE_SUNKEN
, BF_RECT
| BF_ADJUST
);
1642 /* Draw the scroll-bars */
1644 if (dwStyle
& WS_VSCROLL
)
1645 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1646 if (dwStyle
& WS_HSCROLL
)
1647 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1649 /* Draw the "size-box" */
1650 if ((dwStyle
& WS_VSCROLL
) && (dwStyle
& WS_HSCROLL
))
1653 if((dwExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
1654 r
.right
= r
.left
+ GetSystemMetrics(SM_CXVSCROLL
) + 1;
1656 r
.left
= r
.right
- GetSystemMetrics(SM_CXVSCROLL
) + 1;
1657 r
.top
= r
.bottom
- GetSystemMetrics(SM_CYHSCROLL
) + 1;
1658 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1661 ReleaseDC( hwnd
, hdc
);
1667 /***********************************************************************
1670 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1672 LONG
NC_HandleNCPaint( HWND hwnd
, HRGN clip
)
1674 DWORD dwStyle
= GetWindowLongW( hwnd
, GWL_STYLE
);
1676 if( dwStyle
& WS_VISIBLE
)
1678 if( dwStyle
& WS_MINIMIZE
)
1679 WINPOS_RedrawIconTitle( hwnd
);
1680 else if (TWEAK_WineLook
== WIN31_LOOK
)
1681 NC_DoNCPaint( hwnd
, clip
, FALSE
);
1683 NC_DoNCPaint95( hwnd
, clip
, FALSE
);
1689 /***********************************************************************
1690 * NC_HandleNCActivate
1692 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1694 LONG
NC_HandleNCActivate( HWND hwnd
, WPARAM wParam
)
1696 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1698 /* Lotus Notes draws menu descriptions in the caption of its main
1699 * window. When it wants to restore original "system" view, it just
1700 * sends WM_NCACTIVATE message to itself. Any optimizations here in
1701 * attempt to minimize redrawings lead to a not restored caption.
1705 if (wParam
) wndPtr
->flags
|= WIN_NCACTIVATED
;
1706 else wndPtr
->flags
&= ~WIN_NCACTIVATED
;
1707 WIN_ReleaseWndPtr(wndPtr
);
1709 if (IsIconic(hwnd
)) WINPOS_RedrawIconTitle( hwnd
);
1710 else if (TWEAK_WineLook
== WIN31_LOOK
)
1711 NC_DoNCPaint( hwnd
, (HRGN
)1, FALSE
);
1713 NC_DoNCPaint95( hwnd
, (HRGN
)1, FALSE
);
1719 /***********************************************************************
1720 * NC_HandleSetCursor
1722 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1724 LONG
NC_HandleSetCursor( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1726 hwnd
= WIN_GetFullHandle( (HWND
)wParam
);
1728 switch(LOWORD(lParam
))
1732 WORD msg
= HIWORD( lParam
);
1733 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_MBUTTONDOWN
) ||
1734 (msg
== WM_RBUTTONDOWN
))
1741 HCURSOR hCursor
= (HCURSOR
)GetClassLongA(hwnd
, GCL_HCURSOR
);
1751 return (LONG
)SetCursor( LoadCursorA( 0, (LPSTR
)IDC_SIZEWE
) );
1755 return (LONG
)SetCursor( LoadCursorA( 0, (LPSTR
)IDC_SIZENS
) );
1759 return (LONG
)SetCursor( LoadCursorA( 0, (LPSTR
)IDC_SIZENWSE
) );
1763 return (LONG
)SetCursor( LoadCursorA( 0, (LPSTR
)IDC_SIZENESW
) );
1766 /* Default cursor: arrow */
1767 return (LONG
)SetCursor( LoadCursorA( 0, (LPSTR
)IDC_ARROW
) );
1770 /***********************************************************************
1773 void NC_GetSysPopupPos( HWND hwnd
, RECT
* rect
)
1775 if (IsIconic(hwnd
)) GetWindowRect( hwnd
, rect
);
1778 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1779 if (!wndPtr
) return;
1781 NC_GetInsideRect( hwnd
, rect
);
1782 OffsetRect( rect
, wndPtr
->rectWindow
.left
, wndPtr
->rectWindow
.top
);
1783 if (wndPtr
->dwStyle
& WS_CHILD
)
1784 ClientToScreen( GetParent(hwnd
), (POINT
*)rect
);
1785 if (TWEAK_WineLook
== WIN31_LOOK
) {
1786 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CXSIZE
);
1787 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYSIZE
);
1790 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
1791 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
1793 WIN_ReleaseWndPtr( wndPtr
);
1797 /***********************************************************************
1798 * NC_TrackMinMaxBox95
1800 * Track a mouse button press on the minimize or maximize box.
1802 * The big difference between 3.1 and 95 is the disabled button state.
1803 * In win95 the system button can be disabled, so it can ignore the mouse
1807 static void NC_TrackMinMaxBox95( HWND hwnd
, WORD wParam
)
1810 HDC hdc
= GetWindowDC( hwnd
);
1811 BOOL pressed
= TRUE
;
1813 DWORD wndStyle
= GetWindowLongA( hwnd
, GWL_STYLE
);
1814 HMENU hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1816 void (*paintButton
)(HWND
, HDC
, BOOL
, BOOL
);
1818 if (wParam
== HTMINBUTTON
)
1820 /* If the style is not present, do nothing */
1821 if (!(wndStyle
& WS_MINIMIZEBOX
))
1824 /* Check if the sysmenu item for minimize is there */
1825 state
= GetMenuState(hSysMenu
, SC_MINIMIZE
, MF_BYCOMMAND
);
1827 paintButton
= &NC_DrawMinButton95
;
1831 /* If the style is not present, do nothing */
1832 if (!(wndStyle
& WS_MAXIMIZEBOX
))
1835 /* Check if the sysmenu item for maximize is there */
1836 state
= GetMenuState(hSysMenu
, SC_MAXIMIZE
, MF_BYCOMMAND
);
1838 paintButton
= &NC_DrawMaxButton95
;
1843 (*paintButton
)( hwnd
, hdc
, TRUE
, FALSE
);
1847 BOOL oldstate
= pressed
;
1849 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1850 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1852 if(msg
.message
== WM_LBUTTONUP
)
1855 if(msg
.message
!= WM_MOUSEMOVE
)
1858 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1859 if (pressed
!= oldstate
)
1860 (*paintButton
)( hwnd
, hdc
, pressed
, FALSE
);
1864 (*paintButton
)(hwnd
, hdc
, FALSE
, FALSE
);
1867 ReleaseDC( hwnd
, hdc
);
1869 /* If the item minimize or maximize of the sysmenu are not there */
1870 /* or if the style is not present, do nothing */
1871 if ((!pressed
) || (state
== 0xFFFFFFFF))
1874 if (wParam
== HTMINBUTTON
)
1875 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1877 SendMessageA( hwnd
, WM_SYSCOMMAND
,
1878 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1881 /***********************************************************************
1884 * Track a mouse button press on the minimize or maximize box.
1886 static void NC_TrackMinMaxBox( HWND hwnd
, WORD wParam
)
1889 HDC hdc
= GetWindowDC( hwnd
);
1890 BOOL pressed
= TRUE
;
1891 void (*paintButton
)(HWND
, HDC
, BOOL
);
1895 if (wParam
== HTMINBUTTON
)
1896 paintButton
= &NC_DrawMinButton
;
1898 paintButton
= &NC_DrawMaxButton
;
1900 (*paintButton
)( hwnd
, hdc
, TRUE
);
1904 BOOL oldstate
= pressed
;
1906 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1907 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1909 if(msg
.message
== WM_LBUTTONUP
)
1912 if(msg
.message
!= WM_MOUSEMOVE
)
1915 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1916 if (pressed
!= oldstate
)
1917 (*paintButton
)( hwnd
, hdc
, pressed
);
1921 (*paintButton
)( hwnd
, hdc
, FALSE
);
1924 ReleaseDC( hwnd
, hdc
);
1926 if (!pressed
) return;
1928 if (wParam
== HTMINBUTTON
)
1929 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1931 SendMessageA( hwnd
, WM_SYSCOMMAND
,
1932 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1936 /***********************************************************************
1937 * NC_TrackCloseButton95
1939 * Track a mouse button press on the Win95 close button.
1942 NC_TrackCloseButton95 (HWND hwnd
, WORD wParam
)
1946 BOOL pressed
= TRUE
;
1947 HMENU hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1953 state
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
);
1955 /* If the item close of the sysmenu is disabled or not there do nothing */
1956 if((state
& MF_DISABLED
) || (state
& MF_GRAYED
) || (state
== 0xFFFFFFFF))
1959 hdc
= GetWindowDC( hwnd
);
1963 NC_DrawCloseButton95 (hwnd
, hdc
, TRUE
, FALSE
);
1967 BOOL oldstate
= pressed
;
1969 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1970 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1972 if(msg
.message
== WM_LBUTTONUP
)
1975 if(msg
.message
!= WM_MOUSEMOVE
)
1978 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1979 if (pressed
!= oldstate
)
1980 NC_DrawCloseButton95 (hwnd
, hdc
, pressed
, FALSE
);
1984 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
, FALSE
);
1987 ReleaseDC( hwnd
, hdc
);
1988 if (!pressed
) return;
1990 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1994 /***********************************************************************
1997 * Track a mouse button press on the horizontal or vertical scroll-bar.
1999 static void NC_TrackScrollBar( HWND hwnd
, WPARAM wParam
, POINT pt
)
2003 if ((wParam
& 0xfff0) == SC_HSCROLL
)
2005 if ((wParam
& 0x0f) != HTHSCROLL
) return;
2006 scrollbar
= SB_HORZ
;
2008 else /* SC_VSCROLL */
2010 if ((wParam
& 0x0f) != HTVSCROLL
) return;
2011 scrollbar
= SB_VERT
;
2013 SCROLL_TrackScrollBar( hwnd
, scrollbar
, pt
);
2017 /***********************************************************************
2018 * NC_HandleNCLButtonDown
2020 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2022 LONG
NC_HandleNCLButtonDown( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2024 LONG style
= GetWindowLongA( hwnd
, GWL_STYLE
);
2026 switch(wParam
) /* Hit test */
2030 HWND top
= GetAncestor( hwnd
, GA_ROOT
);
2032 if (FOCUS_MouseActivate( top
) || (GetActiveWindow() == top
))
2033 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOVE
+ HTCAPTION
, lParam
);
2038 if( style
& WS_SYSMENU
)
2040 if( !(style
& WS_MINIMIZE
) )
2042 HDC hDC
= GetWindowDC(hwnd
);
2043 if (TWEAK_WineLook
== WIN31_LOOK
)
2044 NC_DrawSysButton( hwnd
, hDC
, TRUE
);
2046 NC_DrawSysButton95( hwnd
, hDC
, TRUE
);
2047 ReleaseDC( hwnd
, hDC
);
2049 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
+ HTSYSMENU
, lParam
);
2054 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
, lParam
);
2058 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
2062 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
2067 if (TWEAK_WineLook
== WIN31_LOOK
)
2068 NC_TrackMinMaxBox( hwnd
, wParam
);
2070 NC_TrackMinMaxBox95( hwnd
, wParam
);
2074 if (TWEAK_WineLook
>= WIN95_LOOK
)
2075 NC_TrackCloseButton95 (hwnd
, wParam
);
2087 * "make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU"
2088 * This was previously done by setting wParam=SC_SIZE + wParam - 2
2090 /* But that is not what WinNT does. Instead it sends this. This
2091 * is easy to differentiate from HTSYSMENU, because HTSYSMENU adds
2092 * SC_MOUSEMENU into wParam.
2094 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_SIZE
+ wParam
- (HTLEFT
-WMSZ_LEFT
), lParam
);
2104 /***********************************************************************
2105 * NC_HandleNCLButtonDblClk
2107 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2109 LONG
NC_HandleNCLButtonDblClk( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2112 * if this is an icon, send a restore since we are handling
2117 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_RESTORE
, lParam
);
2121 switch(wParam
) /* Hit test */
2124 /* stop processing if WS_MAXIMIZEBOX is missing */
2125 if (GetWindowLongA( hwnd
, GWL_STYLE
) & WS_MAXIMIZEBOX
)
2126 SendMessageW( hwnd
, WM_SYSCOMMAND
,
2127 IsZoomed(hwnd
) ? SC_RESTORE
: SC_MAXIMIZE
, lParam
);
2131 if (!(GetClassLongW(hwnd
, GCL_STYLE
) & CS_NOCLOSE
))
2132 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, lParam
);
2136 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
2140 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
2147 /***********************************************************************
2148 * NC_HandleSysCommand
2150 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2152 LONG
NC_HandleSysCommand( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2154 TRACE("Handling WM_SYSCOMMAND %x %lx\n", wParam
, lParam
);
2156 switch (wParam
& 0xfff0)
2160 if (USER_Driver
.pSysCommandSizeMove
)
2161 USER_Driver
.pSysCommandSizeMove( hwnd
, wParam
);
2165 if (hwnd
== GetForegroundWindow())
2166 ShowOwnedPopups(hwnd
,FALSE
);
2167 ShowWindow( hwnd
, SW_MINIMIZE
);
2171 if (IsIconic(hwnd
) && hwnd
== GetForegroundWindow())
2172 ShowOwnedPopups(hwnd
,TRUE
);
2173 ShowWindow( hwnd
, SW_MAXIMIZE
);
2177 if (IsIconic(hwnd
) && hwnd
== GetForegroundWindow())
2178 ShowOwnedPopups(hwnd
,TRUE
);
2179 ShowWindow( hwnd
, SW_RESTORE
);
2183 return SendMessageA( hwnd
, WM_CLOSE
, 0, 0 );
2189 pt
.x
= (short)LOWORD(lParam
);
2190 pt
.y
= (short)HIWORD(lParam
);
2191 NC_TrackScrollBar( hwnd
, wParam
, pt
);
2198 pt
.x
= (short)LOWORD(lParam
);
2199 pt
.y
= (short)HIWORD(lParam
);
2200 MENU_TrackMouseMenuBar( hwnd
, wParam
& 0x000F, pt
);
2205 MENU_TrackKbdMenuBar( hwnd
, wParam
, (WCHAR
)lParam
);
2209 WinExec( "taskman.exe", SW_SHOWNORMAL
);
2213 if (wParam
== SC_ABOUTWINE
)
2215 HMODULE hmodule
= LoadLibraryA( "shell32.dll" );
2218 FARPROC aboutproc
= GetProcAddress( hmodule
, "ShellAboutA" );
2219 if (aboutproc
) aboutproc( hwnd
, PACKAGE_NAME
, PACKAGE_STRING
, 0 );
2220 FreeLibrary( hmodule
);
2224 if (wParam
== SC_PUTMARK
)
2225 TRACE_(shell
)("Mark requested by user\n");
2232 FIXME("unimplemented!\n");
2238 /*************************************************************
2241 * Stub for the grayed button of the caption
2243 *************************************************************/
2245 BOOL
NC_DrawGrayButton(HDC hdc
, int x
, int y
)
2251 hMaskBmp
= CreateBitmap (12, 10, 1, 1, lpGrayMask
);
2256 hdcMask
= CreateCompatibleDC (0);
2257 SelectObject (hdcMask
, hMaskBmp
);
2259 /* Draw the grayed bitmap using the mask */
2260 hOldBrush
= SelectObject (hdc
, (HGDIOBJ
)RGB(128, 128, 128));
2261 BitBlt (hdc
, x
, y
, 12, 10,
2262 hdcMask
, 0, 0, 0xB8074A);
2265 SelectObject (hdc
, hOldBrush
);
2266 DeleteObject(hMaskBmp
);
2272 /***********************************************************************
2273 * GetTitleBarInfo (USER32.@)
2274 * TODO: Handle STATE_SYSTEM_PRESSED
2276 BOOL WINAPI
GetTitleBarInfo(HWND hwnd
, PTITLEBARINFO tbi
) {
2281 TRACE("(%p %p)\n", hwnd
, tbi
);
2283 if(tbi
->cbSize
!= sizeof(TITLEBARINFO
)) {
2284 TRACE("Invalid TITLEBARINFO size: %ld\n", tbi
->cbSize
);
2285 SetLastError(ERROR_INVALID_PARAMETER
);
2288 dwStyle
= GetWindowLongW(hwnd
, GWL_STYLE
);
2289 dwExStyle
= GetWindowLongW(hwnd
, GWL_EXSTYLE
);
2290 NC_GetInsideRect(hwnd
, &tbi
->rcTitleBar
);
2292 GetWindowRect(hwnd
, &wndRect
);
2294 tbi
->rcTitleBar
.top
+= wndRect
.top
;
2295 tbi
->rcTitleBar
.left
+= wndRect
.left
;
2296 tbi
->rcTitleBar
.right
+= wndRect
.left
;
2298 tbi
->rcTitleBar
.bottom
= tbi
->rcTitleBar
.top
;
2299 if(dwExStyle
& WS_EX_TOOLWINDOW
)
2300 tbi
->rcTitleBar
.bottom
+= GetSystemMetrics(SM_CYSMCAPTION
);
2302 tbi
->rcTitleBar
.bottom
+= GetSystemMetrics(SM_CYCAPTION
);
2303 tbi
->rcTitleBar
.left
+= GetSystemMetrics(SM_CXSIZE
);
2306 ZeroMemory(&tbi
->rgstate
, sizeof(tbi
->rgstate
));
2307 /* Does the title bar always have STATE_SYSTEM_FOCUSABLE?
2308 * Under XP it seems to
2310 tbi
->rgstate
[0] = STATE_SYSTEM_FOCUSABLE
;
2311 if(dwStyle
& WS_CAPTION
) {
2312 tbi
->rgstate
[1] = STATE_SYSTEM_INVISIBLE
;
2313 if(dwStyle
& WS_SYSMENU
) {
2314 if(!(dwStyle
& (WS_MINIMIZEBOX
|WS_MAXIMIZEBOX
))) {
2315 tbi
->rgstate
[2] = STATE_SYSTEM_INVISIBLE
;
2316 tbi
->rgstate
[3] = STATE_SYSTEM_INVISIBLE
;
2319 if(!(dwStyle
& WS_MINIMIZEBOX
))
2320 tbi
->rgstate
[2] = STATE_SYSTEM_UNAVAILABLE
;
2321 if(!(dwStyle
& WS_MAXIMIZEBOX
))
2322 tbi
->rgstate
[3] = STATE_SYSTEM_UNAVAILABLE
;
2324 if(!(dwExStyle
& WS_EX_CONTEXTHELP
))
2325 tbi
->rgstate
[4] = STATE_SYSTEM_INVISIBLE
;
2326 if(GetClassLongW(hwnd
, GCL_STYLE
) & CS_NOCLOSE
)
2327 tbi
->rgstate
[5] = STATE_SYSTEM_UNAVAILABLE
;
2330 tbi
->rgstate
[2] = STATE_SYSTEM_INVISIBLE
;
2331 tbi
->rgstate
[3] = STATE_SYSTEM_INVISIBLE
;
2332 tbi
->rgstate
[4] = STATE_SYSTEM_INVISIBLE
;
2333 tbi
->rgstate
[5] = STATE_SYSTEM_INVISIBLE
;
2337 tbi
->rgstate
[0] |= STATE_SYSTEM_INVISIBLE
;