Adapted Winsock to Linux 2.4 TCP socket poll() behaviour
[wine/wine-kai.git] / windows / nonclient.c
blob913a26bba5e8fe6f9456afa0149deff22bc36115
1 /*
2 * Non-client area window functions
4 * Copyright 1994 Alexandre Julliard
6 */
8 #include "windef.h"
9 #include "wingdi.h"
10 #include "wine/winuser16.h"
11 #include "version.h"
12 #include "win.h"
13 #include "message.h"
14 #include "user.h"
15 #include "heap.h"
16 #include "dce.h"
17 #include "cursoricon.h"
18 #include "dialog.h"
19 #include "menu.h"
20 #include "winpos.h"
21 #include "hook.h"
22 #include "scroll.h"
23 #include "nonclient.h"
24 #include "queue.h"
25 #include "selectors.h"
26 #include "tweak.h"
27 #include "debugtools.h"
28 #include "options.h"
29 #include "shellapi.h"
30 #include "cache.h"
31 #include "bitmap.h"
33 DEFAULT_DEBUG_CHANNEL(nonclient)
34 DECLARE_DEBUG_CHANNEL(shell)
36 BOOL NC_DrawGrayButton(HDC hdc, int x, int y);
38 static HBITMAP16 hbitmapClose = 0;
39 static HBITMAP16 hbitmapCloseD = 0;
40 static HBITMAP16 hbitmapMinimize = 0;
41 static HBITMAP16 hbitmapMinimizeD = 0;
42 static HBITMAP16 hbitmapMaximize = 0;
43 static HBITMAP16 hbitmapMaximizeD = 0;
44 static HBITMAP16 hbitmapRestore = 0;
45 static HBITMAP16 hbitmapRestoreD = 0;
47 BYTE lpGrayMask[] = { 0xAA, 0xA0,
48 0x55, 0x50,
49 0xAA, 0xA0,
50 0x55, 0x50,
51 0xAA, 0xA0,
52 0x55, 0x50,
53 0xAA, 0xA0,
54 0x55, 0x50,
55 0xAA, 0xA0,
56 0x55, 0x50};
58 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
59 #define SC_PUTMARK (SC_SCREENSAVE+2)
61 /* Some useful macros */
62 #define HAS_DLGFRAME(style,exStyle) \
63 (((exStyle) & WS_EX_DLGMODALFRAME) || \
64 (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
66 #define HAS_THICKFRAME(style,exStyle) \
67 (((style) & WS_THICKFRAME) && \
68 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
70 #define HAS_THINFRAME(style) \
71 (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
73 #define HAS_BIGFRAME(style,exStyle) \
74 (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
75 ((exStyle) & WS_EX_DLGMODALFRAME))
77 #define HAS_ANYFRAME(style,exStyle) \
78 (((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
79 ((exStyle) & WS_EX_DLGMODALFRAME) || \
80 !((style) & (WS_CHILD | WS_POPUP)))
82 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
84 #define ON_LEFT_BORDER(hit) \
85 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
86 #define ON_RIGHT_BORDER(hit) \
87 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
88 #define ON_TOP_BORDER(hit) \
89 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
90 #define ON_BOTTOM_BORDER(hit) \
91 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
93 /***********************************************************************
94 * WIN_WindowNeedsWMBorder
96 * This method defines the rules for a window to have a WM border,
97 * caption... It is used for consitency purposes.
99 BOOL WIN_WindowNeedsWMBorder( DWORD style, DWORD exStyle )
101 if (!(style & WS_CHILD) &&
102 Options.managed &&
103 !(exStyle & WS_EX_TOOLWINDOW) &&
104 ( ((style & WS_CAPTION) == WS_CAPTION) ||
105 (style & WS_THICKFRAME)))
106 return TRUE;
107 if (exStyle & WS_EX_TRAYWINDOW)
108 return TRUE;
109 return FALSE;
112 /***********************************************************************
113 * NC_AdjustRect
115 * Compute the size of the window rectangle from the size of the
116 * client rectangle.
118 static void NC_AdjustRect( LPRECT16 rect, DWORD style, BOOL menu,
119 DWORD exStyle )
121 if (TWEAK_WineLook > WIN31_LOOK)
122 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
124 if(style & WS_ICONIC) return;
125 /* Decide if the window will be managed (see CreateWindowEx) */
126 if (!WIN_WindowNeedsWMBorder(style, exStyle))
128 if (HAS_THICKFRAME( style, exStyle ))
129 InflateRect16( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
130 else
131 if (HAS_DLGFRAME( style, exStyle ))
132 InflateRect16( rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
133 else
134 if (HAS_THINFRAME( style ))
135 InflateRect16( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
137 if ((style & WS_CAPTION) == WS_CAPTION)
138 rect->top -= GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
140 if (menu) rect->top -= GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYBORDER);
142 if (style & WS_VSCROLL) {
143 rect->right += GetSystemMetrics(SM_CXVSCROLL) - 1;
144 if(!HAS_ANYFRAME( style, exStyle ))
145 rect->right++;
148 if (style & WS_HSCROLL) {
149 rect->bottom += GetSystemMetrics(SM_CYHSCROLL) - 1;
150 if(!HAS_ANYFRAME( style, exStyle ))
151 rect->bottom++;
156 /******************************************************************************
157 * NC_AdjustRectOuter95
159 * Computes the size of the "outside" parts of the window based on the
160 * parameters of the client area.
162 + PARAMS
163 * LPRECT16 rect
164 * DWORD style
165 * BOOL menu
166 * DWORD exStyle
168 * NOTES
169 * "Outer" parts of a window means the whole window frame, caption and
170 * menu bar. It does not include "inner" parts of the frame like client
171 * edge, static edge or scroll bars.
173 * Revision history
174 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
175 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
177 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
178 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
179 * NC_AdjustRectInner95 and added handling of Win95 styles.
181 * 28-Jul-1999 Ove Kåven (ovek@arcticnet.no)
182 * Streamlined window style checks.
184 *****************************************************************************/
186 static void
187 NC_AdjustRectOuter95 (LPRECT16 rect, DWORD style, BOOL menu, DWORD exStyle)
189 if(style & WS_ICONIC) return;
191 /* Decide if the window will be managed (see CreateWindowEx) */
192 if (!WIN_WindowNeedsWMBorder(style, exStyle))
194 if (HAS_THICKFRAME( style, exStyle ))
195 InflateRect16( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
196 else
197 if (HAS_DLGFRAME( style, exStyle ))
198 InflateRect16(rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
199 else
200 if (HAS_THINFRAME( style ))
201 InflateRect16( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
203 if ((style & WS_CAPTION) == WS_CAPTION)
205 if (exStyle & WS_EX_TOOLWINDOW)
206 rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
207 else
208 rect->top -= GetSystemMetrics(SM_CYCAPTION);
212 if (menu)
213 rect->top -= GetSystemMetrics(SM_CYMENU);
217 /******************************************************************************
218 * NC_AdjustRectInner95
220 * Computes the size of the "inside" part of the window based on the
221 * parameters of the client area.
223 + PARAMS
224 * LPRECT16 rect
225 * DWORD style
226 * DWORD exStyle
228 * NOTES
229 * "Inner" part of a window means the window frame inside of the flat
230 * window frame. It includes the client edge, the static edge and the
231 * scroll bars.
233 * Revision history
234 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
235 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
237 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
238 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
239 * NC_AdjustRectInner95 and added handling of Win95 styles.
241 *****************************************************************************/
243 static void
244 NC_AdjustRectInner95 (LPRECT16 rect, DWORD style, DWORD exStyle)
246 if(style & WS_ICONIC) return;
248 if (exStyle & WS_EX_CLIENTEDGE)
249 InflateRect16 (rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
251 if (exStyle & WS_EX_STATICEDGE)
252 InflateRect16 (rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
254 if (style & WS_VSCROLL) rect->right += GetSystemMetrics(SM_CXVSCROLL);
255 if (style & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
259 /***********************************************************************
260 * DrawCaption16 [USER.660] Draws a caption bar
262 * PARAMS
263 * hwnd [I]
264 * hdc [I]
265 * lpRect [I]
266 * uFlags [I]
268 * RETURNS
269 * Success:
270 * Failure:
273 BOOL16 WINAPI
274 DrawCaption16 (HWND16 hwnd, HDC16 hdc, const RECT16 *rect, UINT16 uFlags)
276 RECT rect32;
278 if (rect)
279 CONV_RECT16TO32 (rect, &rect32);
281 return (BOOL16)DrawCaptionTempA (hwnd, hdc, rect ? &rect32 : NULL,
282 0, 0, NULL, uFlags & 0x1F);
286 /***********************************************************************
287 * DrawCaption [USER32.154] Draws a caption bar
289 * PARAMS
290 * hwnd [I]
291 * hdc [I]
292 * lpRect [I]
293 * uFlags [I]
295 * RETURNS
296 * Success:
297 * Failure:
300 BOOL WINAPI
301 DrawCaption (HWND hwnd, HDC hdc, const RECT *lpRect, UINT uFlags)
303 return DrawCaptionTempA (hwnd, hdc, lpRect, 0, 0, NULL, uFlags & 0x1F);
307 /***********************************************************************
308 * DrawCaptionTemp16 [USER.657]
310 * PARAMS
312 * RETURNS
313 * Success:
314 * Failure:
317 BOOL16 WINAPI
318 DrawCaptionTemp16 (HWND16 hwnd, HDC16 hdc, const RECT16 *rect, HFONT16 hFont,
319 HICON16 hIcon, LPCSTR str, UINT16 uFlags)
321 RECT rect32;
323 if (rect)
324 CONV_RECT16TO32(rect,&rect32);
326 return (BOOL16)DrawCaptionTempA (hwnd, hdc, rect?&rect32:NULL, hFont,
327 hIcon, str, uFlags & 0x1F);
331 /***********************************************************************
332 * DrawCaptionTempA [USER32.599]
334 * PARAMS
336 * RETURNS
337 * Success:
338 * Failure:
341 BOOL WINAPI
342 DrawCaptionTempA (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
343 HICON hIcon, LPCSTR str, UINT uFlags)
345 RECT rc = *rect;
347 TRACE("(%08x,%08x,%p,%08x,%08x,\"%s\",%08x)\n",
348 hwnd, hdc, rect, hFont, hIcon, str, uFlags);
350 /* drawing background */
351 if (uFlags & DC_INBUTTON) {
352 FillRect (hdc, &rc, GetSysColorBrush (COLOR_3DFACE));
354 if (uFlags & DC_ACTIVE) {
355 HBRUSH hbr = SelectObject (hdc, CACHE_GetPattern55AABrush ());
356 PatBlt (hdc, rc.left, rc.top,
357 rc.right-rc.left, rc.bottom-rc.top, 0xFA0089);
358 SelectObject (hdc, hbr);
361 else {
362 FillRect (hdc, &rc, GetSysColorBrush ((uFlags & DC_ACTIVE) ?
363 COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
367 /* drawing icon */
368 if ((uFlags & DC_ICON) && !(uFlags & DC_SMALLCAP)) {
369 POINT pt;
371 pt.x = rc.left + 2;
372 pt.y = (rc.bottom + rc.top - GetSystemMetrics(SM_CYSMICON)) / 2;
374 if (hIcon) {
375 DrawIconEx (hdc, pt.x, pt.y, hIcon, GetSystemMetrics(SM_CXSMICON),
376 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
378 else {
379 WND* wndPtr = WIN_FindWndPtr(hwnd);
380 HICON hAppIcon = (HICON) NC_IconForWindow(wndPtr);
381 DrawIconEx (hdc, pt.x, pt.y, hAppIcon, GetSystemMetrics(SM_CXSMICON),
382 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
383 WIN_ReleaseWndPtr(wndPtr);
386 rc.left += (rc.bottom - rc.top);
389 /* drawing text */
390 if (uFlags & DC_TEXT) {
391 HFONT hOldFont;
393 if (uFlags & DC_INBUTTON)
394 SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
395 else if (uFlags & DC_ACTIVE)
396 SetTextColor (hdc, GetSysColor (COLOR_CAPTIONTEXT));
397 else
398 SetTextColor (hdc, GetSysColor (COLOR_INACTIVECAPTIONTEXT));
400 SetBkMode (hdc, TRANSPARENT);
402 if (hFont)
403 hOldFont = SelectObject (hdc, hFont);
404 else {
405 NONCLIENTMETRICSA nclm;
406 HFONT hNewFont;
407 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
408 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
409 hNewFont = CreateFontIndirectA ((uFlags & DC_SMALLCAP) ?
410 &nclm.lfSmCaptionFont : &nclm.lfCaptionFont);
411 hOldFont = SelectObject (hdc, hNewFont);
414 if (str)
415 DrawTextA (hdc, str, -1, &rc,
416 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
417 else {
418 CHAR szText[128];
419 INT nLen;
420 nLen = GetWindowTextA (hwnd, szText, 128);
421 DrawTextA (hdc, szText, nLen, &rc,
422 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
425 if (hFont)
426 SelectObject (hdc, hOldFont);
427 else
428 DeleteObject (SelectObject (hdc, hOldFont));
431 /* drawing focus ??? */
432 if (uFlags & 0x2000)
433 FIXME("undocumented flag (0x2000)!\n");
435 return 0;
439 /***********************************************************************
440 * DrawCaptionTempW [USER32.602]
442 * PARAMS
444 * RETURNS
445 * Success:
446 * Failure:
449 BOOL WINAPI
450 DrawCaptionTempW (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
451 HICON hIcon, LPCWSTR str, UINT uFlags)
453 LPSTR p = HEAP_strdupWtoA (GetProcessHeap (), 0, str);
454 BOOL res = DrawCaptionTempA (hwnd, hdc, rect, hFont, hIcon, p, uFlags);
455 HeapFree (GetProcessHeap (), 0, p);
456 return res;
460 /***********************************************************************
461 * AdjustWindowRect16 (USER.102)
463 BOOL16 WINAPI AdjustWindowRect16( LPRECT16 rect, DWORD style, BOOL16 menu )
465 return AdjustWindowRectEx16( rect, style, menu, 0 );
469 /***********************************************************************
470 * AdjustWindowRect (USER32.2)
472 BOOL WINAPI AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu )
474 return AdjustWindowRectEx( rect, style, menu, 0 );
478 /***********************************************************************
479 * AdjustWindowRectEx16 (USER.454)
481 BOOL16 WINAPI AdjustWindowRectEx16( LPRECT16 rect, DWORD style,
482 BOOL16 menu, DWORD exStyle )
484 /* Correct the window style */
486 if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
487 style |= WS_CAPTION;
488 style &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD);
489 exStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE |
490 WS_EX_STATICEDGE | WS_EX_TOOLWINDOW);
491 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
493 TRACE("(%d,%d)-(%d,%d) %08lx %d %08lx\n",
494 rect->left, rect->top, rect->right, rect->bottom,
495 style, menu, exStyle );
497 if (TWEAK_WineLook == WIN31_LOOK)
498 NC_AdjustRect( rect, style, menu, exStyle );
499 else {
500 NC_AdjustRectOuter95( rect, style, menu, exStyle );
501 NC_AdjustRectInner95( rect, style, exStyle );
504 return TRUE;
508 /***********************************************************************
509 * AdjustWindowRectEx (USER32.3)
511 BOOL WINAPI AdjustWindowRectEx( LPRECT rect, DWORD style,
512 BOOL menu, DWORD exStyle )
514 RECT16 rect16;
515 BOOL ret;
517 CONV_RECT32TO16( rect, &rect16 );
518 ret = AdjustWindowRectEx16( &rect16, style, (BOOL16)menu, exStyle );
519 CONV_RECT16TO32( &rect16, rect );
520 return ret;
524 /***********************************************************************
525 * NC_HandleNCCalcSize
527 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
529 LONG NC_HandleNCCalcSize( WND *pWnd, RECT *winRect )
531 RECT16 tmpRect = { 0, 0, 0, 0 };
532 LONG result = 0;
533 UINT style = (UINT) GetClassLongA(pWnd->hwndSelf, GCL_STYLE);
535 if (style & CS_VREDRAW) result |= WVR_VREDRAW;
536 if (style & CS_HREDRAW) result |= WVR_HREDRAW;
538 if( !( pWnd->dwStyle & WS_MINIMIZE ) ) {
539 if (TWEAK_WineLook == WIN31_LOOK)
540 NC_AdjustRect( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
541 else
542 NC_AdjustRectOuter95( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
544 winRect->left -= tmpRect.left;
545 winRect->top -= tmpRect.top;
546 winRect->right -= tmpRect.right;
547 winRect->bottom -= tmpRect.bottom;
549 if (HAS_MENU(pWnd)) {
550 TRACE("Calling GetMenuBarHeight with HWND 0x%x, width %d, "
551 "at (%d, %d).\n", pWnd->hwndSelf,
552 winRect->right - winRect->left,
553 -tmpRect.left, -tmpRect.top );
555 winRect->top +=
556 MENU_GetMenuBarHeight( pWnd->hwndSelf,
557 winRect->right - winRect->left,
558 -tmpRect.left, -tmpRect.top ) + 1;
561 if (TWEAK_WineLook > WIN31_LOOK) {
562 SetRect16 (&tmpRect, 0, 0, 0, 0);
563 NC_AdjustRectInner95 (&tmpRect, pWnd->dwStyle, pWnd->dwExStyle);
564 winRect->left -= tmpRect.left;
565 winRect->top -= tmpRect.top;
566 winRect->right -= tmpRect.right;
567 winRect->bottom -= tmpRect.bottom;
570 return result;
574 /***********************************************************************
575 * NC_GetInsideRect
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->flags & WIN_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) );
594 else
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 );
602 else
603 if (HAS_THINFRAME( wndPtr->dwStyle ))
604 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
605 END:
606 WIN_ReleaseWndPtr(wndPtr);
607 return;
611 /***********************************************************************
612 * NC_GetInsideRect95
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()).
619 static void
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->flags & WIN_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));
655 END:
656 WIN_ReleaseWndPtr(wndPtr);
657 return;
661 /***********************************************************************
662 * NC_DoNCHitTest
664 * Handle a WM_NCHITTEST message. Called from NC_HandleNcHitTest().
667 static LONG NC_DoNCHitTest (WND *wndPtr, POINT16 pt )
669 RECT16 rect;
671 TRACE("hwnd=%04x pt=%d,%d\n", wndPtr->hwndSelf, pt.x, pt.y );
673 GetWindowRect16 (wndPtr->hwndSelf, &rect );
674 if (!PtInRect16( &rect, pt )) return HTNOWHERE;
676 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
678 if (!(wndPtr->flags & WIN_MANAGED))
680 /* Check borders */
681 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
683 InflateRect16( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
684 if (!PtInRect16( &rect, pt ))
686 /* Check top sizing border */
687 if (pt.y < rect.top)
689 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
690 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
691 return HTTOP;
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;
698 return HTBOTTOM;
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;
705 return HTLEFT;
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;
712 return HTRIGHT;
716 else /* No thick frame */
718 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
719 InflateRect16(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
720 else if (HAS_THINFRAME( wndPtr->dwStyle ))
721 InflateRect16(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
722 if (!PtInRect16( &rect, pt )) return HTBORDER;
725 /* Check caption */
727 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
729 rect.top += GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
730 if (!PtInRect16( &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;
746 return HTCAPTION;
751 /* Check client area */
753 ScreenToClient16( wndPtr->hwndSelf, &pt );
754 GetClientRect16( wndPtr->hwndSelf, &rect );
755 if (PtInRect16( &rect, pt )) return HTCLIENT;
757 /* Check vertical scroll bar */
759 if (wndPtr->dwStyle & WS_VSCROLL)
761 rect.right += GetSystemMetrics(SM_CXVSCROLL);
762 if (PtInRect16( &rect, pt )) return HTVSCROLL;
765 /* Check horizontal scroll bar */
767 if (wndPtr->dwStyle & WS_HSCROLL)
769 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
770 if (PtInRect16( &rect, pt ))
772 /* Check size box */
773 if ((wndPtr->dwStyle & WS_VSCROLL) &&
774 (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
775 return HTSIZE;
776 return HTHSCROLL;
780 /* Check menu bar */
782 if (HAS_MENU(wndPtr))
784 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
785 return HTMENU;
788 /* Has to return HTNOWHERE if nothing was found
789 Could happen when a window has a customized non client area */
790 return HTNOWHERE;
794 /***********************************************************************
795 * NC_DoNCHitTest95
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
803 NC_DoNCHitTest95 (WND *wndPtr, POINT16 pt )
805 RECT16 rect;
807 TRACE("hwnd=%04x pt=%d,%d\n", wndPtr->hwndSelf, pt.x, pt.y );
809 GetWindowRect16 (wndPtr->hwndSelf, &rect );
810 if (!PtInRect16( &rect, pt )) return HTNOWHERE;
812 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
814 if (!(wndPtr->flags & WIN_MANAGED))
816 /* Check borders */
817 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
819 InflateRect16( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
820 if (!PtInRect16( &rect, pt ))
822 /* Check top sizing border */
823 if (pt.y < rect.top)
825 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
826 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
827 return HTTOP;
829 /* Check bottom sizing border */
830 if (pt.y >= rect.bottom)
832 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
833 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
834 return HTBOTTOM;
836 /* Check left sizing border */
837 if (pt.x < rect.left)
839 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
840 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
841 return HTLEFT;
843 /* Check right sizing border */
844 if (pt.x >= rect.right)
846 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
847 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
848 return HTRIGHT;
852 else /* No thick frame */
854 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
855 InflateRect16(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
856 else if (HAS_THINFRAME( wndPtr->dwStyle ))
857 InflateRect16(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
858 if (!PtInRect16( &rect, pt )) return HTBORDER;
861 /* Check caption */
863 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
865 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
866 rect.top += GetSystemMetrics(SM_CYSMCAPTION) - 1;
867 else
868 rect.top += GetSystemMetrics(SM_CYCAPTION) - 1;
869 if (!PtInRect16( &rect, pt ))
871 /* Check system menu */
872 if ((wndPtr->dwStyle & WS_SYSMENU) && !(wndPtr->dwExStyle & WS_EX_TOOLWINDOW))
874 if (NC_IconForWindow(wndPtr))
875 rect.left += GetSystemMetrics(SM_CYCAPTION) - 1;
877 if (pt.x < rect.left) return HTSYSMENU;
879 /* Check close button */
880 if (wndPtr->dwStyle & WS_SYSMENU)
881 rect.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
882 if (pt.x > rect.right) return HTCLOSE;
884 /* Check maximize box */
885 /* In win95 there is automatically a Maximize button when there is a minimize one*/
886 if ((wndPtr->dwStyle & WS_MAXIMIZEBOX)|| (wndPtr->dwStyle & WS_MINIMIZEBOX))
887 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
888 if (pt.x > rect.right) return HTMAXBUTTON;
890 /* Check minimize box */
891 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
892 if ((wndPtr->dwStyle & WS_MINIMIZEBOX)||(wndPtr->dwStyle & WS_MAXIMIZEBOX))
893 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
895 if (pt.x > rect.right) return HTMINBUTTON;
896 return HTCAPTION;
901 /* Check client area */
903 ScreenToClient16( wndPtr->hwndSelf, &pt );
904 GetClientRect16( wndPtr->hwndSelf, &rect );
905 if (PtInRect16( &rect, pt )) return HTCLIENT;
907 /* Check vertical scroll bar */
909 if (wndPtr->dwStyle & WS_VSCROLL)
911 rect.right += GetSystemMetrics(SM_CXVSCROLL);
912 if (PtInRect16( &rect, pt )) return HTVSCROLL;
915 /* Check horizontal scroll bar */
917 if (wndPtr->dwStyle & WS_HSCROLL)
919 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
920 if (PtInRect16( &rect, pt ))
922 /* Check size box */
923 if ((wndPtr->dwStyle & WS_VSCROLL) &&
924 (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
925 return HTSIZE;
926 return HTHSCROLL;
930 /* Check menu bar */
932 if (HAS_MENU(wndPtr))
934 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
935 return HTMENU;
938 /* Has to return HTNOWHERE if nothing was found
939 Could happen when a window has a customized non client area */
940 return HTNOWHERE;
944 /***********************************************************************
945 * NC_HandleNCHitTest
947 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
949 LONG
950 NC_HandleNCHitTest (HWND hwnd , POINT16 pt)
952 LONG retvalue;
953 WND *wndPtr = WIN_FindWndPtr (hwnd);
955 if (!wndPtr)
956 return HTERROR;
958 if (TWEAK_WineLook == WIN31_LOOK)
959 retvalue = NC_DoNCHitTest (wndPtr, pt);
960 else
961 retvalue = NC_DoNCHitTest95 (wndPtr, pt);
962 WIN_ReleaseWndPtr(wndPtr);
963 return retvalue;
967 /***********************************************************************
968 * NC_DrawSysButton
970 void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down )
972 RECT rect;
973 HDC hdcMem;
974 HBITMAP hbitmap;
975 WND *wndPtr = WIN_FindWndPtr( hwnd );
977 if( !(wndPtr->flags & WIN_MANAGED) )
979 NC_GetInsideRect( hwnd, &rect );
980 hdcMem = CreateCompatibleDC( hdc );
981 hbitmap = SelectObject( hdcMem, hbitmapClose );
982 BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE), GetSystemMetrics(SM_CYSIZE),
983 hdcMem, (wndPtr->dwStyle & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE) : 0, 0,
984 down ? NOTSRCCOPY : SRCCOPY );
985 SelectObject( hdcMem, hbitmap );
986 DeleteDC( hdcMem );
988 WIN_ReleaseWndPtr(wndPtr);
992 /***********************************************************************
993 * NC_DrawMaxButton
995 static void NC_DrawMaxButton( HWND hwnd, HDC16 hdc, BOOL down )
997 RECT rect;
998 WND *wndPtr = WIN_FindWndPtr( hwnd );
999 HDC hdcMem;
1001 if( !(wndPtr->flags & WIN_MANAGED) )
1003 NC_GetInsideRect( hwnd, &rect );
1004 hdcMem = CreateCompatibleDC( hdc );
1005 SelectObject( hdcMem, (IsZoomed(hwnd)
1006 ? (down ? hbitmapRestoreD : hbitmapRestore)
1007 : (down ? hbitmapMaximizeD : hbitmapMaximize)) );
1008 BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
1009 GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
1010 SRCCOPY );
1011 DeleteDC( hdcMem );
1013 WIN_ReleaseWndPtr(wndPtr);
1018 /***********************************************************************
1019 * NC_DrawMinButton
1021 static void NC_DrawMinButton( HWND hwnd, HDC16 hdc, BOOL down )
1023 RECT rect;
1024 WND *wndPtr = WIN_FindWndPtr( hwnd );
1025 HDC hdcMem;
1027 if( !(wndPtr->flags & WIN_MANAGED) )
1029 NC_GetInsideRect( hwnd, &rect );
1030 hdcMem = CreateCompatibleDC( hdc );
1031 SelectObject( hdcMem, (down ? hbitmapMinimizeD : hbitmapMinimize) );
1032 if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= GetSystemMetrics(SM_CXSIZE)+1;
1033 BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
1034 GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
1035 SRCCOPY );
1036 DeleteDC( hdcMem );
1038 WIN_ReleaseWndPtr(wndPtr);
1042 /******************************************************************************
1044 * void NC_DrawSysButton95(
1045 * HWND hwnd,
1046 * HDC hdc,
1047 * BOOL down )
1049 * Draws the Win95 system icon.
1051 * Revision history
1052 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1053 * Original implementation from NC_DrawSysButton source.
1054 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1055 * Fixed most bugs.
1057 *****************************************************************************/
1059 BOOL
1060 NC_DrawSysButton95 (HWND hwnd, HDC hdc, BOOL down)
1062 WND *wndPtr = WIN_FindWndPtr( hwnd );
1064 if( !(wndPtr->flags & WIN_MANAGED) )
1066 HICON hIcon;
1067 RECT rect;
1069 NC_GetInsideRect95( hwnd, &rect );
1071 hIcon = NC_IconForWindow( wndPtr );
1073 if (hIcon)
1074 DrawIconEx (hdc, rect.left + 2, rect.top + 2, hIcon,
1075 GetSystemMetrics(SM_CXSMICON),
1076 GetSystemMetrics(SM_CYSMICON),
1077 0, 0, DI_NORMAL);
1079 WIN_ReleaseWndPtr(wndPtr);
1080 return (hIcon != 0);
1082 WIN_ReleaseWndPtr(wndPtr);
1083 return FALSE;
1087 /******************************************************************************
1089 * void NC_DrawCloseButton95(
1090 * HWND hwnd,
1091 * HDC hdc,
1092 * BOOL down,
1093 * BOOL bGrayed )
1095 * Draws the Win95 close button.
1097 * If bGrayed is true, then draw a disabled Close button
1099 * Revision history
1100 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1101 * Original implementation from NC_DrawSysButton95 source.
1103 *****************************************************************************/
1105 static void NC_DrawCloseButton95 (HWND hwnd, HDC hdc, BOOL down, BOOL bGrayed)
1107 RECT rect;
1108 HDC hdcMem;
1109 WND *wndPtr = WIN_FindWndPtr( hwnd );
1111 if( !(wndPtr->flags & WIN_MANAGED) )
1113 BITMAP bmp;
1114 HBITMAP hBmp, hOldBmp;
1116 NC_GetInsideRect95( hwnd, &rect );
1118 /* A tool window has a smaller Close button */
1119 if(wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
1121 RECT toolRect;
1122 INT iBmpHeight = 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
1123 INT iBmpWidth = 11; /* it uses 11x11 for the close button in tool window */
1124 INT iCaptionHeight = GetSystemMetrics(SM_CYSMCAPTION);
1126 toolRect.top = rect.top + (iCaptionHeight - 1 - iBmpHeight) / 2;
1127 toolRect.left = rect.right - (iCaptionHeight + 1 + iBmpWidth) / 2;
1128 toolRect.bottom = toolRect.top + iBmpHeight;
1129 toolRect.right = toolRect.left + iBmpWidth;
1130 DrawFrameControl(hdc,&toolRect,
1131 DFC_CAPTION,DFCS_CAPTIONCLOSE |
1132 down ? DFCS_PUSHED : 0 |
1133 bGrayed ? DFCS_INACTIVE : 0);
1135 else
1137 hdcMem = CreateCompatibleDC( hdc );
1138 hBmp = down ? hbitmapCloseD : hbitmapClose;
1139 hOldBmp = SelectObject (hdcMem, hBmp);
1140 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1142 BitBlt (hdc, rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2,
1143 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1144 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);
1146 if(bGrayed)
1147 NC_DrawGrayButton(hdc,rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2 + 2,
1148 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1150 SelectObject (hdcMem, hOldBmp);
1151 DeleteDC (hdcMem);
1154 WIN_ReleaseWndPtr(wndPtr);
1157 /******************************************************************************
1159 * NC_DrawMaxButton95(
1160 * HWND hwnd,
1161 * HDC16 hdc,
1162 * BOOL down
1163 * BOOL bGrayed )
1165 * Draws the maximize button for Win95 style windows.
1167 * If bGrayed is true, then draw a disabled Maximize button
1169 * Bugs
1170 * Many. Spacing might still be incorrect. Need to fit a close
1171 * button between the max button and the edge.
1172 * Should scale the image with the title bar. And more...
1174 * Revision history
1175 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1176 * Original implementation.
1178 *****************************************************************************/
1180 static void NC_DrawMaxButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
1182 RECT rect;
1183 HDC hdcMem;
1184 WND *wndPtr = WIN_FindWndPtr( hwnd );
1186 if( !(wndPtr->flags & WIN_MANAGED))
1188 BITMAP bmp;
1189 HBITMAP hBmp,hOldBmp;
1191 NC_GetInsideRect95( hwnd, &rect );
1192 hdcMem = CreateCompatibleDC( hdc );
1193 hBmp = IsZoomed(hwnd) ?
1194 (down ? hbitmapRestoreD : hbitmapRestore ) :
1195 (down ? hbitmapMaximizeD: hbitmapMaximize);
1196 hOldBmp=SelectObject( hdcMem, hBmp );
1197 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1199 if (wndPtr->dwStyle & WS_SYSMENU)
1200 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1202 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1203 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1204 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1206 if(bGrayed)
1207 NC_DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
1208 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1211 SelectObject (hdcMem, hOldBmp);
1212 DeleteDC( hdcMem );
1214 WIN_ReleaseWndPtr(wndPtr);
1217 /******************************************************************************
1219 * NC_DrawMinButton95(
1220 * HWND hwnd,
1221 * HDC16 hdc,
1222 * BOOL down,
1223 * BOOL bGrayed )
1225 * Draws the minimize button for Win95 style windows.
1227 * If bGrayed is true, then draw a disabled Minimize button
1229 * Bugs
1230 * Many. Spacing is still incorrect. Should scale the image with the
1231 * title bar. And more...
1233 * Revision history
1234 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1235 * Original implementation.
1237 *****************************************************************************/
1239 static void NC_DrawMinButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
1241 RECT rect;
1242 HDC hdcMem;
1243 WND *wndPtr = WIN_FindWndPtr( hwnd );
1245 if( !(wndPtr->flags & WIN_MANAGED))
1248 BITMAP bmp;
1249 HBITMAP hBmp,hOldBmp;
1251 NC_GetInsideRect95( hwnd, &rect );
1253 hdcMem = CreateCompatibleDC( hdc );
1254 hBmp = down ? hbitmapMinimizeD : hbitmapMinimize;
1255 hOldBmp= SelectObject( hdcMem, hBmp );
1256 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1258 if (wndPtr->dwStyle & WS_SYSMENU)
1259 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1261 /* In win 95 there is always a Maximize box when there is a Minimize one */
1262 if ((wndPtr->dwStyle & WS_MAXIMIZEBOX) || (wndPtr->dwStyle & WS_MINIMIZEBOX))
1263 rect.right += -1 - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2;
1265 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1266 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1267 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1269 if(bGrayed)
1270 NC_DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
1271 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1274 SelectObject (hdcMem, hOldBmp);
1275 DeleteDC( hdcMem );
1277 WIN_ReleaseWndPtr(wndPtr);
1280 /***********************************************************************
1281 * NC_DrawFrame
1283 * Draw a window frame inside the given rectangle, and update the rectangle.
1284 * The correct pen for the frame must be selected in the DC.
1286 static void NC_DrawFrame( HDC hdc, RECT *rect, BOOL dlgFrame,
1287 BOOL active )
1289 INT width, height;
1291 if (TWEAK_WineLook != WIN31_LOOK)
1292 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
1294 if (dlgFrame)
1296 width = GetSystemMetrics(SM_CXDLGFRAME) - 1;
1297 height = GetSystemMetrics(SM_CYDLGFRAME) - 1;
1298 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1299 COLOR_INACTIVECAPTION) );
1301 else
1303 width = GetSystemMetrics(SM_CXFRAME) - 2;
1304 height = GetSystemMetrics(SM_CYFRAME) - 2;
1305 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1306 COLOR_INACTIVEBORDER) );
1309 /* Draw frame */
1310 PatBlt( hdc, rect->left, rect->top,
1311 rect->right - rect->left, height, PATCOPY );
1312 PatBlt( hdc, rect->left, rect->top,
1313 width, rect->bottom - rect->top, PATCOPY );
1314 PatBlt( hdc, rect->left, rect->bottom - 1,
1315 rect->right - rect->left, -height, PATCOPY );
1316 PatBlt( hdc, rect->right - 1, rect->top,
1317 -width, rect->bottom - rect->top, PATCOPY );
1319 if (dlgFrame)
1321 InflateRect( rect, -width, -height );
1323 else
1325 INT decYOff = GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXSIZE) - 1;
1326 INT decXOff = GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYSIZE) - 1;
1328 /* Draw inner rectangle */
1330 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1331 Rectangle( hdc, rect->left + width, rect->top + height,
1332 rect->right - width , rect->bottom - height );
1334 /* Draw the decorations */
1336 MoveToEx( hdc, rect->left, rect->top + decYOff, NULL );
1337 LineTo( hdc, rect->left + width, rect->top + decYOff );
1338 MoveToEx( hdc, rect->right - 1, rect->top + decYOff, NULL );
1339 LineTo( hdc, rect->right - width - 1, rect->top + decYOff );
1340 MoveToEx( hdc, rect->left, rect->bottom - decYOff, NULL );
1341 LineTo( hdc, rect->left + width, rect->bottom - decYOff );
1342 MoveToEx( hdc, rect->right - 1, rect->bottom - decYOff, NULL );
1343 LineTo( hdc, rect->right - width - 1, rect->bottom - decYOff );
1345 MoveToEx( hdc, rect->left + decXOff, rect->top, NULL );
1346 LineTo( hdc, rect->left + decXOff, rect->top + height);
1347 MoveToEx( hdc, rect->left + decXOff, rect->bottom - 1, NULL );
1348 LineTo( hdc, rect->left + decXOff, rect->bottom - height - 1 );
1349 MoveToEx( hdc, rect->right - decXOff, rect->top, NULL );
1350 LineTo( hdc, rect->right - decXOff, rect->top + height );
1351 MoveToEx( hdc, rect->right - decXOff, rect->bottom - 1, NULL );
1352 LineTo( hdc, rect->right - decXOff, rect->bottom - height - 1 );
1354 InflateRect( rect, -width - 1, -height - 1 );
1359 /******************************************************************************
1361 * void NC_DrawFrame95(
1362 * HDC hdc,
1363 * RECT *rect,
1364 * BOOL dlgFrame,
1365 * BOOL active )
1367 * Draw a window frame inside the given rectangle, and update the rectangle.
1368 * The correct pen for the frame must be selected in the DC.
1370 * Bugs
1371 * Many. First, just what IS a frame in Win95? Note that the 3D look
1372 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1373 * edge. The inner rectangle just inside the frame is handled by the
1374 * Caption code.
1376 * In short, for most people, this function should be a nop (unless
1377 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1378 * them lately, but just to get this code right). Even so, it doesn't
1379 * appear to be so. It's being worked on...
1381 * Revision history
1382 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1383 * Original implementation (based on NC_DrawFrame)
1384 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1385 * Some minor fixes.
1386 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1387 * Fixed a fix or something.
1389 *****************************************************************************/
1391 static void NC_DrawFrame95(
1392 HDC hdc,
1393 RECT *rect,
1394 BOOL dlgFrame,
1395 BOOL active )
1397 INT width, height;
1399 if (dlgFrame)
1401 width = GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
1402 height = GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
1404 else
1406 width = GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXEDGE);
1407 height = GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYEDGE);
1410 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1411 COLOR_INACTIVEBORDER) );
1413 /* Draw frame */
1414 PatBlt( hdc, rect->left, rect->top,
1415 rect->right - rect->left, height, PATCOPY );
1416 PatBlt( hdc, rect->left, rect->top,
1417 width, rect->bottom - rect->top, PATCOPY );
1418 PatBlt( hdc, rect->left, rect->bottom - 1,
1419 rect->right - rect->left, -height, PATCOPY );
1420 PatBlt( hdc, rect->right - 1, rect->top,
1421 -width, rect->bottom - rect->top, PATCOPY );
1423 InflateRect( rect, -width, -height );
1426 /***********************************************************************
1427 * NC_DrawMovingFrame
1429 * Draw the frame used when moving or resizing window.
1431 * FIXME: This causes problems in Win95 mode. (why?)
1433 static void NC_DrawMovingFrame( HDC hdc, RECT *rect, BOOL thickframe )
1435 if (thickframe)
1437 RECT16 r16;
1438 CONV_RECT32TO16( rect, &r16 );
1439 FastWindowFrame16( hdc, &r16, GetSystemMetrics(SM_CXFRAME),
1440 GetSystemMetrics(SM_CYFRAME), PATINVERT );
1442 else DrawFocusRect( hdc, rect );
1446 /***********************************************************************
1447 * NC_DrawCaption
1449 * Draw the window caption.
1450 * The correct pen for the window frame must be selected in the DC.
1452 static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd,
1453 DWORD style, BOOL active )
1455 RECT r = *rect;
1456 WND * wndPtr = WIN_FindWndPtr( hwnd );
1457 char buffer[256];
1459 if (wndPtr->flags & WIN_MANAGED)
1461 WIN_ReleaseWndPtr(wndPtr);
1462 return;
1465 if (!hbitmapClose)
1467 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1469 WIN_ReleaseWndPtr(wndPtr);
1470 return;
1472 hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED) );
1473 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1474 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1475 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1476 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1477 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1478 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1481 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
1483 HBRUSH hbrushOld = SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW) );
1484 PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
1485 PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
1486 PatBlt( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
1487 r.left++;
1488 r.right--;
1489 SelectObject( hdc, hbrushOld );
1491 WIN_ReleaseWndPtr(wndPtr);
1492 MoveToEx( hdc, r.left, r.bottom, NULL );
1493 LineTo( hdc, r.right, r.bottom );
1495 if (style & WS_SYSMENU)
1497 NC_DrawSysButton( hwnd, hdc, FALSE );
1498 r.left += GetSystemMetrics(SM_CXSIZE) + 1;
1499 MoveToEx( hdc, r.left - 1, r.top, NULL );
1500 LineTo( hdc, r.left - 1, r.bottom );
1502 if (style & WS_MAXIMIZEBOX)
1504 NC_DrawMaxButton( hwnd, hdc, FALSE );
1505 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1507 if (style & WS_MINIMIZEBOX)
1509 NC_DrawMinButton( hwnd, hdc, FALSE );
1510 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1513 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1514 COLOR_INACTIVECAPTION) );
1516 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) ))
1518 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1519 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1520 SetBkMode( hdc, TRANSPARENT );
1521 DrawTextA( hdc, buffer, -1, &r,
1522 DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );
1527 /******************************************************************************
1529 * NC_DrawCaption95(
1530 * HDC hdc,
1531 * RECT *rect,
1532 * HWND hwnd,
1533 * DWORD style,
1534 * BOOL active )
1536 * Draw the window caption for Win95 style windows.
1537 * The correct pen for the window frame must be selected in the DC.
1539 * Bugs
1540 * Hey, a function that finally works! Well, almost.
1541 * It's being worked on.
1543 * Revision history
1544 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1545 * Original implementation.
1546 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1547 * Some minor fixes.
1549 *****************************************************************************/
1551 static void NC_DrawCaption95(
1552 HDC hdc,
1553 RECT *rect,
1554 HWND hwnd,
1555 DWORD style,
1556 DWORD exStyle,
1557 BOOL active )
1559 RECT r = *rect;
1560 WND *wndPtr = WIN_FindWndPtr( hwnd );
1561 char buffer[256];
1562 HPEN hPrevPen;
1563 HMENU hSysMenu;
1565 if (wndPtr->flags & WIN_MANAGED)
1567 WIN_ReleaseWndPtr(wndPtr);
1568 return;
1570 WIN_ReleaseWndPtr(wndPtr);
1572 hPrevPen = SelectObject( hdc, GetSysColorPen(COLOR_3DFACE) );
1573 MoveToEx( hdc, r.left, r.bottom - 1, NULL );
1574 LineTo( hdc, r.right, r.bottom - 1 );
1575 SelectObject( hdc, hPrevPen );
1576 r.bottom--;
1578 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1579 COLOR_INACTIVECAPTION) );
1581 if (!hbitmapClose) {
1582 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1583 return;
1584 hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED));
1585 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1586 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1587 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1588 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1589 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1590 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1593 if ((style & WS_SYSMENU) && !(exStyle & WS_EX_TOOLWINDOW)) {
1594 if (NC_DrawSysButton95 (hwnd, hdc, FALSE))
1595 r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
1598 if (style & WS_SYSMENU)
1600 UINT state;
1602 /* Go get the sysmenu */
1603 hSysMenu = GetSystemMenu(hwnd, FALSE);
1604 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
1606 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1607 NC_DrawCloseButton95 (hwnd, hdc, FALSE,
1608 ((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
1609 r.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
1611 if ((style & WS_MAXIMIZEBOX) || (style & WS_MINIMIZEBOX))
1613 /* In win95 the two buttons are always there */
1614 /* But if the menu item is not in the menu they're disabled*/
1616 NC_DrawMaxButton95( hwnd, hdc, FALSE, (!(style & WS_MAXIMIZEBOX)));
1617 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1619 NC_DrawMinButton95( hwnd, hdc, FALSE, (!(style & WS_MINIMIZEBOX)));
1620 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1624 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) )) {
1625 NONCLIENTMETRICSA nclm;
1626 HFONT hFont, hOldFont;
1627 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1628 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1629 if (exStyle & WS_EX_TOOLWINDOW)
1630 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
1631 else
1632 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
1633 hOldFont = SelectObject (hdc, hFont);
1634 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1635 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1636 SetBkMode( hdc, TRANSPARENT );
1637 r.left += 2;
1638 DrawTextA( hdc, buffer, -1, &r,
1639 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
1640 DeleteObject (SelectObject (hdc, hOldFont));
1646 /***********************************************************************
1647 * NC_DoNCPaint
1649 * Paint the non-client area. clip is currently unused.
1651 static void NC_DoNCPaint( WND* wndPtr, HRGN clip, BOOL suppress_menupaint )
1653 HDC hdc;
1654 RECT rect;
1655 BOOL active;
1656 HWND hwnd = wndPtr->hwndSelf;
1658 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1659 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1661 active = wndPtr->flags & WIN_NCACTIVATED;
1663 TRACE("%04x %d\n", hwnd, active );
1665 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1666 ((clip > 1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN): 0) ))) return;
1668 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1669 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1670 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1671 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1672 == NULLREGION)
1674 ReleaseDC( hwnd, hdc );
1675 return;
1678 rect.top = rect.left = 0;
1679 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1680 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1682 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1684 if (!(wndPtr->flags & WIN_MANAGED))
1686 if (HAS_ANYFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1688 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1689 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1690 InflateRect( &rect, -1, -1 );
1693 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1694 NC_DrawFrame(hdc, &rect, FALSE, active );
1695 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1696 NC_DrawFrame( hdc, &rect, TRUE, active );
1698 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1700 RECT r = rect;
1701 r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
1702 rect.top += GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYBORDER);
1703 NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active );
1707 if (HAS_MENU(wndPtr))
1709 RECT r = rect;
1710 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU); /* default height */
1711 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint );
1714 /* Draw the scroll-bars */
1716 if (wndPtr->dwStyle & WS_VSCROLL)
1717 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1718 if (wndPtr->dwStyle & WS_HSCROLL)
1719 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1721 /* Draw the "size-box" */
1723 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1725 RECT r = rect;
1726 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1727 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1728 if(wndPtr->dwStyle & WS_BORDER) {
1729 r.left++;
1730 r.top++;
1732 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1735 ReleaseDC( hwnd, hdc );
1739 /******************************************************************************
1741 * void NC_DoNCPaint95(
1742 * WND *wndPtr,
1743 * HRGN clip,
1744 * BOOL suppress_menupaint )
1746 * Paint the non-client area for Win95 windows. The clip region is
1747 * currently ignored.
1749 * Bugs
1750 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1751 * misc/tweak.c controls/menu.c # :-)
1753 * Revision history
1754 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1755 * Original implementation
1756 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1757 * Fixed some bugs.
1758 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1759 * Streamlined window style checks.
1761 *****************************************************************************/
1763 static void NC_DoNCPaint95(
1764 WND *wndPtr,
1765 HRGN clip,
1766 BOOL suppress_menupaint )
1768 HDC hdc;
1769 RECT rfuzz, rect, rectClip;
1770 BOOL active;
1771 HWND hwnd = wndPtr->hwndSelf;
1773 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1774 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1776 active = wndPtr->flags & WIN_NCACTIVATED;
1778 TRACE("%04x %d\n", hwnd, active );
1780 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1781 the call to GetDCEx implying that it is allowed not to use it either.
1782 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1783 will cause clipRgn to be deleted after ReleaseDC().
1784 Now, how is the "system" supposed to tell what happened?
1787 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1788 ((clip > 1) ?(DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0) ))) return;
1791 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1792 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1793 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1794 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1795 == NULLREGION)
1797 ReleaseDC( hwnd, hdc );
1798 return;
1801 rect.top = rect.left = 0;
1802 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1803 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1805 if( clip > 1 )
1806 GetRgnBox( clip, &rectClip );
1807 else
1809 clip = 0;
1810 rectClip = rect;
1813 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1815 if(!(wndPtr->flags & WIN_MANAGED)) {
1816 if (HAS_BIGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle)) {
1817 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1819 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1820 NC_DrawFrame95(hdc, &rect, FALSE, active );
1821 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1822 NC_DrawFrame95( hdc, &rect, TRUE, active );
1823 else if (HAS_THINFRAME( wndPtr->dwStyle )) {
1824 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1825 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1828 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1830 RECT r = rect;
1831 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW) {
1832 r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
1833 rect.top += GetSystemMetrics(SM_CYSMCAPTION);
1835 else {
1836 r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
1837 rect.top += GetSystemMetrics(SM_CYCAPTION);
1839 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
1840 NC_DrawCaption95 (hdc, &r, hwnd, wndPtr->dwStyle,
1841 wndPtr->dwExStyle, active);
1845 if (HAS_MENU(wndPtr))
1847 RECT r = rect;
1848 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
1850 TRACE("Calling DrawMenuBar with rect (%d, %d)-(%d, %d)\n",
1851 r.left, r.top, r.right, r.bottom);
1853 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ) + 1;
1856 TRACE("After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1857 rect.left, rect.top, rect.right, rect.bottom );
1859 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
1860 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1862 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
1863 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1865 /* Draw the scroll-bars */
1867 if (wndPtr->dwStyle & WS_VSCROLL)
1868 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1869 if (wndPtr->dwStyle & WS_HSCROLL)
1870 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1872 /* Draw the "size-box" */
1873 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1875 RECT r = rect;
1876 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1877 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1878 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1881 ReleaseDC( hwnd, hdc );
1887 /***********************************************************************
1888 * NC_HandleNCPaint
1890 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1892 LONG NC_HandleNCPaint( HWND hwnd , HRGN clip)
1894 WND* wndPtr = WIN_FindWndPtr( hwnd );
1896 if( wndPtr && wndPtr->dwStyle & WS_VISIBLE )
1898 if( wndPtr->dwStyle & WS_MINIMIZE )
1899 WINPOS_RedrawIconTitle( hwnd );
1900 else if (TWEAK_WineLook == WIN31_LOOK)
1901 NC_DoNCPaint( wndPtr, clip, FALSE );
1902 else
1903 NC_DoNCPaint95( wndPtr, clip, FALSE );
1905 WIN_ReleaseWndPtr(wndPtr);
1906 return 0;
1910 /***********************************************************************
1911 * NC_HandleNCActivate
1913 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1915 LONG NC_HandleNCActivate( WND *wndPtr, WPARAM16 wParam )
1917 WORD wStateChange;
1919 if( wParam ) wStateChange = !(wndPtr->flags & WIN_NCACTIVATED);
1920 else wStateChange = wndPtr->flags & WIN_NCACTIVATED;
1922 if( wStateChange )
1924 if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
1925 else wndPtr->flags &= ~WIN_NCACTIVATED;
1927 if( wndPtr->dwStyle & WS_MINIMIZE )
1928 WINPOS_RedrawIconTitle( wndPtr->hwndSelf );
1929 else if (TWEAK_WineLook == WIN31_LOOK)
1930 NC_DoNCPaint( wndPtr, (HRGN)1, FALSE );
1931 else
1932 NC_DoNCPaint95( wndPtr, (HRGN)1, FALSE );
1934 return TRUE;
1938 /***********************************************************************
1939 * NC_HandleSetCursor
1941 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1943 LONG NC_HandleSetCursor( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
1945 if (hwnd != (HWND)wParam) return 0; /* Don't set the cursor for child windows */
1947 switch(LOWORD(lParam))
1949 case HTERROR:
1951 WORD msg = HIWORD( lParam );
1952 if ((msg == WM_LBUTTONDOWN) || (msg == WM_MBUTTONDOWN) ||
1953 (msg == WM_RBUTTONDOWN))
1954 MessageBeep(0);
1956 break;
1958 case HTCLIENT:
1960 HICON16 hCursor = (HICON16) GetClassWord(hwnd, GCW_HCURSOR);
1961 if(hCursor) {
1962 SetCursor16(hCursor);
1963 return TRUE;
1965 return FALSE;
1968 case HTLEFT:
1969 case HTRIGHT:
1970 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZEWE16 ) );
1972 case HTTOP:
1973 case HTBOTTOM:
1974 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENS16 ) );
1976 case HTTOPLEFT:
1977 case HTBOTTOMRIGHT:
1978 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENWSE16 ) );
1980 case HTTOPRIGHT:
1981 case HTBOTTOMLEFT:
1982 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENESW16 ) );
1985 /* Default cursor: arrow */
1986 return (LONG)SetCursor16( LoadCursor16( 0, IDC_ARROW16 ) );
1989 /***********************************************************************
1990 * NC_GetSysPopupPos
1992 BOOL NC_GetSysPopupPos( WND* wndPtr, RECT* rect )
1994 if( wndPtr->hSysMenu )
1996 if( wndPtr->dwStyle & WS_MINIMIZE )
1997 GetWindowRect( wndPtr->hwndSelf, rect );
1998 else
2000 if (TWEAK_WineLook == WIN31_LOOK)
2001 NC_GetInsideRect( wndPtr->hwndSelf, rect );
2002 else
2003 NC_GetInsideRect95( wndPtr->hwndSelf, rect );
2004 OffsetRect( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
2005 if (wndPtr->dwStyle & WS_CHILD)
2006 ClientToScreen( wndPtr->parent->hwndSelf, (POINT *)rect );
2007 if (TWEAK_WineLook == WIN31_LOOK) {
2008 rect->right = rect->left + GetSystemMetrics(SM_CXSIZE);
2009 rect->bottom = rect->top + GetSystemMetrics(SM_CYSIZE);
2011 else {
2012 rect->right = rect->left + GetSystemMetrics(SM_CYCAPTION) - 1;
2013 rect->bottom = rect->top + GetSystemMetrics(SM_CYCAPTION) - 1;
2016 return TRUE;
2018 return FALSE;
2021 /***********************************************************************
2022 * NC_StartSizeMove
2024 * Initialisation of a move or resize, when initiatied from a menu choice.
2025 * Return hit test code for caption or sizing border.
2027 static LONG NC_StartSizeMove( WND* wndPtr, WPARAM16 wParam,
2028 POINT16 *capturePoint )
2030 LONG hittest = 0;
2031 POINT16 pt;
2032 MSG msg;
2033 RECT rectWindow;
2035 GetWindowRect(wndPtr->hwndSelf,&rectWindow);
2037 if ((wParam & 0xfff0) == SC_MOVE)
2039 /* Move pointer at the center of the caption */
2040 RECT rect;
2041 if (TWEAK_WineLook == WIN31_LOOK)
2042 NC_GetInsideRect( wndPtr->hwndSelf, &rect );
2043 else
2044 NC_GetInsideRect95( wndPtr->hwndSelf, &rect );
2045 if (wndPtr->dwStyle & WS_SYSMENU)
2046 rect.left += GetSystemMetrics(SM_CXSIZE) + 1;
2047 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
2048 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
2049 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
2050 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
2051 pt.x = rectWindow.left + (rect.right - rect.left) / 2;
2052 pt.y = rectWindow.top + rect.top + GetSystemMetrics(SM_CYSIZE)/2;
2053 hittest = HTCAPTION;
2054 *capturePoint = pt;
2056 else /* SC_SIZE */
2058 while(!hittest)
2060 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE, NULL );
2061 switch(msg.message)
2063 case WM_MOUSEMOVE:
2064 CONV_POINT32TO16(&msg.pt, &pt);
2065 hittest = NC_HandleNCHitTest( wndPtr->hwndSelf, pt );
2066 if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
2067 hittest = 0;
2068 break;
2070 case WM_LBUTTONUP:
2071 return 0;
2073 case WM_KEYDOWN:
2074 switch(msg.wParam)
2076 case VK_UP:
2077 hittest = HTTOP;
2078 pt.x =(rectWindow.left+rectWindow.right)/2;
2079 pt.y = rectWindow.top + GetSystemMetrics(SM_CYFRAME) / 2;
2080 break;
2081 case VK_DOWN:
2082 hittest = HTBOTTOM;
2083 pt.x =(rectWindow.left+rectWindow.right)/2;
2084 pt.y = rectWindow.bottom - GetSystemMetrics(SM_CYFRAME) / 2;
2085 break;
2086 case VK_LEFT:
2087 hittest = HTLEFT;
2088 pt.x = rectWindow.left + GetSystemMetrics(SM_CXFRAME) / 2;
2089 pt.y =(rectWindow.top+rectWindow.bottom)/2;
2090 break;
2091 case VK_RIGHT:
2092 hittest = HTRIGHT;
2093 pt.x = rectWindow.right - GetSystemMetrics(SM_CXFRAME) / 2;
2094 pt.y =(rectWindow.top+rectWindow.bottom)/2;
2095 break;
2096 case VK_RETURN:
2097 case VK_ESCAPE: return 0;
2101 *capturePoint = pt;
2103 SetCursorPos( pt.x, pt.y );
2104 NC_HandleSetCursor( wndPtr->hwndSelf,
2105 wndPtr->hwndSelf, MAKELONG( hittest, WM_MOUSEMOVE ));
2106 return hittest;
2110 /***********************************************************************
2111 * NC_DoSizeMove
2113 * Perform SC_MOVE and SC_SIZE commands. `
2115 static void NC_DoSizeMove( HWND hwnd, WORD wParam )
2117 MSG msg;
2118 RECT sizingRect, mouseRect, origRect;
2119 HDC hdc;
2120 LONG hittest = (LONG)(wParam & 0x0f);
2121 HCURSOR16 hDragCursor = 0, hOldCursor = 0;
2122 POINT minTrack, maxTrack;
2123 POINT16 capturePoint, pt;
2124 WND * wndPtr = WIN_FindWndPtr( hwnd );
2125 BOOL thickframe = HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle );
2126 BOOL iconic = wndPtr->dwStyle & WS_MINIMIZE;
2127 BOOL moved = FALSE;
2128 DWORD dwPoint = GetMessagePos ();
2129 BOOL DragFullWindows = FALSE;
2130 int iWndsLocks;
2132 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS, 0, &DragFullWindows, 0);
2134 capturePoint = pt = *(POINT16*)&dwPoint;
2136 if (IsZoomed(hwnd) || !IsWindowVisible(hwnd) ||
2137 (wndPtr->flags & WIN_MANAGED)) goto END;
2139 if ((wParam & 0xfff0) == SC_MOVE)
2141 if (!hittest)
2142 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2143 if (!hittest) goto END;
2145 else /* SC_SIZE */
2147 if (!thickframe) goto END;
2148 if ( hittest && hittest != HTSYSMENU ) hittest += 2;
2149 else
2151 SetCapture(hwnd);
2152 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2153 if (!hittest)
2155 ReleaseCapture();
2156 goto END;
2161 /* Get min/max info */
2163 WINPOS_GetMinMaxInfo( wndPtr, NULL, NULL, &minTrack, &maxTrack );
2164 sizingRect = wndPtr->rectWindow;
2165 origRect = sizingRect;
2166 if (wndPtr->dwStyle & WS_CHILD)
2167 GetClientRect( wndPtr->parent->hwndSelf, &mouseRect );
2168 else
2169 SetRect(&mouseRect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
2170 if (ON_LEFT_BORDER(hittest))
2172 mouseRect.left = max( mouseRect.left, sizingRect.right-maxTrack.x );
2173 mouseRect.right = min( mouseRect.right, sizingRect.right-minTrack.x );
2175 else if (ON_RIGHT_BORDER(hittest))
2177 mouseRect.left = max( mouseRect.left, sizingRect.left+minTrack.x );
2178 mouseRect.right = min( mouseRect.right, sizingRect.left+maxTrack.x );
2180 if (ON_TOP_BORDER(hittest))
2182 mouseRect.top = max( mouseRect.top, sizingRect.bottom-maxTrack.y );
2183 mouseRect.bottom = min( mouseRect.bottom,sizingRect.bottom-minTrack.y);
2185 else if (ON_BOTTOM_BORDER(hittest))
2187 mouseRect.top = max( mouseRect.top, sizingRect.top+minTrack.y );
2188 mouseRect.bottom = min( mouseRect.bottom, sizingRect.top+maxTrack.y );
2190 if (wndPtr->dwStyle & WS_CHILD)
2192 MapWindowPoints( wndPtr->parent->hwndSelf, 0,
2193 (LPPOINT)&mouseRect, 2 );
2195 SendMessage16( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
2197 if (GetCapture() != hwnd) SetCapture( hwnd );
2199 if (wndPtr->dwStyle & WS_CHILD)
2201 /* Retrieve a default cache DC (without using the window style) */
2202 hdc = GetDCEx( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
2204 else
2205 { /* Grab the server only when moving top-level windows without desktop */
2206 hdc = GetDC( 0 );
2209 wndPtr->pDriver->pPreSizeMove(wndPtr);
2211 if( iconic ) /* create a cursor for dragging */
2213 HICON16 hIcon = GetClassWord(wndPtr->hwndSelf, GCW_HICON);
2214 if(!hIcon) hIcon = (HICON16) SendMessage16( hwnd, WM_QUERYDRAGICON, 0, 0L);
2215 if( hIcon ) hDragCursor = CURSORICON_IconToCursor( hIcon, TRUE );
2216 if( !hDragCursor ) iconic = FALSE;
2219 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
2220 if( !iconic && TWEAK_WineLook == WIN31_LOOK )
2221 if(!DragFullWindows)
2222 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2224 while(1)
2226 int dx = 0, dy = 0;
2228 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE, NULL );
2230 /* Exit on button-up, Return, or Esc */
2231 if ((msg.message == WM_LBUTTONUP) ||
2232 ((msg.message == WM_KEYDOWN) &&
2233 ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
2235 if (msg.message == WM_PAINT)
2237 if(!iconic && !DragFullWindows) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2238 UpdateWindow( msg.hwnd );
2239 if(!iconic && !DragFullWindows) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2240 continue;
2243 if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
2244 continue; /* We are not interested in other messages */
2246 CONV_POINT32TO16(&msg.pt, &pt);
2248 if (msg.message == WM_KEYDOWN) switch(msg.wParam)
2250 case VK_UP: pt.y -= 8; break;
2251 case VK_DOWN: pt.y += 8; break;
2252 case VK_LEFT: pt.x -= 8; break;
2253 case VK_RIGHT: pt.x += 8; break;
2256 pt.x = max( pt.x, mouseRect.left );
2257 pt.x = min( pt.x, mouseRect.right );
2258 pt.y = max( pt.y, mouseRect.top );
2259 pt.y = min( pt.y, mouseRect.bottom );
2261 dx = pt.x - capturePoint.x;
2262 dy = pt.y - capturePoint.y;
2264 if (dx || dy)
2266 if( !moved )
2268 moved = TRUE;
2270 if( iconic ) /* ok, no system popup tracking */
2272 hOldCursor = SetCursor(hDragCursor);
2273 ShowCursor( TRUE );
2274 WINPOS_ShowIconTitle( wndPtr, FALSE );
2275 } else if(TWEAK_WineLook != WIN31_LOOK)
2277 if(!DragFullWindows)
2278 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2282 if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
2283 else
2285 RECT newRect = sizingRect;
2286 WPARAM wpSizingHit = 0;
2288 if (hittest == HTCAPTION) OffsetRect( &newRect, dx, dy );
2289 if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
2290 else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
2291 if (ON_TOP_BORDER(hittest)) newRect.top += dy;
2292 else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
2293 if(!iconic && !DragFullWindows) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2294 capturePoint = pt;
2296 /* determine the hit location */
2297 if (hittest >= HTLEFT && hittest <= HTBOTTOMRIGHT)
2298 wpSizingHit = WMSZ_LEFT + (hittest - HTLEFT);
2299 SendMessageA( hwnd, WM_SIZING, wpSizingHit, (LPARAM)&newRect );
2301 if (!iconic)
2303 if(!DragFullWindows)
2304 NC_DrawMovingFrame( hdc, &newRect, thickframe );
2305 else {
2306 /* To avoid any deadlocks, all the locks on the windows
2307 structures must be suspended before the SetWindowPos */
2308 iWndsLocks = WIN_SuspendWndsLock();
2309 SetWindowPos( hwnd, 0, newRect.left, newRect.top,
2310 newRect.right - newRect.left,
2311 newRect.bottom - newRect.top,
2312 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
2313 WIN_RestoreWndsLock(iWndsLocks);
2316 sizingRect = newRect;
2321 ReleaseCapture();
2322 if( iconic )
2324 if( moved ) /* restore cursors, show icon title later on */
2326 ShowCursor( FALSE );
2327 SetCursor( hOldCursor );
2329 DestroyCursor( hDragCursor );
2331 else if(moved || TWEAK_WineLook == WIN31_LOOK)
2332 if(!DragFullWindows)
2333 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2335 if (wndPtr->dwStyle & WS_CHILD)
2336 ReleaseDC( wndPtr->parent->hwndSelf, hdc );
2337 else
2338 ReleaseDC( 0, hdc );
2340 wndPtr->pDriver->pPostSizeMove(wndPtr);
2342 if (HOOK_IsHooked( WH_CBT ))
2344 RECT16* pr = SEGPTR_NEW(RECT16);
2345 if( pr )
2347 CONV_RECT32TO16( &sizingRect, pr );
2348 if( HOOK_CallHooks16( WH_CBT, HCBT_MOVESIZE, hwnd,
2349 (LPARAM)SEGPTR_GET(pr)) )
2350 sizingRect = wndPtr->rectWindow;
2351 else
2352 CONV_RECT16TO32( pr, &sizingRect );
2353 SEGPTR_FREE(pr);
2356 SendMessage16( hwnd, WM_EXITSIZEMOVE, 0, 0 );
2357 SendMessage16( hwnd, WM_SETVISIBLE, !IsIconic16(hwnd), 0L);
2359 /* window moved or resized */
2360 if (moved)
2362 /* To avoid any deadlocks, all the locks on the windows
2363 structures must be suspended before the SetWindowPos */
2364 iWndsLocks = WIN_SuspendWndsLock();
2366 /* if the moving/resizing isn't canceled call SetWindowPos
2367 * with the new position or the new size of the window
2369 if (!((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
2371 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
2372 if(!DragFullWindows)
2373 SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top,
2374 sizingRect.right - sizingRect.left,
2375 sizingRect.bottom - sizingRect.top,
2376 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
2378 else { /* restore previous size/position */
2379 if(DragFullWindows)
2380 SetWindowPos( hwnd, 0, origRect.left, origRect.top,
2381 origRect.right - origRect.left,
2382 origRect.bottom - origRect.top,
2383 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
2386 WIN_RestoreWndsLock(iWndsLocks);
2389 if( IsWindow(hwnd) )
2390 if( wndPtr->dwStyle & WS_MINIMIZE )
2392 /* Single click brings up the system menu when iconized */
2394 if( !moved )
2396 if( wndPtr->dwStyle & WS_SYSMENU )
2397 SendMessage16( hwnd, WM_SYSCOMMAND,
2398 SC_MOUSEMENU + HTSYSMENU, *((LPARAM*)&pt));
2400 else WINPOS_ShowIconTitle( wndPtr, TRUE );
2403 END:
2404 WIN_ReleaseWndPtr(wndPtr);
2408 /***********************************************************************
2409 * NC_TrackMinMaxBox95
2411 * Track a mouse button press on the minimize or maximize box.
2413 * The big difference between 3.1 and 95 is the disabled button state.
2414 * In win95 the system button can be disabled, so it can ignore the mouse
2415 * event.
2418 static void NC_TrackMinMaxBox95( HWND hwnd, WORD wParam )
2420 MSG msg;
2421 POINT16 pt16;
2422 HDC hdc = GetWindowDC( hwnd );
2423 BOOL pressed = TRUE;
2424 UINT state;
2425 DWORD wndStyle = GetWindowLongA( hwnd, GWL_STYLE);
2426 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
2428 void (*paintButton)(HWND, HDC16, BOOL, BOOL);
2430 if (wParam == HTMINBUTTON)
2432 /* If the style is not present, do nothing */
2433 if (!(wndStyle & WS_MINIMIZEBOX))
2434 return;
2436 /* Check if the sysmenu item for minimize is there */
2437 state = GetMenuState(hSysMenu, SC_MINIMIZE, MF_BYCOMMAND);
2439 paintButton = &NC_DrawMinButton95;
2441 else
2443 /* If the style is not present, do nothing */
2444 if (!(wndStyle & WS_MAXIMIZEBOX))
2445 return;
2447 /* Check if the sysmenu item for maximize is there */
2448 state = GetMenuState(hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
2450 paintButton = &NC_DrawMaxButton95;
2453 SetCapture( hwnd );
2455 (*paintButton)( hwnd, hdc, TRUE, FALSE);
2459 BOOL oldstate = pressed;
2460 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2461 CONV_POINT32TO16( &msg.pt, &pt16 );
2463 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2464 if (pressed != oldstate)
2465 (*paintButton)( hwnd, hdc, pressed, FALSE);
2466 } while (msg.message != WM_LBUTTONUP);
2468 (*paintButton)( hwnd, hdc, FALSE, FALSE);
2470 ReleaseCapture();
2471 ReleaseDC( hwnd, hdc );
2473 /* If the item minimize or maximize of the sysmenu are not there */
2474 /* or if the style is not present, do nothing */
2475 if ((!pressed) || (state == 0xFFFFFFFF))
2476 return;
2478 if (wParam == HTMINBUTTON)
2479 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&pt16 );
2480 else
2481 SendMessage16( hwnd, WM_SYSCOMMAND,
2482 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, *(LONG*)&pt16 );
2485 /***********************************************************************
2486 * NC_TrackMinMaxBox
2488 * Track a mouse button press on the minimize or maximize box.
2490 static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
2492 MSG msg;
2493 POINT16 pt16;
2494 HDC hdc = GetWindowDC( hwnd );
2495 BOOL pressed = TRUE;
2496 void (*paintButton)(HWND, HDC16, BOOL);
2498 SetCapture( hwnd );
2500 if (wParam == HTMINBUTTON)
2501 paintButton = &NC_DrawMinButton;
2502 else
2503 paintButton = &NC_DrawMaxButton;
2505 (*paintButton)( hwnd, hdc, TRUE);
2509 BOOL oldstate = pressed;
2510 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2511 CONV_POINT32TO16( &msg.pt, &pt16 );
2513 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2514 if (pressed != oldstate)
2515 (*paintButton)( hwnd, hdc, pressed);
2516 } while (msg.message != WM_LBUTTONUP);
2518 (*paintButton)( hwnd, hdc, FALSE);
2520 ReleaseCapture();
2521 ReleaseDC( hwnd, hdc );
2523 if (!pressed) return;
2525 if (wParam == HTMINBUTTON)
2526 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&pt16 );
2527 else
2528 SendMessage16( hwnd, WM_SYSCOMMAND,
2529 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, *(LONG*)&pt16 );
2533 /***********************************************************************
2534 * NC_TrackCloseButton95
2536 * Track a mouse button press on the Win95 close button.
2538 static void
2539 NC_TrackCloseButton95 (HWND hwnd, WORD wParam)
2541 MSG msg;
2542 POINT16 pt16;
2543 HDC hdc;
2544 BOOL pressed = TRUE;
2545 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
2546 UINT state;
2548 if(hSysMenu == 0)
2549 return;
2551 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
2553 /* If the item close of the sysmenu is disabled or not there do nothing */
2554 if((state & MF_DISABLED) || (state & MF_GRAYED) || (state == 0xFFFFFFFF))
2555 return;
2557 hdc = GetWindowDC( hwnd );
2559 SetCapture( hwnd );
2561 NC_DrawCloseButton95 (hwnd, hdc, TRUE, FALSE);
2565 BOOL oldstate = pressed;
2566 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2567 CONV_POINT32TO16( &msg.pt, &pt16 );
2569 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2570 if (pressed != oldstate)
2571 NC_DrawCloseButton95 (hwnd, hdc, pressed, FALSE);
2572 } while (msg.message != WM_LBUTTONUP);
2574 NC_DrawCloseButton95 (hwnd, hdc, FALSE, FALSE);
2576 ReleaseCapture();
2577 ReleaseDC( hwnd, hdc );
2578 if (!pressed) return;
2580 SendMessage16( hwnd, WM_SYSCOMMAND, SC_CLOSE, *(LONG*)&pt16 );
2584 /***********************************************************************
2585 * NC_TrackScrollBar
2587 * Track a mouse button press on the horizontal or vertical scroll-bar.
2589 static void NC_TrackScrollBar( HWND hwnd, WPARAM wParam, POINT pt )
2591 MSG16 *msg;
2592 INT scrollbar;
2593 WND *wndPtr = WIN_FindWndPtr( hwnd );
2595 if ((wParam & 0xfff0) == SC_HSCROLL)
2597 if ((wParam & 0x0f) != HTHSCROLL) goto END;
2598 scrollbar = SB_HORZ;
2600 else /* SC_VSCROLL */
2602 if ((wParam & 0x0f) != HTVSCROLL) goto END;
2603 scrollbar = SB_VERT;
2606 if (!(msg = SEGPTR_NEW(MSG16))) goto END;
2607 pt.x -= wndPtr->rectWindow.left;
2608 pt.y -= wndPtr->rectWindow.top;
2609 SetCapture( hwnd );
2610 SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt );
2614 GetMessage16( SEGPTR_GET(msg), 0, 0, 0 );
2615 switch(msg->message)
2617 case WM_LBUTTONUP:
2618 case WM_MOUSEMOVE:
2619 case WM_SYSTIMER:
2620 pt.x = LOWORD(msg->lParam) + wndPtr->rectClient.left -
2621 wndPtr->rectWindow.left;
2622 pt.y = HIWORD(msg->lParam) + wndPtr->rectClient.top -
2623 wndPtr->rectWindow.top;
2624 SCROLL_HandleScrollEvent( hwnd, scrollbar, msg->message, pt );
2625 break;
2626 default:
2627 TranslateMessage16( msg );
2628 DispatchMessage16( msg );
2629 break;
2631 if (!IsWindow( hwnd ))
2633 ReleaseCapture();
2634 break;
2636 } while (msg->message != WM_LBUTTONUP);
2637 SEGPTR_FREE(msg);
2638 END:
2639 WIN_ReleaseWndPtr(wndPtr);
2642 /***********************************************************************
2643 * NC_HandleNCLButtonDown
2645 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2647 LONG NC_HandleNCLButtonDown( WND* pWnd, WPARAM16 wParam, LPARAM lParam )
2649 HWND hwnd = pWnd->hwndSelf;
2651 switch(wParam) /* Hit test */
2653 case HTCAPTION:
2654 hwnd = WIN_GetTopParent(hwnd);
2656 if( WINPOS_SetActiveWindow(hwnd, TRUE, TRUE) || (GetActiveWindow() == hwnd) )
2657 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
2658 break;
2660 case HTSYSMENU:
2661 if( pWnd->dwStyle & WS_SYSMENU )
2663 if( !(pWnd->dwStyle & WS_MINIMIZE) )
2665 HDC hDC = GetWindowDC(hwnd);
2666 if (TWEAK_WineLook == WIN31_LOOK)
2667 NC_DrawSysButton( hwnd, hDC, TRUE );
2668 else
2669 NC_DrawSysButton95( hwnd, hDC, TRUE );
2670 ReleaseDC( hwnd, hDC );
2672 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
2674 break;
2676 case HTMENU:
2677 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam );
2678 break;
2680 case HTHSCROLL:
2681 SendMessage16( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
2682 break;
2684 case HTVSCROLL:
2685 SendMessage16( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
2686 break;
2688 case HTMINBUTTON:
2689 case HTMAXBUTTON:
2690 if (TWEAK_WineLook == WIN31_LOOK)
2691 NC_TrackMinMaxBox( hwnd, wParam );
2692 else
2693 NC_TrackMinMaxBox95( hwnd, wParam );
2694 break;
2696 case HTCLOSE:
2697 if (TWEAK_WineLook >= WIN95_LOOK)
2698 NC_TrackCloseButton95 (hwnd, wParam);
2699 break;
2701 case HTLEFT:
2702 case HTRIGHT:
2703 case HTTOP:
2704 case HTTOPLEFT:
2705 case HTTOPRIGHT:
2706 case HTBOTTOM:
2707 case HTBOTTOMLEFT:
2708 case HTBOTTOMRIGHT:
2709 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2710 SendMessage16( hwnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam);
2711 break;
2713 case HTBORDER:
2714 break;
2716 return 0;
2720 /***********************************************************************
2721 * NC_HandleNCLButtonDblClk
2723 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2725 LONG NC_HandleNCLButtonDblClk( WND *pWnd, WPARAM16 wParam, LPARAM lParam )
2728 * if this is an icon, send a restore since we are handling
2729 * a double click
2731 if (pWnd->dwStyle & WS_MINIMIZE)
2733 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_RESTORE, lParam );
2734 return 0;
2737 switch(wParam) /* Hit test */
2739 case HTCAPTION:
2740 /* stop processing if WS_MAXIMIZEBOX is missing */
2741 if (pWnd->dwStyle & WS_MAXIMIZEBOX)
2742 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND,
2743 (pWnd->dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
2744 lParam );
2745 break;
2747 case HTSYSMENU:
2748 if (!(GetClassWord(pWnd->hwndSelf, GCW_STYLE) & CS_NOCLOSE))
2749 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, lParam );
2750 break;
2752 case HTHSCROLL:
2753 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL,
2754 lParam );
2755 break;
2757 case HTVSCROLL:
2758 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL,
2759 lParam );
2760 break;
2762 return 0;
2766 /***********************************************************************
2767 * NC_HandleSysCommand
2769 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2771 LONG NC_HandleSysCommand( HWND hwnd, WPARAM16 wParam, POINT16 pt )
2773 WND *wndPtr = WIN_FindWndPtr( hwnd );
2774 POINT pt32;
2775 UINT16 uCommand = wParam & 0xFFF0;
2777 TRACE("Handling WM_SYSCOMMAND %x %d,%d\n", wParam, pt.x, pt.y );
2779 if (wndPtr->dwStyle & WS_CHILD && uCommand != SC_KEYMENU )
2780 ScreenToClient16( wndPtr->parent->hwndSelf, &pt );
2782 switch (uCommand)
2784 case SC_SIZE:
2785 case SC_MOVE:
2786 NC_DoSizeMove( hwnd, wParam );
2787 break;
2789 case SC_MINIMIZE:
2790 if (hwnd == GetForegroundWindow())
2791 ShowOwnedPopups(hwnd,FALSE);
2792 ShowWindow( hwnd, SW_MINIMIZE );
2793 break;
2795 case SC_MAXIMIZE:
2796 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2797 ShowOwnedPopups(hwnd,TRUE);
2798 ShowWindow( hwnd, SW_MAXIMIZE );
2799 break;
2801 case SC_RESTORE:
2802 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2803 ShowOwnedPopups(hwnd,TRUE);
2804 ShowWindow( hwnd, SW_RESTORE );
2805 break;
2807 case SC_CLOSE:
2808 WIN_ReleaseWndPtr(wndPtr);
2809 return SendMessage16( hwnd, WM_CLOSE, 0, 0 );
2811 case SC_VSCROLL:
2812 case SC_HSCROLL:
2813 CONV_POINT16TO32( &pt, &pt32 );
2814 NC_TrackScrollBar( hwnd, wParam, pt32 );
2815 break;
2817 case SC_MOUSEMENU:
2818 CONV_POINT16TO32( &pt, &pt32 );
2819 MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt32 );
2820 break;
2822 case SC_KEYMENU:
2823 MENU_TrackKbdMenuBar( wndPtr , wParam , pt.x );
2824 break;
2826 case SC_TASKLIST:
2827 WinExec( "taskman.exe", SW_SHOWNORMAL );
2828 break;
2830 case SC_SCREENSAVE:
2831 if (wParam == SC_ABOUTWINE)
2833 HMODULE hmodule = LoadLibraryA( "shell32.dll" );
2834 if (hmodule)
2836 FARPROC aboutproc = GetProcAddress( hmodule, "ShellAboutA" );
2837 if (aboutproc) aboutproc( hwnd, "Wine", WINE_RELEASE_INFO, 0 );
2838 FreeLibrary( hmodule );
2841 else
2842 if (wParam == SC_PUTMARK)
2843 TRACE_(shell)("Mark requested by user\n");
2844 break;
2846 case SC_HOTKEY:
2847 case SC_ARRANGE:
2848 case SC_NEXTWINDOW:
2849 case SC_PREVWINDOW:
2850 FIXME("unimplemented!\n");
2851 break;
2853 WIN_ReleaseWndPtr(wndPtr);
2854 return 0;
2857 /*************************************************************
2858 * NC_DrawGrayButton
2860 * Stub for the grayed button of the caption
2862 *************************************************************/
2864 BOOL NC_DrawGrayButton(HDC hdc, int x, int y)
2866 HBITMAP hMaskBmp;
2867 HDC hdcMask = CreateCompatibleDC (0);
2868 HBRUSH hOldBrush;
2870 hMaskBmp = CreateBitmap (12, 10, 1, 1, lpGrayMask);
2872 if(hMaskBmp == 0)
2873 return FALSE;
2875 SelectObject (hdcMask, hMaskBmp);
2877 /* Draw the grayed bitmap using the mask */
2878 hOldBrush = SelectObject (hdc, RGB(128, 128, 128));
2879 BitBlt (hdc, x, y, 12, 10,
2880 hdcMask, 0, 0, 0xB8074A);
2882 /* Clean up */
2883 SelectObject (hdc, hOldBrush);
2884 DeleteObject(hMaskBmp);
2885 DeleteDC (hdcMask);
2887 return TRUE;
2890 HICON16 NC_IconForWindow(WND *wndPtr)
2892 HICON16 hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICONSM);
2893 if(!hIcon) hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICON);
2895 /* If there is no hIcon specified and this is a modal dialog, */
2896 /* get the default one. */
2897 if (!hIcon && (wndPtr->dwStyle & DS_MODALFRAME))
2898 hIcon = LoadImageA(0, MAKEINTRESOURCEA(OIC_WINEICON), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
2900 return hIcon;