2 * Non-client area window functions
4 * Copyright 1994 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "wine/winuser16.h"
34 #include "cursoricon.h"
36 #include "nonclient.h"
39 #include "wine/debug.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(nonclient);
42 WINE_DECLARE_DEBUG_CHANNEL(shell);
44 BOOL NC_DrawGrayButton(HDC hdc, int x, int y);
46 static HBITMAP hbitmapClose;
48 static const BYTE lpGrayMask[] = { 0xAA, 0xA0,
59 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
60 #define SC_PUTMARK (SC_SCREENSAVE+2)
62 /* Some useful macros */
63 #define HAS_DLGFRAME(style,exStyle) \
64 (((exStyle) & WS_EX_DLGMODALFRAME) || \
65 (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
67 #define HAS_THICKFRAME(style,exStyle) \
68 (((style) & WS_THICKFRAME) && \
69 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
71 #define HAS_THINFRAME(style) \
72 (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
74 #define HAS_BIGFRAME(style,exStyle) \
75 (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
76 ((exStyle) & WS_EX_DLGMODALFRAME))
78 #define HAS_STATICOUTERFRAME(style,exStyle) \
79 (((exStyle) & (WS_EX_STATICEDGE|WS_EX_DLGMODALFRAME)) == \
82 #define HAS_ANYFRAME(style,exStyle) \
83 (((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
84 ((exStyle) & WS_EX_DLGMODALFRAME) || \
85 !((style) & (WS_CHILD | WS_POPUP)))
87 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
90 /***********************************************************************
93 * Compute the size of the window rectangle from the size of the
96 static void NC_AdjustRect( LPRECT rect, DWORD style, BOOL menu, DWORD exStyle )
98 if (TWEAK_WineLook > WIN31_LOOK)
99 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
101 if(style & WS_ICONIC) return;
103 if (HAS_THICKFRAME( style, exStyle ))
104 InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
105 else if (HAS_DLGFRAME( style, exStyle ))
106 InflateRect( rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
107 else if (HAS_THINFRAME( style ))
108 InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
110 if ((style & WS_CAPTION) == WS_CAPTION)
111 rect->top -= GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
113 if (menu) rect->top -= GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYBORDER);
115 if (style & WS_VSCROLL) {
116 rect->right += GetSystemMetrics(SM_CXVSCROLL) - 1;
117 if(!HAS_ANYFRAME( style, exStyle ))
121 if (style & WS_HSCROLL) {
122 rect->bottom += GetSystemMetrics(SM_CYHSCROLL) - 1;
123 if(!HAS_ANYFRAME( style, exStyle ))
129 /******************************************************************************
130 * NC_AdjustRectOuter95
132 * Computes the size of the "outside" parts of the window based on the
133 * parameters of the client area.
142 * "Outer" parts of a window means the whole window frame, caption and
143 * menu bar. It does not include "inner" parts of the frame like client
144 * edge, static edge or scroll bars.
147 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
148 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
150 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
151 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
152 * NC_AdjustRectInner95 and added handling of Win95 styles.
154 * 28-Jul-1999 Ove Kåven (ovek@arcticnet.no)
155 * Streamlined window style checks.
157 *****************************************************************************/
160 NC_AdjustRectOuter95 (LPRECT rect, DWORD style, BOOL menu, DWORD exStyle)
163 if(style & WS_ICONIC) return;
165 if ((exStyle & (WS_EX_STATICEDGE|WS_EX_DLGMODALFRAME)) ==
168 adjust = 1; /* for the outer frame always present */
173 if ((exStyle & WS_EX_DLGMODALFRAME) ||
174 (style & (WS_THICKFRAME|WS_DLGFRAME))) adjust = 2; /* outer */
176 if (style & WS_THICKFRAME)
177 adjust += ( GetSystemMetrics (SM_CXFRAME)
178 - GetSystemMetrics (SM_CXDLGFRAME)); /* The resize border */
179 if ((style & (WS_BORDER|WS_DLGFRAME)) ||
180 (exStyle & WS_EX_DLGMODALFRAME))
181 adjust++; /* The other border */
183 InflateRect (rect, adjust, adjust);
185 if ((style & WS_CAPTION) == WS_CAPTION)
187 if (exStyle & WS_EX_TOOLWINDOW)
188 rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
190 rect->top -= GetSystemMetrics(SM_CYCAPTION);
192 if (menu) rect->top -= GetSystemMetrics(SM_CYMENU);
196 /******************************************************************************
197 * NC_AdjustRectInner95
199 * Computes the size of the "inside" part of the window based on the
200 * parameters of the client area.
208 * "Inner" part of a window means the window frame inside of the flat
209 * window frame. It includes the client edge, the static edge and the
213 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
214 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
216 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
217 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
218 * NC_AdjustRectInner95 and added handling of Win95 styles.
220 *****************************************************************************/
223 NC_AdjustRectInner95 (LPRECT rect, DWORD style, DWORD exStyle)
225 if(style & WS_ICONIC) return;
227 if (exStyle & WS_EX_CLIENTEDGE)
228 InflateRect(rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
230 if (style & WS_VSCROLL)
232 if((exStyle & WS_EX_LEFTSCROLLBAR) != 0)
233 rect->left -= GetSystemMetrics(SM_CXVSCROLL);
235 rect->right += GetSystemMetrics(SM_CXVSCROLL);
237 if (style & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
242 static HICON NC_IconForWindow( HWND hwnd )
244 HICON hIcon = (HICON) GetClassLongA( hwnd, GCL_HICONSM );
245 if (!hIcon) hIcon = (HICON) GetClassLongA( hwnd, GCL_HICON );
247 /* If there is no hIcon specified and this is a modal dialog,
248 * get the default one.
250 if (!hIcon && (GetWindowLongA( hwnd, GWL_STYLE ) & DS_MODALFRAME))
251 hIcon = LoadImageA(0, (LPSTR)IDI_WINLOGO, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
255 /***********************************************************************
256 * DrawCaption (USER32.@) Draws a caption bar
270 DrawCaption (HWND hwnd, HDC hdc, const RECT *lpRect, UINT uFlags)
272 return DrawCaptionTempA (hwnd, hdc, lpRect, 0, 0, NULL, uFlags & 0x1F);
276 /***********************************************************************
277 * DrawCaptionTempA (USER32.@)
279 BOOL WINAPI DrawCaptionTempA (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
280 HICON hIcon, LPCSTR str, UINT uFlags)
286 if (!(uFlags & DC_TEXT) || !str)
287 return DrawCaptionTempW( hwnd, hdc, rect, hFont, hIcon, NULL, uFlags );
289 len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
290 if ((strW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
292 MultiByteToWideChar( CP_ACP, 0, str, -1, strW, len );
293 ret = DrawCaptionTempW (hwnd, hdc, rect, hFont, hIcon, strW, uFlags);
294 HeapFree( GetProcessHeap (), 0, strW );
300 /***********************************************************************
301 * DrawCaptionTempW (USER32.@)
303 BOOL WINAPI DrawCaptionTempW (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
304 HICON hIcon, LPCWSTR str, UINT uFlags)
308 TRACE("(%p,%p,%p,%p,%p,%s,%08x)\n",
309 hwnd, hdc, rect, hFont, hIcon, debugstr_w(str), uFlags);
311 /* drawing background */
312 if (uFlags & DC_INBUTTON) {
313 FillRect (hdc, &rc, GetSysColorBrush (COLOR_3DFACE));
315 if (uFlags & DC_ACTIVE) {
316 HBRUSH hbr = SelectObject (hdc, CACHE_GetPattern55AABrush ());
317 PatBlt (hdc, rc.left, rc.top,
318 rc.right-rc.left, rc.bottom-rc.top, 0xFA0089);
319 SelectObject (hdc, hbr);
323 FillRect (hdc, &rc, GetSysColorBrush ((uFlags & DC_ACTIVE) ?
324 COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
329 if ((uFlags & DC_ICON) && !(uFlags & DC_SMALLCAP)) {
333 pt.y = (rc.bottom + rc.top - GetSystemMetrics(SM_CYSMICON)) / 2;
335 if (!hIcon) hIcon = NC_IconForWindow(hwnd);
336 DrawIconEx (hdc, pt.x, pt.y, hIcon, GetSystemMetrics(SM_CXSMICON),
337 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
338 rc.left += (rc.bottom - rc.top);
342 if (uFlags & DC_TEXT) {
345 if (uFlags & DC_INBUTTON)
346 SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
347 else if (uFlags & DC_ACTIVE)
348 SetTextColor (hdc, GetSysColor (COLOR_CAPTIONTEXT));
350 SetTextColor (hdc, GetSysColor (COLOR_INACTIVECAPTIONTEXT));
352 SetBkMode (hdc, TRANSPARENT);
355 hOldFont = SelectObject (hdc, hFont);
357 NONCLIENTMETRICSW nclm;
359 nclm.cbSize = sizeof(NONCLIENTMETRICSW);
360 SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
361 hNewFont = CreateFontIndirectW ((uFlags & DC_SMALLCAP) ?
362 &nclm.lfSmCaptionFont : &nclm.lfCaptionFont);
363 hOldFont = SelectObject (hdc, hNewFont);
367 DrawTextW (hdc, str, -1, &rc,
368 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
372 nLen = GetWindowTextW (hwnd, szText, 128);
373 DrawTextW (hdc, szText, nLen, &rc,
374 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
378 SelectObject (hdc, hOldFont);
380 DeleteObject (SelectObject (hdc, hOldFont));
383 /* drawing focus ??? */
385 FIXME("undocumented flag (0x2000)!\n");
391 /***********************************************************************
392 * AdjustWindowRect (USER.102)
394 BOOL16 WINAPI AdjustWindowRect16( LPRECT16 rect, DWORD style, BOOL16 menu )
396 return AdjustWindowRectEx16( rect, style, menu, 0 );
400 /***********************************************************************
401 * AdjustWindowRect (USER32.@)
403 BOOL WINAPI AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu )
405 return AdjustWindowRectEx( rect, style, menu, 0 );
409 /***********************************************************************
410 * AdjustWindowRectEx (USER.454)
412 BOOL16 WINAPI AdjustWindowRectEx16( LPRECT16 rect, DWORD style,
413 BOOL16 menu, DWORD exStyle )
418 CONV_RECT16TO32( rect, &rect32 );
419 ret = AdjustWindowRectEx( &rect32, style, menu, exStyle );
420 CONV_RECT32TO16( &rect32, rect );
425 /***********************************************************************
426 * AdjustWindowRectEx (USER32.@)
428 BOOL WINAPI AdjustWindowRectEx( LPRECT rect, DWORD style, BOOL menu, DWORD exStyle )
430 /* Correct the window style */
431 style &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD);
432 exStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE |
433 WS_EX_STATICEDGE | WS_EX_TOOLWINDOW);
434 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
436 TRACE("(%ld,%ld)-(%ld,%ld) %08lx %d %08lx\n",
437 rect->left, rect->top, rect->right, rect->bottom,
438 style, menu, exStyle );
440 if (TWEAK_WineLook == WIN31_LOOK)
441 NC_AdjustRect( rect, style, menu, exStyle );
444 NC_AdjustRectOuter95( rect, style, menu, exStyle );
445 NC_AdjustRectInner95( rect, style, exStyle );
451 /***********************************************************************
452 * NC_HandleNCCalcSize
454 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
456 LONG NC_HandleNCCalcSize( HWND hwnd, RECT *winRect )
458 RECT tmpRect = { 0, 0, 0, 0 };
460 LONG cls_style = GetClassLongA(hwnd, GCL_STYLE);
461 LONG style = GetWindowLongA( hwnd, GWL_STYLE );
462 LONG exStyle = GetWindowLongA( hwnd, GWL_EXSTYLE );
464 if (cls_style & CS_VREDRAW) result |= WVR_VREDRAW;
465 if (cls_style & CS_HREDRAW) result |= WVR_HREDRAW;
469 if (TWEAK_WineLook == WIN31_LOOK)
470 NC_AdjustRect( &tmpRect, style, FALSE, exStyle );
472 NC_AdjustRectOuter95( &tmpRect, style, FALSE, exStyle );
474 winRect->left -= tmpRect.left;
475 winRect->top -= tmpRect.top;
476 winRect->right -= tmpRect.right;
477 winRect->bottom -= tmpRect.bottom;
479 if (!(style & WS_CHILD) && GetMenu(hwnd))
481 TRACE("Calling GetMenuBarHeight with hwnd %p, width %ld, at (%ld, %ld).\n",
482 hwnd, winRect->right - winRect->left, -tmpRect.left, -tmpRect.top );
485 MENU_GetMenuBarHeight( hwnd,
486 winRect->right - winRect->left,
487 -tmpRect.left, -tmpRect.top ) + 1;
490 if (TWEAK_WineLook > WIN31_LOOK) {
491 SetRect(&tmpRect, 0, 0, 0, 0);
492 NC_AdjustRectInner95 (&tmpRect, style, exStyle);
493 winRect->left -= tmpRect.left;
494 winRect->top -= tmpRect.top;
495 winRect->right -= tmpRect.right;
496 winRect->bottom -= tmpRect.bottom;
499 if (winRect->top > winRect->bottom)
500 winRect->bottom = winRect->top;
502 if (winRect->left > winRect->right)
503 winRect->right = winRect->left;
509 /***********************************************************************
512 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
513 * but without the borders (if any).
514 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
516 void NC_GetInsideRect( HWND hwnd, RECT *rect )
518 WND * wndPtr = WIN_FindWndPtr( hwnd );
520 rect->top = rect->left = 0;
521 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
522 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
524 if (wndPtr->dwStyle & WS_ICONIC) goto END;
526 /* Remove frame from rectangle */
527 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
529 InflateRect( rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
531 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
533 InflateRect( rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
534 /* FIXME: this isn't in NC_AdjustRect? why not? */
535 if ((TWEAK_WineLook == WIN31_LOOK) && (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME))
536 InflateRect( rect, -1, 0 );
538 else if (HAS_THINFRAME( wndPtr->dwStyle ))
540 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
543 /* We have additional border information if the window
544 * is a child (but not an MDI child) */
545 if (TWEAK_WineLook != WIN31_LOOK)
547 if ( (wndPtr->dwStyle & WS_CHILD) &&
548 ( (wndPtr->dwExStyle & WS_EX_MDICHILD) == 0 ) )
550 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
551 InflateRect (rect, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE));
552 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
553 InflateRect (rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
558 WIN_ReleaseWndPtr(wndPtr);
563 /***********************************************************************
566 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
569 static LONG NC_DoNCHitTest (WND *wndPtr, POINT pt )
573 TRACE("hwnd=%p pt=%ld,%ld\n", wndPtr->hwndSelf, pt.x, pt.y );
575 GetWindowRect(wndPtr->hwndSelf, &rect );
576 if (!PtInRect( &rect, pt )) return HTNOWHERE;
578 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
581 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
583 InflateRect( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
584 if (!PtInRect( &rect, pt ))
586 /* Check top sizing border */
589 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
590 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
593 /* Check bottom sizing border */
594 if (pt.y >= rect.bottom)
596 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
597 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
600 /* Check left sizing border */
601 if (pt.x < rect.left)
603 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
604 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
607 /* Check right sizing border */
608 if (pt.x >= rect.right)
610 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
611 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
616 else /* No thick frame */
618 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
619 InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
620 else if (HAS_THINFRAME( wndPtr->dwStyle ))
621 InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
622 if (!PtInRect( &rect, pt )) return HTBORDER;
627 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
629 rect.top += GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
630 if (!PtInRect( &rect, pt ))
632 /* Check system menu */
633 if ((wndPtr->dwStyle & WS_SYSMENU) && !(wndPtr->dwExStyle & WS_EX_TOOLWINDOW))
634 rect.left += GetSystemMetrics(SM_CXSIZE);
635 if (pt.x <= rect.left) return HTSYSMENU;
637 /* Check maximize box */
638 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
639 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
641 if (pt.x >= rect.right) return HTMAXBUTTON;
642 /* Check minimize box */
643 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
644 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
645 if (pt.x >= rect.right) return HTMINBUTTON;
650 /* Check client area */
652 ScreenToClient( wndPtr->hwndSelf, &pt );
653 GetClientRect( wndPtr->hwndSelf, &rect );
654 if (PtInRect( &rect, pt )) return HTCLIENT;
656 /* Check vertical scroll bar */
658 if (wndPtr->dwStyle & WS_VSCROLL)
660 if((wndPtr->dwExStyle & WS_EX_LEFTSCROLLBAR) != 0)
661 rect.left -= GetSystemMetrics(SM_CXVSCROLL);
663 rect.right += GetSystemMetrics(SM_CXVSCROLL);
664 if (PtInRect( &rect, pt )) return HTVSCROLL;
667 /* Check horizontal scroll bar */
669 if (wndPtr->dwStyle & WS_HSCROLL)
671 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
672 if (PtInRect( &rect, pt ))
675 if ((wndPtr->dwStyle & WS_VSCROLL) &&
676 ((((wndPtr->dwExStyle & WS_EX_LEFTSCROLLBAR) != 0) && (pt.x <= rect.left + GetSystemMetrics(SM_CXVSCROLL))) ||
677 (((wndPtr->dwExStyle & WS_EX_LEFTSCROLLBAR) == 0) && (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))))
685 if (HAS_MENU(wndPtr))
687 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
691 /* Has to return HTNOWHERE if nothing was found
692 Could happen when a window has a customized non client area */
697 /***********************************************************************
700 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
702 * FIXME: Just a modified copy of the Win 3.1 version.
705 static LONG NC_DoNCHitTest95 (WND *wndPtr, POINT pt )
709 TRACE("hwnd=%p pt=%ld,%ld\n", wndPtr->hwndSelf, pt.x, pt.y );
711 GetWindowRect(wndPtr->hwndSelf, &rect );
712 if (!PtInRect( &rect, pt )) return HTNOWHERE;
714 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
717 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
719 InflateRect( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
720 if (!PtInRect( &rect, pt ))
722 /* Check top sizing border */
725 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
726 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
729 /* Check bottom sizing border */
730 if (pt.y >= rect.bottom)
732 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
733 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
736 /* Check left sizing border */
737 if (pt.x < rect.left)
739 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
740 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
743 /* Check right sizing border */
744 if (pt.x >= rect.right)
746 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
747 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
752 else /* No thick frame */
754 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
755 InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
756 else if (HAS_THINFRAME( wndPtr->dwStyle ))
757 InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
758 if (!PtInRect( &rect, pt )) return HTBORDER;
763 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
765 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
766 rect.top += GetSystemMetrics(SM_CYSMCAPTION) - 1;
768 rect.top += GetSystemMetrics(SM_CYCAPTION) - 1;
769 if (!PtInRect( &rect, pt ))
771 /* Check system menu */
772 if ((wndPtr->dwStyle & WS_SYSMENU) && !(wndPtr->dwExStyle & WS_EX_TOOLWINDOW))
774 if (NC_IconForWindow(wndPtr->hwndSelf))
775 rect.left += GetSystemMetrics(SM_CYCAPTION) - 1;
777 if (pt.x < rect.left) return HTSYSMENU;
779 /* Check close button */
780 if (wndPtr->dwStyle & WS_SYSMENU)
781 rect.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
782 if (pt.x > rect.right) return HTCLOSE;
784 /* Check maximize box */
785 /* In win95 there is automatically a Maximize button when there is a minimize one*/
786 if ((wndPtr->dwStyle & WS_MAXIMIZEBOX)|| (wndPtr->dwStyle & WS_MINIMIZEBOX))
787 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
788 if (pt.x > rect.right) return HTMAXBUTTON;
790 /* Check minimize box */
791 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
792 if ((wndPtr->dwStyle & WS_MINIMIZEBOX)||(wndPtr->dwStyle & WS_MAXIMIZEBOX))
793 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
795 if (pt.x > rect.right) return HTMINBUTTON;
800 /* Check client area */
802 ScreenToClient( wndPtr->hwndSelf, &pt );
803 GetClientRect( wndPtr->hwndSelf, &rect );
804 if (PtInRect( &rect, pt )) return HTCLIENT;
806 /* Check vertical scroll bar */
808 if (wndPtr->dwStyle & WS_VSCROLL)
810 if((wndPtr->dwExStyle & WS_EX_LEFTSCROLLBAR) != 0)
811 rect.left -= GetSystemMetrics(SM_CXVSCROLL);
813 rect.right += GetSystemMetrics(SM_CXVSCROLL);
814 if (PtInRect( &rect, pt )) return HTVSCROLL;
817 /* Check horizontal scroll bar */
819 if (wndPtr->dwStyle & WS_HSCROLL)
821 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
822 if (PtInRect( &rect, pt ))
825 if ((wndPtr->dwStyle & WS_VSCROLL) &&
826 ((((wndPtr->dwExStyle & WS_EX_LEFTSCROLLBAR) != 0) && (pt.x <= rect.left + GetSystemMetrics(SM_CXVSCROLL))) ||
827 (((wndPtr->dwExStyle & WS_EX_LEFTSCROLLBAR) == 0) && (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))))
835 if (HAS_MENU(wndPtr))
837 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
841 /* Has to return HTNOWHERE if nothing was found
842 Could happen when a window has a customized non client area */
847 /***********************************************************************
850 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
852 LONG NC_HandleNCHitTest (HWND hwnd , POINT pt)
855 WND *wndPtr = WIN_FindWndPtr (hwnd);
860 if (TWEAK_WineLook == WIN31_LOOK)
861 retvalue = NC_DoNCHitTest (wndPtr, pt);
863 retvalue = NC_DoNCHitTest95 (wndPtr, pt);
864 WIN_ReleaseWndPtr(wndPtr);
869 /***********************************************************************
872 void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down )
878 NC_GetInsideRect( hwnd, &rect );
879 hdcMem = CreateCompatibleDC( hdc );
880 hbitmap = SelectObject( hdcMem, hbitmapClose );
881 BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE), GetSystemMetrics(SM_CYSIZE),
882 hdcMem, (GetWindowLongA(hwnd,GWL_STYLE) & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE) : 0, 0,
883 down ? NOTSRCCOPY : SRCCOPY );
884 SelectObject( hdcMem, hbitmap );
889 /***********************************************************************
892 static void NC_DrawMaxButton( HWND hwnd, HDC hdc, BOOL down )
895 UINT flags = IsZoomed(hwnd) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMAX;
897 NC_GetInsideRect( hwnd, &rect );
898 rect.left = rect.right - GetSystemMetrics(SM_CXSIZE) + 1;
899 rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
902 if (down) flags |= DFCS_PUSHED;
903 DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
907 /***********************************************************************
910 static void NC_DrawMinButton( HWND hwnd, HDC hdc, BOOL down )
913 UINT flags = DFCS_CAPTIONMIN;
914 DWORD style = GetWindowLongA( hwnd, GWL_STYLE );
916 NC_GetInsideRect( hwnd, &rect );
917 if (style & (WS_MAXIMIZEBOX|WS_MINIMIZEBOX))
918 rect.right -= GetSystemMetrics(SM_CXSIZE) - 2;
919 rect.left = rect.right - GetSystemMetrics(SM_CXSIZE) + 1;
920 rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
923 if (down) flags |= DFCS_PUSHED;
924 DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
928 /******************************************************************************
930 * void NC_DrawSysButton95(
935 * Draws the Win95 system icon.
938 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
939 * Original implementation from NC_DrawSysButton source.
940 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
943 *****************************************************************************/
946 NC_DrawSysButton95 (HWND hwnd, HDC hdc, BOOL down)
948 HICON hIcon = NC_IconForWindow( hwnd );
953 NC_GetInsideRect( hwnd, &rect );
954 DrawIconEx (hdc, rect.left + 1, rect.top + 1, hIcon,
955 GetSystemMetrics(SM_CXSIZE) - 1,
956 GetSystemMetrics(SM_CYSIZE) - 1, 0, 0, DI_NORMAL);
962 /******************************************************************************
964 * void NC_DrawCloseButton95(
970 * Draws the Win95 close button.
972 * If bGrayed is true, then draw a disabled Close button
975 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
976 * Original implementation from NC_DrawSysButton95 source.
978 *****************************************************************************/
980 static void NC_DrawCloseButton95 (HWND hwnd, HDC hdc, BOOL down, BOOL bGrayed)
984 NC_GetInsideRect( hwnd, &rect );
986 /* A tool window has a smaller Close button */
987 if (GetWindowLongA( hwnd, GWL_EXSTYLE ) & WS_EX_TOOLWINDOW)
989 INT iBmpHeight = 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
990 INT iBmpWidth = 11; /* it uses 11x11 for the close button in tool window */
991 INT iCaptionHeight = GetSystemMetrics(SM_CYSMCAPTION);
993 rect.top = rect.top + (iCaptionHeight - 1 - iBmpHeight) / 2;
994 rect.left = rect.right - (iCaptionHeight + 1 + iBmpWidth) / 2;
995 rect.bottom = rect.top + iBmpHeight;
996 rect.right = rect.left + iBmpWidth;
1000 rect.left = rect.right - GetSystemMetrics(SM_CXSIZE) - 1;
1001 rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
1005 DrawFrameControl( hdc, &rect, DFC_CAPTION,
1006 (DFCS_CAPTIONCLOSE |
1007 (down ? DFCS_PUSHED : 0) |
1008 (bGrayed ? DFCS_INACTIVE : 0)) );
1011 /******************************************************************************
1012 * NC_DrawMaxButton95
1014 * Draws the maximize button for Win95 style windows.
1015 * If bGrayed is true, then draw a disabled Maximize button
1017 static void NC_DrawMaxButton95(HWND hwnd,HDC hdc,BOOL down, BOOL bGrayed)
1020 UINT flags = IsZoomed(hwnd) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMAX;
1022 NC_GetInsideRect( hwnd, &rect );
1023 if (GetWindowLongA( hwnd, GWL_STYLE) & WS_SYSMENU)
1024 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1025 rect.left = rect.right - GetSystemMetrics(SM_CXSIZE);
1026 rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
1029 if (down) flags |= DFCS_PUSHED;
1030 if (bGrayed) flags |= DFCS_INACTIVE;
1031 DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
1034 /******************************************************************************
1035 * NC_DrawMinButton95
1037 * Draws the minimize button for Win95 style windows.
1038 * If bGrayed is true, then draw a disabled Minimize button
1040 static void NC_DrawMinButton95(HWND hwnd,HDC hdc,BOOL down, BOOL bGrayed)
1043 UINT flags = DFCS_CAPTIONMIN;
1044 DWORD style = GetWindowLongA( hwnd, GWL_STYLE );
1046 NC_GetInsideRect( hwnd, &rect );
1047 if (style & WS_SYSMENU)
1048 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1049 if (style & (WS_MAXIMIZEBOX|WS_MINIMIZEBOX))
1050 rect.right -= GetSystemMetrics(SM_CXSIZE) - 2;
1051 rect.left = rect.right - GetSystemMetrics(SM_CXSIZE);
1052 rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
1055 if (down) flags |= DFCS_PUSHED;
1056 if (bGrayed) flags |= DFCS_INACTIVE;
1057 DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
1060 /***********************************************************************
1063 * Draw a window frame inside the given rectangle, and update the rectangle.
1064 * The correct pen for the frame must be selected in the DC.
1066 static void NC_DrawFrame( HDC hdc, RECT *rect, BOOL dlgFrame,
1071 if (TWEAK_WineLook != WIN31_LOOK)
1072 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
1076 width = GetSystemMetrics(SM_CXDLGFRAME) - 1;
1077 height = GetSystemMetrics(SM_CYDLGFRAME) - 1;
1078 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1079 COLOR_INACTIVECAPTION) );
1083 width = GetSystemMetrics(SM_CXFRAME) - 2;
1084 height = GetSystemMetrics(SM_CYFRAME) - 2;
1085 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1086 COLOR_INACTIVEBORDER) );
1090 PatBlt( hdc, rect->left, rect->top,
1091 rect->right - rect->left, height, PATCOPY );
1092 PatBlt( hdc, rect->left, rect->top,
1093 width, rect->bottom - rect->top, PATCOPY );
1094 PatBlt( hdc, rect->left, rect->bottom - 1,
1095 rect->right - rect->left, -height, PATCOPY );
1096 PatBlt( hdc, rect->right - 1, rect->top,
1097 -width, rect->bottom - rect->top, PATCOPY );
1101 InflateRect( rect, -width, -height );
1105 INT decYOff = GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXSIZE) - 1;
1106 INT decXOff = GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYSIZE) - 1;
1108 /* Draw inner rectangle */
1110 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1111 Rectangle( hdc, rect->left + width, rect->top + height,
1112 rect->right - width , rect->bottom - height );
1114 /* Draw the decorations */
1116 MoveToEx( hdc, rect->left, rect->top + decYOff, NULL );
1117 LineTo( hdc, rect->left + width, rect->top + decYOff );
1118 MoveToEx( hdc, rect->right - 1, rect->top + decYOff, NULL );
1119 LineTo( hdc, rect->right - width - 1, rect->top + decYOff );
1120 MoveToEx( hdc, rect->left, rect->bottom - decYOff, NULL );
1121 LineTo( hdc, rect->left + width, rect->bottom - decYOff );
1122 MoveToEx( hdc, rect->right - 1, rect->bottom - decYOff, NULL );
1123 LineTo( hdc, rect->right - width - 1, rect->bottom - decYOff );
1125 MoveToEx( hdc, rect->left + decXOff, rect->top, NULL );
1126 LineTo( hdc, rect->left + decXOff, rect->top + height);
1127 MoveToEx( hdc, rect->left + decXOff, rect->bottom - 1, NULL );
1128 LineTo( hdc, rect->left + decXOff, rect->bottom - height - 1 );
1129 MoveToEx( hdc, rect->right - decXOff, rect->top, NULL );
1130 LineTo( hdc, rect->right - decXOff, rect->top + height );
1131 MoveToEx( hdc, rect->right - decXOff, rect->bottom - 1, NULL );
1132 LineTo( hdc, rect->right - decXOff, rect->bottom - height - 1 );
1134 InflateRect( rect, -width - 1, -height - 1 );
1139 /******************************************************************************
1141 * void NC_DrawFrame95(
1148 * Draw a window frame inside the given rectangle, and update the rectangle.
1151 * Many. First, just what IS a frame in Win95? Note that the 3D look
1152 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1153 * edge. The inner rectangle just inside the frame is handled by the
1156 * In short, for most people, this function should be a nop (unless
1157 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1158 * them lately, but just to get this code right). Even so, it doesn't
1159 * appear to be so. It's being worked on...
1162 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1163 * Original implementation (based on NC_DrawFrame)
1164 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1166 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1167 * Fixed a fix or something.
1169 *****************************************************************************/
1171 static void NC_DrawFrame95(
1180 /* Firstly the "thick" frame */
1181 if (style & WS_THICKFRAME)
1183 width = GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXDLGFRAME);
1184 height = GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYDLGFRAME);
1186 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1187 COLOR_INACTIVEBORDER) );
1189 PatBlt( hdc, rect->left, rect->top,
1190 rect->right - rect->left, height, PATCOPY );
1191 PatBlt( hdc, rect->left, rect->top,
1192 width, rect->bottom - rect->top, PATCOPY );
1193 PatBlt( hdc, rect->left, rect->bottom - 1,
1194 rect->right - rect->left, -height, PATCOPY );
1195 PatBlt( hdc, rect->right - 1, rect->top,
1196 -width, rect->bottom - rect->top, PATCOPY );
1198 InflateRect( rect, -width, -height );
1201 /* Now the other bit of the frame */
1202 if ((style & (WS_BORDER|WS_DLGFRAME)) ||
1203 (exStyle & WS_EX_DLGMODALFRAME))
1205 width = GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
1206 height = GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
1207 /* This should give a value of 1 that should also work for a border */
1209 SelectObject( hdc, GetSysColorBrush(
1210 (exStyle & (WS_EX_DLGMODALFRAME|WS_EX_CLIENTEDGE)) ?
1212 (exStyle & WS_EX_STATICEDGE) ?
1214 (style & (WS_DLGFRAME|WS_THICKFRAME)) ?
1217 COLOR_WINDOWFRAME));
1220 PatBlt( hdc, rect->left, rect->top,
1221 rect->right - rect->left, height, PATCOPY );
1222 PatBlt( hdc, rect->left, rect->top,
1223 width, rect->bottom - rect->top, PATCOPY );
1224 PatBlt( hdc, rect->left, rect->bottom - 1,
1225 rect->right - rect->left, -height, PATCOPY );
1226 PatBlt( hdc, rect->right - 1, rect->top,
1227 -width, rect->bottom - rect->top, PATCOPY );
1229 InflateRect( rect, -width, -height );
1234 /***********************************************************************
1237 * Draw the window caption.
1238 * The correct pen for the window frame must be selected in the DC.
1240 static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd,
1241 DWORD style, BOOL active )
1248 if (!(hbitmapClose = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_OLD_CLOSE) ))) return;
1251 if (GetWindowLongA( hwnd, GWL_EXSTYLE) & WS_EX_DLGMODALFRAME)
1253 HBRUSH hbrushOld = SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW) );
1254 PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
1255 PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
1256 PatBlt( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
1259 SelectObject( hdc, hbrushOld );
1261 MoveToEx( hdc, r.left, r.bottom, NULL );
1262 LineTo( hdc, r.right, r.bottom );
1264 if (style & WS_SYSMENU)
1266 NC_DrawSysButton( hwnd, hdc, FALSE );
1267 r.left += GetSystemMetrics(SM_CXSIZE) + 1;
1268 MoveToEx( hdc, r.left - 1, r.top, NULL );
1269 LineTo( hdc, r.left - 1, r.bottom );
1271 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION) );
1272 if (style & WS_MAXIMIZEBOX)
1274 NC_DrawMaxButton( hwnd, hdc, FALSE );
1275 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1277 if (style & WS_MINIMIZEBOX)
1279 NC_DrawMinButton( hwnd, hdc, FALSE );
1280 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1283 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) ))
1285 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1286 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1287 SetBkMode( hdc, TRANSPARENT );
1288 DrawTextA( hdc, buffer, -1, &r,
1289 DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );
1294 /******************************************************************************
1303 * Draw the window caption for Win95 style windows.
1304 * The correct pen for the window frame must be selected in the DC.
1307 * Hey, a function that finally works! Well, almost.
1308 * It's being worked on.
1311 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1312 * Original implementation.
1313 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1316 *****************************************************************************/
1318 static void NC_DrawCaption95(
1331 hPrevPen = SelectObject( hdc, SYSCOLOR_GetPen(
1332 ((exStyle & (WS_EX_STATICEDGE|WS_EX_CLIENTEDGE|
1333 WS_EX_DLGMODALFRAME)) == WS_EX_STATICEDGE) ?
1334 COLOR_WINDOWFRAME : COLOR_3DFACE) );
1335 MoveToEx( hdc, r.left, r.bottom - 1, NULL );
1336 LineTo( hdc, r.right, r.bottom - 1 );
1337 SelectObject( hdc, hPrevPen );
1340 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1341 COLOR_INACTIVECAPTION) );
1343 if ((style & WS_SYSMENU) && !(exStyle & WS_EX_TOOLWINDOW)) {
1344 if (NC_DrawSysButton95 (hwnd, hdc, FALSE))
1345 r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
1348 if (style & WS_SYSMENU)
1352 /* Go get the sysmenu */
1353 hSysMenu = GetSystemMenu(hwnd, FALSE);
1354 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
1356 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1357 NC_DrawCloseButton95 (hwnd, hdc, FALSE,
1358 ((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
1359 r.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
1361 if ((style & WS_MAXIMIZEBOX) || (style & WS_MINIMIZEBOX))
1363 /* In win95 the two buttons are always there */
1364 /* But if the menu item is not in the menu they're disabled*/
1366 NC_DrawMaxButton95( hwnd, hdc, FALSE, (!(style & WS_MAXIMIZEBOX)));
1367 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1369 NC_DrawMinButton95( hwnd, hdc, FALSE, (!(style & WS_MINIMIZEBOX)));
1370 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1374 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) )) {
1375 NONCLIENTMETRICSA nclm;
1376 HFONT hFont, hOldFont;
1377 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1378 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1379 if (exStyle & WS_EX_TOOLWINDOW)
1380 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
1382 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
1383 hOldFont = SelectObject (hdc, hFont);
1384 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1385 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1386 SetBkMode( hdc, TRANSPARENT );
1388 DrawTextA( hdc, buffer, -1, &r,
1389 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
1390 DeleteObject (SelectObject (hdc, hOldFont));
1396 /***********************************************************************
1399 * Paint the non-client area. clip is currently unused.
1401 static void NC_DoNCPaint( HWND hwnd, HRGN clip, BOOL suppress_menupaint )
1407 DWORD dwStyle, dwExStyle;
1409 RECT rectClient, rectWindow;
1412 if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return;
1413 has_menu = HAS_MENU(wndPtr);
1414 dwStyle = wndPtr->dwStyle;
1415 dwExStyle = wndPtr->dwExStyle;
1416 flags = wndPtr->flags;
1417 rectClient = wndPtr->rectClient;
1418 rectWindow = wndPtr->rectWindow;
1419 WIN_ReleasePtr( wndPtr );
1421 if ( dwStyle & WS_MINIMIZE ||
1422 !WIN_IsWindowDrawable( hwnd, 0 )) return; /* Nothing to do */
1424 active = flags & WIN_NCACTIVATED;
1426 TRACE("%p %d\n", hwnd, active );
1428 if (!(hdc = GetDCEx( hwnd, (clip > (HRGN)1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1429 ((clip > (HRGN)1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN): 0) ))) return;
1431 if (ExcludeVisRect16( HDC_16(hdc), rectClient.left-rectWindow.left,
1432 rectClient.top-rectWindow.top,
1433 rectClient.right-rectWindow.left,
1434 rectClient.bottom-rectWindow.top )
1437 ReleaseDC( hwnd, hdc );
1441 rect.top = rect.left = 0;
1442 rect.right = rectWindow.right - rectWindow.left;
1443 rect.bottom = rectWindow.bottom - rectWindow.top;
1445 SelectObject( hdc, SYSCOLOR_GetPen(COLOR_WINDOWFRAME) );
1447 if (HAS_ANYFRAME( dwStyle, dwExStyle ))
1449 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1450 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1451 InflateRect( &rect, -1, -1 );
1454 if (HAS_THICKFRAME( dwStyle, dwExStyle ))
1455 NC_DrawFrame(hdc, &rect, FALSE, active );
1456 else if (HAS_DLGFRAME( dwStyle, dwExStyle ))
1457 NC_DrawFrame( hdc, &rect, TRUE, active );
1459 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
1462 r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
1463 rect.top += GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYBORDER);
1464 NC_DrawCaption( hdc, &r, hwnd, dwStyle, active );
1470 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU); /* default height */
1471 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint );
1474 /* Draw the scroll-bars */
1476 if (dwStyle & WS_VSCROLL)
1477 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1478 if (dwStyle & WS_HSCROLL)
1479 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1481 /* Draw the "size-box" */
1483 if ((dwStyle & WS_VSCROLL) && (dwStyle & WS_HSCROLL))
1486 if((dwExStyle & WS_EX_LEFTSCROLLBAR) != 0)
1487 r.right = r.left + GetSystemMetrics(SM_CXVSCROLL) + 1;
1489 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1490 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1491 if(wndPtr->dwStyle & WS_BORDER) {
1495 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1498 ReleaseDC( hwnd, hdc );
1502 /******************************************************************************
1504 * void NC_DoNCPaint95(
1507 * BOOL suppress_menupaint )
1509 * Paint the non-client area for Win95 windows. The clip region is
1510 * currently ignored.
1513 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1514 * misc/tweak.c controls/menu.c # :-)
1517 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1518 * Original implementation
1519 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1521 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1522 * Streamlined window style checks.
1524 *****************************************************************************/
1526 static void NC_DoNCPaint95(
1529 BOOL suppress_menupaint )
1532 RECT rfuzz, rect, rectClip;
1535 DWORD dwStyle, dwExStyle;
1537 RECT rectClient, rectWindow;
1540 if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return;
1541 has_menu = HAS_MENU(wndPtr);
1542 dwStyle = wndPtr->dwStyle;
1543 dwExStyle = wndPtr->dwExStyle;
1544 flags = wndPtr->flags;
1545 rectClient = wndPtr->rectClient;
1546 rectWindow = wndPtr->rectWindow;
1547 WIN_ReleasePtr( wndPtr );
1549 if ( dwStyle & WS_MINIMIZE ||
1550 !WIN_IsWindowDrawable( hwnd, 0 )) return; /* Nothing to do */
1552 active = flags & WIN_NCACTIVATED;
1554 TRACE("%p %d\n", hwnd, active );
1556 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1557 the call to GetDCEx implying that it is allowed not to use it either.
1558 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1559 will cause clipRgn to be deleted after ReleaseDC().
1560 Now, how is the "system" supposed to tell what happened?
1563 if (!(hdc = GetDCEx( hwnd, (clip > (HRGN)1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1564 ((clip > (HRGN)1) ?(DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0) ))) return;
1567 if (ExcludeVisRect16( HDC_16(hdc), rectClient.left-rectWindow.left,
1568 rectClient.top-rectWindow.top,
1569 rectClient.right-rectWindow.left,
1570 rectClient.bottom-rectWindow.top )
1573 ReleaseDC( hwnd, hdc );
1577 rect.top = rect.left = 0;
1578 rect.right = rectWindow.right - rectWindow.left;
1579 rect.bottom = rectWindow.bottom - rectWindow.top;
1581 if( clip > (HRGN)1 )
1582 GetRgnBox( clip, &rectClip );
1589 SelectObject( hdc, SYSCOLOR_GetPen(COLOR_WINDOWFRAME) );
1591 if (HAS_STATICOUTERFRAME(dwStyle, dwExStyle)) {
1592 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1594 else if (HAS_BIGFRAME( dwStyle, dwExStyle)) {
1595 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1598 NC_DrawFrame95(hdc, &rect, active, dwStyle, dwExStyle );
1600 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
1603 if (dwExStyle & WS_EX_TOOLWINDOW) {
1604 r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
1605 rect.top += GetSystemMetrics(SM_CYSMCAPTION);
1608 r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
1609 rect.top += GetSystemMetrics(SM_CYCAPTION);
1611 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
1612 NC_DrawCaption95 (hdc, &r, hwnd, dwStyle,
1619 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
1621 TRACE("Calling DrawMenuBar with rect (%ld, %ld)-(%ld, %ld)\n",
1622 r.left, r.top, r.right, r.bottom);
1624 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ) + 1;
1627 TRACE("After MenuBar, rect is (%ld, %ld)-(%ld, %ld).\n",
1628 rect.left, rect.top, rect.right, rect.bottom );
1630 if (dwExStyle & WS_EX_CLIENTEDGE)
1631 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1633 /* Draw the scroll-bars */
1635 if (dwStyle & WS_VSCROLL)
1636 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1637 if (dwStyle & WS_HSCROLL)
1638 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1640 /* Draw the "size-box" */
1641 if ((dwStyle & WS_VSCROLL) && (dwStyle & WS_HSCROLL))
1644 if((dwExStyle & WS_EX_LEFTSCROLLBAR) != 0)
1645 r.right = r.left + GetSystemMetrics(SM_CXVSCROLL) + 1;
1647 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1648 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1649 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1652 ReleaseDC( hwnd, hdc );
1658 /***********************************************************************
1661 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1663 LONG NC_HandleNCPaint( HWND hwnd , HRGN clip)
1665 DWORD dwStyle = GetWindowLongW( hwnd, GWL_STYLE );
1667 if( dwStyle & WS_VISIBLE )
1669 if( dwStyle & WS_MINIMIZE )
1670 WINPOS_RedrawIconTitle( hwnd );
1671 else if (TWEAK_WineLook == WIN31_LOOK)
1672 NC_DoNCPaint( hwnd, clip, FALSE );
1674 NC_DoNCPaint95( hwnd, clip, FALSE );
1680 /***********************************************************************
1681 * NC_HandleNCActivate
1683 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1685 LONG NC_HandleNCActivate( HWND hwnd, WPARAM wParam )
1687 WND* wndPtr = WIN_FindWndPtr( hwnd );
1689 /* Lotus Notes draws menu descriptions in the caption of its main
1690 * window. When it wants to restore original "system" view, it just
1691 * sends WM_NCACTIVATE message to itself. Any optimizations here in
1692 * attempt to minimize redrawings lead to a not restored caption.
1696 if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
1697 else wndPtr->flags &= ~WIN_NCACTIVATED;
1698 WIN_ReleaseWndPtr(wndPtr);
1700 if (IsIconic(hwnd)) WINPOS_RedrawIconTitle( hwnd );
1701 else if (TWEAK_WineLook == WIN31_LOOK)
1702 NC_DoNCPaint( hwnd, (HRGN)1, FALSE );
1704 NC_DoNCPaint95( hwnd, (HRGN)1, FALSE );
1710 /***********************************************************************
1711 * NC_HandleSetCursor
1713 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1715 LONG NC_HandleSetCursor( HWND hwnd, WPARAM wParam, LPARAM lParam )
1717 hwnd = WIN_GetFullHandle( (HWND)wParam );
1719 switch(LOWORD(lParam))
1723 WORD msg = HIWORD( lParam );
1724 if ((msg == WM_LBUTTONDOWN) || (msg == WM_MBUTTONDOWN) ||
1725 (msg == WM_RBUTTONDOWN))
1732 HCURSOR hCursor = (HCURSOR)GetClassLongA(hwnd, GCL_HCURSOR);
1742 return (LONG)SetCursor( LoadCursorA( 0, (LPSTR)IDC_SIZEWE ) );
1746 return (LONG)SetCursor( LoadCursorA( 0, (LPSTR)IDC_SIZENS ) );
1750 return (LONG)SetCursor( LoadCursorA( 0, (LPSTR)IDC_SIZENWSE ) );
1754 return (LONG)SetCursor( LoadCursorA( 0, (LPSTR)IDC_SIZENESW ) );
1757 /* Default cursor: arrow */
1758 return (LONG)SetCursor( LoadCursorA( 0, (LPSTR)IDC_ARROW ) );
1761 /***********************************************************************
1764 void NC_GetSysPopupPos( HWND hwnd, RECT* rect )
1766 if (IsIconic(hwnd)) GetWindowRect( hwnd, rect );
1769 WND *wndPtr = WIN_FindWndPtr( hwnd );
1770 if (!wndPtr) return;
1772 NC_GetInsideRect( hwnd, rect );
1773 OffsetRect( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
1774 if (wndPtr->dwStyle & WS_CHILD)
1775 ClientToScreen( GetParent(hwnd), (POINT *)rect );
1776 if (TWEAK_WineLook == WIN31_LOOK) {
1777 rect->right = rect->left + GetSystemMetrics(SM_CXSIZE);
1778 rect->bottom = rect->top + GetSystemMetrics(SM_CYSIZE);
1781 rect->right = rect->left + GetSystemMetrics(SM_CYCAPTION) - 1;
1782 rect->bottom = rect->top + GetSystemMetrics(SM_CYCAPTION) - 1;
1784 WIN_ReleaseWndPtr( wndPtr );
1788 /***********************************************************************
1789 * NC_TrackMinMaxBox95
1791 * Track a mouse button press on the minimize or maximize box.
1793 * The big difference between 3.1 and 95 is the disabled button state.
1794 * In win95 the system button can be disabled, so it can ignore the mouse
1798 static void NC_TrackMinMaxBox95( HWND hwnd, WORD wParam )
1801 HDC hdc = GetWindowDC( hwnd );
1802 BOOL pressed = TRUE;
1804 DWORD wndStyle = GetWindowLongA( hwnd, GWL_STYLE);
1805 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
1807 void (*paintButton)(HWND, HDC, BOOL, BOOL);
1809 if (wParam == HTMINBUTTON)
1811 /* If the style is not present, do nothing */
1812 if (!(wndStyle & WS_MINIMIZEBOX))
1815 /* Check if the sysmenu item for minimize is there */
1816 state = GetMenuState(hSysMenu, SC_MINIMIZE, MF_BYCOMMAND);
1818 paintButton = &NC_DrawMinButton95;
1822 /* If the style is not present, do nothing */
1823 if (!(wndStyle & WS_MAXIMIZEBOX))
1826 /* Check if the sysmenu item for maximize is there */
1827 state = GetMenuState(hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
1829 paintButton = &NC_DrawMaxButton95;
1834 (*paintButton)( hwnd, hdc, TRUE, FALSE);
1838 BOOL oldstate = pressed;
1840 if (!GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST )) break;
1841 if (CallMsgFilterW( &msg, MSGF_MAX )) continue;
1843 if(msg.message == WM_LBUTTONUP)
1846 if(msg.message != WM_MOUSEMOVE)
1849 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
1850 if (pressed != oldstate)
1851 (*paintButton)( hwnd, hdc, pressed, FALSE);
1855 (*paintButton)(hwnd, hdc, FALSE, FALSE);
1858 ReleaseDC( hwnd, hdc );
1860 /* If the item minimize or maximize of the sysmenu are not there */
1861 /* or if the style is not present, do nothing */
1862 if ((!pressed) || (state == 0xFFFFFFFF))
1865 if (wParam == HTMINBUTTON)
1866 SendMessageA( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
1868 SendMessageA( hwnd, WM_SYSCOMMAND,
1869 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
1872 /***********************************************************************
1875 * Track a mouse button press on the minimize or maximize box.
1877 static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
1880 HDC hdc = GetWindowDC( hwnd );
1881 BOOL pressed = TRUE;
1882 void (*paintButton)(HWND, HDC, BOOL);
1886 if (wParam == HTMINBUTTON)
1887 paintButton = &NC_DrawMinButton;
1889 paintButton = &NC_DrawMaxButton;
1891 (*paintButton)( hwnd, hdc, TRUE);
1895 BOOL oldstate = pressed;
1897 if (!GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST )) break;
1898 if (CallMsgFilterW( &msg, MSGF_MAX )) continue;
1900 if(msg.message == WM_LBUTTONUP)
1903 if(msg.message != WM_MOUSEMOVE)
1906 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
1907 if (pressed != oldstate)
1908 (*paintButton)( hwnd, hdc, pressed);
1912 (*paintButton)( hwnd, hdc, FALSE);
1915 ReleaseDC( hwnd, hdc );
1917 if (!pressed) return;
1919 if (wParam == HTMINBUTTON)
1920 SendMessageA( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
1922 SendMessageA( hwnd, WM_SYSCOMMAND,
1923 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
1927 /***********************************************************************
1928 * NC_TrackCloseButton95
1930 * Track a mouse button press on the Win95 close button.
1933 NC_TrackCloseButton95 (HWND hwnd, WORD wParam)
1937 BOOL pressed = TRUE;
1938 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
1944 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
1946 /* If the item close of the sysmenu is disabled or not there do nothing */
1947 if((state & MF_DISABLED) || (state & MF_GRAYED) || (state == 0xFFFFFFFF))
1950 hdc = GetWindowDC( hwnd );
1954 NC_DrawCloseButton95 (hwnd, hdc, TRUE, FALSE);
1958 BOOL oldstate = pressed;
1960 if (!GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST )) break;
1961 if (CallMsgFilterW( &msg, MSGF_MAX )) continue;
1963 if(msg.message == WM_LBUTTONUP)
1966 if(msg.message != WM_MOUSEMOVE)
1969 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
1970 if (pressed != oldstate)
1971 NC_DrawCloseButton95 (hwnd, hdc, pressed, FALSE);
1975 NC_DrawCloseButton95 (hwnd, hdc, FALSE, FALSE);
1978 ReleaseDC( hwnd, hdc );
1979 if (!pressed) return;
1981 SendMessageA( hwnd, WM_SYSCOMMAND, SC_CLOSE, MAKELONG(msg.pt.x,msg.pt.y) );
1985 /***********************************************************************
1988 * Track a mouse button press on the horizontal or vertical scroll-bar.
1990 static void NC_TrackScrollBar( HWND hwnd, WPARAM wParam, POINT pt )
1994 if ((wParam & 0xfff0) == SC_HSCROLL)
1996 if ((wParam & 0x0f) != HTHSCROLL) return;
1997 scrollbar = SB_HORZ;
1999 else /* SC_VSCROLL */
2001 if ((wParam & 0x0f) != HTVSCROLL) return;
2002 scrollbar = SB_VERT;
2004 SCROLL_TrackScrollBar( hwnd, scrollbar, pt );
2008 /***********************************************************************
2009 * NC_HandleNCLButtonDown
2011 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2013 LONG NC_HandleNCLButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam )
2015 LONG style = GetWindowLongA( hwnd, GWL_STYLE );
2017 switch(wParam) /* Hit test */
2021 HWND top = GetAncestor( hwnd, GA_ROOT );
2023 if (FOCUS_MouseActivate( top ) || (GetActiveWindow() == top))
2024 SendMessageW( hwnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
2029 if( style & WS_SYSMENU )
2031 if( !(style & WS_MINIMIZE) )
2033 HDC hDC = GetWindowDC(hwnd);
2034 if (TWEAK_WineLook == WIN31_LOOK)
2035 NC_DrawSysButton( hwnd, hDC, TRUE );
2037 NC_DrawSysButton95( hwnd, hDC, TRUE );
2038 ReleaseDC( hwnd, hDC );
2040 SendMessageW( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
2045 SendMessageW( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam );
2049 SendMessageW( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
2053 SendMessageW( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
2058 if (TWEAK_WineLook == WIN31_LOOK)
2059 NC_TrackMinMaxBox( hwnd, wParam );
2061 NC_TrackMinMaxBox95( hwnd, wParam );
2065 if (TWEAK_WineLook >= WIN95_LOOK)
2066 NC_TrackCloseButton95 (hwnd, wParam);
2078 * "make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU"
2079 * This was previously done by setting wParam=SC_SIZE + wParam - 2
2081 /* But that is not what WinNT does. Instead it sends this. This
2082 * is easy to differentiate from HTSYSMENU, because HTSYSMENU adds
2083 * SC_MOUSEMENU into wParam.
2085 SendMessageW( hwnd, WM_SYSCOMMAND, SC_SIZE + wParam - (HTLEFT-WMSZ_LEFT), lParam);
2095 /***********************************************************************
2096 * NC_HandleNCLButtonDblClk
2098 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2100 LONG NC_HandleNCLButtonDblClk( HWND hwnd, WPARAM wParam, LPARAM lParam )
2103 * if this is an icon, send a restore since we are handling
2108 SendMessageW( hwnd, WM_SYSCOMMAND, SC_RESTORE, lParam );
2112 switch(wParam) /* Hit test */
2115 /* stop processing if WS_MAXIMIZEBOX is missing */
2116 if (GetWindowLongA( hwnd, GWL_STYLE ) & WS_MAXIMIZEBOX)
2117 SendMessageW( hwnd, WM_SYSCOMMAND,
2118 IsZoomed(hwnd) ? SC_RESTORE : SC_MAXIMIZE, lParam );
2122 if (!(GetClassLongW(hwnd, GCL_STYLE) & CS_NOCLOSE))
2123 SendMessageW( hwnd, WM_SYSCOMMAND, SC_CLOSE, lParam );
2127 SendMessageW( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
2131 SendMessageW( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
2138 /***********************************************************************
2139 * NC_HandleSysCommand
2141 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2143 LONG NC_HandleSysCommand( HWND hwnd, WPARAM wParam, LPARAM lParam )
2145 TRACE("Handling WM_SYSCOMMAND %x %lx\n", wParam, lParam );
2147 switch (wParam & 0xfff0)
2151 if (USER_Driver.pSysCommandSizeMove)
2152 USER_Driver.pSysCommandSizeMove( hwnd, wParam );
2156 if (hwnd == GetForegroundWindow())
2157 ShowOwnedPopups(hwnd,FALSE);
2158 ShowWindow( hwnd, SW_MINIMIZE );
2162 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2163 ShowOwnedPopups(hwnd,TRUE);
2164 ShowWindow( hwnd, SW_MAXIMIZE );
2168 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2169 ShowOwnedPopups(hwnd,TRUE);
2170 ShowWindow( hwnd, SW_RESTORE );
2174 return SendMessageA( hwnd, WM_CLOSE, 0, 0 );
2180 pt.x = (short)LOWORD(lParam);
2181 pt.y = (short)HIWORD(lParam);
2182 NC_TrackScrollBar( hwnd, wParam, pt );
2189 pt.x = (short)LOWORD(lParam);
2190 pt.y = (short)HIWORD(lParam);
2191 MENU_TrackMouseMenuBar( hwnd, wParam & 0x000F, pt );
2196 MENU_TrackKbdMenuBar( hwnd, wParam, (WCHAR)lParam );
2200 WinExec( "taskman.exe", SW_SHOWNORMAL );
2204 if (wParam == SC_ABOUTWINE)
2206 HMODULE hmodule = LoadLibraryA( "shell32.dll" );
2209 FARPROC aboutproc = GetProcAddress( hmodule, "ShellAboutA" );
2210 if (aboutproc) aboutproc( hwnd, PACKAGE_NAME, PACKAGE_STRING, 0 );
2211 FreeLibrary( hmodule );
2215 if (wParam == SC_PUTMARK)
2216 TRACE_(shell)("Mark requested by user\n");
2223 FIXME("unimplemented!\n");
2229 /*************************************************************
2232 * Stub for the grayed button of the caption
2234 *************************************************************/
2236 BOOL NC_DrawGrayButton(HDC hdc, int x, int y)
2242 hMaskBmp = CreateBitmap (12, 10, 1, 1, lpGrayMask);
2247 hdcMask = CreateCompatibleDC (0);
2248 SelectObject (hdcMask, hMaskBmp);
2250 /* Draw the grayed bitmap using the mask */
2251 hOldBrush = SelectObject (hdc, (HGDIOBJ)RGB(128, 128, 128));
2252 BitBlt (hdc, x, y, 12, 10,
2253 hdcMask, 0, 0, 0xB8074A);
2256 SelectObject (hdc, hOldBrush);
2257 DeleteObject(hMaskBmp);
2263 /***********************************************************************
2264 * GetTitleBarInfo (USER32.@)
2265 * TODO: Handle STATE_SYSTEM_PRESSED
2267 BOOL WINAPI GetTitleBarInfo(HWND hwnd, PTITLEBARINFO tbi) {
2272 TRACE("(%p %p)\n", hwnd, tbi);
2274 if(tbi->cbSize != sizeof(TITLEBARINFO)) {
2275 TRACE("Invalid TITLEBARINFO size: %ld\n", tbi->cbSize);
2276 SetLastError(ERROR_INVALID_PARAMETER);
2279 dwStyle = GetWindowLongW(hwnd, GWL_STYLE);
2280 dwExStyle = GetWindowLongW(hwnd, GWL_EXSTYLE);
2281 NC_GetInsideRect(hwnd, &tbi->rcTitleBar);
2283 GetWindowRect(hwnd, &wndRect);
2285 tbi->rcTitleBar.top += wndRect.top;
2286 tbi->rcTitleBar.left += wndRect.left;
2287 tbi->rcTitleBar.right += wndRect.left;
2289 tbi->rcTitleBar.bottom = tbi->rcTitleBar.top;
2290 if(dwExStyle & WS_EX_TOOLWINDOW)
2291 tbi->rcTitleBar.bottom += GetSystemMetrics(SM_CYSMCAPTION);
2293 tbi->rcTitleBar.bottom += GetSystemMetrics(SM_CYCAPTION);
2294 tbi->rcTitleBar.left += GetSystemMetrics(SM_CXSIZE);
2297 ZeroMemory(&tbi->rgstate, sizeof(tbi->rgstate));
2298 /* Does the title bar always have STATE_SYSTEM_FOCUSABLE?
2299 * Under XP it seems to
2301 tbi->rgstate[0] = STATE_SYSTEM_FOCUSABLE;
2302 if(dwStyle & WS_CAPTION) {
2303 tbi->rgstate[1] = STATE_SYSTEM_INVISIBLE;
2304 if(dwStyle & WS_SYSMENU) {
2305 if(!(dwStyle & (WS_MINIMIZEBOX|WS_MAXIMIZEBOX))) {
2306 tbi->rgstate[2] = STATE_SYSTEM_INVISIBLE;
2307 tbi->rgstate[3] = STATE_SYSTEM_INVISIBLE;
2310 if(!(dwStyle & WS_MINIMIZEBOX))
2311 tbi->rgstate[2] = STATE_SYSTEM_UNAVAILABLE;
2312 if(!(dwStyle & WS_MAXIMIZEBOX))
2313 tbi->rgstate[3] = STATE_SYSTEM_UNAVAILABLE;
2315 if(!(dwExStyle & WS_EX_CONTEXTHELP))
2316 tbi->rgstate[4] = STATE_SYSTEM_INVISIBLE;
2317 if(GetClassLongW(hwnd, GCL_STYLE) & CS_NOCLOSE)
2318 tbi->rgstate[5] = STATE_SYSTEM_UNAVAILABLE;
2321 tbi->rgstate[2] = STATE_SYSTEM_INVISIBLE;
2322 tbi->rgstate[3] = STATE_SYSTEM_INVISIBLE;
2323 tbi->rgstate[4] = STATE_SYSTEM_INVISIBLE;
2324 tbi->rgstate[5] = STATE_SYSTEM_INVISIBLE;
2328 tbi->rgstate[0] |= STATE_SYSTEM_INVISIBLE;