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