2 * Non-client area window functions
4 * Copyright 1994 Alexandre Julliard
11 #include "sysmetrics.h"
14 #include "cursoricon.h"
20 #include "nonclient.h"
22 #include "selectors.h"
29 static HBITMAP16 hbitmapClose
= 0;
30 static HBITMAP16 hbitmapCloseD
= 0;
31 static HBITMAP16 hbitmapMinimize
= 0;
32 static HBITMAP16 hbitmapMinimizeD
= 0;
33 static HBITMAP16 hbitmapMaximize
= 0;
34 static HBITMAP16 hbitmapMaximizeD
= 0;
35 static HBITMAP16 hbitmapRestore
= 0;
36 static HBITMAP16 hbitmapRestoreD
= 0;
38 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
39 #define SC_PUTMARK (SC_SCREENSAVE+2)
41 /* Some useful macros */
42 #define HAS_DLGFRAME(style,exStyle) \
43 (((exStyle) & WS_EX_DLGMODALFRAME) || \
44 (((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
46 #define HAS_THICKFRAME(style) \
47 (((style) & WS_THICKFRAME) && \
48 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
50 #define HAS_FIXEDFRAME(style,exStyle) \
51 (((((exStyle) & WS_EX_DLGMODALFRAME) || \
52 ((style) & WS_DLGFRAME)) && ((style) & WS_BORDER)) && \
53 !((style) & WS_THICKFRAME))
55 #define HAS_SIZEFRAME(style) \
56 (((style) & WS_THICKFRAME) && \
57 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
59 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
61 #define ON_LEFT_BORDER(hit) \
62 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
63 #define ON_RIGHT_BORDER(hit) \
64 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
65 #define ON_TOP_BORDER(hit) \
66 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
67 #define ON_BOTTOM_BORDER(hit) \
68 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
70 /***********************************************************************
73 * Compute the size of the window rectangle from the size of the
76 static void NC_AdjustRect( LPRECT16 rect
, DWORD style
, BOOL menu
,
79 if (TWEAK_WineLook
> WIN31_LOOK
)
80 ERR(nonclient
, "Called in Win95 mode. Aiee! Please report this.\n" );
82 if(style
& WS_ICONIC
) return;
83 /* Decide if the window will be managed (see CreateWindowEx) */
84 if (!(Options
.managed
&& !(style
& WS_CHILD
) &&
85 ((style
& (WS_DLGFRAME
| WS_THICKFRAME
)) ||
86 (exStyle
& WS_EX_DLGMODALFRAME
))))
88 if (HAS_DLGFRAME( style
, exStyle
))
89 InflateRect16(rect
, SYSMETRICS_CXDLGFRAME
, SYSMETRICS_CYDLGFRAME
);
92 if (HAS_THICKFRAME(style
))
93 InflateRect16( rect
, SYSMETRICS_CXFRAME
, SYSMETRICS_CYFRAME
);
94 if (style
& WS_BORDER
)
95 InflateRect16( rect
, SYSMETRICS_CXBORDER
, SYSMETRICS_CYBORDER
);
98 if ((style
& WS_CAPTION
) == WS_CAPTION
)
99 rect
->top
-= SYSMETRICS_CYCAPTION
- SYSMETRICS_CYBORDER
;
101 if (menu
) rect
->top
-= SYSMETRICS_CYMENU
+ SYSMETRICS_CYBORDER
;
103 if (style
& WS_VSCROLL
) {
104 rect
->right
+= SYSMETRICS_CXVSCROLL
- 1;
105 if(!(style
& WS_BORDER
))
109 if (style
& WS_HSCROLL
) {
110 rect
->bottom
+= SYSMETRICS_CYHSCROLL
- 1;
111 if(!(style
& WS_BORDER
))
117 /******************************************************************************
118 * NC_AdjustRectOuter95
120 * Computes the size of the "outside" parts of the window based on the
121 * parameters of the client area.
130 * "Outer" parts of a window means the whole window frame, caption and
131 * menu bar. It does not include "inner" parts of the frame like client
132 * edge, static edge or scroll bars.
135 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
136 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
138 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
139 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
140 * NC_AdjustRectInner95 and added handling of Win95 styles.
142 *****************************************************************************/
145 NC_AdjustRectOuter95 (LPRECT16 rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
147 if(style
& WS_ICONIC
) return;
149 /* Decide if the window will be managed (see CreateWindowEx) */
150 if (!(Options
.managed
&& !(style
& WS_CHILD
) &&
151 ((style
& (WS_DLGFRAME
| WS_THICKFRAME
)) ||
152 (exStyle
& WS_EX_DLGMODALFRAME
))))
154 if (HAS_FIXEDFRAME( style
, exStyle
))
155 InflateRect16(rect
, SYSMETRICS_CXDLGFRAME
, SYSMETRICS_CYDLGFRAME
);
158 if (HAS_SIZEFRAME(style
))
159 InflateRect16( rect
, SYSMETRICS_CXFRAME
, SYSMETRICS_CYFRAME
);
161 if (style
& WS_BORDER
)
162 InflateRect16( rect
, SYSMETRICS_CXBORDER
, SYSMETRICS_CYBORDER
);
166 if ((style
& WS_CAPTION
) == WS_CAPTION
)
168 if (exStyle
& WS_EX_TOOLWINDOW
)
169 rect
->top
-= SYSMETRICS_CYSMCAPTION
;
171 rect
->top
-= SYSMETRICS_CYCAPTION
;
176 rect
->top
-= sysMetrics
[SM_CYMENU
];
180 /******************************************************************************
181 * NC_AdjustRectInner95
183 * Computes the size of the "inside" part of the window based on the
184 * parameters of the client area.
192 * "Inner" part of a window means the window frame inside of the flat
193 * window frame. It includes the client edge, the static edge and the
197 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
198 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
200 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
201 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
202 * NC_AdjustRectInner95 and added handling of Win95 styles.
204 *****************************************************************************/
207 NC_AdjustRectInner95 (LPRECT16 rect
, DWORD style
, DWORD exStyle
)
209 if(style
& WS_ICONIC
) return;
211 if (exStyle
& WS_EX_CLIENTEDGE
)
212 InflateRect16 (rect
, sysMetrics
[SM_CXEDGE
], sysMetrics
[SM_CYEDGE
]);
214 if (exStyle
& WS_EX_STATICEDGE
)
215 InflateRect16 (rect
, sysMetrics
[SM_CXBORDER
], sysMetrics
[SM_CYBORDER
]);
217 if (style
& WS_VSCROLL
) rect
->right
+= SYSMETRICS_CXVSCROLL
;
218 if (style
& WS_HSCROLL
) rect
->bottom
+= SYSMETRICS_CYHSCROLL
;
222 /***********************************************************************
223 * DrawCaption16 [USER.660] Draws a caption bar
237 DrawCaption16 (HWND16 hwnd
, HDC16 hdc
, const RECT16
*rect
, UINT16 uFlags
)
242 CONV_RECT16TO32 (rect
, &rect32
);
244 return (BOOL16
)DrawCaptionTempA (hwnd
, hdc
, rect
? &rect32
: NULL
,
245 0, 0, NULL
, uFlags
& 0x1F);
249 /***********************************************************************
250 * DrawCaption32 [USER32.154] Draws a caption bar
264 DrawCaption (HWND hwnd
, HDC hdc
, const RECT
*lpRect
, UINT uFlags
)
266 return DrawCaptionTempA (hwnd
, hdc
, lpRect
, 0, 0, NULL
, uFlags
& 0x1F);
270 /***********************************************************************
271 * DrawCaptionTemp16 [USER.657]
281 DrawCaptionTemp16 (HWND16 hwnd
, HDC16 hdc
, const RECT16
*rect
, HFONT16 hFont
,
282 HICON16 hIcon
, LPCSTR str
, UINT16 uFlags
)
287 CONV_RECT16TO32(rect
,&rect32
);
289 return (BOOL16
)DrawCaptionTempA (hwnd
, hdc
, rect
?&rect32
:NULL
, hFont
,
290 hIcon
, str
, uFlags
& 0x1F);
294 /***********************************************************************
295 * DrawCaptionTemp32A [USER32.599]
305 DrawCaptionTempA (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
306 HICON hIcon
, LPCSTR str
, UINT uFlags
)
310 TRACE (nonclient
, "(%08x,%08x,%p,%08x,%08x,\"%s\",%08x)\n",
311 hwnd
, hdc
, rect
, hFont
, hIcon
, str
, uFlags
);
313 /* drawing background */
314 if (uFlags
& DC_INBUTTON
) {
315 FillRect (hdc
, &rc
, GetSysColorBrush (COLOR_3DFACE
));
317 if (uFlags
& DC_ACTIVE
) {
318 HBRUSH hbr
= SelectObject (hdc
, CACHE_GetPattern55AABrush ());
319 PatBlt (hdc
, rc
.left
, rc
.top
,
320 rc
.right
-rc
.left
, rc
.bottom
-rc
.top
, 0xFA0089);
321 SelectObject (hdc
, hbr
);
325 FillRect (hdc
, &rc
, GetSysColorBrush ((uFlags
& DC_ACTIVE
) ?
326 COLOR_ACTIVECAPTION
: COLOR_INACTIVECAPTION
));
331 if ((uFlags
& DC_ICON
) && !(uFlags
& DC_SMALLCAP
)) {
335 pt
.y
= (rc
.bottom
+ rc
.top
- sysMetrics
[SM_CYSMICON
]) / 2;
338 DrawIconEx (hdc
, pt
.x
, pt
.y
, hIcon
, sysMetrics
[SM_CXSMICON
],
339 sysMetrics
[SM_CYSMICON
], 0, 0, DI_NORMAL
);
342 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
345 if (wndPtr
->class->hIconSm
)
346 hAppIcon
= wndPtr
->class->hIconSm
;
347 else if (wndPtr
->class->hIcon
)
348 hAppIcon
= wndPtr
->class->hIcon
;
350 DrawIconEx (hdc
, pt
.x
, pt
.y
, hAppIcon
, sysMetrics
[SM_CXSMICON
],
351 sysMetrics
[SM_CYSMICON
], 0, 0, DI_NORMAL
);
354 rc
.left
+= (rc
.bottom
- rc
.top
);
358 if (uFlags
& DC_TEXT
) {
361 if (uFlags
& DC_INBUTTON
)
362 SetTextColor (hdc
, GetSysColor (COLOR_BTNTEXT
));
363 else if (uFlags
& DC_ACTIVE
)
364 SetTextColor (hdc
, GetSysColor (COLOR_CAPTIONTEXT
));
366 SetTextColor (hdc
, GetSysColor (COLOR_INACTIVECAPTIONTEXT
));
368 SetBkMode (hdc
, TRANSPARENT
);
371 hOldFont
= SelectObject (hdc
, hFont
);
373 NONCLIENTMETRICSA nclm
;
375 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
376 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
377 hNewFont
= CreateFontIndirectA ((uFlags
& DC_SMALLCAP
) ?
378 &nclm
.lfSmCaptionFont
: &nclm
.lfCaptionFont
);
379 hOldFont
= SelectObject (hdc
, hNewFont
);
383 DrawTextA (hdc
, str
, -1, &rc
,
384 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
388 nLen
= GetWindowTextA (hwnd
, szText
, 128);
389 DrawTextA (hdc
, szText
, nLen
, &rc
,
390 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
394 SelectObject (hdc
, hOldFont
);
396 DeleteObject (SelectObject (hdc
, hOldFont
));
399 /* drawing focus ??? */
401 FIXME (nonclient
, "undocumented flag (0x2000)!\n");
407 /***********************************************************************
408 * DrawCaptionTemp32W [USER32.602]
418 DrawCaptionTempW (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
419 HICON hIcon
, LPCWSTR str
, UINT uFlags
)
421 LPSTR p
= HEAP_strdupWtoA (GetProcessHeap (), 0, str
);
422 BOOL res
= DrawCaptionTempA (hwnd
, hdc
, rect
, hFont
, hIcon
, p
, uFlags
);
423 HeapFree (GetProcessHeap (), 0, p
);
428 /***********************************************************************
429 * AdjustWindowRect16 (USER.102)
431 BOOL16 WINAPI
AdjustWindowRect16( LPRECT16 rect
, DWORD style
, BOOL16 menu
)
433 return AdjustWindowRectEx16( rect
, style
, menu
, 0 );
437 /***********************************************************************
438 * AdjustWindowRect32 (USER32.2)
440 BOOL WINAPI
AdjustWindowRect( LPRECT rect
, DWORD style
, BOOL menu
)
442 return AdjustWindowRectEx( rect
, style
, menu
, 0 );
446 /***********************************************************************
447 * AdjustWindowRectEx16 (USER.454)
449 BOOL16 WINAPI
AdjustWindowRectEx16( LPRECT16 rect
, DWORD style
,
450 BOOL16 menu
, DWORD exStyle
)
452 /* Correct the window style */
454 if (!(style
& (WS_POPUP
| WS_CHILD
))) /* Overlapped window */
456 style
&= (WS_DLGFRAME
| WS_BORDER
| WS_THICKFRAME
| WS_CHILD
);
457 exStyle
&= (WS_EX_DLGMODALFRAME
| WS_EX_CLIENTEDGE
|
458 WS_EX_STATICEDGE
| WS_EX_TOOLWINDOW
);
459 if (exStyle
& WS_EX_DLGMODALFRAME
) style
&= ~WS_THICKFRAME
;
461 TRACE(nonclient
, "(%d,%d)-(%d,%d) %08lx %d %08lx\n",
462 rect
->left
, rect
->top
, rect
->right
, rect
->bottom
,
463 style
, menu
, exStyle
);
465 if (TWEAK_WineLook
== WIN31_LOOK
)
466 NC_AdjustRect( rect
, style
, menu
, exStyle
);
468 NC_AdjustRectOuter95( rect
, style
, menu
, exStyle
);
469 NC_AdjustRectInner95( rect
, style
, exStyle
);
476 /***********************************************************************
477 * AdjustWindowRectEx32 (USER32.3)
479 BOOL WINAPI
AdjustWindowRectEx( LPRECT rect
, DWORD style
,
480 BOOL menu
, DWORD exStyle
)
485 CONV_RECT32TO16( rect
, &rect16
);
486 ret
= AdjustWindowRectEx16( &rect16
, style
, (BOOL16
)menu
, exStyle
);
487 CONV_RECT16TO32( &rect16
, rect
);
492 /***********************************************************************
493 * NC_HandleNCCalcSize
495 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
497 LONG
NC_HandleNCCalcSize( WND
*pWnd
, RECT
*winRect
)
499 RECT16 tmpRect
= { 0, 0, 0, 0 };
502 if (pWnd
->class->style
& CS_VREDRAW
) result
|= WVR_VREDRAW
;
503 if (pWnd
->class->style
& CS_HREDRAW
) result
|= WVR_HREDRAW
;
505 if( !( pWnd
->dwStyle
& WS_MINIMIZE
) ) {
506 if (TWEAK_WineLook
== WIN31_LOOK
)
507 NC_AdjustRect( &tmpRect
, pWnd
->dwStyle
, FALSE
, pWnd
->dwExStyle
);
509 NC_AdjustRectOuter95( &tmpRect
, pWnd
->dwStyle
, FALSE
, pWnd
->dwExStyle
);
511 winRect
->left
-= tmpRect
.left
;
512 winRect
->top
-= tmpRect
.top
;
513 winRect
->right
-= tmpRect
.right
;
514 winRect
->bottom
-= tmpRect
.bottom
;
516 if (HAS_MENU(pWnd
)) {
517 TRACE(nonclient
, "Calling "
518 "GetMenuBarHeight with HWND 0x%x, width %d, "
519 "at (%d, %d).\n", pWnd
->hwndSelf
,
520 winRect
->right
- winRect
->left
,
521 -tmpRect
.left
, -tmpRect
.top
);
524 MENU_GetMenuBarHeight( pWnd
->hwndSelf
,
525 winRect
->right
- winRect
->left
,
526 -tmpRect
.left
, -tmpRect
.top
) + 1;
529 if (TWEAK_WineLook
> WIN31_LOOK
) {
530 SetRect16 (&tmpRect
, 0, 0, 0, 0);
531 NC_AdjustRectInner95 (&tmpRect
, pWnd
->dwStyle
, pWnd
->dwExStyle
);
532 winRect
->left
-= tmpRect
.left
;
533 winRect
->top
-= tmpRect
.top
;
534 winRect
->right
-= tmpRect
.right
;
535 winRect
->bottom
-= tmpRect
.bottom
;
542 /***********************************************************************
545 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
546 * but without the borders (if any).
547 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
549 static void NC_GetInsideRect( HWND hwnd
, RECT
*rect
)
551 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
553 rect
->top
= rect
->left
= 0;
554 rect
->right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
555 rect
->bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
557 if ((wndPtr
->dwStyle
& WS_ICONIC
) || (wndPtr
->flags
& WIN_MANAGED
)) return;
559 /* Remove frame from rectangle */
560 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
562 InflateRect( rect
, -SYSMETRICS_CXDLGFRAME
, -SYSMETRICS_CYDLGFRAME
);
563 if (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
)
564 InflateRect( rect
, -1, 0 );
568 if (HAS_THICKFRAME( wndPtr
->dwStyle
))
569 InflateRect( rect
, -SYSMETRICS_CXFRAME
, -SYSMETRICS_CYFRAME
);
570 if (wndPtr
->dwStyle
& WS_BORDER
)
571 InflateRect( rect
, -SYSMETRICS_CXBORDER
, -SYSMETRICS_CYBORDER
);
578 /***********************************************************************
581 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
582 * but without the borders (if any).
583 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
587 NC_GetInsideRect95 (HWND hwnd
, RECT
*rect
)
589 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
591 rect
->top
= rect
->left
= 0;
592 rect
->right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
593 rect
->bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
595 if ((wndPtr
->dwStyle
& WS_ICONIC
) || (wndPtr
->flags
& WIN_MANAGED
)) return;
597 /* Remove frame from rectangle */
598 if (HAS_FIXEDFRAME (wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
600 InflateRect( rect
, -SYSMETRICS_CXFIXEDFRAME
, -SYSMETRICS_CYFIXEDFRAME
);
602 else if (HAS_SIZEFRAME (wndPtr
->dwStyle
))
604 InflateRect( rect
, -SYSMETRICS_CXSIZEFRAME
, -SYSMETRICS_CYSIZEFRAME
);
606 /* if (wndPtr->dwStyle & WS_BORDER)
607 InflateRect32( rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER );*/
610 if (wndPtr
->dwStyle
& WS_CHILD
) {
611 if (wndPtr
->dwExStyle
& WS_EX_CLIENTEDGE
)
612 InflateRect (rect
, -SYSMETRICS_CXEDGE
, -SYSMETRICS_CYEDGE
);
614 if (wndPtr
->dwExStyle
& WS_EX_STATICEDGE
)
615 InflateRect (rect
, -SYSMETRICS_CXBORDER
, -SYSMETRICS_CYBORDER
);
622 /***********************************************************************
625 * Handle a WM_NCHITTEST message. Called from NC_HandleNcHitTest().
628 LONG
NC_DoNCHitTest (WND
*wndPtr
, POINT16 pt
)
632 TRACE(nonclient
, "hwnd=%04x pt=%d,%d\n",
633 wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
635 GetWindowRect16 (wndPtr
->hwndSelf
, &rect
);
636 if (!PtInRect16( &rect
, pt
)) return HTNOWHERE
;
638 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
640 if (!(wndPtr
->flags
& WIN_MANAGED
))
643 if (HAS_THICKFRAME( wndPtr
->dwStyle
))
645 InflateRect16( &rect
, -SYSMETRICS_CXFRAME
, -SYSMETRICS_CYFRAME
);
646 if (wndPtr
->dwStyle
& WS_BORDER
)
647 InflateRect16(&rect
,-SYSMETRICS_CXBORDER
,-SYSMETRICS_CYBORDER
);
648 if (!PtInRect16( &rect
, pt
))
650 /* Check top sizing border */
653 if (pt
.x
< rect
.left
+SYSMETRICS_CXSIZE
) return HTTOPLEFT
;
654 if (pt
.x
>= rect
.right
-SYSMETRICS_CXSIZE
) return HTTOPRIGHT
;
657 /* Check bottom sizing border */
658 if (pt
.y
>= rect
.bottom
)
660 if (pt
.x
< rect
.left
+SYSMETRICS_CXSIZE
) return HTBOTTOMLEFT
;
661 if (pt
.x
>= rect
.right
-SYSMETRICS_CXSIZE
) return HTBOTTOMRIGHT
;
664 /* Check left sizing border */
665 if (pt
.x
< rect
.left
)
667 if (pt
.y
< rect
.top
+SYSMETRICS_CYSIZE
) return HTTOPLEFT
;
668 if (pt
.y
>= rect
.bottom
-SYSMETRICS_CYSIZE
) return HTBOTTOMLEFT
;
671 /* Check right sizing border */
672 if (pt
.x
>= rect
.right
)
674 if (pt
.y
< rect
.top
+SYSMETRICS_CYSIZE
) return HTTOPRIGHT
;
675 if (pt
.y
>= rect
.bottom
-SYSMETRICS_CYSIZE
) return HTBOTTOMRIGHT
;
680 else /* No thick frame */
682 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
683 InflateRect16(&rect
, -SYSMETRICS_CXDLGFRAME
, -SYSMETRICS_CYDLGFRAME
);
684 else if (wndPtr
->dwStyle
& WS_BORDER
)
685 InflateRect16(&rect
, -SYSMETRICS_CXBORDER
, -SYSMETRICS_CYBORDER
);
686 if (!PtInRect16( &rect
, pt
)) return HTBORDER
;
691 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
693 rect
.top
+= sysMetrics
[SM_CYCAPTION
] - 1;
694 if (!PtInRect16( &rect
, pt
))
696 /* Check system menu */
697 if (wndPtr
->dwStyle
& WS_SYSMENU
)
698 rect
.left
+= SYSMETRICS_CXSIZE
;
699 if (pt
.x
<= rect
.left
) return HTSYSMENU
;
700 /* Check maximize box */
701 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
702 rect
.right
-= SYSMETRICS_CXSIZE
+ 1;
703 if (pt
.x
>= rect
.right
) return HTMAXBUTTON
;
704 /* Check minimize box */
705 if (wndPtr
->dwStyle
& WS_MINIMIZEBOX
)
706 rect
.right
-= SYSMETRICS_CXSIZE
+ 1;
707 if (pt
.x
>= rect
.right
) return HTMINBUTTON
;
713 /* Check client area */
715 ScreenToClient16( wndPtr
->hwndSelf
, &pt
);
716 GetClientRect16( wndPtr
->hwndSelf
, &rect
);
717 if (PtInRect16( &rect
, pt
)) return HTCLIENT
;
719 /* Check vertical scroll bar */
721 if (wndPtr
->dwStyle
& WS_VSCROLL
)
723 rect
.right
+= SYSMETRICS_CXVSCROLL
;
724 if (PtInRect16( &rect
, pt
)) return HTVSCROLL
;
727 /* Check horizontal scroll bar */
729 if (wndPtr
->dwStyle
& WS_HSCROLL
)
731 rect
.bottom
+= SYSMETRICS_CYHSCROLL
;
732 if (PtInRect16( &rect
, pt
))
735 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
736 (pt
.x
>= rect
.right
- SYSMETRICS_CXVSCROLL
))
744 if (HAS_MENU(wndPtr
))
746 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
750 /* Should never get here */
755 /***********************************************************************
758 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
760 * FIXME: Just a modified copy of the Win 3.1 version.
764 NC_DoNCHitTest95 (WND
*wndPtr
, POINT16 pt
)
768 TRACE(nonclient
, "hwnd=%04x pt=%d,%d\n",
769 wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
771 GetWindowRect16 (wndPtr
->hwndSelf
, &rect
);
772 if (!PtInRect16( &rect
, pt
)) return HTNOWHERE
;
774 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
776 if (!(wndPtr
->flags
& WIN_MANAGED
))
779 if (HAS_SIZEFRAME( wndPtr
->dwStyle
))
781 InflateRect16( &rect
, -SYSMETRICS_CXFRAME
, -SYSMETRICS_CYFRAME
);
782 /* if (wndPtr->dwStyle & WS_BORDER) */
783 /* InflateRect16(&rect,-SYSMETRICS_CXBORDER,-SYSMETRICS_CYBORDER); */
784 if (!PtInRect16( &rect
, pt
))
786 /* Check top sizing border */
789 if (pt
.x
< rect
.left
+SYSMETRICS_CXSIZE
) return HTTOPLEFT
;
790 if (pt
.x
>= rect
.right
-SYSMETRICS_CXSIZE
) return HTTOPRIGHT
;
793 /* Check bottom sizing border */
794 if (pt
.y
>= rect
.bottom
)
796 if (pt
.x
< rect
.left
+SYSMETRICS_CXSIZE
) return HTBOTTOMLEFT
;
797 if (pt
.x
>= rect
.right
-SYSMETRICS_CXSIZE
) return HTBOTTOMRIGHT
;
800 /* Check left sizing border */
801 if (pt
.x
< rect
.left
)
803 if (pt
.y
< rect
.top
+SYSMETRICS_CYSIZE
) return HTTOPLEFT
;
804 if (pt
.y
>= rect
.bottom
-SYSMETRICS_CYSIZE
) return HTBOTTOMLEFT
;
807 /* Check right sizing border */
808 if (pt
.x
>= rect
.right
)
810 if (pt
.y
< rect
.top
+SYSMETRICS_CYSIZE
) return HTTOPRIGHT
;
811 if (pt
.y
>= rect
.bottom
-SYSMETRICS_CYSIZE
) return HTBOTTOMRIGHT
;
816 else /* No thick frame */
818 if (HAS_FIXEDFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
819 InflateRect16(&rect
, -SYSMETRICS_CXDLGFRAME
, -SYSMETRICS_CYDLGFRAME
);
820 /* else if (wndPtr->dwStyle & WS_BORDER) */
821 /* InflateRect16(&rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER); */
822 if (!PtInRect16( &rect
, pt
)) return HTBORDER
;
827 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
829 if (wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
)
830 rect
.top
+= sysMetrics
[SM_CYSMCAPTION
] - 1;
832 rect
.top
+= sysMetrics
[SM_CYCAPTION
] - 1;
833 if (!PtInRect16( &rect
, pt
))
835 /* Check system menu */
836 if ((wndPtr
->dwStyle
& WS_SYSMENU
) &&
837 ((wndPtr
->class->hIconSm
) || (wndPtr
->class->hIcon
)))
838 rect
.left
+= sysMetrics
[SM_CYCAPTION
] - 1;
839 if (pt
.x
< rect
.left
) return HTSYSMENU
;
841 /* Check close button */
842 if (wndPtr
->dwStyle
& WS_SYSMENU
)
843 rect
.right
-= sysMetrics
[SM_CYCAPTION
] - 1;
844 if (pt
.x
> rect
.right
) return HTCLOSE
;
846 /* Check maximize box */
847 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
848 rect
.right
-= SYSMETRICS_CXSIZE
+ 1;
849 if (pt
.x
> rect
.right
) return HTMAXBUTTON
;
851 /* Check minimize box */
852 if (wndPtr
->dwStyle
& WS_MINIMIZEBOX
)
853 rect
.right
-= SYSMETRICS_CXSIZE
+ 1;
854 if (pt
.x
> rect
.right
) return HTMINBUTTON
;
860 /* Check client area */
862 ScreenToClient16( wndPtr
->hwndSelf
, &pt
);
863 GetClientRect16( wndPtr
->hwndSelf
, &rect
);
864 if (PtInRect16( &rect
, pt
)) return HTCLIENT
;
866 /* Check vertical scroll bar */
868 if (wndPtr
->dwStyle
& WS_VSCROLL
)
870 rect
.right
+= SYSMETRICS_CXVSCROLL
;
871 if (PtInRect16( &rect
, pt
)) return HTVSCROLL
;
874 /* Check horizontal scroll bar */
876 if (wndPtr
->dwStyle
& WS_HSCROLL
)
878 rect
.bottom
+= SYSMETRICS_CYHSCROLL
;
879 if (PtInRect16( &rect
, pt
))
882 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
883 (pt
.x
>= rect
.right
- SYSMETRICS_CXVSCROLL
))
891 if (HAS_MENU(wndPtr
))
893 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
897 /* Should never get here */
902 /***********************************************************************
905 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
908 NC_HandleNCHitTest (HWND hwnd
, POINT16 pt
)
910 WND
*wndPtr
= WIN_FindWndPtr (hwnd
);
915 if (TWEAK_WineLook
== WIN31_LOOK
)
916 return NC_DoNCHitTest (wndPtr
, pt
);
918 return NC_DoNCHitTest95 (wndPtr
, pt
);
922 /***********************************************************************
925 void NC_DrawSysButton( HWND hwnd
, HDC hdc
, BOOL down
)
930 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
932 if( !(wndPtr
->flags
& WIN_MANAGED
) )
934 NC_GetInsideRect( hwnd
, &rect
);
935 hdcMem
= CreateCompatibleDC( hdc
);
936 hbitmap
= SelectObject( hdcMem
, hbitmapClose
);
937 BitBlt(hdc
, rect
.left
, rect
.top
, SYSMETRICS_CXSIZE
, SYSMETRICS_CYSIZE
,
938 hdcMem
, (wndPtr
->dwStyle
& WS_CHILD
) ? SYSMETRICS_CXSIZE
: 0, 0,
939 down
? NOTSRCCOPY
: SRCCOPY
);
940 SelectObject( hdcMem
, hbitmap
);
946 /***********************************************************************
949 static void NC_DrawMaxButton( HWND hwnd
, HDC16 hdc
, BOOL down
)
952 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
955 if( !(wndPtr
->flags
& WIN_MANAGED
) )
957 NC_GetInsideRect( hwnd
, &rect
);
958 hdcMem
= CreateCompatibleDC( hdc
);
959 SelectObject( hdcMem
, (IsZoomed(hwnd
)
960 ? (down
? hbitmapRestoreD
: hbitmapRestore
)
961 : (down
? hbitmapMaximizeD
: hbitmapMaximize
)) );
962 BitBlt( hdc
, rect
.right
- SYSMETRICS_CXSIZE
- 1, rect
.top
,
963 SYSMETRICS_CXSIZE
+ 1, SYSMETRICS_CYSIZE
, hdcMem
, 0, 0,
970 /***********************************************************************
973 static void NC_DrawMinButton( HWND hwnd
, HDC16 hdc
, BOOL down
)
976 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
979 if( !(wndPtr
->flags
& WIN_MANAGED
) )
981 NC_GetInsideRect( hwnd
, &rect
);
982 hdcMem
= CreateCompatibleDC( hdc
);
983 SelectObject( hdcMem
, (down
? hbitmapMinimizeD
: hbitmapMinimize
) );
984 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
) rect
.right
-= SYSMETRICS_CXSIZE
+1;
985 BitBlt( hdc
, rect
.right
- SYSMETRICS_CXSIZE
- 1, rect
.top
,
986 SYSMETRICS_CXSIZE
+ 1, SYSMETRICS_CYSIZE
, hdcMem
, 0, 0,
993 /******************************************************************************
995 * void NC_DrawSysButton95(
1000 * Draws the Win95 system icon.
1003 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1004 * Original implementation from NC_DrawSysButton source.
1005 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1008 *****************************************************************************/
1011 NC_DrawSysButton95 (HWND hwnd
, HDC hdc
, BOOL down
)
1013 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1015 if( !(wndPtr
->flags
& WIN_MANAGED
) )
1020 NC_GetInsideRect95( hwnd
, &rect
);
1022 if (wndPtr
->class->hIconSm
)
1023 hIcon
= wndPtr
->class->hIconSm
;
1024 else if (wndPtr
->class->hIcon
)
1025 hIcon
= wndPtr
->class->hIcon
;
1028 DrawIconEx (hdc
, rect
.left
+ 2, rect
.top
+ 2, hIcon
,
1029 sysMetrics
[SM_CXSMICON
],
1030 sysMetrics
[SM_CYSMICON
],
1033 return (hIcon
!= 0);
1039 /******************************************************************************
1041 * void NC_DrawCloseButton95(
1046 * Draws the Win95 close button.
1049 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1050 * Original implementation from NC_DrawSysButton95 source.
1052 *****************************************************************************/
1054 void NC_DrawCloseButton95 (HWND hwnd
, HDC hdc
, BOOL down
)
1058 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1060 if( !(wndPtr
->flags
& WIN_MANAGED
) )
1063 HBITMAP hBmp
, hOldBmp
;
1065 NC_GetInsideRect95( hwnd
, &rect
);
1067 hdcMem
= CreateCompatibleDC( hdc
);
1068 hBmp
= down
? hbitmapCloseD
: hbitmapClose
;
1069 hOldBmp
= SelectObject (hdcMem
, hBmp
);
1070 GetObjectA (hBmp
, sizeof(BITMAP
), &bmp
);
1071 BitBlt (hdc
, rect
.right
- (sysMetrics
[SM_CYCAPTION
] + 1 + bmp
.bmWidth
) / 2,
1072 rect
.top
+ (sysMetrics
[SM_CYCAPTION
] - 1 - bmp
.bmHeight
) / 2,
1073 bmp
.bmWidth
, bmp
.bmHeight
, hdcMem
, 0, 0, down
? NOTSRCCOPY
: SRCCOPY
);
1075 SelectObject (hdcMem
, hOldBmp
);
1080 /******************************************************************************
1082 * NC_DrawMaxButton95(
1087 * Draws the maximize button for Win95 style windows.
1090 * Many. Spacing might still be incorrect. Need to fit a close
1091 * button between the max button and the edge.
1092 * Should scale the image with the title bar. And more...
1095 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1096 * Original implementation.
1098 *****************************************************************************/
1100 static void NC_DrawMaxButton95(HWND hwnd
,HDC16 hdc
,BOOL down
)
1104 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1106 if( !(wndPtr
->flags
& WIN_MANAGED
))
1109 HBITMAP hBmp
,hOldBmp
;
1111 NC_GetInsideRect95( hwnd
, &rect
);
1112 hdcMem
= CreateCompatibleDC( hdc
);
1113 hBmp
= IsZoomed(hwnd
) ?
1114 (down
? hbitmapRestoreD
: hbitmapRestore
) :
1115 (down
? hbitmapMaximizeD
: hbitmapMaximize
);
1116 hOldBmp
=SelectObject( hdcMem
, hBmp
);
1117 GetObjectA (hBmp
, sizeof(BITMAP
), &bmp
);
1119 if (wndPtr
->dwStyle
& WS_SYSMENU
)
1120 rect
.right
-= sysMetrics
[SM_CYCAPTION
] + 1;
1122 BitBlt( hdc
, rect
.right
- (sysMetrics
[SM_CXSIZE
] + bmp
.bmWidth
) / 2,
1123 rect
.top
+ (sysMetrics
[SM_CYCAPTION
] - 1 - bmp
.bmHeight
) / 2,
1124 bmp
.bmWidth
, bmp
.bmHeight
, hdcMem
, 0, 0, SRCCOPY
);
1125 SelectObject (hdcMem
, hOldBmp
);
1130 /******************************************************************************
1132 * NC_DrawMinButton95(
1137 * Draws the minimize button for Win95 style windows.
1140 * Many. Spacing is still incorrect. Should scale the image with the
1141 * title bar. And more...
1144 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1145 * Original implementation.
1147 *****************************************************************************/
1149 static void NC_DrawMinButton95(HWND hwnd
,HDC16 hdc
,BOOL down
)
1153 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1155 if( !(wndPtr
->flags
& WIN_MANAGED
))
1159 HBITMAP hBmp
,hOldBmp
;
1161 NC_GetInsideRect95( hwnd
, &rect
);
1163 hdcMem
= CreateCompatibleDC( hdc
);
1164 hBmp
= down
? hbitmapMinimizeD
: hbitmapMinimize
;
1165 hOldBmp
= SelectObject( hdcMem
, hBmp
);
1166 GetObjectA (hBmp
, sizeof(BITMAP
), &bmp
);
1168 if (wndPtr
->dwStyle
& WS_SYSMENU
)
1169 rect
.right
-= sysMetrics
[SM_CYCAPTION
] + 1;
1171 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
1172 rect
.right
+= -1 - (sysMetrics
[SM_CXSIZE
] + bmp
.bmWidth
) / 2;
1174 BitBlt( hdc
, rect
.right
- (sysMetrics
[SM_CXSIZE
] + bmp
.bmWidth
) / 2,
1175 rect
.top
+ (sysMetrics
[SM_CYCAPTION
] - 1 - bmp
.bmHeight
) / 2,
1176 bmp
.bmWidth
, bmp
.bmHeight
, hdcMem
, 0, 0, SRCCOPY
);
1178 SelectObject (hdcMem
, hOldBmp
);
1183 /***********************************************************************
1186 * Draw a window frame inside the given rectangle, and update the rectangle.
1187 * The correct pen for the frame must be selected in the DC.
1189 static void NC_DrawFrame( HDC hdc
, RECT
*rect
, BOOL dlgFrame
,
1194 if (TWEAK_WineLook
!= WIN31_LOOK
)
1195 ERR (nonclient
, "Called in Win95 mode. Aiee! Please report this.\n" );
1199 width
= SYSMETRICS_CXDLGFRAME
- 1;
1200 height
= SYSMETRICS_CYDLGFRAME
- 1;
1201 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1202 COLOR_INACTIVECAPTION
) );
1206 width
= SYSMETRICS_CXFRAME
- 1;
1207 height
= SYSMETRICS_CYFRAME
- 1;
1208 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1209 COLOR_INACTIVEBORDER
) );
1213 PatBlt( hdc
, rect
->left
, rect
->top
,
1214 rect
->right
- rect
->left
, height
, PATCOPY
);
1215 PatBlt( hdc
, rect
->left
, rect
->top
,
1216 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1217 PatBlt( hdc
, rect
->left
, rect
->bottom
,
1218 rect
->right
- rect
->left
, -height
, PATCOPY
);
1219 PatBlt( hdc
, rect
->right
, rect
->top
,
1220 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1224 InflateRect( rect
, -width
, -height
);
1228 INT decYOff
= SYSMETRICS_CXFRAME
+ SYSMETRICS_CXSIZE
;
1229 INT decXOff
= SYSMETRICS_CYFRAME
+ SYSMETRICS_CYSIZE
;
1231 /* Draw inner rectangle */
1233 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1234 Rectangle( hdc
, rect
->left
+ width
, rect
->top
+ height
,
1235 rect
->right
- width
, rect
->bottom
- height
);
1237 /* Draw the decorations */
1239 MoveToEx( hdc
, rect
->left
, rect
->top
+ decYOff
, NULL
);
1240 LineTo( hdc
, rect
->left
+ width
, rect
->top
+ decYOff
);
1241 MoveToEx( hdc
, rect
->right
- 1, rect
->top
+ decYOff
, NULL
);
1242 LineTo( hdc
, rect
->right
- width
- 1, rect
->top
+ decYOff
);
1243 MoveToEx( hdc
, rect
->left
, rect
->bottom
- decYOff
, NULL
);
1244 LineTo( hdc
, rect
->left
+ width
, rect
->bottom
- decYOff
);
1245 MoveToEx( hdc
, rect
->right
- 1, rect
->bottom
- decYOff
, NULL
);
1246 LineTo( hdc
, rect
->right
- width
- 1, rect
->bottom
- decYOff
);
1248 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->top
, NULL
);
1249 LineTo( hdc
, rect
->left
+ decXOff
, rect
->top
+ height
);
1250 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->bottom
- 1, NULL
);
1251 LineTo( hdc
, rect
->left
+ decXOff
, rect
->bottom
- height
- 1 );
1252 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->top
, NULL
);
1253 LineTo( hdc
, rect
->right
- decXOff
, rect
->top
+ height
);
1254 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->bottom
- 1, NULL
);
1255 LineTo( hdc
, rect
->right
- decXOff
, rect
->bottom
- height
- 1 );
1257 InflateRect( rect
, -width
- 1, -height
- 1 );
1262 /******************************************************************************
1264 * void NC_DrawFrame95(
1270 * Draw a window frame inside the given rectangle, and update the rectangle.
1271 * The correct pen for the frame must be selected in the DC.
1274 * Many. First, just what IS a frame in Win95? Note that the 3D look
1275 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1276 * edge. The inner rectangle just inside the frame is handled by the
1279 * In short, for most people, this function should be a nop (unless
1280 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1281 * them lately, but just to get this code right). Even so, it doesn't
1282 * appear to be so. It's being worked on...
1285 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1286 * Original implementation (based on NC_DrawFrame)
1287 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1290 *****************************************************************************/
1292 static void NC_DrawFrame95(
1302 width
= sysMetrics
[SM_CXDLGFRAME
] - sysMetrics
[SM_CXEDGE
];
1303 height
= sysMetrics
[SM_CYDLGFRAME
] - sysMetrics
[SM_CYEDGE
];
1307 width
= sysMetrics
[SM_CXFRAME
] - sysMetrics
[SM_CXEDGE
];
1308 height
= sysMetrics
[SM_CYFRAME
] - sysMetrics
[SM_CYEDGE
];
1311 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1312 COLOR_INACTIVEBORDER
) );
1315 PatBlt( hdc
, rect
->left
, rect
->top
,
1316 rect
->right
- rect
->left
, height
, PATCOPY
);
1317 PatBlt( hdc
, rect
->left
, rect
->top
,
1318 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1319 PatBlt( hdc
, rect
->left
, rect
->bottom
,
1320 rect
->right
- rect
->left
, -height
, PATCOPY
);
1321 PatBlt( hdc
, rect
->right
, rect
->top
,
1322 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1324 InflateRect( rect
, -width
, -height
);
1327 /***********************************************************************
1328 * NC_DrawMovingFrame
1330 * Draw the frame used when moving or resizing window.
1332 * FIXME: This causes problems in Win95 mode. (why?)
1334 static void NC_DrawMovingFrame( HDC hdc
, RECT
*rect
, BOOL thickframe
)
1339 CONV_RECT32TO16( rect
, &r16
);
1340 FastWindowFrame16( hdc
, &r16
, SYSMETRICS_CXFRAME
,
1341 SYSMETRICS_CYFRAME
, PATINVERT
);
1343 else DrawFocusRect( hdc
, rect
);
1347 /***********************************************************************
1350 * Draw the window caption.
1351 * The correct pen for the window frame must be selected in the DC.
1353 static void NC_DrawCaption( HDC hdc
, RECT
*rect
, HWND hwnd
,
1354 DWORD style
, BOOL active
)
1357 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1360 if (wndPtr
->flags
& WIN_MANAGED
) return;
1364 if (!(hbitmapClose
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE
) )))
1366 hbitmapCloseD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED
) );
1367 hbitmapMinimize
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE
) );
1368 hbitmapMinimizeD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED
) );
1369 hbitmapMaximize
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM
) );
1370 hbitmapMaximizeD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD
) );
1371 hbitmapRestore
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE
) );
1372 hbitmapRestoreD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED
) );
1375 if (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
)
1377 HBRUSH hbrushOld
= SelectObject(hdc
, GetSysColorBrush(COLOR_WINDOW
) );
1378 PatBlt( hdc
, r
.left
, r
.top
, 1, r
.bottom
-r
.top
+1,PATCOPY
);
1379 PatBlt( hdc
, r
.right
-1, r
.top
, 1, r
.bottom
-r
.top
+1, PATCOPY
);
1380 PatBlt( hdc
, r
.left
, r
.top
-1, r
.right
-r
.left
, 1, PATCOPY
);
1383 SelectObject( hdc
, hbrushOld
);
1386 MoveTo16( hdc
, r
.left
, r
.bottom
);
1387 LineTo( hdc
, r
.right
, r
.bottom
);
1389 if (style
& WS_SYSMENU
)
1391 NC_DrawSysButton( hwnd
, hdc
, FALSE
);
1392 r
.left
+= SYSMETRICS_CXSIZE
+ 1;
1393 MoveTo16( hdc
, r
.left
- 1, r
.top
);
1394 LineTo( hdc
, r
.left
- 1, r
.bottom
);
1396 if (style
& WS_MAXIMIZEBOX
)
1398 NC_DrawMaxButton( hwnd
, hdc
, FALSE
);
1399 r
.right
-= SYSMETRICS_CXSIZE
+ 1;
1401 if (style
& WS_MINIMIZEBOX
)
1403 NC_DrawMinButton( hwnd
, hdc
, FALSE
);
1404 r
.right
-= SYSMETRICS_CXSIZE
+ 1;
1407 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1408 COLOR_INACTIVECAPTION
) );
1410 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) ))
1412 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1413 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1414 SetBkMode( hdc
, TRANSPARENT
);
1415 DrawTextA( hdc
, buffer
, -1, &r
,
1416 DT_SINGLELINE
| DT_CENTER
| DT_VCENTER
| DT_NOPREFIX
);
1421 /******************************************************************************
1430 * Draw the window caption for Win95 style windows.
1431 * The correct pen for the window frame must be selected in the DC.
1434 * Hey, a function that finally works! Well, almost.
1435 * It's being worked on.
1438 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1439 * Original implementation.
1440 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1443 *****************************************************************************/
1445 static void NC_DrawCaption95(
1454 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1458 if (wndPtr
->flags
& WIN_MANAGED
) return;
1460 hPrevPen
= SelectObject( hdc
, GetSysColorPen(COLOR_3DFACE
) );
1461 MoveToEx( hdc
, r
.left
, r
.bottom
- 1, NULL
);
1462 LineTo( hdc
, r
.right
, r
.bottom
- 1 );
1463 SelectObject( hdc
, hPrevPen
);
1466 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1467 COLOR_INACTIVECAPTION
) );
1469 if (!hbitmapClose
) {
1470 if (!(hbitmapClose
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE
) )))
1472 hbitmapCloseD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED
));
1473 hbitmapMinimize
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE
) );
1474 hbitmapMinimizeD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED
) );
1475 hbitmapMaximize
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM
) );
1476 hbitmapMaximizeD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD
) );
1477 hbitmapRestore
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE
) );
1478 hbitmapRestoreD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED
) );
1481 if ((style
& WS_SYSMENU
) && !(exStyle
& WS_EX_TOOLWINDOW
)) {
1482 if (NC_DrawSysButton95 (hwnd
, hdc
, FALSE
))
1483 r
.left
+= sysMetrics
[SM_CYCAPTION
] - 1;
1485 if (style
& WS_SYSMENU
) {
1486 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
);
1487 r
.right
-= sysMetrics
[SM_CYCAPTION
] - 1;
1489 if (style
& WS_MAXIMIZEBOX
) {
1490 NC_DrawMaxButton95( hwnd
, hdc
, FALSE
);
1491 r
.right
-= SYSMETRICS_CXSIZE
+ 1;
1493 if (style
& WS_MINIMIZEBOX
) {
1494 NC_DrawMinButton95( hwnd
, hdc
, FALSE
);
1495 r
.right
-= SYSMETRICS_CXSIZE
+ 1;
1498 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) )) {
1499 NONCLIENTMETRICSA nclm
;
1500 HFONT hFont
, hOldFont
;
1501 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
1502 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
1503 if (exStyle
& WS_EX_TOOLWINDOW
)
1504 hFont
= CreateFontIndirectA (&nclm
.lfSmCaptionFont
);
1506 hFont
= CreateFontIndirectA (&nclm
.lfCaptionFont
);
1507 hOldFont
= SelectObject (hdc
, hFont
);
1508 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1509 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1510 SetBkMode( hdc
, TRANSPARENT
);
1512 DrawTextA( hdc
, buffer
, -1, &r
,
1513 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
1514 DeleteObject (SelectObject (hdc
, hOldFont
));
1520 /***********************************************************************
1523 * Paint the non-client area. clip is currently unused.
1525 void NC_DoNCPaint( WND
* wndPtr
, HRGN clip
, BOOL suppress_menupaint
)
1530 HWND hwnd
= wndPtr
->hwndSelf
;
1532 if ( wndPtr
->dwStyle
& WS_MINIMIZE
||
1533 !WIN_IsWindowDrawable( wndPtr
, 0 )) return; /* Nothing to do */
1535 active
= wndPtr
->flags
& WIN_NCACTIVATED
;
1537 TRACE(nonclient
, "%04x %d\n", hwnd
, active
);
1539 if (!(hdc
= GetDCEx( hwnd
, 0, DCX_USESTYLE
| DCX_WINDOW
))) return;
1541 if (ExcludeVisRect16( hdc
, wndPtr
->rectClient
.left
-wndPtr
->rectWindow
.left
,
1542 wndPtr
->rectClient
.top
-wndPtr
->rectWindow
.top
,
1543 wndPtr
->rectClient
.right
-wndPtr
->rectWindow
.left
,
1544 wndPtr
->rectClient
.bottom
-wndPtr
->rectWindow
.top
)
1547 ReleaseDC( hwnd
, hdc
);
1551 rect
.top
= rect
.left
= 0;
1552 rect
.right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
1553 rect
.bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
1555 SelectObject( hdc
, GetSysColorPen(COLOR_WINDOWFRAME
) );
1557 if (!(wndPtr
->flags
& WIN_MANAGED
))
1559 if ((wndPtr
->dwStyle
& WS_BORDER
) || (wndPtr
->dwStyle
& WS_DLGFRAME
) ||
1560 (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
))
1562 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1563 Rectangle( hdc
, 0, 0, rect
.right
, rect
.bottom
);
1564 InflateRect( &rect
, -1, -1 );
1567 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1568 NC_DrawFrame( hdc
, &rect
, TRUE
, active
);
1569 else if (wndPtr
->dwStyle
& WS_THICKFRAME
)
1570 NC_DrawFrame(hdc
, &rect
, FALSE
, active
);
1572 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1575 r
.bottom
= rect
.top
+ SYSMETRICS_CYSIZE
;
1576 rect
.top
+= SYSMETRICS_CYSIZE
+ SYSMETRICS_CYBORDER
;
1577 NC_DrawCaption( hdc
, &r
, hwnd
, wndPtr
->dwStyle
, active
);
1581 if (HAS_MENU(wndPtr
))
1584 r
.bottom
= rect
.top
+ SYSMETRICS_CYMENU
; /* default height */
1585 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
);
1588 /* Draw the scroll-bars */
1590 if (wndPtr
->dwStyle
& WS_VSCROLL
)
1591 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1592 if (wndPtr
->dwStyle
& WS_HSCROLL
)
1593 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1595 /* Draw the "size-box" */
1597 if ((wndPtr
->dwStyle
& WS_VSCROLL
) && (wndPtr
->dwStyle
& WS_HSCROLL
))
1600 r
.left
= r
.right
- SYSMETRICS_CXVSCROLL
+ 1;
1601 r
.top
= r
.bottom
- SYSMETRICS_CYHSCROLL
+ 1;
1602 if(wndPtr
->dwStyle
& WS_BORDER
) {
1606 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1609 ReleaseDC( hwnd
, hdc
);
1613 /******************************************************************************
1615 * void NC_DoNCPaint95(
1618 * BOOL32 suppress_menupaint )
1620 * Paint the non-client area for Win95 windows. The clip region is
1621 * currently ignored.
1624 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1625 * misc/tweak.c controls/menu.c # :-)
1628 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1629 * Original implementation
1630 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1633 *****************************************************************************/
1635 void NC_DoNCPaint95(
1638 BOOL suppress_menupaint
)
1643 HWND hwnd
= wndPtr
->hwndSelf
;
1645 if ( wndPtr
->dwStyle
& WS_MINIMIZE
||
1646 !WIN_IsWindowDrawable( wndPtr
, 0 )) return; /* Nothing to do */
1648 active
= wndPtr
->flags
& WIN_NCACTIVATED
;
1650 TRACE(nonclient
, "%04x %d\n", hwnd
, active
);
1652 if (!(hdc
= GetDCEx( hwnd
, 0, DCX_USESTYLE
| DCX_WINDOW
))) return;
1654 if (ExcludeVisRect16( hdc
, wndPtr
->rectClient
.left
-wndPtr
->rectWindow
.left
,
1655 wndPtr
->rectClient
.top
-wndPtr
->rectWindow
.top
,
1656 wndPtr
->rectClient
.right
-wndPtr
->rectWindow
.left
,
1657 wndPtr
->rectClient
.bottom
-wndPtr
->rectWindow
.top
)
1660 ReleaseDC( hwnd
, hdc
);
1664 rect
.top
= rect
.left
= 0;
1665 rect
.right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
1666 rect
.bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
1668 SelectObject( hdc
, GetSysColorPen(COLOR_WINDOWFRAME
) );
1670 if(!(wndPtr
->flags
& WIN_MANAGED
)) {
1671 if ((wndPtr
->dwStyle
& WS_BORDER
) && ((wndPtr
->dwStyle
& WS_DLGFRAME
) ||
1672 (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
) || (wndPtr
->dwStyle
& WS_THICKFRAME
))) {
1673 DrawEdge (hdc
, &rect
, EDGE_RAISED
, BF_RECT
| BF_ADJUST
);
1676 if (HAS_FIXEDFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1677 NC_DrawFrame95( hdc
, &rect
, TRUE
, active
);
1678 else if (wndPtr
->dwStyle
& WS_THICKFRAME
)
1679 NC_DrawFrame95(hdc
, &rect
, FALSE
, active
);
1681 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1684 if (wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
) {
1685 r
.bottom
= rect
.top
+ sysMetrics
[SM_CYSMCAPTION
];
1686 rect
.top
+= sysMetrics
[SM_CYSMCAPTION
];
1689 r
.bottom
= rect
.top
+ sysMetrics
[SM_CYCAPTION
];
1690 rect
.top
+= sysMetrics
[SM_CYCAPTION
];
1692 NC_DrawCaption95 (hdc
, &r
, hwnd
, wndPtr
->dwStyle
,
1693 wndPtr
->dwExStyle
, active
);
1697 if (HAS_MENU(wndPtr
))
1700 r
.bottom
= rect
.top
+ sysMetrics
[SM_CYMENU
];
1702 TRACE(nonclient
, "Calling DrawMenuBar with "
1703 "rect (%d, %d)-(%d, %d)\n", r
.left
, r
.top
,
1706 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
) + 1;
1709 TRACE(nonclient
, "After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1710 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1712 if (wndPtr
->dwExStyle
& WS_EX_CLIENTEDGE
)
1713 DrawEdge (hdc
, &rect
, EDGE_SUNKEN
, BF_RECT
| BF_ADJUST
);
1715 if (wndPtr
->dwExStyle
& WS_EX_STATICEDGE
)
1716 DrawEdge (hdc
, &rect
, BDR_SUNKENOUTER
, BF_RECT
| BF_ADJUST
);
1718 /* Draw the scroll-bars */
1720 if (wndPtr
->dwStyle
& WS_VSCROLL
)
1721 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1722 if (wndPtr
->dwStyle
& WS_HSCROLL
)
1723 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1725 /* Draw the "size-box" */
1726 if ((wndPtr
->dwStyle
& WS_VSCROLL
) && (wndPtr
->dwStyle
& WS_HSCROLL
))
1729 r
.left
= r
.right
- SYSMETRICS_CXVSCROLL
+ 1;
1730 r
.top
= r
.bottom
- SYSMETRICS_CYHSCROLL
+ 1;
1731 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1734 ReleaseDC( hwnd
, hdc
);
1740 /***********************************************************************
1743 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1745 LONG
NC_HandleNCPaint( HWND hwnd
, HRGN clip
)
1747 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1749 if( wndPtr
&& wndPtr
->dwStyle
& WS_VISIBLE
)
1751 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
1752 WINPOS_RedrawIconTitle( hwnd
);
1753 else if (TWEAK_WineLook
== WIN31_LOOK
)
1754 NC_DoNCPaint( wndPtr
, clip
, FALSE
);
1756 NC_DoNCPaint95( wndPtr
, clip
, FALSE
);
1762 /***********************************************************************
1763 * NC_HandleNCActivate
1765 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1767 LONG
NC_HandleNCActivate( WND
*wndPtr
, WPARAM16 wParam
)
1771 if( wParam
) wStateChange
= !(wndPtr
->flags
& WIN_NCACTIVATED
);
1772 else wStateChange
= wndPtr
->flags
& WIN_NCACTIVATED
;
1776 if (wParam
) wndPtr
->flags
|= WIN_NCACTIVATED
;
1777 else wndPtr
->flags
&= ~WIN_NCACTIVATED
;
1779 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
1780 WINPOS_RedrawIconTitle( wndPtr
->hwndSelf
);
1781 else if (TWEAK_WineLook
== WIN31_LOOK
)
1782 NC_DoNCPaint( wndPtr
, (HRGN
)1, FALSE
);
1784 NC_DoNCPaint95( wndPtr
, (HRGN
)1, FALSE
);
1790 /***********************************************************************
1791 * NC_HandleSetCursor
1793 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1795 LONG
NC_HandleSetCursor( HWND hwnd
, WPARAM16 wParam
, LPARAM lParam
)
1797 if (hwnd
!= (HWND
)wParam
) return 0; /* Don't set the cursor for child windows */
1799 switch(LOWORD(lParam
))
1803 WORD msg
= HIWORD( lParam
);
1804 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_MBUTTONDOWN
) ||
1805 (msg
== WM_RBUTTONDOWN
))
1813 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) break;
1814 if (wndPtr
->class->hCursor
)
1816 SetCursor16( wndPtr
->class->hCursor
);
1824 return (LONG
)SetCursor16( LoadCursor16( 0, IDC_SIZEWE16
) );
1828 return (LONG
)SetCursor16( LoadCursor16( 0, IDC_SIZENS16
) );
1832 return (LONG
)SetCursor16( LoadCursor16( 0, IDC_SIZENWSE16
) );
1836 return (LONG
)SetCursor16( LoadCursor16( 0, IDC_SIZENESW16
) );
1839 /* Default cursor: arrow */
1840 return (LONG
)SetCursor16( LoadCursor16( 0, IDC_ARROW16
) );
1843 /***********************************************************************
1846 BOOL
NC_GetSysPopupPos( WND
* wndPtr
, RECT
* rect
)
1848 if( wndPtr
->hSysMenu
)
1850 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
1851 GetWindowRect( wndPtr
->hwndSelf
, rect
);
1854 if (TWEAK_WineLook
== WIN31_LOOK
)
1855 NC_GetInsideRect( wndPtr
->hwndSelf
, rect
);
1857 NC_GetInsideRect95( wndPtr
->hwndSelf
, rect
);
1858 OffsetRect( rect
, wndPtr
->rectWindow
.left
, wndPtr
->rectWindow
.top
);
1859 if (wndPtr
->dwStyle
& WS_CHILD
)
1860 ClientToScreen( wndPtr
->parent
->hwndSelf
, (POINT
*)rect
);
1861 if (TWEAK_WineLook
== WIN31_LOOK
) {
1862 rect
->right
= rect
->left
+ SYSMETRICS_CXSIZE
;
1863 rect
->bottom
= rect
->top
+ SYSMETRICS_CYSIZE
;
1866 rect
->right
= rect
->left
+ sysMetrics
[SM_CYCAPTION
] - 1;
1867 rect
->bottom
= rect
->top
+ sysMetrics
[SM_CYCAPTION
] - 1;
1875 /***********************************************************************
1878 * Initialisation of a move or resize, when initiatied from a menu choice.
1879 * Return hit test code for caption or sizing border.
1881 static LONG
NC_StartSizeMove( WND
* wndPtr
, WPARAM16 wParam
,
1882 POINT16
*capturePoint
)
1888 if ((wParam
& 0xfff0) == SC_MOVE
)
1890 /* Move pointer at the center of the caption */
1892 if (TWEAK_WineLook
== WIN31_LOOK
)
1893 NC_GetInsideRect( wndPtr
->hwndSelf
, &rect
);
1895 NC_GetInsideRect95( wndPtr
->hwndSelf
, &rect
);
1896 if (wndPtr
->dwStyle
& WS_SYSMENU
)
1897 rect
.left
+= SYSMETRICS_CXSIZE
+ 1;
1898 if (wndPtr
->dwStyle
& WS_MINIMIZEBOX
)
1899 rect
.right
-= SYSMETRICS_CXSIZE
+ 1;
1900 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
1901 rect
.right
-= SYSMETRICS_CXSIZE
+ 1;
1902 pt
.x
= wndPtr
->rectWindow
.left
+ (rect
.right
- rect
.left
) / 2;
1903 pt
.y
= wndPtr
->rectWindow
.top
+ rect
.top
+ SYSMETRICS_CYSIZE
/2;
1904 hittest
= HTCAPTION
;
1911 MSG_InternalGetMessage( &msg
, 0, 0, MSGF_SIZE
, PM_REMOVE
, FALSE
);
1915 CONV_POINT32TO16(&msg
.pt
, &pt
);
1916 hittest
= NC_HandleNCHitTest( wndPtr
->hwndSelf
, pt
);
1917 if ((hittest
< HTLEFT
) || (hittest
> HTBOTTOMRIGHT
))
1929 pt
.x
=(wndPtr
->rectWindow
.left
+wndPtr
->rectWindow
.right
)/2;
1930 pt
.y
= wndPtr
->rectWindow
.top
+ SYSMETRICS_CYFRAME
/ 2;
1934 pt
.x
=(wndPtr
->rectWindow
.left
+wndPtr
->rectWindow
.right
)/2;
1935 pt
.y
= wndPtr
->rectWindow
.bottom
- SYSMETRICS_CYFRAME
/ 2;
1939 pt
.x
= wndPtr
->rectWindow
.left
+ SYSMETRICS_CXFRAME
/ 2;
1940 pt
.y
=(wndPtr
->rectWindow
.top
+wndPtr
->rectWindow
.bottom
)/2;
1944 pt
.x
= wndPtr
->rectWindow
.right
- SYSMETRICS_CXFRAME
/ 2;
1945 pt
.y
=(wndPtr
->rectWindow
.top
+wndPtr
->rectWindow
.bottom
)/2;
1948 case VK_ESCAPE
: return 0;
1954 SetCursorPos( pt
.x
, pt
.y
);
1955 NC_HandleSetCursor( wndPtr
->hwndSelf
,
1956 wndPtr
->hwndSelf
, MAKELONG( hittest
, WM_MOUSEMOVE
));
1961 /***********************************************************************
1964 * Perform SC_MOVE and SC_SIZE commands. `
1966 static void NC_DoSizeMove( HWND hwnd
, WORD wParam
)
1969 RECT sizingRect
, mouseRect
;
1971 LONG hittest
= (LONG
)(wParam
& 0x0f);
1972 HCURSOR16 hDragCursor
= 0, hOldCursor
= 0;
1973 POINT minTrack
, maxTrack
;
1974 POINT16 capturePoint
, pt
;
1975 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1976 BOOL thickframe
= HAS_THICKFRAME( wndPtr
->dwStyle
);
1977 BOOL iconic
= wndPtr
->dwStyle
& WS_MINIMIZE
;
1979 DWORD dwPoint
= GetMessagePos ();
1981 capturePoint
= pt
= *(POINT16
*)&dwPoint
;
1983 if (IsZoomed(hwnd
) || !IsWindowVisible(hwnd
) ||
1984 (wndPtr
->flags
& WIN_MANAGED
)) return;
1986 if ((wParam
& 0xfff0) == SC_MOVE
)
1988 if (!(wndPtr
->dwStyle
& WS_CAPTION
)) return;
1990 hittest
= NC_StartSizeMove( wndPtr
, wParam
, &capturePoint
);
1991 if (!hittest
) return;
1995 if (!thickframe
) return;
1996 if ( hittest
&& hittest
!= HTSYSMENU
) hittest
+= 2;
2000 hittest
= NC_StartSizeMove( wndPtr
, wParam
, &capturePoint
);
2009 /* Get min/max info */
2011 WINPOS_GetMinMaxInfo( wndPtr
, NULL
, NULL
, &minTrack
, &maxTrack
);
2012 sizingRect
= wndPtr
->rectWindow
;
2013 if (wndPtr
->dwStyle
& WS_CHILD
)
2014 GetClientRect( wndPtr
->parent
->hwndSelf
, &mouseRect
);
2016 SetRect(&mouseRect
, 0, 0, SYSMETRICS_CXSCREEN
, SYSMETRICS_CYSCREEN
);
2017 if (ON_LEFT_BORDER(hittest
))
2019 mouseRect
.left
= MAX( mouseRect
.left
, sizingRect
.right
-maxTrack
.x
);
2020 mouseRect
.right
= MIN( mouseRect
.right
, sizingRect
.right
-minTrack
.x
);
2022 else if (ON_RIGHT_BORDER(hittest
))
2024 mouseRect
.left
= MAX( mouseRect
.left
, sizingRect
.left
+minTrack
.x
);
2025 mouseRect
.right
= MIN( mouseRect
.right
, sizingRect
.left
+maxTrack
.x
);
2027 if (ON_TOP_BORDER(hittest
))
2029 mouseRect
.top
= MAX( mouseRect
.top
, sizingRect
.bottom
-maxTrack
.y
);
2030 mouseRect
.bottom
= MIN( mouseRect
.bottom
,sizingRect
.bottom
-minTrack
.y
);
2032 else if (ON_BOTTOM_BORDER(hittest
))
2034 mouseRect
.top
= MAX( mouseRect
.top
, sizingRect
.top
+minTrack
.y
);
2035 mouseRect
.bottom
= MIN( mouseRect
.bottom
, sizingRect
.top
+maxTrack
.y
);
2037 if (wndPtr
->dwStyle
& WS_CHILD
)
2039 MapWindowPoints( wndPtr
->parent
->hwndSelf
, 0,
2040 (LPPOINT
)&mouseRect
, 2 );
2042 SendMessage16( hwnd
, WM_ENTERSIZEMOVE
, 0, 0 );
2044 if (GetCapture() != hwnd
) SetCapture( hwnd
);
2046 if (wndPtr
->dwStyle
& WS_CHILD
)
2048 /* Retrieve a default cache DC (without using the window style) */
2049 hdc
= GetDCEx( wndPtr
->parent
->hwndSelf
, 0, DCX_CACHE
);
2052 { /* Grab the server only when moving top-level windows without desktop */
2056 wndPtr
->pDriver
->pPreSizeMove(wndPtr
);
2058 if( iconic
) /* create a cursor for dragging */
2060 HICON16 hIcon
= (wndPtr
->class->hIcon
) ? wndPtr
->class->hIcon
2061 : (HICON16
)SendMessage16( hwnd
, WM_QUERYDRAGICON
, 0, 0L);
2062 if( hIcon
) hDragCursor
= CURSORICON_IconToCursor( hIcon
, TRUE
);
2063 if( !hDragCursor
) iconic
= FALSE
;
2066 if( !iconic
) NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2072 MSG_InternalGetMessage( &msg
, 0, 0, MSGF_SIZE
, PM_REMOVE
, FALSE
);
2074 /* Exit on button-up, Return, or Esc */
2075 if ((msg
.message
== WM_LBUTTONUP
) ||
2076 ((msg
.message
== WM_KEYDOWN
) &&
2077 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
2079 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
2080 continue; /* We are not interested in other messages */
2082 dwPoint
= GetMessagePos ();
2083 pt
= *(POINT16
*)&dwPoint
;
2085 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
2087 case VK_UP
: pt
.y
-= 8; break;
2088 case VK_DOWN
: pt
.y
+= 8; break;
2089 case VK_LEFT
: pt
.x
-= 8; break;
2090 case VK_RIGHT
: pt
.x
+= 8; break;
2093 pt
.x
= MAX( pt
.x
, mouseRect
.left
);
2094 pt
.x
= MIN( pt
.x
, mouseRect
.right
);
2095 pt
.y
= MAX( pt
.y
, mouseRect
.top
);
2096 pt
.y
= MIN( pt
.y
, mouseRect
.bottom
);
2098 dx
= pt
.x
- capturePoint
.x
;
2099 dy
= pt
.y
- capturePoint
.y
;
2106 if( iconic
) /* ok, no system popup tracking */
2108 hOldCursor
= SetCursor(hDragCursor
);
2110 WINPOS_ShowIconTitle( wndPtr
, FALSE
);
2114 if (msg
.message
== WM_KEYDOWN
) SetCursorPos( pt
.x
, pt
.y
);
2117 RECT newRect
= sizingRect
;
2119 if (hittest
== HTCAPTION
) OffsetRect( &newRect
, dx
, dy
);
2120 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
2121 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
2122 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
2123 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
2126 NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2127 NC_DrawMovingFrame( hdc
, &newRect
, thickframe
);
2130 sizingRect
= newRect
;
2138 if( moved
) /* restore cursors, show icon title later on */
2140 ShowCursor( FALSE
);
2141 SetCursor( hOldCursor
);
2143 DestroyCursor( hDragCursor
);
2146 NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2148 if (wndPtr
->dwStyle
& WS_CHILD
)
2149 ReleaseDC( wndPtr
->parent
->hwndSelf
, hdc
);
2152 ReleaseDC( 0, hdc
);
2155 wndPtr
->pDriver
->pPostSizeMove(wndPtr
);
2157 if (HOOK_IsHooked( WH_CBT
))
2159 RECT16
* pr
= SEGPTR_NEW(RECT16
);
2162 CONV_RECT32TO16( &sizingRect
, pr
);
2163 if( HOOK_CallHooks16( WH_CBT
, HCBT_MOVESIZE
, hwnd
,
2164 (LPARAM
)SEGPTR_GET(pr
)) )
2165 sizingRect
= wndPtr
->rectWindow
;
2167 CONV_RECT16TO32( pr
, &sizingRect
);
2171 SendMessage16( hwnd
, WM_EXITSIZEMOVE
, 0, 0 );
2172 SendMessage16( hwnd
, WM_SETVISIBLE
, !IsIconic16(hwnd
), 0L);
2174 if( moved
&& !((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
2176 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
2177 SetWindowPos( hwnd
, 0, sizingRect
.left
, sizingRect
.top
,
2178 sizingRect
.right
- sizingRect
.left
,
2179 sizingRect
.bottom
- sizingRect
.top
,
2180 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
2183 if( IsWindow(hwnd
) )
2184 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
2186 /* Single click brings up the system menu when iconized */
2190 if( wndPtr
->dwStyle
& WS_SYSMENU
)
2191 SendMessage16( hwnd
, WM_SYSCOMMAND
,
2192 SC_MOUSEMENU
+ HTSYSMENU
, *((LPARAM
*)&pt
));
2194 else WINPOS_ShowIconTitle( wndPtr
, TRUE
);
2199 /***********************************************************************
2202 * Track a mouse button press on the minimize or maximize box.
2204 static void NC_TrackMinMaxBox( HWND hwnd
, WORD wParam
)
2208 HDC hdc
= GetWindowDC( hwnd
);
2209 BOOL pressed
= TRUE
;
2210 void (*paintButton
)(HWND
, HDC16
, BOOL
);
2213 if (wParam
== HTMINBUTTON
)
2215 (TWEAK_WineLook
== WIN31_LOOK
) ? &NC_DrawMinButton
: &NC_DrawMinButton95
;
2218 (TWEAK_WineLook
== WIN31_LOOK
) ? &NC_DrawMaxButton
: &NC_DrawMaxButton95
;
2220 (*paintButton
)( hwnd
, hdc
, TRUE
);
2224 BOOL oldstate
= pressed
;
2225 MSG_InternalGetMessage( &msg
, 0, 0, 0, PM_REMOVE
, FALSE
);
2226 CONV_POINT32TO16( &msg
.pt
, &pt16
);
2228 pressed
= (NC_HandleNCHitTest( hwnd
, pt16
) == wParam
);
2229 if (pressed
!= oldstate
)
2230 (*paintButton
)( hwnd
, hdc
, pressed
);
2231 } while (msg
.message
!= WM_LBUTTONUP
);
2233 (*paintButton
)( hwnd
, hdc
, FALSE
);
2236 ReleaseDC( hwnd
, hdc
);
2237 if (!pressed
) return;
2239 if (wParam
== HTMINBUTTON
)
2240 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, *(LONG
*)&pt16
);
2242 SendMessage16( hwnd
, WM_SYSCOMMAND
,
2243 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, *(LONG
*)&pt16
);
2247 /***********************************************************************
2248 * NC_TrackCloseButton95
2250 * Track a mouse button press on the Win95 close button.
2253 NC_TrackCloseButton95 (HWND hwnd
, WORD wParam
)
2257 HDC hdc
= GetWindowDC( hwnd
);
2258 BOOL pressed
= TRUE
;
2262 NC_DrawCloseButton95 (hwnd
, hdc
, TRUE
);
2266 BOOL oldstate
= pressed
;
2267 MSG_InternalGetMessage( &msg
, 0, 0, 0, PM_REMOVE
, FALSE
);
2268 CONV_POINT32TO16( &msg
.pt
, &pt16
);
2270 pressed
= (NC_HandleNCHitTest( hwnd
, pt16
) == wParam
);
2271 if (pressed
!= oldstate
)
2272 NC_DrawCloseButton95 (hwnd
, hdc
, pressed
);
2273 } while (msg
.message
!= WM_LBUTTONUP
);
2275 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
);
2278 ReleaseDC( hwnd
, hdc
);
2279 if (!pressed
) return;
2281 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, *(LONG
*)&pt16
);
2285 /***********************************************************************
2288 * Track a mouse button press on the horizontal or vertical scroll-bar.
2290 static void NC_TrackScrollBar( HWND hwnd
, WPARAM wParam
, POINT pt
)
2294 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
2296 if ((wParam
& 0xfff0) == SC_HSCROLL
)
2298 if ((wParam
& 0x0f) != HTHSCROLL
) return;
2299 scrollbar
= SB_HORZ
;
2301 else /* SC_VSCROLL */
2303 if ((wParam
& 0x0f) != HTVSCROLL
) return;
2304 scrollbar
= SB_VERT
;
2307 if (!(msg
= SEGPTR_NEW(MSG16
))) return;
2308 pt
.x
-= wndPtr
->rectWindow
.left
;
2309 pt
.y
-= wndPtr
->rectWindow
.top
;
2311 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, WM_LBUTTONDOWN
, pt
);
2315 GetMessage16( SEGPTR_GET(msg
), 0, 0, 0 );
2316 switch(msg
->message
)
2321 pt
.x
= LOWORD(msg
->lParam
) + wndPtr
->rectClient
.left
-
2322 wndPtr
->rectWindow
.left
;
2323 pt
.y
= HIWORD(msg
->lParam
) + wndPtr
->rectClient
.top
-
2324 wndPtr
->rectWindow
.top
;
2325 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, msg
->message
, pt
);
2328 TranslateMessage16( msg
);
2329 DispatchMessage16( msg
);
2332 if (!IsWindow( hwnd
))
2337 } while (msg
->message
!= WM_LBUTTONUP
);
2341 /***********************************************************************
2342 * NC_HandleNCLButtonDown
2344 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2346 LONG
NC_HandleNCLButtonDown( WND
* pWnd
, WPARAM16 wParam
, LPARAM lParam
)
2348 HWND hwnd
= pWnd
->hwndSelf
;
2350 switch(wParam
) /* Hit test */
2353 hwnd
= WIN_GetTopParent(hwnd
);
2355 if( WINPOS_SetActiveWindow(hwnd
, TRUE
, TRUE
) || (GetActiveWindow() == hwnd
) )
2356 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_MOVE
+ HTCAPTION
, lParam
);
2360 if( pWnd
->dwStyle
& WS_SYSMENU
)
2362 if( !(pWnd
->dwStyle
& WS_MINIMIZE
) )
2364 HDC hDC
= GetWindowDC(hwnd
);
2365 if (TWEAK_WineLook
== WIN31_LOOK
)
2366 NC_DrawSysButton( hwnd
, hDC
, TRUE
);
2368 NC_DrawSysButton95( hwnd
, hDC
, TRUE
);
2369 ReleaseDC( hwnd
, hDC
);
2371 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
+ HTSYSMENU
, lParam
);
2376 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
, lParam
);
2380 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
2384 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
2389 NC_TrackMinMaxBox( hwnd
, wParam
);
2393 if (TWEAK_WineLook
>= WIN95_LOOK
)
2394 NC_TrackCloseButton95 (hwnd
, wParam
);
2405 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2406 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_SIZE
+ wParam
- 2, lParam
);
2416 /***********************************************************************
2417 * NC_HandleNCLButtonDblClk
2419 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2421 LONG
NC_HandleNCLButtonDblClk( WND
*pWnd
, WPARAM16 wParam
, LPARAM lParam
)
2424 * if this is an icon, send a restore since we are handling
2427 if (pWnd
->dwStyle
& WS_MINIMIZE
)
2429 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_RESTORE
, lParam
);
2433 switch(wParam
) /* Hit test */
2436 /* stop processing if WS_MAXIMIZEBOX is missing */
2437 if (pWnd
->dwStyle
& WS_MAXIMIZEBOX
)
2438 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
,
2439 (pWnd
->dwStyle
& WS_MAXIMIZE
) ? SC_RESTORE
: SC_MAXIMIZE
,
2444 if (!(pWnd
->class->style
& CS_NOCLOSE
))
2445 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_CLOSE
, lParam
);
2449 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
,
2454 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
,
2462 /***********************************************************************
2463 * NC_HandleSysCommand
2465 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2467 LONG
NC_HandleSysCommand( HWND hwnd
, WPARAM16 wParam
, POINT16 pt
)
2469 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
2471 UINT16 uCommand
= wParam
& 0xFFF0;
2473 TRACE(nonclient
, "Handling WM_SYSCOMMAND %x %d,%d\n",
2474 wParam
, pt
.x
, pt
.y
);
2476 if (wndPtr
->dwStyle
& WS_CHILD
&& uCommand
!= SC_KEYMENU
)
2477 ScreenToClient16( wndPtr
->parent
->hwndSelf
, &pt
);
2483 NC_DoSizeMove( hwnd
, wParam
);
2487 ShowWindow( hwnd
, SW_MINIMIZE
);
2491 ShowWindow( hwnd
, SW_MAXIMIZE
);
2495 ShowWindow( hwnd
, SW_RESTORE
);
2499 return SendMessage16( hwnd
, WM_CLOSE
, 0, 0 );
2503 CONV_POINT16TO32( &pt
, &pt32
);
2504 NC_TrackScrollBar( hwnd
, wParam
, pt32
);
2508 CONV_POINT16TO32( &pt
, &pt32
);
2509 MENU_TrackMouseMenuBar( wndPtr
, wParam
& 0x000F, pt32
);
2513 MENU_TrackKbdMenuBar( wndPtr
, wParam
, pt
.x
);
2517 WinExec( "taskman.exe", SW_SHOWNORMAL
);
2521 if (wParam
== SC_ABOUTWINE
)
2522 ShellAboutA(hwnd
,"Wine", WINE_RELEASE_INFO
, 0);
2524 if (wParam
== SC_PUTMARK
)
2525 TRACE(shell
,"Mark requested by user\n");
2532 FIXME (nonclient
, "unimplemented!\n");