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
)
229 if((exStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
230 rect
->left
-= GetSystemMetrics(SM_CXVSCROLL
);
232 rect
->right
+= GetSystemMetrics(SM_CXVSCROLL
);
234 if (style
& WS_HSCROLL
) rect
->bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
239 static HICON
NC_IconForWindow( HWND hwnd
)
241 HICON hIcon
= (HICON
) GetClassLongA( hwnd
, GCL_HICONSM
);
242 if (!hIcon
) hIcon
= (HICON
) GetClassLongA( hwnd
, GCL_HICON
);
244 /* If there is no hIcon specified and this is a modal dialog,
245 * get the default one.
247 if (!hIcon
&& (GetWindowLongA( hwnd
, GWL_STYLE
) & DS_MODALFRAME
))
248 hIcon
= LoadImageA(0, IDI_WINLOGOA
, IMAGE_ICON
, 0, 0, LR_DEFAULTCOLOR
);
252 /***********************************************************************
253 * DrawCaption (USER32.@) Draws a caption bar
267 DrawCaption (HWND hwnd
, HDC hdc
, const RECT
*lpRect
, UINT uFlags
)
269 return DrawCaptionTempA (hwnd
, hdc
, lpRect
, 0, 0, NULL
, uFlags
& 0x1F);
273 /***********************************************************************
274 * DrawCaptionTempA (USER32.@)
276 BOOL WINAPI
DrawCaptionTempA (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
277 HICON hIcon
, LPCSTR str
, UINT uFlags
)
283 if (!(uFlags
& DC_TEXT
) || !str
)
284 return DrawCaptionTempW( hwnd
, hdc
, rect
, hFont
, hIcon
, NULL
, uFlags
);
286 len
= MultiByteToWideChar( CP_ACP
, 0, str
, -1, NULL
, 0 );
287 if ((strW
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) )))
289 MultiByteToWideChar( CP_ACP
, 0, str
, -1, strW
, len
);
290 ret
= DrawCaptionTempW (hwnd
, hdc
, rect
, hFont
, hIcon
, strW
, uFlags
);
291 HeapFree( GetProcessHeap (), 0, strW
);
297 /***********************************************************************
298 * DrawCaptionTempW (USER32.@)
300 BOOL WINAPI
DrawCaptionTempW (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
301 HICON hIcon
, LPCWSTR str
, UINT uFlags
)
305 TRACE("(%p,%p,%p,%p,%p,%s,%08x)\n",
306 hwnd
, hdc
, rect
, hFont
, hIcon
, debugstr_w(str
), uFlags
);
308 /* drawing background */
309 if (uFlags
& DC_INBUTTON
) {
310 FillRect (hdc
, &rc
, GetSysColorBrush (COLOR_3DFACE
));
312 if (uFlags
& DC_ACTIVE
) {
313 HBRUSH hbr
= SelectObject (hdc
, CACHE_GetPattern55AABrush ());
314 PatBlt (hdc
, rc
.left
, rc
.top
,
315 rc
.right
-rc
.left
, rc
.bottom
-rc
.top
, 0xFA0089);
316 SelectObject (hdc
, hbr
);
320 FillRect (hdc
, &rc
, GetSysColorBrush ((uFlags
& DC_ACTIVE
) ?
321 COLOR_ACTIVECAPTION
: COLOR_INACTIVECAPTION
));
326 if ((uFlags
& DC_ICON
) && !(uFlags
& DC_SMALLCAP
)) {
330 pt
.y
= (rc
.bottom
+ rc
.top
- GetSystemMetrics(SM_CYSMICON
)) / 2;
332 if (!hIcon
) hIcon
= NC_IconForWindow(hwnd
);
333 DrawIconEx (hdc
, pt
.x
, pt
.y
, hIcon
, GetSystemMetrics(SM_CXSMICON
),
334 GetSystemMetrics(SM_CYSMICON
), 0, 0, DI_NORMAL
);
335 rc
.left
+= (rc
.bottom
- rc
.top
);
339 if (uFlags
& DC_TEXT
) {
342 if (uFlags
& DC_INBUTTON
)
343 SetTextColor (hdc
, GetSysColor (COLOR_BTNTEXT
));
344 else if (uFlags
& DC_ACTIVE
)
345 SetTextColor (hdc
, GetSysColor (COLOR_CAPTIONTEXT
));
347 SetTextColor (hdc
, GetSysColor (COLOR_INACTIVECAPTIONTEXT
));
349 SetBkMode (hdc
, TRANSPARENT
);
352 hOldFont
= SelectObject (hdc
, hFont
);
354 NONCLIENTMETRICSW nclm
;
356 nclm
.cbSize
= sizeof(NONCLIENTMETRICSW
);
357 SystemParametersInfoW (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
358 hNewFont
= CreateFontIndirectW ((uFlags
& DC_SMALLCAP
) ?
359 &nclm
.lfSmCaptionFont
: &nclm
.lfCaptionFont
);
360 hOldFont
= SelectObject (hdc
, hNewFont
);
364 DrawTextW (hdc
, str
, -1, &rc
,
365 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
369 nLen
= GetWindowTextW (hwnd
, szText
, 128);
370 DrawTextW (hdc
, szText
, nLen
, &rc
,
371 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
375 SelectObject (hdc
, hOldFont
);
377 DeleteObject (SelectObject (hdc
, hOldFont
));
380 /* drawing focus ??? */
382 FIXME("undocumented flag (0x2000)!\n");
388 /***********************************************************************
389 * AdjustWindowRect (USER.102)
391 BOOL16 WINAPI
AdjustWindowRect16( LPRECT16 rect
, DWORD style
, BOOL16 menu
)
393 return AdjustWindowRectEx16( rect
, style
, menu
, 0 );
397 /***********************************************************************
398 * AdjustWindowRect (USER32.@)
400 BOOL WINAPI
AdjustWindowRect( LPRECT rect
, DWORD style
, BOOL menu
)
402 return AdjustWindowRectEx( rect
, style
, menu
, 0 );
406 /***********************************************************************
407 * AdjustWindowRectEx (USER.454)
409 BOOL16 WINAPI
AdjustWindowRectEx16( LPRECT16 rect
, DWORD style
,
410 BOOL16 menu
, DWORD exStyle
)
415 CONV_RECT16TO32( rect
, &rect32
);
416 ret
= AdjustWindowRectEx( &rect32
, style
, menu
, exStyle
);
417 CONV_RECT32TO16( &rect32
, rect
);
422 /***********************************************************************
423 * AdjustWindowRectEx (USER32.@)
425 BOOL WINAPI
AdjustWindowRectEx( LPRECT rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
427 /* Correct the window style */
428 style
&= (WS_DLGFRAME
| WS_BORDER
| WS_THICKFRAME
| WS_CHILD
);
429 exStyle
&= (WS_EX_DLGMODALFRAME
| WS_EX_CLIENTEDGE
|
430 WS_EX_STATICEDGE
| WS_EX_TOOLWINDOW
);
431 if (exStyle
& WS_EX_DLGMODALFRAME
) style
&= ~WS_THICKFRAME
;
433 TRACE("(%ld,%ld)-(%ld,%ld) %08lx %d %08lx\n",
434 rect
->left
, rect
->top
, rect
->right
, rect
->bottom
,
435 style
, menu
, exStyle
);
437 if (TWEAK_WineLook
== WIN31_LOOK
)
438 NC_AdjustRect( rect
, style
, menu
, exStyle
);
441 NC_AdjustRectOuter95( rect
, style
, menu
, exStyle
);
442 NC_AdjustRectInner95( rect
, style
, exStyle
);
448 /***********************************************************************
449 * NC_HandleNCCalcSize
451 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
453 LONG
NC_HandleNCCalcSize( HWND hwnd
, RECT
*winRect
)
455 RECT tmpRect
= { 0, 0, 0, 0 };
457 LONG cls_style
= GetClassLongA(hwnd
, GCL_STYLE
);
458 LONG style
= GetWindowLongA( hwnd
, GWL_STYLE
);
459 LONG exStyle
= GetWindowLongA( hwnd
, GWL_EXSTYLE
);
461 if (cls_style
& CS_VREDRAW
) result
|= WVR_VREDRAW
;
462 if (cls_style
& CS_HREDRAW
) result
|= WVR_HREDRAW
;
466 if (TWEAK_WineLook
== WIN31_LOOK
)
467 NC_AdjustRect( &tmpRect
, style
, FALSE
, exStyle
);
469 NC_AdjustRectOuter95( &tmpRect
, style
, FALSE
, exStyle
);
471 winRect
->left
-= tmpRect
.left
;
472 winRect
->top
-= tmpRect
.top
;
473 winRect
->right
-= tmpRect
.right
;
474 winRect
->bottom
-= tmpRect
.bottom
;
476 if (!(style
& WS_CHILD
) && GetMenu(hwnd
))
478 TRACE("Calling GetMenuBarHeight with hwnd %p, width %ld, at (%ld, %ld).\n",
479 hwnd
, winRect
->right
- winRect
->left
, -tmpRect
.left
, -tmpRect
.top
);
482 MENU_GetMenuBarHeight( hwnd
,
483 winRect
->right
- winRect
->left
,
484 -tmpRect
.left
, -tmpRect
.top
) + 1;
487 if (TWEAK_WineLook
> WIN31_LOOK
) {
488 SetRect(&tmpRect
, 0, 0, 0, 0);
489 NC_AdjustRectInner95 (&tmpRect
, style
, exStyle
);
490 winRect
->left
-= tmpRect
.left
;
491 winRect
->top
-= tmpRect
.top
;
492 winRect
->right
-= tmpRect
.right
;
493 winRect
->bottom
-= tmpRect
.bottom
;
496 if (winRect
->top
> winRect
->bottom
)
497 winRect
->bottom
= winRect
->top
;
499 if (winRect
->left
> winRect
->right
)
500 winRect
->right
= winRect
->left
;
506 /***********************************************************************
509 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
510 * but without the borders (if any).
511 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
513 void NC_GetInsideRect( HWND hwnd
, RECT
*rect
)
515 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
517 rect
->top
= rect
->left
= 0;
518 rect
->right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
519 rect
->bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
521 if (wndPtr
->dwStyle
& WS_ICONIC
) goto END
;
523 /* Remove frame from rectangle */
524 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
526 InflateRect( rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
528 else if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
530 InflateRect( rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
531 /* FIXME: this isn't in NC_AdjustRect? why not? */
532 if ((TWEAK_WineLook
== WIN31_LOOK
) && (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
))
533 InflateRect( rect
, -1, 0 );
535 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
537 InflateRect( rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
) );
540 /* We have additional border information if the window
541 * is a child (but not an MDI child) */
542 if (TWEAK_WineLook
!= WIN31_LOOK
)
544 if ( (wndPtr
->dwStyle
& WS_CHILD
) &&
545 ( (wndPtr
->dwExStyle
& WS_EX_MDICHILD
) == 0 ) )
547 if (wndPtr
->dwExStyle
& WS_EX_CLIENTEDGE
)
548 InflateRect (rect
, -GetSystemMetrics(SM_CXEDGE
), -GetSystemMetrics(SM_CYEDGE
));
549 if (wndPtr
->dwExStyle
& WS_EX_STATICEDGE
)
550 InflateRect (rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
555 WIN_ReleaseWndPtr(wndPtr
);
560 /***********************************************************************
563 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
566 static LONG
NC_DoNCHitTest (WND
*wndPtr
, POINT pt
)
570 TRACE("hwnd=%p pt=%ld,%ld\n", wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
572 GetWindowRect(wndPtr
->hwndSelf
, &rect
);
573 if (!PtInRect( &rect
, pt
)) return HTNOWHERE
;
575 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
578 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
580 InflateRect( &rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
581 if (!PtInRect( &rect
, pt
))
583 /* Check top sizing border */
586 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
587 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
590 /* Check bottom sizing border */
591 if (pt
.y
>= rect
.bottom
)
593 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
594 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
597 /* Check left sizing border */
598 if (pt
.x
< rect
.left
)
600 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
601 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
604 /* Check right sizing border */
605 if (pt
.x
>= rect
.right
)
607 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
608 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
613 else /* No thick frame */
615 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
616 InflateRect(&rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
617 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
618 InflateRect(&rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
619 if (!PtInRect( &rect
, pt
)) return HTBORDER
;
624 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
626 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
) - GetSystemMetrics(SM_CYBORDER
);
627 if (!PtInRect( &rect
, pt
))
629 /* Check system menu */
630 if ((wndPtr
->dwStyle
& WS_SYSMENU
) && !(wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
))
631 rect
.left
+= GetSystemMetrics(SM_CXSIZE
);
632 if (pt
.x
<= rect
.left
) return HTSYSMENU
;
634 /* Check maximize box */
635 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
636 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
638 if (pt
.x
>= rect
.right
) return HTMAXBUTTON
;
639 /* Check minimize box */
640 if (wndPtr
->dwStyle
& WS_MINIMIZEBOX
)
641 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
642 if (pt
.x
>= rect
.right
) return HTMINBUTTON
;
647 /* Check client area */
649 ScreenToClient( wndPtr
->hwndSelf
, &pt
);
650 GetClientRect( wndPtr
->hwndSelf
, &rect
);
651 if (PtInRect( &rect
, pt
)) return HTCLIENT
;
653 /* Check vertical scroll bar */
655 if (wndPtr
->dwStyle
& WS_VSCROLL
)
657 if((wndPtr
->dwExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
658 rect
.left
-= GetSystemMetrics(SM_CXVSCROLL
);
660 rect
.right
+= GetSystemMetrics(SM_CXVSCROLL
);
661 if (PtInRect( &rect
, pt
)) return HTVSCROLL
;
664 /* Check horizontal scroll bar */
666 if (wndPtr
->dwStyle
& WS_HSCROLL
)
668 rect
.bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
669 if (PtInRect( &rect
, pt
))
672 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
673 ((((wndPtr
->dwExStyle
& WS_EX_LEFTSCROLLBAR
) != 0) && (pt
.x
<= rect
.left
+ GetSystemMetrics(SM_CXVSCROLL
))) ||
674 (((wndPtr
->dwExStyle
& WS_EX_LEFTSCROLLBAR
) == 0) && (pt
.x
>= rect
.right
- GetSystemMetrics(SM_CXVSCROLL
)))))
682 if (HAS_MENU(wndPtr
))
684 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
688 /* Has to return HTNOWHERE if nothing was found
689 Could happen when a window has a customized non client area */
694 /***********************************************************************
697 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
699 * FIXME: Just a modified copy of the Win 3.1 version.
702 static LONG
NC_DoNCHitTest95 (WND
*wndPtr
, POINT pt
)
706 TRACE("hwnd=%p pt=%ld,%ld\n", wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
708 GetWindowRect(wndPtr
->hwndSelf
, &rect
);
709 if (!PtInRect( &rect
, pt
)) return HTNOWHERE
;
711 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
714 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
716 InflateRect( &rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
717 if (!PtInRect( &rect
, pt
))
719 /* Check top sizing border */
722 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
723 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
726 /* Check bottom sizing border */
727 if (pt
.y
>= rect
.bottom
)
729 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
730 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
733 /* Check left sizing border */
734 if (pt
.x
< rect
.left
)
736 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
737 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
740 /* Check right sizing border */
741 if (pt
.x
>= rect
.right
)
743 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
744 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
749 else /* No thick frame */
751 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
752 InflateRect(&rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
753 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
754 InflateRect(&rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
755 if (!PtInRect( &rect
, pt
)) return HTBORDER
;
760 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
762 if (wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
)
763 rect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
) - 1;
765 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
766 if (!PtInRect( &rect
, pt
))
768 /* Check system menu */
769 if ((wndPtr
->dwStyle
& WS_SYSMENU
) && !(wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
))
771 if (NC_IconForWindow(wndPtr
->hwndSelf
))
772 rect
.left
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
774 if (pt
.x
< rect
.left
) return HTSYSMENU
;
776 /* Check close button */
777 if (wndPtr
->dwStyle
& WS_SYSMENU
)
778 rect
.right
-= GetSystemMetrics(SM_CYCAPTION
) - 1;
779 if (pt
.x
> rect
.right
) return HTCLOSE
;
781 /* Check maximize box */
782 /* In win95 there is automatically a Maximize button when there is a minimize one*/
783 if ((wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)|| (wndPtr
->dwStyle
& WS_MINIMIZEBOX
))
784 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
785 if (pt
.x
> rect
.right
) return HTMAXBUTTON
;
787 /* Check minimize box */
788 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
789 if ((wndPtr
->dwStyle
& WS_MINIMIZEBOX
)||(wndPtr
->dwStyle
& WS_MAXIMIZEBOX
))
790 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
792 if (pt
.x
> rect
.right
) return HTMINBUTTON
;
797 /* Check client area */
799 ScreenToClient( wndPtr
->hwndSelf
, &pt
);
800 GetClientRect( wndPtr
->hwndSelf
, &rect
);
801 if (PtInRect( &rect
, pt
)) return HTCLIENT
;
803 /* Check vertical scroll bar */
805 if (wndPtr
->dwStyle
& WS_VSCROLL
)
807 if((wndPtr
->dwExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
808 rect
.left
-= GetSystemMetrics(SM_CXVSCROLL
);
810 rect
.right
+= GetSystemMetrics(SM_CXVSCROLL
);
811 if (PtInRect( &rect
, pt
)) return HTVSCROLL
;
814 /* Check horizontal scroll bar */
816 if (wndPtr
->dwStyle
& WS_HSCROLL
)
818 rect
.bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
819 if (PtInRect( &rect
, pt
))
822 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
823 ((((wndPtr
->dwExStyle
& WS_EX_LEFTSCROLLBAR
) != 0) && (pt
.x
<= rect
.left
+ GetSystemMetrics(SM_CXVSCROLL
))) ||
824 (((wndPtr
->dwExStyle
& WS_EX_LEFTSCROLLBAR
) == 0) && (pt
.x
>= rect
.right
- GetSystemMetrics(SM_CXVSCROLL
)))))
832 if (HAS_MENU(wndPtr
))
834 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
838 /* Has to return HTNOWHERE if nothing was found
839 Could happen when a window has a customized non client area */
844 /***********************************************************************
847 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
849 LONG
NC_HandleNCHitTest (HWND hwnd
, POINT pt
)
852 WND
*wndPtr
= WIN_FindWndPtr (hwnd
);
857 if (TWEAK_WineLook
== WIN31_LOOK
)
858 retvalue
= NC_DoNCHitTest (wndPtr
, pt
);
860 retvalue
= NC_DoNCHitTest95 (wndPtr
, pt
);
861 WIN_ReleaseWndPtr(wndPtr
);
866 /***********************************************************************
869 void NC_DrawSysButton( HWND hwnd
, HDC hdc
, BOOL down
)
875 NC_GetInsideRect( hwnd
, &rect
);
876 hdcMem
= CreateCompatibleDC( hdc
);
877 hbitmap
= SelectObject( hdcMem
, hbitmapClose
);
878 BitBlt(hdc
, rect
.left
, rect
.top
, GetSystemMetrics(SM_CXSIZE
), GetSystemMetrics(SM_CYSIZE
),
879 hdcMem
, (GetWindowLongA(hwnd
,GWL_STYLE
) & WS_CHILD
) ? GetSystemMetrics(SM_CXSIZE
) : 0, 0,
880 down
? NOTSRCCOPY
: SRCCOPY
);
881 SelectObject( hdcMem
, hbitmap
);
886 /***********************************************************************
889 static void NC_DrawMaxButton( HWND hwnd
, HDC hdc
, BOOL down
)
892 UINT flags
= IsZoomed(hwnd
) ? DFCS_CAPTIONRESTORE
: DFCS_CAPTIONMAX
;
894 NC_GetInsideRect( hwnd
, &rect
);
895 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
) + 1;
896 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
899 if (down
) flags
|= DFCS_PUSHED
;
900 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
904 /***********************************************************************
907 static void NC_DrawMinButton( HWND hwnd
, HDC hdc
, BOOL down
)
910 UINT flags
= DFCS_CAPTIONMIN
;
911 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
913 NC_GetInsideRect( hwnd
, &rect
);
914 if (style
& (WS_MAXIMIZEBOX
|WS_MINIMIZEBOX
))
915 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) - 2;
916 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
) + 1;
917 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
920 if (down
) flags
|= DFCS_PUSHED
;
921 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
925 /******************************************************************************
927 * void NC_DrawSysButton95(
932 * Draws the Win95 system icon.
935 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
936 * Original implementation from NC_DrawSysButton source.
937 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
940 *****************************************************************************/
943 NC_DrawSysButton95 (HWND hwnd
, HDC hdc
, BOOL down
)
945 HICON hIcon
= NC_IconForWindow( hwnd
);
950 NC_GetInsideRect( hwnd
, &rect
);
951 DrawIconEx (hdc
, rect
.left
+ 1, rect
.top
+ 1, hIcon
,
952 GetSystemMetrics(SM_CXSIZE
) - 1,
953 GetSystemMetrics(SM_CYSIZE
) - 1, 0, 0, DI_NORMAL
);
959 /******************************************************************************
961 * void NC_DrawCloseButton95(
967 * Draws the Win95 close button.
969 * If bGrayed is true, then draw a disabled Close button
972 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
973 * Original implementation from NC_DrawSysButton95 source.
975 *****************************************************************************/
977 static void NC_DrawCloseButton95 (HWND hwnd
, HDC hdc
, BOOL down
, BOOL bGrayed
)
981 NC_GetInsideRect( hwnd
, &rect
);
983 /* A tool window has a smaller Close button */
984 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_TOOLWINDOW
)
986 INT iBmpHeight
= 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
987 INT iBmpWidth
= 11; /* it uses 11x11 for the close button in tool window */
988 INT iCaptionHeight
= GetSystemMetrics(SM_CYSMCAPTION
);
990 rect
.top
= rect
.top
+ (iCaptionHeight
- 1 - iBmpHeight
) / 2;
991 rect
.left
= rect
.right
- (iCaptionHeight
+ 1 + iBmpWidth
) / 2;
992 rect
.bottom
= rect
.top
+ iBmpHeight
;
993 rect
.right
= rect
.left
+ iBmpWidth
;
997 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
) - 1;
998 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1002 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
,
1003 (DFCS_CAPTIONCLOSE
|
1004 (down
? DFCS_PUSHED
: 0) |
1005 (bGrayed
? DFCS_INACTIVE
: 0)) );
1008 /******************************************************************************
1009 * NC_DrawMaxButton95
1011 * Draws the maximize button for Win95 style windows.
1012 * If bGrayed is true, then draw a disabled Maximize button
1014 static void NC_DrawMaxButton95(HWND hwnd
,HDC hdc
,BOOL down
, BOOL bGrayed
)
1017 UINT flags
= IsZoomed(hwnd
) ? DFCS_CAPTIONRESTORE
: DFCS_CAPTIONMAX
;
1019 NC_GetInsideRect( hwnd
, &rect
);
1020 if (GetWindowLongA( hwnd
, GWL_STYLE
) & WS_SYSMENU
)
1021 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1022 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
);
1023 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1026 if (down
) flags
|= DFCS_PUSHED
;
1027 if (bGrayed
) flags
|= DFCS_INACTIVE
;
1028 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
1031 /******************************************************************************
1032 * NC_DrawMinButton95
1034 * Draws the minimize button for Win95 style windows.
1035 * If bGrayed is true, then draw a disabled Minimize button
1037 static void NC_DrawMinButton95(HWND hwnd
,HDC hdc
,BOOL down
, BOOL bGrayed
)
1040 UINT flags
= DFCS_CAPTIONMIN
;
1041 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
1043 NC_GetInsideRect( hwnd
, &rect
);
1044 if (style
& WS_SYSMENU
)
1045 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1046 if (style
& (WS_MAXIMIZEBOX
|WS_MINIMIZEBOX
))
1047 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) - 2;
1048 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
);
1049 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1052 if (down
) flags
|= DFCS_PUSHED
;
1053 if (bGrayed
) flags
|= DFCS_INACTIVE
;
1054 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
1057 /***********************************************************************
1060 * Draw a window frame inside the given rectangle, and update the rectangle.
1061 * The correct pen for the frame must be selected in the DC.
1063 static void NC_DrawFrame( HDC hdc
, RECT
*rect
, BOOL dlgFrame
,
1068 if (TWEAK_WineLook
!= WIN31_LOOK
)
1069 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
1073 width
= GetSystemMetrics(SM_CXDLGFRAME
) - 1;
1074 height
= GetSystemMetrics(SM_CYDLGFRAME
) - 1;
1075 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1076 COLOR_INACTIVECAPTION
) );
1080 width
= GetSystemMetrics(SM_CXFRAME
) - 2;
1081 height
= GetSystemMetrics(SM_CYFRAME
) - 2;
1082 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1083 COLOR_INACTIVEBORDER
) );
1087 PatBlt( hdc
, rect
->left
, rect
->top
,
1088 rect
->right
- rect
->left
, height
, PATCOPY
);
1089 PatBlt( hdc
, rect
->left
, rect
->top
,
1090 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1091 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1092 rect
->right
- rect
->left
, -height
, PATCOPY
);
1093 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1094 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1098 InflateRect( rect
, -width
, -height
);
1102 INT decYOff
= GetSystemMetrics(SM_CXFRAME
) + GetSystemMetrics(SM_CXSIZE
) - 1;
1103 INT decXOff
= GetSystemMetrics(SM_CYFRAME
) + GetSystemMetrics(SM_CYSIZE
) - 1;
1105 /* Draw inner rectangle */
1107 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1108 Rectangle( hdc
, rect
->left
+ width
, rect
->top
+ height
,
1109 rect
->right
- width
, rect
->bottom
- height
);
1111 /* Draw the decorations */
1113 MoveToEx( hdc
, rect
->left
, rect
->top
+ decYOff
, NULL
);
1114 LineTo( hdc
, rect
->left
+ width
, rect
->top
+ decYOff
);
1115 MoveToEx( hdc
, rect
->right
- 1, rect
->top
+ decYOff
, NULL
);
1116 LineTo( hdc
, rect
->right
- width
- 1, rect
->top
+ decYOff
);
1117 MoveToEx( hdc
, rect
->left
, rect
->bottom
- decYOff
, NULL
);
1118 LineTo( hdc
, rect
->left
+ width
, rect
->bottom
- decYOff
);
1119 MoveToEx( hdc
, rect
->right
- 1, rect
->bottom
- decYOff
, NULL
);
1120 LineTo( hdc
, rect
->right
- width
- 1, rect
->bottom
- decYOff
);
1122 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->top
, NULL
);
1123 LineTo( hdc
, rect
->left
+ decXOff
, rect
->top
+ height
);
1124 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->bottom
- 1, NULL
);
1125 LineTo( hdc
, rect
->left
+ decXOff
, rect
->bottom
- height
- 1 );
1126 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->top
, NULL
);
1127 LineTo( hdc
, rect
->right
- decXOff
, rect
->top
+ height
);
1128 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->bottom
- 1, NULL
);
1129 LineTo( hdc
, rect
->right
- decXOff
, rect
->bottom
- height
- 1 );
1131 InflateRect( rect
, -width
- 1, -height
- 1 );
1136 /******************************************************************************
1138 * void NC_DrawFrame95(
1145 * Draw a window frame inside the given rectangle, and update the rectangle.
1148 * Many. First, just what IS a frame in Win95? Note that the 3D look
1149 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1150 * edge. The inner rectangle just inside the frame is handled by the
1153 * In short, for most people, this function should be a nop (unless
1154 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1155 * them lately, but just to get this code right). Even so, it doesn't
1156 * appear to be so. It's being worked on...
1159 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1160 * Original implementation (based on NC_DrawFrame)
1161 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1163 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1164 * Fixed a fix or something.
1166 *****************************************************************************/
1168 static void NC_DrawFrame95(
1177 /* Firstly the "thick" frame */
1178 if (style
& WS_THICKFRAME
)
1180 width
= GetSystemMetrics(SM_CXFRAME
) - GetSystemMetrics(SM_CXDLGFRAME
);
1181 height
= GetSystemMetrics(SM_CYFRAME
) - GetSystemMetrics(SM_CYDLGFRAME
);
1183 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1184 COLOR_INACTIVEBORDER
) );
1186 PatBlt( hdc
, rect
->left
, rect
->top
,
1187 rect
->right
- rect
->left
, height
, PATCOPY
);
1188 PatBlt( hdc
, rect
->left
, rect
->top
,
1189 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1190 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1191 rect
->right
- rect
->left
, -height
, PATCOPY
);
1192 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1193 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1195 InflateRect( rect
, -width
, -height
);
1198 /* Now the other bit of the frame */
1199 if ((style
& (WS_BORDER
|WS_DLGFRAME
)) ||
1200 (exStyle
& WS_EX_DLGMODALFRAME
))
1202 width
= GetSystemMetrics(SM_CXDLGFRAME
) - GetSystemMetrics(SM_CXEDGE
);
1203 height
= GetSystemMetrics(SM_CYDLGFRAME
) - GetSystemMetrics(SM_CYEDGE
);
1204 /* This should give a value of 1 that should also work for a border */
1206 SelectObject( hdc
, GetSysColorBrush(
1207 (exStyle
& (WS_EX_DLGMODALFRAME
|WS_EX_CLIENTEDGE
)) ?
1209 (exStyle
& WS_EX_STATICEDGE
) ?
1211 (style
& (WS_DLGFRAME
|WS_THICKFRAME
)) ?
1214 COLOR_WINDOWFRAME
));
1217 PatBlt( hdc
, rect
->left
, rect
->top
,
1218 rect
->right
- rect
->left
, height
, PATCOPY
);
1219 PatBlt( hdc
, rect
->left
, rect
->top
,
1220 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1221 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1222 rect
->right
- rect
->left
, -height
, PATCOPY
);
1223 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1224 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1226 InflateRect( rect
, -width
, -height
);
1231 /***********************************************************************
1234 * Draw the window caption.
1235 * The correct pen for the window frame must be selected in the DC.
1237 static void NC_DrawCaption( HDC hdc
, RECT
*rect
, HWND hwnd
,
1238 DWORD style
, BOOL active
)
1245 if (!(hbitmapClose
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_OLD_CLOSE
) ))) return;
1248 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_DLGMODALFRAME
)
1250 HBRUSH hbrushOld
= SelectObject(hdc
, GetSysColorBrush(COLOR_WINDOW
) );
1251 PatBlt( hdc
, r
.left
, r
.top
, 1, r
.bottom
-r
.top
+1,PATCOPY
);
1252 PatBlt( hdc
, r
.right
-1, r
.top
, 1, r
.bottom
-r
.top
+1, PATCOPY
);
1253 PatBlt( hdc
, r
.left
, r
.top
-1, r
.right
-r
.left
, 1, PATCOPY
);
1256 SelectObject( hdc
, hbrushOld
);
1258 MoveToEx( hdc
, r
.left
, r
.bottom
, NULL
);
1259 LineTo( hdc
, r
.right
, r
.bottom
);
1261 if (style
& WS_SYSMENU
)
1263 NC_DrawSysButton( hwnd
, hdc
, FALSE
);
1264 r
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
1265 MoveToEx( hdc
, r
.left
- 1, r
.top
, NULL
);
1266 LineTo( hdc
, r
.left
- 1, r
.bottom
);
1268 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
: COLOR_INACTIVECAPTION
) );
1269 if (style
& WS_MAXIMIZEBOX
)
1271 NC_DrawMaxButton( hwnd
, hdc
, FALSE
);
1272 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1274 if (style
& WS_MINIMIZEBOX
)
1276 NC_DrawMinButton( hwnd
, hdc
, FALSE
);
1277 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1280 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) ))
1282 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1283 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1284 SetBkMode( hdc
, TRANSPARENT
);
1285 DrawTextA( hdc
, buffer
, -1, &r
,
1286 DT_SINGLELINE
| DT_CENTER
| DT_VCENTER
| DT_NOPREFIX
);
1291 /******************************************************************************
1300 * Draw the window caption for Win95 style windows.
1301 * The correct pen for the window frame must be selected in the DC.
1304 * Hey, a function that finally works! Well, almost.
1305 * It's being worked on.
1308 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1309 * Original implementation.
1310 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1313 *****************************************************************************/
1315 static void NC_DrawCaption95(
1328 hPrevPen
= SelectObject( hdc
, SYSCOLOR_GetPen(
1329 ((exStyle
& (WS_EX_STATICEDGE
|WS_EX_CLIENTEDGE
|
1330 WS_EX_DLGMODALFRAME
)) == WS_EX_STATICEDGE
) ?
1331 COLOR_WINDOWFRAME
: COLOR_3DFACE
) );
1332 MoveToEx( hdc
, r
.left
, r
.bottom
- 1, NULL
);
1333 LineTo( hdc
, r
.right
, r
.bottom
- 1 );
1334 SelectObject( hdc
, hPrevPen
);
1337 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1338 COLOR_INACTIVECAPTION
) );
1340 if ((style
& WS_SYSMENU
) && !(exStyle
& WS_EX_TOOLWINDOW
)) {
1341 if (NC_DrawSysButton95 (hwnd
, hdc
, FALSE
))
1342 r
.left
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
1345 if (style
& WS_SYSMENU
)
1349 /* Go get the sysmenu */
1350 hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1351 state
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
);
1353 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1354 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
,
1355 ((((state
& MF_DISABLED
) || (state
& MF_GRAYED
))) && (state
!= 0xFFFFFFFF)));
1356 r
.right
-= GetSystemMetrics(SM_CYCAPTION
) - 1;
1358 if ((style
& WS_MAXIMIZEBOX
) || (style
& WS_MINIMIZEBOX
))
1360 /* In win95 the two buttons are always there */
1361 /* But if the menu item is not in the menu they're disabled*/
1363 NC_DrawMaxButton95( hwnd
, hdc
, FALSE
, (!(style
& WS_MAXIMIZEBOX
)));
1364 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1366 NC_DrawMinButton95( hwnd
, hdc
, FALSE
, (!(style
& WS_MINIMIZEBOX
)));
1367 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1371 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) )) {
1372 NONCLIENTMETRICSA nclm
;
1373 HFONT hFont
, hOldFont
;
1374 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
1375 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
1376 if (exStyle
& WS_EX_TOOLWINDOW
)
1377 hFont
= CreateFontIndirectA (&nclm
.lfSmCaptionFont
);
1379 hFont
= CreateFontIndirectA (&nclm
.lfCaptionFont
);
1380 hOldFont
= SelectObject (hdc
, hFont
);
1381 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1382 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1383 SetBkMode( hdc
, TRANSPARENT
);
1385 DrawTextA( hdc
, buffer
, -1, &r
,
1386 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
1387 DeleteObject (SelectObject (hdc
, hOldFont
));
1393 /***********************************************************************
1396 * Paint the non-client area. clip is currently unused.
1398 static void NC_DoNCPaint( HWND hwnd
, HRGN clip
, BOOL suppress_menupaint
)
1404 DWORD dwStyle
, dwExStyle
;
1406 RECT rectClient
, rectWindow
;
1409 if (!(wndPtr
= WIN_GetPtr( hwnd
)) || wndPtr
== WND_OTHER_PROCESS
) return;
1410 has_menu
= HAS_MENU(wndPtr
);
1411 dwStyle
= wndPtr
->dwStyle
;
1412 dwExStyle
= wndPtr
->dwExStyle
;
1413 flags
= wndPtr
->flags
;
1414 rectClient
= wndPtr
->rectClient
;
1415 rectWindow
= wndPtr
->rectWindow
;
1416 WIN_ReleasePtr( wndPtr
);
1418 if ( dwStyle
& WS_MINIMIZE
||
1419 !WIN_IsWindowDrawable( hwnd
, 0 )) return; /* Nothing to do */
1421 active
= flags
& WIN_NCACTIVATED
;
1423 TRACE("%p %d\n", hwnd
, active
);
1425 if (!(hdc
= GetDCEx( hwnd
, (clip
> (HRGN
)1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
1426 ((clip
> (HRGN
)1) ? (DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
): 0) ))) return;
1428 if (ExcludeVisRect16( HDC_16(hdc
), rectClient
.left
-rectWindow
.left
,
1429 rectClient
.top
-rectWindow
.top
,
1430 rectClient
.right
-rectWindow
.left
,
1431 rectClient
.bottom
-rectWindow
.top
)
1434 ReleaseDC( hwnd
, hdc
);
1438 rect
.top
= rect
.left
= 0;
1439 rect
.right
= rectWindow
.right
- rectWindow
.left
;
1440 rect
.bottom
= rectWindow
.bottom
- rectWindow
.top
;
1442 SelectObject( hdc
, SYSCOLOR_GetPen(COLOR_WINDOWFRAME
) );
1444 if (HAS_ANYFRAME( dwStyle
, dwExStyle
))
1446 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1447 Rectangle( hdc
, 0, 0, rect
.right
, rect
.bottom
);
1448 InflateRect( &rect
, -1, -1 );
1451 if (HAS_THICKFRAME( dwStyle
, dwExStyle
))
1452 NC_DrawFrame(hdc
, &rect
, FALSE
, active
);
1453 else if (HAS_DLGFRAME( dwStyle
, dwExStyle
))
1454 NC_DrawFrame( hdc
, &rect
, TRUE
, active
);
1456 if ((dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1459 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
);
1460 rect
.top
+= GetSystemMetrics(SM_CYSIZE
) + GetSystemMetrics(SM_CYBORDER
);
1461 NC_DrawCaption( hdc
, &r
, hwnd
, dwStyle
, active
);
1467 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYMENU
); /* default height */
1468 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
);
1471 /* Draw the scroll-bars */
1473 if (dwStyle
& WS_VSCROLL
)
1474 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1475 if (dwStyle
& WS_HSCROLL
)
1476 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1478 /* Draw the "size-box" */
1480 if ((dwStyle
& WS_VSCROLL
) && (dwStyle
& WS_HSCROLL
))
1483 if((dwExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
1484 r
.right
= r
.left
+ GetSystemMetrics(SM_CXVSCROLL
) + 1;
1486 r
.left
= r
.right
- GetSystemMetrics(SM_CXVSCROLL
) + 1;
1487 r
.top
= r
.bottom
- GetSystemMetrics(SM_CYHSCROLL
) + 1;
1488 if(wndPtr
->dwStyle
& WS_BORDER
) {
1492 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1495 ReleaseDC( hwnd
, hdc
);
1499 /******************************************************************************
1501 * void NC_DoNCPaint95(
1504 * BOOL suppress_menupaint )
1506 * Paint the non-client area for Win95 windows. The clip region is
1507 * currently ignored.
1510 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1511 * misc/tweak.c controls/menu.c # :-)
1514 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1515 * Original implementation
1516 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1518 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1519 * Streamlined window style checks.
1521 *****************************************************************************/
1523 static void NC_DoNCPaint95(
1526 BOOL suppress_menupaint
)
1529 RECT rfuzz
, rect
, rectClip
;
1532 DWORD dwStyle
, dwExStyle
;
1534 RECT rectClient
, rectWindow
;
1537 if (!(wndPtr
= WIN_GetPtr( hwnd
)) || wndPtr
== WND_OTHER_PROCESS
) return;
1538 has_menu
= HAS_MENU(wndPtr
);
1539 dwStyle
= wndPtr
->dwStyle
;
1540 dwExStyle
= wndPtr
->dwExStyle
;
1541 flags
= wndPtr
->flags
;
1542 rectClient
= wndPtr
->rectClient
;
1543 rectWindow
= wndPtr
->rectWindow
;
1544 WIN_ReleasePtr( wndPtr
);
1546 if ( dwStyle
& WS_MINIMIZE
||
1547 !WIN_IsWindowDrawable( hwnd
, 0 )) return; /* Nothing to do */
1549 active
= flags
& WIN_NCACTIVATED
;
1551 TRACE("%p %d\n", hwnd
, active
);
1553 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1554 the call to GetDCEx implying that it is allowed not to use it either.
1555 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1556 will cause clipRgn to be deleted after ReleaseDC().
1557 Now, how is the "system" supposed to tell what happened?
1560 if (!(hdc
= GetDCEx( hwnd
, (clip
> (HRGN
)1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
1561 ((clip
> (HRGN
)1) ?(DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
) : 0) ))) return;
1564 if (ExcludeVisRect16( HDC_16(hdc
), rectClient
.left
-rectWindow
.left
,
1565 rectClient
.top
-rectWindow
.top
,
1566 rectClient
.right
-rectWindow
.left
,
1567 rectClient
.bottom
-rectWindow
.top
)
1570 ReleaseDC( hwnd
, hdc
);
1574 rect
.top
= rect
.left
= 0;
1575 rect
.right
= rectWindow
.right
- rectWindow
.left
;
1576 rect
.bottom
= rectWindow
.bottom
- rectWindow
.top
;
1578 if( clip
> (HRGN
)1 )
1579 GetRgnBox( clip
, &rectClip
);
1586 SelectObject( hdc
, SYSCOLOR_GetPen(COLOR_WINDOWFRAME
) );
1588 if (HAS_STATICOUTERFRAME(dwStyle
, dwExStyle
)) {
1589 DrawEdge (hdc
, &rect
, BDR_SUNKENOUTER
, BF_RECT
| BF_ADJUST
);
1591 else if (HAS_BIGFRAME( dwStyle
, dwExStyle
)) {
1592 DrawEdge (hdc
, &rect
, EDGE_RAISED
, BF_RECT
| BF_ADJUST
);
1595 NC_DrawFrame95(hdc
, &rect
, active
, dwStyle
, dwExStyle
);
1597 if ((dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1600 if (dwExStyle
& WS_EX_TOOLWINDOW
) {
1601 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSMCAPTION
);
1602 rect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
);
1605 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYCAPTION
);
1606 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
);
1608 if( !clip
|| IntersectRect( &rfuzz
, &r
, &rectClip
) )
1609 NC_DrawCaption95 (hdc
, &r
, hwnd
, dwStyle
,
1616 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYMENU
);
1618 TRACE("Calling DrawMenuBar with rect (%ld, %ld)-(%ld, %ld)\n",
1619 r
.left
, r
.top
, r
.right
, r
.bottom
);
1621 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
) + 1;
1624 TRACE("After MenuBar, rect is (%ld, %ld)-(%ld, %ld).\n",
1625 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1627 if (dwExStyle
& WS_EX_CLIENTEDGE
)
1628 DrawEdge (hdc
, &rect
, EDGE_SUNKEN
, BF_RECT
| BF_ADJUST
);
1630 /* Draw the scroll-bars */
1632 if (dwStyle
& WS_VSCROLL
)
1633 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1634 if (dwStyle
& WS_HSCROLL
)
1635 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1637 /* Draw the "size-box" */
1638 if ((dwStyle
& WS_VSCROLL
) && (dwStyle
& WS_HSCROLL
))
1641 if((dwExStyle
& WS_EX_LEFTSCROLLBAR
) != 0)
1642 r
.right
= r
.left
+ GetSystemMetrics(SM_CXVSCROLL
) + 1;
1644 r
.left
= r
.right
- GetSystemMetrics(SM_CXVSCROLL
) + 1;
1645 r
.top
= r
.bottom
- GetSystemMetrics(SM_CYHSCROLL
) + 1;
1646 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1649 ReleaseDC( hwnd
, hdc
);
1655 /***********************************************************************
1658 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1660 LONG
NC_HandleNCPaint( HWND hwnd
, HRGN clip
)
1662 DWORD dwStyle
= GetWindowLongW( hwnd
, GWL_STYLE
);
1664 if( dwStyle
& WS_VISIBLE
)
1666 if( dwStyle
& WS_MINIMIZE
)
1667 WINPOS_RedrawIconTitle( hwnd
);
1668 else if (TWEAK_WineLook
== WIN31_LOOK
)
1669 NC_DoNCPaint( hwnd
, clip
, FALSE
);
1671 NC_DoNCPaint95( hwnd
, clip
, FALSE
);
1677 /***********************************************************************
1678 * NC_HandleNCActivate
1680 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1682 LONG
NC_HandleNCActivate( HWND hwnd
, WPARAM wParam
)
1684 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1686 /* Lotus Notes draws menu descriptions in the caption of its main
1687 * window. When it wants to restore original "system" view, it just
1688 * sends WM_NCACTIVATE message to itself. Any optimizations here in
1689 * attempt to minimize redrawings lead to a not restored caption.
1693 if (wParam
) wndPtr
->flags
|= WIN_NCACTIVATED
;
1694 else wndPtr
->flags
&= ~WIN_NCACTIVATED
;
1695 WIN_ReleaseWndPtr(wndPtr
);
1697 if (IsIconic(hwnd
)) WINPOS_RedrawIconTitle( hwnd
);
1698 else if (TWEAK_WineLook
== WIN31_LOOK
)
1699 NC_DoNCPaint( hwnd
, (HRGN
)1, FALSE
);
1701 NC_DoNCPaint95( hwnd
, (HRGN
)1, FALSE
);
1707 /***********************************************************************
1708 * NC_HandleSetCursor
1710 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1712 LONG
NC_HandleSetCursor( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1714 hwnd
= WIN_GetFullHandle( (HWND
)wParam
);
1716 switch(LOWORD(lParam
))
1720 WORD msg
= HIWORD( lParam
);
1721 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_MBUTTONDOWN
) ||
1722 (msg
== WM_RBUTTONDOWN
))
1729 HCURSOR hCursor
= (HCURSOR
)GetClassLongA(hwnd
, GCL_HCURSOR
);
1739 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZEWEA
) );
1743 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENSA
) );
1747 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENWSEA
) );
1751 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENESWA
) );
1754 /* Default cursor: arrow */
1755 return (LONG
)SetCursor( LoadCursorA( 0, IDC_ARROWA
) );
1758 /***********************************************************************
1761 void NC_GetSysPopupPos( HWND hwnd
, RECT
* rect
)
1763 if (IsIconic(hwnd
)) GetWindowRect( hwnd
, rect
);
1766 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1767 if (!wndPtr
) return;
1769 NC_GetInsideRect( hwnd
, rect
);
1770 OffsetRect( rect
, wndPtr
->rectWindow
.left
, wndPtr
->rectWindow
.top
);
1771 if (wndPtr
->dwStyle
& WS_CHILD
)
1772 ClientToScreen( GetParent(hwnd
), (POINT
*)rect
);
1773 if (TWEAK_WineLook
== WIN31_LOOK
) {
1774 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CXSIZE
);
1775 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYSIZE
);
1778 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
1779 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
1781 WIN_ReleaseWndPtr( wndPtr
);
1785 /***********************************************************************
1786 * NC_TrackMinMaxBox95
1788 * Track a mouse button press on the minimize or maximize box.
1790 * The big difference between 3.1 and 95 is the disabled button state.
1791 * In win95 the system button can be disabled, so it can ignore the mouse
1795 static void NC_TrackMinMaxBox95( HWND hwnd
, WORD wParam
)
1798 HDC hdc
= GetWindowDC( hwnd
);
1799 BOOL pressed
= TRUE
;
1801 DWORD wndStyle
= GetWindowLongA( hwnd
, GWL_STYLE
);
1802 HMENU hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1804 void (*paintButton
)(HWND
, HDC
, BOOL
, BOOL
);
1806 if (wParam
== HTMINBUTTON
)
1808 /* If the style is not present, do nothing */
1809 if (!(wndStyle
& WS_MINIMIZEBOX
))
1812 /* Check if the sysmenu item for minimize is there */
1813 state
= GetMenuState(hSysMenu
, SC_MINIMIZE
, MF_BYCOMMAND
);
1815 paintButton
= &NC_DrawMinButton95
;
1819 /* If the style is not present, do nothing */
1820 if (!(wndStyle
& WS_MAXIMIZEBOX
))
1823 /* Check if the sysmenu item for maximize is there */
1824 state
= GetMenuState(hSysMenu
, SC_MAXIMIZE
, MF_BYCOMMAND
);
1826 paintButton
= &NC_DrawMaxButton95
;
1831 (*paintButton
)( hwnd
, hdc
, TRUE
, FALSE
);
1835 BOOL oldstate
= pressed
;
1837 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1838 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1840 if(msg
.message
== WM_LBUTTONUP
)
1843 if(msg
.message
!= WM_MOUSEMOVE
)
1846 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1847 if (pressed
!= oldstate
)
1848 (*paintButton
)( hwnd
, hdc
, pressed
, FALSE
);
1852 (*paintButton
)(hwnd
, hdc
, FALSE
, FALSE
);
1855 ReleaseDC( hwnd
, hdc
);
1857 /* If the item minimize or maximize of the sysmenu are not there */
1858 /* or if the style is not present, do nothing */
1859 if ((!pressed
) || (state
== 0xFFFFFFFF))
1862 if (wParam
== HTMINBUTTON
)
1863 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1865 SendMessageA( hwnd
, WM_SYSCOMMAND
,
1866 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1869 /***********************************************************************
1872 * Track a mouse button press on the minimize or maximize box.
1874 static void NC_TrackMinMaxBox( HWND hwnd
, WORD wParam
)
1877 HDC hdc
= GetWindowDC( hwnd
);
1878 BOOL pressed
= TRUE
;
1879 void (*paintButton
)(HWND
, HDC
, BOOL
);
1883 if (wParam
== HTMINBUTTON
)
1884 paintButton
= &NC_DrawMinButton
;
1886 paintButton
= &NC_DrawMaxButton
;
1888 (*paintButton
)( hwnd
, hdc
, TRUE
);
1892 BOOL oldstate
= pressed
;
1894 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1895 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1897 if(msg
.message
== WM_LBUTTONUP
)
1900 if(msg
.message
!= WM_MOUSEMOVE
)
1903 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1904 if (pressed
!= oldstate
)
1905 (*paintButton
)( hwnd
, hdc
, pressed
);
1909 (*paintButton
)( hwnd
, hdc
, FALSE
);
1912 ReleaseDC( hwnd
, hdc
);
1914 if (!pressed
) return;
1916 if (wParam
== HTMINBUTTON
)
1917 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1919 SendMessageA( hwnd
, WM_SYSCOMMAND
,
1920 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1924 /***********************************************************************
1925 * NC_TrackCloseButton95
1927 * Track a mouse button press on the Win95 close button.
1930 NC_TrackCloseButton95 (HWND hwnd
, WORD wParam
)
1934 BOOL pressed
= TRUE
;
1935 HMENU hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1941 state
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
);
1943 /* If the item close of the sysmenu is disabled or not there do nothing */
1944 if((state
& MF_DISABLED
) || (state
& MF_GRAYED
) || (state
== 0xFFFFFFFF))
1947 hdc
= GetWindowDC( hwnd
);
1951 NC_DrawCloseButton95 (hwnd
, hdc
, TRUE
, FALSE
);
1955 BOOL oldstate
= pressed
;
1957 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1958 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1960 if(msg
.message
== WM_LBUTTONUP
)
1963 if(msg
.message
!= WM_MOUSEMOVE
)
1966 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1967 if (pressed
!= oldstate
)
1968 NC_DrawCloseButton95 (hwnd
, hdc
, pressed
, FALSE
);
1972 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
, FALSE
);
1975 ReleaseDC( hwnd
, hdc
);
1976 if (!pressed
) return;
1978 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1982 /***********************************************************************
1985 * Track a mouse button press on the horizontal or vertical scroll-bar.
1987 static void NC_TrackScrollBar( HWND hwnd
, WPARAM wParam
, POINT pt
)
1991 if ((wParam
& 0xfff0) == SC_HSCROLL
)
1993 if ((wParam
& 0x0f) != HTHSCROLL
) return;
1994 scrollbar
= SB_HORZ
;
1996 else /* SC_VSCROLL */
1998 if ((wParam
& 0x0f) != HTVSCROLL
) return;
1999 scrollbar
= SB_VERT
;
2001 SCROLL_TrackScrollBar( hwnd
, scrollbar
, pt
);
2005 /***********************************************************************
2006 * NC_HandleNCLButtonDown
2008 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2010 LONG
NC_HandleNCLButtonDown( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2012 LONG style
= GetWindowLongA( hwnd
, GWL_STYLE
);
2014 switch(wParam
) /* Hit test */
2018 HWND top
= GetAncestor( hwnd
, GA_ROOT
);
2020 if (FOCUS_MouseActivate( top
) || (GetActiveWindow() == top
))
2021 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOVE
+ HTCAPTION
, lParam
);
2026 if( style
& WS_SYSMENU
)
2028 if( !(style
& WS_MINIMIZE
) )
2030 HDC hDC
= GetWindowDC(hwnd
);
2031 if (TWEAK_WineLook
== WIN31_LOOK
)
2032 NC_DrawSysButton( hwnd
, hDC
, TRUE
);
2034 NC_DrawSysButton95( hwnd
, hDC
, TRUE
);
2035 ReleaseDC( hwnd
, hDC
);
2037 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
+ HTSYSMENU
, lParam
);
2042 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
, lParam
);
2046 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
2050 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
2055 if (TWEAK_WineLook
== WIN31_LOOK
)
2056 NC_TrackMinMaxBox( hwnd
, wParam
);
2058 NC_TrackMinMaxBox95( hwnd
, wParam
);
2062 if (TWEAK_WineLook
>= WIN95_LOOK
)
2063 NC_TrackCloseButton95 (hwnd
, wParam
);
2075 * "make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU"
2076 * This was previously done by setting wParam=SC_SIZE + wParam - 2
2078 /* But that is not what WinNT does. Instead it sends this. This
2079 * is easy to differentiate from HTSYSMENU, because HTSYSMENU adds
2080 * SC_MOUSEMENU into wParam.
2082 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_SIZE
+ wParam
- (HTLEFT
-WMSZ_LEFT
), lParam
);
2092 /***********************************************************************
2093 * NC_HandleNCLButtonDblClk
2095 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2097 LONG
NC_HandleNCLButtonDblClk( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2100 * if this is an icon, send a restore since we are handling
2105 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_RESTORE
, lParam
);
2109 switch(wParam
) /* Hit test */
2112 /* stop processing if WS_MAXIMIZEBOX is missing */
2113 if (GetWindowLongA( hwnd
, GWL_STYLE
) & WS_MAXIMIZEBOX
)
2114 SendMessageW( hwnd
, WM_SYSCOMMAND
,
2115 IsZoomed(hwnd
) ? SC_RESTORE
: SC_MAXIMIZE
, lParam
);
2119 if (!(GetClassLongW(hwnd
, GCL_STYLE
) & CS_NOCLOSE
))
2120 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, lParam
);
2124 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
2128 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
2135 /***********************************************************************
2136 * NC_HandleSysCommand
2138 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2140 LONG
NC_HandleSysCommand( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2142 TRACE("Handling WM_SYSCOMMAND %x %lx\n", wParam
, lParam
);
2144 switch (wParam
& 0xfff0)
2148 if (USER_Driver
.pSysCommandSizeMove
)
2149 USER_Driver
.pSysCommandSizeMove( hwnd
, wParam
);
2153 if (hwnd
== GetForegroundWindow())
2154 ShowOwnedPopups(hwnd
,FALSE
);
2155 ShowWindow( hwnd
, SW_MINIMIZE
);
2159 if (IsIconic(hwnd
) && hwnd
== GetForegroundWindow())
2160 ShowOwnedPopups(hwnd
,TRUE
);
2161 ShowWindow( hwnd
, SW_MAXIMIZE
);
2165 if (IsIconic(hwnd
) && hwnd
== GetForegroundWindow())
2166 ShowOwnedPopups(hwnd
,TRUE
);
2167 ShowWindow( hwnd
, SW_RESTORE
);
2171 return SendMessageA( hwnd
, WM_CLOSE
, 0, 0 );
2177 pt
.x
= SLOWORD(lParam
);
2178 pt
.y
= SHIWORD(lParam
);
2179 NC_TrackScrollBar( hwnd
, wParam
, pt
);
2186 pt
.x
= SLOWORD(lParam
);
2187 pt
.y
= SHIWORD(lParam
);
2188 MENU_TrackMouseMenuBar( hwnd
, wParam
& 0x000F, pt
);
2193 MENU_TrackKbdMenuBar( hwnd
, wParam
, LOWORD(lParam
) );
2197 WinExec( "taskman.exe", SW_SHOWNORMAL
);
2201 if (wParam
== SC_ABOUTWINE
)
2203 HMODULE hmodule
= LoadLibraryA( "shell32.dll" );
2206 FARPROC aboutproc
= GetProcAddress( hmodule
, "ShellAboutA" );
2207 if (aboutproc
) aboutproc( hwnd
, PACKAGE_NAME
, PACKAGE_STRING
, 0 );
2208 FreeLibrary( hmodule
);
2212 if (wParam
== SC_PUTMARK
)
2213 TRACE_(shell
)("Mark requested by user\n");
2220 FIXME("unimplemented!\n");
2226 /*************************************************************
2229 * Stub for the grayed button of the caption
2231 *************************************************************/
2233 BOOL
NC_DrawGrayButton(HDC hdc
, int x
, int y
)
2239 hMaskBmp
= CreateBitmap (12, 10, 1, 1, lpGrayMask
);
2244 hdcMask
= CreateCompatibleDC (0);
2245 SelectObject (hdcMask
, hMaskBmp
);
2247 /* Draw the grayed bitmap using the mask */
2248 hOldBrush
= SelectObject (hdc
, (HGDIOBJ
)RGB(128, 128, 128));
2249 BitBlt (hdc
, x
, y
, 12, 10,
2250 hdcMask
, 0, 0, 0xB8074A);
2253 SelectObject (hdc
, hOldBrush
);
2254 DeleteObject(hMaskBmp
);