2 * Non-client area window functions
4 * Copyright 1994 Alexandre Julliard
11 #include "sysmetrics.h"
15 #include "cursoricon.h"
21 #include "nonclient.h"
23 #include "selectors.h"
30 static HBITMAP16 hbitmapClose
= 0;
31 static HBITMAP16 hbitmapCloseD
= 0;
32 static HBITMAP16 hbitmapMinimize
= 0;
33 static HBITMAP16 hbitmapMinimizeD
= 0;
34 static HBITMAP16 hbitmapMaximize
= 0;
35 static HBITMAP16 hbitmapMaximizeD
= 0;
36 static HBITMAP16 hbitmapRestore
= 0;
37 static HBITMAP16 hbitmapRestoreD
= 0;
39 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
40 #define SC_PUTMARK (SC_SCREENSAVE+2)
42 /* Some useful macros */
43 #define HAS_DLGFRAME(style,exStyle) \
44 (((exStyle) & WS_EX_DLGMODALFRAME) || \
45 (((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
47 #define HAS_THICKFRAME(style) \
48 (((style) & WS_THICKFRAME) && \
49 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
51 #define HAS_FIXEDFRAME(style,exStyle) \
52 (((((exStyle) & WS_EX_DLGMODALFRAME) || \
53 ((style) & WS_DLGFRAME)) && ((style) & WS_BORDER)) && \
54 !((style) & WS_THICKFRAME))
56 #define HAS_SIZEFRAME(style) \
57 (((style) & WS_THICKFRAME) && \
58 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
60 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
62 #define ON_LEFT_BORDER(hit) \
63 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
64 #define ON_RIGHT_BORDER(hit) \
65 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
66 #define ON_TOP_BORDER(hit) \
67 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
68 #define ON_BOTTOM_BORDER(hit) \
69 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
71 /***********************************************************************
74 * Compute the size of the window rectangle from the size of the
77 static void NC_AdjustRect( LPRECT16 rect
, DWORD style
, BOOL menu
,
80 if (TWEAK_WineLook
> WIN31_LOOK
)
81 ERR(nonclient
, "Called in Win95 mode. Aiee! Please report this.\n" );
83 if(style
& WS_ICONIC
) return;
84 /* Decide if the window will be managed (see CreateWindowEx) */
85 if (!(Options
.managed
&& !(style
& WS_CHILD
) &&
86 ((style
& (WS_DLGFRAME
| WS_THICKFRAME
)) ||
87 (exStyle
& WS_EX_DLGMODALFRAME
))))
89 if (HAS_DLGFRAME( style
, exStyle
))
90 InflateRect16(rect
, SYSMETRICS_CXDLGFRAME
, SYSMETRICS_CYDLGFRAME
);
93 if (HAS_THICKFRAME(style
))
94 InflateRect16( rect
, SYSMETRICS_CXFRAME
, SYSMETRICS_CYFRAME
);
95 if (style
& WS_BORDER
)
96 InflateRect16( rect
, SYSMETRICS_CXBORDER
, SYSMETRICS_CYBORDER
);
99 if ((style
& WS_CAPTION
) == WS_CAPTION
)
100 rect
->top
-= SYSMETRICS_CYCAPTION
- SYSMETRICS_CYBORDER
;
102 if (menu
) rect
->top
-= SYSMETRICS_CYMENU
+ SYSMETRICS_CYBORDER
;
104 if (style
& WS_VSCROLL
) {
105 rect
->right
+= SYSMETRICS_CXVSCROLL
- 1;
106 if(!(style
& WS_BORDER
))
110 if (style
& WS_HSCROLL
) {
111 rect
->bottom
+= SYSMETRICS_CYHSCROLL
- 1;
112 if(!(style
& WS_BORDER
))
118 /******************************************************************************
119 * NC_AdjustRectOuter95
121 * Computes the size of the "outside" parts of the window based on the
122 * parameters of the client area.
131 * "Outer" parts of a window means the whole window frame, caption and
132 * menu bar. It does not include "inner" parts of the frame like client
133 * edge, static edge or scroll bars.
136 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
137 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
139 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
140 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
141 * NC_AdjustRectInner95 and added handling of Win95 styles.
143 *****************************************************************************/
146 NC_AdjustRectOuter95 (LPRECT16 rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
148 if(style
& WS_ICONIC
) return;
150 /* Decide if the window will be managed (see CreateWindowEx) */
151 if (!(Options
.managed
&& !(style
& WS_CHILD
) &&
152 ((style
& (WS_DLGFRAME
| WS_THICKFRAME
)) ||
153 (exStyle
& WS_EX_DLGMODALFRAME
))))
155 if (HAS_FIXEDFRAME( style
, exStyle
))
156 InflateRect16(rect
, SYSMETRICS_CXDLGFRAME
, SYSMETRICS_CYDLGFRAME
);
159 if (HAS_SIZEFRAME(style
))
160 InflateRect16( rect
, SYSMETRICS_CXFRAME
, SYSMETRICS_CYFRAME
);
162 if (style
& WS_BORDER
)
163 InflateRect16( rect
, SYSMETRICS_CXBORDER
, SYSMETRICS_CYBORDER
);
167 if ((style
& WS_CAPTION
) == WS_CAPTION
)
169 if (exStyle
& WS_EX_TOOLWINDOW
)
170 rect
->top
-= SYSMETRICS_CYSMCAPTION
;
172 rect
->top
-= SYSMETRICS_CYCAPTION
;
177 rect
->top
-= sysMetrics
[SM_CYMENU
];
181 /******************************************************************************
182 * NC_AdjustRectInner95
184 * Computes the size of the "inside" part of the window based on the
185 * parameters of the client area.
193 * "Inner" part of a window means the window frame inside of the flat
194 * window frame. It includes the client edge, the static edge and the
198 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
199 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
201 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
202 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
203 * NC_AdjustRectInner95 and added handling of Win95 styles.
205 *****************************************************************************/
208 NC_AdjustRectInner95 (LPRECT16 rect
, DWORD style
, DWORD exStyle
)
210 if(style
& WS_ICONIC
) return;
212 if (exStyle
& WS_EX_CLIENTEDGE
)
213 InflateRect16 (rect
, sysMetrics
[SM_CXEDGE
], sysMetrics
[SM_CYEDGE
]);
215 if (exStyle
& WS_EX_STATICEDGE
)
216 InflateRect16 (rect
, sysMetrics
[SM_CXBORDER
], sysMetrics
[SM_CYBORDER
]);
218 if (style
& WS_VSCROLL
) rect
->right
+= SYSMETRICS_CXVSCROLL
;
219 if (style
& WS_HSCROLL
) rect
->bottom
+= SYSMETRICS_CYHSCROLL
;
223 /***********************************************************************
224 * DrawCaption16 [USER.660] Draws a caption bar
238 DrawCaption16 (HWND16 hwnd
, HDC16 hdc
, const RECT16
*rect
, UINT16 uFlags
)
243 CONV_RECT16TO32 (rect
, &rect32
);
245 return (BOOL16
)DrawCaptionTempA (hwnd
, hdc
, rect
? &rect32
: NULL
,
246 0, 0, NULL
, uFlags
& 0x1F);
250 /***********************************************************************
251 * DrawCaption32 [USER32.154] Draws a caption bar
265 DrawCaption (HWND hwnd
, HDC hdc
, const RECT
*lpRect
, UINT uFlags
)
267 return DrawCaptionTempA (hwnd
, hdc
, lpRect
, 0, 0, NULL
, uFlags
& 0x1F);
271 /***********************************************************************
272 * DrawCaptionTemp16 [USER.657]
282 DrawCaptionTemp16 (HWND16 hwnd
, HDC16 hdc
, const RECT16
*rect
, HFONT16 hFont
,
283 HICON16 hIcon
, LPCSTR str
, UINT16 uFlags
)
288 CONV_RECT16TO32(rect
,&rect32
);
290 return (BOOL16
)DrawCaptionTempA (hwnd
, hdc
, rect
?&rect32
:NULL
, hFont
,
291 hIcon
, str
, uFlags
& 0x1F);
295 /***********************************************************************
296 * DrawCaptionTemp32A [USER32.599]
306 DrawCaptionTempA (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
307 HICON hIcon
, LPCSTR str
, UINT uFlags
)
311 TRACE (nonclient
, "(%08x,%08x,%p,%08x,%08x,\"%s\",%08x)\n",
312 hwnd
, hdc
, rect
, hFont
, hIcon
, str
, uFlags
);
314 /* drawing background */
315 if (uFlags
& DC_INBUTTON
) {
316 FillRect (hdc
, &rc
, GetSysColorBrush (COLOR_3DFACE
));
318 if (uFlags
& DC_ACTIVE
) {
319 HBRUSH hbr
= SelectObject (hdc
, CACHE_GetPattern55AABrush ());
320 PatBlt (hdc
, rc
.left
, rc
.top
,
321 rc
.right
-rc
.left
, rc
.bottom
-rc
.top
, 0xFA0089);
322 SelectObject (hdc
, hbr
);
326 FillRect (hdc
, &rc
, GetSysColorBrush ((uFlags
& DC_ACTIVE
) ?
327 COLOR_ACTIVECAPTION
: COLOR_INACTIVECAPTION
));
332 if ((uFlags
& DC_ICON
) && !(uFlags
& DC_SMALLCAP
)) {
336 pt
.y
= (rc
.bottom
+ rc
.top
- sysMetrics
[SM_CYSMICON
]) / 2;
339 DrawIconEx (hdc
, pt
.x
, pt
.y
, hIcon
, sysMetrics
[SM_CXSMICON
],
340 sysMetrics
[SM_CYSMICON
], 0, 0, DI_NORMAL
);
343 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
346 if (wndPtr
->class->hIconSm
)
347 hAppIcon
= wndPtr
->class->hIconSm
;
348 else if (wndPtr
->class->hIcon
)
349 hAppIcon
= wndPtr
->class->hIcon
;
351 DrawIconEx (hdc
, pt
.x
, pt
.y
, hAppIcon
, sysMetrics
[SM_CXSMICON
],
352 sysMetrics
[SM_CYSMICON
], 0, 0, DI_NORMAL
);
353 WIN_ReleaseWndPtr(wndPtr
);
356 rc
.left
+= (rc
.bottom
- rc
.top
);
360 if (uFlags
& DC_TEXT
) {
363 if (uFlags
& DC_INBUTTON
)
364 SetTextColor (hdc
, GetSysColor (COLOR_BTNTEXT
));
365 else if (uFlags
& DC_ACTIVE
)
366 SetTextColor (hdc
, GetSysColor (COLOR_CAPTIONTEXT
));
368 SetTextColor (hdc
, GetSysColor (COLOR_INACTIVECAPTIONTEXT
));
370 SetBkMode (hdc
, TRANSPARENT
);
373 hOldFont
= SelectObject (hdc
, hFont
);
375 NONCLIENTMETRICSA nclm
;
377 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
378 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
379 hNewFont
= CreateFontIndirectA ((uFlags
& DC_SMALLCAP
) ?
380 &nclm
.lfSmCaptionFont
: &nclm
.lfCaptionFont
);
381 hOldFont
= SelectObject (hdc
, hNewFont
);
385 DrawTextA (hdc
, str
, -1, &rc
,
386 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
390 nLen
= GetWindowTextA (hwnd
, szText
, 128);
391 DrawTextA (hdc
, szText
, nLen
, &rc
,
392 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
396 SelectObject (hdc
, hOldFont
);
398 DeleteObject (SelectObject (hdc
, hOldFont
));
401 /* drawing focus ??? */
403 FIXME (nonclient
, "undocumented flag (0x2000)!\n");
409 /***********************************************************************
410 * DrawCaptionTemp32W [USER32.602]
420 DrawCaptionTempW (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
421 HICON hIcon
, LPCWSTR str
, UINT uFlags
)
423 LPSTR p
= HEAP_strdupWtoA (GetProcessHeap (), 0, str
);
424 BOOL res
= DrawCaptionTempA (hwnd
, hdc
, rect
, hFont
, hIcon
, p
, uFlags
);
425 HeapFree (GetProcessHeap (), 0, p
);
430 /***********************************************************************
431 * AdjustWindowRect16 (USER.102)
433 BOOL16 WINAPI
AdjustWindowRect16( LPRECT16 rect
, DWORD style
, BOOL16 menu
)
435 return AdjustWindowRectEx16( rect
, style
, menu
, 0 );
439 /***********************************************************************
440 * AdjustWindowRect32 (USER32.2)
442 BOOL WINAPI
AdjustWindowRect( LPRECT rect
, DWORD style
, BOOL menu
)
444 return AdjustWindowRectEx( rect
, style
, menu
, 0 );
448 /***********************************************************************
449 * AdjustWindowRectEx16 (USER.454)
451 BOOL16 WINAPI
AdjustWindowRectEx16( LPRECT16 rect
, DWORD style
,
452 BOOL16 menu
, DWORD exStyle
)
454 /* Correct the window style */
456 if (!(style
& (WS_POPUP
| WS_CHILD
))) /* Overlapped window */
458 style
&= (WS_DLGFRAME
| WS_BORDER
| WS_THICKFRAME
| WS_CHILD
);
459 exStyle
&= (WS_EX_DLGMODALFRAME
| WS_EX_CLIENTEDGE
|
460 WS_EX_STATICEDGE
| WS_EX_TOOLWINDOW
);
461 if (exStyle
& WS_EX_DLGMODALFRAME
) style
&= ~WS_THICKFRAME
;
463 TRACE(nonclient
, "(%d,%d)-(%d,%d) %08lx %d %08lx\n",
464 rect
->left
, rect
->top
, rect
->right
, rect
->bottom
,
465 style
, menu
, exStyle
);
467 if (TWEAK_WineLook
== WIN31_LOOK
)
468 NC_AdjustRect( rect
, style
, menu
, exStyle
);
470 NC_AdjustRectOuter95( rect
, style
, menu
, exStyle
);
471 NC_AdjustRectInner95( rect
, style
, exStyle
);
478 /***********************************************************************
479 * AdjustWindowRectEx32 (USER32.3)
481 BOOL WINAPI
AdjustWindowRectEx( LPRECT rect
, DWORD style
,
482 BOOL menu
, DWORD exStyle
)
487 CONV_RECT32TO16( rect
, &rect16
);
488 ret
= AdjustWindowRectEx16( &rect16
, style
, (BOOL16
)menu
, exStyle
);
489 CONV_RECT16TO32( &rect16
, rect
);
494 /***********************************************************************
495 * NC_HandleNCCalcSize
497 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
499 LONG
NC_HandleNCCalcSize( WND
*pWnd
, RECT
*winRect
)
501 RECT16 tmpRect
= { 0, 0, 0, 0 };
504 if (pWnd
->class->style
& CS_VREDRAW
) result
|= WVR_VREDRAW
;
505 if (pWnd
->class->style
& CS_HREDRAW
) result
|= WVR_HREDRAW
;
507 if( !( pWnd
->dwStyle
& WS_MINIMIZE
) ) {
508 if (TWEAK_WineLook
== WIN31_LOOK
)
509 NC_AdjustRect( &tmpRect
, pWnd
->dwStyle
, FALSE
, pWnd
->dwExStyle
);
511 NC_AdjustRectOuter95( &tmpRect
, pWnd
->dwStyle
, FALSE
, pWnd
->dwExStyle
);
513 winRect
->left
-= tmpRect
.left
;
514 winRect
->top
-= tmpRect
.top
;
515 winRect
->right
-= tmpRect
.right
;
516 winRect
->bottom
-= tmpRect
.bottom
;
518 if (HAS_MENU(pWnd
)) {
519 TRACE(nonclient
, "Calling "
520 "GetMenuBarHeight with HWND 0x%x, width %d, "
521 "at (%d, %d).\n", pWnd
->hwndSelf
,
522 winRect
->right
- winRect
->left
,
523 -tmpRect
.left
, -tmpRect
.top
);
526 MENU_GetMenuBarHeight( pWnd
->hwndSelf
,
527 winRect
->right
- winRect
->left
,
528 -tmpRect
.left
, -tmpRect
.top
) + 1;
531 if (TWEAK_WineLook
> WIN31_LOOK
) {
532 SetRect16 (&tmpRect
, 0, 0, 0, 0);
533 NC_AdjustRectInner95 (&tmpRect
, pWnd
->dwStyle
, pWnd
->dwExStyle
);
534 winRect
->left
-= tmpRect
.left
;
535 winRect
->top
-= tmpRect
.top
;
536 winRect
->right
-= tmpRect
.right
;
537 winRect
->bottom
-= tmpRect
.bottom
;
544 /***********************************************************************
547 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
548 * but without the borders (if any).
549 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
551 static void NC_GetInsideRect( HWND hwnd
, RECT
*rect
)
553 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
555 rect
->top
= rect
->left
= 0;
556 rect
->right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
557 rect
->bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
559 if ((wndPtr
->dwStyle
& WS_ICONIC
) || (wndPtr
->flags
& WIN_MANAGED
)) goto END
;
561 /* Remove frame from rectangle */
562 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
564 InflateRect( rect
, -SYSMETRICS_CXDLGFRAME
, -SYSMETRICS_CYDLGFRAME
);
565 if (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
)
566 InflateRect( rect
, -1, 0 );
570 if (HAS_THICKFRAME( wndPtr
->dwStyle
))
571 InflateRect( rect
, -SYSMETRICS_CXFRAME
, -SYSMETRICS_CYFRAME
);
572 if (wndPtr
->dwStyle
& WS_BORDER
)
573 InflateRect( rect
, -SYSMETRICS_CXBORDER
, -SYSMETRICS_CYBORDER
);
576 WIN_ReleaseWndPtr(wndPtr
);
581 /***********************************************************************
584 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
585 * but without the borders (if any).
586 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
590 NC_GetInsideRect95 (HWND hwnd
, RECT
*rect
)
592 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
594 rect
->top
= rect
->left
= 0;
595 rect
->right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
596 rect
->bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
598 if ((wndPtr
->dwStyle
& WS_ICONIC
) || (wndPtr
->flags
& WIN_MANAGED
)) goto END
;
600 /* Remove frame from rectangle */
601 if (HAS_FIXEDFRAME (wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
603 InflateRect( rect
, -SYSMETRICS_CXFIXEDFRAME
, -SYSMETRICS_CYFIXEDFRAME
);
605 else if (HAS_SIZEFRAME (wndPtr
->dwStyle
))
607 InflateRect( rect
, -SYSMETRICS_CXSIZEFRAME
, -SYSMETRICS_CYSIZEFRAME
);
609 /* if (wndPtr->dwStyle & WS_BORDER)
610 InflateRect32( rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER );*/
613 if (wndPtr
->dwStyle
& WS_CHILD
) {
614 if (wndPtr
->dwExStyle
& WS_EX_CLIENTEDGE
)
615 InflateRect (rect
, -SYSMETRICS_CXEDGE
, -SYSMETRICS_CYEDGE
);
617 if (wndPtr
->dwExStyle
& WS_EX_STATICEDGE
)
618 InflateRect (rect
, -SYSMETRICS_CXBORDER
, -SYSMETRICS_CYBORDER
);
621 WIN_ReleaseWndPtr(wndPtr
);
626 /***********************************************************************
629 * Handle a WM_NCHITTEST message. Called from NC_HandleNcHitTest().
632 LONG
NC_DoNCHitTest (WND
*wndPtr
, POINT16 pt
)
636 TRACE(nonclient
, "hwnd=%04x pt=%d,%d\n",
637 wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
639 GetWindowRect16 (wndPtr
->hwndSelf
, &rect
);
640 if (!PtInRect16( &rect
, pt
)) return HTNOWHERE
;
642 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
644 if (!(wndPtr
->flags
& WIN_MANAGED
))
647 if (HAS_THICKFRAME( wndPtr
->dwStyle
))
649 InflateRect16( &rect
, -SYSMETRICS_CXFRAME
, -SYSMETRICS_CYFRAME
);
650 if (wndPtr
->dwStyle
& WS_BORDER
)
651 InflateRect16(&rect
,-SYSMETRICS_CXBORDER
,-SYSMETRICS_CYBORDER
);
652 if (!PtInRect16( &rect
, pt
))
654 /* Check top sizing border */
657 if (pt
.x
< rect
.left
+SYSMETRICS_CXSIZE
) return HTTOPLEFT
;
658 if (pt
.x
>= rect
.right
-SYSMETRICS_CXSIZE
) return HTTOPRIGHT
;
661 /* Check bottom sizing border */
662 if (pt
.y
>= rect
.bottom
)
664 if (pt
.x
< rect
.left
+SYSMETRICS_CXSIZE
) return HTBOTTOMLEFT
;
665 if (pt
.x
>= rect
.right
-SYSMETRICS_CXSIZE
) return HTBOTTOMRIGHT
;
668 /* Check left sizing border */
669 if (pt
.x
< rect
.left
)
671 if (pt
.y
< rect
.top
+SYSMETRICS_CYSIZE
) return HTTOPLEFT
;
672 if (pt
.y
>= rect
.bottom
-SYSMETRICS_CYSIZE
) return HTBOTTOMLEFT
;
675 /* Check right sizing border */
676 if (pt
.x
>= rect
.right
)
678 if (pt
.y
< rect
.top
+SYSMETRICS_CYSIZE
) return HTTOPRIGHT
;
679 if (pt
.y
>= rect
.bottom
-SYSMETRICS_CYSIZE
) return HTBOTTOMRIGHT
;
684 else /* No thick frame */
686 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
687 InflateRect16(&rect
, -SYSMETRICS_CXDLGFRAME
, -SYSMETRICS_CYDLGFRAME
);
688 else if (wndPtr
->dwStyle
& WS_BORDER
)
689 InflateRect16(&rect
, -SYSMETRICS_CXBORDER
, -SYSMETRICS_CYBORDER
);
690 if (!PtInRect16( &rect
, pt
)) return HTBORDER
;
695 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
697 rect
.top
+= sysMetrics
[SM_CYCAPTION
] - 1;
698 if (!PtInRect16( &rect
, pt
))
700 /* Check system menu */
701 if (wndPtr
->dwStyle
& WS_SYSMENU
)
702 rect
.left
+= SYSMETRICS_CXSIZE
;
703 if (pt
.x
<= rect
.left
) return HTSYSMENU
;
704 /* Check maximize box */
705 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
706 rect
.right
-= SYSMETRICS_CXSIZE
+ 1;
707 if (pt
.x
>= rect
.right
) return HTMAXBUTTON
;
708 /* Check minimize box */
709 if (wndPtr
->dwStyle
& WS_MINIMIZEBOX
)
710 rect
.right
-= SYSMETRICS_CXSIZE
+ 1;
711 if (pt
.x
>= rect
.right
) return HTMINBUTTON
;
717 /* Check client area */
719 ScreenToClient16( wndPtr
->hwndSelf
, &pt
);
720 GetClientRect16( wndPtr
->hwndSelf
, &rect
);
721 if (PtInRect16( &rect
, pt
)) return HTCLIENT
;
723 /* Check vertical scroll bar */
725 if (wndPtr
->dwStyle
& WS_VSCROLL
)
727 rect
.right
+= SYSMETRICS_CXVSCROLL
;
728 if (PtInRect16( &rect
, pt
)) return HTVSCROLL
;
731 /* Check horizontal scroll bar */
733 if (wndPtr
->dwStyle
& WS_HSCROLL
)
735 rect
.bottom
+= SYSMETRICS_CYHSCROLL
;
736 if (PtInRect16( &rect
, pt
))
739 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
740 (pt
.x
>= rect
.right
- SYSMETRICS_CXVSCROLL
))
748 if (HAS_MENU(wndPtr
))
750 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
754 /* Should never get here */
759 /***********************************************************************
762 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
764 * FIXME: Just a modified copy of the Win 3.1 version.
768 NC_DoNCHitTest95 (WND
*wndPtr
, POINT16 pt
)
772 TRACE(nonclient
, "hwnd=%04x pt=%d,%d\n",
773 wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
775 GetWindowRect16 (wndPtr
->hwndSelf
, &rect
);
776 if (!PtInRect16( &rect
, pt
)) return HTNOWHERE
;
778 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
780 if (!(wndPtr
->flags
& WIN_MANAGED
))
783 if (HAS_SIZEFRAME( wndPtr
->dwStyle
))
785 InflateRect16( &rect
, -SYSMETRICS_CXFRAME
, -SYSMETRICS_CYFRAME
);
786 /* if (wndPtr->dwStyle & WS_BORDER) */
787 /* InflateRect16(&rect,-SYSMETRICS_CXBORDER,-SYSMETRICS_CYBORDER); */
788 if (!PtInRect16( &rect
, pt
))
790 /* Check top sizing border */
793 if (pt
.x
< rect
.left
+SYSMETRICS_CXSIZE
) return HTTOPLEFT
;
794 if (pt
.x
>= rect
.right
-SYSMETRICS_CXSIZE
) return HTTOPRIGHT
;
797 /* Check bottom sizing border */
798 if (pt
.y
>= rect
.bottom
)
800 if (pt
.x
< rect
.left
+SYSMETRICS_CXSIZE
) return HTBOTTOMLEFT
;
801 if (pt
.x
>= rect
.right
-SYSMETRICS_CXSIZE
) return HTBOTTOMRIGHT
;
804 /* Check left sizing border */
805 if (pt
.x
< rect
.left
)
807 if (pt
.y
< rect
.top
+SYSMETRICS_CYSIZE
) return HTTOPLEFT
;
808 if (pt
.y
>= rect
.bottom
-SYSMETRICS_CYSIZE
) return HTBOTTOMLEFT
;
811 /* Check right sizing border */
812 if (pt
.x
>= rect
.right
)
814 if (pt
.y
< rect
.top
+SYSMETRICS_CYSIZE
) return HTTOPRIGHT
;
815 if (pt
.y
>= rect
.bottom
-SYSMETRICS_CYSIZE
) return HTBOTTOMRIGHT
;
820 else /* No thick frame */
822 if (HAS_FIXEDFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
823 InflateRect16(&rect
, -SYSMETRICS_CXDLGFRAME
, -SYSMETRICS_CYDLGFRAME
);
824 /* else if (wndPtr->dwStyle & WS_BORDER) */
825 /* InflateRect16(&rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER); */
826 if (!PtInRect16( &rect
, pt
)) return HTBORDER
;
831 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
833 if (wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
)
834 rect
.top
+= sysMetrics
[SM_CYSMCAPTION
] - 1;
836 rect
.top
+= sysMetrics
[SM_CYCAPTION
] - 1;
837 if (!PtInRect16( &rect
, pt
))
839 /* Check system menu */
840 if ((wndPtr
->dwStyle
& WS_SYSMENU
) &&
841 ((wndPtr
->class->hIconSm
) || (wndPtr
->class->hIcon
)))
842 rect
.left
+= sysMetrics
[SM_CYCAPTION
] - 1;
843 if (pt
.x
< rect
.left
) return HTSYSMENU
;
845 /* Check close button */
846 if (wndPtr
->dwStyle
& WS_SYSMENU
)
847 rect
.right
-= sysMetrics
[SM_CYCAPTION
] - 1;
848 if (pt
.x
> rect
.right
) return HTCLOSE
;
850 /* Check maximize box */
851 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
852 rect
.right
-= SYSMETRICS_CXSIZE
+ 1;
853 if (pt
.x
> rect
.right
) return HTMAXBUTTON
;
855 /* Check minimize box */
856 if (wndPtr
->dwStyle
& WS_MINIMIZEBOX
)
857 rect
.right
-= SYSMETRICS_CXSIZE
+ 1;
858 if (pt
.x
> rect
.right
) return HTMINBUTTON
;
864 /* Check client area */
866 ScreenToClient16( wndPtr
->hwndSelf
, &pt
);
867 GetClientRect16( wndPtr
->hwndSelf
, &rect
);
868 if (PtInRect16( &rect
, pt
)) return HTCLIENT
;
870 /* Check vertical scroll bar */
872 if (wndPtr
->dwStyle
& WS_VSCROLL
)
874 rect
.right
+= SYSMETRICS_CXVSCROLL
;
875 if (PtInRect16( &rect
, pt
)) return HTVSCROLL
;
878 /* Check horizontal scroll bar */
880 if (wndPtr
->dwStyle
& WS_HSCROLL
)
882 rect
.bottom
+= SYSMETRICS_CYHSCROLL
;
883 if (PtInRect16( &rect
, pt
))
886 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
887 (pt
.x
>= rect
.right
- SYSMETRICS_CXVSCROLL
))
895 if (HAS_MENU(wndPtr
))
897 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
901 /* Should never get here */
906 /***********************************************************************
909 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
912 NC_HandleNCHitTest (HWND hwnd
, POINT16 pt
)
915 WND
*wndPtr
= WIN_FindWndPtr (hwnd
);
920 if (TWEAK_WineLook
== WIN31_LOOK
)
921 retvalue
= NC_DoNCHitTest (wndPtr
, pt
);
923 retvalue
= NC_DoNCHitTest95 (wndPtr
, pt
);
924 WIN_ReleaseWndPtr(wndPtr
);
929 /***********************************************************************
932 void NC_DrawSysButton( HWND hwnd
, HDC hdc
, BOOL down
)
937 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
939 if( !(wndPtr
->flags
& WIN_MANAGED
) )
941 NC_GetInsideRect( hwnd
, &rect
);
942 hdcMem
= CreateCompatibleDC( hdc
);
943 hbitmap
= SelectObject( hdcMem
, hbitmapClose
);
944 BitBlt(hdc
, rect
.left
, rect
.top
, SYSMETRICS_CXSIZE
, SYSMETRICS_CYSIZE
,
945 hdcMem
, (wndPtr
->dwStyle
& WS_CHILD
) ? SYSMETRICS_CXSIZE
: 0, 0,
946 down
? NOTSRCCOPY
: SRCCOPY
);
947 SelectObject( hdcMem
, hbitmap
);
950 WIN_ReleaseWndPtr(wndPtr
);
954 /***********************************************************************
957 static void NC_DrawMaxButton( HWND hwnd
, HDC16 hdc
, BOOL down
)
960 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
963 if( !(wndPtr
->flags
& WIN_MANAGED
) )
965 NC_GetInsideRect( hwnd
, &rect
);
966 hdcMem
= CreateCompatibleDC( hdc
);
967 SelectObject( hdcMem
, (IsZoomed(hwnd
)
968 ? (down
? hbitmapRestoreD
: hbitmapRestore
)
969 : (down
? hbitmapMaximizeD
: hbitmapMaximize
)) );
970 BitBlt( hdc
, rect
.right
- SYSMETRICS_CXSIZE
- 1, rect
.top
,
971 SYSMETRICS_CXSIZE
+ 1, SYSMETRICS_CYSIZE
, hdcMem
, 0, 0,
975 WIN_ReleaseWndPtr(wndPtr
);
980 /***********************************************************************
983 static void NC_DrawMinButton( HWND hwnd
, HDC16 hdc
, BOOL down
)
986 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
989 if( !(wndPtr
->flags
& WIN_MANAGED
) )
991 NC_GetInsideRect( hwnd
, &rect
);
992 hdcMem
= CreateCompatibleDC( hdc
);
993 SelectObject( hdcMem
, (down
? hbitmapMinimizeD
: hbitmapMinimize
) );
994 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
) rect
.right
-= SYSMETRICS_CXSIZE
+1;
995 BitBlt( hdc
, rect
.right
- SYSMETRICS_CXSIZE
- 1, rect
.top
,
996 SYSMETRICS_CXSIZE
+ 1, SYSMETRICS_CYSIZE
, hdcMem
, 0, 0,
1000 WIN_ReleaseWndPtr(wndPtr
);
1004 /******************************************************************************
1006 * void NC_DrawSysButton95(
1011 * Draws the Win95 system icon.
1014 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1015 * Original implementation from NC_DrawSysButton source.
1016 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1019 *****************************************************************************/
1022 NC_DrawSysButton95 (HWND hwnd
, HDC hdc
, BOOL down
)
1024 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1026 if( !(wndPtr
->flags
& WIN_MANAGED
) )
1031 NC_GetInsideRect95( hwnd
, &rect
);
1033 if (wndPtr
->class->hIconSm
)
1034 hIcon
= wndPtr
->class->hIconSm
;
1035 else if (wndPtr
->class->hIcon
)
1036 hIcon
= wndPtr
->class->hIcon
;
1039 DrawIconEx (hdc
, rect
.left
+ 2, rect
.top
+ 2, hIcon
,
1040 sysMetrics
[SM_CXSMICON
],
1041 sysMetrics
[SM_CYSMICON
],
1044 WIN_ReleaseWndPtr(wndPtr
);
1045 return (hIcon
!= 0);
1047 WIN_ReleaseWndPtr(wndPtr
);
1052 /******************************************************************************
1054 * void NC_DrawCloseButton95(
1059 * Draws the Win95 close button.
1062 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1063 * Original implementation from NC_DrawSysButton95 source.
1065 *****************************************************************************/
1067 void NC_DrawCloseButton95 (HWND hwnd
, HDC hdc
, BOOL down
)
1071 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1073 if( !(wndPtr
->flags
& WIN_MANAGED
) )
1076 HBITMAP hBmp
, hOldBmp
;
1078 NC_GetInsideRect95( hwnd
, &rect
);
1080 hdcMem
= CreateCompatibleDC( hdc
);
1081 hBmp
= down
? hbitmapCloseD
: hbitmapClose
;
1082 hOldBmp
= SelectObject (hdcMem
, hBmp
);
1083 GetObjectA (hBmp
, sizeof(BITMAP
), &bmp
);
1084 BitBlt (hdc
, rect
.right
- (sysMetrics
[SM_CYCAPTION
] + 1 + bmp
.bmWidth
) / 2,
1085 rect
.top
+ (sysMetrics
[SM_CYCAPTION
] - 1 - bmp
.bmHeight
) / 2,
1086 bmp
.bmWidth
, bmp
.bmHeight
, hdcMem
, 0, 0, SRCCOPY
);
1088 SelectObject (hdcMem
, hOldBmp
);
1091 WIN_ReleaseWndPtr(wndPtr
);
1094 /******************************************************************************
1096 * NC_DrawMaxButton95(
1101 * Draws the maximize button for Win95 style windows.
1104 * Many. Spacing might still be incorrect. Need to fit a close
1105 * button between the max button and the edge.
1106 * Should scale the image with the title bar. And more...
1109 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1110 * Original implementation.
1112 *****************************************************************************/
1114 static void NC_DrawMaxButton95(HWND hwnd
,HDC16 hdc
,BOOL down
)
1118 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1120 if( !(wndPtr
->flags
& WIN_MANAGED
))
1123 HBITMAP hBmp
,hOldBmp
;
1125 NC_GetInsideRect95( hwnd
, &rect
);
1126 hdcMem
= CreateCompatibleDC( hdc
);
1127 hBmp
= IsZoomed(hwnd
) ?
1128 (down
? hbitmapRestoreD
: hbitmapRestore
) :
1129 (down
? hbitmapMaximizeD
: hbitmapMaximize
);
1130 hOldBmp
=SelectObject( hdcMem
, hBmp
);
1131 GetObjectA (hBmp
, sizeof(BITMAP
), &bmp
);
1133 if (wndPtr
->dwStyle
& WS_SYSMENU
)
1134 rect
.right
-= sysMetrics
[SM_CYCAPTION
] + 1;
1136 BitBlt( hdc
, rect
.right
- (sysMetrics
[SM_CXSIZE
] + bmp
.bmWidth
) / 2,
1137 rect
.top
+ (sysMetrics
[SM_CYCAPTION
] - 1 - bmp
.bmHeight
) / 2,
1138 bmp
.bmWidth
, bmp
.bmHeight
, hdcMem
, 0, 0, SRCCOPY
);
1139 SelectObject (hdcMem
, hOldBmp
);
1142 WIN_ReleaseWndPtr(wndPtr
);
1145 /******************************************************************************
1147 * NC_DrawMinButton95(
1152 * Draws the minimize button for Win95 style windows.
1155 * Many. Spacing is still incorrect. Should scale the image with the
1156 * title bar. And more...
1159 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1160 * Original implementation.
1162 *****************************************************************************/
1164 static void NC_DrawMinButton95(HWND hwnd
,HDC16 hdc
,BOOL down
)
1168 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1170 if( !(wndPtr
->flags
& WIN_MANAGED
))
1174 HBITMAP hBmp
,hOldBmp
;
1176 NC_GetInsideRect95( hwnd
, &rect
);
1178 hdcMem
= CreateCompatibleDC( hdc
);
1179 hBmp
= down
? hbitmapMinimizeD
: hbitmapMinimize
;
1180 hOldBmp
= SelectObject( hdcMem
, hBmp
);
1181 GetObjectA (hBmp
, sizeof(BITMAP
), &bmp
);
1183 if (wndPtr
->dwStyle
& WS_SYSMENU
)
1184 rect
.right
-= sysMetrics
[SM_CYCAPTION
] + 1;
1186 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
1187 rect
.right
+= -1 - (sysMetrics
[SM_CXSIZE
] + bmp
.bmWidth
) / 2;
1189 BitBlt( hdc
, rect
.right
- (sysMetrics
[SM_CXSIZE
] + bmp
.bmWidth
) / 2,
1190 rect
.top
+ (sysMetrics
[SM_CYCAPTION
] - 1 - bmp
.bmHeight
) / 2,
1191 bmp
.bmWidth
, bmp
.bmHeight
, hdcMem
, 0, 0, SRCCOPY
);
1193 SelectObject (hdcMem
, hOldBmp
);
1196 WIN_ReleaseWndPtr(wndPtr
);
1199 /***********************************************************************
1202 * Draw a window frame inside the given rectangle, and update the rectangle.
1203 * The correct pen for the frame must be selected in the DC.
1205 static void NC_DrawFrame( HDC hdc
, RECT
*rect
, BOOL dlgFrame
,
1210 if (TWEAK_WineLook
!= WIN31_LOOK
)
1211 ERR (nonclient
, "Called in Win95 mode. Aiee! Please report this.\n" );
1215 width
= SYSMETRICS_CXDLGFRAME
- 1;
1216 height
= SYSMETRICS_CYDLGFRAME
- 1;
1217 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1218 COLOR_INACTIVECAPTION
) );
1222 width
= SYSMETRICS_CXFRAME
- 1;
1223 height
= SYSMETRICS_CYFRAME
- 1;
1224 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1225 COLOR_INACTIVEBORDER
) );
1229 PatBlt( hdc
, rect
->left
, rect
->top
,
1230 rect
->right
- rect
->left
, height
, PATCOPY
);
1231 PatBlt( hdc
, rect
->left
, rect
->top
,
1232 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1233 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1234 rect
->right
- rect
->left
, -height
, PATCOPY
);
1235 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1236 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1240 InflateRect( rect
, -width
, -height
);
1244 INT decYOff
= SYSMETRICS_CXFRAME
+ SYSMETRICS_CXSIZE
;
1245 INT decXOff
= SYSMETRICS_CYFRAME
+ SYSMETRICS_CYSIZE
;
1247 /* Draw inner rectangle */
1249 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1250 Rectangle( hdc
, rect
->left
+ width
, rect
->top
+ height
,
1251 rect
->right
- width
, rect
->bottom
- height
);
1253 /* Draw the decorations */
1255 MoveToEx( hdc
, rect
->left
, rect
->top
+ decYOff
, NULL
);
1256 LineTo( hdc
, rect
->left
+ width
, rect
->top
+ decYOff
);
1257 MoveToEx( hdc
, rect
->right
- 1, rect
->top
+ decYOff
, NULL
);
1258 LineTo( hdc
, rect
->right
- width
- 1, rect
->top
+ decYOff
);
1259 MoveToEx( hdc
, rect
->left
, rect
->bottom
- decYOff
, NULL
);
1260 LineTo( hdc
, rect
->left
+ width
, rect
->bottom
- decYOff
);
1261 MoveToEx( hdc
, rect
->right
- 1, rect
->bottom
- decYOff
, NULL
);
1262 LineTo( hdc
, rect
->right
- width
- 1, rect
->bottom
- decYOff
);
1264 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->top
, NULL
);
1265 LineTo( hdc
, rect
->left
+ decXOff
, rect
->top
+ height
);
1266 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->bottom
- 1, NULL
);
1267 LineTo( hdc
, rect
->left
+ decXOff
, rect
->bottom
- height
- 1 );
1268 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->top
, NULL
);
1269 LineTo( hdc
, rect
->right
- decXOff
, rect
->top
+ height
);
1270 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->bottom
- 1, NULL
);
1271 LineTo( hdc
, rect
->right
- decXOff
, rect
->bottom
- height
- 1 );
1273 InflateRect( rect
, -width
- 1, -height
- 1 );
1278 /******************************************************************************
1280 * void NC_DrawFrame95(
1286 * Draw a window frame inside the given rectangle, and update the rectangle.
1287 * The correct pen for the frame must be selected in the DC.
1290 * Many. First, just what IS a frame in Win95? Note that the 3D look
1291 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1292 * edge. The inner rectangle just inside the frame is handled by the
1295 * In short, for most people, this function should be a nop (unless
1296 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1297 * them lately, but just to get this code right). Even so, it doesn't
1298 * appear to be so. It's being worked on...
1301 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1302 * Original implementation (based on NC_DrawFrame)
1303 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1306 *****************************************************************************/
1308 static void NC_DrawFrame95(
1318 width
= sysMetrics
[SM_CXDLGFRAME
] - sysMetrics
[SM_CXEDGE
];
1319 height
= sysMetrics
[SM_CYDLGFRAME
] - sysMetrics
[SM_CYEDGE
];
1323 width
= sysMetrics
[SM_CXFRAME
] - sysMetrics
[SM_CXEDGE
];
1324 height
= sysMetrics
[SM_CYFRAME
] - sysMetrics
[SM_CYEDGE
];
1327 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1328 COLOR_INACTIVEBORDER
) );
1331 PatBlt( hdc
, rect
->left
, rect
->top
,
1332 rect
->right
- rect
->left
, height
, PATCOPY
);
1333 PatBlt( hdc
, rect
->left
, rect
->top
,
1334 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1335 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1336 rect
->right
- rect
->left
, -height
, PATCOPY
);
1337 PatBlt( hdc
, rect
->right
- 1, rect
->top
- 1,
1338 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1340 InflateRect( rect
, -width
, -height
);
1343 /***********************************************************************
1344 * NC_DrawMovingFrame
1346 * Draw the frame used when moving or resizing window.
1348 * FIXME: This causes problems in Win95 mode. (why?)
1350 static void NC_DrawMovingFrame( HDC hdc
, RECT
*rect
, BOOL thickframe
)
1355 CONV_RECT32TO16( rect
, &r16
);
1356 FastWindowFrame16( hdc
, &r16
, SYSMETRICS_CXFRAME
,
1357 SYSMETRICS_CYFRAME
, PATINVERT
);
1359 else DrawFocusRect( hdc
, rect
);
1363 /***********************************************************************
1366 * Draw the window caption.
1367 * The correct pen for the window frame must be selected in the DC.
1369 static void NC_DrawCaption( HDC hdc
, RECT
*rect
, HWND hwnd
,
1370 DWORD style
, BOOL active
)
1373 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1376 if (wndPtr
->flags
& WIN_MANAGED
)
1378 WIN_ReleaseWndPtr(wndPtr
);
1384 if (!(hbitmapClose
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE
) )))
1386 WIN_ReleaseWndPtr(wndPtr
);
1389 hbitmapCloseD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED
) );
1390 hbitmapMinimize
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE
) );
1391 hbitmapMinimizeD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED
) );
1392 hbitmapMaximize
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM
) );
1393 hbitmapMaximizeD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD
) );
1394 hbitmapRestore
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE
) );
1395 hbitmapRestoreD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED
) );
1398 if (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
)
1400 HBRUSH hbrushOld
= SelectObject(hdc
, GetSysColorBrush(COLOR_WINDOW
) );
1401 PatBlt( hdc
, r
.left
, r
.top
, 1, r
.bottom
-r
.top
+1,PATCOPY
);
1402 PatBlt( hdc
, r
.right
-1, r
.top
, 1, r
.bottom
-r
.top
+1, PATCOPY
);
1403 PatBlt( hdc
, r
.left
, r
.top
-1, r
.right
-r
.left
, 1, PATCOPY
);
1406 SelectObject( hdc
, hbrushOld
);
1408 WIN_ReleaseWndPtr(wndPtr
);
1409 MoveTo16( hdc
, r
.left
, r
.bottom
);
1410 LineTo( hdc
, r
.right
, r
.bottom
);
1412 if (style
& WS_SYSMENU
)
1414 NC_DrawSysButton( hwnd
, hdc
, FALSE
);
1415 r
.left
+= SYSMETRICS_CXSIZE
+ 1;
1416 MoveTo16( hdc
, r
.left
- 1, r
.top
);
1417 LineTo( hdc
, r
.left
- 1, r
.bottom
);
1419 if (style
& WS_MAXIMIZEBOX
)
1421 NC_DrawMaxButton( hwnd
, hdc
, FALSE
);
1422 r
.right
-= SYSMETRICS_CXSIZE
+ 1;
1424 if (style
& WS_MINIMIZEBOX
)
1426 NC_DrawMinButton( hwnd
, hdc
, FALSE
);
1427 r
.right
-= SYSMETRICS_CXSIZE
+ 1;
1430 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1431 COLOR_INACTIVECAPTION
) );
1433 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) ))
1435 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1436 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1437 SetBkMode( hdc
, TRANSPARENT
);
1438 DrawTextA( hdc
, buffer
, -1, &r
,
1439 DT_SINGLELINE
| DT_CENTER
| DT_VCENTER
| DT_NOPREFIX
);
1444 /******************************************************************************
1453 * Draw the window caption for Win95 style windows.
1454 * The correct pen for the window frame must be selected in the DC.
1457 * Hey, a function that finally works! Well, almost.
1458 * It's being worked on.
1461 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1462 * Original implementation.
1463 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1466 *****************************************************************************/
1468 static void NC_DrawCaption95(
1477 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1481 if (wndPtr
->flags
& WIN_MANAGED
)
1483 WIN_ReleaseWndPtr(wndPtr
);
1486 WIN_ReleaseWndPtr(wndPtr
);
1488 hPrevPen
= SelectObject( hdc
, GetSysColorPen(COLOR_3DFACE
) );
1489 MoveToEx( hdc
, r
.left
, r
.bottom
- 1, NULL
);
1490 LineTo( hdc
, r
.right
, r
.bottom
- 1 );
1491 SelectObject( hdc
, hPrevPen
);
1494 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1495 COLOR_INACTIVECAPTION
) );
1497 if (!hbitmapClose
) {
1498 if (!(hbitmapClose
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE
) )))
1500 hbitmapCloseD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED
));
1501 hbitmapMinimize
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE
) );
1502 hbitmapMinimizeD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED
) );
1503 hbitmapMaximize
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM
) );
1504 hbitmapMaximizeD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD
) );
1505 hbitmapRestore
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE
) );
1506 hbitmapRestoreD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED
) );
1509 if ((style
& WS_SYSMENU
) && !(exStyle
& WS_EX_TOOLWINDOW
)) {
1510 if (NC_DrawSysButton95 (hwnd
, hdc
, FALSE
))
1511 r
.left
+= sysMetrics
[SM_CYCAPTION
] - 1;
1513 if (style
& WS_SYSMENU
) {
1514 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
);
1515 r
.right
-= sysMetrics
[SM_CYCAPTION
] - 1;
1517 if (style
& WS_MAXIMIZEBOX
) {
1518 NC_DrawMaxButton95( hwnd
, hdc
, FALSE
);
1519 r
.right
-= SYSMETRICS_CXSIZE
+ 1;
1521 if (style
& WS_MINIMIZEBOX
) {
1522 NC_DrawMinButton95( hwnd
, hdc
, FALSE
);
1523 r
.right
-= SYSMETRICS_CXSIZE
+ 1;
1526 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) )) {
1527 NONCLIENTMETRICSA nclm
;
1528 HFONT hFont
, hOldFont
;
1529 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
1530 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
1531 if (exStyle
& WS_EX_TOOLWINDOW
)
1532 hFont
= CreateFontIndirectA (&nclm
.lfSmCaptionFont
);
1534 hFont
= CreateFontIndirectA (&nclm
.lfCaptionFont
);
1535 hOldFont
= SelectObject (hdc
, hFont
);
1536 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1537 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1538 SetBkMode( hdc
, TRANSPARENT
);
1540 DrawTextA( hdc
, buffer
, -1, &r
,
1541 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
1542 DeleteObject (SelectObject (hdc
, hOldFont
));
1548 /***********************************************************************
1551 * Paint the non-client area. clip is currently unused.
1553 void NC_DoNCPaint( WND
* wndPtr
, HRGN clip
, BOOL suppress_menupaint
)
1558 HWND hwnd
= wndPtr
->hwndSelf
;
1560 if ( wndPtr
->dwStyle
& WS_MINIMIZE
||
1561 !WIN_IsWindowDrawable( wndPtr
, 0 )) return; /* Nothing to do */
1563 active
= wndPtr
->flags
& WIN_NCACTIVATED
;
1565 TRACE(nonclient
, "%04x %d\n", hwnd
, active
);
1567 if (!(hdc
= GetDCEx( hwnd
, (clip
> 1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
1568 ((clip
> 1) ? (DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
): 0) ))) return;
1570 if (ExcludeVisRect16( hdc
, wndPtr
->rectClient
.left
-wndPtr
->rectWindow
.left
,
1571 wndPtr
->rectClient
.top
-wndPtr
->rectWindow
.top
,
1572 wndPtr
->rectClient
.right
-wndPtr
->rectWindow
.left
,
1573 wndPtr
->rectClient
.bottom
-wndPtr
->rectWindow
.top
)
1576 ReleaseDC( hwnd
, hdc
);
1580 rect
.top
= rect
.left
= 0;
1581 rect
.right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
1582 rect
.bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
1584 SelectObject( hdc
, GetSysColorPen(COLOR_WINDOWFRAME
) );
1586 if (!(wndPtr
->flags
& WIN_MANAGED
))
1588 if ((wndPtr
->dwStyle
& WS_BORDER
) || (wndPtr
->dwStyle
& WS_DLGFRAME
) ||
1589 (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
))
1591 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1592 Rectangle( hdc
, 0, 0, rect
.right
, rect
.bottom
);
1593 InflateRect( &rect
, -1, -1 );
1596 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1597 NC_DrawFrame( hdc
, &rect
, TRUE
, active
);
1598 else if (wndPtr
->dwStyle
& WS_THICKFRAME
)
1599 NC_DrawFrame(hdc
, &rect
, FALSE
, active
);
1601 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1604 r
.bottom
= rect
.top
+ SYSMETRICS_CYSIZE
;
1605 rect
.top
+= SYSMETRICS_CYSIZE
+ SYSMETRICS_CYBORDER
;
1606 NC_DrawCaption( hdc
, &r
, hwnd
, wndPtr
->dwStyle
, active
);
1610 if (HAS_MENU(wndPtr
))
1613 r
.bottom
= rect
.top
+ SYSMETRICS_CYMENU
; /* default height */
1614 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
);
1617 /* Draw the scroll-bars */
1619 if (wndPtr
->dwStyle
& WS_VSCROLL
)
1620 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1621 if (wndPtr
->dwStyle
& WS_HSCROLL
)
1622 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1624 /* Draw the "size-box" */
1626 if ((wndPtr
->dwStyle
& WS_VSCROLL
) && (wndPtr
->dwStyle
& WS_HSCROLL
))
1629 r
.left
= r
.right
- SYSMETRICS_CXVSCROLL
+ 1;
1630 r
.top
= r
.bottom
- SYSMETRICS_CYHSCROLL
+ 1;
1631 if(wndPtr
->dwStyle
& WS_BORDER
) {
1635 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1638 ReleaseDC( hwnd
, hdc
);
1642 /******************************************************************************
1644 * void NC_DoNCPaint95(
1647 * BOOL32 suppress_menupaint )
1649 * Paint the non-client area for Win95 windows. The clip region is
1650 * currently ignored.
1653 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1654 * misc/tweak.c controls/menu.c # :-)
1657 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1658 * Original implementation
1659 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1662 *****************************************************************************/
1664 void NC_DoNCPaint95(
1667 BOOL suppress_menupaint
)
1670 RECT rfuzz
, rect
, rectClip
;
1672 HWND hwnd
= wndPtr
->hwndSelf
;
1674 if ( wndPtr
->dwStyle
& WS_MINIMIZE
||
1675 !WIN_IsWindowDrawable( wndPtr
, 0 )) return; /* Nothing to do */
1677 active
= wndPtr
->flags
& WIN_NCACTIVATED
;
1679 TRACE(nonclient
, "%04x %d\n", hwnd
, active
);
1681 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in the call to
1682 * GetDCEx implying that it is allowed not to use it either. However, the suggested
1683 * GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN) will cause clipRgn to be deleted
1684 * after ReleaseDC(). Now, how is the "system" supposed to tell what happened?
1687 if (!(hdc
= GetDCEx( hwnd
, (clip
> 1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
1688 ((clip
> 1) ?(DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
) : 0) ))) return;
1691 if (ExcludeVisRect16( hdc
, wndPtr
->rectClient
.left
-wndPtr
->rectWindow
.left
,
1692 wndPtr
->rectClient
.top
-wndPtr
->rectWindow
.top
,
1693 wndPtr
->rectClient
.right
-wndPtr
->rectWindow
.left
,
1694 wndPtr
->rectClient
.bottom
-wndPtr
->rectWindow
.top
)
1697 ReleaseDC( hwnd
, hdc
);
1701 rect
.top
= rect
.left
= 0;
1702 rect
.right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
1703 rect
.bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
1706 GetRgnBox( clip
, &rectClip
);
1713 SelectObject( hdc
, GetSysColorPen(COLOR_WINDOWFRAME
) );
1715 if(!(wndPtr
->flags
& WIN_MANAGED
)) {
1716 if ((wndPtr
->dwStyle
& WS_BORDER
) && ((wndPtr
->dwStyle
& WS_DLGFRAME
) ||
1717 (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
) || (wndPtr
->dwStyle
& WS_THICKFRAME
))) {
1718 DrawEdge (hdc
, &rect
, EDGE_RAISED
, BF_RECT
| BF_ADJUST
);
1721 if (HAS_FIXEDFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1722 NC_DrawFrame95( hdc
, &rect
, TRUE
, active
);
1723 else if (wndPtr
->dwStyle
& WS_THICKFRAME
)
1724 NC_DrawFrame95(hdc
, &rect
, FALSE
, active
);
1726 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1729 if (wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
) {
1730 r
.bottom
= rect
.top
+ sysMetrics
[SM_CYSMCAPTION
];
1731 rect
.top
+= sysMetrics
[SM_CYSMCAPTION
];
1734 r
.bottom
= rect
.top
+ sysMetrics
[SM_CYCAPTION
];
1735 rect
.top
+= sysMetrics
[SM_CYCAPTION
];
1737 if( !clip
|| IntersectRect( &rfuzz
, &r
, &rectClip
) )
1738 NC_DrawCaption95 (hdc
, &r
, hwnd
, wndPtr
->dwStyle
,
1739 wndPtr
->dwExStyle
, active
);
1743 if (HAS_MENU(wndPtr
))
1746 r
.bottom
= rect
.top
+ sysMetrics
[SM_CYMENU
];
1748 TRACE(nonclient
, "Calling DrawMenuBar with "
1749 "rect (%d, %d)-(%d, %d)\n", r
.left
, r
.top
,
1752 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
) + 1;
1755 TRACE(nonclient
, "After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1756 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1758 if (wndPtr
->dwExStyle
& WS_EX_CLIENTEDGE
)
1759 DrawEdge (hdc
, &rect
, EDGE_SUNKEN
, BF_RECT
| BF_ADJUST
);
1761 if (wndPtr
->dwExStyle
& WS_EX_STATICEDGE
)
1762 DrawEdge (hdc
, &rect
, BDR_SUNKENOUTER
, BF_RECT
| BF_ADJUST
);
1764 /* Draw the scroll-bars */
1766 if (wndPtr
->dwStyle
& WS_VSCROLL
)
1767 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1768 if (wndPtr
->dwStyle
& WS_HSCROLL
)
1769 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1771 /* Draw the "size-box" */
1772 if ((wndPtr
->dwStyle
& WS_VSCROLL
) && (wndPtr
->dwStyle
& WS_HSCROLL
))
1775 r
.left
= r
.right
- SYSMETRICS_CXVSCROLL
+ 1;
1776 r
.top
= r
.bottom
- SYSMETRICS_CYHSCROLL
+ 1;
1777 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1780 ReleaseDC( hwnd
, hdc
);
1786 /***********************************************************************
1789 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1791 LONG
NC_HandleNCPaint( HWND hwnd
, HRGN clip
)
1793 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1795 if( wndPtr
&& wndPtr
->dwStyle
& WS_VISIBLE
)
1797 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
1798 WINPOS_RedrawIconTitle( hwnd
);
1799 else if (TWEAK_WineLook
== WIN31_LOOK
)
1800 NC_DoNCPaint( wndPtr
, clip
, FALSE
);
1802 NC_DoNCPaint95( wndPtr
, clip
, FALSE
);
1804 WIN_ReleaseWndPtr(wndPtr
);
1809 /***********************************************************************
1810 * NC_HandleNCActivate
1812 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1814 LONG
NC_HandleNCActivate( WND
*wndPtr
, WPARAM16 wParam
)
1818 if( wParam
) wStateChange
= !(wndPtr
->flags
& WIN_NCACTIVATED
);
1819 else wStateChange
= wndPtr
->flags
& WIN_NCACTIVATED
;
1823 if (wParam
) wndPtr
->flags
|= WIN_NCACTIVATED
;
1824 else wndPtr
->flags
&= ~WIN_NCACTIVATED
;
1826 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
1827 WINPOS_RedrawIconTitle( wndPtr
->hwndSelf
);
1828 else if (TWEAK_WineLook
== WIN31_LOOK
)
1829 NC_DoNCPaint( wndPtr
, (HRGN
)1, FALSE
);
1831 NC_DoNCPaint95( wndPtr
, (HRGN
)1, FALSE
);
1837 /***********************************************************************
1838 * NC_HandleSetCursor
1840 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1842 LONG
NC_HandleSetCursor( HWND hwnd
, WPARAM16 wParam
, LPARAM lParam
)
1844 if (hwnd
!= (HWND
)wParam
) return 0; /* Don't set the cursor for child windows */
1846 switch(LOWORD(lParam
))
1850 WORD msg
= HIWORD( lParam
);
1851 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_MBUTTONDOWN
) ||
1852 (msg
== WM_RBUTTONDOWN
))
1862 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) break;
1863 if (wndPtr
->class->hCursor
)
1865 SetCursor16( wndPtr
->class->hCursor
);
1868 else retvalue
= FALSE
;
1869 WIN_ReleaseWndPtr(wndPtr
);
1875 return (LONG
)SetCursor16( LoadCursor16( 0, IDC_SIZEWE16
) );
1879 return (LONG
)SetCursor16( LoadCursor16( 0, IDC_SIZENS16
) );
1883 return (LONG
)SetCursor16( LoadCursor16( 0, IDC_SIZENWSE16
) );
1887 return (LONG
)SetCursor16( LoadCursor16( 0, IDC_SIZENESW16
) );
1890 /* Default cursor: arrow */
1891 return (LONG
)SetCursor16( LoadCursor16( 0, IDC_ARROW16
) );
1894 /***********************************************************************
1897 BOOL
NC_GetSysPopupPos( WND
* wndPtr
, RECT
* rect
)
1899 if( wndPtr
->hSysMenu
)
1901 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
1902 GetWindowRect( wndPtr
->hwndSelf
, rect
);
1905 if (TWEAK_WineLook
== WIN31_LOOK
)
1906 NC_GetInsideRect( wndPtr
->hwndSelf
, rect
);
1908 NC_GetInsideRect95( wndPtr
->hwndSelf
, rect
);
1909 OffsetRect( rect
, wndPtr
->rectWindow
.left
, wndPtr
->rectWindow
.top
);
1910 if (wndPtr
->dwStyle
& WS_CHILD
)
1911 ClientToScreen( wndPtr
->parent
->hwndSelf
, (POINT
*)rect
);
1912 if (TWEAK_WineLook
== WIN31_LOOK
) {
1913 rect
->right
= rect
->left
+ SYSMETRICS_CXSIZE
;
1914 rect
->bottom
= rect
->top
+ SYSMETRICS_CYSIZE
;
1917 rect
->right
= rect
->left
+ sysMetrics
[SM_CYCAPTION
] - 1;
1918 rect
->bottom
= rect
->top
+ sysMetrics
[SM_CYCAPTION
] - 1;
1926 /***********************************************************************
1929 * Initialisation of a move or resize, when initiatied from a menu choice.
1930 * Return hit test code for caption or sizing border.
1932 static LONG
NC_StartSizeMove( WND
* wndPtr
, WPARAM16 wParam
,
1933 POINT16
*capturePoint
)
1939 if ((wParam
& 0xfff0) == SC_MOVE
)
1941 /* Move pointer at the center of the caption */
1943 if (TWEAK_WineLook
== WIN31_LOOK
)
1944 NC_GetInsideRect( wndPtr
->hwndSelf
, &rect
);
1946 NC_GetInsideRect95( wndPtr
->hwndSelf
, &rect
);
1947 if (wndPtr
->dwStyle
& WS_SYSMENU
)
1948 rect
.left
+= SYSMETRICS_CXSIZE
+ 1;
1949 if (wndPtr
->dwStyle
& WS_MINIMIZEBOX
)
1950 rect
.right
-= SYSMETRICS_CXSIZE
+ 1;
1951 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
1952 rect
.right
-= SYSMETRICS_CXSIZE
+ 1;
1953 pt
.x
= wndPtr
->rectWindow
.left
+ (rect
.right
- rect
.left
) / 2;
1954 pt
.y
= wndPtr
->rectWindow
.top
+ rect
.top
+ SYSMETRICS_CYSIZE
/2;
1955 hittest
= HTCAPTION
;
1962 MSG_InternalGetMessage( &msg
, 0, 0, MSGF_SIZE
, PM_REMOVE
, FALSE
);
1966 CONV_POINT32TO16(&msg
.pt
, &pt
);
1967 hittest
= NC_HandleNCHitTest( wndPtr
->hwndSelf
, pt
);
1968 if ((hittest
< HTLEFT
) || (hittest
> HTBOTTOMRIGHT
))
1980 pt
.x
=(wndPtr
->rectWindow
.left
+wndPtr
->rectWindow
.right
)/2;
1981 pt
.y
= wndPtr
->rectWindow
.top
+ SYSMETRICS_CYFRAME
/ 2;
1985 pt
.x
=(wndPtr
->rectWindow
.left
+wndPtr
->rectWindow
.right
)/2;
1986 pt
.y
= wndPtr
->rectWindow
.bottom
- SYSMETRICS_CYFRAME
/ 2;
1990 pt
.x
= wndPtr
->rectWindow
.left
+ SYSMETRICS_CXFRAME
/ 2;
1991 pt
.y
=(wndPtr
->rectWindow
.top
+wndPtr
->rectWindow
.bottom
)/2;
1995 pt
.x
= wndPtr
->rectWindow
.right
- SYSMETRICS_CXFRAME
/ 2;
1996 pt
.y
=(wndPtr
->rectWindow
.top
+wndPtr
->rectWindow
.bottom
)/2;
1999 case VK_ESCAPE
: return 0;
2005 SetCursorPos( pt
.x
, pt
.y
);
2006 NC_HandleSetCursor( wndPtr
->hwndSelf
,
2007 wndPtr
->hwndSelf
, MAKELONG( hittest
, WM_MOUSEMOVE
));
2012 /***********************************************************************
2015 * Perform SC_MOVE and SC_SIZE commands. `
2017 static void NC_DoSizeMove( HWND hwnd
, WORD wParam
)
2020 RECT sizingRect
, mouseRect
;
2022 LONG hittest
= (LONG
)(wParam
& 0x0f);
2023 HCURSOR16 hDragCursor
= 0, hOldCursor
= 0;
2024 POINT minTrack
, maxTrack
;
2025 POINT16 capturePoint
, pt
;
2026 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
2027 BOOL thickframe
= HAS_THICKFRAME( wndPtr
->dwStyle
);
2028 BOOL iconic
= wndPtr
->dwStyle
& WS_MINIMIZE
;
2030 DWORD dwPoint
= GetMessagePos ();
2032 capturePoint
= pt
= *(POINT16
*)&dwPoint
;
2034 if (IsZoomed(hwnd
) || !IsWindowVisible(hwnd
) ||
2035 (wndPtr
->flags
& WIN_MANAGED
)) goto END
;
2037 if ((wParam
& 0xfff0) == SC_MOVE
)
2039 if (!(wndPtr
->dwStyle
& WS_CAPTION
)) goto END
;
2041 hittest
= NC_StartSizeMove( wndPtr
, wParam
, &capturePoint
);
2042 if (!hittest
) goto END
;
2046 if (!thickframe
) goto END
;
2047 if ( hittest
&& hittest
!= HTSYSMENU
) hittest
+= 2;
2051 hittest
= NC_StartSizeMove( wndPtr
, wParam
, &capturePoint
);
2060 /* Get min/max info */
2062 WINPOS_GetMinMaxInfo( wndPtr
, NULL
, NULL
, &minTrack
, &maxTrack
);
2063 sizingRect
= wndPtr
->rectWindow
;
2064 if (wndPtr
->dwStyle
& WS_CHILD
)
2065 GetClientRect( wndPtr
->parent
->hwndSelf
, &mouseRect
);
2067 SetRect(&mouseRect
, 0, 0, SYSMETRICS_CXSCREEN
, SYSMETRICS_CYSCREEN
);
2068 if (ON_LEFT_BORDER(hittest
))
2070 mouseRect
.left
= MAX( mouseRect
.left
, sizingRect
.right
-maxTrack
.x
);
2071 mouseRect
.right
= MIN( mouseRect
.right
, sizingRect
.right
-minTrack
.x
);
2073 else if (ON_RIGHT_BORDER(hittest
))
2075 mouseRect
.left
= MAX( mouseRect
.left
, sizingRect
.left
+minTrack
.x
);
2076 mouseRect
.right
= MIN( mouseRect
.right
, sizingRect
.left
+maxTrack
.x
);
2078 if (ON_TOP_BORDER(hittest
))
2080 mouseRect
.top
= MAX( mouseRect
.top
, sizingRect
.bottom
-maxTrack
.y
);
2081 mouseRect
.bottom
= MIN( mouseRect
.bottom
,sizingRect
.bottom
-minTrack
.y
);
2083 else if (ON_BOTTOM_BORDER(hittest
))
2085 mouseRect
.top
= MAX( mouseRect
.top
, sizingRect
.top
+minTrack
.y
);
2086 mouseRect
.bottom
= MIN( mouseRect
.bottom
, sizingRect
.top
+maxTrack
.y
);
2088 if (wndPtr
->dwStyle
& WS_CHILD
)
2090 MapWindowPoints( wndPtr
->parent
->hwndSelf
, 0,
2091 (LPPOINT
)&mouseRect
, 2 );
2093 SendMessage16( hwnd
, WM_ENTERSIZEMOVE
, 0, 0 );
2095 if (GetCapture() != hwnd
) SetCapture( hwnd
);
2097 if (wndPtr
->dwStyle
& WS_CHILD
)
2099 /* Retrieve a default cache DC (without using the window style) */
2100 hdc
= GetDCEx( wndPtr
->parent
->hwndSelf
, 0, DCX_CACHE
);
2103 { /* Grab the server only when moving top-level windows without desktop */
2107 wndPtr
->pDriver
->pPreSizeMove(wndPtr
);
2109 if( iconic
) /* create a cursor for dragging */
2111 HICON16 hIcon
= (wndPtr
->class->hIcon
) ? wndPtr
->class->hIcon
2112 : (HICON16
)SendMessage16( hwnd
, WM_QUERYDRAGICON
, 0, 0L);
2113 if( hIcon
) hDragCursor
= CURSORICON_IconToCursor( hIcon
, TRUE
);
2114 if( !hDragCursor
) iconic
= FALSE
;
2117 if( !iconic
) NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2123 MSG_InternalGetMessage( &msg
, 0, 0, MSGF_SIZE
, PM_REMOVE
, FALSE
);
2125 /* Exit on button-up, Return, or Esc */
2126 if ((msg
.message
== WM_LBUTTONUP
) ||
2127 ((msg
.message
== WM_KEYDOWN
) &&
2128 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
2130 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
2131 continue; /* We are not interested in other messages */
2133 dwPoint
= GetMessagePos ();
2134 pt
= *(POINT16
*)&dwPoint
;
2136 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
2138 case VK_UP
: pt
.y
-= 8; break;
2139 case VK_DOWN
: pt
.y
+= 8; break;
2140 case VK_LEFT
: pt
.x
-= 8; break;
2141 case VK_RIGHT
: pt
.x
+= 8; break;
2144 pt
.x
= MAX( pt
.x
, mouseRect
.left
);
2145 pt
.x
= MIN( pt
.x
, mouseRect
.right
);
2146 pt
.y
= MAX( pt
.y
, mouseRect
.top
);
2147 pt
.y
= MIN( pt
.y
, mouseRect
.bottom
);
2149 dx
= pt
.x
- capturePoint
.x
;
2150 dy
= pt
.y
- capturePoint
.y
;
2157 if( iconic
) /* ok, no system popup tracking */
2159 hOldCursor
= SetCursor(hDragCursor
);
2161 WINPOS_ShowIconTitle( wndPtr
, FALSE
);
2165 if (msg
.message
== WM_KEYDOWN
) SetCursorPos( pt
.x
, pt
.y
);
2168 RECT newRect
= sizingRect
;
2170 if (hittest
== HTCAPTION
) OffsetRect( &newRect
, dx
, dy
);
2171 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
2172 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
2173 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
2174 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
2177 NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2178 NC_DrawMovingFrame( hdc
, &newRect
, thickframe
);
2181 sizingRect
= newRect
;
2189 if( moved
) /* restore cursors, show icon title later on */
2191 ShowCursor( FALSE
);
2192 SetCursor( hOldCursor
);
2194 DestroyCursor( hDragCursor
);
2197 NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2199 if (wndPtr
->dwStyle
& WS_CHILD
)
2200 ReleaseDC( wndPtr
->parent
->hwndSelf
, hdc
);
2203 ReleaseDC( 0, hdc
);
2206 wndPtr
->pDriver
->pPostSizeMove(wndPtr
);
2208 if (HOOK_IsHooked( WH_CBT
))
2210 RECT16
* pr
= SEGPTR_NEW(RECT16
);
2213 CONV_RECT32TO16( &sizingRect
, pr
);
2214 if( HOOK_CallHooks16( WH_CBT
, HCBT_MOVESIZE
, hwnd
,
2215 (LPARAM
)SEGPTR_GET(pr
)) )
2216 sizingRect
= wndPtr
->rectWindow
;
2218 CONV_RECT16TO32( pr
, &sizingRect
);
2222 SendMessage16( hwnd
, WM_EXITSIZEMOVE
, 0, 0 );
2223 SendMessage16( hwnd
, WM_SETVISIBLE
, !IsIconic16(hwnd
), 0L);
2225 if( moved
&& !((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
2227 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
2228 SetWindowPos( hwnd
, 0, sizingRect
.left
, sizingRect
.top
,
2229 sizingRect
.right
- sizingRect
.left
,
2230 sizingRect
.bottom
- sizingRect
.top
,
2231 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
2234 if( IsWindow(hwnd
) )
2235 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
2237 /* Single click brings up the system menu when iconized */
2241 if( wndPtr
->dwStyle
& WS_SYSMENU
)
2242 SendMessage16( hwnd
, WM_SYSCOMMAND
,
2243 SC_MOUSEMENU
+ HTSYSMENU
, *((LPARAM
*)&pt
));
2245 else WINPOS_ShowIconTitle( wndPtr
, TRUE
);
2249 WIN_ReleaseWndPtr(wndPtr
);
2253 /***********************************************************************
2256 * Track a mouse button press on the minimize or maximize box.
2258 static void NC_TrackMinMaxBox( HWND hwnd
, WORD wParam
)
2262 HDC hdc
= GetWindowDC( hwnd
);
2263 BOOL pressed
= TRUE
;
2264 void (*paintButton
)(HWND
, HDC16
, BOOL
);
2267 if (wParam
== HTMINBUTTON
)
2269 (TWEAK_WineLook
== WIN31_LOOK
) ? &NC_DrawMinButton
: &NC_DrawMinButton95
;
2272 (TWEAK_WineLook
== WIN31_LOOK
) ? &NC_DrawMaxButton
: &NC_DrawMaxButton95
;
2274 (*paintButton
)( hwnd
, hdc
, TRUE
);
2278 BOOL oldstate
= pressed
;
2279 MSG_InternalGetMessage( &msg
, 0, 0, 0, PM_REMOVE
, FALSE
);
2280 CONV_POINT32TO16( &msg
.pt
, &pt16
);
2282 pressed
= (NC_HandleNCHitTest( hwnd
, pt16
) == wParam
);
2283 if (pressed
!= oldstate
)
2284 (*paintButton
)( hwnd
, hdc
, pressed
);
2285 } while (msg
.message
!= WM_LBUTTONUP
);
2287 (*paintButton
)( hwnd
, hdc
, FALSE
);
2290 ReleaseDC( hwnd
, hdc
);
2291 if (!pressed
) return;
2293 if (wParam
== HTMINBUTTON
)
2294 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, *(LONG
*)&pt16
);
2296 SendMessage16( hwnd
, WM_SYSCOMMAND
,
2297 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, *(LONG
*)&pt16
);
2301 /***********************************************************************
2302 * NC_TrackCloseButton95
2304 * Track a mouse button press on the Win95 close button.
2307 NC_TrackCloseButton95 (HWND hwnd
, WORD wParam
)
2311 HDC hdc
= GetWindowDC( hwnd
);
2312 BOOL pressed
= TRUE
;
2316 NC_DrawCloseButton95 (hwnd
, hdc
, TRUE
);
2320 BOOL oldstate
= pressed
;
2321 MSG_InternalGetMessage( &msg
, 0, 0, 0, PM_REMOVE
, FALSE
);
2322 CONV_POINT32TO16( &msg
.pt
, &pt16
);
2324 pressed
= (NC_HandleNCHitTest( hwnd
, pt16
) == wParam
);
2325 if (pressed
!= oldstate
)
2326 NC_DrawCloseButton95 (hwnd
, hdc
, pressed
);
2327 } while (msg
.message
!= WM_LBUTTONUP
);
2329 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
);
2332 ReleaseDC( hwnd
, hdc
);
2333 if (!pressed
) return;
2335 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, *(LONG
*)&pt16
);
2339 /***********************************************************************
2342 * Track a mouse button press on the horizontal or vertical scroll-bar.
2344 static void NC_TrackScrollBar( HWND hwnd
, WPARAM wParam
, POINT pt
)
2348 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
2350 if ((wParam
& 0xfff0) == SC_HSCROLL
)
2352 if ((wParam
& 0x0f) != HTHSCROLL
) goto END
;
2353 scrollbar
= SB_HORZ
;
2355 else /* SC_VSCROLL */
2357 if ((wParam
& 0x0f) != HTVSCROLL
) goto END
;
2358 scrollbar
= SB_VERT
;
2361 if (!(msg
= SEGPTR_NEW(MSG16
))) goto END
;
2362 pt
.x
-= wndPtr
->rectWindow
.left
;
2363 pt
.y
-= wndPtr
->rectWindow
.top
;
2365 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, WM_LBUTTONDOWN
, pt
);
2369 GetMessage16( SEGPTR_GET(msg
), 0, 0, 0 );
2370 switch(msg
->message
)
2375 pt
.x
= LOWORD(msg
->lParam
) + wndPtr
->rectClient
.left
-
2376 wndPtr
->rectWindow
.left
;
2377 pt
.y
= HIWORD(msg
->lParam
) + wndPtr
->rectClient
.top
-
2378 wndPtr
->rectWindow
.top
;
2379 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, msg
->message
, pt
);
2382 TranslateMessage16( msg
);
2383 DispatchMessage16( msg
);
2386 if (!IsWindow( hwnd
))
2391 } while (msg
->message
!= WM_LBUTTONUP
);
2394 WIN_ReleaseWndPtr(wndPtr
);
2397 /***********************************************************************
2398 * NC_HandleNCLButtonDown
2400 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2402 LONG
NC_HandleNCLButtonDown( WND
* pWnd
, WPARAM16 wParam
, LPARAM lParam
)
2404 HWND hwnd
= pWnd
->hwndSelf
;
2406 switch(wParam
) /* Hit test */
2409 hwnd
= WIN_GetTopParent(hwnd
);
2411 if( WINPOS_SetActiveWindow(hwnd
, TRUE
, TRUE
) || (GetActiveWindow() == hwnd
) )
2412 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_MOVE
+ HTCAPTION
, lParam
);
2416 if( pWnd
->dwStyle
& WS_SYSMENU
)
2418 if( !(pWnd
->dwStyle
& WS_MINIMIZE
) )
2420 HDC hDC
= GetWindowDC(hwnd
);
2421 if (TWEAK_WineLook
== WIN31_LOOK
)
2422 NC_DrawSysButton( hwnd
, hDC
, TRUE
);
2424 NC_DrawSysButton95( hwnd
, hDC
, TRUE
);
2425 ReleaseDC( hwnd
, hDC
);
2427 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
+ HTSYSMENU
, lParam
);
2432 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
, lParam
);
2436 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
2440 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
2445 NC_TrackMinMaxBox( hwnd
, wParam
);
2449 if (TWEAK_WineLook
>= WIN95_LOOK
)
2450 NC_TrackCloseButton95 (hwnd
, wParam
);
2461 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2462 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_SIZE
+ wParam
- 2, lParam
);
2472 /***********************************************************************
2473 * NC_HandleNCLButtonDblClk
2475 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2477 LONG
NC_HandleNCLButtonDblClk( WND
*pWnd
, WPARAM16 wParam
, LPARAM lParam
)
2480 * if this is an icon, send a restore since we are handling
2483 if (pWnd
->dwStyle
& WS_MINIMIZE
)
2485 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_RESTORE
, lParam
);
2489 switch(wParam
) /* Hit test */
2492 /* stop processing if WS_MAXIMIZEBOX is missing */
2493 if (pWnd
->dwStyle
& WS_MAXIMIZEBOX
)
2494 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
,
2495 (pWnd
->dwStyle
& WS_MAXIMIZE
) ? SC_RESTORE
: SC_MAXIMIZE
,
2500 if (!(pWnd
->class->style
& CS_NOCLOSE
))
2501 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_CLOSE
, lParam
);
2505 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
,
2510 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
,
2518 /***********************************************************************
2519 * NC_HandleSysCommand
2521 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2523 LONG
NC_HandleSysCommand( HWND hwnd
, WPARAM16 wParam
, POINT16 pt
)
2525 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
2527 UINT16 uCommand
= wParam
& 0xFFF0;
2529 TRACE(nonclient
, "Handling WM_SYSCOMMAND %x %d,%d\n",
2530 wParam
, pt
.x
, pt
.y
);
2532 if (wndPtr
->dwStyle
& WS_CHILD
&& uCommand
!= SC_KEYMENU
)
2533 ScreenToClient16( wndPtr
->parent
->hwndSelf
, &pt
);
2539 NC_DoSizeMove( hwnd
, wParam
);
2543 ShowWindow( hwnd
, SW_MINIMIZE
);
2547 ShowWindow( hwnd
, SW_MAXIMIZE
);
2551 ShowWindow( hwnd
, SW_RESTORE
);
2555 WIN_ReleaseWndPtr(wndPtr
);
2556 return SendMessage16( hwnd
, WM_CLOSE
, 0, 0 );
2560 CONV_POINT16TO32( &pt
, &pt32
);
2561 NC_TrackScrollBar( hwnd
, wParam
, pt32
);
2565 CONV_POINT16TO32( &pt
, &pt32
);
2566 MENU_TrackMouseMenuBar( wndPtr
, wParam
& 0x000F, pt32
);
2570 MENU_TrackKbdMenuBar( wndPtr
, wParam
, pt
.x
);
2574 WinExec( "taskman.exe", SW_SHOWNORMAL
);
2578 if (wParam
== SC_ABOUTWINE
)
2579 ShellAboutA(hwnd
,"Wine", WINE_RELEASE_INFO
, 0);
2581 if (wParam
== SC_PUTMARK
)
2582 TRACE(shell
,"Mark requested by user\n");
2589 FIXME (nonclient
, "unimplemented!\n");
2592 WIN_ReleaseWndPtr(wndPtr
);