2 * Non-client area window functions
4 * Copyright 1994 Alexandre Julliard
10 #include "wine/winuser16.h"
17 #include "cursoricon.h"
20 #include "nonclient.h"
21 #include "debugtools.h"
25 DEFAULT_DEBUG_CHANNEL(nonclient
);
26 DECLARE_DEBUG_CHANNEL(shell
);
28 BOOL
NC_DrawGrayButton(HDC hdc
, int x
, int y
);
30 static HBITMAP hbitmapClose
;
31 static HBITMAP hbitmapMinimize
;
32 static HBITMAP hbitmapMinimizeD
;
33 static HBITMAP hbitmapMaximize
;
34 static HBITMAP hbitmapMaximizeD
;
35 static HBITMAP hbitmapRestore
;
36 static HBITMAP hbitmapRestoreD
;
38 static const BYTE lpGrayMask
[] = { 0xAA, 0xA0,
49 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
50 #define SC_PUTMARK (SC_SCREENSAVE+2)
52 /* Some useful macros */
53 #define HAS_DLGFRAME(style,exStyle) \
54 (((exStyle) & WS_EX_DLGMODALFRAME) || \
55 (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
57 #define HAS_THICKFRAME(style,exStyle) \
58 (((style) & WS_THICKFRAME) && \
59 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
61 #define HAS_THINFRAME(style) \
62 (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
64 #define HAS_BIGFRAME(style,exStyle) \
65 (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
66 ((exStyle) & WS_EX_DLGMODALFRAME))
68 #define HAS_STATICOUTERFRAME(style,exStyle) \
69 (((exStyle) & (WS_EX_STATICEDGE|WS_EX_DLGMODALFRAME)) == \
72 #define HAS_ANYFRAME(style,exStyle) \
73 (((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
74 ((exStyle) & WS_EX_DLGMODALFRAME) || \
75 !((style) & (WS_CHILD | WS_POPUP)))
77 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
80 /***********************************************************************
83 * Compute the size of the window rectangle from the size of the
86 static void NC_AdjustRect( LPRECT rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
88 if (TWEAK_WineLook
> WIN31_LOOK
)
89 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
91 if(style
& WS_ICONIC
) return;
93 if (HAS_THICKFRAME( style
, exStyle
))
94 InflateRect( rect
, GetSystemMetrics(SM_CXFRAME
), GetSystemMetrics(SM_CYFRAME
) );
95 else if (HAS_DLGFRAME( style
, exStyle
))
96 InflateRect( rect
, GetSystemMetrics(SM_CXDLGFRAME
), GetSystemMetrics(SM_CYDLGFRAME
) );
97 else if (HAS_THINFRAME( style
))
98 InflateRect( rect
, GetSystemMetrics(SM_CXBORDER
), GetSystemMetrics(SM_CYBORDER
));
100 if ((style
& WS_CAPTION
) == WS_CAPTION
)
101 rect
->top
-= GetSystemMetrics(SM_CYCAPTION
) - GetSystemMetrics(SM_CYBORDER
);
103 if (menu
) rect
->top
-= GetSystemMetrics(SM_CYMENU
) + GetSystemMetrics(SM_CYBORDER
);
105 if (style
& WS_VSCROLL
) {
106 rect
->right
+= GetSystemMetrics(SM_CXVSCROLL
) - 1;
107 if(!HAS_ANYFRAME( style
, exStyle
))
111 if (style
& WS_HSCROLL
) {
112 rect
->bottom
+= GetSystemMetrics(SM_CYHSCROLL
) - 1;
113 if(!HAS_ANYFRAME( style
, exStyle
))
119 /******************************************************************************
120 * NC_AdjustRectOuter95
122 * Computes the size of the "outside" parts of the window based on the
123 * parameters of the client area.
132 * "Outer" parts of a window means the whole window frame, caption and
133 * menu bar. It does not include "inner" parts of the frame like client
134 * edge, static edge or scroll bars.
137 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
138 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
140 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
141 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
142 * NC_AdjustRectInner95 and added handling of Win95 styles.
144 * 28-Jul-1999 Ove Kåven (ovek@arcticnet.no)
145 * Streamlined window style checks.
147 *****************************************************************************/
150 NC_AdjustRectOuter95 (LPRECT rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
153 if(style
& WS_ICONIC
) return;
155 if ((exStyle
& (WS_EX_STATICEDGE
|WS_EX_DLGMODALFRAME
)) ==
158 adjust
= 1; /* for the outer frame always present */
163 if ((exStyle
& WS_EX_DLGMODALFRAME
) ||
164 (style
& (WS_THICKFRAME
|WS_DLGFRAME
))) adjust
= 2; /* outer */
166 if (style
& WS_THICKFRAME
)
167 adjust
+= ( GetSystemMetrics (SM_CXFRAME
)
168 - GetSystemMetrics (SM_CXDLGFRAME
)); /* The resize border */
169 if ((style
& (WS_BORDER
|WS_DLGFRAME
)) ||
170 (exStyle
& WS_EX_DLGMODALFRAME
))
171 adjust
++; /* The other border */
173 InflateRect (rect
, adjust
, adjust
);
175 if ((style
& WS_CAPTION
) == WS_CAPTION
)
177 if (exStyle
& WS_EX_TOOLWINDOW
)
178 rect
->top
-= GetSystemMetrics(SM_CYSMCAPTION
);
180 rect
->top
-= GetSystemMetrics(SM_CYCAPTION
);
182 if (menu
) rect
->top
-= GetSystemMetrics(SM_CYMENU
);
186 /******************************************************************************
187 * NC_AdjustRectInner95
189 * Computes the size of the "inside" part of the window based on the
190 * parameters of the client area.
198 * "Inner" part of a window means the window frame inside of the flat
199 * window frame. It includes the client edge, the static edge and the
203 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
204 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
206 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
207 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
208 * NC_AdjustRectInner95 and added handling of Win95 styles.
210 *****************************************************************************/
213 NC_AdjustRectInner95 (LPRECT rect
, DWORD style
, DWORD exStyle
)
215 if(style
& WS_ICONIC
) return;
217 if (exStyle
& WS_EX_CLIENTEDGE
)
218 InflateRect(rect
, GetSystemMetrics(SM_CXEDGE
), GetSystemMetrics(SM_CYEDGE
));
220 if (style
& WS_VSCROLL
) rect
->right
+= GetSystemMetrics(SM_CXVSCROLL
);
221 if (style
& WS_HSCROLL
) rect
->bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
226 static HICON
NC_IconForWindow( HWND hwnd
)
228 HICON hIcon
= (HICON
) GetClassLongA( hwnd
, GCL_HICONSM
);
229 if (!hIcon
) hIcon
= (HICON
) GetClassLongA( hwnd
, GCL_HICON
);
231 /* If there is no hIcon specified and this is a modal dialog,
232 * get the default one.
234 if (!hIcon
&& (GetWindowLongA( hwnd
, GWL_STYLE
) & DS_MODALFRAME
))
235 hIcon
= LoadImageA(0, IDI_WINLOGOA
, IMAGE_ICON
, 0, 0, LR_DEFAULTCOLOR
);
239 /***********************************************************************
240 * DrawCaption (USER.660) Draws a caption bar
254 DrawCaption16 (HWND16 hwnd
, HDC16 hdc
, const RECT16
*rect
, UINT16 uFlags
)
259 CONV_RECT16TO32 (rect
, &rect32
);
261 return (BOOL16
)DrawCaptionTempA (hwnd
, hdc
, rect
? &rect32
: NULL
,
262 0, 0, NULL
, uFlags
& 0x1F);
266 /***********************************************************************
267 * DrawCaption (USER32.@) Draws a caption bar
281 DrawCaption (HWND hwnd
, HDC hdc
, const RECT
*lpRect
, UINT uFlags
)
283 return DrawCaptionTempA (hwnd
, hdc
, lpRect
, 0, 0, NULL
, uFlags
& 0x1F);
287 /***********************************************************************
288 * DrawCaptionTemp (USER.657)
298 DrawCaptionTemp16 (HWND16 hwnd
, HDC16 hdc
, const RECT16
*rect
, HFONT16 hFont
,
299 HICON16 hIcon
, LPCSTR str
, UINT16 uFlags
)
304 CONV_RECT16TO32(rect
,&rect32
);
306 return (BOOL16
)DrawCaptionTempA (hwnd
, hdc
, rect
?&rect32
:NULL
, hFont
,
307 hIcon
, str
, uFlags
& 0x1F);
311 /***********************************************************************
312 * DrawCaptionTempA (USER32.@)
322 DrawCaptionTempA (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
323 HICON hIcon
, LPCSTR str
, UINT uFlags
)
327 TRACE("(%08x,%08x,%p,%08x,%08x,\"%s\",%08x)\n",
328 hwnd
, hdc
, rect
, hFont
, hIcon
, str
, uFlags
);
330 /* drawing background */
331 if (uFlags
& DC_INBUTTON
) {
332 FillRect (hdc
, &rc
, GetSysColorBrush (COLOR_3DFACE
));
334 if (uFlags
& DC_ACTIVE
) {
335 HBRUSH hbr
= SelectObject (hdc
, CACHE_GetPattern55AABrush ());
336 PatBlt (hdc
, rc
.left
, rc
.top
,
337 rc
.right
-rc
.left
, rc
.bottom
-rc
.top
, 0xFA0089);
338 SelectObject (hdc
, hbr
);
342 FillRect (hdc
, &rc
, GetSysColorBrush ((uFlags
& DC_ACTIVE
) ?
343 COLOR_ACTIVECAPTION
: COLOR_INACTIVECAPTION
));
348 if ((uFlags
& DC_ICON
) && !(uFlags
& DC_SMALLCAP
)) {
352 pt
.y
= (rc
.bottom
+ rc
.top
- GetSystemMetrics(SM_CYSMICON
)) / 2;
354 if (!hIcon
) hIcon
= NC_IconForWindow(hwnd
);
355 DrawIconEx (hdc
, pt
.x
, pt
.y
, hIcon
, GetSystemMetrics(SM_CXSMICON
),
356 GetSystemMetrics(SM_CYSMICON
), 0, 0, DI_NORMAL
);
357 rc
.left
+= (rc
.bottom
- rc
.top
);
361 if (uFlags
& DC_TEXT
) {
364 if (uFlags
& DC_INBUTTON
)
365 SetTextColor (hdc
, GetSysColor (COLOR_BTNTEXT
));
366 else if (uFlags
& DC_ACTIVE
)
367 SetTextColor (hdc
, GetSysColor (COLOR_CAPTIONTEXT
));
369 SetTextColor (hdc
, GetSysColor (COLOR_INACTIVECAPTIONTEXT
));
371 SetBkMode (hdc
, TRANSPARENT
);
374 hOldFont
= SelectObject (hdc
, hFont
);
376 NONCLIENTMETRICSA nclm
;
378 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
379 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
380 hNewFont
= CreateFontIndirectA ((uFlags
& DC_SMALLCAP
) ?
381 &nclm
.lfSmCaptionFont
: &nclm
.lfCaptionFont
);
382 hOldFont
= SelectObject (hdc
, hNewFont
);
386 DrawTextA (hdc
, str
, -1, &rc
,
387 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
391 nLen
= GetWindowTextA (hwnd
, szText
, 128);
392 DrawTextA (hdc
, szText
, nLen
, &rc
,
393 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
397 SelectObject (hdc
, hOldFont
);
399 DeleteObject (SelectObject (hdc
, hOldFont
));
402 /* drawing focus ??? */
404 FIXME("undocumented flag (0x2000)!\n");
410 /***********************************************************************
411 * DrawCaptionTempW (USER32.@)
421 DrawCaptionTempW (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
422 HICON hIcon
, LPCWSTR str
, UINT uFlags
)
424 LPSTR p
= HEAP_strdupWtoA (GetProcessHeap (), 0, str
);
425 BOOL res
= DrawCaptionTempA (hwnd
, hdc
, rect
, hFont
, hIcon
, p
, uFlags
);
426 HeapFree (GetProcessHeap (), 0, p
);
431 /***********************************************************************
432 * AdjustWindowRect (USER.102)
434 BOOL16 WINAPI
AdjustWindowRect16( LPRECT16 rect
, DWORD style
, BOOL16 menu
)
436 return AdjustWindowRectEx16( rect
, style
, menu
, 0 );
440 /***********************************************************************
441 * AdjustWindowRect (USER32.@)
443 BOOL WINAPI
AdjustWindowRect( LPRECT rect
, DWORD style
, BOOL menu
)
445 return AdjustWindowRectEx( rect
, style
, menu
, 0 );
449 /***********************************************************************
450 * AdjustWindowRectEx (USER.454)
452 BOOL16 WINAPI
AdjustWindowRectEx16( LPRECT16 rect
, DWORD style
,
453 BOOL16 menu
, DWORD exStyle
)
458 CONV_RECT16TO32( rect
, &rect32
);
459 ret
= AdjustWindowRectEx( &rect32
, style
, menu
, exStyle
);
460 CONV_RECT32TO16( &rect32
, rect
);
465 /***********************************************************************
466 * AdjustWindowRectEx (USER32.@)
468 BOOL WINAPI
AdjustWindowRectEx( LPRECT rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
470 /* Correct the window style */
472 if (!(style
& (WS_POPUP
| WS_CHILD
))) style
|= WS_CAPTION
; /* Overlapped window */
473 style
&= (WS_DLGFRAME
| WS_BORDER
| WS_THICKFRAME
| WS_CHILD
);
474 exStyle
&= (WS_EX_DLGMODALFRAME
| WS_EX_CLIENTEDGE
|
475 WS_EX_STATICEDGE
| WS_EX_TOOLWINDOW
);
476 if (exStyle
& WS_EX_DLGMODALFRAME
) style
&= ~WS_THICKFRAME
;
478 TRACE("(%d,%d)-(%d,%d) %08lx %d %08lx\n",
479 rect
->left
, rect
->top
, rect
->right
, rect
->bottom
,
480 style
, menu
, exStyle
);
482 if (TWEAK_WineLook
== WIN31_LOOK
)
483 NC_AdjustRect( rect
, style
, menu
, exStyle
);
486 NC_AdjustRectOuter95( rect
, style
, menu
, exStyle
);
487 NC_AdjustRectInner95( rect
, style
, exStyle
);
493 /***********************************************************************
494 * NC_HandleNCCalcSize
496 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
498 LONG
NC_HandleNCCalcSize( HWND hwnd
, RECT
*winRect
)
500 RECT tmpRect
= { 0, 0, 0, 0 };
502 LONG cls_style
= GetClassLongA(hwnd
, GCL_STYLE
);
503 LONG style
= GetWindowLongA( hwnd
, GWL_STYLE
);
504 LONG exStyle
= GetWindowLongA( hwnd
, GWL_EXSTYLE
);
506 if (cls_style
& CS_VREDRAW
) result
|= WVR_VREDRAW
;
507 if (cls_style
& CS_HREDRAW
) result
|= WVR_HREDRAW
;
511 if (TWEAK_WineLook
== WIN31_LOOK
)
512 NC_AdjustRect( &tmpRect
, style
, FALSE
, exStyle
);
514 NC_AdjustRectOuter95( &tmpRect
, style
, FALSE
, exStyle
);
516 winRect
->left
-= tmpRect
.left
;
517 winRect
->top
-= tmpRect
.top
;
518 winRect
->right
-= tmpRect
.right
;
519 winRect
->bottom
-= tmpRect
.bottom
;
521 if (!(style
& WS_CHILD
) && GetMenu(hwnd
))
523 TRACE("Calling GetMenuBarHeight with HWND 0x%x, width %d, "
524 "at (%d, %d).\n", hwnd
,
525 winRect
->right
- winRect
->left
,
526 -tmpRect
.left
, -tmpRect
.top
);
529 MENU_GetMenuBarHeight( hwnd
,
530 winRect
->right
- winRect
->left
,
531 -tmpRect
.left
, -tmpRect
.top
) + 1;
534 if (TWEAK_WineLook
> WIN31_LOOK
) {
535 SetRect(&tmpRect
, 0, 0, 0, 0);
536 NC_AdjustRectInner95 (&tmpRect
, style
, exStyle
);
537 winRect
->left
-= tmpRect
.left
;
538 winRect
->top
-= tmpRect
.top
;
539 winRect
->right
-= tmpRect
.right
;
540 winRect
->bottom
-= tmpRect
.bottom
;
543 if (winRect
->top
> winRect
->bottom
)
544 winRect
->bottom
= winRect
->top
;
546 if (winRect
->left
> winRect
->right
)
547 winRect
->right
= winRect
->left
;
553 /***********************************************************************
556 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
557 * but without the borders (if any).
558 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
560 void NC_GetInsideRect( HWND hwnd
, RECT
*rect
)
562 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
564 rect
->top
= rect
->left
= 0;
565 rect
->right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
566 rect
->bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
568 if (wndPtr
->dwStyle
& WS_ICONIC
) goto END
;
570 /* Remove frame from rectangle */
571 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
573 InflateRect( rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
575 else if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
577 InflateRect( rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
578 /* FIXME: this isn't in NC_AdjustRect? why not? */
579 if ((TWEAK_WineLook
== WIN31_LOOK
) && (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
))
580 InflateRect( rect
, -1, 0 );
582 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
584 InflateRect( rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
) );
587 /* We have additional border information if the window
588 * is a child (but not an MDI child) */
589 if (TWEAK_WineLook
!= WIN31_LOOK
)
591 if ( (wndPtr
->dwStyle
& WS_CHILD
) &&
592 ( (wndPtr
->dwExStyle
& WS_EX_MDICHILD
) == 0 ) )
594 if (wndPtr
->dwExStyle
& WS_EX_CLIENTEDGE
)
595 InflateRect (rect
, -GetSystemMetrics(SM_CXEDGE
), -GetSystemMetrics(SM_CYEDGE
));
596 if (wndPtr
->dwExStyle
& WS_EX_STATICEDGE
)
597 InflateRect (rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
602 WIN_ReleaseWndPtr(wndPtr
);
607 /***********************************************************************
610 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
613 static LONG
NC_DoNCHitTest (WND
*wndPtr
, POINT pt
)
617 TRACE("hwnd=%04x pt=%ld,%ld\n", wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
619 GetWindowRect(wndPtr
->hwndSelf
, &rect
);
620 if (!PtInRect( &rect
, pt
)) return HTNOWHERE
;
622 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
625 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
627 InflateRect( &rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
628 if (!PtInRect( &rect
, pt
))
630 /* Check top sizing border */
633 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
634 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
637 /* Check bottom sizing border */
638 if (pt
.y
>= rect
.bottom
)
640 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
641 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
644 /* Check left sizing border */
645 if (pt
.x
< rect
.left
)
647 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
648 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
651 /* Check right sizing border */
652 if (pt
.x
>= rect
.right
)
654 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
655 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
660 else /* No thick frame */
662 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
663 InflateRect(&rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
664 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
665 InflateRect(&rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
666 if (!PtInRect( &rect
, pt
)) return HTBORDER
;
671 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
673 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
) - GetSystemMetrics(SM_CYBORDER
);
674 if (!PtInRect( &rect
, pt
))
676 /* Check system menu */
677 if ((wndPtr
->dwStyle
& WS_SYSMENU
) && !(wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
))
678 rect
.left
+= GetSystemMetrics(SM_CXSIZE
);
679 if (pt
.x
<= rect
.left
) return HTSYSMENU
;
681 /* Check maximize box */
682 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
683 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
685 if (pt
.x
>= rect
.right
) return HTMAXBUTTON
;
686 /* Check minimize box */
687 if (wndPtr
->dwStyle
& WS_MINIMIZEBOX
)
688 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
689 if (pt
.x
>= rect
.right
) return HTMINBUTTON
;
694 /* Check client area */
696 ScreenToClient( wndPtr
->hwndSelf
, &pt
);
697 GetClientRect( wndPtr
->hwndSelf
, &rect
);
698 if (PtInRect( &rect
, pt
)) return HTCLIENT
;
700 /* Check vertical scroll bar */
702 if (wndPtr
->dwStyle
& WS_VSCROLL
)
704 rect
.right
+= GetSystemMetrics(SM_CXVSCROLL
);
705 if (PtInRect( &rect
, pt
)) return HTVSCROLL
;
708 /* Check horizontal scroll bar */
710 if (wndPtr
->dwStyle
& WS_HSCROLL
)
712 rect
.bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
713 if (PtInRect( &rect
, pt
))
716 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
717 (pt
.x
>= rect
.right
- GetSystemMetrics(SM_CXVSCROLL
)))
725 if (HAS_MENU(wndPtr
))
727 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
731 /* Has to return HTNOWHERE if nothing was found
732 Could happen when a window has a customized non client area */
737 /***********************************************************************
740 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
742 * FIXME: Just a modified copy of the Win 3.1 version.
745 static LONG
NC_DoNCHitTest95 (WND
*wndPtr
, POINT pt
)
749 TRACE("hwnd=%04x pt=%ld,%ld\n", wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
751 GetWindowRect(wndPtr
->hwndSelf
, &rect
);
752 if (!PtInRect( &rect
, pt
)) return HTNOWHERE
;
754 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
757 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
759 InflateRect( &rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
760 if (!PtInRect( &rect
, pt
))
762 /* Check top sizing border */
765 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
766 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
769 /* Check bottom sizing border */
770 if (pt
.y
>= rect
.bottom
)
772 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
773 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
776 /* Check left sizing border */
777 if (pt
.x
< rect
.left
)
779 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
780 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
783 /* Check right sizing border */
784 if (pt
.x
>= rect
.right
)
786 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
787 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
792 else /* No thick frame */
794 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
795 InflateRect(&rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
796 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
797 InflateRect(&rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
798 if (!PtInRect( &rect
, pt
)) return HTBORDER
;
803 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
805 if (wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
)
806 rect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
) - 1;
808 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
809 if (!PtInRect( &rect
, pt
))
811 /* Check system menu */
812 if ((wndPtr
->dwStyle
& WS_SYSMENU
) && !(wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
))
814 if (NC_IconForWindow(wndPtr
->hwndSelf
))
815 rect
.left
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
817 if (pt
.x
< rect
.left
) return HTSYSMENU
;
819 /* Check close button */
820 if (wndPtr
->dwStyle
& WS_SYSMENU
)
821 rect
.right
-= GetSystemMetrics(SM_CYCAPTION
) - 1;
822 if (pt
.x
> rect
.right
) return HTCLOSE
;
824 /* Check maximize box */
825 /* In win95 there is automatically a Maximize button when there is a minimize one*/
826 if ((wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)|| (wndPtr
->dwStyle
& WS_MINIMIZEBOX
))
827 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
828 if (pt
.x
> rect
.right
) return HTMAXBUTTON
;
830 /* Check minimize box */
831 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
832 if ((wndPtr
->dwStyle
& WS_MINIMIZEBOX
)||(wndPtr
->dwStyle
& WS_MAXIMIZEBOX
))
833 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
835 if (pt
.x
> rect
.right
) return HTMINBUTTON
;
840 /* Check client area */
842 ScreenToClient( wndPtr
->hwndSelf
, &pt
);
843 GetClientRect( wndPtr
->hwndSelf
, &rect
);
844 if (PtInRect( &rect
, pt
)) return HTCLIENT
;
846 /* Check vertical scroll bar */
848 if (wndPtr
->dwStyle
& WS_VSCROLL
)
850 rect
.right
+= GetSystemMetrics(SM_CXVSCROLL
);
851 if (PtInRect( &rect
, pt
)) return HTVSCROLL
;
854 /* Check horizontal scroll bar */
856 if (wndPtr
->dwStyle
& WS_HSCROLL
)
858 rect
.bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
859 if (PtInRect( &rect
, pt
))
862 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
863 (pt
.x
>= rect
.right
- GetSystemMetrics(SM_CXVSCROLL
)))
871 if (HAS_MENU(wndPtr
))
873 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
877 /* Has to return HTNOWHERE if nothing was found
878 Could happen when a window has a customized non client area */
883 /***********************************************************************
886 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
888 LONG
NC_HandleNCHitTest (HWND hwnd
, POINT pt
)
891 WND
*wndPtr
= WIN_FindWndPtr (hwnd
);
896 if (TWEAK_WineLook
== WIN31_LOOK
)
897 retvalue
= NC_DoNCHitTest (wndPtr
, pt
);
899 retvalue
= NC_DoNCHitTest95 (wndPtr
, pt
);
900 WIN_ReleaseWndPtr(wndPtr
);
905 /***********************************************************************
908 void NC_DrawSysButton( HWND hwnd
, HDC hdc
, BOOL down
)
914 NC_GetInsideRect( hwnd
, &rect
);
915 hdcMem
= CreateCompatibleDC( hdc
);
916 hbitmap
= SelectObject( hdcMem
, hbitmapClose
);
917 BitBlt(hdc
, rect
.left
, rect
.top
, GetSystemMetrics(SM_CXSIZE
), GetSystemMetrics(SM_CYSIZE
),
918 hdcMem
, (GetWindowLongA(hwnd
,GWL_STYLE
) & WS_CHILD
) ? GetSystemMetrics(SM_CXSIZE
) : 0, 0,
919 down
? NOTSRCCOPY
: SRCCOPY
);
920 SelectObject( hdcMem
, hbitmap
);
925 /***********************************************************************
928 static void NC_DrawMaxButton( HWND hwnd
, HDC16 hdc
, BOOL down
)
933 NC_GetInsideRect( hwnd
, &rect
);
934 hdcMem
= CreateCompatibleDC( hdc
);
935 SelectObject( hdcMem
, (IsZoomed(hwnd
)
936 ? (down
? hbitmapRestoreD
: hbitmapRestore
)
937 : (down
? hbitmapMaximizeD
: hbitmapMaximize
)) );
938 BitBlt( hdc
, rect
.right
- GetSystemMetrics(SM_CXSIZE
) - 1, rect
.top
,
939 GetSystemMetrics(SM_CXSIZE
) + 1, GetSystemMetrics(SM_CYSIZE
), hdcMem
, 0, 0,
946 /***********************************************************************
949 static void NC_DrawMinButton( HWND hwnd
, HDC16 hdc
, BOOL down
)
954 NC_GetInsideRect( hwnd
, &rect
);
955 hdcMem
= CreateCompatibleDC( hdc
);
956 SelectObject( hdcMem
, (down
? hbitmapMinimizeD
: hbitmapMinimize
) );
957 if (GetWindowLongA(hwnd
,GWL_STYLE
) & WS_MAXIMIZEBOX
)
958 rect
.right
-= GetSystemMetrics(SM_CXSIZE
)+1;
959 BitBlt( hdc
, rect
.right
- GetSystemMetrics(SM_CXSIZE
) - 1, rect
.top
,
960 GetSystemMetrics(SM_CXSIZE
) + 1, GetSystemMetrics(SM_CYSIZE
), hdcMem
, 0, 0,
966 /******************************************************************************
968 * void NC_DrawSysButton95(
973 * Draws the Win95 system icon.
976 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
977 * Original implementation from NC_DrawSysButton source.
978 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
981 *****************************************************************************/
984 NC_DrawSysButton95 (HWND hwnd
, HDC hdc
, BOOL down
)
986 HICON hIcon
= NC_IconForWindow( hwnd
);
991 NC_GetInsideRect( hwnd
, &rect
);
992 DrawIconEx (hdc
, rect
.left
+ 2, rect
.top
+ 2, hIcon
,
993 GetSystemMetrics(SM_CXSMICON
),
994 GetSystemMetrics(SM_CYSMICON
), 0, 0, DI_NORMAL
);
1000 /******************************************************************************
1002 * void NC_DrawCloseButton95(
1008 * Draws the Win95 close button.
1010 * If bGrayed is true, then draw a disabled Close button
1013 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1014 * Original implementation from NC_DrawSysButton95 source.
1016 *****************************************************************************/
1018 static void NC_DrawCloseButton95 (HWND hwnd
, HDC hdc
, BOOL down
, BOOL bGrayed
)
1022 NC_GetInsideRect( hwnd
, &rect
);
1024 /* A tool window has a smaller Close button */
1025 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_TOOLWINDOW
)
1027 INT iBmpHeight
= 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
1028 INT iBmpWidth
= 11; /* it uses 11x11 for the close button in tool window */
1029 INT iCaptionHeight
= GetSystemMetrics(SM_CYSMCAPTION
);
1031 rect
.top
= rect
.top
+ (iCaptionHeight
- 1 - iBmpHeight
) / 2;
1032 rect
.left
= rect
.right
- (iCaptionHeight
+ 1 + iBmpWidth
) / 2;
1033 rect
.bottom
= rect
.top
+ iBmpHeight
;
1034 rect
.right
= rect
.left
+ iBmpWidth
;
1038 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
) - 1;
1039 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1043 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
,
1044 (DFCS_CAPTIONCLOSE
|
1045 (down
? DFCS_PUSHED
: 0) |
1046 (bGrayed
? DFCS_INACTIVE
: 0)) );
1049 /******************************************************************************
1050 * NC_DrawMaxButton95
1052 * Draws the maximize button for Win95 style windows.
1053 * If bGrayed is true, then draw a disabled Maximize button
1055 static void NC_DrawMaxButton95(HWND hwnd
,HDC16 hdc
,BOOL down
, BOOL bGrayed
)
1058 UINT flags
= IsZoomed(hwnd
) ? DFCS_CAPTIONRESTORE
: DFCS_CAPTIONMAX
;
1060 NC_GetInsideRect( hwnd
, &rect
);
1061 if (GetWindowLongA( hwnd
, GWL_STYLE
) & WS_SYSMENU
)
1062 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1063 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
);
1064 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1067 if (down
) flags
|= DFCS_PUSHED
;
1068 if (bGrayed
) flags
|= DFCS_INACTIVE
;
1069 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
1072 /******************************************************************************
1073 * NC_DrawMinButton95
1075 * Draws the minimize button for Win95 style windows.
1076 * If bGrayed is true, then draw a disabled Minimize button
1078 static void NC_DrawMinButton95(HWND hwnd
,HDC16 hdc
,BOOL down
, BOOL bGrayed
)
1081 UINT flags
= DFCS_CAPTIONMIN
;
1082 DWORD style
= GetWindowLongA( hwnd
, GWL_STYLE
);
1084 NC_GetInsideRect( hwnd
, &rect
);
1085 if (style
& WS_SYSMENU
)
1086 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1087 if (style
& (WS_MAXIMIZEBOX
|WS_MINIMIZEBOX
))
1088 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) - 2;
1089 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
);
1090 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1093 if (down
) flags
|= DFCS_PUSHED
;
1094 if (bGrayed
) flags
|= DFCS_INACTIVE
;
1095 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
1098 /***********************************************************************
1101 * Draw a window frame inside the given rectangle, and update the rectangle.
1102 * The correct pen for the frame must be selected in the DC.
1104 static void NC_DrawFrame( HDC hdc
, RECT
*rect
, BOOL dlgFrame
,
1109 if (TWEAK_WineLook
!= WIN31_LOOK
)
1110 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
1114 width
= GetSystemMetrics(SM_CXDLGFRAME
) - 1;
1115 height
= GetSystemMetrics(SM_CYDLGFRAME
) - 1;
1116 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1117 COLOR_INACTIVECAPTION
) );
1121 width
= GetSystemMetrics(SM_CXFRAME
) - 2;
1122 height
= GetSystemMetrics(SM_CYFRAME
) - 2;
1123 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1124 COLOR_INACTIVEBORDER
) );
1128 PatBlt( hdc
, rect
->left
, rect
->top
,
1129 rect
->right
- rect
->left
, height
, PATCOPY
);
1130 PatBlt( hdc
, rect
->left
, rect
->top
,
1131 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1132 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1133 rect
->right
- rect
->left
, -height
, PATCOPY
);
1134 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1135 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1139 InflateRect( rect
, -width
, -height
);
1143 INT decYOff
= GetSystemMetrics(SM_CXFRAME
) + GetSystemMetrics(SM_CXSIZE
) - 1;
1144 INT decXOff
= GetSystemMetrics(SM_CYFRAME
) + GetSystemMetrics(SM_CYSIZE
) - 1;
1146 /* Draw inner rectangle */
1148 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1149 Rectangle( hdc
, rect
->left
+ width
, rect
->top
+ height
,
1150 rect
->right
- width
, rect
->bottom
- height
);
1152 /* Draw the decorations */
1154 MoveToEx( hdc
, rect
->left
, rect
->top
+ decYOff
, NULL
);
1155 LineTo( hdc
, rect
->left
+ width
, rect
->top
+ decYOff
);
1156 MoveToEx( hdc
, rect
->right
- 1, rect
->top
+ decYOff
, NULL
);
1157 LineTo( hdc
, rect
->right
- width
- 1, rect
->top
+ decYOff
);
1158 MoveToEx( hdc
, rect
->left
, rect
->bottom
- decYOff
, NULL
);
1159 LineTo( hdc
, rect
->left
+ width
, rect
->bottom
- decYOff
);
1160 MoveToEx( hdc
, rect
->right
- 1, rect
->bottom
- decYOff
, NULL
);
1161 LineTo( hdc
, rect
->right
- width
- 1, rect
->bottom
- decYOff
);
1163 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->top
, NULL
);
1164 LineTo( hdc
, rect
->left
+ decXOff
, rect
->top
+ height
);
1165 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->bottom
- 1, NULL
);
1166 LineTo( hdc
, rect
->left
+ decXOff
, rect
->bottom
- height
- 1 );
1167 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->top
, NULL
);
1168 LineTo( hdc
, rect
->right
- decXOff
, rect
->top
+ height
);
1169 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->bottom
- 1, NULL
);
1170 LineTo( hdc
, rect
->right
- decXOff
, rect
->bottom
- height
- 1 );
1172 InflateRect( rect
, -width
- 1, -height
- 1 );
1177 /******************************************************************************
1179 * void NC_DrawFrame95(
1186 * Draw a window frame inside the given rectangle, and update the rectangle.
1189 * Many. First, just what IS a frame in Win95? Note that the 3D look
1190 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1191 * edge. The inner rectangle just inside the frame is handled by the
1194 * In short, for most people, this function should be a nop (unless
1195 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1196 * them lately, but just to get this code right). Even so, it doesn't
1197 * appear to be so. It's being worked on...
1200 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1201 * Original implementation (based on NC_DrawFrame)
1202 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1204 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1205 * Fixed a fix or something.
1207 *****************************************************************************/
1209 static void NC_DrawFrame95(
1218 /* Firstly the "thick" frame */
1219 if (style
& WS_THICKFRAME
)
1221 width
= GetSystemMetrics(SM_CXFRAME
) - GetSystemMetrics(SM_CXDLGFRAME
);
1222 height
= GetSystemMetrics(SM_CYFRAME
) - GetSystemMetrics(SM_CYDLGFRAME
);
1224 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1225 COLOR_INACTIVEBORDER
) );
1227 PatBlt( hdc
, rect
->left
, rect
->top
,
1228 rect
->right
- rect
->left
, height
, PATCOPY
);
1229 PatBlt( hdc
, rect
->left
, rect
->top
,
1230 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1231 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1232 rect
->right
- rect
->left
, -height
, PATCOPY
);
1233 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1234 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1236 InflateRect( rect
, -width
, -height
);
1239 /* Now the other bit of the frame */
1240 if ((style
& (WS_BORDER
|WS_DLGFRAME
)) ||
1241 (exStyle
& WS_EX_DLGMODALFRAME
))
1243 width
= GetSystemMetrics(SM_CXDLGFRAME
) - GetSystemMetrics(SM_CXEDGE
);
1244 height
= GetSystemMetrics(SM_CYDLGFRAME
) - GetSystemMetrics(SM_CYEDGE
);
1245 /* This should give a value of 1 that should also work for a border */
1247 SelectObject( hdc
, GetSysColorBrush(
1248 (exStyle
& (WS_EX_DLGMODALFRAME
|WS_EX_CLIENTEDGE
)) ?
1250 (exStyle
& WS_EX_STATICEDGE
) ?
1252 (style
& (WS_DLGFRAME
|WS_THICKFRAME
)) ?
1255 COLOR_WINDOWFRAME
));
1258 PatBlt( hdc
, rect
->left
, rect
->top
,
1259 rect
->right
- rect
->left
, height
, PATCOPY
);
1260 PatBlt( hdc
, rect
->left
, rect
->top
,
1261 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1262 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1263 rect
->right
- rect
->left
, -height
, PATCOPY
);
1264 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1265 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1267 InflateRect( rect
, -width
, -height
);
1272 /***********************************************************************
1275 * Draw the window caption.
1276 * The correct pen for the window frame must be selected in the DC.
1278 static void NC_DrawCaption( HDC hdc
, RECT
*rect
, HWND hwnd
,
1279 DWORD style
, BOOL active
)
1286 if (!(hbitmapClose
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_CLOSE
) ))) return;
1287 hbitmapMinimize
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_REDUCE
) );
1288 hbitmapMinimizeD
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_REDUCED
) );
1289 hbitmapMaximize
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_ZOOM
) );
1290 hbitmapMaximizeD
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_ZOOMD
) );
1291 hbitmapRestore
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RESTORE
) );
1292 hbitmapRestoreD
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RESTORED
) );
1295 if (GetWindowLongA( hwnd
, GWL_EXSTYLE
) & WS_EX_DLGMODALFRAME
)
1297 HBRUSH hbrushOld
= SelectObject(hdc
, GetSysColorBrush(COLOR_WINDOW
) );
1298 PatBlt( hdc
, r
.left
, r
.top
, 1, r
.bottom
-r
.top
+1,PATCOPY
);
1299 PatBlt( hdc
, r
.right
-1, r
.top
, 1, r
.bottom
-r
.top
+1, PATCOPY
);
1300 PatBlt( hdc
, r
.left
, r
.top
-1, r
.right
-r
.left
, 1, PATCOPY
);
1303 SelectObject( hdc
, hbrushOld
);
1305 MoveToEx( hdc
, r
.left
, r
.bottom
, NULL
);
1306 LineTo( hdc
, r
.right
, r
.bottom
);
1308 if (style
& WS_SYSMENU
)
1310 NC_DrawSysButton( hwnd
, hdc
, FALSE
);
1311 r
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
1312 MoveToEx( hdc
, r
.left
- 1, r
.top
, NULL
);
1313 LineTo( hdc
, r
.left
- 1, r
.bottom
);
1315 if (style
& WS_MAXIMIZEBOX
)
1317 NC_DrawMaxButton( hwnd
, hdc
, FALSE
);
1318 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1320 if (style
& WS_MINIMIZEBOX
)
1322 NC_DrawMinButton( hwnd
, hdc
, FALSE
);
1323 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1326 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1327 COLOR_INACTIVECAPTION
) );
1329 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) ))
1331 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1332 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1333 SetBkMode( hdc
, TRANSPARENT
);
1334 DrawTextA( hdc
, buffer
, -1, &r
,
1335 DT_SINGLELINE
| DT_CENTER
| DT_VCENTER
| DT_NOPREFIX
);
1340 /******************************************************************************
1349 * Draw the window caption for Win95 style windows.
1350 * The correct pen for the window frame must be selected in the DC.
1353 * Hey, a function that finally works! Well, almost.
1354 * It's being worked on.
1357 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1358 * Original implementation.
1359 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1362 *****************************************************************************/
1364 static void NC_DrawCaption95(
1377 hPrevPen
= SelectObject( hdc
, GetSysColorPen(
1378 ((exStyle
& (WS_EX_STATICEDGE
|WS_EX_CLIENTEDGE
|
1379 WS_EX_DLGMODALFRAME
)) == WS_EX_STATICEDGE
) ?
1380 COLOR_WINDOWFRAME
: COLOR_3DFACE
) );
1381 MoveToEx( hdc
, r
.left
, r
.bottom
- 1, NULL
);
1382 LineTo( hdc
, r
.right
, r
.bottom
- 1 );
1383 SelectObject( hdc
, hPrevPen
);
1386 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1387 COLOR_INACTIVECAPTION
) );
1389 if ((style
& WS_SYSMENU
) && !(exStyle
& WS_EX_TOOLWINDOW
)) {
1390 if (NC_DrawSysButton95 (hwnd
, hdc
, FALSE
))
1391 r
.left
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
1394 if (style
& WS_SYSMENU
)
1398 /* Go get the sysmenu */
1399 hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1400 state
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
);
1402 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1403 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
,
1404 ((((state
& MF_DISABLED
) || (state
& MF_GRAYED
))) && (state
!= 0xFFFFFFFF)));
1405 r
.right
-= GetSystemMetrics(SM_CYCAPTION
) - 1;
1407 if ((style
& WS_MAXIMIZEBOX
) || (style
& WS_MINIMIZEBOX
))
1409 /* In win95 the two buttons are always there */
1410 /* But if the menu item is not in the menu they're disabled*/
1412 NC_DrawMaxButton95( hwnd
, hdc
, FALSE
, (!(style
& WS_MAXIMIZEBOX
)));
1413 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1415 NC_DrawMinButton95( hwnd
, hdc
, FALSE
, (!(style
& WS_MINIMIZEBOX
)));
1416 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1420 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) )) {
1421 NONCLIENTMETRICSA nclm
;
1422 HFONT hFont
, hOldFont
;
1423 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
1424 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
1425 if (exStyle
& WS_EX_TOOLWINDOW
)
1426 hFont
= CreateFontIndirectA (&nclm
.lfSmCaptionFont
);
1428 hFont
= CreateFontIndirectA (&nclm
.lfCaptionFont
);
1429 hOldFont
= SelectObject (hdc
, hFont
);
1430 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1431 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1432 SetBkMode( hdc
, TRANSPARENT
);
1434 DrawTextA( hdc
, buffer
, -1, &r
,
1435 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
1436 DeleteObject (SelectObject (hdc
, hOldFont
));
1442 /***********************************************************************
1445 * Paint the non-client area. clip is currently unused.
1447 static void NC_DoNCPaint( WND
* wndPtr
, HRGN clip
, BOOL suppress_menupaint
)
1452 HWND hwnd
= wndPtr
->hwndSelf
;
1454 if ( wndPtr
->dwStyle
& WS_MINIMIZE
||
1455 !WIN_IsWindowDrawable( wndPtr
, 0 )) return; /* Nothing to do */
1457 active
= wndPtr
->flags
& WIN_NCACTIVATED
;
1459 TRACE("%04x %d\n", hwnd
, active
);
1461 if (!(hdc
= GetDCEx( hwnd
, (clip
> 1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
1462 ((clip
> 1) ? (DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
): 0) ))) return;
1464 if (ExcludeVisRect16( hdc
, wndPtr
->rectClient
.left
-wndPtr
->rectWindow
.left
,
1465 wndPtr
->rectClient
.top
-wndPtr
->rectWindow
.top
,
1466 wndPtr
->rectClient
.right
-wndPtr
->rectWindow
.left
,
1467 wndPtr
->rectClient
.bottom
-wndPtr
->rectWindow
.top
)
1470 ReleaseDC( hwnd
, hdc
);
1474 rect
.top
= rect
.left
= 0;
1475 rect
.right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
1476 rect
.bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
1478 SelectObject( hdc
, GetSysColorPen(COLOR_WINDOWFRAME
) );
1480 if (HAS_ANYFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1482 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1483 Rectangle( hdc
, 0, 0, rect
.right
, rect
.bottom
);
1484 InflateRect( &rect
, -1, -1 );
1487 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1488 NC_DrawFrame(hdc
, &rect
, FALSE
, active
);
1489 else if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1490 NC_DrawFrame( hdc
, &rect
, TRUE
, active
);
1492 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1495 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
);
1496 rect
.top
+= GetSystemMetrics(SM_CYSIZE
) + GetSystemMetrics(SM_CYBORDER
);
1497 NC_DrawCaption( hdc
, &r
, hwnd
, wndPtr
->dwStyle
, active
);
1500 if (HAS_MENU(wndPtr
))
1503 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYMENU
); /* default height */
1504 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
);
1507 /* Draw the scroll-bars */
1509 if (wndPtr
->dwStyle
& WS_VSCROLL
)
1510 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1511 if (wndPtr
->dwStyle
& WS_HSCROLL
)
1512 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1514 /* Draw the "size-box" */
1516 if ((wndPtr
->dwStyle
& WS_VSCROLL
) && (wndPtr
->dwStyle
& WS_HSCROLL
))
1519 r
.left
= r
.right
- GetSystemMetrics(SM_CXVSCROLL
) + 1;
1520 r
.top
= r
.bottom
- GetSystemMetrics(SM_CYHSCROLL
) + 1;
1521 if(wndPtr
->dwStyle
& WS_BORDER
) {
1525 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1528 ReleaseDC( hwnd
, hdc
);
1532 /******************************************************************************
1534 * void NC_DoNCPaint95(
1537 * BOOL suppress_menupaint )
1539 * Paint the non-client area for Win95 windows. The clip region is
1540 * currently ignored.
1543 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1544 * misc/tweak.c controls/menu.c # :-)
1547 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1548 * Original implementation
1549 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1551 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1552 * Streamlined window style checks.
1554 *****************************************************************************/
1556 static void NC_DoNCPaint95(
1559 BOOL suppress_menupaint
)
1562 RECT rfuzz
, rect
, rectClip
;
1564 HWND hwnd
= wndPtr
->hwndSelf
;
1566 if ( wndPtr
->dwStyle
& WS_MINIMIZE
||
1567 !WIN_IsWindowDrawable( wndPtr
, 0 )) return; /* Nothing to do */
1569 active
= wndPtr
->flags
& WIN_NCACTIVATED
;
1571 TRACE("%04x %d\n", hwnd
, active
);
1573 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1574 the call to GetDCEx implying that it is allowed not to use it either.
1575 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1576 will cause clipRgn to be deleted after ReleaseDC().
1577 Now, how is the "system" supposed to tell what happened?
1580 if (!(hdc
= GetDCEx( hwnd
, (clip
> 1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
1581 ((clip
> 1) ?(DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
) : 0) ))) return;
1584 if (ExcludeVisRect16( hdc
, wndPtr
->rectClient
.left
-wndPtr
->rectWindow
.left
,
1585 wndPtr
->rectClient
.top
-wndPtr
->rectWindow
.top
,
1586 wndPtr
->rectClient
.right
-wndPtr
->rectWindow
.left
,
1587 wndPtr
->rectClient
.bottom
-wndPtr
->rectWindow
.top
)
1590 ReleaseDC( hwnd
, hdc
);
1594 rect
.top
= rect
.left
= 0;
1595 rect
.right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
1596 rect
.bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
1599 GetRgnBox( clip
, &rectClip
);
1606 SelectObject( hdc
, GetSysColorPen(COLOR_WINDOWFRAME
) );
1608 if (HAS_STATICOUTERFRAME(wndPtr
->dwStyle
, wndPtr
->dwExStyle
)) {
1609 DrawEdge (hdc
, &rect
, BDR_SUNKENOUTER
, BF_RECT
| BF_ADJUST
);
1611 else if (HAS_BIGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
)) {
1612 DrawEdge (hdc
, &rect
, EDGE_RAISED
, BF_RECT
| BF_ADJUST
);
1615 NC_DrawFrame95(hdc
, &rect
, active
, wndPtr
->dwStyle
, wndPtr
->dwExStyle
);
1617 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1620 if (wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
) {
1621 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSMCAPTION
);
1622 rect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
);
1625 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYCAPTION
);
1626 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
);
1628 if( !clip
|| IntersectRect( &rfuzz
, &r
, &rectClip
) )
1629 NC_DrawCaption95 (hdc
, &r
, hwnd
, wndPtr
->dwStyle
,
1630 wndPtr
->dwExStyle
, active
);
1633 if (HAS_MENU(wndPtr
))
1636 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYMENU
);
1638 TRACE("Calling DrawMenuBar with rect (%d, %d)-(%d, %d)\n",
1639 r
.left
, r
.top
, r
.right
, r
.bottom
);
1641 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
) + 1;
1644 TRACE("After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1645 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1647 if (wndPtr
->dwExStyle
& WS_EX_CLIENTEDGE
)
1648 DrawEdge (hdc
, &rect
, EDGE_SUNKEN
, BF_RECT
| BF_ADJUST
);
1650 /* Draw the scroll-bars */
1652 if (wndPtr
->dwStyle
& WS_VSCROLL
)
1653 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1654 if (wndPtr
->dwStyle
& WS_HSCROLL
)
1655 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1657 /* Draw the "size-box" */
1658 if ((wndPtr
->dwStyle
& WS_VSCROLL
) && (wndPtr
->dwStyle
& WS_HSCROLL
))
1661 r
.left
= r
.right
- GetSystemMetrics(SM_CXVSCROLL
) + 1;
1662 r
.top
= r
.bottom
- GetSystemMetrics(SM_CYHSCROLL
) + 1;
1663 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1666 ReleaseDC( hwnd
, hdc
);
1672 /***********************************************************************
1675 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1677 LONG
NC_HandleNCPaint( HWND hwnd
, HRGN clip
)
1679 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1681 if( wndPtr
&& wndPtr
->dwStyle
& WS_VISIBLE
)
1683 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
1684 WINPOS_RedrawIconTitle( hwnd
);
1685 else if (TWEAK_WineLook
== WIN31_LOOK
)
1686 NC_DoNCPaint( wndPtr
, clip
, FALSE
);
1688 NC_DoNCPaint95( wndPtr
, clip
, FALSE
);
1690 WIN_ReleaseWndPtr(wndPtr
);
1695 /***********************************************************************
1696 * NC_HandleNCActivate
1698 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1700 LONG
NC_HandleNCActivate( HWND hwnd
, WPARAM wParam
)
1702 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1704 /* Lotus Notes draws menu descriptions in the caption of its main
1705 * window. When it wants to restore original "system" view, it just
1706 * sends WM_NCACTIVATE message to itself. Any optimizations here in
1707 * attempt to minimize redrawings lead to a not restored caption.
1711 if (wParam
) wndPtr
->flags
|= WIN_NCACTIVATED
;
1712 else wndPtr
->flags
&= ~WIN_NCACTIVATED
;
1714 if (IsIconic(hwnd
)) WINPOS_RedrawIconTitle( hwnd
);
1715 else if (TWEAK_WineLook
== WIN31_LOOK
)
1716 NC_DoNCPaint( wndPtr
, (HRGN
)1, FALSE
);
1718 NC_DoNCPaint95( wndPtr
, (HRGN
)1, FALSE
);
1719 WIN_ReleaseWndPtr(wndPtr
);
1725 /***********************************************************************
1726 * NC_HandleSetCursor
1728 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1730 LONG
NC_HandleSetCursor( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1732 if (hwnd
!= WIN_GetFullHandle( (HWND
)wParam
))
1733 return 0; /* Don't set the cursor for child windows */
1735 switch(LOWORD(lParam
))
1739 WORD msg
= HIWORD( lParam
);
1740 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_MBUTTONDOWN
) ||
1741 (msg
== WM_RBUTTONDOWN
))
1748 HCURSOR hCursor
= GetClassLongA(hwnd
, GCL_HCURSOR
);
1758 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZEWEA
) );
1762 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENSA
) );
1766 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENWSEA
) );
1770 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENESWA
) );
1773 /* Default cursor: arrow */
1774 return (LONG
)SetCursor( LoadCursorA( 0, IDC_ARROWA
) );
1777 /***********************************************************************
1780 void NC_GetSysPopupPos( HWND hwnd
, RECT
* rect
)
1782 if (IsIconic(hwnd
)) GetWindowRect( hwnd
, rect
);
1785 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1786 if (!wndPtr
) return;
1788 NC_GetInsideRect( hwnd
, rect
);
1789 OffsetRect( rect
, wndPtr
->rectWindow
.left
, wndPtr
->rectWindow
.top
);
1790 if (wndPtr
->dwStyle
& WS_CHILD
)
1791 ClientToScreen( GetParent(hwnd
), (POINT
*)rect
);
1792 if (TWEAK_WineLook
== WIN31_LOOK
) {
1793 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CXSIZE
);
1794 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYSIZE
);
1797 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
1798 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
1800 WIN_ReleaseWndPtr( wndPtr
);
1804 /***********************************************************************
1805 * NC_TrackMinMaxBox95
1807 * Track a mouse button press on the minimize or maximize box.
1809 * The big difference between 3.1 and 95 is the disabled button state.
1810 * In win95 the system button can be disabled, so it can ignore the mouse
1814 static void NC_TrackMinMaxBox95( HWND hwnd
, WORD wParam
)
1817 HDC hdc
= GetWindowDC( hwnd
);
1818 BOOL pressed
= TRUE
;
1820 DWORD wndStyle
= GetWindowLongA( hwnd
, GWL_STYLE
);
1821 HMENU hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1823 void (*paintButton
)(HWND
, HDC16
, BOOL
, BOOL
);
1825 if (wParam
== HTMINBUTTON
)
1827 /* If the style is not present, do nothing */
1828 if (!(wndStyle
& WS_MINIMIZEBOX
))
1831 /* Check if the sysmenu item for minimize is there */
1832 state
= GetMenuState(hSysMenu
, SC_MINIMIZE
, MF_BYCOMMAND
);
1834 paintButton
= &NC_DrawMinButton95
;
1838 /* If the style is not present, do nothing */
1839 if (!(wndStyle
& WS_MAXIMIZEBOX
))
1842 /* Check if the sysmenu item for maximize is there */
1843 state
= GetMenuState(hSysMenu
, SC_MAXIMIZE
, MF_BYCOMMAND
);
1845 paintButton
= &NC_DrawMaxButton95
;
1850 (*paintButton
)( hwnd
, hdc
, TRUE
, FALSE
);
1854 BOOL oldstate
= pressed
;
1856 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1857 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1859 if(msg
.message
== WM_LBUTTONUP
)
1862 if(msg
.message
!= WM_MOUSEMOVE
)
1865 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1866 if (pressed
!= oldstate
)
1867 (*paintButton
)( hwnd
, hdc
, pressed
, FALSE
);
1871 (*paintButton
)(hwnd
, hdc
, FALSE
, FALSE
);
1874 ReleaseDC( hwnd
, hdc
);
1876 /* If the item minimize or maximize of the sysmenu are not there */
1877 /* or if the style is not present, do nothing */
1878 if ((!pressed
) || (state
== 0xFFFFFFFF))
1881 if (wParam
== HTMINBUTTON
)
1882 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1884 SendMessageA( hwnd
, WM_SYSCOMMAND
,
1885 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1888 /***********************************************************************
1891 * Track a mouse button press on the minimize or maximize box.
1893 static void NC_TrackMinMaxBox( HWND hwnd
, WORD wParam
)
1896 HDC hdc
= GetWindowDC( hwnd
);
1897 BOOL pressed
= TRUE
;
1898 void (*paintButton
)(HWND
, HDC16
, BOOL
);
1902 if (wParam
== HTMINBUTTON
)
1903 paintButton
= &NC_DrawMinButton
;
1905 paintButton
= &NC_DrawMaxButton
;
1907 (*paintButton
)( hwnd
, hdc
, TRUE
);
1911 BOOL oldstate
= pressed
;
1913 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1914 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1916 if(msg
.message
== WM_LBUTTONUP
)
1919 if(msg
.message
!= WM_MOUSEMOVE
)
1922 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1923 if (pressed
!= oldstate
)
1924 (*paintButton
)( hwnd
, hdc
, pressed
);
1928 (*paintButton
)( hwnd
, hdc
, FALSE
);
1931 ReleaseDC( hwnd
, hdc
);
1933 if (!pressed
) return;
1935 if (wParam
== HTMINBUTTON
)
1936 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1938 SendMessageA( hwnd
, WM_SYSCOMMAND
,
1939 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
1943 /***********************************************************************
1944 * NC_TrackCloseButton95
1946 * Track a mouse button press on the Win95 close button.
1949 NC_TrackCloseButton95 (HWND hwnd
, WORD wParam
)
1953 BOOL pressed
= TRUE
;
1954 HMENU hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1960 state
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
);
1962 /* If the item close of the sysmenu is disabled or not there do nothing */
1963 if((state
& MF_DISABLED
) || (state
& MF_GRAYED
) || (state
== 0xFFFFFFFF))
1966 hdc
= GetWindowDC( hwnd
);
1970 NC_DrawCloseButton95 (hwnd
, hdc
, TRUE
, FALSE
);
1974 BOOL oldstate
= pressed
;
1976 if (!GetMessageW( &msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
)) break;
1977 if (CallMsgFilterW( &msg
, MSGF_MAX
)) continue;
1979 if(msg
.message
== WM_LBUTTONUP
)
1982 if(msg
.message
!= WM_MOUSEMOVE
)
1985 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
1986 if (pressed
!= oldstate
)
1987 NC_DrawCloseButton95 (hwnd
, hdc
, pressed
, FALSE
);
1991 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
, FALSE
);
1994 ReleaseDC( hwnd
, hdc
);
1995 if (!pressed
) return;
1997 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
2001 /***********************************************************************
2004 * Track a mouse button press on the horizontal or vertical scroll-bar.
2006 static void NC_TrackScrollBar( HWND hwnd
, WPARAM wParam
, POINT pt
)
2010 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
2012 if ((wParam
& 0xfff0) == SC_HSCROLL
)
2014 if ((wParam
& 0x0f) != HTHSCROLL
) goto END
;
2015 scrollbar
= SB_HORZ
;
2017 else /* SC_VSCROLL */
2019 if ((wParam
& 0x0f) != HTVSCROLL
) goto END
;
2020 scrollbar
= SB_VERT
;
2023 pt
.x
-= wndPtr
->rectWindow
.left
;
2024 pt
.y
-= wndPtr
->rectWindow
.top
;
2026 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, WM_LBUTTONDOWN
, pt
);
2030 if (!GetMessageW( &msg
, 0, 0, 0 )) break;
2031 if (CallMsgFilterW( &msg
, MSGF_SCROLLBAR
)) continue;
2037 pt
.x
= LOWORD(msg
.lParam
) + wndPtr
->rectClient
.left
- wndPtr
->rectWindow
.left
;
2038 pt
.y
= HIWORD(msg
.lParam
) + wndPtr
->rectClient
.top
- wndPtr
->rectWindow
.top
;
2039 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, msg
.message
, pt
);
2042 TranslateMessage( &msg
);
2043 DispatchMessageW( &msg
);
2046 if (!IsWindow( hwnd
))
2051 } while (msg
.message
!= WM_LBUTTONUP
);
2053 WIN_ReleaseWndPtr(wndPtr
);
2056 /***********************************************************************
2057 * NC_HandleNCLButtonDown
2059 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2061 LONG
NC_HandleNCLButtonDown( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2063 LONG style
= GetWindowLongA( hwnd
, GWL_STYLE
);
2065 switch(wParam
) /* Hit test */
2069 HWND top
= GetAncestor( hwnd
, GA_ROOT
);
2071 if( WINPOS_SetActiveWindow(top
, TRUE
, TRUE
) || (GetActiveWindow() == top
) )
2072 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOVE
+ HTCAPTION
, lParam
);
2077 if( style
& WS_SYSMENU
)
2079 if( !(style
& WS_MINIMIZE
) )
2081 HDC hDC
= GetWindowDC(hwnd
);
2082 if (TWEAK_WineLook
== WIN31_LOOK
)
2083 NC_DrawSysButton( hwnd
, hDC
, TRUE
);
2085 NC_DrawSysButton95( hwnd
, hDC
, TRUE
);
2086 ReleaseDC( hwnd
, hDC
);
2088 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
+ HTSYSMENU
, lParam
);
2093 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
, lParam
);
2097 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
2101 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
2106 if (TWEAK_WineLook
== WIN31_LOOK
)
2107 NC_TrackMinMaxBox( hwnd
, wParam
);
2109 NC_TrackMinMaxBox95( hwnd
, wParam
);
2113 if (TWEAK_WineLook
>= WIN95_LOOK
)
2114 NC_TrackCloseButton95 (hwnd
, wParam
);
2125 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2126 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_SIZE
+ wParam
- 2, lParam
);
2136 /***********************************************************************
2137 * NC_HandleNCLButtonDblClk
2139 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2141 LONG
NC_HandleNCLButtonDblClk( HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
2144 * if this is an icon, send a restore since we are handling
2149 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_RESTORE
, lParam
);
2153 switch(wParam
) /* Hit test */
2156 /* stop processing if WS_MAXIMIZEBOX is missing */
2157 if (GetWindowLongA( hwnd
, GWL_STYLE
) & WS_MAXIMIZEBOX
)
2158 SendMessageW( hwnd
, WM_SYSCOMMAND
,
2159 IsZoomed(hwnd
) ? SC_RESTORE
: SC_MAXIMIZE
, lParam
);
2163 if (!(GetClassLongW(hwnd
, GCL_STYLE
) & CS_NOCLOSE
))
2164 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, lParam
);
2168 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
2172 SendMessageW( hwnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
2179 /***********************************************************************
2180 * NC_HandleSysCommand
2182 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2184 LONG
NC_HandleSysCommand( HWND hwnd
, WPARAM wParam
, POINT pt
)
2186 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
2187 UINT16 uCommand
= wParam
& 0xFFF0;
2189 TRACE("Handling WM_SYSCOMMAND %x %ld,%ld\n", wParam
, pt
.x
, pt
.y
);
2191 if (uCommand
!= SC_KEYMENU
)
2193 HWND parent
= GetAncestor( hwnd
, GA_PARENT
);
2194 if (parent
!= GetDesktopWindow()) ScreenToClient( parent
, &pt
);
2201 if (USER_Driver
.pSysCommandSizeMove
)
2202 USER_Driver
.pSysCommandSizeMove( hwnd
, wParam
);
2206 if (hwnd
== GetForegroundWindow())
2207 ShowOwnedPopups(hwnd
,FALSE
);
2208 ShowWindow( hwnd
, SW_MINIMIZE
);
2212 if (IsIconic(hwnd
) && hwnd
== GetForegroundWindow())
2213 ShowOwnedPopups(hwnd
,TRUE
);
2214 ShowWindow( hwnd
, SW_MAXIMIZE
);
2218 if (IsIconic(hwnd
) && hwnd
== GetForegroundWindow())
2219 ShowOwnedPopups(hwnd
,TRUE
);
2220 ShowWindow( hwnd
, SW_RESTORE
);
2224 WIN_ReleaseWndPtr(wndPtr
);
2225 return SendMessageA( hwnd
, WM_CLOSE
, 0, 0 );
2229 NC_TrackScrollBar( hwnd
, wParam
, pt
);
2233 MENU_TrackMouseMenuBar( hwnd
, wParam
& 0x000F, pt
);
2237 MENU_TrackKbdMenuBar( hwnd
, wParam
, pt
.x
);
2241 WinExec( "taskman.exe", SW_SHOWNORMAL
);
2245 if (wParam
== SC_ABOUTWINE
)
2247 HMODULE hmodule
= LoadLibraryA( "shell32.dll" );
2250 FARPROC aboutproc
= GetProcAddress( hmodule
, "ShellAboutA" );
2251 if (aboutproc
) aboutproc( hwnd
, "Wine", WINE_RELEASE_INFO
, 0 );
2252 FreeLibrary( hmodule
);
2256 if (wParam
== SC_PUTMARK
)
2257 TRACE_(shell
)("Mark requested by user\n");
2264 FIXME("unimplemented!\n");
2267 WIN_ReleaseWndPtr(wndPtr
);
2271 /*************************************************************
2274 * Stub for the grayed button of the caption
2276 *************************************************************/
2278 BOOL
NC_DrawGrayButton(HDC hdc
, int x
, int y
)
2281 HDC hdcMask
= CreateCompatibleDC (0);
2284 hMaskBmp
= CreateBitmap (12, 10, 1, 1, lpGrayMask
);
2289 SelectObject (hdcMask
, hMaskBmp
);
2291 /* Draw the grayed bitmap using the mask */
2292 hOldBrush
= SelectObject (hdc
, RGB(128, 128, 128));
2293 BitBlt (hdc
, x
, y
, 12, 10,
2294 hdcMask
, 0, 0, 0xB8074A);
2297 SelectObject (hdc
, hOldBrush
);
2298 DeleteObject(hMaskBmp
);