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
, BOOL32 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
, BOOL32 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
)DrawCaptionTemp32A (hwnd
, hdc
, rect
? &rect32
: NULL
,
245 0, 0, NULL
, uFlags
& 0x1F);
249 /***********************************************************************
250 * DrawCaption32 [USER32.154] Draws a caption bar
264 DrawCaption32 (HWND32 hwnd
, HDC32 hdc
, const RECT32
*lpRect
, UINT32 uFlags
)
266 return DrawCaptionTemp32A (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
)DrawCaptionTemp32A (hwnd
, hdc
, rect
?&rect32
:NULL
, hFont
,
290 hIcon
, str
, uFlags
& 0x1F);
294 /***********************************************************************
295 * DrawCaptionTemp32A [USER32.599]
305 DrawCaptionTemp32A (HWND32 hwnd
, HDC32 hdc
, const RECT32
*rect
, HFONT32 hFont
,
306 HICON32 hIcon
, LPCSTR str
, UINT32 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 FillRect32 (hdc
, &rc
, GetSysColorBrush32 (COLOR_3DFACE
));
317 if (uFlags
& DC_ACTIVE
) {
318 HBRUSH32 hbr
= SelectObject32 (hdc
, CACHE_GetPattern55AABrush ());
319 PatBlt32 (hdc
, rc
.left
, rc
.top
,
320 rc
.right
-rc
.left
, rc
.bottom
-rc
.top
, 0xFA0089);
321 SelectObject32 (hdc
, hbr
);
325 FillRect32 (hdc
, &rc
, GetSysColorBrush32 ((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 DrawIconEx32 (hdc
, pt
.x
, pt
.y
, hIcon
, sysMetrics
[SM_CXSMICON
],
339 sysMetrics
[SM_CYSMICON
], 0, 0, DI_NORMAL
);
342 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
343 HICON32 hAppIcon
= 0;
345 if (wndPtr
->class->hIconSm
)
346 hAppIcon
= wndPtr
->class->hIconSm
;
347 else if (wndPtr
->class->hIcon
)
348 hAppIcon
= wndPtr
->class->hIcon
;
350 DrawIconEx32 (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 SetTextColor32 (hdc
, GetSysColor32 (COLOR_BTNTEXT
));
363 else if (uFlags
& DC_ACTIVE
)
364 SetTextColor32 (hdc
, GetSysColor32 (COLOR_CAPTIONTEXT
));
366 SetTextColor32 (hdc
, GetSysColor32 (COLOR_INACTIVECAPTIONTEXT
));
368 SetBkMode32 (hdc
, TRANSPARENT
);
371 hOldFont
= SelectObject32 (hdc
, hFont
);
373 NONCLIENTMETRICS32A nclm
;
375 nclm
.cbSize
= sizeof(NONCLIENTMETRICS32A
);
376 SystemParametersInfo32A (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
377 hNewFont
= CreateFontIndirect32A ((uFlags
& DC_SMALLCAP
) ?
378 &nclm
.lfSmCaptionFont
: &nclm
.lfCaptionFont
);
379 hOldFont
= SelectObject32 (hdc
, hNewFont
);
383 DrawText32A (hdc
, str
, -1, &rc
,
384 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
388 nLen
= GetWindowText32A (hwnd
, szText
, 128);
389 DrawText32A (hdc
, szText
, nLen
, &rc
,
390 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
394 SelectObject32 (hdc
, hOldFont
);
396 DeleteObject32 (SelectObject32 (hdc
, hOldFont
));
399 /* drawing focus ??? */
401 FIXME (nonclient
, "undocumented flag (0x2000)!\n");
407 /***********************************************************************
408 * DrawCaptionTemp32W [USER32.602]
418 DrawCaptionTemp32W (HWND32 hwnd
, HDC32 hdc
, const RECT32
*rect
, HFONT32 hFont
,
419 HICON32 hIcon
, LPCWSTR str
, UINT32 uFlags
)
421 LPSTR p
= HEAP_strdupWtoA (GetProcessHeap (), 0, str
);
422 BOOL32 res
= DrawCaptionTemp32A (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 BOOL32 WINAPI
AdjustWindowRect32( LPRECT32 rect
, DWORD style
, BOOL32 menu
)
442 return AdjustWindowRectEx32( 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 BOOL32 WINAPI
AdjustWindowRectEx32( LPRECT32 rect
, DWORD style
,
480 BOOL32 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
, RECT32
*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( HWND32 hwnd
, RECT32
*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 InflateRect32( rect
, -SYSMETRICS_CXDLGFRAME
, -SYSMETRICS_CYDLGFRAME
);
563 if (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
)
564 InflateRect32( rect
, -1, 0 );
568 if (HAS_THICKFRAME( wndPtr
->dwStyle
))
569 InflateRect32( rect
, -SYSMETRICS_CXFRAME
, -SYSMETRICS_CYFRAME
);
570 if (wndPtr
->dwStyle
& WS_BORDER
)
571 InflateRect32( 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 (HWND32 hwnd
, RECT32
*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 InflateRect32( rect
, -SYSMETRICS_CXFIXEDFRAME
, -SYSMETRICS_CYFIXEDFRAME
);
602 else if (HAS_SIZEFRAME (wndPtr
->dwStyle
))
604 InflateRect32( 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 InflateRect32 (rect
, -SYSMETRICS_CXEDGE
, -SYSMETRICS_CYEDGE
);
614 if (wndPtr
->dwExStyle
& WS_EX_STATICEDGE
)
615 InflateRect32 (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 (HWND32 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( HWND32 hwnd
, HDC32 hdc
, BOOL32 down
)
930 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
932 if( !(wndPtr
->flags
& WIN_MANAGED
) )
934 NC_GetInsideRect( hwnd
, &rect
);
935 hdcMem
= CreateCompatibleDC32( hdc
);
936 hbitmap
= SelectObject32( hdcMem
, hbitmapClose
);
937 BitBlt32(hdc
, rect
.left
, rect
.top
, SYSMETRICS_CXSIZE
, SYSMETRICS_CYSIZE
,
938 hdcMem
, (wndPtr
->dwStyle
& WS_CHILD
) ? SYSMETRICS_CXSIZE
: 0, 0,
939 down
? NOTSRCCOPY
: SRCCOPY
);
940 SelectObject32( hdcMem
, hbitmap
);
941 DeleteDC32( hdcMem
);
946 /***********************************************************************
949 static void NC_DrawMaxButton( HWND32 hwnd
, HDC16 hdc
, BOOL32 down
)
952 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
955 if( !(wndPtr
->flags
& WIN_MANAGED
) )
957 NC_GetInsideRect( hwnd
, &rect
);
958 hdcMem
= CreateCompatibleDC32( hdc
);
959 SelectObject32( hdcMem
, (IsZoomed32(hwnd
)
960 ? (down
? hbitmapRestoreD
: hbitmapRestore
)
961 : (down
? hbitmapMaximizeD
: hbitmapMaximize
)) );
962 BitBlt32( hdc
, rect
.right
- SYSMETRICS_CXSIZE
- 1, rect
.top
,
963 SYSMETRICS_CXSIZE
+ 1, SYSMETRICS_CYSIZE
, hdcMem
, 0, 0,
965 DeleteDC32( hdcMem
);
970 /***********************************************************************
973 static void NC_DrawMinButton( HWND32 hwnd
, HDC16 hdc
, BOOL32 down
)
976 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
979 if( !(wndPtr
->flags
& WIN_MANAGED
) )
981 NC_GetInsideRect( hwnd
, &rect
);
982 hdcMem
= CreateCompatibleDC32( hdc
);
983 SelectObject32( hdcMem
, (down
? hbitmapMinimizeD
: hbitmapMinimize
) );
984 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
) rect
.right
-= SYSMETRICS_CXSIZE
+1;
985 BitBlt32( hdc
, rect
.right
- SYSMETRICS_CXSIZE
- 1, rect
.top
,
986 SYSMETRICS_CXSIZE
+ 1, SYSMETRICS_CYSIZE
, hdcMem
, 0, 0,
988 DeleteDC32( hdcMem
);
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 (HWND32 hwnd
, HDC32 hdc
, BOOL32 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 DrawIconEx32 (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 (HWND32 hwnd
, HDC32 hdc
, BOOL32 down
)
1058 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1060 if( !(wndPtr
->flags
& WIN_MANAGED
) )
1063 HBITMAP32 hBmp
, hOldBmp
;
1065 NC_GetInsideRect95( hwnd
, &rect
);
1067 hdcMem
= CreateCompatibleDC32( hdc
);
1068 hBmp
= down
? hbitmapCloseD
: hbitmapClose
;
1069 hOldBmp
= SelectObject32 (hdcMem
, hBmp
);
1070 GetObject32A (hBmp
, sizeof(BITMAP32
), &bmp
);
1071 BitBlt32 (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 SelectObject32 (hdcMem
, hOldBmp
);
1076 DeleteDC32 (hdcMem
);
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(HWND32 hwnd
,HDC16 hdc
,BOOL32 down
)
1104 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1106 if( !(wndPtr
->flags
& WIN_MANAGED
))
1109 HBITMAP32 hBmp
,hOldBmp
;
1111 NC_GetInsideRect95( hwnd
, &rect
);
1112 hdcMem
= CreateCompatibleDC32( hdc
);
1113 hBmp
= IsZoomed32(hwnd
) ?
1114 (down
? hbitmapRestoreD
: hbitmapRestore
) :
1115 (down
? hbitmapMaximizeD
: hbitmapMaximize
);
1116 hOldBmp
=SelectObject32( hdcMem
, hBmp
);
1117 GetObject32A (hBmp
, sizeof(BITMAP32
), &bmp
);
1119 if (wndPtr
->dwStyle
& WS_SYSMENU
)
1120 rect
.right
-= sysMetrics
[SM_CYCAPTION
] + 1;
1122 BitBlt32( 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 SelectObject32 (hdcMem
, hOldBmp
);
1126 DeleteDC32( hdcMem
);
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(HWND32 hwnd
,HDC16 hdc
,BOOL32 down
)
1153 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1155 if( !(wndPtr
->flags
& WIN_MANAGED
))
1159 HBITMAP32 hBmp
,hOldBmp
;
1161 NC_GetInsideRect95( hwnd
, &rect
);
1163 hdcMem
= CreateCompatibleDC32( hdc
);
1164 hBmp
= down
? hbitmapMinimizeD
: hbitmapMinimize
;
1165 hOldBmp
= SelectObject32( hdcMem
, hBmp
);
1166 GetObject32A (hBmp
, sizeof(BITMAP32
), &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 BitBlt32( 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 SelectObject32 (hdcMem
, hOldBmp
);
1179 DeleteDC32( hdcMem
);
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( HDC32 hdc
, RECT32
*rect
, BOOL32 dlgFrame
,
1192 INT32 width
, height
;
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 SelectObject32( hdc
, GetSysColorBrush32(active
? COLOR_ACTIVECAPTION
:
1202 COLOR_INACTIVECAPTION
) );
1206 width
= SYSMETRICS_CXFRAME
- 1;
1207 height
= SYSMETRICS_CYFRAME
- 1;
1208 SelectObject32( hdc
, GetSysColorBrush32(active
? COLOR_ACTIVEBORDER
:
1209 COLOR_INACTIVEBORDER
) );
1213 PatBlt32( hdc
, rect
->left
, rect
->top
,
1214 rect
->right
- rect
->left
, height
, PATCOPY
);
1215 PatBlt32( hdc
, rect
->left
, rect
->top
,
1216 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1217 PatBlt32( hdc
, rect
->left
, rect
->bottom
,
1218 rect
->right
- rect
->left
, -height
, PATCOPY
);
1219 PatBlt32( hdc
, rect
->right
, rect
->top
,
1220 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1224 InflateRect32( rect
, -width
, -height
);
1228 INT32 decYOff
= SYSMETRICS_CXFRAME
+ SYSMETRICS_CXSIZE
;
1229 INT32 decXOff
= SYSMETRICS_CYFRAME
+ SYSMETRICS_CYSIZE
;
1231 /* Draw inner rectangle */
1233 SelectObject32( hdc
, GetStockObject32(NULL_BRUSH
) );
1234 Rectangle32( hdc
, rect
->left
+ width
, rect
->top
+ height
,
1235 rect
->right
- width
, rect
->bottom
- height
);
1237 /* Draw the decorations */
1239 MoveToEx32( hdc
, rect
->left
, rect
->top
+ decYOff
, NULL
);
1240 LineTo32( hdc
, rect
->left
+ width
, rect
->top
+ decYOff
);
1241 MoveToEx32( hdc
, rect
->right
- 1, rect
->top
+ decYOff
, NULL
);
1242 LineTo32( hdc
, rect
->right
- width
- 1, rect
->top
+ decYOff
);
1243 MoveToEx32( hdc
, rect
->left
, rect
->bottom
- decYOff
, NULL
);
1244 LineTo32( hdc
, rect
->left
+ width
, rect
->bottom
- decYOff
);
1245 MoveToEx32( hdc
, rect
->right
- 1, rect
->bottom
- decYOff
, NULL
);
1246 LineTo32( hdc
, rect
->right
- width
- 1, rect
->bottom
- decYOff
);
1248 MoveToEx32( hdc
, rect
->left
+ decXOff
, rect
->top
, NULL
);
1249 LineTo32( hdc
, rect
->left
+ decXOff
, rect
->top
+ height
);
1250 MoveToEx32( hdc
, rect
->left
+ decXOff
, rect
->bottom
- 1, NULL
);
1251 LineTo32( hdc
, rect
->left
+ decXOff
, rect
->bottom
- height
- 1 );
1252 MoveToEx32( hdc
, rect
->right
- decXOff
, rect
->top
, NULL
);
1253 LineTo32( hdc
, rect
->right
- decXOff
, rect
->top
+ height
);
1254 MoveToEx32( hdc
, rect
->right
- decXOff
, rect
->bottom
- 1, NULL
);
1255 LineTo32( hdc
, rect
->right
- decXOff
, rect
->bottom
- height
- 1 );
1257 InflateRect32( 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(
1298 INT32 width
, height
;
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 SelectObject32( hdc
, GetSysColorBrush32(active
? COLOR_ACTIVEBORDER
:
1312 COLOR_INACTIVEBORDER
) );
1315 PatBlt32( hdc
, rect
->left
, rect
->top
,
1316 rect
->right
- rect
->left
, height
, PATCOPY
);
1317 PatBlt32( hdc
, rect
->left
, rect
->top
,
1318 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1319 PatBlt32( hdc
, rect
->left
, rect
->bottom
,
1320 rect
->right
- rect
->left
, -height
, PATCOPY
);
1321 PatBlt32( hdc
, rect
->right
, rect
->top
,
1322 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1324 InflateRect32( 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( HDC32 hdc
, RECT32
*rect
, BOOL32 thickframe
)
1339 CONV_RECT32TO16( rect
, &r16
);
1340 FastWindowFrame( hdc
, &r16
, SYSMETRICS_CXFRAME
,
1341 SYSMETRICS_CYFRAME
, PATINVERT
);
1343 else DrawFocusRect32( 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( HDC32 hdc
, RECT32
*rect
, HWND32 hwnd
,
1354 DWORD style
, BOOL32 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_CLOSE
) );
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 HBRUSH32 hbrushOld
= SelectObject32(hdc
, GetSysColorBrush32(COLOR_WINDOW
) );
1378 PatBlt32( hdc
, r
.left
, r
.top
, 1, r
.bottom
-r
.top
+1,PATCOPY
);
1379 PatBlt32( hdc
, r
.right
-1, r
.top
, 1, r
.bottom
-r
.top
+1, PATCOPY
);
1380 PatBlt32( hdc
, r
.left
, r
.top
-1, r
.right
-r
.left
, 1, PATCOPY
);
1383 SelectObject32( hdc
, hbrushOld
);
1386 MoveTo( hdc
, r
.left
, r
.bottom
);
1387 LineTo32( hdc
, r
.right
, r
.bottom
);
1389 if (style
& WS_SYSMENU
)
1391 NC_DrawSysButton( hwnd
, hdc
, FALSE
);
1392 r
.left
+= SYSMETRICS_CXSIZE
+ 1;
1393 MoveTo( hdc
, r
.left
- 1, r
.top
);
1394 LineTo32( 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 FillRect32( hdc
, &r
, GetSysColorBrush32(active
? COLOR_ACTIVECAPTION
:
1408 COLOR_INACTIVECAPTION
) );
1410 if (GetWindowText32A( hwnd
, buffer
, sizeof(buffer
) ))
1412 if (active
) SetTextColor32( hdc
, GetSysColor32( COLOR_CAPTIONTEXT
) );
1413 else SetTextColor32( hdc
, GetSysColor32( COLOR_INACTIVECAPTIONTEXT
) );
1414 SetBkMode32( hdc
, TRANSPARENT
);
1415 DrawText32A( 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
= SelectObject32( hdc
, GetSysColorPen32(COLOR_3DFACE
) );
1461 MoveToEx32( hdc
, r
.left
, r
.bottom
- 1, NULL
);
1462 LineTo32( hdc
, r
.right
, r
.bottom
- 1 );
1463 SelectObject32( hdc
, hPrevPen
);
1466 FillRect32( hdc
, &r
, GetSysColorBrush32(active
? COLOR_ACTIVECAPTION
:
1467 COLOR_INACTIVECAPTION
) );
1469 if (!hbitmapClose
) {
1470 if (!(hbitmapClose
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE
) )))
1472 hbitmapMinimize
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE
) );
1473 hbitmapMinimizeD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED
) );
1474 hbitmapMaximize
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM
) );
1475 hbitmapMaximizeD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD
) );
1476 hbitmapRestore
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE
) );
1477 hbitmapRestoreD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED
) );
1480 if ((style
& WS_SYSMENU
) && !(exStyle
& WS_EX_TOOLWINDOW
)) {
1481 if (NC_DrawSysButton95 (hwnd
, hdc
, FALSE
))
1482 r
.left
+= sysMetrics
[SM_CYCAPTION
] - 1;
1484 if (style
& WS_SYSMENU
) {
1485 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
);
1486 r
.right
-= sysMetrics
[SM_CYCAPTION
] - 1;
1488 if (style
& WS_MAXIMIZEBOX
) {
1489 NC_DrawMaxButton95( hwnd
, hdc
, FALSE
);
1490 r
.right
-= SYSMETRICS_CXSIZE
+ 1;
1492 if (style
& WS_MINIMIZEBOX
) {
1493 NC_DrawMinButton95( hwnd
, hdc
, FALSE
);
1494 r
.right
-= SYSMETRICS_CXSIZE
+ 1;
1497 if (GetWindowText32A( hwnd
, buffer
, sizeof(buffer
) )) {
1498 NONCLIENTMETRICS32A nclm
;
1499 HFONT32 hFont
, hOldFont
;
1500 nclm
.cbSize
= sizeof(NONCLIENTMETRICS32A
);
1501 SystemParametersInfo32A (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
1502 if (exStyle
& WS_EX_TOOLWINDOW
)
1503 hFont
= CreateFontIndirect32A (&nclm
.lfSmCaptionFont
);
1505 hFont
= CreateFontIndirect32A (&nclm
.lfCaptionFont
);
1506 hOldFont
= SelectObject32 (hdc
, hFont
);
1507 if (active
) SetTextColor32( hdc
, GetSysColor32( COLOR_CAPTIONTEXT
) );
1508 else SetTextColor32( hdc
, GetSysColor32( COLOR_INACTIVECAPTIONTEXT
) );
1509 SetBkMode32( hdc
, TRANSPARENT
);
1511 DrawText32A( hdc
, buffer
, -1, &r
,
1512 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
1513 DeleteObject32 (SelectObject32 (hdc
, hOldFont
));
1519 /***********************************************************************
1522 * Paint the non-client area. clip is currently unused.
1524 void NC_DoNCPaint( WND
* wndPtr
, HRGN32 clip
, BOOL32 suppress_menupaint
)
1529 HWND32 hwnd
= wndPtr
->hwndSelf
;
1531 if ( wndPtr
->dwStyle
& WS_MINIMIZE
||
1532 !WIN_IsWindowDrawable( wndPtr
, 0 )) return; /* Nothing to do */
1534 active
= wndPtr
->flags
& WIN_NCACTIVATED
;
1536 TRACE(nonclient
, "%04x %d\n", hwnd
, active
);
1538 if (!(hdc
= GetDCEx32( hwnd
, 0, DCX_USESTYLE
| DCX_WINDOW
))) return;
1540 if (ExcludeVisRect( hdc
, wndPtr
->rectClient
.left
-wndPtr
->rectWindow
.left
,
1541 wndPtr
->rectClient
.top
-wndPtr
->rectWindow
.top
,
1542 wndPtr
->rectClient
.right
-wndPtr
->rectWindow
.left
,
1543 wndPtr
->rectClient
.bottom
-wndPtr
->rectWindow
.top
)
1546 ReleaseDC32( hwnd
, hdc
);
1550 rect
.top
= rect
.left
= 0;
1551 rect
.right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
1552 rect
.bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
1554 SelectObject32( hdc
, GetSysColorPen32(COLOR_WINDOWFRAME
) );
1556 if (!(wndPtr
->flags
& WIN_MANAGED
))
1558 if ((wndPtr
->dwStyle
& WS_BORDER
) || (wndPtr
->dwStyle
& WS_DLGFRAME
) ||
1559 (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
))
1561 SelectObject32( hdc
, GetStockObject32(NULL_BRUSH
) );
1562 Rectangle32( hdc
, 0, 0, rect
.right
, rect
.bottom
);
1563 InflateRect32( &rect
, -1, -1 );
1566 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1567 NC_DrawFrame( hdc
, &rect
, TRUE
, active
);
1568 else if (wndPtr
->dwStyle
& WS_THICKFRAME
)
1569 NC_DrawFrame(hdc
, &rect
, FALSE
, active
);
1571 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1574 r
.bottom
= rect
.top
+ SYSMETRICS_CYSIZE
;
1575 rect
.top
+= SYSMETRICS_CYSIZE
+ SYSMETRICS_CYBORDER
;
1576 NC_DrawCaption( hdc
, &r
, hwnd
, wndPtr
->dwStyle
, active
);
1580 if (HAS_MENU(wndPtr
))
1583 r
.bottom
= rect
.top
+ SYSMETRICS_CYMENU
; /* default height */
1584 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
);
1587 /* Draw the scroll-bars */
1589 if (wndPtr
->dwStyle
& WS_VSCROLL
)
1590 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1591 if (wndPtr
->dwStyle
& WS_HSCROLL
)
1592 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1594 /* Draw the "size-box" */
1596 if ((wndPtr
->dwStyle
& WS_VSCROLL
) && (wndPtr
->dwStyle
& WS_HSCROLL
))
1599 r
.left
= r
.right
- SYSMETRICS_CXVSCROLL
+ 1;
1600 r
.top
= r
.bottom
- SYSMETRICS_CYHSCROLL
+ 1;
1601 if(wndPtr
->dwStyle
& WS_BORDER
) {
1605 FillRect32( hdc
, &r
, GetSysColorBrush32(COLOR_SCROLLBAR
) );
1608 ReleaseDC32( hwnd
, hdc
);
1612 /******************************************************************************
1614 * void NC_DoNCPaint95(
1617 * BOOL32 suppress_menupaint )
1619 * Paint the non-client area for Win95 windows. The clip region is
1620 * currently ignored.
1623 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1624 * misc/tweak.c controls/menu.c # :-)
1627 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1628 * Original implementation
1629 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1632 *****************************************************************************/
1634 void NC_DoNCPaint95(
1637 BOOL32 suppress_menupaint
)
1642 HWND32 hwnd
= wndPtr
->hwndSelf
;
1644 if ( wndPtr
->dwStyle
& WS_MINIMIZE
||
1645 !WIN_IsWindowDrawable( wndPtr
, 0 )) return; /* Nothing to do */
1647 active
= wndPtr
->flags
& WIN_NCACTIVATED
;
1649 TRACE(nonclient
, "%04x %d\n", hwnd
, active
);
1651 if (!(hdc
= GetDCEx32( hwnd
, 0, DCX_USESTYLE
| DCX_WINDOW
))) return;
1653 if (ExcludeVisRect( hdc
, wndPtr
->rectClient
.left
-wndPtr
->rectWindow
.left
,
1654 wndPtr
->rectClient
.top
-wndPtr
->rectWindow
.top
,
1655 wndPtr
->rectClient
.right
-wndPtr
->rectWindow
.left
,
1656 wndPtr
->rectClient
.bottom
-wndPtr
->rectWindow
.top
)
1659 ReleaseDC32( hwnd
, hdc
);
1663 rect
.top
= rect
.left
= 0;
1664 rect
.right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
1665 rect
.bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
1667 SelectObject32( hdc
, GetSysColorPen32(COLOR_WINDOWFRAME
) );
1669 if(!(wndPtr
->flags
& WIN_MANAGED
)) {
1670 if ((wndPtr
->dwStyle
& WS_BORDER
) && ((wndPtr
->dwStyle
& WS_DLGFRAME
) ||
1671 (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
) || (wndPtr
->dwStyle
& WS_THICKFRAME
))) {
1672 DrawEdge32 (hdc
, &rect
, EDGE_RAISED
, BF_RECT
| BF_ADJUST
);
1675 if (HAS_FIXEDFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1676 NC_DrawFrame95( hdc
, &rect
, TRUE
, active
);
1677 else if (wndPtr
->dwStyle
& WS_THICKFRAME
)
1678 NC_DrawFrame95(hdc
, &rect
, FALSE
, active
);
1680 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1683 if (wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
) {
1684 r
.bottom
= rect
.top
+ sysMetrics
[SM_CYSMCAPTION
];
1685 rect
.top
+= sysMetrics
[SM_CYSMCAPTION
];
1688 r
.bottom
= rect
.top
+ sysMetrics
[SM_CYCAPTION
];
1689 rect
.top
+= sysMetrics
[SM_CYCAPTION
];
1691 NC_DrawCaption95 (hdc
, &r
, hwnd
, wndPtr
->dwStyle
,
1692 wndPtr
->dwExStyle
, active
);
1696 if (HAS_MENU(wndPtr
))
1699 r
.bottom
= rect
.top
+ sysMetrics
[SM_CYMENU
];
1701 TRACE(nonclient
, "Calling DrawMenuBar with "
1702 "rect (%d, %d)-(%d, %d)\n", r
.left
, r
.top
,
1705 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
) + 1;
1708 TRACE(nonclient
, "After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1709 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1711 if (wndPtr
->dwExStyle
& WS_EX_CLIENTEDGE
)
1712 DrawEdge32 (hdc
, &rect
, EDGE_SUNKEN
, BF_RECT
| BF_ADJUST
);
1714 if (wndPtr
->dwExStyle
& WS_EX_STATICEDGE
)
1715 DrawEdge32 (hdc
, &rect
, BDR_SUNKENOUTER
, BF_RECT
| BF_ADJUST
);
1717 /* Draw the scroll-bars */
1719 if (wndPtr
->dwStyle
& WS_VSCROLL
)
1720 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1721 if (wndPtr
->dwStyle
& WS_HSCROLL
)
1722 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1724 /* Draw the "size-box" */
1725 if ((wndPtr
->dwStyle
& WS_VSCROLL
) && (wndPtr
->dwStyle
& WS_HSCROLL
))
1728 r
.left
= r
.right
- SYSMETRICS_CXVSCROLL
+ 1;
1729 r
.top
= r
.bottom
- SYSMETRICS_CYHSCROLL
+ 1;
1730 FillRect32( hdc
, &r
, GetSysColorBrush32(COLOR_SCROLLBAR
) );
1733 ReleaseDC32( hwnd
, hdc
);
1739 /***********************************************************************
1742 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1744 LONG
NC_HandleNCPaint( HWND32 hwnd
, HRGN32 clip
)
1746 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1748 if( wndPtr
&& wndPtr
->dwStyle
& WS_VISIBLE
)
1750 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
1751 WINPOS_RedrawIconTitle( hwnd
);
1752 else if (TWEAK_WineLook
== WIN31_LOOK
)
1753 NC_DoNCPaint( wndPtr
, clip
, FALSE
);
1755 NC_DoNCPaint95( wndPtr
, clip
, FALSE
);
1761 /***********************************************************************
1762 * NC_HandleNCActivate
1764 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1766 LONG
NC_HandleNCActivate( WND
*wndPtr
, WPARAM16 wParam
)
1770 if( wParam
) wStateChange
= !(wndPtr
->flags
& WIN_NCACTIVATED
);
1771 else wStateChange
= wndPtr
->flags
& WIN_NCACTIVATED
;
1775 if (wParam
) wndPtr
->flags
|= WIN_NCACTIVATED
;
1776 else wndPtr
->flags
&= ~WIN_NCACTIVATED
;
1778 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
1779 WINPOS_RedrawIconTitle( wndPtr
->hwndSelf
);
1780 else if (TWEAK_WineLook
== WIN31_LOOK
)
1781 NC_DoNCPaint( wndPtr
, (HRGN32
)1, FALSE
);
1783 NC_DoNCPaint95( wndPtr
, (HRGN32
)1, FALSE
);
1789 /***********************************************************************
1790 * NC_HandleSetCursor
1792 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1794 LONG
NC_HandleSetCursor( HWND32 hwnd
, WPARAM16 wParam
, LPARAM lParam
)
1796 if (hwnd
!= (HWND32
)wParam
) return 0; /* Don't set the cursor for child windows */
1798 switch(LOWORD(lParam
))
1802 WORD msg
= HIWORD( lParam
);
1803 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_MBUTTONDOWN
) ||
1804 (msg
== WM_RBUTTONDOWN
))
1812 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) break;
1813 if (wndPtr
->class->hCursor
)
1815 SetCursor16( wndPtr
->class->hCursor
);
1823 return (LONG
)SetCursor16( LoadCursor16( 0, IDC_SIZEWE16
) );
1827 return (LONG
)SetCursor16( LoadCursor16( 0, IDC_SIZENS16
) );
1831 return (LONG
)SetCursor16( LoadCursor16( 0, IDC_SIZENWSE16
) );
1835 return (LONG
)SetCursor16( LoadCursor16( 0, IDC_SIZENESW16
) );
1838 /* Default cursor: arrow */
1839 return (LONG
)SetCursor16( LoadCursor16( 0, IDC_ARROW16
) );
1842 /***********************************************************************
1845 BOOL32
NC_GetSysPopupPos( WND
* wndPtr
, RECT32
* rect
)
1847 if( wndPtr
->hSysMenu
)
1849 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
1850 GetWindowRect32( wndPtr
->hwndSelf
, rect
);
1853 if (TWEAK_WineLook
== WIN31_LOOK
)
1854 NC_GetInsideRect( wndPtr
->hwndSelf
, rect
);
1856 NC_GetInsideRect95( wndPtr
->hwndSelf
, rect
);
1857 OffsetRect32( rect
, wndPtr
->rectWindow
.left
, wndPtr
->rectWindow
.top
);
1858 if (wndPtr
->dwStyle
& WS_CHILD
)
1859 ClientToScreen32( wndPtr
->parent
->hwndSelf
, (POINT32
*)rect
);
1860 if (TWEAK_WineLook
== WIN31_LOOK
) {
1861 rect
->right
= rect
->left
+ SYSMETRICS_CXSIZE
;
1862 rect
->bottom
= rect
->top
+ SYSMETRICS_CYSIZE
;
1865 rect
->right
= rect
->left
+ sysMetrics
[SM_CYCAPTION
] - 1;
1866 rect
->bottom
= rect
->top
+ sysMetrics
[SM_CYCAPTION
] - 1;
1874 /***********************************************************************
1877 * Initialisation of a move or resize, when initiatied from a menu choice.
1878 * Return hit test code for caption or sizing border.
1880 static LONG
NC_StartSizeMove( WND
* wndPtr
, WPARAM16 wParam
,
1881 POINT16
*capturePoint
)
1887 if ((wParam
& 0xfff0) == SC_MOVE
)
1889 /* Move pointer at the center of the caption */
1891 if (TWEAK_WineLook
== WIN31_LOOK
)
1892 NC_GetInsideRect( wndPtr
->hwndSelf
, &rect
);
1894 NC_GetInsideRect95( wndPtr
->hwndSelf
, &rect
);
1895 if (wndPtr
->dwStyle
& WS_SYSMENU
)
1896 rect
.left
+= SYSMETRICS_CXSIZE
+ 1;
1897 if (wndPtr
->dwStyle
& WS_MINIMIZEBOX
)
1898 rect
.right
-= SYSMETRICS_CXSIZE
+ 1;
1899 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
1900 rect
.right
-= SYSMETRICS_CXSIZE
+ 1;
1901 pt
.x
= wndPtr
->rectWindow
.left
+ (rect
.right
- rect
.left
) / 2;
1902 pt
.y
= wndPtr
->rectWindow
.top
+ rect
.top
+ SYSMETRICS_CYSIZE
/2;
1903 hittest
= HTCAPTION
;
1910 MSG_InternalGetMessage( &msg
, 0, 0, MSGF_SIZE
, PM_REMOVE
, FALSE
);
1914 CONV_POINT32TO16(&msg
.pt
, &pt
);
1915 hittest
= NC_HandleNCHitTest( wndPtr
->hwndSelf
, pt
);
1916 if ((hittest
< HTLEFT
) || (hittest
> HTBOTTOMRIGHT
))
1928 pt
.x
=(wndPtr
->rectWindow
.left
+wndPtr
->rectWindow
.right
)/2;
1929 pt
.y
= wndPtr
->rectWindow
.top
+ SYSMETRICS_CYFRAME
/ 2;
1933 pt
.x
=(wndPtr
->rectWindow
.left
+wndPtr
->rectWindow
.right
)/2;
1934 pt
.y
= wndPtr
->rectWindow
.bottom
- SYSMETRICS_CYFRAME
/ 2;
1938 pt
.x
= wndPtr
->rectWindow
.left
+ SYSMETRICS_CXFRAME
/ 2;
1939 pt
.y
=(wndPtr
->rectWindow
.top
+wndPtr
->rectWindow
.bottom
)/2;
1943 pt
.x
= wndPtr
->rectWindow
.right
- SYSMETRICS_CXFRAME
/ 2;
1944 pt
.y
=(wndPtr
->rectWindow
.top
+wndPtr
->rectWindow
.bottom
)/2;
1947 case VK_ESCAPE
: return 0;
1953 SetCursorPos32( pt
.x
, pt
.y
);
1954 NC_HandleSetCursor( wndPtr
->hwndSelf
,
1955 wndPtr
->hwndSelf
, MAKELONG( hittest
, WM_MOUSEMOVE
));
1960 /***********************************************************************
1963 * Perform SC_MOVE and SC_SIZE commands. `
1965 static void NC_DoSizeMove( HWND32 hwnd
, WORD wParam
)
1968 RECT32 sizingRect
, mouseRect
;
1970 LONG hittest
= (LONG
)(wParam
& 0x0f);
1971 HCURSOR16 hDragCursor
= 0, hOldCursor
= 0;
1972 POINT32 minTrack
, maxTrack
;
1973 POINT16 capturePoint
, pt
;
1974 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1975 BOOL32 thickframe
= HAS_THICKFRAME( wndPtr
->dwStyle
);
1976 BOOL32 iconic
= wndPtr
->dwStyle
& WS_MINIMIZE
;
1977 BOOL32 moved
= FALSE
;
1978 DWORD dwPoint
= GetMessagePos ();
1980 capturePoint
= pt
= *(POINT16
*)&dwPoint
;
1982 if (IsZoomed32(hwnd
) || !IsWindowVisible32(hwnd
) ||
1983 (wndPtr
->flags
& WIN_MANAGED
)) return;
1985 if ((wParam
& 0xfff0) == SC_MOVE
)
1987 if (!(wndPtr
->dwStyle
& WS_CAPTION
)) return;
1989 hittest
= NC_StartSizeMove( wndPtr
, wParam
, &capturePoint
);
1990 if (!hittest
) return;
1994 if (!thickframe
) return;
1995 if ( hittest
&& hittest
!= HTSYSMENU
) hittest
+= 2;
1999 hittest
= NC_StartSizeMove( wndPtr
, wParam
, &capturePoint
);
2008 /* Get min/max info */
2010 WINPOS_GetMinMaxInfo( wndPtr
, NULL
, NULL
, &minTrack
, &maxTrack
);
2011 sizingRect
= wndPtr
->rectWindow
;
2012 if (wndPtr
->dwStyle
& WS_CHILD
)
2013 GetClientRect32( wndPtr
->parent
->hwndSelf
, &mouseRect
);
2015 SetRect32(&mouseRect
, 0, 0, SYSMETRICS_CXSCREEN
, SYSMETRICS_CYSCREEN
);
2016 if (ON_LEFT_BORDER(hittest
))
2018 mouseRect
.left
= MAX( mouseRect
.left
, sizingRect
.right
-maxTrack
.x
);
2019 mouseRect
.right
= MIN( mouseRect
.right
, sizingRect
.right
-minTrack
.x
);
2021 else if (ON_RIGHT_BORDER(hittest
))
2023 mouseRect
.left
= MAX( mouseRect
.left
, sizingRect
.left
+minTrack
.x
);
2024 mouseRect
.right
= MIN( mouseRect
.right
, sizingRect
.left
+maxTrack
.x
);
2026 if (ON_TOP_BORDER(hittest
))
2028 mouseRect
.top
= MAX( mouseRect
.top
, sizingRect
.bottom
-maxTrack
.y
);
2029 mouseRect
.bottom
= MIN( mouseRect
.bottom
,sizingRect
.bottom
-minTrack
.y
);
2031 else if (ON_BOTTOM_BORDER(hittest
))
2033 mouseRect
.top
= MAX( mouseRect
.top
, sizingRect
.top
+minTrack
.y
);
2034 mouseRect
.bottom
= MIN( mouseRect
.bottom
, sizingRect
.top
+maxTrack
.y
);
2036 if (wndPtr
->dwStyle
& WS_CHILD
)
2038 MapWindowPoints32( wndPtr
->parent
->hwndSelf
, 0,
2039 (LPPOINT32
)&mouseRect
, 2 );
2041 SendMessage16( hwnd
, WM_ENTERSIZEMOVE
, 0, 0 );
2043 if (GetCapture32() != hwnd
) SetCapture32( hwnd
);
2045 if (wndPtr
->dwStyle
& WS_CHILD
)
2047 /* Retrieve a default cache DC (without using the window style) */
2048 hdc
= GetDCEx32( wndPtr
->parent
->hwndSelf
, 0, DCX_CACHE
);
2051 { /* Grab the server only when moving top-level windows without desktop */
2055 wndPtr
->pDriver
->pPreSizeMove(wndPtr
);
2057 if( iconic
) /* create a cursor for dragging */
2059 HICON16 hIcon
= (wndPtr
->class->hIcon
) ? wndPtr
->class->hIcon
2060 : (HICON16
)SendMessage16( hwnd
, WM_QUERYDRAGICON
, 0, 0L);
2061 if( hIcon
) hDragCursor
= CURSORICON_IconToCursor( hIcon
, TRUE
);
2062 if( !hDragCursor
) iconic
= FALSE
;
2065 if( !iconic
) NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2071 MSG_InternalGetMessage( &msg
, 0, 0, MSGF_SIZE
, PM_REMOVE
, FALSE
);
2073 /* Exit on button-up, Return, or Esc */
2074 if ((msg
.message
== WM_LBUTTONUP
) ||
2075 ((msg
.message
== WM_KEYDOWN
) &&
2076 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
2078 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
2079 continue; /* We are not interested in other messages */
2081 dwPoint
= GetMessagePos ();
2082 pt
= *(POINT16
*)&dwPoint
;
2084 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
2086 case VK_UP
: pt
.y
-= 8; break;
2087 case VK_DOWN
: pt
.y
+= 8; break;
2088 case VK_LEFT
: pt
.x
-= 8; break;
2089 case VK_RIGHT
: pt
.x
+= 8; break;
2092 pt
.x
= MAX( pt
.x
, mouseRect
.left
);
2093 pt
.x
= MIN( pt
.x
, mouseRect
.right
);
2094 pt
.y
= MAX( pt
.y
, mouseRect
.top
);
2095 pt
.y
= MIN( pt
.y
, mouseRect
.bottom
);
2097 dx
= pt
.x
- capturePoint
.x
;
2098 dy
= pt
.y
- capturePoint
.y
;
2105 if( iconic
) /* ok, no system popup tracking */
2107 hOldCursor
= SetCursor32(hDragCursor
);
2108 ShowCursor32( TRUE
);
2109 WINPOS_ShowIconTitle( wndPtr
, FALSE
);
2113 if (msg
.message
== WM_KEYDOWN
) SetCursorPos32( pt
.x
, pt
.y
);
2116 RECT32 newRect
= sizingRect
;
2118 if (hittest
== HTCAPTION
) OffsetRect32( &newRect
, dx
, dy
);
2119 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
2120 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
2121 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
2122 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
2125 NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2126 NC_DrawMovingFrame( hdc
, &newRect
, thickframe
);
2129 sizingRect
= newRect
;
2137 if( moved
) /* restore cursors, show icon title later on */
2139 ShowCursor32( FALSE
);
2140 SetCursor32( hOldCursor
);
2142 DestroyCursor32( hDragCursor
);
2145 NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2147 if (wndPtr
->dwStyle
& WS_CHILD
)
2148 ReleaseDC32( wndPtr
->parent
->hwndSelf
, hdc
);
2151 ReleaseDC32( 0, hdc
);
2154 wndPtr
->pDriver
->pPostSizeMove(wndPtr
);
2156 if (HOOK_IsHooked( WH_CBT
))
2158 RECT16
* pr
= SEGPTR_NEW(RECT16
);
2161 CONV_RECT32TO16( &sizingRect
, pr
);
2162 if( HOOK_CallHooks16( WH_CBT
, HCBT_MOVESIZE
, hwnd
,
2163 (LPARAM
)SEGPTR_GET(pr
)) )
2164 sizingRect
= wndPtr
->rectWindow
;
2166 CONV_RECT16TO32( pr
, &sizingRect
);
2170 SendMessage16( hwnd
, WM_EXITSIZEMOVE
, 0, 0 );
2171 SendMessage16( hwnd
, WM_SETVISIBLE
, !IsIconic16(hwnd
), 0L);
2173 if( moved
&& !((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
2175 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
2176 SetWindowPos32( hwnd
, 0, sizingRect
.left
, sizingRect
.top
,
2177 sizingRect
.right
- sizingRect
.left
,
2178 sizingRect
.bottom
- sizingRect
.top
,
2179 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
2182 if( IsWindow32(hwnd
) )
2183 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
2185 /* Single click brings up the system menu when iconized */
2189 if( wndPtr
->dwStyle
& WS_SYSMENU
)
2190 SendMessage16( hwnd
, WM_SYSCOMMAND
,
2191 SC_MOUSEMENU
+ HTSYSMENU
, *((LPARAM
*)&pt
));
2193 else WINPOS_ShowIconTitle( wndPtr
, TRUE
);
2198 /***********************************************************************
2201 * Track a mouse button press on the minimize or maximize box.
2203 static void NC_TrackMinMaxBox( HWND32 hwnd
, WORD wParam
)
2207 HDC32 hdc
= GetWindowDC32( hwnd
);
2208 BOOL32 pressed
= TRUE
;
2209 void (*paintButton
)(HWND32
, HDC16
, BOOL32
);
2211 SetCapture32( hwnd
);
2212 if (wParam
== HTMINBUTTON
)
2214 (TWEAK_WineLook
== WIN31_LOOK
) ? &NC_DrawMinButton
: &NC_DrawMinButton95
;
2217 (TWEAK_WineLook
== WIN31_LOOK
) ? &NC_DrawMaxButton
: &NC_DrawMaxButton95
;
2219 (*paintButton
)( hwnd
, hdc
, TRUE
);
2223 BOOL32 oldstate
= pressed
;
2224 MSG_InternalGetMessage( &msg
, 0, 0, 0, PM_REMOVE
, FALSE
);
2225 CONV_POINT32TO16( &msg
.pt
, &pt16
);
2227 pressed
= (NC_HandleNCHitTest( hwnd
, pt16
) == wParam
);
2228 if (pressed
!= oldstate
)
2229 (*paintButton
)( hwnd
, hdc
, pressed
);
2230 } while (msg
.message
!= WM_LBUTTONUP
);
2232 (*paintButton
)( hwnd
, hdc
, FALSE
);
2235 ReleaseDC32( hwnd
, hdc
);
2236 if (!pressed
) return;
2238 if (wParam
== HTMINBUTTON
)
2239 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, *(LONG
*)&pt16
);
2241 SendMessage16( hwnd
, WM_SYSCOMMAND
,
2242 IsZoomed32(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, *(LONG
*)&pt16
);
2246 /***********************************************************************
2247 * NC_TrackCloseButton95
2249 * Track a mouse button press on the Win95 close button.
2252 NC_TrackCloseButton95 (HWND32 hwnd
, WORD wParam
)
2256 HDC32 hdc
= GetWindowDC32( hwnd
);
2257 BOOL32 pressed
= TRUE
;
2259 SetCapture32( hwnd
);
2261 NC_DrawCloseButton95 (hwnd
, hdc
, TRUE
);
2265 BOOL32 oldstate
= pressed
;
2266 MSG_InternalGetMessage( &msg
, 0, 0, 0, PM_REMOVE
, FALSE
);
2267 CONV_POINT32TO16( &msg
.pt
, &pt16
);
2269 pressed
= (NC_HandleNCHitTest( hwnd
, pt16
) == wParam
);
2270 if (pressed
!= oldstate
)
2271 NC_DrawCloseButton95 (hwnd
, hdc
, pressed
);
2272 } while (msg
.message
!= WM_LBUTTONUP
);
2274 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
);
2277 ReleaseDC32( hwnd
, hdc
);
2278 if (!pressed
) return;
2280 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, *(LONG
*)&pt16
);
2284 /***********************************************************************
2287 * Track a mouse button press on the horizontal or vertical scroll-bar.
2289 static void NC_TrackScrollBar( HWND32 hwnd
, WPARAM32 wParam
, POINT32 pt
)
2293 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
2295 if ((wParam
& 0xfff0) == SC_HSCROLL
)
2297 if ((wParam
& 0x0f) != HTHSCROLL
) return;
2298 scrollbar
= SB_HORZ
;
2300 else /* SC_VSCROLL */
2302 if ((wParam
& 0x0f) != HTVSCROLL
) return;
2303 scrollbar
= SB_VERT
;
2306 if (!(msg
= SEGPTR_NEW(MSG16
))) return;
2307 pt
.x
-= wndPtr
->rectWindow
.left
;
2308 pt
.y
-= wndPtr
->rectWindow
.top
;
2309 SetCapture32( hwnd
);
2310 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, WM_LBUTTONDOWN
, pt
);
2314 GetMessage16( SEGPTR_GET(msg
), 0, 0, 0 );
2315 switch(msg
->message
)
2320 pt
.x
= LOWORD(msg
->lParam
) + wndPtr
->rectClient
.left
-
2321 wndPtr
->rectWindow
.left
;
2322 pt
.y
= HIWORD(msg
->lParam
) + wndPtr
->rectClient
.top
-
2323 wndPtr
->rectWindow
.top
;
2324 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, msg
->message
, pt
);
2327 TranslateMessage16( msg
);
2328 DispatchMessage16( msg
);
2331 if (!IsWindow32( hwnd
))
2336 } while (msg
->message
!= WM_LBUTTONUP
);
2340 /***********************************************************************
2341 * NC_HandleNCLButtonDown
2343 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2345 LONG
NC_HandleNCLButtonDown( WND
* pWnd
, WPARAM16 wParam
, LPARAM lParam
)
2347 HWND32 hwnd
= pWnd
->hwndSelf
;
2349 switch(wParam
) /* Hit test */
2352 hwnd
= WIN_GetTopParent(hwnd
);
2354 if( WINPOS_SetActiveWindow(hwnd
, TRUE
, TRUE
) || (GetActiveWindow32() == hwnd
) )
2355 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_MOVE
+ HTCAPTION
, lParam
);
2359 if( pWnd
->dwStyle
& WS_SYSMENU
)
2361 if( !(pWnd
->dwStyle
& WS_MINIMIZE
) )
2363 HDC32 hDC
= GetWindowDC32(hwnd
);
2364 if (TWEAK_WineLook
== WIN31_LOOK
)
2365 NC_DrawSysButton( hwnd
, hDC
, TRUE
);
2367 NC_DrawSysButton95( hwnd
, hDC
, TRUE
);
2368 ReleaseDC32( hwnd
, hDC
);
2370 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
+ HTSYSMENU
, lParam
);
2375 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
, lParam
);
2379 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
2383 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
2388 NC_TrackMinMaxBox( hwnd
, wParam
);
2392 if (TWEAK_WineLook
>= WIN95_LOOK
)
2393 NC_TrackCloseButton95 (hwnd
, wParam
);
2404 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2405 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_SIZE
+ wParam
- 2, lParam
);
2415 /***********************************************************************
2416 * NC_HandleNCLButtonDblClk
2418 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2420 LONG
NC_HandleNCLButtonDblClk( WND
*pWnd
, WPARAM16 wParam
, LPARAM lParam
)
2423 * if this is an icon, send a restore since we are handling
2426 if (pWnd
->dwStyle
& WS_MINIMIZE
)
2428 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_RESTORE
, lParam
);
2432 switch(wParam
) /* Hit test */
2435 /* stop processing if WS_MAXIMIZEBOX is missing */
2436 if (pWnd
->dwStyle
& WS_MAXIMIZEBOX
)
2437 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
,
2438 (pWnd
->dwStyle
& WS_MAXIMIZE
) ? SC_RESTORE
: SC_MAXIMIZE
,
2443 if (!(pWnd
->class->style
& CS_NOCLOSE
))
2444 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_CLOSE
, lParam
);
2448 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
,
2453 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
,
2461 /***********************************************************************
2462 * NC_HandleSysCommand
2464 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2466 LONG
NC_HandleSysCommand( HWND32 hwnd
, WPARAM16 wParam
, POINT16 pt
)
2468 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
2470 UINT16 uCommand
= wParam
& 0xFFF0;
2472 TRACE(nonclient
, "Handling WM_SYSCOMMAND %x %d,%d\n",
2473 wParam
, pt
.x
, pt
.y
);
2475 if (wndPtr
->dwStyle
& WS_CHILD
&& uCommand
!= SC_KEYMENU
)
2476 ScreenToClient16( wndPtr
->parent
->hwndSelf
, &pt
);
2482 NC_DoSizeMove( hwnd
, wParam
);
2486 ShowWindow32( hwnd
, SW_MINIMIZE
);
2490 ShowWindow32( hwnd
, SW_MAXIMIZE
);
2494 ShowWindow32( hwnd
, SW_RESTORE
);
2498 return SendMessage16( hwnd
, WM_CLOSE
, 0, 0 );
2502 CONV_POINT16TO32( &pt
, &pt32
);
2503 NC_TrackScrollBar( hwnd
, wParam
, pt32
);
2507 CONV_POINT16TO32( &pt
, &pt32
);
2508 MENU_TrackMouseMenuBar( wndPtr
, wParam
& 0x000F, pt32
);
2512 MENU_TrackKbdMenuBar( wndPtr
, wParam
, pt
.x
);
2516 WinExec32( "taskman.exe", SW_SHOWNORMAL
);
2520 if (wParam
== SC_ABOUTWINE
)
2521 ShellAbout32A(hwnd
,"Wine", WINE_RELEASE_INFO
, 0);
2523 if (wParam
== SC_PUTMARK
)
2524 TRACE(shell
,"Mark requested by user\n");
2531 FIXME (nonclient
, "unimplemented!\n");