2 * Non-client area window functions
4 * Copyright 1994 Alexandre Julliard
10 #include "wine/winuser16.h"
18 #include "cursoricon.h"
21 #include "nonclient.h"
23 #include "debugtools.h"
28 DEFAULT_DEBUG_CHANNEL(nonclient
);
29 DECLARE_DEBUG_CHANNEL(shell
);
31 BOOL
NC_DrawGrayButton(HDC hdc
, int x
, int y
);
33 static HBITMAP hbitmapClose
;
34 static HBITMAP hbitmapMinimize
;
35 static HBITMAP hbitmapMinimizeD
;
36 static HBITMAP hbitmapMaximize
;
37 static HBITMAP hbitmapMaximizeD
;
38 static HBITMAP hbitmapRestore
;
39 static HBITMAP hbitmapRestoreD
;
41 static const BYTE lpGrayMask
[] = { 0xAA, 0xA0,
52 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
53 #define SC_PUTMARK (SC_SCREENSAVE+2)
55 /* Some useful macros */
56 #define HAS_DLGFRAME(style,exStyle) \
57 (((exStyle) & WS_EX_DLGMODALFRAME) || \
58 (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
60 #define HAS_THICKFRAME(style,exStyle) \
61 (((style) & WS_THICKFRAME) && \
62 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
64 #define HAS_THINFRAME(style) \
65 (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
67 #define HAS_BIGFRAME(style,exStyle) \
68 (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
69 ((exStyle) & WS_EX_DLGMODALFRAME))
71 #define HAS_ANYFRAME(style,exStyle) \
72 (((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
73 ((exStyle) & WS_EX_DLGMODALFRAME) || \
74 !((style) & (WS_CHILD | WS_POPUP)))
76 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
78 #define ON_LEFT_BORDER(hit) \
79 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
80 #define ON_RIGHT_BORDER(hit) \
81 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
82 #define ON_TOP_BORDER(hit) \
83 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
84 #define ON_BOTTOM_BORDER(hit) \
85 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
87 /***********************************************************************
88 * WIN_WindowNeedsWMBorder
90 * This method defines the rules for a window to have a WM border,
91 * caption... It is used for consistency purposes.
93 BOOL
WIN_WindowNeedsWMBorder( DWORD style
, DWORD exStyle
)
95 if (!(style
& WS_CHILD
) &&
97 !(exStyle
& WS_EX_TOOLWINDOW
) &&
98 ( ((style
& WS_CAPTION
) == WS_CAPTION
) ||
99 (style
& WS_THICKFRAME
)))
101 if (exStyle
& WS_EX_TRAYWINDOW
)
106 /***********************************************************************
109 * Compute the size of the window rectangle from the size of the
112 static void NC_AdjustRect( LPRECT16 rect
, DWORD style
, BOOL menu
,
115 if (TWEAK_WineLook
> WIN31_LOOK
)
116 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
118 if(style
& WS_ICONIC
) return;
119 /* Decide if the window will be managed (see CreateWindowEx) */
120 if (!WIN_WindowNeedsWMBorder(style
, exStyle
))
122 if (HAS_THICKFRAME( style
, exStyle
))
123 InflateRect16( rect
, GetSystemMetrics(SM_CXFRAME
), GetSystemMetrics(SM_CYFRAME
) );
125 if (HAS_DLGFRAME( style
, exStyle
))
126 InflateRect16( rect
, GetSystemMetrics(SM_CXDLGFRAME
), GetSystemMetrics(SM_CYDLGFRAME
) );
128 if (HAS_THINFRAME( style
))
129 InflateRect16( rect
, GetSystemMetrics(SM_CXBORDER
), GetSystemMetrics(SM_CYBORDER
));
131 if ((style
& WS_CAPTION
) == WS_CAPTION
)
132 rect
->top
-= GetSystemMetrics(SM_CYCAPTION
) - GetSystemMetrics(SM_CYBORDER
);
134 if (menu
) rect
->top
-= GetSystemMetrics(SM_CYMENU
) + GetSystemMetrics(SM_CYBORDER
);
136 if (style
& WS_VSCROLL
) {
137 rect
->right
+= GetSystemMetrics(SM_CXVSCROLL
) - 1;
138 if(!HAS_ANYFRAME( style
, exStyle
))
142 if (style
& WS_HSCROLL
) {
143 rect
->bottom
+= GetSystemMetrics(SM_CYHSCROLL
) - 1;
144 if(!HAS_ANYFRAME( style
, exStyle
))
150 /******************************************************************************
151 * NC_AdjustRectOuter95
153 * Computes the size of the "outside" parts of the window based on the
154 * parameters of the client area.
163 * "Outer" parts of a window means the whole window frame, caption and
164 * menu bar. It does not include "inner" parts of the frame like client
165 * edge, static edge or scroll bars.
168 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
169 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
171 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
172 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
173 * NC_AdjustRectInner95 and added handling of Win95 styles.
175 * 28-Jul-1999 Ove Kåven (ovek@arcticnet.no)
176 * Streamlined window style checks.
178 *****************************************************************************/
181 NC_AdjustRectOuter95 (LPRECT16 rect
, DWORD style
, BOOL menu
, DWORD exStyle
)
183 if(style
& WS_ICONIC
) return;
185 /* Decide if the window will be managed (see CreateWindowEx) */
186 if (!WIN_WindowNeedsWMBorder(style
, exStyle
))
188 if (HAS_THICKFRAME( style
, exStyle
))
189 InflateRect16( rect
, GetSystemMetrics(SM_CXFRAME
), GetSystemMetrics(SM_CYFRAME
) );
191 if (HAS_DLGFRAME( style
, exStyle
))
192 InflateRect16(rect
, GetSystemMetrics(SM_CXDLGFRAME
), GetSystemMetrics(SM_CYDLGFRAME
) );
194 if (HAS_THINFRAME( style
))
195 InflateRect16( rect
, GetSystemMetrics(SM_CXBORDER
), GetSystemMetrics(SM_CYBORDER
));
197 if ((style
& WS_CAPTION
) == WS_CAPTION
)
199 if (exStyle
& WS_EX_TOOLWINDOW
)
200 rect
->top
-= GetSystemMetrics(SM_CYSMCAPTION
);
202 rect
->top
-= GetSystemMetrics(SM_CYCAPTION
);
207 rect
->top
-= GetSystemMetrics(SM_CYMENU
);
211 /******************************************************************************
212 * NC_AdjustRectInner95
214 * Computes the size of the "inside" part of the window based on the
215 * parameters of the client area.
223 * "Inner" part of a window means the window frame inside of the flat
224 * window frame. It includes the client edge, the static edge and the
228 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
229 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
231 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
232 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
233 * NC_AdjustRectInner95 and added handling of Win95 styles.
235 *****************************************************************************/
238 NC_AdjustRectInner95 (LPRECT16 rect
, DWORD style
, DWORD exStyle
)
240 if(style
& WS_ICONIC
) return;
242 if (exStyle
& WS_EX_CLIENTEDGE
)
243 InflateRect16 (rect
, GetSystemMetrics(SM_CXEDGE
), GetSystemMetrics(SM_CYEDGE
));
245 if (exStyle
& WS_EX_STATICEDGE
)
246 InflateRect16 (rect
, GetSystemMetrics(SM_CXBORDER
), GetSystemMetrics(SM_CYBORDER
));
248 if (style
& WS_VSCROLL
) rect
->right
+= GetSystemMetrics(SM_CXVSCROLL
);
249 if (style
& WS_HSCROLL
) rect
->bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
253 /***********************************************************************
254 * DrawCaption (USER.660) Draws a caption bar
268 DrawCaption16 (HWND16 hwnd
, HDC16 hdc
, const RECT16
*rect
, UINT16 uFlags
)
273 CONV_RECT16TO32 (rect
, &rect32
);
275 return (BOOL16
)DrawCaptionTempA (hwnd
, hdc
, rect
? &rect32
: NULL
,
276 0, 0, NULL
, uFlags
& 0x1F);
280 /***********************************************************************
281 * DrawCaption (USER32.@) Draws a caption bar
295 DrawCaption (HWND hwnd
, HDC hdc
, const RECT
*lpRect
, UINT uFlags
)
297 return DrawCaptionTempA (hwnd
, hdc
, lpRect
, 0, 0, NULL
, uFlags
& 0x1F);
301 /***********************************************************************
302 * DrawCaptionTemp (USER.657)
312 DrawCaptionTemp16 (HWND16 hwnd
, HDC16 hdc
, const RECT16
*rect
, HFONT16 hFont
,
313 HICON16 hIcon
, LPCSTR str
, UINT16 uFlags
)
318 CONV_RECT16TO32(rect
,&rect32
);
320 return (BOOL16
)DrawCaptionTempA (hwnd
, hdc
, rect
?&rect32
:NULL
, hFont
,
321 hIcon
, str
, uFlags
& 0x1F);
325 /***********************************************************************
326 * DrawCaptionTempA (USER32.@)
336 DrawCaptionTempA (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
337 HICON hIcon
, LPCSTR str
, UINT uFlags
)
341 TRACE("(%08x,%08x,%p,%08x,%08x,\"%s\",%08x)\n",
342 hwnd
, hdc
, rect
, hFont
, hIcon
, str
, uFlags
);
344 /* drawing background */
345 if (uFlags
& DC_INBUTTON
) {
346 FillRect (hdc
, &rc
, GetSysColorBrush (COLOR_3DFACE
));
348 if (uFlags
& DC_ACTIVE
) {
349 HBRUSH hbr
= SelectObject (hdc
, CACHE_GetPattern55AABrush ());
350 PatBlt (hdc
, rc
.left
, rc
.top
,
351 rc
.right
-rc
.left
, rc
.bottom
-rc
.top
, 0xFA0089);
352 SelectObject (hdc
, hbr
);
356 FillRect (hdc
, &rc
, GetSysColorBrush ((uFlags
& DC_ACTIVE
) ?
357 COLOR_ACTIVECAPTION
: COLOR_INACTIVECAPTION
));
362 if ((uFlags
& DC_ICON
) && !(uFlags
& DC_SMALLCAP
)) {
366 pt
.y
= (rc
.bottom
+ rc
.top
- GetSystemMetrics(SM_CYSMICON
)) / 2;
369 DrawIconEx (hdc
, pt
.x
, pt
.y
, hIcon
, GetSystemMetrics(SM_CXSMICON
),
370 GetSystemMetrics(SM_CYSMICON
), 0, 0, DI_NORMAL
);
373 WND
* wndPtr
= WIN_FindWndPtr(hwnd
);
374 HICON hAppIcon
= (HICON
) NC_IconForWindow(wndPtr
);
375 DrawIconEx (hdc
, pt
.x
, pt
.y
, hAppIcon
, GetSystemMetrics(SM_CXSMICON
),
376 GetSystemMetrics(SM_CYSMICON
), 0, 0, DI_NORMAL
);
377 WIN_ReleaseWndPtr(wndPtr
);
380 rc
.left
+= (rc
.bottom
- rc
.top
);
384 if (uFlags
& DC_TEXT
) {
387 if (uFlags
& DC_INBUTTON
)
388 SetTextColor (hdc
, GetSysColor (COLOR_BTNTEXT
));
389 else if (uFlags
& DC_ACTIVE
)
390 SetTextColor (hdc
, GetSysColor (COLOR_CAPTIONTEXT
));
392 SetTextColor (hdc
, GetSysColor (COLOR_INACTIVECAPTIONTEXT
));
394 SetBkMode (hdc
, TRANSPARENT
);
397 hOldFont
= SelectObject (hdc
, hFont
);
399 NONCLIENTMETRICSA nclm
;
401 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
402 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
403 hNewFont
= CreateFontIndirectA ((uFlags
& DC_SMALLCAP
) ?
404 &nclm
.lfSmCaptionFont
: &nclm
.lfCaptionFont
);
405 hOldFont
= SelectObject (hdc
, hNewFont
);
409 DrawTextA (hdc
, str
, -1, &rc
,
410 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
414 nLen
= GetWindowTextA (hwnd
, szText
, 128);
415 DrawTextA (hdc
, szText
, nLen
, &rc
,
416 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
420 SelectObject (hdc
, hOldFont
);
422 DeleteObject (SelectObject (hdc
, hOldFont
));
425 /* drawing focus ??? */
427 FIXME("undocumented flag (0x2000)!\n");
433 /***********************************************************************
434 * DrawCaptionTempW (USER32.@)
444 DrawCaptionTempW (HWND hwnd
, HDC hdc
, const RECT
*rect
, HFONT hFont
,
445 HICON hIcon
, LPCWSTR str
, UINT uFlags
)
447 LPSTR p
= HEAP_strdupWtoA (GetProcessHeap (), 0, str
);
448 BOOL res
= DrawCaptionTempA (hwnd
, hdc
, rect
, hFont
, hIcon
, p
, uFlags
);
449 HeapFree (GetProcessHeap (), 0, p
);
454 /***********************************************************************
455 * AdjustWindowRect (USER.102)
457 BOOL16 WINAPI
AdjustWindowRect16( LPRECT16 rect
, DWORD style
, BOOL16 menu
)
459 return AdjustWindowRectEx16( rect
, style
, menu
, 0 );
463 /***********************************************************************
464 * AdjustWindowRect (USER32.@)
466 BOOL WINAPI
AdjustWindowRect( LPRECT rect
, DWORD style
, BOOL menu
)
468 return AdjustWindowRectEx( rect
, style
, menu
, 0 );
472 /***********************************************************************
473 * AdjustWindowRectEx (USER.454)
475 BOOL16 WINAPI
AdjustWindowRectEx16( LPRECT16 rect
, DWORD style
,
476 BOOL16 menu
, DWORD exStyle
)
478 /* Correct the window style */
480 if (!(style
& (WS_POPUP
| WS_CHILD
))) /* Overlapped window */
482 style
&= (WS_DLGFRAME
| WS_BORDER
| WS_THICKFRAME
| WS_CHILD
);
483 exStyle
&= (WS_EX_DLGMODALFRAME
| WS_EX_CLIENTEDGE
|
484 WS_EX_STATICEDGE
| WS_EX_TOOLWINDOW
);
485 if (exStyle
& WS_EX_DLGMODALFRAME
) style
&= ~WS_THICKFRAME
;
487 TRACE("(%d,%d)-(%d,%d) %08lx %d %08lx\n",
488 rect
->left
, rect
->top
, rect
->right
, rect
->bottom
,
489 style
, menu
, exStyle
);
491 if (TWEAK_WineLook
== WIN31_LOOK
)
492 NC_AdjustRect( rect
, style
, menu
, exStyle
);
494 NC_AdjustRectOuter95( rect
, style
, menu
, exStyle
);
495 NC_AdjustRectInner95( rect
, style
, exStyle
);
502 /***********************************************************************
503 * AdjustWindowRectEx (USER32.@)
505 BOOL WINAPI
AdjustWindowRectEx( LPRECT rect
, DWORD style
,
506 BOOL menu
, DWORD exStyle
)
511 CONV_RECT32TO16( rect
, &rect16
);
512 ret
= AdjustWindowRectEx16( &rect16
, style
, (BOOL16
)menu
, exStyle
);
513 CONV_RECT16TO32( &rect16
, rect
);
518 /***********************************************************************
519 * NC_HandleNCCalcSize
521 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
523 LONG
NC_HandleNCCalcSize( WND
*pWnd
, RECT
*winRect
)
525 RECT16 tmpRect
= { 0, 0, 0, 0 };
527 UINT style
= (UINT
) GetClassLongA(pWnd
->hwndSelf
, GCL_STYLE
);
529 if (style
& CS_VREDRAW
) result
|= WVR_VREDRAW
;
530 if (style
& CS_HREDRAW
) result
|= WVR_HREDRAW
;
532 if( !( pWnd
->dwStyle
& WS_MINIMIZE
) ) {
533 if (TWEAK_WineLook
== WIN31_LOOK
)
534 NC_AdjustRect( &tmpRect
, pWnd
->dwStyle
, FALSE
, pWnd
->dwExStyle
);
536 NC_AdjustRectOuter95( &tmpRect
, pWnd
->dwStyle
, FALSE
, pWnd
->dwExStyle
);
538 winRect
->left
-= tmpRect
.left
;
539 winRect
->top
-= tmpRect
.top
;
540 winRect
->right
-= tmpRect
.right
;
541 winRect
->bottom
-= tmpRect
.bottom
;
543 if (HAS_MENU(pWnd
)) {
544 TRACE("Calling GetMenuBarHeight with HWND 0x%x, width %d, "
545 "at (%d, %d).\n", pWnd
->hwndSelf
,
546 winRect
->right
- winRect
->left
,
547 -tmpRect
.left
, -tmpRect
.top
);
550 MENU_GetMenuBarHeight( pWnd
->hwndSelf
,
551 winRect
->right
- winRect
->left
,
552 -tmpRect
.left
, -tmpRect
.top
) + 1;
555 if (TWEAK_WineLook
> WIN31_LOOK
) {
556 SetRect16 (&tmpRect
, 0, 0, 0, 0);
557 NC_AdjustRectInner95 (&tmpRect
, pWnd
->dwStyle
, pWnd
->dwExStyle
);
558 winRect
->left
-= tmpRect
.left
;
559 winRect
->top
-= tmpRect
.top
;
560 winRect
->right
-= tmpRect
.right
;
561 winRect
->bottom
-= tmpRect
.bottom
;
564 if (winRect
->top
> winRect
->bottom
)
565 winRect
->bottom
= winRect
->top
;
567 if (winRect
->left
> winRect
->right
)
568 winRect
->right
= winRect
->left
;
574 /***********************************************************************
577 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
578 * but without the borders (if any).
579 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
581 static void NC_GetInsideRect( HWND hwnd
, RECT
*rect
)
583 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
585 rect
->top
= rect
->left
= 0;
586 rect
->right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
587 rect
->bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
589 if ((wndPtr
->dwStyle
& WS_ICONIC
) || (wndPtr
->dwExStyle
& WS_EX_MANAGED
)) goto END
;
591 /* Remove frame from rectangle */
592 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
593 InflateRect( rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
595 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
597 InflateRect( rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
598 /* FIXME: this isn't in NC_AdjustRect? why not? */
599 if (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
)
600 InflateRect( rect
, -1, 0 );
603 if (HAS_THINFRAME( wndPtr
->dwStyle
))
604 InflateRect( rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
) );
606 WIN_ReleaseWndPtr(wndPtr
);
611 /***********************************************************************
614 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
615 * but without the borders (if any).
616 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
620 NC_GetInsideRect95 (HWND hwnd
, RECT
*rect
)
622 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
624 rect
->top
= rect
->left
= 0;
625 rect
->right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
626 rect
->bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
628 if ((wndPtr
->dwStyle
& WS_ICONIC
) || (wndPtr
->dwExStyle
& WS_EX_MANAGED
)) goto END
;
630 /* Remove frame from rectangle */
631 if (HAS_THICKFRAME (wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
633 InflateRect( rect
, -GetSystemMetrics(SM_CXSIZEFRAME
), -GetSystemMetrics(SM_CYSIZEFRAME
) );
635 else if (HAS_DLGFRAME (wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
637 InflateRect( rect
, -GetSystemMetrics(SM_CXFIXEDFRAME
), -GetSystemMetrics(SM_CYFIXEDFRAME
));
639 else if (HAS_THINFRAME (wndPtr
->dwStyle
))
641 InflateRect( rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
) );
644 /* We have additional border information if the window
645 * is a child (but not an MDI child) */
646 if ( (wndPtr
->dwStyle
& WS_CHILD
) &&
647 ( (wndPtr
->dwExStyle
& WS_EX_MDICHILD
) == 0 ) )
649 if (wndPtr
->dwExStyle
& WS_EX_CLIENTEDGE
)
650 InflateRect (rect
, -GetSystemMetrics(SM_CXEDGE
), -GetSystemMetrics(SM_CYEDGE
));
652 if (wndPtr
->dwExStyle
& WS_EX_STATICEDGE
)
653 InflateRect (rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
656 WIN_ReleaseWndPtr(wndPtr
);
661 /***********************************************************************
664 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
667 static LONG
NC_DoNCHitTest (WND
*wndPtr
, POINT pt
)
671 TRACE("hwnd=%04x pt=%ld,%ld\n", wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
673 GetWindowRect(wndPtr
->hwndSelf
, &rect
);
674 if (!PtInRect( &rect
, pt
)) return HTNOWHERE
;
676 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
678 if (!(wndPtr
->dwExStyle
& WS_EX_MANAGED
))
681 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
683 InflateRect( &rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
684 if (!PtInRect( &rect
, pt
))
686 /* Check top sizing border */
689 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
690 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
693 /* Check bottom sizing border */
694 if (pt
.y
>= rect
.bottom
)
696 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
697 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
700 /* Check left sizing border */
701 if (pt
.x
< rect
.left
)
703 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
704 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
707 /* Check right sizing border */
708 if (pt
.x
>= rect
.right
)
710 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
711 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
716 else /* No thick frame */
718 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
719 InflateRect(&rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
720 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
721 InflateRect(&rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
722 if (!PtInRect( &rect
, pt
)) return HTBORDER
;
727 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
729 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
) - GetSystemMetrics(SM_CYBORDER
);
730 if (!PtInRect( &rect
, pt
))
732 /* Check system menu */
733 if ((wndPtr
->dwStyle
& WS_SYSMENU
) && !(wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
))
734 rect
.left
+= GetSystemMetrics(SM_CXSIZE
);
735 if (pt
.x
<= rect
.left
) return HTSYSMENU
;
737 /* Check maximize box */
738 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
739 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
741 if (pt
.x
>= rect
.right
) return HTMAXBUTTON
;
742 /* Check minimize box */
743 if (wndPtr
->dwStyle
& WS_MINIMIZEBOX
)
744 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
745 if (pt
.x
>= rect
.right
) return HTMINBUTTON
;
751 /* Check client area */
753 ScreenToClient( wndPtr
->hwndSelf
, &pt
);
754 GetClientRect( wndPtr
->hwndSelf
, &rect
);
755 if (PtInRect( &rect
, pt
)) return HTCLIENT
;
757 /* Check vertical scroll bar */
759 if (wndPtr
->dwStyle
& WS_VSCROLL
)
761 rect
.right
+= GetSystemMetrics(SM_CXVSCROLL
);
762 if (PtInRect( &rect
, pt
)) return HTVSCROLL
;
765 /* Check horizontal scroll bar */
767 if (wndPtr
->dwStyle
& WS_HSCROLL
)
769 rect
.bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
770 if (PtInRect( &rect
, pt
))
773 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
774 (pt
.x
>= rect
.right
- GetSystemMetrics(SM_CXVSCROLL
)))
782 if (HAS_MENU(wndPtr
))
784 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
788 /* Has to return HTNOWHERE if nothing was found
789 Could happen when a window has a customized non client area */
794 /***********************************************************************
797 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
799 * FIXME: Just a modified copy of the Win 3.1 version.
802 static LONG
NC_DoNCHitTest95 (WND
*wndPtr
, POINT pt
)
806 TRACE("hwnd=%04x pt=%ld,%ld\n", wndPtr
->hwndSelf
, pt
.x
, pt
.y
);
808 GetWindowRect(wndPtr
->hwndSelf
, &rect
);
809 if (!PtInRect( &rect
, pt
)) return HTNOWHERE
;
811 if (wndPtr
->dwStyle
& WS_MINIMIZE
) return HTCAPTION
;
813 if (!(wndPtr
->dwExStyle
& WS_EX_MANAGED
))
816 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
818 InflateRect( &rect
, -GetSystemMetrics(SM_CXFRAME
), -GetSystemMetrics(SM_CYFRAME
) );
819 if (!PtInRect( &rect
, pt
))
821 /* Check top sizing border */
824 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTTOPLEFT
;
825 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTTOPRIGHT
;
828 /* Check bottom sizing border */
829 if (pt
.y
>= rect
.bottom
)
831 if (pt
.x
< rect
.left
+GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMLEFT
;
832 if (pt
.x
>= rect
.right
-GetSystemMetrics(SM_CXSIZE
)) return HTBOTTOMRIGHT
;
835 /* Check left sizing border */
836 if (pt
.x
< rect
.left
)
838 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPLEFT
;
839 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMLEFT
;
842 /* Check right sizing border */
843 if (pt
.x
>= rect
.right
)
845 if (pt
.y
< rect
.top
+GetSystemMetrics(SM_CYSIZE
)) return HTTOPRIGHT
;
846 if (pt
.y
>= rect
.bottom
-GetSystemMetrics(SM_CYSIZE
)) return HTBOTTOMRIGHT
;
851 else /* No thick frame */
853 if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
854 InflateRect(&rect
, -GetSystemMetrics(SM_CXDLGFRAME
), -GetSystemMetrics(SM_CYDLGFRAME
));
855 else if (HAS_THINFRAME( wndPtr
->dwStyle
))
856 InflateRect(&rect
, -GetSystemMetrics(SM_CXBORDER
), -GetSystemMetrics(SM_CYBORDER
));
857 if (!PtInRect( &rect
, pt
)) return HTBORDER
;
862 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
864 if (wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
)
865 rect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
) - 1;
867 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
868 if (!PtInRect( &rect
, pt
))
870 /* Check system menu */
871 if ((wndPtr
->dwStyle
& WS_SYSMENU
) && !(wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
))
873 if (NC_IconForWindow(wndPtr
))
874 rect
.left
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
876 if (pt
.x
< rect
.left
) return HTSYSMENU
;
878 /* Check close button */
879 if (wndPtr
->dwStyle
& WS_SYSMENU
)
880 rect
.right
-= GetSystemMetrics(SM_CYCAPTION
) - 1;
881 if (pt
.x
> rect
.right
) return HTCLOSE
;
883 /* Check maximize box */
884 /* In win95 there is automatically a Maximize button when there is a minimize one*/
885 if ((wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)|| (wndPtr
->dwStyle
& WS_MINIMIZEBOX
))
886 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
887 if (pt
.x
> rect
.right
) return HTMAXBUTTON
;
889 /* Check minimize box */
890 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
891 if ((wndPtr
->dwStyle
& WS_MINIMIZEBOX
)||(wndPtr
->dwStyle
& WS_MAXIMIZEBOX
))
892 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
894 if (pt
.x
> rect
.right
) return HTMINBUTTON
;
900 /* Check client area */
902 ScreenToClient( wndPtr
->hwndSelf
, &pt
);
903 GetClientRect( wndPtr
->hwndSelf
, &rect
);
904 if (PtInRect( &rect
, pt
)) return HTCLIENT
;
906 /* Check vertical scroll bar */
908 if (wndPtr
->dwStyle
& WS_VSCROLL
)
910 rect
.right
+= GetSystemMetrics(SM_CXVSCROLL
);
911 if (PtInRect( &rect
, pt
)) return HTVSCROLL
;
914 /* Check horizontal scroll bar */
916 if (wndPtr
->dwStyle
& WS_HSCROLL
)
918 rect
.bottom
+= GetSystemMetrics(SM_CYHSCROLL
);
919 if (PtInRect( &rect
, pt
))
922 if ((wndPtr
->dwStyle
& WS_VSCROLL
) &&
923 (pt
.x
>= rect
.right
- GetSystemMetrics(SM_CXVSCROLL
)))
931 if (HAS_MENU(wndPtr
))
933 if ((pt
.y
< 0) && (pt
.x
>= 0) && (pt
.x
< rect
.right
))
937 /* Has to return HTNOWHERE if nothing was found
938 Could happen when a window has a customized non client area */
943 /***********************************************************************
946 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
948 LONG
NC_HandleNCHitTest (HWND hwnd
, POINT pt
)
951 WND
*wndPtr
= WIN_FindWndPtr (hwnd
);
956 if (TWEAK_WineLook
== WIN31_LOOK
)
957 retvalue
= NC_DoNCHitTest (wndPtr
, pt
);
959 retvalue
= NC_DoNCHitTest95 (wndPtr
, pt
);
960 WIN_ReleaseWndPtr(wndPtr
);
965 /***********************************************************************
968 void NC_DrawSysButton( HWND hwnd
, HDC hdc
, BOOL down
)
973 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
975 if( !(wndPtr
->dwExStyle
& WS_EX_MANAGED
) )
977 NC_GetInsideRect( hwnd
, &rect
);
978 hdcMem
= CreateCompatibleDC( hdc
);
979 hbitmap
= SelectObject( hdcMem
, hbitmapClose
);
980 BitBlt(hdc
, rect
.left
, rect
.top
, GetSystemMetrics(SM_CXSIZE
), GetSystemMetrics(SM_CYSIZE
),
981 hdcMem
, (wndPtr
->dwStyle
& WS_CHILD
) ? GetSystemMetrics(SM_CXSIZE
) : 0, 0,
982 down
? NOTSRCCOPY
: SRCCOPY
);
983 SelectObject( hdcMem
, hbitmap
);
986 WIN_ReleaseWndPtr(wndPtr
);
990 /***********************************************************************
993 static void NC_DrawMaxButton( HWND hwnd
, HDC16 hdc
, BOOL down
)
996 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
999 if( !(wndPtr
->dwExStyle
& WS_EX_MANAGED
) )
1001 NC_GetInsideRect( hwnd
, &rect
);
1002 hdcMem
= CreateCompatibleDC( hdc
);
1003 SelectObject( hdcMem
, (IsZoomed(hwnd
)
1004 ? (down
? hbitmapRestoreD
: hbitmapRestore
)
1005 : (down
? hbitmapMaximizeD
: hbitmapMaximize
)) );
1006 BitBlt( hdc
, rect
.right
- GetSystemMetrics(SM_CXSIZE
) - 1, rect
.top
,
1007 GetSystemMetrics(SM_CXSIZE
) + 1, GetSystemMetrics(SM_CYSIZE
), hdcMem
, 0, 0,
1011 WIN_ReleaseWndPtr(wndPtr
);
1016 /***********************************************************************
1019 static void NC_DrawMinButton( HWND hwnd
, HDC16 hdc
, BOOL down
)
1022 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1025 if( !(wndPtr
->dwExStyle
& WS_EX_MANAGED
) )
1027 NC_GetInsideRect( hwnd
, &rect
);
1028 hdcMem
= CreateCompatibleDC( hdc
);
1029 SelectObject( hdcMem
, (down
? hbitmapMinimizeD
: hbitmapMinimize
) );
1030 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
) rect
.right
-= GetSystemMetrics(SM_CXSIZE
)+1;
1031 BitBlt( hdc
, rect
.right
- GetSystemMetrics(SM_CXSIZE
) - 1, rect
.top
,
1032 GetSystemMetrics(SM_CXSIZE
) + 1, GetSystemMetrics(SM_CYSIZE
), hdcMem
, 0, 0,
1036 WIN_ReleaseWndPtr(wndPtr
);
1040 /******************************************************************************
1042 * void NC_DrawSysButton95(
1047 * Draws the Win95 system icon.
1050 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1051 * Original implementation from NC_DrawSysButton source.
1052 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1055 *****************************************************************************/
1058 NC_DrawSysButton95 (HWND hwnd
, HDC hdc
, BOOL down
)
1060 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1062 if( !(wndPtr
->dwExStyle
& WS_EX_MANAGED
) )
1067 NC_GetInsideRect95( hwnd
, &rect
);
1069 hIcon
= NC_IconForWindow( wndPtr
);
1072 DrawIconEx (hdc
, rect
.left
+ 2, rect
.top
+ 2, hIcon
,
1073 GetSystemMetrics(SM_CXSMICON
),
1074 GetSystemMetrics(SM_CYSMICON
),
1077 WIN_ReleaseWndPtr(wndPtr
);
1078 return (hIcon
!= 0);
1080 WIN_ReleaseWndPtr(wndPtr
);
1085 /******************************************************************************
1087 * void NC_DrawCloseButton95(
1093 * Draws the Win95 close button.
1095 * If bGrayed is true, then draw a disabled Close button
1098 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1099 * Original implementation from NC_DrawSysButton95 source.
1101 *****************************************************************************/
1103 static void NC_DrawCloseButton95 (HWND hwnd
, HDC hdc
, BOOL down
, BOOL bGrayed
)
1106 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1108 if( !(wndPtr
->dwExStyle
& WS_EX_MANAGED
) )
1110 NC_GetInsideRect95( hwnd
, &rect
);
1112 /* A tool window has a smaller Close button */
1113 if(wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
)
1115 INT iBmpHeight
= 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
1116 INT iBmpWidth
= 11; /* it uses 11x11 for the close button in tool window */
1117 INT iCaptionHeight
= GetSystemMetrics(SM_CYSMCAPTION
);
1119 rect
.top
= rect
.top
+ (iCaptionHeight
- 1 - iBmpHeight
) / 2;
1120 rect
.left
= rect
.right
- (iCaptionHeight
+ 1 + iBmpWidth
) / 2;
1121 rect
.bottom
= rect
.top
+ iBmpHeight
;
1122 rect
.right
= rect
.left
+ iBmpWidth
;
1126 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
) - 1;
1127 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1131 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
,
1132 (DFCS_CAPTIONCLOSE
|
1133 (down
? DFCS_PUSHED
: 0) |
1134 (bGrayed
? DFCS_INACTIVE
: 0)) );
1136 WIN_ReleaseWndPtr(wndPtr
);
1139 /******************************************************************************
1140 * NC_DrawMaxButton95
1142 * Draws the maximize button for Win95 style windows.
1143 * If bGrayed is true, then draw a disabled Maximize button
1145 static void NC_DrawMaxButton95(HWND hwnd
,HDC16 hdc
,BOOL down
, BOOL bGrayed
)
1148 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1150 if( !(wndPtr
->dwExStyle
& WS_EX_MANAGED
))
1152 UINT flags
= IsZoomed(hwnd
) ? DFCS_CAPTIONRESTORE
: DFCS_CAPTIONMAX
;
1153 NC_GetInsideRect95( hwnd
, &rect
);
1154 if (wndPtr
->dwStyle
& WS_SYSMENU
)
1155 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1156 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
);
1157 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1160 if (down
) flags
|= DFCS_PUSHED
;
1161 if (bGrayed
) flags
|= DFCS_INACTIVE
;
1162 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
1164 WIN_ReleaseWndPtr(wndPtr
);
1167 /******************************************************************************
1168 * NC_DrawMinButton95
1170 * Draws the minimize button for Win95 style windows.
1171 * If bGrayed is true, then draw a disabled Minimize button
1173 static void NC_DrawMinButton95(HWND hwnd
,HDC16 hdc
,BOOL down
, BOOL bGrayed
)
1176 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1178 if( !(wndPtr
->dwExStyle
& WS_EX_MANAGED
))
1180 UINT flags
= DFCS_CAPTIONMIN
;
1181 NC_GetInsideRect95( hwnd
, &rect
);
1182 if (wndPtr
->dwStyle
& WS_SYSMENU
)
1183 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1184 if (wndPtr
->dwStyle
& (WS_MAXIMIZEBOX
|WS_MINIMIZEBOX
))
1185 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) - 2;
1186 rect
.left
= rect
.right
- GetSystemMetrics(SM_CXSIZE
);
1187 rect
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
) - 1;
1190 if (down
) flags
|= DFCS_PUSHED
;
1191 if (bGrayed
) flags
|= DFCS_INACTIVE
;
1192 DrawFrameControl( hdc
, &rect
, DFC_CAPTION
, flags
);
1194 WIN_ReleaseWndPtr(wndPtr
);
1197 /***********************************************************************
1200 * Draw a window frame inside the given rectangle, and update the rectangle.
1201 * The correct pen for the frame must be selected in the DC.
1203 static void NC_DrawFrame( HDC hdc
, RECT
*rect
, BOOL dlgFrame
,
1208 if (TWEAK_WineLook
!= WIN31_LOOK
)
1209 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
1213 width
= GetSystemMetrics(SM_CXDLGFRAME
) - 1;
1214 height
= GetSystemMetrics(SM_CYDLGFRAME
) - 1;
1215 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1216 COLOR_INACTIVECAPTION
) );
1220 width
= GetSystemMetrics(SM_CXFRAME
) - 2;
1221 height
= GetSystemMetrics(SM_CYFRAME
) - 2;
1222 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1223 COLOR_INACTIVEBORDER
) );
1227 PatBlt( hdc
, rect
->left
, rect
->top
,
1228 rect
->right
- rect
->left
, height
, PATCOPY
);
1229 PatBlt( hdc
, rect
->left
, rect
->top
,
1230 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1231 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1232 rect
->right
- rect
->left
, -height
, PATCOPY
);
1233 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1234 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1238 InflateRect( rect
, -width
, -height
);
1242 INT decYOff
= GetSystemMetrics(SM_CXFRAME
) + GetSystemMetrics(SM_CXSIZE
) - 1;
1243 INT decXOff
= GetSystemMetrics(SM_CYFRAME
) + GetSystemMetrics(SM_CYSIZE
) - 1;
1245 /* Draw inner rectangle */
1247 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1248 Rectangle( hdc
, rect
->left
+ width
, rect
->top
+ height
,
1249 rect
->right
- width
, rect
->bottom
- height
);
1251 /* Draw the decorations */
1253 MoveToEx( hdc
, rect
->left
, rect
->top
+ decYOff
, NULL
);
1254 LineTo( hdc
, rect
->left
+ width
, rect
->top
+ decYOff
);
1255 MoveToEx( hdc
, rect
->right
- 1, rect
->top
+ decYOff
, NULL
);
1256 LineTo( hdc
, rect
->right
- width
- 1, rect
->top
+ decYOff
);
1257 MoveToEx( hdc
, rect
->left
, rect
->bottom
- decYOff
, NULL
);
1258 LineTo( hdc
, rect
->left
+ width
, rect
->bottom
- decYOff
);
1259 MoveToEx( hdc
, rect
->right
- 1, rect
->bottom
- decYOff
, NULL
);
1260 LineTo( hdc
, rect
->right
- width
- 1, rect
->bottom
- decYOff
);
1262 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->top
, NULL
);
1263 LineTo( hdc
, rect
->left
+ decXOff
, rect
->top
+ height
);
1264 MoveToEx( hdc
, rect
->left
+ decXOff
, rect
->bottom
- 1, NULL
);
1265 LineTo( hdc
, rect
->left
+ decXOff
, rect
->bottom
- height
- 1 );
1266 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->top
, NULL
);
1267 LineTo( hdc
, rect
->right
- decXOff
, rect
->top
+ height
);
1268 MoveToEx( hdc
, rect
->right
- decXOff
, rect
->bottom
- 1, NULL
);
1269 LineTo( hdc
, rect
->right
- decXOff
, rect
->bottom
- height
- 1 );
1271 InflateRect( rect
, -width
- 1, -height
- 1 );
1276 /******************************************************************************
1278 * void NC_DrawFrame95(
1284 * Draw a window frame inside the given rectangle, and update the rectangle.
1285 * The correct pen for the frame must be selected in the DC.
1288 * Many. First, just what IS a frame in Win95? Note that the 3D look
1289 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1290 * edge. The inner rectangle just inside the frame is handled by the
1293 * In short, for most people, this function should be a nop (unless
1294 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1295 * them lately, but just to get this code right). Even so, it doesn't
1296 * appear to be so. It's being worked on...
1299 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1300 * Original implementation (based on NC_DrawFrame)
1301 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1303 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1304 * Fixed a fix or something.
1306 *****************************************************************************/
1308 static void NC_DrawFrame95(
1318 width
= GetSystemMetrics(SM_CXDLGFRAME
) - GetSystemMetrics(SM_CXEDGE
);
1319 height
= GetSystemMetrics(SM_CYDLGFRAME
) - GetSystemMetrics(SM_CYEDGE
);
1323 width
= GetSystemMetrics(SM_CXFRAME
) - GetSystemMetrics(SM_CXEDGE
);
1324 height
= GetSystemMetrics(SM_CYFRAME
) - GetSystemMetrics(SM_CYEDGE
);
1327 SelectObject( hdc
, GetSysColorBrush(active
? COLOR_ACTIVEBORDER
:
1328 COLOR_INACTIVEBORDER
) );
1331 PatBlt( hdc
, rect
->left
, rect
->top
,
1332 rect
->right
- rect
->left
, height
, PATCOPY
);
1333 PatBlt( hdc
, rect
->left
, rect
->top
,
1334 width
, rect
->bottom
- rect
->top
, PATCOPY
);
1335 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
1336 rect
->right
- rect
->left
, -height
, PATCOPY
);
1337 PatBlt( hdc
, rect
->right
- 1, rect
->top
,
1338 -width
, rect
->bottom
- rect
->top
, PATCOPY
);
1340 InflateRect( rect
, -width
, -height
);
1343 /***********************************************************************
1344 * NC_DrawMovingFrame
1346 * Draw the frame used when moving or resizing window.
1348 * FIXME: This causes problems in Win95 mode. (why?)
1350 static void NC_DrawMovingFrame( HDC hdc
, RECT
*rect
, BOOL thickframe
)
1355 CONV_RECT32TO16( rect
, &r16
);
1356 FastWindowFrame16( hdc
, &r16
, GetSystemMetrics(SM_CXFRAME
),
1357 GetSystemMetrics(SM_CYFRAME
), PATINVERT
);
1359 else DrawFocusRect( hdc
, rect
);
1363 /***********************************************************************
1366 * Draw the window caption.
1367 * The correct pen for the window frame must be selected in the DC.
1369 static void NC_DrawCaption( HDC hdc
, RECT
*rect
, HWND hwnd
,
1370 DWORD style
, BOOL active
)
1373 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1376 if (wndPtr
->dwExStyle
& WS_EX_MANAGED
)
1378 WIN_ReleaseWndPtr(wndPtr
);
1384 if (!(hbitmapClose
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_CLOSE
) )))
1386 WIN_ReleaseWndPtr(wndPtr
);
1389 hbitmapMinimize
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_REDUCE
) );
1390 hbitmapMinimizeD
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_REDUCED
) );
1391 hbitmapMaximize
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_ZOOM
) );
1392 hbitmapMaximizeD
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_ZOOMD
) );
1393 hbitmapRestore
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RESTORE
) );
1394 hbitmapRestoreD
= LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RESTORED
) );
1397 if (wndPtr
->dwExStyle
& WS_EX_DLGMODALFRAME
)
1399 HBRUSH hbrushOld
= SelectObject(hdc
, GetSysColorBrush(COLOR_WINDOW
) );
1400 PatBlt( hdc
, r
.left
, r
.top
, 1, r
.bottom
-r
.top
+1,PATCOPY
);
1401 PatBlt( hdc
, r
.right
-1, r
.top
, 1, r
.bottom
-r
.top
+1, PATCOPY
);
1402 PatBlt( hdc
, r
.left
, r
.top
-1, r
.right
-r
.left
, 1, PATCOPY
);
1405 SelectObject( hdc
, hbrushOld
);
1407 WIN_ReleaseWndPtr(wndPtr
);
1408 MoveToEx( hdc
, r
.left
, r
.bottom
, NULL
);
1409 LineTo( hdc
, r
.right
, r
.bottom
);
1411 if (style
& WS_SYSMENU
)
1413 NC_DrawSysButton( hwnd
, hdc
, FALSE
);
1414 r
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
1415 MoveToEx( hdc
, r
.left
- 1, r
.top
, NULL
);
1416 LineTo( hdc
, r
.left
- 1, r
.bottom
);
1418 if (style
& WS_MAXIMIZEBOX
)
1420 NC_DrawMaxButton( hwnd
, hdc
, FALSE
);
1421 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1423 if (style
& WS_MINIMIZEBOX
)
1425 NC_DrawMinButton( hwnd
, hdc
, FALSE
);
1426 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1429 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1430 COLOR_INACTIVECAPTION
) );
1432 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) ))
1434 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1435 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1436 SetBkMode( hdc
, TRANSPARENT
);
1437 DrawTextA( hdc
, buffer
, -1, &r
,
1438 DT_SINGLELINE
| DT_CENTER
| DT_VCENTER
| DT_NOPREFIX
);
1443 /******************************************************************************
1452 * Draw the window caption for Win95 style windows.
1453 * The correct pen for the window frame must be selected in the DC.
1456 * Hey, a function that finally works! Well, almost.
1457 * It's being worked on.
1460 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1461 * Original implementation.
1462 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1465 *****************************************************************************/
1467 static void NC_DrawCaption95(
1476 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
1481 if (wndPtr
->dwExStyle
& WS_EX_MANAGED
)
1483 WIN_ReleaseWndPtr(wndPtr
);
1486 WIN_ReleaseWndPtr(wndPtr
);
1488 hPrevPen
= SelectObject( hdc
, GetSysColorPen(COLOR_3DFACE
) );
1489 MoveToEx( hdc
, r
.left
, r
.bottom
- 1, NULL
);
1490 LineTo( hdc
, r
.right
, r
.bottom
- 1 );
1491 SelectObject( hdc
, hPrevPen
);
1494 FillRect( hdc
, &r
, GetSysColorBrush(active
? COLOR_ACTIVECAPTION
:
1495 COLOR_INACTIVECAPTION
) );
1497 if ((style
& WS_SYSMENU
) && !(exStyle
& WS_EX_TOOLWINDOW
)) {
1498 if (NC_DrawSysButton95 (hwnd
, hdc
, FALSE
))
1499 r
.left
+= GetSystemMetrics(SM_CYCAPTION
) - 1;
1502 if (style
& WS_SYSMENU
)
1506 /* Go get the sysmenu */
1507 hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
1508 state
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
);
1510 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1511 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
,
1512 ((((state
& MF_DISABLED
) || (state
& MF_GRAYED
))) && (state
!= 0xFFFFFFFF)));
1513 r
.right
-= GetSystemMetrics(SM_CYCAPTION
) - 1;
1515 if ((style
& WS_MAXIMIZEBOX
) || (style
& WS_MINIMIZEBOX
))
1517 /* In win95 the two buttons are always there */
1518 /* But if the menu item is not in the menu they're disabled*/
1520 NC_DrawMaxButton95( hwnd
, hdc
, FALSE
, (!(style
& WS_MAXIMIZEBOX
)));
1521 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1523 NC_DrawMinButton95( hwnd
, hdc
, FALSE
, (!(style
& WS_MINIMIZEBOX
)));
1524 r
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1528 if (GetWindowTextA( hwnd
, buffer
, sizeof(buffer
) )) {
1529 NONCLIENTMETRICSA nclm
;
1530 HFONT hFont
, hOldFont
;
1531 nclm
.cbSize
= sizeof(NONCLIENTMETRICSA
);
1532 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS
, 0, &nclm
, 0);
1533 if (exStyle
& WS_EX_TOOLWINDOW
)
1534 hFont
= CreateFontIndirectA (&nclm
.lfSmCaptionFont
);
1536 hFont
= CreateFontIndirectA (&nclm
.lfCaptionFont
);
1537 hOldFont
= SelectObject (hdc
, hFont
);
1538 if (active
) SetTextColor( hdc
, GetSysColor( COLOR_CAPTIONTEXT
) );
1539 else SetTextColor( hdc
, GetSysColor( COLOR_INACTIVECAPTIONTEXT
) );
1540 SetBkMode( hdc
, TRANSPARENT
);
1542 DrawTextA( hdc
, buffer
, -1, &r
,
1543 DT_SINGLELINE
| DT_VCENTER
| DT_NOPREFIX
| DT_LEFT
);
1544 DeleteObject (SelectObject (hdc
, hOldFont
));
1550 /***********************************************************************
1553 * Paint the non-client area. clip is currently unused.
1555 static void NC_DoNCPaint( WND
* wndPtr
, HRGN clip
, BOOL suppress_menupaint
)
1560 HWND hwnd
= wndPtr
->hwndSelf
;
1562 if ( wndPtr
->dwStyle
& WS_MINIMIZE
||
1563 !WIN_IsWindowDrawable( wndPtr
, 0 )) return; /* Nothing to do */
1565 active
= wndPtr
->flags
& WIN_NCACTIVATED
;
1567 TRACE("%04x %d\n", hwnd
, active
);
1569 if (!(hdc
= GetDCEx( hwnd
, (clip
> 1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
1570 ((clip
> 1) ? (DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
): 0) ))) return;
1572 if (ExcludeVisRect16( hdc
, wndPtr
->rectClient
.left
-wndPtr
->rectWindow
.left
,
1573 wndPtr
->rectClient
.top
-wndPtr
->rectWindow
.top
,
1574 wndPtr
->rectClient
.right
-wndPtr
->rectWindow
.left
,
1575 wndPtr
->rectClient
.bottom
-wndPtr
->rectWindow
.top
)
1578 ReleaseDC( hwnd
, hdc
);
1582 rect
.top
= rect
.left
= 0;
1583 rect
.right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
1584 rect
.bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
1586 SelectObject( hdc
, GetSysColorPen(COLOR_WINDOWFRAME
) );
1588 if (!(wndPtr
->dwExStyle
& WS_EX_MANAGED
))
1590 if (HAS_ANYFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1592 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1593 Rectangle( hdc
, 0, 0, rect
.right
, rect
.bottom
);
1594 InflateRect( &rect
, -1, -1 );
1597 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1598 NC_DrawFrame(hdc
, &rect
, FALSE
, active
);
1599 else if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1600 NC_DrawFrame( hdc
, &rect
, TRUE
, active
);
1602 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1605 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSIZE
);
1606 rect
.top
+= GetSystemMetrics(SM_CYSIZE
) + GetSystemMetrics(SM_CYBORDER
);
1607 NC_DrawCaption( hdc
, &r
, hwnd
, wndPtr
->dwStyle
, active
);
1611 if (HAS_MENU(wndPtr
))
1614 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYMENU
); /* default height */
1615 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
);
1618 /* Draw the scroll-bars */
1620 if (wndPtr
->dwStyle
& WS_VSCROLL
)
1621 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1622 if (wndPtr
->dwStyle
& WS_HSCROLL
)
1623 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1625 /* Draw the "size-box" */
1627 if ((wndPtr
->dwStyle
& WS_VSCROLL
) && (wndPtr
->dwStyle
& WS_HSCROLL
))
1630 r
.left
= r
.right
- GetSystemMetrics(SM_CXVSCROLL
) + 1;
1631 r
.top
= r
.bottom
- GetSystemMetrics(SM_CYHSCROLL
) + 1;
1632 if(wndPtr
->dwStyle
& WS_BORDER
) {
1636 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1639 ReleaseDC( hwnd
, hdc
);
1643 /******************************************************************************
1645 * void NC_DoNCPaint95(
1648 * BOOL suppress_menupaint )
1650 * Paint the non-client area for Win95 windows. The clip region is
1651 * currently ignored.
1654 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1655 * misc/tweak.c controls/menu.c # :-)
1658 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1659 * Original implementation
1660 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1662 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1663 * Streamlined window style checks.
1665 *****************************************************************************/
1667 static 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("%04x %d\n", hwnd
, active
);
1684 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1685 the call to GetDCEx implying that it is allowed not to use it either.
1686 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1687 will cause clipRgn to be deleted after ReleaseDC().
1688 Now, how is the "system" supposed to tell what happened?
1691 if (!(hdc
= GetDCEx( hwnd
, (clip
> 1) ? clip
: 0, DCX_USESTYLE
| DCX_WINDOW
|
1692 ((clip
> 1) ?(DCX_INTERSECTRGN
| DCX_KEEPCLIPRGN
) : 0) ))) return;
1695 if (ExcludeVisRect16( hdc
, wndPtr
->rectClient
.left
-wndPtr
->rectWindow
.left
,
1696 wndPtr
->rectClient
.top
-wndPtr
->rectWindow
.top
,
1697 wndPtr
->rectClient
.right
-wndPtr
->rectWindow
.left
,
1698 wndPtr
->rectClient
.bottom
-wndPtr
->rectWindow
.top
)
1701 ReleaseDC( hwnd
, hdc
);
1705 rect
.top
= rect
.left
= 0;
1706 rect
.right
= wndPtr
->rectWindow
.right
- wndPtr
->rectWindow
.left
;
1707 rect
.bottom
= wndPtr
->rectWindow
.bottom
- wndPtr
->rectWindow
.top
;
1710 GetRgnBox( clip
, &rectClip
);
1717 SelectObject( hdc
, GetSysColorPen(COLOR_WINDOWFRAME
) );
1719 if(!(wndPtr
->dwExStyle
& WS_EX_MANAGED
)) {
1720 if (HAS_BIGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
)) {
1721 DrawEdge (hdc
, &rect
, EDGE_RAISED
, BF_RECT
| BF_ADJUST
);
1723 if (HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1724 NC_DrawFrame95(hdc
, &rect
, FALSE
, active
);
1725 else if (HAS_DLGFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
))
1726 NC_DrawFrame95( hdc
, &rect
, TRUE
, active
);
1727 else if (HAS_THINFRAME( wndPtr
->dwStyle
)) {
1728 SelectObject( hdc
, GetStockObject(NULL_BRUSH
) );
1729 Rectangle( hdc
, 0, 0, rect
.right
, rect
.bottom
);
1732 if ((wndPtr
->dwStyle
& WS_CAPTION
) == WS_CAPTION
)
1735 if (wndPtr
->dwExStyle
& WS_EX_TOOLWINDOW
) {
1736 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYSMCAPTION
);
1737 rect
.top
+= GetSystemMetrics(SM_CYSMCAPTION
);
1740 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYCAPTION
);
1741 rect
.top
+= GetSystemMetrics(SM_CYCAPTION
);
1743 if( !clip
|| IntersectRect( &rfuzz
, &r
, &rectClip
) )
1744 NC_DrawCaption95 (hdc
, &r
, hwnd
, wndPtr
->dwStyle
,
1745 wndPtr
->dwExStyle
, active
);
1749 if (HAS_MENU(wndPtr
))
1752 r
.bottom
= rect
.top
+ GetSystemMetrics(SM_CYMENU
);
1754 TRACE("Calling DrawMenuBar with rect (%d, %d)-(%d, %d)\n",
1755 r
.left
, r
.top
, r
.right
, r
.bottom
);
1757 rect
.top
+= MENU_DrawMenuBar( hdc
, &r
, hwnd
, suppress_menupaint
) + 1;
1760 TRACE("After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1761 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1763 if (wndPtr
->dwExStyle
& WS_EX_CLIENTEDGE
)
1764 DrawEdge (hdc
, &rect
, EDGE_SUNKEN
, BF_RECT
| BF_ADJUST
);
1766 if (wndPtr
->dwExStyle
& WS_EX_STATICEDGE
)
1767 DrawEdge (hdc
, &rect
, BDR_SUNKENOUTER
, BF_RECT
| BF_ADJUST
);
1769 /* Draw the scroll-bars */
1771 if (wndPtr
->dwStyle
& WS_VSCROLL
)
1772 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_VERT
, TRUE
, TRUE
);
1773 if (wndPtr
->dwStyle
& WS_HSCROLL
)
1774 SCROLL_DrawScrollBar( hwnd
, hdc
, SB_HORZ
, TRUE
, TRUE
);
1776 /* Draw the "size-box" */
1777 if ((wndPtr
->dwStyle
& WS_VSCROLL
) && (wndPtr
->dwStyle
& WS_HSCROLL
))
1780 r
.left
= r
.right
- GetSystemMetrics(SM_CXVSCROLL
) + 1;
1781 r
.top
= r
.bottom
- GetSystemMetrics(SM_CYHSCROLL
) + 1;
1782 FillRect( hdc
, &r
, GetSysColorBrush(COLOR_SCROLLBAR
) );
1785 ReleaseDC( hwnd
, hdc
);
1791 /***********************************************************************
1794 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1796 LONG
NC_HandleNCPaint( HWND hwnd
, HRGN clip
)
1798 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
1800 if( wndPtr
&& wndPtr
->dwStyle
& WS_VISIBLE
)
1802 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
1803 WINPOS_RedrawIconTitle( hwnd
);
1804 else if (TWEAK_WineLook
== WIN31_LOOK
)
1805 NC_DoNCPaint( wndPtr
, clip
, FALSE
);
1807 NC_DoNCPaint95( wndPtr
, clip
, FALSE
);
1809 WIN_ReleaseWndPtr(wndPtr
);
1814 /***********************************************************************
1815 * NC_HandleNCActivate
1817 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1819 LONG
NC_HandleNCActivate( WND
*wndPtr
, WPARAM16 wParam
)
1823 if( wParam
) wStateChange
= !(wndPtr
->flags
& WIN_NCACTIVATED
);
1824 else wStateChange
= wndPtr
->flags
& WIN_NCACTIVATED
;
1828 if (wParam
) wndPtr
->flags
|= WIN_NCACTIVATED
;
1829 else wndPtr
->flags
&= ~WIN_NCACTIVATED
;
1831 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
1832 WINPOS_RedrawIconTitle( wndPtr
->hwndSelf
);
1833 else if (TWEAK_WineLook
== WIN31_LOOK
)
1834 NC_DoNCPaint( wndPtr
, (HRGN
)1, FALSE
);
1836 NC_DoNCPaint95( wndPtr
, (HRGN
)1, FALSE
);
1842 /***********************************************************************
1843 * NC_HandleSetCursor
1845 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1847 LONG
NC_HandleSetCursor( HWND hwnd
, WPARAM16 wParam
, LPARAM lParam
)
1849 if (hwnd
!= (HWND
)wParam
) return 0; /* Don't set the cursor for child windows */
1851 switch(LOWORD(lParam
))
1855 WORD msg
= HIWORD( lParam
);
1856 if ((msg
== WM_LBUTTONDOWN
) || (msg
== WM_MBUTTONDOWN
) ||
1857 (msg
== WM_RBUTTONDOWN
))
1864 HICON16 hCursor
= (HICON16
) GetClassWord(hwnd
, GCW_HCURSOR
);
1866 SetCursor16(hCursor
);
1874 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZEWEA
) );
1878 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENSA
) );
1882 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENWSEA
) );
1886 return (LONG
)SetCursor( LoadCursorA( 0, IDC_SIZENESWA
) );
1889 /* Default cursor: arrow */
1890 return (LONG
)SetCursor( LoadCursorA( 0, IDC_ARROWA
) );
1893 /***********************************************************************
1896 BOOL
NC_GetSysPopupPos( WND
* wndPtr
, RECT
* rect
)
1898 if( wndPtr
->hSysMenu
)
1900 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
1901 GetWindowRect( wndPtr
->hwndSelf
, rect
);
1904 if (TWEAK_WineLook
== WIN31_LOOK
)
1905 NC_GetInsideRect( wndPtr
->hwndSelf
, rect
);
1907 NC_GetInsideRect95( wndPtr
->hwndSelf
, rect
);
1908 OffsetRect( rect
, wndPtr
->rectWindow
.left
, wndPtr
->rectWindow
.top
);
1909 if (wndPtr
->dwStyle
& WS_CHILD
)
1910 ClientToScreen( wndPtr
->parent
->hwndSelf
, (POINT
*)rect
);
1911 if (TWEAK_WineLook
== WIN31_LOOK
) {
1912 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CXSIZE
);
1913 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYSIZE
);
1916 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
1917 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYCAPTION
) - 1;
1925 /***********************************************************************
1928 * Initialisation of a move or resize, when initiatied from a menu choice.
1929 * Return hit test code for caption or sizing border.
1931 static LONG
NC_StartSizeMove( WND
* wndPtr
, WPARAM16 wParam
,
1932 POINT
*capturePoint
)
1939 GetWindowRect(wndPtr
->hwndSelf
,&rectWindow
);
1941 if ((wParam
& 0xfff0) == SC_MOVE
)
1943 /* Move pointer at the center of the caption */
1945 if (TWEAK_WineLook
== WIN31_LOOK
)
1946 NC_GetInsideRect( wndPtr
->hwndSelf
, &rect
);
1948 NC_GetInsideRect95( wndPtr
->hwndSelf
, &rect
);
1949 if (wndPtr
->dwStyle
& WS_SYSMENU
)
1950 rect
.left
+= GetSystemMetrics(SM_CXSIZE
) + 1;
1951 if (wndPtr
->dwStyle
& WS_MINIMIZEBOX
)
1952 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1953 if (wndPtr
->dwStyle
& WS_MAXIMIZEBOX
)
1954 rect
.right
-= GetSystemMetrics(SM_CXSIZE
) + 1;
1955 pt
.x
= rectWindow
.left
+ (rect
.right
- rect
.left
) / 2;
1956 pt
.y
= rectWindow
.top
+ rect
.top
+ GetSystemMetrics(SM_CYSIZE
)/2;
1957 hittest
= HTCAPTION
;
1964 MSG_InternalGetMessage( QMSG_WIN32A
, &msg
, 0, 0, MSGF_SIZE
, PM_REMOVE
, FALSE
, NULL
);
1968 hittest
= NC_HandleNCHitTest( wndPtr
->hwndSelf
, msg
.pt
);
1969 if ((hittest
< HTLEFT
) || (hittest
> HTBOTTOMRIGHT
))
1981 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
1982 pt
.y
= rectWindow
.top
+ GetSystemMetrics(SM_CYFRAME
) / 2;
1986 pt
.x
=(rectWindow
.left
+rectWindow
.right
)/2;
1987 pt
.y
= rectWindow
.bottom
- GetSystemMetrics(SM_CYFRAME
) / 2;
1991 pt
.x
= rectWindow
.left
+ GetSystemMetrics(SM_CXFRAME
) / 2;
1992 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
1996 pt
.x
= rectWindow
.right
- GetSystemMetrics(SM_CXFRAME
) / 2;
1997 pt
.y
=(rectWindow
.top
+rectWindow
.bottom
)/2;
2000 case VK_ESCAPE
: return 0;
2006 SetCursorPos( pt
.x
, pt
.y
);
2007 NC_HandleSetCursor( wndPtr
->hwndSelf
,
2008 wndPtr
->hwndSelf
, MAKELONG( hittest
, WM_MOUSEMOVE
));
2013 /***********************************************************************
2016 * Perform SC_MOVE and SC_SIZE commands. `
2018 static void NC_DoSizeMove( HWND hwnd
, WORD wParam
)
2021 RECT sizingRect
, mouseRect
, origRect
;
2023 LONG hittest
= (LONG
)(wParam
& 0x0f);
2024 HCURSOR16 hDragCursor
= 0, hOldCursor
= 0;
2025 POINT minTrack
, maxTrack
;
2026 POINT capturePoint
, pt
;
2027 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
2028 BOOL thickframe
= HAS_THICKFRAME( wndPtr
->dwStyle
, wndPtr
->dwExStyle
);
2029 BOOL iconic
= wndPtr
->dwStyle
& WS_MINIMIZE
;
2031 DWORD dwPoint
= GetMessagePos ();
2032 BOOL DragFullWindows
= FALSE
;
2035 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS
, 0, &DragFullWindows
, 0);
2037 pt
.x
= SLOWORD(dwPoint
);
2038 pt
.y
= SHIWORD(dwPoint
);
2041 if (IsZoomed(hwnd
) || !IsWindowVisible(hwnd
) ||
2042 (wndPtr
->dwExStyle
& WS_EX_MANAGED
)) goto END
;
2044 if ((wParam
& 0xfff0) == SC_MOVE
)
2047 hittest
= NC_StartSizeMove( wndPtr
, wParam
, &capturePoint
);
2048 if (!hittest
) goto END
;
2052 if (!thickframe
) goto END
;
2053 if ( hittest
&& hittest
!= HTSYSMENU
) hittest
+= 2;
2057 hittest
= NC_StartSizeMove( wndPtr
, wParam
, &capturePoint
);
2066 /* Get min/max info */
2068 WINPOS_GetMinMaxInfo( wndPtr
, NULL
, NULL
, &minTrack
, &maxTrack
);
2069 sizingRect
= wndPtr
->rectWindow
;
2070 origRect
= sizingRect
;
2071 if (wndPtr
->dwStyle
& WS_CHILD
)
2072 GetClientRect( wndPtr
->parent
->hwndSelf
, &mouseRect
);
2074 SetRect(&mouseRect
, 0, 0, GetSystemMetrics(SM_CXSCREEN
), GetSystemMetrics(SM_CYSCREEN
));
2075 if (ON_LEFT_BORDER(hittest
))
2077 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.right
-maxTrack
.x
);
2078 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.right
-minTrack
.x
);
2080 else if (ON_RIGHT_BORDER(hittest
))
2082 mouseRect
.left
= max( mouseRect
.left
, sizingRect
.left
+minTrack
.x
);
2083 mouseRect
.right
= min( mouseRect
.right
, sizingRect
.left
+maxTrack
.x
);
2085 if (ON_TOP_BORDER(hittest
))
2087 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.bottom
-maxTrack
.y
);
2088 mouseRect
.bottom
= min( mouseRect
.bottom
,sizingRect
.bottom
-minTrack
.y
);
2090 else if (ON_BOTTOM_BORDER(hittest
))
2092 mouseRect
.top
= max( mouseRect
.top
, sizingRect
.top
+minTrack
.y
);
2093 mouseRect
.bottom
= min( mouseRect
.bottom
, sizingRect
.top
+maxTrack
.y
);
2095 if (wndPtr
->dwStyle
& WS_CHILD
)
2097 MapWindowPoints( wndPtr
->parent
->hwndSelf
, 0,
2098 (LPPOINT
)&mouseRect
, 2 );
2100 SendMessageA( hwnd
, WM_ENTERSIZEMOVE
, 0, 0 );
2102 if (GetCapture() != hwnd
) SetCapture( hwnd
);
2104 if (wndPtr
->parent
&& (wndPtr
->parent
->hwndSelf
!= GetDesktopWindow()))
2106 /* Retrieve a default cache DC (without using the window style) */
2107 hdc
= GetDCEx( wndPtr
->parent
->hwndSelf
, 0, DCX_CACHE
);
2112 if( iconic
) /* create a cursor for dragging */
2114 HICON16 hIcon
= GetClassWord(wndPtr
->hwndSelf
, GCW_HICON
);
2115 if(!hIcon
) hIcon
= (HICON16
) SendMessage16( hwnd
, WM_QUERYDRAGICON
, 0, 0L);
2116 if( hIcon
) hDragCursor
= CURSORICON_IconToCursor( hIcon
, TRUE
);
2117 if( !hDragCursor
) iconic
= FALSE
;
2120 wndPtr
->pDriver
->pPreSizeMove(wndPtr
);
2122 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
2123 if( !iconic
&& TWEAK_WineLook
== WIN31_LOOK
)
2124 if(!DragFullWindows
)
2125 NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2131 MSG_InternalGetMessage( QMSG_WIN32A
, &msg
, 0, 0, MSGF_SIZE
, PM_REMOVE
, FALSE
, NULL
);
2133 /* Exit on button-up, Return, or Esc */
2134 if ((msg
.message
== WM_LBUTTONUP
) ||
2135 ((msg
.message
== WM_KEYDOWN
) &&
2136 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
2138 if (msg
.message
== WM_PAINT
)
2140 if(!iconic
&& !DragFullWindows
) NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2141 UpdateWindow( msg
.hwnd
);
2142 if(!iconic
&& !DragFullWindows
) NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2146 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
2147 continue; /* We are not interested in other messages */
2151 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
2153 case VK_UP
: pt
.y
-= 8; break;
2154 case VK_DOWN
: pt
.y
+= 8; break;
2155 case VK_LEFT
: pt
.x
-= 8; break;
2156 case VK_RIGHT
: pt
.x
+= 8; break;
2159 pt
.x
= max( pt
.x
, mouseRect
.left
);
2160 pt
.x
= min( pt
.x
, mouseRect
.right
);
2161 pt
.y
= max( pt
.y
, mouseRect
.top
);
2162 pt
.y
= min( pt
.y
, mouseRect
.bottom
);
2164 dx
= pt
.x
- capturePoint
.x
;
2165 dy
= pt
.y
- capturePoint
.y
;
2173 if( iconic
) /* ok, no system popup tracking */
2175 hOldCursor
= SetCursor(hDragCursor
);
2177 WINPOS_ShowIconTitle( wndPtr
, FALSE
);
2178 } else if(TWEAK_WineLook
!= WIN31_LOOK
)
2180 if(!DragFullWindows
)
2181 NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2185 if (msg
.message
== WM_KEYDOWN
) SetCursorPos( pt
.x
, pt
.y
);
2188 RECT newRect
= sizingRect
;
2189 WPARAM wpSizingHit
= 0;
2191 if (hittest
== HTCAPTION
) OffsetRect( &newRect
, dx
, dy
);
2192 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
2193 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
2194 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
2195 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
2196 if(!iconic
&& !DragFullWindows
) NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2199 /* determine the hit location */
2200 if (hittest
>= HTLEFT
&& hittest
<= HTBOTTOMRIGHT
)
2201 wpSizingHit
= WMSZ_LEFT
+ (hittest
- HTLEFT
);
2202 SendMessageA( hwnd
, WM_SIZING
, wpSizingHit
, (LPARAM
)&newRect
);
2206 if(!DragFullWindows
)
2207 NC_DrawMovingFrame( hdc
, &newRect
, thickframe
);
2209 /* To avoid any deadlocks, all the locks on the windows
2210 structures must be suspended before the SetWindowPos */
2211 iWndsLocks
= WIN_SuspendWndsLock();
2212 SetWindowPos( hwnd
, 0, newRect
.left
, newRect
.top
,
2213 newRect
.right
- newRect
.left
,
2214 newRect
.bottom
- newRect
.top
,
2215 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
2216 WIN_RestoreWndsLock(iWndsLocks
);
2219 sizingRect
= newRect
;
2227 if( moved
) /* restore cursors, show icon title later on */
2229 ShowCursor( FALSE
);
2230 SetCursor( hOldCursor
);
2232 DestroyCursor( hDragCursor
);
2234 else if(moved
|| TWEAK_WineLook
== WIN31_LOOK
)
2235 if(!DragFullWindows
)
2236 NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2238 if (wndPtr
->parent
&& (wndPtr
->parent
->hwndSelf
!= GetDesktopWindow()))
2239 ReleaseDC( wndPtr
->parent
->hwndSelf
, hdc
);
2241 ReleaseDC( 0, hdc
);
2243 wndPtr
->pDriver
->pPostSizeMove(wndPtr
);
2245 if (HOOK_IsHooked( WH_CBT
))
2247 RECT16
* pr
= SEGPTR_NEW(RECT16
);
2250 CONV_RECT32TO16( &sizingRect
, pr
);
2251 if( HOOK_CallHooks16( WH_CBT
, HCBT_MOVESIZE
, hwnd
,
2252 (LPARAM
)SEGPTR_GET(pr
)) )
2253 sizingRect
= wndPtr
->rectWindow
;
2255 CONV_RECT16TO32( pr
, &sizingRect
);
2259 SendMessageA( hwnd
, WM_EXITSIZEMOVE
, 0, 0 );
2260 SendMessageA( hwnd
, WM_SETVISIBLE
, !IsIconic16(hwnd
), 0L);
2262 /* window moved or resized */
2265 /* To avoid any deadlocks, all the locks on the windows
2266 structures must be suspended before the SetWindowPos */
2267 iWndsLocks
= WIN_SuspendWndsLock();
2269 /* if the moving/resizing isn't canceled call SetWindowPos
2270 * with the new position or the new size of the window
2272 if (!((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
2274 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
2275 if(!DragFullWindows
)
2276 SetWindowPos( hwnd
, 0, sizingRect
.left
, sizingRect
.top
,
2277 sizingRect
.right
- sizingRect
.left
,
2278 sizingRect
.bottom
- sizingRect
.top
,
2279 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
2281 else { /* restore previous size/position */
2283 SetWindowPos( hwnd
, 0, origRect
.left
, origRect
.top
,
2284 origRect
.right
- origRect
.left
,
2285 origRect
.bottom
- origRect
.top
,
2286 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
2289 WIN_RestoreWndsLock(iWndsLocks
);
2292 if( IsWindow(hwnd
) )
2293 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
2295 /* Single click brings up the system menu when iconized */
2299 if( wndPtr
->dwStyle
& WS_SYSMENU
)
2300 SendMessageA( hwnd
, WM_SYSCOMMAND
,
2301 SC_MOUSEMENU
+ HTSYSMENU
, MAKELONG(pt
.x
,pt
.y
));
2303 else WINPOS_ShowIconTitle( wndPtr
, TRUE
);
2307 WIN_ReleaseWndPtr(wndPtr
);
2311 /***********************************************************************
2312 * NC_TrackMinMaxBox95
2314 * Track a mouse button press on the minimize or maximize box.
2316 * The big difference between 3.1 and 95 is the disabled button state.
2317 * In win95 the system button can be disabled, so it can ignore the mouse
2321 static void NC_TrackMinMaxBox95( HWND hwnd
, WORD wParam
)
2324 HDC hdc
= GetWindowDC( hwnd
);
2325 BOOL pressed
= TRUE
;
2327 DWORD wndStyle
= GetWindowLongA( hwnd
, GWL_STYLE
);
2328 HMENU hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
2330 void (*paintButton
)(HWND
, HDC16
, BOOL
, BOOL
);
2332 if (wParam
== HTMINBUTTON
)
2334 /* If the style is not present, do nothing */
2335 if (!(wndStyle
& WS_MINIMIZEBOX
))
2338 /* Check if the sysmenu item for minimize is there */
2339 state
= GetMenuState(hSysMenu
, SC_MINIMIZE
, MF_BYCOMMAND
);
2341 paintButton
= &NC_DrawMinButton95
;
2345 /* If the style is not present, do nothing */
2346 if (!(wndStyle
& WS_MAXIMIZEBOX
))
2349 /* Check if the sysmenu item for maximize is there */
2350 state
= GetMenuState(hSysMenu
, SC_MAXIMIZE
, MF_BYCOMMAND
);
2352 paintButton
= &NC_DrawMaxButton95
;
2357 (*paintButton
)( hwnd
, hdc
, TRUE
, FALSE
);
2361 BOOL oldstate
= pressed
;
2362 MSG_InternalGetMessage( QMSG_WIN32A
, &msg
, 0, 0, 0, PM_REMOVE
, FALSE
, NULL
);
2364 if(msg
.message
== WM_LBUTTONUP
)
2367 if(msg
.message
!= WM_MOUSEMOVE
)
2370 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
2371 if (pressed
!= oldstate
)
2372 (*paintButton
)( hwnd
, hdc
, pressed
, FALSE
);
2376 (*paintButton
)(hwnd
, hdc
, FALSE
, FALSE
);
2379 ReleaseDC( hwnd
, hdc
);
2381 /* If the item minimize or maximize of the sysmenu are not there */
2382 /* or if the style is not present, do nothing */
2383 if ((!pressed
) || (state
== 0xFFFFFFFF))
2386 if (wParam
== HTMINBUTTON
)
2387 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
2389 SendMessageA( hwnd
, WM_SYSCOMMAND
,
2390 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
2393 /***********************************************************************
2396 * Track a mouse button press on the minimize or maximize box.
2398 static void NC_TrackMinMaxBox( HWND hwnd
, WORD wParam
)
2401 HDC hdc
= GetWindowDC( hwnd
);
2402 BOOL pressed
= TRUE
;
2403 void (*paintButton
)(HWND
, HDC16
, BOOL
);
2407 if (wParam
== HTMINBUTTON
)
2408 paintButton
= &NC_DrawMinButton
;
2410 paintButton
= &NC_DrawMaxButton
;
2412 (*paintButton
)( hwnd
, hdc
, TRUE
);
2416 BOOL oldstate
= pressed
;
2417 MSG_InternalGetMessage( QMSG_WIN32A
, &msg
, 0, 0, 0, PM_REMOVE
, FALSE
, NULL
);
2419 if(msg
.message
== WM_LBUTTONUP
)
2422 if(msg
.message
!= WM_MOUSEMOVE
)
2425 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
2426 if (pressed
!= oldstate
)
2427 (*paintButton
)( hwnd
, hdc
, pressed
);
2431 (*paintButton
)( hwnd
, hdc
, FALSE
);
2434 ReleaseDC( hwnd
, hdc
);
2436 if (!pressed
) return;
2438 if (wParam
== HTMINBUTTON
)
2439 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
2441 SendMessageA( hwnd
, WM_SYSCOMMAND
,
2442 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
2446 /***********************************************************************
2447 * NC_TrackCloseButton95
2449 * Track a mouse button press on the Win95 close button.
2452 NC_TrackCloseButton95 (HWND hwnd
, WORD wParam
)
2456 BOOL pressed
= TRUE
;
2457 HMENU hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
2463 state
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
);
2465 /* If the item close of the sysmenu is disabled or not there do nothing */
2466 if((state
& MF_DISABLED
) || (state
& MF_GRAYED
) || (state
== 0xFFFFFFFF))
2469 hdc
= GetWindowDC( hwnd
);
2473 NC_DrawCloseButton95 (hwnd
, hdc
, TRUE
, FALSE
);
2477 BOOL oldstate
= pressed
;
2478 MSG_InternalGetMessage( QMSG_WIN32A
, &msg
, 0, 0, 0, PM_REMOVE
, FALSE
, NULL
);
2480 if(msg
.message
== WM_LBUTTONUP
)
2483 if(msg
.message
!= WM_MOUSEMOVE
)
2486 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
2487 if (pressed
!= oldstate
)
2488 NC_DrawCloseButton95 (hwnd
, hdc
, pressed
, FALSE
);
2492 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
, FALSE
);
2495 ReleaseDC( hwnd
, hdc
);
2496 if (!pressed
) return;
2498 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
2502 /***********************************************************************
2505 * Track a mouse button press on the horizontal or vertical scroll-bar.
2507 static void NC_TrackScrollBar( HWND hwnd
, WPARAM wParam
, POINT pt
)
2511 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
2513 if ((wParam
& 0xfff0) == SC_HSCROLL
)
2515 if ((wParam
& 0x0f) != HTHSCROLL
) goto END
;
2516 scrollbar
= SB_HORZ
;
2518 else /* SC_VSCROLL */
2520 if ((wParam
& 0x0f) != HTVSCROLL
) goto END
;
2521 scrollbar
= SB_VERT
;
2524 if (!(msg
= SEGPTR_NEW(MSG16
))) goto END
;
2525 pt
.x
-= wndPtr
->rectWindow
.left
;
2526 pt
.y
-= wndPtr
->rectWindow
.top
;
2528 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, WM_LBUTTONDOWN
, pt
);
2532 GetMessage16( SEGPTR_GET(msg
), 0, 0, 0 );
2533 switch(msg
->message
)
2538 pt
.x
= LOWORD(msg
->lParam
) + wndPtr
->rectClient
.left
-
2539 wndPtr
->rectWindow
.left
;
2540 pt
.y
= HIWORD(msg
->lParam
) + wndPtr
->rectClient
.top
-
2541 wndPtr
->rectWindow
.top
;
2542 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, msg
->message
, pt
);
2545 TranslateMessage16( msg
);
2546 DispatchMessage16( msg
);
2549 if (!IsWindow( hwnd
))
2554 } while (msg
->message
!= WM_LBUTTONUP
);
2557 WIN_ReleaseWndPtr(wndPtr
);
2560 /***********************************************************************
2561 * NC_HandleNCLButtonDown
2563 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2565 LONG
NC_HandleNCLButtonDown( WND
* pWnd
, WPARAM16 wParam
, LPARAM lParam
)
2567 HWND hwnd
= pWnd
->hwndSelf
;
2569 switch(wParam
) /* Hit test */
2572 hwnd
= WIN_GetTopParent(hwnd
);
2574 if( WINPOS_SetActiveWindow(hwnd
, TRUE
, TRUE
) || (GetActiveWindow() == hwnd
) )
2575 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_MOVE
+ HTCAPTION
, lParam
);
2579 if( pWnd
->dwStyle
& WS_SYSMENU
)
2581 if( !(pWnd
->dwStyle
& WS_MINIMIZE
) )
2583 HDC hDC
= GetWindowDC(hwnd
);
2584 if (TWEAK_WineLook
== WIN31_LOOK
)
2585 NC_DrawSysButton( hwnd
, hDC
, TRUE
);
2587 NC_DrawSysButton95( hwnd
, hDC
, TRUE
);
2588 ReleaseDC( hwnd
, hDC
);
2590 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
+ HTSYSMENU
, lParam
);
2595 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
, lParam
);
2599 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
2603 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
2608 if (TWEAK_WineLook
== WIN31_LOOK
)
2609 NC_TrackMinMaxBox( hwnd
, wParam
);
2611 NC_TrackMinMaxBox95( hwnd
, wParam
);
2615 if (TWEAK_WineLook
>= WIN95_LOOK
)
2616 NC_TrackCloseButton95 (hwnd
, wParam
);
2627 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2628 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_SIZE
+ wParam
- 2, lParam
);
2638 /***********************************************************************
2639 * NC_HandleNCLButtonDblClk
2641 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2643 LONG
NC_HandleNCLButtonDblClk( WND
*pWnd
, WPARAM16 wParam
, LPARAM lParam
)
2646 * if this is an icon, send a restore since we are handling
2649 if (pWnd
->dwStyle
& WS_MINIMIZE
)
2651 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_RESTORE
, lParam
);
2655 switch(wParam
) /* Hit test */
2658 /* stop processing if WS_MAXIMIZEBOX is missing */
2659 if (pWnd
->dwStyle
& WS_MAXIMIZEBOX
)
2660 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
,
2661 (pWnd
->dwStyle
& WS_MAXIMIZE
) ? SC_RESTORE
: SC_MAXIMIZE
,
2666 if (!(GetClassWord(pWnd
->hwndSelf
, GCW_STYLE
) & CS_NOCLOSE
))
2667 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_CLOSE
, lParam
);
2671 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
,
2676 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
,
2684 /***********************************************************************
2685 * NC_HandleSysCommand
2687 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2689 LONG
NC_HandleSysCommand( HWND hwnd
, WPARAM wParam
, POINT pt
)
2691 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
2692 UINT16 uCommand
= wParam
& 0xFFF0;
2694 TRACE("Handling WM_SYSCOMMAND %x %ld,%ld\n", wParam
, pt
.x
, pt
.y
);
2696 if (wndPtr
->parent
&& (uCommand
!= SC_KEYMENU
))
2697 ScreenToClient( wndPtr
->parent
->hwndSelf
, &pt
);
2703 NC_DoSizeMove( hwnd
, wParam
);
2707 if (hwnd
== GetForegroundWindow())
2708 ShowOwnedPopups(hwnd
,FALSE
);
2709 ShowWindow( hwnd
, SW_MINIMIZE
);
2713 if (IsIconic(hwnd
) && hwnd
== GetForegroundWindow())
2714 ShowOwnedPopups(hwnd
,TRUE
);
2715 ShowWindow( hwnd
, SW_MAXIMIZE
);
2719 if (IsIconic(hwnd
) && hwnd
== GetForegroundWindow())
2720 ShowOwnedPopups(hwnd
,TRUE
);
2721 ShowWindow( hwnd
, SW_RESTORE
);
2725 WIN_ReleaseWndPtr(wndPtr
);
2726 return SendMessageA( hwnd
, WM_CLOSE
, 0, 0 );
2730 NC_TrackScrollBar( hwnd
, wParam
, pt
);
2734 MENU_TrackMouseMenuBar( wndPtr
, wParam
& 0x000F, pt
);
2738 MENU_TrackKbdMenuBar( wndPtr
, wParam
, pt
.x
);
2742 WinExec( "taskman.exe", SW_SHOWNORMAL
);
2746 if (wParam
== SC_ABOUTWINE
)
2748 HMODULE hmodule
= LoadLibraryA( "shell32.dll" );
2751 FARPROC aboutproc
= GetProcAddress( hmodule
, "ShellAboutA" );
2752 if (aboutproc
) aboutproc( hwnd
, "Wine", WINE_RELEASE_INFO
, 0 );
2753 FreeLibrary( hmodule
);
2757 if (wParam
== SC_PUTMARK
)
2758 TRACE_(shell
)("Mark requested by user\n");
2765 FIXME("unimplemented!\n");
2768 WIN_ReleaseWndPtr(wndPtr
);
2772 /*************************************************************
2775 * Stub for the grayed button of the caption
2777 *************************************************************/
2779 BOOL
NC_DrawGrayButton(HDC hdc
, int x
, int y
)
2782 HDC hdcMask
= CreateCompatibleDC (0);
2785 hMaskBmp
= CreateBitmap (12, 10, 1, 1, lpGrayMask
);
2790 SelectObject (hdcMask
, hMaskBmp
);
2792 /* Draw the grayed bitmap using the mask */
2793 hOldBrush
= SelectObject (hdc
, RGB(128, 128, 128));
2794 BitBlt (hdc
, x
, y
, 12, 10,
2795 hdcMask
, 0, 0, 0xB8074A);
2798 SelectObject (hdc
, hOldBrush
);
2799 DeleteObject(hMaskBmp
);
2805 HICON16
NC_IconForWindow(WND
*wndPtr
)
2807 HICON16 hIcon
= (HICON
) GetClassLongA(wndPtr
->hwndSelf
, GCL_HICONSM
);
2808 if(!hIcon
) hIcon
= (HICON
) GetClassLongA(wndPtr
->hwndSelf
, GCL_HICON
);
2810 /* If there is no hIcon specified and this is a modal dialog, */
2811 /* get the default one. */
2812 if (!hIcon
&& (wndPtr
->dwStyle
& DS_MODALFRAME
))
2813 hIcon
= LoadImageA(0, IDI_WINLOGOA
, IMAGE_ICON
, 0, 0, LR_DEFAULTCOLOR
);