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 DECLARE_DEBUG_CHANNEL(nonclient
)
31 DECLARE_DEBUG_CHANNEL(shell
)
33 static HBITMAP16 hbitmapClose
= 0;
34 static HBITMAP16 hbitmapCloseD
= 0;
35 static HBITMAP16 hbitmapMinimize
= 0;
36 static HBITMAP16 hbitmapMinimizeD
= 0;
37 static HBITMAP16 hbitmapMaximize
= 0;
38 static HBITMAP16 hbitmapMaximizeD
= 0;
39 static HBITMAP16 hbitmapRestore
= 0;
40 static HBITMAP16 hbitmapRestoreD
= 0;
42 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
43 #define SC_PUTMARK (SC_SCREENSAVE+2)
45 /* Some useful macros */
46 #define HAS_DLGFRAME(style,exStyle) \
47 (((exStyle) & WS_EX_DLGMODALFRAME) || \
48 (((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
50 #define HAS_THICKFRAME(style) \
51 (((style) & WS_THICKFRAME) && \
52 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
54 #define HAS_FIXEDFRAME(style,exStyle) \
55 (((((exStyle) & WS_EX_DLGMODALFRAME) || \
56 ((style) & WS_DLGFRAME)) && ((style) & WS_BORDER)) && \
57 !((style) & WS_THICKFRAME))
59 #define HAS_SIZEFRAME(style) \
60 (((style) & WS_THICKFRAME) && \
61 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
63 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
65 #define ON_LEFT_BORDER(hit) \
66 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
67 #define ON_RIGHT_BORDER(hit) \
68 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
69 #define ON_TOP_BORDER(hit) \
70 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
71 #define ON_BOTTOM_BORDER(hit) \
72 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
74 /***********************************************************************
77 * Compute the size of the window rectangle from the size of the
80 static void NC_AdjustRect( LPRECT16 rect
, DWORD style
, BOOL menu
,
83 if (TWEAK_WineLook
> WIN31_LOOK
)
84 ERR(nonclient
, "Called in Win95 mode. Aiee! Please report this.\n" );
86 if(style
& WS_ICONIC
) return;
87 /* Decide if the window will be managed (see CreateWindowEx) */
88 if (!(Options
.managed
&& !(style
& WS_CHILD
) &&
89 ((style
& (WS_DLGFRAME
| WS_THICKFRAME
)) ||
90 (exStyle
& WS_EX_DLGMODALFRAME
))))
92 if (HAS_DLGFRAME( style
, exStyle
))
93 InflateRect16(rect
, SYSMETRICS_CXDLGFRAME
, SYSMETRICS_CYDLGFRAME
);
96 if (HAS_THICKFRAME(style
))
97 InflateRect16( rect
, SYSMETRICS_CXFRAME
, SYSMETRICS_CYFRAME
);
98 if (style
& WS_BORDER
)
99 InflateRect16( rect
, SYSMETRICS_CXBORDER
, SYSMETRICS_CYBORDER
);
102 if ((style
& WS_CAPTION
) == WS_CAPTION
)
103 rect
->top
-= SYSMETRICS_CYCAPTION
- SYSMETRICS_CYBORDER
;
105 if (menu
) rect
->top
-= SYSMETRICS_CYMENU
+ SYSMETRICS_CYBORDER
;
107 if (style
& WS_VSCROLL
) {
108 rect
->right
+= SYSMETRICS_CXVSCROLL
- 1;
109 if(!(style
& WS_BORDER
))
113 if (style
& WS_HSCROLL
) {
114 rect
->bottom
+= SYSMETRICS_CYHSCROLL
- 1;
115 if(!(style
& WS_BORDER
))
121 /******************************************************************************
122 * NC_AdjustRectOuter95
124 * Computes the size of the "outside" parts of the window based on the
125 * parameters of the client area.
134 * "Outer" parts of a window means the whole window frame, caption and
135 * menu bar. It does not include "inner" parts of the frame like client
136 * edge, static edge or scroll bars.
139 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
140 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
142 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
143 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
144 * NC_AdjustRectInner95 and added handling of Win95 styles.
146 *****************************************************************************/
149 NC_AdjustRectOuter95 (LPRECT16 rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
151 if(style
& WS_ICONIC
) return;
153 /* Decide if the window will be managed (see CreateWindowEx) */
154 if (!(Options
.managed
&& !(style
& WS_CHILD
) &&
155 ((style
& (WS_DLGFRAME
| WS_THICKFRAME
)) ||
156 (exStyle
& WS_EX_DLGMODALFRAME
))))
158 if (HAS_FIXEDFRAME( style
, exStyle
))
159 InflateRect16(rect
, SYSMETRICS_CXDLGFRAME
, SYSMETRICS_CYDLGFRAME
);
162 if (HAS_SIZEFRAME(style
))
163 InflateRect16( rect
, SYSMETRICS_CXFRAME
, SYSMETRICS_CYFRAME
);
165 if (style
& WS_BORDER
)
166 InflateRect16( rect
, SYSMETRICS_CXBORDER
, SYSMETRICS_CYBORDER
);
170 if ((style
& WS_CAPTION
) == WS_CAPTION
)
172 if (exStyle
& WS_EX_TOOLWINDOW
)
173 rect
->top
-= SYSMETRICS_CYSMCAPTION
;
175 rect
->top
-= SYSMETRICS_CYCAPTION
;
180 rect
->top
-= sysMetrics
[SM_CYMENU
];
184 /******************************************************************************
185 * NC_AdjustRectInner95
187 * Computes the size of the "inside" part of the window based on the
188 * parameters of the client area.
196 * "Inner" part of a window means the window frame inside of the flat
197 * window frame. It includes the client edge, the static edge and the
201 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
202 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
204 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
205 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
206 * NC_AdjustRectInner95 and added handling of Win95 styles.
208 *****************************************************************************/
211 NC_AdjustRectInner95 (LPRECT16 rect
, DWORD style
, DWORD exStyle
)
213 if(style
& WS_ICONIC
) return;
215 if (exStyle
& WS_EX_CLIENTEDGE
)
216 InflateRect16 (rect
, sysMetrics
[SM_CXEDGE
], sysMetrics
[SM_CYEDGE
]);
218 if (exStyle
& WS_EX_STATICEDGE
)
219 InflateRect16 (rect
, sysMetrics
[SM_CXBORDER
], sysMetrics
[SM_CYBORDER
]);
221 if (style
& WS_VSCROLL
) rect
->right
+= SYSMETRICS_CXVSCROLL
;
222 if (style
& WS_HSCROLL
) rect
->bottom
+= SYSMETRICS_CYHSCROLL
;
226 /***********************************************************************
227 * DrawCaption16 [USER.660] Draws a caption bar
241 DrawCaption16 (HWND16 hwnd
, HDC16 hdc
, const RECT16
*rect
, UINT16 uFlags
)
246 CONV_RECT16TO32 (rect
, &rect32
);
248 return (BOOL16
)DrawCaptionTempA (hwnd
, hdc
, rect
? &rect32
: NULL
,
249 0, 0, NULL
, uFlags
& 0x1F);
253 /***********************************************************************
254 * DrawCaption32 [USER32.154] Draws a caption bar
268 DrawCaption (HWND hwnd
, HDC hdc
, const RECT
*lpRect
, UINT uFlags
)
270 return DrawCaptionTempA (hwnd
, hdc
, lpRect
, 0, 0, NULL
, uFlags
& 0x1F);
274 /***********************************************************************
275 * DrawCaptionTemp16 [USER.657]
285 DrawCaptionTemp16 (HWND16 hwnd
, HDC16 hdc
, const RECT16
*rect
, HFONT16 hFont
,
286 HICON16 hIcon
, LPCSTR str
, UINT16 uFlags
)
291 CONV_RECT16TO32(rect
,&rect32
);
293 return (BOOL16
)DrawCaptionTempA (hwnd
, hdc
, rect
?&rect32
:NULL
, hFont
,
294 hIcon
, str
, uFlags
& 0x1F);
298 /***********************************************************************
299 * DrawCaptionTemp32A [USER32.599]
309 DrawCaptionTempA (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
310 HICON hIcon
, LPCSTR str
, UINT uFlags
)
314 TRACE (nonclient
, "(%08x,%08x,%p,%08x,%08x,\"%s\",%08x)\n",
315 hwnd
, hdc
, rect
, hFont
, hIcon
, str
, uFlags
);
317 /* drawing background */
318 if (uFlags
& DC_INBUTTON
) {
319 FillRect (hdc
, &rc
, GetSysColorBrush (COLOR_3DFACE
));
321 if (uFlags
& DC_ACTIVE
) {
322 HBRUSH hbr
= SelectObject (hdc
, CACHE_GetPattern55AABrush ());
323 PatBlt (hdc
, rc
.left
, rc
.top
,
324 rc
.right
-rc
.left
, rc
.bottom
-rc
.top
, 0xFA0089);
325 SelectObject (hdc
, hbr
);
329 FillRect (hdc
, &rc
, GetSysColorBrush ((uFlags
& DC_ACTIVE
) ?
330 COLOR_ACTIVECAPTION
: COLOR_INACTIVECAPTION
));
335 if ((uFlags
& DC_ICON
) && !(uFlags
& DC_SMALLCAP
)) {
339 pt
.y
= (rc
.bottom
+ rc
.top
- sysMetrics
[SM_CYSMICON
]) / 2;
342 DrawIconEx (hdc
, pt
.x
, pt
.y
, hIcon
, sysMetrics
[SM_CXSMICON
],
343 sysMetrics
[SM_CYSMICON
], 0, 0, DI_NORMAL
);
346 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
349 if (wndPtr
->class->hIconSm
)
350 hAppIcon
= wndPtr
->class->hIconSm
;
351 else if (wndPtr
->class->hIcon
)
352 hAppIcon
= wndPtr
->class->hIcon
;
354 DrawIconEx (hdc
, pt
.x
, pt
.y
, hAppIcon
, sysMetrics
[SM_CXSMICON
],
355 sysMetrics
[SM_CYSMICON
], 0, 0, DI_NORMAL
);
356 WIN_ReleaseWndPtr(wndPtr
);
359 rc
.left
+= (rc
.bottom
- rc
.top
);
363 if (uFlags
& DC_TEXT
) {
366 if (uFlags
& DC_INBUTTON
)
367 SetTextColor (hdc
, GetSysColor (COLOR_BTNTEXT
));
368 else if (uFlags
& DC_ACTIVE
)
369 SetTextColor (hdc
, GetSysColor (COLOR_CAPTIONTEXT
));
371 SetTextColor (hdc
, GetSysColor (COLOR_INACTIVECAPTIONTEXT
));
373 SetBkMode (hdc
, TRANSPARENT
);
376 hOldFont
= SelectObject (hdc
, hFont
);
378 NONCLIENTMETRICSA nclm
;
380 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
381 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
382 hNewFont
= CreateFontIndirectA ((uFlags
& DC_SMALLCAP
) ?
383 &nclm
.lfSmCaptionFont
: &nclm
.lfCaptionFont
);
384 hOldFont
= SelectObject (hdc
, hNewFont
);
388 DrawTextA (hdc
, str
, -1, &rc
,
389 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
393 nLen
= GetWindowTextA (hwnd
, szText
, 128);
394 DrawTextA (hdc
, szText
, nLen
, &rc
,
395 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
399 SelectObject (hdc
, hOldFont
);
401 DeleteObject (SelectObject (hdc
, hOldFont
));
404 /* drawing focus ??? */
406 FIXME (nonclient
, "undocumented flag (0x2000)!\n");
412 /***********************************************************************
413 * DrawCaptionTemp32W [USER32.602]
423 DrawCaptionTempW (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
424 HICON hIcon
, LPCWSTR str
, UINT uFlags
)
426 LPSTR p
= HEAP_strdupWtoA (GetProcessHeap (), 0, str
);
427 BOOL res
= DrawCaptionTempA (hwnd
, hdc
, rect
, hFont
, hIcon
, p
, uFlags
);
428 HeapFree (GetProcessHeap (), 0, p
);
433 /***********************************************************************
434 * AdjustWindowRect16 (USER.102)
436 BOOL16 WINAPI
AdjustWindowRect16( LPRECT16 rect
, DWORD style
, BOOL16 menu
)
438 return AdjustWindowRectEx16( rect
, style
, menu
, 0 );
442 /***********************************************************************
443 * AdjustWindowRect32 (USER32.2)
445 BOOL WINAPI
AdjustWindowRect( LPRECT rect
, DWORD style
, BOOL menu
)
447 return AdjustWindowRectEx( rect
, style
, menu
, 0 );
451 /***********************************************************************
452 * AdjustWindowRectEx16 (USER.454)
454 BOOL16 WINAPI
AdjustWindowRectEx16( LPRECT16 rect
, DWORD style
,
455 BOOL16 menu
, DWORD exStyle
)
457 /* Correct the window style */
459 if (!(style
& (WS_POPUP
| WS_CHILD
))) /* Overlapped window */
461 style
&= (WS_DLGFRAME
| WS_BORDER
| WS_THICKFRAME
| WS_CHILD
);
462 exStyle
&= (WS_EX_DLGMODALFRAME
| WS_EX_CLIENTEDGE
|
463 WS_EX_STATICEDGE
| WS_EX_TOOLWINDOW
);
464 if (exStyle
& WS_EX_DLGMODALFRAME
) style
&= ~WS_THICKFRAME
;
466 TRACE(nonclient
, "(%d,%d)-(%d,%d) %08lx %d %08lx\n",
467 rect
->left
, rect
->top
, rect
->right
, rect
->bottom
,
468 style
, menu
, exStyle
);
470 if (TWEAK_WineLook
== WIN31_LOOK
)
471 NC_AdjustRect( rect
, style
, menu
, exStyle
);
473 NC_AdjustRectOuter95( rect
, style
, menu
, exStyle
);
474 NC_AdjustRectInner95( rect
, style
, exStyle
);
481 /***********************************************************************
482 * AdjustWindowRectEx32 (USER32.3)
484 BOOL WINAPI
AdjustWindowRectEx( LPRECT rect
, DWORD style
,
485 BOOL menu
, DWORD exStyle
)
490 CONV_RECT32TO16( rect
, &rect16
);
491 ret
= AdjustWindowRectEx16( &rect16
, style
, (BOOL16
)menu
, exStyle
);
492 CONV_RECT16TO32( &rect16
, rect
);
497 /***********************************************************************
498 * NC_HandleNCCalcSize
500 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
502 LONG
NC_HandleNCCalcSize( WND
*pWnd
, RECT
*winRect
)
504 RECT16 tmpRect
= { 0, 0, 0, 0 };
507 if (pWnd
->class->style
& CS_VREDRAW
) result
|= WVR_VREDRAW
;
508 if (pWnd
->class->style
& CS_HREDRAW
) result
|= WVR_HREDRAW
;
510 if( !( pWnd
->dwStyle
& WS_MINIMIZE
) ) {
511 if (TWEAK_WineLook
== WIN31_LOOK
)
512 NC_AdjustRect( &tmpRect
, pWnd
->dwStyle
, FALSE
, pWnd
->dwExStyle
);
514 NC_AdjustRectOuter95( &tmpRect
, pWnd
->dwStyle
, FALSE
, pWnd
->dwExStyle
);
516 winRect
->left
-= tmpRect
.left
;
517 winRect
->top
-= tmpRect
.top
;
518 winRect
->right
-= tmpRect
.right
;
519 winRect
->bottom
-= tmpRect
.bottom
;
521 if (HAS_MENU(pWnd
)) {
522 TRACE(nonclient
, "Calling "
523 "GetMenuBarHeight with HWND 0x%x, width %d, "
524 "at (%d, %d).\n", pWnd
->hwndSelf
,
525 winRect
->right
- winRect
->left
,
526 -tmpRect
.left
, -tmpRect
.top
);
529 MENU_GetMenuBarHeight( pWnd
->hwndSelf
,
530 winRect
->right
- winRect
->left
,
531 -tmpRect
.left
, -tmpRect
.top
) + 1;
534 if (TWEAK_WineLook
> WIN31_LOOK
) {
535 SetRect16 (&tmpRect
, 0, 0, 0, 0);
536 NC_AdjustRectInner95 (&tmpRect
, pWnd
->dwStyle
, pWnd
->dwExStyle
);
537 winRect
->left
-= tmpRect
.left
;
538 winRect
->top
-= tmpRect
.top
;
539 winRect
->right
-= tmpRect
.right
;
540 winRect
->bottom
-= tmpRect
.bottom
;
547 /***********************************************************************
550 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
551 * but without the borders (if any).
552 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
554 static void NC_GetInsideRect( HWND hwnd
, RECT
*rect
)
556 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
558 rect
->top
= rect
->left
= 0;
559 rect
->right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
560 rect
->bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
562 if ((wndPtr
->dwStyle
& WS_ICONIC
) || (wndPtr
->flags
& WIN_MANAGED
)) goto END
;
564 /* Remove frame from rectangle */
565 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
567 InflateRect( rect
, -SYSMETRICS_CXDLGFRAME
, -SYSMETRICS_CYDLGFRAME
);
568 if (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
)
569 InflateRect( rect
, -1, 0 );
573 if (HAS_THICKFRAME( wndPtr
->dwStyle
))
574 InflateRect( rect
, -SYSMETRICS_CXFRAME
, -SYSMETRICS_CYFRAME
);
575 if (wndPtr
->dwStyle
& WS_BORDER
)
576 InflateRect( rect
, -SYSMETRICS_CXBORDER
, -SYSMETRICS_CYBORDER
);
579 WIN_ReleaseWndPtr(wndPtr
);
584 /***********************************************************************
587 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
588 * but without the borders (if any).
589 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
593 NC_GetInsideRect95 (HWND hwnd
, RECT
*rect
)
595 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
597 rect
->top
= rect
->left
= 0;
598 rect
->right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
599 rect
->bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
601 if ((wndPtr
->dwStyle
& WS_ICONIC
) || (wndPtr
->flags
& WIN_MANAGED
)) goto END
;
603 /* Remove frame from rectangle */
604 if (HAS_FIXEDFRAME (wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
606 InflateRect( rect
, -SYSMETRICS_CXFIXEDFRAME
, -SYSMETRICS_CYFIXEDFRAME
);
608 else if (HAS_SIZEFRAME (wndPtr
->dwStyle
))
610 InflateRect( rect
, -SYSMETRICS_CXSIZEFRAME
, -SYSMETRICS_CYSIZEFRAME
);
612 /* if (wndPtr->dwStyle & WS_BORDER)
613 InflateRect32( rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER );*/
616 if (wndPtr
->dwStyle
& WS_CHILD
) {
617 if (wndPtr
->dwExStyle
& WS_EX_CLIENTEDGE
)
618 InflateRect (rect
, -SYSMETRICS_CXEDGE
, -SYSMETRICS_CYEDGE
);
620 if (wndPtr
->dwExStyle
& WS_EX_STATICEDGE
)
621 InflateRect (rect
, -SYSMETRICS_CXBORDER
, -SYSMETRICS_CYBORDER
);
624 WIN_ReleaseWndPtr(wndPtr
);
629 /***********************************************************************
632 * Handle a WM_NCHITTEST message. Called from NC_HandleNcHitTest().
635 LONG
NC_DoNCHitTest (WND
*wndPtr
, POINT16 pt
)
639 TRACE(nonclient
, "hwnd=%04x pt=%d,%d\n",
640 wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
642 GetWindowRect16 (wndPtr
->hwndSelf
, &rect
);
643 if (!PtInRect16( &rect
, pt
)) return HTNOWHERE
;
645 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
647 if (!(wndPtr
->flags
& WIN_MANAGED
))
650 if (HAS_THICKFRAME( wndPtr
->dwStyle
))
652 InflateRect16( &rect
, -SYSMETRICS_CXFRAME
, -SYSMETRICS_CYFRAME
);
653 if (wndPtr
->dwStyle
& WS_BORDER
)
654 InflateRect16(&rect
,-SYSMETRICS_CXBORDER
,-SYSMETRICS_CYBORDER
);
655 if (!PtInRect16( &rect
, pt
))
657 /* Check top sizing border */
660 if (pt
.x
< rect
.left
+SYSMETRICS_CXSIZE
) return HTTOPLEFT
;
661 if (pt
.x
>= rect
.right
-SYSMETRICS_CXSIZE
) return HTTOPRIGHT
;
664 /* Check bottom sizing border */
665 if (pt
.y
>= rect
.bottom
)
667 if (pt
.x
< rect
.left
+SYSMETRICS_CXSIZE
) return HTBOTTOMLEFT
;
668 if (pt
.x
>= rect
.right
-SYSMETRICS_CXSIZE
) return HTBOTTOMRIGHT
;
671 /* Check left sizing border */
672 if (pt
.x
< rect
.left
)
674 if (pt
.y
< rect
.top
+SYSMETRICS_CYSIZE
) return HTTOPLEFT
;
675 if (pt
.y
>= rect
.bottom
-SYSMETRICS_CYSIZE
) return HTBOTTOMLEFT
;
678 /* Check right sizing border */
679 if (pt
.x
>= rect
.right
)
681 if (pt
.y
< rect
.top
+SYSMETRICS_CYSIZE
) return HTTOPRIGHT
;
682 if (pt
.y
>= rect
.bottom
-SYSMETRICS_CYSIZE
) return HTBOTTOMRIGHT
;
687 else /* No thick frame */
689 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
690 InflateRect16(&rect
, -SYSMETRICS_CXDLGFRAME
, -SYSMETRICS_CYDLGFRAME
);
691 else if (wndPtr
->dwStyle
& WS_BORDER
)
692 InflateRect16(&rect
, -SYSMETRICS_CXBORDER
, -SYSMETRICS_CYBORDER
);
693 if (!PtInRect16( &rect
, pt
)) return HTBORDER
;
698 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
700 rect
.top
+= sysMetrics
[SM_CYCAPTION
] - 1;
701 if (!PtInRect16( &rect
, pt
))
703 /* Check system menu */
704 if (wndPtr
->dwStyle
& WS_SYSMENU
)
705 rect
.left
+= SYSMETRICS_CXSIZE
;
706 if (pt
.x
<= rect
.left
) return HTSYSMENU
;
707 /* Check maximize box */
708 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
709 rect
.right
-= SYSMETRICS_CXSIZE
+ 1;
710 if (pt
.x
>= rect
.right
) return HTMAXBUTTON
;
711 /* Check minimize box */
712 if (wndPtr
->dwStyle
& WS_MINIMIZEBOX
)
713 rect
.right
-= SYSMETRICS_CXSIZE
+ 1;
714 if (pt
.x
>= rect
.right
) return HTMINBUTTON
;
720 /* Check client area */
722 ScreenToClient16( wndPtr
->hwndSelf
, &pt
);
723 GetClientRect16( wndPtr
->hwndSelf
, &rect
);
724 if (PtInRect16( &rect
, pt
)) return HTCLIENT
;
726 /* Check vertical scroll bar */
728 if (wndPtr
->dwStyle
& WS_VSCROLL
)
730 rect
.right
+= SYSMETRICS_CXVSCROLL
;
731 if (PtInRect16( &rect
, pt
)) return HTVSCROLL
;
734 /* Check horizontal scroll bar */
736 if (wndPtr
->dwStyle
& WS_HSCROLL
)
738 rect
.bottom
+= SYSMETRICS_CYHSCROLL
;
739 if (PtInRect16( &rect
, pt
))
742 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
743 (pt
.x
>= rect
.right
- SYSMETRICS_CXVSCROLL
))
751 if (HAS_MENU(wndPtr
))
753 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
757 /* Should never get here */
762 /***********************************************************************
765 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
767 * FIXME: Just a modified copy of the Win 3.1 version.
771 NC_DoNCHitTest95 (WND
*wndPtr
, POINT16 pt
)
775 TRACE(nonclient
, "hwnd=%04x pt=%d,%d\n",
776 wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
778 GetWindowRect16 (wndPtr
->hwndSelf
, &rect
);
779 if (!PtInRect16( &rect
, pt
)) return HTNOWHERE
;
781 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
783 if (!(wndPtr
->flags
& WIN_MANAGED
))
786 if (HAS_SIZEFRAME( wndPtr
->dwStyle
))
788 InflateRect16( &rect
, -SYSMETRICS_CXFRAME
, -SYSMETRICS_CYFRAME
);
789 /* if (wndPtr->dwStyle & WS_BORDER) */
790 /* InflateRect16(&rect,-SYSMETRICS_CXBORDER,-SYSMETRICS_CYBORDER); */
791 if (!PtInRect16( &rect
, pt
))
793 /* Check top sizing border */
796 if (pt
.x
< rect
.left
+SYSMETRICS_CXSIZE
) return HTTOPLEFT
;
797 if (pt
.x
>= rect
.right
-SYSMETRICS_CXSIZE
) return HTTOPRIGHT
;
800 /* Check bottom sizing border */
801 if (pt
.y
>= rect
.bottom
)
803 if (pt
.x
< rect
.left
+SYSMETRICS_CXSIZE
) return HTBOTTOMLEFT
;
804 if (pt
.x
>= rect
.right
-SYSMETRICS_CXSIZE
) return HTBOTTOMRIGHT
;
807 /* Check left sizing border */
808 if (pt
.x
< rect
.left
)
810 if (pt
.y
< rect
.top
+SYSMETRICS_CYSIZE
) return HTTOPLEFT
;
811 if (pt
.y
>= rect
.bottom
-SYSMETRICS_CYSIZE
) return HTBOTTOMLEFT
;
814 /* Check right sizing border */
815 if (pt
.x
>= rect
.right
)
817 if (pt
.y
< rect
.top
+SYSMETRICS_CYSIZE
) return HTTOPRIGHT
;
818 if (pt
.y
>= rect
.bottom
-SYSMETRICS_CYSIZE
) return HTBOTTOMRIGHT
;
823 else /* No thick frame */
825 if (HAS_FIXEDFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
826 InflateRect16(&rect
, -SYSMETRICS_CXDLGFRAME
, -SYSMETRICS_CYDLGFRAME
);
827 /* else if (wndPtr->dwStyle & WS_BORDER) */
828 /* InflateRect16(&rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER); */
829 if (!PtInRect16( &rect
, pt
)) return HTBORDER
;
834 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
836 if (wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
)
837 rect
.top
+= sysMetrics
[SM_CYSMCAPTION
] - 1;
839 rect
.top
+= sysMetrics
[SM_CYCAPTION
] - 1;
840 if (!PtInRect16( &rect
, pt
))
842 /* Check system menu */
843 if ((wndPtr
->dwStyle
& WS_SYSMENU
) &&
844 ((wndPtr
->class->hIconSm
) || (wndPtr
->class->hIcon
)))
845 rect
.left
+= sysMetrics
[SM_CYCAPTION
] - 1;
846 if (pt
.x
< rect
.left
) return HTSYSMENU
;
848 /* Check close button */
849 if (wndPtr
->dwStyle
& WS_SYSMENU
)
850 rect
.right
-= sysMetrics
[SM_CYCAPTION
] - 1;
851 if (pt
.x
> rect
.right
) return HTCLOSE
;
853 /* Check maximize box */
854 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
855 rect
.right
-= SYSMETRICS_CXSIZE
+ 1;
856 if (pt
.x
> rect
.right
) return HTMAXBUTTON
;
858 /* Check minimize box */
859 if (wndPtr
->dwStyle
& WS_MINIMIZEBOX
)
860 rect
.right
-= SYSMETRICS_CXSIZE
+ 1;
861 if (pt
.x
> rect
.right
) return HTMINBUTTON
;
867 /* Check client area */
869 ScreenToClient16( wndPtr
->hwndSelf
, &pt
);
870 GetClientRect16( wndPtr
->hwndSelf
, &rect
);
871 if (PtInRect16( &rect
, pt
)) return HTCLIENT
;
873 /* Check vertical scroll bar */
875 if (wndPtr
->dwStyle
& WS_VSCROLL
)
877 rect
.right
+= SYSMETRICS_CXVSCROLL
;
878 if (PtInRect16( &rect
, pt
)) return HTVSCROLL
;
881 /* Check horizontal scroll bar */
883 if (wndPtr
->dwStyle
& WS_HSCROLL
)
885 rect
.bottom
+= SYSMETRICS_CYHSCROLL
;
886 if (PtInRect16( &rect
, pt
))
889 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
890 (pt
.x
>= rect
.right
- SYSMETRICS_CXVSCROLL
))
898 if (HAS_MENU(wndPtr
))
900 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
904 /* Should never get here */
909 /***********************************************************************
912 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
915 NC_HandleNCHitTest (HWND hwnd
, POINT16 pt
)
918 WND
*wndPtr
= WIN_FindWndPtr (hwnd
);
923 if (TWEAK_WineLook
== WIN31_LOOK
)
924 retvalue
= NC_DoNCHitTest (wndPtr
, pt
);
926 retvalue
= NC_DoNCHitTest95 (wndPtr
, pt
);
927 WIN_ReleaseWndPtr(wndPtr
);
932 /***********************************************************************
935 void NC_DrawSysButton( HWND hwnd
, HDC hdc
, BOOL down
)
940 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
942 if( !(wndPtr
->flags
& WIN_MANAGED
) )
944 NC_GetInsideRect( hwnd
, &rect
);
945 hdcMem
= CreateCompatibleDC( hdc
);
946 hbitmap
= SelectObject( hdcMem
, hbitmapClose
);
947 BitBlt(hdc
, rect
.left
, rect
.top
, SYSMETRICS_CXSIZE
, SYSMETRICS_CYSIZE
,
948 hdcMem
, (wndPtr
->dwStyle
& WS_CHILD
) ? SYSMETRICS_CXSIZE
: 0, 0,
949 down
? NOTSRCCOPY
: SRCCOPY
);
950 SelectObject( hdcMem
, hbitmap
);
953 WIN_ReleaseWndPtr(wndPtr
);
957 /***********************************************************************
960 static void NC_DrawMaxButton( HWND hwnd
, HDC16 hdc
, BOOL down
)
963 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
966 if( !(wndPtr
->flags
& WIN_MANAGED
) )
968 NC_GetInsideRect( hwnd
, &rect
);
969 hdcMem
= CreateCompatibleDC( hdc
);
970 SelectObject( hdcMem
, (IsZoomed(hwnd
)
971 ? (down
? hbitmapRestoreD
: hbitmapRestore
)
972 : (down
? hbitmapMaximizeD
: hbitmapMaximize
)) );
973 BitBlt( hdc
, rect
.right
- SYSMETRICS_CXSIZE
- 1, rect
.top
,
974 SYSMETRICS_CXSIZE
+ 1, SYSMETRICS_CYSIZE
, hdcMem
, 0, 0,
978 WIN_ReleaseWndPtr(wndPtr
);
983 /***********************************************************************
986 static void NC_DrawMinButton( HWND hwnd
, HDC16 hdc
, BOOL down
)
989 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
992 if( !(wndPtr
->flags
& WIN_MANAGED
) )
994 NC_GetInsideRect( hwnd
, &rect
);
995 hdcMem
= CreateCompatibleDC( hdc
);
996 SelectObject( hdcMem
, (down
? hbitmapMinimizeD
: hbitmapMinimize
) );
997 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
) rect
.right
-= SYSMETRICS_CXSIZE
+1;
998 BitBlt( hdc
, rect
.right
- SYSMETRICS_CXSIZE
- 1, rect
.top
,
999 SYSMETRICS_CXSIZE
+ 1, SYSMETRICS_CYSIZE
, hdcMem
, 0, 0,
1003 WIN_ReleaseWndPtr(wndPtr
);
1007 /******************************************************************************
1009 * void NC_DrawSysButton95(
1014 * Draws the Win95 system icon.
1017 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1018 * Original implementation from NC_DrawSysButton source.
1019 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1022 *****************************************************************************/
1025 NC_DrawSysButton95 (HWND hwnd
, HDC hdc
, BOOL down
)
1027 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1029 if( !(wndPtr
->flags
& WIN_MANAGED
) )
1034 NC_GetInsideRect95( hwnd
, &rect
);
1036 if (wndPtr
->class->hIconSm
)
1037 hIcon
= wndPtr
->class->hIconSm
;
1038 else if (wndPtr
->class->hIcon
)
1039 hIcon
= wndPtr
->class->hIcon
;
1042 DrawIconEx (hdc
, rect
.left
+ 2, rect
.top
+ 2, hIcon
,
1043 sysMetrics
[SM_CXSMICON
],
1044 sysMetrics
[SM_CYSMICON
],
1047 WIN_ReleaseWndPtr(wndPtr
);
1048 return (hIcon
!= 0);
1050 WIN_ReleaseWndPtr(wndPtr
);
1055 /******************************************************************************
1057 * void NC_DrawCloseButton95(
1062 * Draws the Win95 close button.
1065 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1066 * Original implementation from NC_DrawSysButton95 source.
1068 *****************************************************************************/
1070 void NC_DrawCloseButton95 (HWND hwnd
, HDC hdc
, BOOL down
)
1074 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1076 if( !(wndPtr
->flags
& WIN_MANAGED
) )
1079 HBITMAP hBmp
, hOldBmp
;
1081 NC_GetInsideRect95( hwnd
, &rect
);
1083 hdcMem
= CreateCompatibleDC( hdc
);
1084 hBmp
= down
? hbitmapCloseD
: hbitmapClose
;
1085 hOldBmp
= SelectObject (hdcMem
, hBmp
);
1086 GetObjectA (hBmp
, sizeof(BITMAP
), &bmp
);
1087 BitBlt (hdc
, rect
.right
- (sysMetrics
[SM_CYCAPTION
] + 1 + bmp
.bmWidth
) / 2,
1088 rect
.top
+ (sysMetrics
[SM_CYCAPTION
] - 1 - bmp
.bmHeight
) / 2,
1089 bmp
.bmWidth
, bmp
.bmHeight
, hdcMem
, 0, 0, SRCCOPY
);
1091 SelectObject (hdcMem
, hOldBmp
);
1094 WIN_ReleaseWndPtr(wndPtr
);
1097 /******************************************************************************
1099 * NC_DrawMaxButton95(
1104 * Draws the maximize button for Win95 style windows.
1107 * Many. Spacing might still be incorrect. Need to fit a close
1108 * button between the max button and the edge.
1109 * Should scale the image with the title bar. And more...
1112 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1113 * Original implementation.
1115 *****************************************************************************/
1117 static void NC_DrawMaxButton95(HWND hwnd
,HDC16 hdc
,BOOL down
)
1121 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1123 if( !(wndPtr
->flags
& WIN_MANAGED
))
1126 HBITMAP hBmp
,hOldBmp
;
1128 NC_GetInsideRect95( hwnd
, &rect
);
1129 hdcMem
= CreateCompatibleDC( hdc
);
1130 hBmp
= IsZoomed(hwnd
) ?
1131 (down
? hbitmapRestoreD
: hbitmapRestore
) :
1132 (down
? hbitmapMaximizeD
: hbitmapMaximize
);
1133 hOldBmp
=SelectObject( hdcMem
, hBmp
);
1134 GetObjectA (hBmp
, sizeof(BITMAP
), &bmp
);
1136 if (wndPtr
->dwStyle
& WS_SYSMENU
)
1137 rect
.right
-= sysMetrics
[SM_CYCAPTION
] + 1;
1139 BitBlt( hdc
, rect
.right
- (sysMetrics
[SM_CXSIZE
] + bmp
.bmWidth
) / 2,
1140 rect
.top
+ (sysMetrics
[SM_CYCAPTION
] - 1 - bmp
.bmHeight
) / 2,
1141 bmp
.bmWidth
, bmp
.bmHeight
, hdcMem
, 0, 0, SRCCOPY
);
1142 SelectObject (hdcMem
, hOldBmp
);
1145 WIN_ReleaseWndPtr(wndPtr
);
1148 /******************************************************************************
1150 * NC_DrawMinButton95(
1155 * Draws the minimize button for Win95 style windows.
1158 * Many. Spacing is still incorrect. Should scale the image with the
1159 * title bar. And more...
1162 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1163 * Original implementation.
1165 *****************************************************************************/
1167 static void NC_DrawMinButton95(HWND hwnd
,HDC16 hdc
,BOOL down
)
1171 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1173 if( !(wndPtr
->flags
& WIN_MANAGED
))
1177 HBITMAP hBmp
,hOldBmp
;
1179 NC_GetInsideRect95( hwnd
, &rect
);
1181 hdcMem
= CreateCompatibleDC( hdc
);
1182 hBmp
= down
? hbitmapMinimizeD
: hbitmapMinimize
;
1183 hOldBmp
= SelectObject( hdcMem
, hBmp
);
1184 GetObjectA (hBmp
, sizeof(BITMAP
), &bmp
);
1186 if (wndPtr
->dwStyle
& WS_SYSMENU
)
1187 rect
.right
-= sysMetrics
[SM_CYCAPTION
] + 1;
1189 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
1190 rect
.right
+= -1 - (sysMetrics
[SM_CXSIZE
] + bmp
.bmWidth
) / 2;
1192 BitBlt( hdc
, rect
.right
- (sysMetrics
[SM_CXSIZE
] + bmp
.bmWidth
) / 2,
1193 rect
.top
+ (sysMetrics
[SM_CYCAPTION
] - 1 - bmp
.bmHeight
) / 2,
1194 bmp
.bmWidth
, bmp
.bmHeight
, hdcMem
, 0, 0, SRCCOPY
);
1196 SelectObject (hdcMem
, hOldBmp
);
1199 WIN_ReleaseWndPtr(wndPtr
);
1202 /***********************************************************************
1205 * Draw a window frame inside the given rectangle, and update the rectangle.
1206 * The correct pen for the frame must be selected in the DC.
1208 static void NC_DrawFrame( HDC hdc
, RECT
*rect
, BOOL dlgFrame
,
1213 if (TWEAK_WineLook
!= WIN31_LOOK
)
1214 ERR (nonclient
, "Called in Win95 mode. Aiee! Please report this.\n" );
1218 width
= SYSMETRICS_CXDLGFRAME
- 1;
1219 height
= SYSMETRICS_CYDLGFRAME
- 1;
1220 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1221 COLOR_INACTIVECAPTION
) );
1225 width
= SYSMETRICS_CXFRAME
- 1;
1226 height
= SYSMETRICS_CYFRAME
- 1;
1227 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1228 COLOR_INACTIVEBORDER
) );
1232 PatBlt( hdc
, rect
->left
, rect
->top
,
1233 rect
->right
- rect
->left
, height
, PATCOPY
);
1234 PatBlt( hdc
, rect
->left
, rect
->top
,
1235 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1236 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1237 rect
->right
- rect
->left
, -height
, PATCOPY
);
1238 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1239 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1243 InflateRect( rect
, -width
, -height
);
1247 INT decYOff
= SYSMETRICS_CXFRAME
+ SYSMETRICS_CXSIZE
;
1248 INT decXOff
= SYSMETRICS_CYFRAME
+ SYSMETRICS_CYSIZE
;
1250 /* Draw inner rectangle */
1252 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1253 Rectangle( hdc
, rect
->left
+ width
, rect
->top
+ height
,
1254 rect
->right
- width
, rect
->bottom
- height
);
1256 /* Draw the decorations */
1258 MoveToEx( hdc
, rect
->left
, rect
->top
+ decYOff
, NULL
);
1259 LineTo( hdc
, rect
->left
+ width
, rect
->top
+ decYOff
);
1260 MoveToEx( hdc
, rect
->right
- 1, rect
->top
+ decYOff
, NULL
);
1261 LineTo( hdc
, rect
->right
- width
- 1, rect
->top
+ decYOff
);
1262 MoveToEx( hdc
, rect
->left
, rect
->bottom
- decYOff
, NULL
);
1263 LineTo( hdc
, rect
->left
+ width
, rect
->bottom
- decYOff
);
1264 MoveToEx( hdc
, rect
->right
- 1, rect
->bottom
- decYOff
, NULL
);
1265 LineTo( hdc
, rect
->right
- width
- 1, rect
->bottom
- decYOff
);
1267 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->top
, NULL
);
1268 LineTo( hdc
, rect
->left
+ decXOff
, rect
->top
+ height
);
1269 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->bottom
- 1, NULL
);
1270 LineTo( hdc
, rect
->left
+ decXOff
, rect
->bottom
- height
- 1 );
1271 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->top
, NULL
);
1272 LineTo( hdc
, rect
->right
- decXOff
, rect
->top
+ height
);
1273 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->bottom
- 1, NULL
);
1274 LineTo( hdc
, rect
->right
- decXOff
, rect
->bottom
- height
- 1 );
1276 InflateRect( rect
, -width
- 1, -height
- 1 );
1281 /******************************************************************************
1283 * void NC_DrawFrame95(
1289 * Draw a window frame inside the given rectangle, and update the rectangle.
1290 * The correct pen for the frame must be selected in the DC.
1293 * Many. First, just what IS a frame in Win95? Note that the 3D look
1294 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1295 * edge. The inner rectangle just inside the frame is handled by the
1298 * In short, for most people, this function should be a nop (unless
1299 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1300 * them lately, but just to get this code right). Even so, it doesn't
1301 * appear to be so. It's being worked on...
1304 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1305 * Original implementation (based on NC_DrawFrame)
1306 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1309 *****************************************************************************/
1311 static void NC_DrawFrame95(
1321 width
= sysMetrics
[SM_CXDLGFRAME
] - sysMetrics
[SM_CXEDGE
];
1322 height
= sysMetrics
[SM_CYDLGFRAME
] - sysMetrics
[SM_CYEDGE
];
1326 width
= sysMetrics
[SM_CXFRAME
] - sysMetrics
[SM_CXEDGE
];
1327 height
= sysMetrics
[SM_CYFRAME
] - sysMetrics
[SM_CYEDGE
];
1330 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1331 COLOR_INACTIVEBORDER
) );
1334 PatBlt( hdc
, rect
->left
, rect
->top
,
1335 rect
->right
- rect
->left
, height
, PATCOPY
);
1336 PatBlt( hdc
, rect
->left
, rect
->top
,
1337 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1338 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1339 rect
->right
- rect
->left
, -height
, PATCOPY
);
1340 PatBlt( hdc
, rect
->right
- 1, rect
->top
- 1,
1341 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1343 InflateRect( rect
, -width
, -height
);
1346 /***********************************************************************
1347 * NC_DrawMovingFrame
1349 * Draw the frame used when moving or resizing window.
1351 * FIXME: This causes problems in Win95 mode. (why?)
1353 static void NC_DrawMovingFrame( HDC hdc
, RECT
*rect
, BOOL thickframe
)
1358 CONV_RECT32TO16( rect
, &r16
);
1359 FastWindowFrame16( hdc
, &r16
, SYSMETRICS_CXFRAME
,
1360 SYSMETRICS_CYFRAME
, PATINVERT
);
1362 else DrawFocusRect( hdc
, rect
);
1366 /***********************************************************************
1369 * Draw the window caption.
1370 * The correct pen for the window frame must be selected in the DC.
1372 static void NC_DrawCaption( HDC hdc
, RECT
*rect
, HWND hwnd
,
1373 DWORD style
, BOOL active
)
1376 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1379 if (wndPtr
->flags
& WIN_MANAGED
)
1381 WIN_ReleaseWndPtr(wndPtr
);
1387 if (!(hbitmapClose
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE
) )))
1389 WIN_ReleaseWndPtr(wndPtr
);
1392 hbitmapCloseD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED
) );
1393 hbitmapMinimize
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE
) );
1394 hbitmapMinimizeD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED
) );
1395 hbitmapMaximize
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM
) );
1396 hbitmapMaximizeD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD
) );
1397 hbitmapRestore
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE
) );
1398 hbitmapRestoreD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED
) );
1401 if (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
)
1403 HBRUSH hbrushOld
= SelectObject(hdc
, GetSysColorBrush(COLOR_WINDOW
) );
1404 PatBlt( hdc
, r
.left
, r
.top
, 1, r
.bottom
-r
.top
+1,PATCOPY
);
1405 PatBlt( hdc
, r
.right
-1, r
.top
, 1, r
.bottom
-r
.top
+1, PATCOPY
);
1406 PatBlt( hdc
, r
.left
, r
.top
-1, r
.right
-r
.left
, 1, PATCOPY
);
1409 SelectObject( hdc
, hbrushOld
);
1411 WIN_ReleaseWndPtr(wndPtr
);
1412 MoveTo16( hdc
, r
.left
, r
.bottom
);
1413 LineTo( hdc
, r
.right
, r
.bottom
);
1415 if (style
& WS_SYSMENU
)
1417 NC_DrawSysButton( hwnd
, hdc
, FALSE
);
1418 r
.left
+= SYSMETRICS_CXSIZE
+ 1;
1419 MoveTo16( hdc
, r
.left
- 1, r
.top
);
1420 LineTo( hdc
, r
.left
- 1, r
.bottom
);
1422 if (style
& WS_MAXIMIZEBOX
)
1424 NC_DrawMaxButton( hwnd
, hdc
, FALSE
);
1425 r
.right
-= SYSMETRICS_CXSIZE
+ 1;
1427 if (style
& WS_MINIMIZEBOX
)
1429 NC_DrawMinButton( hwnd
, hdc
, FALSE
);
1430 r
.right
-= SYSMETRICS_CXSIZE
+ 1;
1433 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1434 COLOR_INACTIVECAPTION
) );
1436 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) ))
1438 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1439 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1440 SetBkMode( hdc
, TRANSPARENT
);
1441 DrawTextA( hdc
, buffer
, -1, &r
,
1442 DT_SINGLELINE
| DT_CENTER
| DT_VCENTER
| DT_NOPREFIX
);
1447 /******************************************************************************
1456 * Draw the window caption for Win95 style windows.
1457 * The correct pen for the window frame must be selected in the DC.
1460 * Hey, a function that finally works! Well, almost.
1461 * It's being worked on.
1464 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1465 * Original implementation.
1466 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1469 *****************************************************************************/
1471 static void NC_DrawCaption95(
1480 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1484 if (wndPtr
->flags
& WIN_MANAGED
)
1486 WIN_ReleaseWndPtr(wndPtr
);
1489 WIN_ReleaseWndPtr(wndPtr
);
1491 hPrevPen
= SelectObject( hdc
, GetSysColorPen(COLOR_3DFACE
) );
1492 MoveToEx( hdc
, r
.left
, r
.bottom
- 1, NULL
);
1493 LineTo( hdc
, r
.right
, r
.bottom
- 1 );
1494 SelectObject( hdc
, hPrevPen
);
1497 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1498 COLOR_INACTIVECAPTION
) );
1500 if (!hbitmapClose
) {
1501 if (!(hbitmapClose
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE
) )))
1503 hbitmapCloseD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED
));
1504 hbitmapMinimize
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE
) );
1505 hbitmapMinimizeD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED
) );
1506 hbitmapMaximize
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM
) );
1507 hbitmapMaximizeD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD
) );
1508 hbitmapRestore
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE
) );
1509 hbitmapRestoreD
= LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED
) );
1512 if ((style
& WS_SYSMENU
) && !(exStyle
& WS_EX_TOOLWINDOW
)) {
1513 if (NC_DrawSysButton95 (hwnd
, hdc
, FALSE
))
1514 r
.left
+= sysMetrics
[SM_CYCAPTION
] - 1;
1516 if (style
& WS_SYSMENU
) {
1517 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
);
1518 r
.right
-= sysMetrics
[SM_CYCAPTION
] - 1;
1520 if (style
& WS_MAXIMIZEBOX
) {
1521 NC_DrawMaxButton95( hwnd
, hdc
, FALSE
);
1522 r
.right
-= SYSMETRICS_CXSIZE
+ 1;
1524 if (style
& WS_MINIMIZEBOX
) {
1525 NC_DrawMinButton95( hwnd
, hdc
, FALSE
);
1526 r
.right
-= SYSMETRICS_CXSIZE
+ 1;
1529 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) )) {
1530 NONCLIENTMETRICSA nclm
;
1531 HFONT hFont
, hOldFont
;
1532 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
1533 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
1534 if (exStyle
& WS_EX_TOOLWINDOW
)
1535 hFont
= CreateFontIndirectA (&nclm
.lfSmCaptionFont
);
1537 hFont
= CreateFontIndirectA (&nclm
.lfCaptionFont
);
1538 hOldFont
= SelectObject (hdc
, hFont
);
1539 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1540 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1541 SetBkMode( hdc
, TRANSPARENT
);
1543 DrawTextA( hdc
, buffer
, -1, &r
,
1544 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
1545 DeleteObject (SelectObject (hdc
, hOldFont
));
1551 /***********************************************************************
1554 * Paint the non-client area. clip is currently unused.
1556 void NC_DoNCPaint( WND
* wndPtr
, HRGN clip
, BOOL suppress_menupaint
)
1561 HWND hwnd
= wndPtr
->hwndSelf
;
1563 if ( wndPtr
->dwStyle
& WS_MINIMIZE
||
1564 !WIN_IsWindowDrawable( wndPtr
, 0 )) return; /* Nothing to do */
1566 active
= wndPtr
->flags
& WIN_NCACTIVATED
;
1568 TRACE(nonclient
, "%04x %d\n", hwnd
, active
);
1570 if (!(hdc
= GetDCEx( hwnd
, (clip
> 1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
1571 ((clip
> 1) ? (DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
): 0) ))) return;
1573 if (ExcludeVisRect16( hdc
, wndPtr
->rectClient
.left
-wndPtr
->rectWindow
.left
,
1574 wndPtr
->rectClient
.top
-wndPtr
->rectWindow
.top
,
1575 wndPtr
->rectClient
.right
-wndPtr
->rectWindow
.left
,
1576 wndPtr
->rectClient
.bottom
-wndPtr
->rectWindow
.top
)
1579 ReleaseDC( hwnd
, hdc
);
1583 rect
.top
= rect
.left
= 0;
1584 rect
.right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
1585 rect
.bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
1587 SelectObject( hdc
, GetSysColorPen(COLOR_WINDOWFRAME
) );
1589 if (!(wndPtr
->flags
& WIN_MANAGED
))
1591 if ((wndPtr
->dwStyle
& WS_BORDER
) || (wndPtr
->dwStyle
& WS_DLGFRAME
) ||
1592 (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
))
1594 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1595 Rectangle( hdc
, 0, 0, rect
.right
, rect
.bottom
);
1596 InflateRect( &rect
, -1, -1 );
1599 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1600 NC_DrawFrame( hdc
, &rect
, TRUE
, active
);
1601 else if (wndPtr
->dwStyle
& WS_THICKFRAME
)
1602 NC_DrawFrame(hdc
, &rect
, FALSE
, active
);
1604 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1607 r
.bottom
= rect
.top
+ SYSMETRICS_CYSIZE
;
1608 rect
.top
+= SYSMETRICS_CYSIZE
+ SYSMETRICS_CYBORDER
;
1609 NC_DrawCaption( hdc
, &r
, hwnd
, wndPtr
->dwStyle
, active
);
1613 if (HAS_MENU(wndPtr
))
1616 r
.bottom
= rect
.top
+ SYSMETRICS_CYMENU
; /* default height */
1617 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
);
1620 /* Draw the scroll-bars */
1622 if (wndPtr
->dwStyle
& WS_VSCROLL
)
1623 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1624 if (wndPtr
->dwStyle
& WS_HSCROLL
)
1625 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1627 /* Draw the "size-box" */
1629 if ((wndPtr
->dwStyle
& WS_VSCROLL
) && (wndPtr
->dwStyle
& WS_HSCROLL
))
1632 r
.left
= r
.right
- SYSMETRICS_CXVSCROLL
+ 1;
1633 r
.top
= r
.bottom
- SYSMETRICS_CYHSCROLL
+ 1;
1634 if(wndPtr
->dwStyle
& WS_BORDER
) {
1638 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1641 ReleaseDC( hwnd
, hdc
);
1645 /******************************************************************************
1647 * void NC_DoNCPaint95(
1650 * BOOL32 suppress_menupaint )
1652 * Paint the non-client area for Win95 windows. The clip region is
1653 * currently ignored.
1656 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1657 * misc/tweak.c controls/menu.c # :-)
1660 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1661 * Original implementation
1662 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1665 *****************************************************************************/
1667 void NC_DoNCPaint95(
1670 BOOL suppress_menupaint
)
1673 RECT rfuzz
, rect
, rectClip
;
1675 HWND hwnd
= wndPtr
->hwndSelf
;
1677 if ( wndPtr
->dwStyle
& WS_MINIMIZE
||
1678 !WIN_IsWindowDrawable( wndPtr
, 0 )) return; /* Nothing to do */
1680 active
= wndPtr
->flags
& WIN_NCACTIVATED
;
1682 TRACE(nonclient
, "%04x %d\n", hwnd
, active
);
1684 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in the call to
1685 * GetDCEx implying that it is allowed not to use it either. However, the suggested
1686 * GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN) will cause clipRgn to be deleted
1687 * after ReleaseDC(). Now, how is the "system" supposed to tell what happened?
1690 if (!(hdc
= GetDCEx( hwnd
, (clip
> 1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
1691 ((clip
> 1) ?(DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
) : 0) ))) return;
1694 if (ExcludeVisRect16( hdc
, wndPtr
->rectClient
.left
-wndPtr
->rectWindow
.left
,
1695 wndPtr
->rectClient
.top
-wndPtr
->rectWindow
.top
,
1696 wndPtr
->rectClient
.right
-wndPtr
->rectWindow
.left
,
1697 wndPtr
->rectClient
.bottom
-wndPtr
->rectWindow
.top
)
1700 ReleaseDC( hwnd
, hdc
);
1704 rect
.top
= rect
.left
= 0;
1705 rect
.right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
1706 rect
.bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
1709 GetRgnBox( clip
, &rectClip
);
1716 SelectObject( hdc
, GetSysColorPen(COLOR_WINDOWFRAME
) );
1718 if(!(wndPtr
->flags
& WIN_MANAGED
)) {
1719 if ((wndPtr
->dwStyle
& WS_BORDER
) && ((wndPtr
->dwStyle
& WS_DLGFRAME
) ||
1720 (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
) || (wndPtr
->dwStyle
& WS_THICKFRAME
))) {
1721 DrawEdge (hdc
, &rect
, EDGE_RAISED
, BF_RECT
| BF_ADJUST
);
1724 if (HAS_FIXEDFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1725 NC_DrawFrame95( hdc
, &rect
, TRUE
, active
);
1726 else if (wndPtr
->dwStyle
& WS_THICKFRAME
)
1727 NC_DrawFrame95(hdc
, &rect
, FALSE
, active
);
1729 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1732 if (wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
) {
1733 r
.bottom
= rect
.top
+ sysMetrics
[SM_CYSMCAPTION
];
1734 rect
.top
+= sysMetrics
[SM_CYSMCAPTION
];
1737 r
.bottom
= rect
.top
+ sysMetrics
[SM_CYCAPTION
];
1738 rect
.top
+= sysMetrics
[SM_CYCAPTION
];
1740 if( !clip
|| IntersectRect( &rfuzz
, &r
, &rectClip
) )
1741 NC_DrawCaption95 (hdc
, &r
, hwnd
, wndPtr
->dwStyle
,
1742 wndPtr
->dwExStyle
, active
);
1746 if (HAS_MENU(wndPtr
))
1749 r
.bottom
= rect
.top
+ sysMetrics
[SM_CYMENU
];
1751 TRACE(nonclient
, "Calling DrawMenuBar with "
1752 "rect (%d, %d)-(%d, %d)\n", r
.left
, r
.top
,
1755 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
) + 1;
1758 TRACE(nonclient
, "After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1759 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1761 if (wndPtr
->dwExStyle
& WS_EX_CLIENTEDGE
)
1762 DrawEdge (hdc
, &rect
, EDGE_SUNKEN
, BF_RECT
| BF_ADJUST
);
1764 if (wndPtr
->dwExStyle
& WS_EX_STATICEDGE
)
1765 DrawEdge (hdc
, &rect
, BDR_SUNKENOUTER
, BF_RECT
| BF_ADJUST
);
1767 /* Draw the scroll-bars */
1769 if (wndPtr
->dwStyle
& WS_VSCROLL
)
1770 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1771 if (wndPtr
->dwStyle
& WS_HSCROLL
)
1772 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1774 /* Draw the "size-box" */
1775 if ((wndPtr
->dwStyle
& WS_VSCROLL
) && (wndPtr
->dwStyle
& WS_HSCROLL
))
1778 r
.left
= r
.right
- SYSMETRICS_CXVSCROLL
+ 1;
1779 r
.top
= r
.bottom
- SYSMETRICS_CYHSCROLL
+ 1;
1780 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1783 ReleaseDC( hwnd
, hdc
);
1789 /***********************************************************************
1792 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1794 LONG
NC_HandleNCPaint( HWND hwnd
, HRGN clip
)
1796 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1798 if( wndPtr
&& wndPtr
->dwStyle
& WS_VISIBLE
)
1800 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
1801 WINPOS_RedrawIconTitle( hwnd
);
1802 else if (TWEAK_WineLook
== WIN31_LOOK
)
1803 NC_DoNCPaint( wndPtr
, clip
, FALSE
);
1805 NC_DoNCPaint95( wndPtr
, clip
, FALSE
);
1807 WIN_ReleaseWndPtr(wndPtr
);
1812 /***********************************************************************
1813 * NC_HandleNCActivate
1815 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1817 LONG
NC_HandleNCActivate( WND
*wndPtr
, WPARAM16 wParam
)
1821 if( wParam
) wStateChange
= !(wndPtr
->flags
& WIN_NCACTIVATED
);
1822 else wStateChange
= wndPtr
->flags
& WIN_NCACTIVATED
;
1826 if (wParam
) wndPtr
->flags
|= WIN_NCACTIVATED
;
1827 else wndPtr
->flags
&= ~WIN_NCACTIVATED
;
1829 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
1830 WINPOS_RedrawIconTitle( wndPtr
->hwndSelf
);
1831 else if (TWEAK_WineLook
== WIN31_LOOK
)
1832 NC_DoNCPaint( wndPtr
, (HRGN
)1, FALSE
);
1834 NC_DoNCPaint95( wndPtr
, (HRGN
)1, FALSE
);
1840 /***********************************************************************
1841 * NC_HandleSetCursor
1843 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1845 LONG
NC_HandleSetCursor( HWND hwnd
, WPARAM16 wParam
, LPARAM lParam
)
1847 if (hwnd
!= (HWND
)wParam
) return 0; /* Don't set the cursor for child windows */
1849 switch(LOWORD(lParam
))
1853 WORD msg
= HIWORD( lParam
);
1854 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_MBUTTONDOWN
) ||
1855 (msg
== WM_RBUTTONDOWN
))
1865 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) break;
1866 if (wndPtr
->class->hCursor
)
1868 SetCursor16( wndPtr
->class->hCursor
);
1871 else retvalue
= FALSE
;
1872 WIN_ReleaseWndPtr(wndPtr
);
1878 return (LONG
)SetCursor16( LoadCursor16( 0, IDC_SIZEWE16
) );
1882 return (LONG
)SetCursor16( LoadCursor16( 0, IDC_SIZENS16
) );
1886 return (LONG
)SetCursor16( LoadCursor16( 0, IDC_SIZENWSE16
) );
1890 return (LONG
)SetCursor16( LoadCursor16( 0, IDC_SIZENESW16
) );
1893 /* Default cursor: arrow */
1894 return (LONG
)SetCursor16( LoadCursor16( 0, IDC_ARROW16
) );
1897 /***********************************************************************
1900 BOOL
NC_GetSysPopupPos( WND
* wndPtr
, RECT
* rect
)
1902 if( wndPtr
->hSysMenu
)
1904 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
1905 GetWindowRect( wndPtr
->hwndSelf
, rect
);
1908 if (TWEAK_WineLook
== WIN31_LOOK
)
1909 NC_GetInsideRect( wndPtr
->hwndSelf
, rect
);
1911 NC_GetInsideRect95( wndPtr
->hwndSelf
, rect
);
1912 OffsetRect( rect
, wndPtr
->rectWindow
.left
, wndPtr
->rectWindow
.top
);
1913 if (wndPtr
->dwStyle
& WS_CHILD
)
1914 ClientToScreen( wndPtr
->parent
->hwndSelf
, (POINT
*)rect
);
1915 if (TWEAK_WineLook
== WIN31_LOOK
) {
1916 rect
->right
= rect
->left
+ SYSMETRICS_CXSIZE
;
1917 rect
->bottom
= rect
->top
+ SYSMETRICS_CYSIZE
;
1920 rect
->right
= rect
->left
+ sysMetrics
[SM_CYCAPTION
] - 1;
1921 rect
->bottom
= rect
->top
+ sysMetrics
[SM_CYCAPTION
] - 1;
1929 /***********************************************************************
1932 * Initialisation of a move or resize, when initiatied from a menu choice.
1933 * Return hit test code for caption or sizing border.
1935 static LONG
NC_StartSizeMove( WND
* wndPtr
, WPARAM16 wParam
,
1936 POINT16
*capturePoint
)
1942 if ((wParam
& 0xfff0) == SC_MOVE
)
1944 /* Move pointer at the center of the caption */
1946 if (TWEAK_WineLook
== WIN31_LOOK
)
1947 NC_GetInsideRect( wndPtr
->hwndSelf
, &rect
);
1949 NC_GetInsideRect95( wndPtr
->hwndSelf
, &rect
);
1950 if (wndPtr
->dwStyle
& WS_SYSMENU
)
1951 rect
.left
+= SYSMETRICS_CXSIZE
+ 1;
1952 if (wndPtr
->dwStyle
& WS_MINIMIZEBOX
)
1953 rect
.right
-= SYSMETRICS_CXSIZE
+ 1;
1954 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
1955 rect
.right
-= SYSMETRICS_CXSIZE
+ 1;
1956 pt
.x
= wndPtr
->rectWindow
.left
+ (rect
.right
- rect
.left
) / 2;
1957 pt
.y
= wndPtr
->rectWindow
.top
+ rect
.top
+ SYSMETRICS_CYSIZE
/2;
1958 hittest
= HTCAPTION
;
1965 MSG_InternalGetMessage( &msg
, 0, 0, MSGF_SIZE
, PM_REMOVE
, FALSE
);
1969 CONV_POINT32TO16(&msg
.pt
, &pt
);
1970 hittest
= NC_HandleNCHitTest( wndPtr
->hwndSelf
, pt
);
1971 if ((hittest
< HTLEFT
) || (hittest
> HTBOTTOMRIGHT
))
1983 pt
.x
=(wndPtr
->rectWindow
.left
+wndPtr
->rectWindow
.right
)/2;
1984 pt
.y
= wndPtr
->rectWindow
.top
+ SYSMETRICS_CYFRAME
/ 2;
1988 pt
.x
=(wndPtr
->rectWindow
.left
+wndPtr
->rectWindow
.right
)/2;
1989 pt
.y
= wndPtr
->rectWindow
.bottom
- SYSMETRICS_CYFRAME
/ 2;
1993 pt
.x
= wndPtr
->rectWindow
.left
+ SYSMETRICS_CXFRAME
/ 2;
1994 pt
.y
=(wndPtr
->rectWindow
.top
+wndPtr
->rectWindow
.bottom
)/2;
1998 pt
.x
= wndPtr
->rectWindow
.right
- SYSMETRICS_CXFRAME
/ 2;
1999 pt
.y
=(wndPtr
->rectWindow
.top
+wndPtr
->rectWindow
.bottom
)/2;
2002 case VK_ESCAPE
: return 0;
2008 SetCursorPos( pt
.x
, pt
.y
);
2009 NC_HandleSetCursor( wndPtr
->hwndSelf
,
2010 wndPtr
->hwndSelf
, MAKELONG( hittest
, WM_MOUSEMOVE
));
2015 /***********************************************************************
2018 * Perform SC_MOVE and SC_SIZE commands. `
2020 static void NC_DoSizeMove( HWND hwnd
, WORD wParam
)
2023 RECT sizingRect
, mouseRect
;
2025 LONG hittest
= (LONG
)(wParam
& 0x0f);
2026 HCURSOR16 hDragCursor
= 0, hOldCursor
= 0;
2027 POINT minTrack
, maxTrack
;
2028 POINT16 capturePoint
, pt
;
2029 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
2030 BOOL thickframe
= HAS_THICKFRAME( wndPtr
->dwStyle
);
2031 BOOL iconic
= wndPtr
->dwStyle
& WS_MINIMIZE
;
2033 DWORD dwPoint
= GetMessagePos ();
2035 capturePoint
= pt
= *(POINT16
*)&dwPoint
;
2037 if (IsZoomed(hwnd
) || !IsWindowVisible(hwnd
) ||
2038 (wndPtr
->flags
& WIN_MANAGED
)) goto END
;
2040 if ((wParam
& 0xfff0) == SC_MOVE
)
2042 if (!(wndPtr
->dwStyle
& WS_CAPTION
)) goto END
;
2044 hittest
= NC_StartSizeMove( wndPtr
, wParam
, &capturePoint
);
2045 if (!hittest
) goto END
;
2049 if (!thickframe
) goto END
;
2050 if ( hittest
&& hittest
!= HTSYSMENU
) hittest
+= 2;
2054 hittest
= NC_StartSizeMove( wndPtr
, wParam
, &capturePoint
);
2063 /* Get min/max info */
2065 WINPOS_GetMinMaxInfo( wndPtr
, NULL
, NULL
, &minTrack
, &maxTrack
);
2066 sizingRect
= wndPtr
->rectWindow
;
2067 if (wndPtr
->dwStyle
& WS_CHILD
)
2068 GetClientRect( wndPtr
->parent
->hwndSelf
, &mouseRect
);
2070 SetRect(&mouseRect
, 0, 0, SYSMETRICS_CXSCREEN
, SYSMETRICS_CYSCREEN
);
2071 if (ON_LEFT_BORDER(hittest
))
2073 mouseRect
.left
= MAX( mouseRect
.left
, sizingRect
.right
-maxTrack
.x
);
2074 mouseRect
.right
= MIN( mouseRect
.right
, sizingRect
.right
-minTrack
.x
);
2076 else if (ON_RIGHT_BORDER(hittest
))
2078 mouseRect
.left
= MAX( mouseRect
.left
, sizingRect
.left
+minTrack
.x
);
2079 mouseRect
.right
= MIN( mouseRect
.right
, sizingRect
.left
+maxTrack
.x
);
2081 if (ON_TOP_BORDER(hittest
))
2083 mouseRect
.top
= MAX( mouseRect
.top
, sizingRect
.bottom
-maxTrack
.y
);
2084 mouseRect
.bottom
= MIN( mouseRect
.bottom
,sizingRect
.bottom
-minTrack
.y
);
2086 else if (ON_BOTTOM_BORDER(hittest
))
2088 mouseRect
.top
= MAX( mouseRect
.top
, sizingRect
.top
+minTrack
.y
);
2089 mouseRect
.bottom
= MIN( mouseRect
.bottom
, sizingRect
.top
+maxTrack
.y
);
2091 if (wndPtr
->dwStyle
& WS_CHILD
)
2093 MapWindowPoints( wndPtr
->parent
->hwndSelf
, 0,
2094 (LPPOINT
)&mouseRect
, 2 );
2096 SendMessage16( hwnd
, WM_ENTERSIZEMOVE
, 0, 0 );
2098 if (GetCapture() != hwnd
) SetCapture( hwnd
);
2100 if (wndPtr
->dwStyle
& WS_CHILD
)
2102 /* Retrieve a default cache DC (without using the window style) */
2103 hdc
= GetDCEx( wndPtr
->parent
->hwndSelf
, 0, DCX_CACHE
);
2106 { /* Grab the server only when moving top-level windows without desktop */
2110 wndPtr
->pDriver
->pPreSizeMove(wndPtr
);
2112 if( iconic
) /* create a cursor for dragging */
2114 HICON16 hIcon
= (wndPtr
->class->hIcon
) ? wndPtr
->class->hIcon
2115 : (HICON16
)SendMessage16( hwnd
, WM_QUERYDRAGICON
, 0, 0L);
2116 if( hIcon
) hDragCursor
= CURSORICON_IconToCursor( hIcon
, TRUE
);
2117 if( !hDragCursor
) iconic
= FALSE
;
2120 if( !iconic
) NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2126 MSG_InternalGetMessage( &msg
, 0, 0, MSGF_SIZE
, PM_REMOVE
, FALSE
);
2128 /* Exit on button-up, Return, or Esc */
2129 if ((msg
.message
== WM_LBUTTONUP
) ||
2130 ((msg
.message
== WM_KEYDOWN
) &&
2131 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
2133 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
2134 continue; /* We are not interested in other messages */
2136 dwPoint
= GetMessagePos ();
2137 pt
= *(POINT16
*)&dwPoint
;
2139 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
2141 case VK_UP
: pt
.y
-= 8; break;
2142 case VK_DOWN
: pt
.y
+= 8; break;
2143 case VK_LEFT
: pt
.x
-= 8; break;
2144 case VK_RIGHT
: pt
.x
+= 8; break;
2147 pt
.x
= MAX( pt
.x
, mouseRect
.left
);
2148 pt
.x
= MIN( pt
.x
, mouseRect
.right
);
2149 pt
.y
= MAX( pt
.y
, mouseRect
.top
);
2150 pt
.y
= MIN( pt
.y
, mouseRect
.bottom
);
2152 dx
= pt
.x
- capturePoint
.x
;
2153 dy
= pt
.y
- capturePoint
.y
;
2160 if( iconic
) /* ok, no system popup tracking */
2162 hOldCursor
= SetCursor(hDragCursor
);
2164 WINPOS_ShowIconTitle( wndPtr
, FALSE
);
2168 if (msg
.message
== WM_KEYDOWN
) SetCursorPos( pt
.x
, pt
.y
);
2171 RECT newRect
= sizingRect
;
2173 if (hittest
== HTCAPTION
) OffsetRect( &newRect
, dx
, dy
);
2174 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
2175 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
2176 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
2177 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
2180 NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2181 NC_DrawMovingFrame( hdc
, &newRect
, thickframe
);
2184 sizingRect
= newRect
;
2192 if( moved
) /* restore cursors, show icon title later on */
2194 ShowCursor( FALSE
);
2195 SetCursor( hOldCursor
);
2197 DestroyCursor( hDragCursor
);
2200 NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2202 if (wndPtr
->dwStyle
& WS_CHILD
)
2203 ReleaseDC( wndPtr
->parent
->hwndSelf
, hdc
);
2206 ReleaseDC( 0, hdc
);
2209 wndPtr
->pDriver
->pPostSizeMove(wndPtr
);
2211 if (HOOK_IsHooked( WH_CBT
))
2213 RECT16
* pr
= SEGPTR_NEW(RECT16
);
2216 CONV_RECT32TO16( &sizingRect
, pr
);
2217 if( HOOK_CallHooks16( WH_CBT
, HCBT_MOVESIZE
, hwnd
,
2218 (LPARAM
)SEGPTR_GET(pr
)) )
2219 sizingRect
= wndPtr
->rectWindow
;
2221 CONV_RECT16TO32( pr
, &sizingRect
);
2225 SendMessage16( hwnd
, WM_EXITSIZEMOVE
, 0, 0 );
2226 SendMessage16( hwnd
, WM_SETVISIBLE
, !IsIconic16(hwnd
), 0L);
2228 if( moved
&& !((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
2230 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
2231 SetWindowPos( hwnd
, 0, sizingRect
.left
, sizingRect
.top
,
2232 sizingRect
.right
- sizingRect
.left
,
2233 sizingRect
.bottom
- sizingRect
.top
,
2234 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
2237 if( IsWindow(hwnd
) )
2238 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
2240 /* Single click brings up the system menu when iconized */
2244 if( wndPtr
->dwStyle
& WS_SYSMENU
)
2245 SendMessage16( hwnd
, WM_SYSCOMMAND
,
2246 SC_MOUSEMENU
+ HTSYSMENU
, *((LPARAM
*)&pt
));
2248 else WINPOS_ShowIconTitle( wndPtr
, TRUE
);
2252 WIN_ReleaseWndPtr(wndPtr
);
2256 /***********************************************************************
2259 * Track a mouse button press on the minimize or maximize box.
2261 static void NC_TrackMinMaxBox( HWND hwnd
, WORD wParam
)
2265 HDC hdc
= GetWindowDC( hwnd
);
2266 BOOL pressed
= TRUE
;
2267 void (*paintButton
)(HWND
, HDC16
, BOOL
);
2270 if (wParam
== HTMINBUTTON
)
2272 (TWEAK_WineLook
== WIN31_LOOK
) ? &NC_DrawMinButton
: &NC_DrawMinButton95
;
2275 (TWEAK_WineLook
== WIN31_LOOK
) ? &NC_DrawMaxButton
: &NC_DrawMaxButton95
;
2277 (*paintButton
)( hwnd
, hdc
, TRUE
);
2281 BOOL oldstate
= pressed
;
2282 MSG_InternalGetMessage( &msg
, 0, 0, 0, PM_REMOVE
, FALSE
);
2283 CONV_POINT32TO16( &msg
.pt
, &pt16
);
2285 pressed
= (NC_HandleNCHitTest( hwnd
, pt16
) == wParam
);
2286 if (pressed
!= oldstate
)
2287 (*paintButton
)( hwnd
, hdc
, pressed
);
2288 } while (msg
.message
!= WM_LBUTTONUP
);
2290 (*paintButton
)( hwnd
, hdc
, FALSE
);
2293 ReleaseDC( hwnd
, hdc
);
2294 if (!pressed
) return;
2296 if (wParam
== HTMINBUTTON
)
2297 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, *(LONG
*)&pt16
);
2299 SendMessage16( hwnd
, WM_SYSCOMMAND
,
2300 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, *(LONG
*)&pt16
);
2304 /***********************************************************************
2305 * NC_TrackCloseButton95
2307 * Track a mouse button press on the Win95 close button.
2310 NC_TrackCloseButton95 (HWND hwnd
, WORD wParam
)
2314 HDC hdc
= GetWindowDC( hwnd
);
2315 BOOL pressed
= TRUE
;
2319 NC_DrawCloseButton95 (hwnd
, hdc
, TRUE
);
2323 BOOL oldstate
= pressed
;
2324 MSG_InternalGetMessage( &msg
, 0, 0, 0, PM_REMOVE
, FALSE
);
2325 CONV_POINT32TO16( &msg
.pt
, &pt16
);
2327 pressed
= (NC_HandleNCHitTest( hwnd
, pt16
) == wParam
);
2328 if (pressed
!= oldstate
)
2329 NC_DrawCloseButton95 (hwnd
, hdc
, pressed
);
2330 } while (msg
.message
!= WM_LBUTTONUP
);
2332 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
);
2335 ReleaseDC( hwnd
, hdc
);
2336 if (!pressed
) return;
2338 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, *(LONG
*)&pt16
);
2342 /***********************************************************************
2345 * Track a mouse button press on the horizontal or vertical scroll-bar.
2347 static void NC_TrackScrollBar( HWND hwnd
, WPARAM wParam
, POINT pt
)
2351 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
2353 if ((wParam
& 0xfff0) == SC_HSCROLL
)
2355 if ((wParam
& 0x0f) != HTHSCROLL
) goto END
;
2356 scrollbar
= SB_HORZ
;
2358 else /* SC_VSCROLL */
2360 if ((wParam
& 0x0f) != HTVSCROLL
) goto END
;
2361 scrollbar
= SB_VERT
;
2364 if (!(msg
= SEGPTR_NEW(MSG16
))) goto END
;
2365 pt
.x
-= wndPtr
->rectWindow
.left
;
2366 pt
.y
-= wndPtr
->rectWindow
.top
;
2368 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, WM_LBUTTONDOWN
, pt
);
2372 GetMessage16( SEGPTR_GET(msg
), 0, 0, 0 );
2373 switch(msg
->message
)
2378 pt
.x
= LOWORD(msg
->lParam
) + wndPtr
->rectClient
.left
-
2379 wndPtr
->rectWindow
.left
;
2380 pt
.y
= HIWORD(msg
->lParam
) + wndPtr
->rectClient
.top
-
2381 wndPtr
->rectWindow
.top
;
2382 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, msg
->message
, pt
);
2385 TranslateMessage16( msg
);
2386 DispatchMessage16( msg
);
2389 if (!IsWindow( hwnd
))
2394 } while (msg
->message
!= WM_LBUTTONUP
);
2397 WIN_ReleaseWndPtr(wndPtr
);
2400 /***********************************************************************
2401 * NC_HandleNCLButtonDown
2403 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2405 LONG
NC_HandleNCLButtonDown( WND
* pWnd
, WPARAM16 wParam
, LPARAM lParam
)
2407 HWND hwnd
= pWnd
->hwndSelf
;
2409 switch(wParam
) /* Hit test */
2412 hwnd
= WIN_GetTopParent(hwnd
);
2414 if( WINPOS_SetActiveWindow(hwnd
, TRUE
, TRUE
) || (GetActiveWindow() == hwnd
) )
2415 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_MOVE
+ HTCAPTION
, lParam
);
2419 if( pWnd
->dwStyle
& WS_SYSMENU
)
2421 if( !(pWnd
->dwStyle
& WS_MINIMIZE
) )
2423 HDC hDC
= GetWindowDC(hwnd
);
2424 if (TWEAK_WineLook
== WIN31_LOOK
)
2425 NC_DrawSysButton( hwnd
, hDC
, TRUE
);
2427 NC_DrawSysButton95( hwnd
, hDC
, TRUE
);
2428 ReleaseDC( hwnd
, hDC
);
2430 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
+ HTSYSMENU
, lParam
);
2435 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
, lParam
);
2439 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
2443 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
2448 NC_TrackMinMaxBox( hwnd
, wParam
);
2452 if (TWEAK_WineLook
>= WIN95_LOOK
)
2453 NC_TrackCloseButton95 (hwnd
, wParam
);
2464 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2465 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_SIZE
+ wParam
- 2, lParam
);
2475 /***********************************************************************
2476 * NC_HandleNCLButtonDblClk
2478 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2480 LONG
NC_HandleNCLButtonDblClk( WND
*pWnd
, WPARAM16 wParam
, LPARAM lParam
)
2483 * if this is an icon, send a restore since we are handling
2486 if (pWnd
->dwStyle
& WS_MINIMIZE
)
2488 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_RESTORE
, lParam
);
2492 switch(wParam
) /* Hit test */
2495 /* stop processing if WS_MAXIMIZEBOX is missing */
2496 if (pWnd
->dwStyle
& WS_MAXIMIZEBOX
)
2497 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
,
2498 (pWnd
->dwStyle
& WS_MAXIMIZE
) ? SC_RESTORE
: SC_MAXIMIZE
,
2503 if (!(pWnd
->class->style
& CS_NOCLOSE
))
2504 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_CLOSE
, lParam
);
2508 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
,
2513 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
,
2521 /***********************************************************************
2522 * NC_HandleSysCommand
2524 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2526 LONG
NC_HandleSysCommand( HWND hwnd
, WPARAM16 wParam
, POINT16 pt
)
2528 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
2530 UINT16 uCommand
= wParam
& 0xFFF0;
2532 TRACE(nonclient
, "Handling WM_SYSCOMMAND %x %d,%d\n",
2533 wParam
, pt
.x
, pt
.y
);
2535 if (wndPtr
->dwStyle
& WS_CHILD
&& uCommand
!= SC_KEYMENU
)
2536 ScreenToClient16( wndPtr
->parent
->hwndSelf
, &pt
);
2542 NC_DoSizeMove( hwnd
, wParam
);
2546 ShowWindow( hwnd
, SW_MINIMIZE
);
2550 ShowWindow( hwnd
, SW_MAXIMIZE
);
2554 ShowWindow( hwnd
, SW_RESTORE
);
2558 WIN_ReleaseWndPtr(wndPtr
);
2559 return SendMessage16( hwnd
, WM_CLOSE
, 0, 0 );
2563 CONV_POINT16TO32( &pt
, &pt32
);
2564 NC_TrackScrollBar( hwnd
, wParam
, pt32
);
2568 CONV_POINT16TO32( &pt
, &pt32
);
2569 MENU_TrackMouseMenuBar( wndPtr
, wParam
& 0x000F, pt32
);
2573 MENU_TrackKbdMenuBar( wndPtr
, wParam
, pt
.x
);
2577 WinExec( "taskman.exe", SW_SHOWNORMAL
);
2581 if (wParam
== SC_ABOUTWINE
)
2582 ShellAboutA(hwnd
,"Wine", WINE_RELEASE_INFO
, 0);
2584 if (wParam
== SC_PUTMARK
)
2585 TRACE(shell
,"Mark requested by user\n");
2592 FIXME (nonclient
, "unimplemented!\n");
2595 WIN_ReleaseWndPtr(wndPtr
);