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 consitency 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
->dwStyle
& WS_CHILD
)
2106 /* Retrieve a default cache DC (without using the window style) */
2107 hdc
= GetDCEx( wndPtr
->parent
->hwndSelf
, 0, DCX_CACHE
);
2110 { /* Grab the server only when moving top-level windows without desktop */
2114 wndPtr
->pDriver
->pPreSizeMove(wndPtr
);
2116 if( iconic
) /* create a cursor for dragging */
2118 HICON16 hIcon
= GetClassWord(wndPtr
->hwndSelf
, GCW_HICON
);
2119 if(!hIcon
) hIcon
= (HICON16
) SendMessage16( hwnd
, WM_QUERYDRAGICON
, 0, 0L);
2120 if( hIcon
) hDragCursor
= CURSORICON_IconToCursor( hIcon
, TRUE
);
2121 if( !hDragCursor
) iconic
= FALSE
;
2124 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
2125 if( !iconic
&& TWEAK_WineLook
== WIN31_LOOK
)
2126 if(!DragFullWindows
)
2127 NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2133 MSG_InternalGetMessage( QMSG_WIN32A
, &msg
, 0, 0, MSGF_SIZE
, PM_REMOVE
, FALSE
, NULL
);
2135 /* Exit on button-up, Return, or Esc */
2136 if ((msg
.message
== WM_LBUTTONUP
) ||
2137 ((msg
.message
== WM_KEYDOWN
) &&
2138 ((msg
.wParam
== VK_RETURN
) || (msg
.wParam
== VK_ESCAPE
)))) break;
2140 if (msg
.message
== WM_PAINT
)
2142 if(!iconic
&& !DragFullWindows
) NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2143 UpdateWindow( msg
.hwnd
);
2144 if(!iconic
&& !DragFullWindows
) NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2148 if ((msg
.message
!= WM_KEYDOWN
) && (msg
.message
!= WM_MOUSEMOVE
))
2149 continue; /* We are not interested in other messages */
2153 if (msg
.message
== WM_KEYDOWN
) switch(msg
.wParam
)
2155 case VK_UP
: pt
.y
-= 8; break;
2156 case VK_DOWN
: pt
.y
+= 8; break;
2157 case VK_LEFT
: pt
.x
-= 8; break;
2158 case VK_RIGHT
: pt
.x
+= 8; break;
2161 pt
.x
= max( pt
.x
, mouseRect
.left
);
2162 pt
.x
= min( pt
.x
, mouseRect
.right
);
2163 pt
.y
= max( pt
.y
, mouseRect
.top
);
2164 pt
.y
= min( pt
.y
, mouseRect
.bottom
);
2166 dx
= pt
.x
- capturePoint
.x
;
2167 dy
= pt
.y
- capturePoint
.y
;
2175 if( iconic
) /* ok, no system popup tracking */
2177 hOldCursor
= SetCursor(hDragCursor
);
2179 WINPOS_ShowIconTitle( wndPtr
, FALSE
);
2180 } else if(TWEAK_WineLook
!= WIN31_LOOK
)
2182 if(!DragFullWindows
)
2183 NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2187 if (msg
.message
== WM_KEYDOWN
) SetCursorPos( pt
.x
, pt
.y
);
2190 RECT newRect
= sizingRect
;
2191 WPARAM wpSizingHit
= 0;
2193 if (hittest
== HTCAPTION
) OffsetRect( &newRect
, dx
, dy
);
2194 if (ON_LEFT_BORDER(hittest
)) newRect
.left
+= dx
;
2195 else if (ON_RIGHT_BORDER(hittest
)) newRect
.right
+= dx
;
2196 if (ON_TOP_BORDER(hittest
)) newRect
.top
+= dy
;
2197 else if (ON_BOTTOM_BORDER(hittest
)) newRect
.bottom
+= dy
;
2198 if(!iconic
&& !DragFullWindows
) NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2201 /* determine the hit location */
2202 if (hittest
>= HTLEFT
&& hittest
<= HTBOTTOMRIGHT
)
2203 wpSizingHit
= WMSZ_LEFT
+ (hittest
- HTLEFT
);
2204 SendMessageA( hwnd
, WM_SIZING
, wpSizingHit
, (LPARAM
)&newRect
);
2208 if(!DragFullWindows
)
2209 NC_DrawMovingFrame( hdc
, &newRect
, thickframe
);
2211 /* To avoid any deadlocks, all the locks on the windows
2212 structures must be suspended before the SetWindowPos */
2213 iWndsLocks
= WIN_SuspendWndsLock();
2214 SetWindowPos( hwnd
, 0, newRect
.left
, newRect
.top
,
2215 newRect
.right
- newRect
.left
,
2216 newRect
.bottom
- newRect
.top
,
2217 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
2218 WIN_RestoreWndsLock(iWndsLocks
);
2221 sizingRect
= newRect
;
2229 if( moved
) /* restore cursors, show icon title later on */
2231 ShowCursor( FALSE
);
2232 SetCursor( hOldCursor
);
2234 DestroyCursor( hDragCursor
);
2236 else if(moved
|| TWEAK_WineLook
== WIN31_LOOK
)
2237 if(!DragFullWindows
)
2238 NC_DrawMovingFrame( hdc
, &sizingRect
, thickframe
);
2240 if (wndPtr
->dwStyle
& WS_CHILD
)
2241 ReleaseDC( wndPtr
->parent
->hwndSelf
, hdc
);
2243 ReleaseDC( 0, hdc
);
2245 wndPtr
->pDriver
->pPostSizeMove(wndPtr
);
2247 if (HOOK_IsHooked( WH_CBT
))
2249 RECT16
* pr
= SEGPTR_NEW(RECT16
);
2252 CONV_RECT32TO16( &sizingRect
, pr
);
2253 if( HOOK_CallHooks16( WH_CBT
, HCBT_MOVESIZE
, hwnd
,
2254 (LPARAM
)SEGPTR_GET(pr
)) )
2255 sizingRect
= wndPtr
->rectWindow
;
2257 CONV_RECT16TO32( pr
, &sizingRect
);
2261 SendMessageA( hwnd
, WM_EXITSIZEMOVE
, 0, 0 );
2262 SendMessageA( hwnd
, WM_SETVISIBLE
, !IsIconic16(hwnd
), 0L);
2264 /* window moved or resized */
2267 /* To avoid any deadlocks, all the locks on the windows
2268 structures must be suspended before the SetWindowPos */
2269 iWndsLocks
= WIN_SuspendWndsLock();
2271 /* if the moving/resizing isn't canceled call SetWindowPos
2272 * with the new position or the new size of the window
2274 if (!((msg
.message
== WM_KEYDOWN
) && (msg
.wParam
== VK_ESCAPE
)) )
2276 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
2277 if(!DragFullWindows
)
2278 SetWindowPos( hwnd
, 0, sizingRect
.left
, sizingRect
.top
,
2279 sizingRect
.right
- sizingRect
.left
,
2280 sizingRect
.bottom
- sizingRect
.top
,
2281 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
2283 else { /* restore previous size/position */
2285 SetWindowPos( hwnd
, 0, origRect
.left
, origRect
.top
,
2286 origRect
.right
- origRect
.left
,
2287 origRect
.bottom
- origRect
.top
,
2288 ( hittest
== HTCAPTION
) ? SWP_NOSIZE
: 0 );
2291 WIN_RestoreWndsLock(iWndsLocks
);
2294 if( IsWindow(hwnd
) )
2295 if( wndPtr
->dwStyle
& WS_MINIMIZE
)
2297 /* Single click brings up the system menu when iconized */
2301 if( wndPtr
->dwStyle
& WS_SYSMENU
)
2302 SendMessageA( hwnd
, WM_SYSCOMMAND
,
2303 SC_MOUSEMENU
+ HTSYSMENU
, MAKELONG(pt
.x
,pt
.y
));
2305 else WINPOS_ShowIconTitle( wndPtr
, TRUE
);
2309 WIN_ReleaseWndPtr(wndPtr
);
2313 /***********************************************************************
2314 * NC_TrackMinMaxBox95
2316 * Track a mouse button press on the minimize or maximize box.
2318 * The big difference between 3.1 and 95 is the disabled button state.
2319 * In win95 the system button can be disabled, so it can ignore the mouse
2323 static void NC_TrackMinMaxBox95( HWND hwnd
, WORD wParam
)
2326 HDC hdc
= GetWindowDC( hwnd
);
2327 BOOL pressed
= TRUE
;
2329 DWORD wndStyle
= GetWindowLongA( hwnd
, GWL_STYLE
);
2330 HMENU hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
2332 void (*paintButton
)(HWND
, HDC16
, BOOL
, BOOL
);
2334 if (wParam
== HTMINBUTTON
)
2336 /* If the style is not present, do nothing */
2337 if (!(wndStyle
& WS_MINIMIZEBOX
))
2340 /* Check if the sysmenu item for minimize is there */
2341 state
= GetMenuState(hSysMenu
, SC_MINIMIZE
, MF_BYCOMMAND
);
2343 paintButton
= &NC_DrawMinButton95
;
2347 /* If the style is not present, do nothing */
2348 if (!(wndStyle
& WS_MAXIMIZEBOX
))
2351 /* Check if the sysmenu item for maximize is there */
2352 state
= GetMenuState(hSysMenu
, SC_MAXIMIZE
, MF_BYCOMMAND
);
2354 paintButton
= &NC_DrawMaxButton95
;
2359 (*paintButton
)( hwnd
, hdc
, TRUE
, FALSE
);
2363 BOOL oldstate
= pressed
;
2364 MSG_InternalGetMessage( QMSG_WIN32A
, &msg
, 0, 0, 0, PM_REMOVE
, FALSE
, NULL
);
2366 if(msg
.message
== WM_LBUTTONUP
)
2369 if(msg
.message
!= WM_MOUSEMOVE
)
2372 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
2373 if (pressed
!= oldstate
)
2374 (*paintButton
)( hwnd
, hdc
, pressed
, FALSE
);
2378 (*paintButton
)(hwnd
, hdc
, FALSE
, FALSE
);
2381 ReleaseDC( hwnd
, hdc
);
2383 /* If the item minimize or maximize of the sysmenu are not there */
2384 /* or if the style is not present, do nothing */
2385 if ((!pressed
) || (state
== 0xFFFFFFFF))
2388 if (wParam
== HTMINBUTTON
)
2389 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
2391 SendMessageA( hwnd
, WM_SYSCOMMAND
,
2392 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
2395 /***********************************************************************
2398 * Track a mouse button press on the minimize or maximize box.
2400 static void NC_TrackMinMaxBox( HWND hwnd
, WORD wParam
)
2403 HDC hdc
= GetWindowDC( hwnd
);
2404 BOOL pressed
= TRUE
;
2405 void (*paintButton
)(HWND
, HDC16
, BOOL
);
2409 if (wParam
== HTMINBUTTON
)
2410 paintButton
= &NC_DrawMinButton
;
2412 paintButton
= &NC_DrawMaxButton
;
2414 (*paintButton
)( hwnd
, hdc
, TRUE
);
2418 BOOL oldstate
= pressed
;
2419 MSG_InternalGetMessage( QMSG_WIN32A
, &msg
, 0, 0, 0, PM_REMOVE
, FALSE
, NULL
);
2421 if(msg
.message
== WM_LBUTTONUP
)
2424 if(msg
.message
!= WM_MOUSEMOVE
)
2427 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
2428 if (pressed
!= oldstate
)
2429 (*paintButton
)( hwnd
, hdc
, pressed
);
2433 (*paintButton
)( hwnd
, hdc
, FALSE
);
2436 ReleaseDC( hwnd
, hdc
);
2438 if (!pressed
) return;
2440 if (wParam
== HTMINBUTTON
)
2441 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_MINIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
2443 SendMessageA( hwnd
, WM_SYSCOMMAND
,
2444 IsZoomed(hwnd
) ? SC_RESTORE
:SC_MAXIMIZE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
2448 /***********************************************************************
2449 * NC_TrackCloseButton95
2451 * Track a mouse button press on the Win95 close button.
2454 NC_TrackCloseButton95 (HWND hwnd
, WORD wParam
)
2458 BOOL pressed
= TRUE
;
2459 HMENU hSysMenu
= GetSystemMenu(hwnd
, FALSE
);
2465 state
= GetMenuState(hSysMenu
, SC_CLOSE
, MF_BYCOMMAND
);
2467 /* If the item close of the sysmenu is disabled or not there do nothing */
2468 if((state
& MF_DISABLED
) || (state
& MF_GRAYED
) || (state
== 0xFFFFFFFF))
2471 hdc
= GetWindowDC( hwnd
);
2475 NC_DrawCloseButton95 (hwnd
, hdc
, TRUE
, FALSE
);
2479 BOOL oldstate
= pressed
;
2480 MSG_InternalGetMessage( QMSG_WIN32A
, &msg
, 0, 0, 0, PM_REMOVE
, FALSE
, NULL
);
2482 if(msg
.message
== WM_LBUTTONUP
)
2485 if(msg
.message
!= WM_MOUSEMOVE
)
2488 pressed
= (NC_HandleNCHitTest( hwnd
, msg
.pt
) == wParam
);
2489 if (pressed
!= oldstate
)
2490 NC_DrawCloseButton95 (hwnd
, hdc
, pressed
, FALSE
);
2494 NC_DrawCloseButton95 (hwnd
, hdc
, FALSE
, FALSE
);
2497 ReleaseDC( hwnd
, hdc
);
2498 if (!pressed
) return;
2500 SendMessageA( hwnd
, WM_SYSCOMMAND
, SC_CLOSE
, MAKELONG(msg
.pt
.x
,msg
.pt
.y
) );
2504 /***********************************************************************
2507 * Track a mouse button press on the horizontal or vertical scroll-bar.
2509 static void NC_TrackScrollBar( HWND hwnd
, WPARAM wParam
, POINT pt
)
2513 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
2515 if ((wParam
& 0xfff0) == SC_HSCROLL
)
2517 if ((wParam
& 0x0f) != HTHSCROLL
) goto END
;
2518 scrollbar
= SB_HORZ
;
2520 else /* SC_VSCROLL */
2522 if ((wParam
& 0x0f) != HTVSCROLL
) goto END
;
2523 scrollbar
= SB_VERT
;
2526 if (!(msg
= SEGPTR_NEW(MSG16
))) goto END
;
2527 pt
.x
-= wndPtr
->rectWindow
.left
;
2528 pt
.y
-= wndPtr
->rectWindow
.top
;
2530 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, WM_LBUTTONDOWN
, pt
);
2534 GetMessage16( SEGPTR_GET(msg
), 0, 0, 0 );
2535 switch(msg
->message
)
2540 pt
.x
= LOWORD(msg
->lParam
) + wndPtr
->rectClient
.left
-
2541 wndPtr
->rectWindow
.left
;
2542 pt
.y
= HIWORD(msg
->lParam
) + wndPtr
->rectClient
.top
-
2543 wndPtr
->rectWindow
.top
;
2544 SCROLL_HandleScrollEvent( hwnd
, scrollbar
, msg
->message
, pt
);
2547 TranslateMessage16( msg
);
2548 DispatchMessage16( msg
);
2551 if (!IsWindow( hwnd
))
2556 } while (msg
->message
!= WM_LBUTTONUP
);
2559 WIN_ReleaseWndPtr(wndPtr
);
2562 /***********************************************************************
2563 * NC_HandleNCLButtonDown
2565 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2567 LONG
NC_HandleNCLButtonDown( WND
* pWnd
, WPARAM16 wParam
, LPARAM lParam
)
2569 HWND hwnd
= pWnd
->hwndSelf
;
2571 switch(wParam
) /* Hit test */
2574 hwnd
= WIN_GetTopParent(hwnd
);
2576 if( WINPOS_SetActiveWindow(hwnd
, TRUE
, TRUE
) || (GetActiveWindow() == hwnd
) )
2577 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_MOVE
+ HTCAPTION
, lParam
);
2581 if( pWnd
->dwStyle
& WS_SYSMENU
)
2583 if( !(pWnd
->dwStyle
& WS_MINIMIZE
) )
2585 HDC hDC
= GetWindowDC(hwnd
);
2586 if (TWEAK_WineLook
== WIN31_LOOK
)
2587 NC_DrawSysButton( hwnd
, hDC
, TRUE
);
2589 NC_DrawSysButton95( hwnd
, hDC
, TRUE
);
2590 ReleaseDC( hwnd
, hDC
);
2592 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
+ HTSYSMENU
, lParam
);
2597 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_MOUSEMENU
, lParam
);
2601 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
, lParam
);
2605 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
, lParam
);
2610 if (TWEAK_WineLook
== WIN31_LOOK
)
2611 NC_TrackMinMaxBox( hwnd
, wParam
);
2613 NC_TrackMinMaxBox95( hwnd
, wParam
);
2617 if (TWEAK_WineLook
>= WIN95_LOOK
)
2618 NC_TrackCloseButton95 (hwnd
, wParam
);
2629 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2630 SendMessage16( hwnd
, WM_SYSCOMMAND
, SC_SIZE
+ wParam
- 2, lParam
);
2640 /***********************************************************************
2641 * NC_HandleNCLButtonDblClk
2643 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2645 LONG
NC_HandleNCLButtonDblClk( WND
*pWnd
, WPARAM16 wParam
, LPARAM lParam
)
2648 * if this is an icon, send a restore since we are handling
2651 if (pWnd
->dwStyle
& WS_MINIMIZE
)
2653 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_RESTORE
, lParam
);
2657 switch(wParam
) /* Hit test */
2660 /* stop processing if WS_MAXIMIZEBOX is missing */
2661 if (pWnd
->dwStyle
& WS_MAXIMIZEBOX
)
2662 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
,
2663 (pWnd
->dwStyle
& WS_MAXIMIZE
) ? SC_RESTORE
: SC_MAXIMIZE
,
2668 if (!(GetClassWord(pWnd
->hwndSelf
, GCW_STYLE
) & CS_NOCLOSE
))
2669 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_CLOSE
, lParam
);
2673 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_HSCROLL
+ HTHSCROLL
,
2678 SendMessage16( pWnd
->hwndSelf
, WM_SYSCOMMAND
, SC_VSCROLL
+ HTVSCROLL
,
2686 /***********************************************************************
2687 * NC_HandleSysCommand
2689 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2691 LONG
NC_HandleSysCommand( HWND hwnd
, WPARAM wParam
, POINT pt
)
2693 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
2694 UINT16 uCommand
= wParam
& 0xFFF0;
2696 TRACE("Handling WM_SYSCOMMAND %x %ld,%ld\n", wParam
, pt
.x
, pt
.y
);
2698 if (wndPtr
->dwStyle
& WS_CHILD
&& uCommand
!= SC_KEYMENU
)
2699 ScreenToClient( wndPtr
->parent
->hwndSelf
, &pt
);
2705 NC_DoSizeMove( hwnd
, wParam
);
2709 if (hwnd
== GetForegroundWindow())
2710 ShowOwnedPopups(hwnd
,FALSE
);
2711 ShowWindow( hwnd
, SW_MINIMIZE
);
2715 if (IsIconic(hwnd
) && hwnd
== GetForegroundWindow())
2716 ShowOwnedPopups(hwnd
,TRUE
);
2717 ShowWindow( hwnd
, SW_MAXIMIZE
);
2721 if (IsIconic(hwnd
) && hwnd
== GetForegroundWindow())
2722 ShowOwnedPopups(hwnd
,TRUE
);
2723 ShowWindow( hwnd
, SW_RESTORE
);
2727 WIN_ReleaseWndPtr(wndPtr
);
2728 return SendMessageA( hwnd
, WM_CLOSE
, 0, 0 );
2732 NC_TrackScrollBar( hwnd
, wParam
, pt
);
2736 MENU_TrackMouseMenuBar( wndPtr
, wParam
& 0x000F, pt
);
2740 MENU_TrackKbdMenuBar( wndPtr
, wParam
, pt
.x
);
2744 WinExec( "taskman.exe", SW_SHOWNORMAL
);
2748 if (wParam
== SC_ABOUTWINE
)
2750 HMODULE hmodule
= LoadLibraryA( "shell32.dll" );
2753 FARPROC aboutproc
= GetProcAddress( hmodule
, "ShellAboutA" );
2754 if (aboutproc
) aboutproc( hwnd
, "Wine", WINE_RELEASE_INFO
, 0 );
2755 FreeLibrary( hmodule
);
2759 if (wParam
== SC_PUTMARK
)
2760 TRACE_(shell
)("Mark requested by user\n");
2767 FIXME("unimplemented!\n");
2770 WIN_ReleaseWndPtr(wndPtr
);
2774 /*************************************************************
2777 * Stub for the grayed button of the caption
2779 *************************************************************/
2781 BOOL
NC_DrawGrayButton(HDC hdc
, int x
, int y
)
2784 HDC hdcMask
= CreateCompatibleDC (0);
2787 hMaskBmp
= CreateBitmap (12, 10, 1, 1, lpGrayMask
);
2792 SelectObject (hdcMask
, hMaskBmp
);
2794 /* Draw the grayed bitmap using the mask */
2795 hOldBrush
= SelectObject (hdc
, RGB(128, 128, 128));
2796 BitBlt (hdc
, x
, y
, 12, 10,
2797 hdcMask
, 0, 0, 0xB8074A);
2800 SelectObject (hdc
, hOldBrush
);
2801 DeleteObject(hMaskBmp
);
2807 HICON16
NC_IconForWindow(WND
*wndPtr
)
2809 HICON16 hIcon
= (HICON
) GetClassLongA(wndPtr
->hwndSelf
, GCL_HICONSM
);
2810 if(!hIcon
) hIcon
= (HICON
) GetClassLongA(wndPtr
->hwndSelf
, GCL_HICON
);
2812 /* If there is no hIcon specified and this is a modal dialog, */
2813 /* get the default one. */
2814 if (!hIcon
&& (wndPtr
->dwStyle
& DS_MODALFRAME
))
2815 hIcon
= LoadImageA(0, IDI_WINLOGOA
, IMAGE_ICON
, 0, 0, LR_DEFAULTCOLOR
);