2 * Non-client area window functions
4 * Copyright 1994 Alexandre Julliard
11 #include "sysmetrics.h"
15 #include "cursoricon.h"
21 #include "nonclient.h"
23 #include "selectors.h"
30 DECLARE_DEBUG_CHANNEL(nonclient)
31 DECLARE_DEBUG_CHANNEL(shell)
33 static HBITMAP16 hbitmapClose = 0;
34 static HBITMAP16 hbitmapCloseD = 0;
35 static HBITMAP16 hbitmapMinimize = 0;
36 static HBITMAP16 hbitmapMinimizeD = 0;
37 static HBITMAP16 hbitmapMaximize = 0;
38 static HBITMAP16 hbitmapMaximizeD = 0;
39 static HBITMAP16 hbitmapRestore = 0;
40 static HBITMAP16 hbitmapRestoreD = 0;
42 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
43 #define SC_PUTMARK (SC_SCREENSAVE+2)
45 /* Some useful macros */
46 #define HAS_DLGFRAME(style,exStyle) \
47 (((exStyle) & WS_EX_DLGMODALFRAME) || \
48 (((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
50 #define HAS_THICKFRAME(style) \
51 (((style) & WS_THICKFRAME) && \
52 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
54 #define HAS_FIXEDFRAME(style,exStyle) \
55 (((((exStyle) & WS_EX_DLGMODALFRAME) || \
56 ((style) & WS_DLGFRAME)) && ((style) & WS_BORDER)) && \
57 !((style) & WS_THICKFRAME))
59 #define HAS_SIZEFRAME(style) \
60 (((style) & WS_THICKFRAME) && \
61 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
63 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
65 #define ON_LEFT_BORDER(hit) \
66 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
67 #define ON_RIGHT_BORDER(hit) \
68 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
69 #define ON_TOP_BORDER(hit) \
70 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
71 #define ON_BOTTOM_BORDER(hit) \
72 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
74 /***********************************************************************
77 * Compute the size of the window rectangle from the size of the
80 static void NC_AdjustRect( LPRECT16 rect, DWORD style, BOOL menu,
83 if (TWEAK_WineLook > WIN31_LOOK)
84 ERR(nonclient, "Called in Win95 mode. Aiee! Please report this.\n" );
86 if(style & WS_ICONIC) return;
87 /* Decide if the window will be managed (see CreateWindowEx) */
88 if (!(Options.managed && !(style & WS_CHILD) &&
89 ((style & (WS_DLGFRAME | WS_THICKFRAME)) ||
90 (exStyle & WS_EX_DLGMODALFRAME))))
92 if (HAS_DLGFRAME( style, exStyle ))
93 InflateRect16(rect, SYSMETRICS_CXDLGFRAME, SYSMETRICS_CYDLGFRAME );
96 if (HAS_THICKFRAME(style))
97 InflateRect16( rect, SYSMETRICS_CXFRAME, SYSMETRICS_CYFRAME );
98 if (style & WS_BORDER)
99 InflateRect16( rect, SYSMETRICS_CXBORDER, SYSMETRICS_CYBORDER);
102 if ((style & WS_CAPTION) == WS_CAPTION)
103 rect->top -= SYSMETRICS_CYCAPTION - SYSMETRICS_CYBORDER;
105 if (menu) rect->top -= SYSMETRICS_CYMENU + SYSMETRICS_CYBORDER;
107 if (style & WS_VSCROLL) {
108 rect->right += SYSMETRICS_CXVSCROLL - 1;
109 if(!(style & WS_BORDER))
113 if (style & WS_HSCROLL) {
114 rect->bottom += SYSMETRICS_CYHSCROLL - 1;
115 if(!(style & WS_BORDER))
121 /******************************************************************************
122 * NC_AdjustRectOuter95
124 * Computes the size of the "outside" parts of the window based on the
125 * parameters of the client area.
134 * "Outer" parts of a window means the whole window frame, caption and
135 * menu bar. It does not include "inner" parts of the frame like client
136 * edge, static edge or scroll bars.
139 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
140 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
142 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
143 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
144 * NC_AdjustRectInner95 and added handling of Win95 styles.
146 *****************************************************************************/
149 NC_AdjustRectOuter95 (LPRECT16 rect, DWORD style, BOOL menu, DWORD exStyle)
151 if(style & WS_ICONIC) return;
153 /* Decide if the window will be managed (see CreateWindowEx) */
154 if (!(Options.managed && !(style & WS_CHILD) &&
155 ((style & (WS_DLGFRAME | WS_THICKFRAME)) ||
156 (exStyle & WS_EX_DLGMODALFRAME))))
158 if (HAS_FIXEDFRAME( style, exStyle ))
159 InflateRect16(rect, SYSMETRICS_CXDLGFRAME, SYSMETRICS_CYDLGFRAME );
162 if (HAS_SIZEFRAME(style))
163 InflateRect16( rect, SYSMETRICS_CXFRAME, SYSMETRICS_CYFRAME );
165 if (style & WS_BORDER)
166 InflateRect16( rect, SYSMETRICS_CXBORDER, SYSMETRICS_CYBORDER);
170 if ((style & WS_CAPTION) == WS_CAPTION)
172 if (exStyle & WS_EX_TOOLWINDOW)
173 rect->top -= SYSMETRICS_CYSMCAPTION;
175 rect->top -= SYSMETRICS_CYCAPTION;
180 rect->top -= sysMetrics[SM_CYMENU];
184 /******************************************************************************
185 * NC_AdjustRectInner95
187 * Computes the size of the "inside" part of the window based on the
188 * parameters of the client area.
196 * "Inner" part of a window means the window frame inside of the flat
197 * window frame. It includes the client edge, the static edge and the
201 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
202 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
204 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
205 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
206 * NC_AdjustRectInner95 and added handling of Win95 styles.
208 *****************************************************************************/
211 NC_AdjustRectInner95 (LPRECT16 rect, DWORD style, DWORD exStyle)
213 if(style & WS_ICONIC) return;
215 if (exStyle & WS_EX_CLIENTEDGE)
216 InflateRect16 (rect, sysMetrics[SM_CXEDGE], sysMetrics[SM_CYEDGE]);
218 if (exStyle & WS_EX_STATICEDGE)
219 InflateRect16 (rect, sysMetrics[SM_CXBORDER], sysMetrics[SM_CYBORDER]);
221 if (style & WS_VSCROLL) rect->right += SYSMETRICS_CXVSCROLL;
222 if (style & WS_HSCROLL) rect->bottom += SYSMETRICS_CYHSCROLL;
226 /***********************************************************************
227 * DrawCaption16 [USER.660] Draws a caption bar
241 DrawCaption16 (HWND16 hwnd, HDC16 hdc, const RECT16 *rect, UINT16 uFlags)
246 CONV_RECT16TO32 (rect, &rect32);
248 return (BOOL16)DrawCaptionTempA (hwnd, hdc, rect ? &rect32 : NULL,
249 0, 0, NULL, uFlags & 0x1F);
253 /***********************************************************************
254 * DrawCaption32 [USER32.154] Draws a caption bar
268 DrawCaption (HWND hwnd, HDC hdc, const RECT *lpRect, UINT uFlags)
270 return DrawCaptionTempA (hwnd, hdc, lpRect, 0, 0, NULL, uFlags & 0x1F);
274 /***********************************************************************
275 * DrawCaptionTemp16 [USER.657]
285 DrawCaptionTemp16 (HWND16 hwnd, HDC16 hdc, const RECT16 *rect, HFONT16 hFont,
286 HICON16 hIcon, LPCSTR str, UINT16 uFlags)
291 CONV_RECT16TO32(rect,&rect32);
293 return (BOOL16)DrawCaptionTempA (hwnd, hdc, rect?&rect32:NULL, hFont,
294 hIcon, str, uFlags & 0x1F);
298 /***********************************************************************
299 * DrawCaptionTemp32A [USER32.599]
309 DrawCaptionTempA (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
310 HICON hIcon, LPCSTR str, UINT uFlags)
314 TRACE (nonclient, "(%08x,%08x,%p,%08x,%08x,\"%s\",%08x)\n",
315 hwnd, hdc, rect, hFont, hIcon, str, uFlags);
317 /* drawing background */
318 if (uFlags & DC_INBUTTON) {
319 FillRect (hdc, &rc, GetSysColorBrush (COLOR_3DFACE));
321 if (uFlags & DC_ACTIVE) {
322 HBRUSH hbr = SelectObject (hdc, CACHE_GetPattern55AABrush ());
323 PatBlt (hdc, rc.left, rc.top,
324 rc.right-rc.left, rc.bottom-rc.top, 0xFA0089);
325 SelectObject (hdc, hbr);
329 FillRect (hdc, &rc, GetSysColorBrush ((uFlags & DC_ACTIVE) ?
330 COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
335 if ((uFlags & DC_ICON) && !(uFlags & DC_SMALLCAP)) {
339 pt.y = (rc.bottom + rc.top - sysMetrics[SM_CYSMICON]) / 2;
342 DrawIconEx (hdc, pt.x, pt.y, hIcon, sysMetrics[SM_CXSMICON],
343 sysMetrics[SM_CYSMICON], 0, 0, DI_NORMAL);
346 WND *wndPtr = WIN_FindWndPtr(hwnd);
349 if (wndPtr->class->hIconSm)
350 hAppIcon = wndPtr->class->hIconSm;
351 else if (wndPtr->class->hIcon)
352 hAppIcon = wndPtr->class->hIcon;
354 DrawIconEx (hdc, pt.x, pt.y, hAppIcon, sysMetrics[SM_CXSMICON],
355 sysMetrics[SM_CYSMICON], 0, 0, DI_NORMAL);
356 WIN_ReleaseWndPtr(wndPtr);
359 rc.left += (rc.bottom - rc.top);
363 if (uFlags & DC_TEXT) {
366 if (uFlags & DC_INBUTTON)
367 SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
368 else if (uFlags & DC_ACTIVE)
369 SetTextColor (hdc, GetSysColor (COLOR_CAPTIONTEXT));
371 SetTextColor (hdc, GetSysColor (COLOR_INACTIVECAPTIONTEXT));
373 SetBkMode (hdc, TRANSPARENT);
376 hOldFont = SelectObject (hdc, hFont);
378 NONCLIENTMETRICSA nclm;
380 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
381 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
382 hNewFont = CreateFontIndirectA ((uFlags & DC_SMALLCAP) ?
383 &nclm.lfSmCaptionFont : &nclm.lfCaptionFont);
384 hOldFont = SelectObject (hdc, hNewFont);
388 DrawTextA (hdc, str, -1, &rc,
389 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
393 nLen = GetWindowTextA (hwnd, szText, 128);
394 DrawTextA (hdc, szText, nLen, &rc,
395 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
399 SelectObject (hdc, hOldFont);
401 DeleteObject (SelectObject (hdc, hOldFont));
404 /* drawing focus ??? */
406 FIXME (nonclient, "undocumented flag (0x2000)!\n");
412 /***********************************************************************
413 * DrawCaptionTemp32W [USER32.602]
423 DrawCaptionTempW (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
424 HICON hIcon, LPCWSTR str, UINT uFlags)
426 LPSTR p = HEAP_strdupWtoA (GetProcessHeap (), 0, str);
427 BOOL res = DrawCaptionTempA (hwnd, hdc, rect, hFont, hIcon, p, uFlags);
428 HeapFree (GetProcessHeap (), 0, p);
433 /***********************************************************************
434 * AdjustWindowRect16 (USER.102)
436 BOOL16 WINAPI AdjustWindowRect16( LPRECT16 rect, DWORD style, BOOL16 menu )
438 return AdjustWindowRectEx16( rect, style, menu, 0 );
442 /***********************************************************************
443 * AdjustWindowRect32 (USER32.2)
445 BOOL WINAPI AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu )
447 return AdjustWindowRectEx( rect, style, menu, 0 );
451 /***********************************************************************
452 * AdjustWindowRectEx16 (USER.454)
454 BOOL16 WINAPI AdjustWindowRectEx16( LPRECT16 rect, DWORD style,
455 BOOL16 menu, DWORD exStyle )
457 /* Correct the window style */
459 if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
461 style &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD);
462 exStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE |
463 WS_EX_STATICEDGE | WS_EX_TOOLWINDOW);
464 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
466 TRACE(nonclient, "(%d,%d)-(%d,%d) %08lx %d %08lx\n",
467 rect->left, rect->top, rect->right, rect->bottom,
468 style, menu, exStyle );
470 if (TWEAK_WineLook == WIN31_LOOK)
471 NC_AdjustRect( rect, style, menu, exStyle );
473 NC_AdjustRectOuter95( rect, style, menu, exStyle );
474 NC_AdjustRectInner95( rect, style, exStyle );
481 /***********************************************************************
482 * AdjustWindowRectEx32 (USER32.3)
484 BOOL WINAPI AdjustWindowRectEx( LPRECT rect, DWORD style,
485 BOOL menu, DWORD exStyle )
490 CONV_RECT32TO16( rect, &rect16 );
491 ret = AdjustWindowRectEx16( &rect16, style, (BOOL16)menu, exStyle );
492 CONV_RECT16TO32( &rect16, rect );
497 /***********************************************************************
498 * NC_HandleNCCalcSize
500 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
502 LONG NC_HandleNCCalcSize( WND *pWnd, RECT *winRect )
504 RECT16 tmpRect = { 0, 0, 0, 0 };
507 if (pWnd->class->style & CS_VREDRAW) result |= WVR_VREDRAW;
508 if (pWnd->class->style & CS_HREDRAW) result |= WVR_HREDRAW;
510 if( !( pWnd->dwStyle & WS_MINIMIZE ) ) {
511 if (TWEAK_WineLook == WIN31_LOOK)
512 NC_AdjustRect( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
514 NC_AdjustRectOuter95( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
516 winRect->left -= tmpRect.left;
517 winRect->top -= tmpRect.top;
518 winRect->right -= tmpRect.right;
519 winRect->bottom -= tmpRect.bottom;
521 if (HAS_MENU(pWnd)) {
522 TRACE(nonclient, "Calling "
523 "GetMenuBarHeight with HWND 0x%x, width %d, "
524 "at (%d, %d).\n", pWnd->hwndSelf,
525 winRect->right - winRect->left,
526 -tmpRect.left, -tmpRect.top );
529 MENU_GetMenuBarHeight( pWnd->hwndSelf,
530 winRect->right - winRect->left,
531 -tmpRect.left, -tmpRect.top ) + 1;
534 if (TWEAK_WineLook > WIN31_LOOK) {
535 SetRect16 (&tmpRect, 0, 0, 0, 0);
536 NC_AdjustRectInner95 (&tmpRect, pWnd->dwStyle, pWnd->dwExStyle);
537 winRect->left -= tmpRect.left;
538 winRect->top -= tmpRect.top;
539 winRect->right -= tmpRect.right;
540 winRect->bottom -= tmpRect.bottom;
547 /***********************************************************************
550 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
551 * but without the borders (if any).
552 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
554 static void NC_GetInsideRect( HWND hwnd, RECT *rect )
556 WND * wndPtr = WIN_FindWndPtr( hwnd );
558 rect->top = rect->left = 0;
559 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
560 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
562 if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) goto END;
564 /* Remove frame from rectangle */
565 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
567 InflateRect( rect, -SYSMETRICS_CXDLGFRAME, -SYSMETRICS_CYDLGFRAME);
568 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
569 InflateRect( rect, -1, 0 );
573 if (HAS_THICKFRAME( wndPtr->dwStyle ))
574 InflateRect( rect, -SYSMETRICS_CXFRAME, -SYSMETRICS_CYFRAME );
575 if (wndPtr->dwStyle & WS_BORDER)
576 InflateRect( rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER );
579 WIN_ReleaseWndPtr(wndPtr);
584 /***********************************************************************
587 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
588 * but without the borders (if any).
589 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
593 NC_GetInsideRect95 (HWND hwnd, RECT *rect)
595 WND * wndPtr = WIN_FindWndPtr( hwnd );
597 rect->top = rect->left = 0;
598 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
599 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
601 if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) goto END;
603 /* Remove frame from rectangle */
604 if (HAS_FIXEDFRAME (wndPtr->dwStyle, wndPtr->dwExStyle ))
606 InflateRect( rect, -SYSMETRICS_CXFIXEDFRAME, -SYSMETRICS_CYFIXEDFRAME);
608 else if (HAS_SIZEFRAME (wndPtr->dwStyle))
610 InflateRect( rect, -SYSMETRICS_CXSIZEFRAME, -SYSMETRICS_CYSIZEFRAME );
612 /* if (wndPtr->dwStyle & WS_BORDER)
613 InflateRect32( rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER );*/
616 if (wndPtr->dwStyle & WS_CHILD) {
617 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
618 InflateRect (rect, -SYSMETRICS_CXEDGE, -SYSMETRICS_CYEDGE);
620 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
621 InflateRect (rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER);
624 WIN_ReleaseWndPtr(wndPtr);
629 /***********************************************************************
632 * Handle a WM_NCHITTEST message. Called from NC_HandleNcHitTest().
635 LONG NC_DoNCHitTest (WND *wndPtr, POINT16 pt )
639 TRACE(nonclient, "hwnd=%04x pt=%d,%d\n",
640 wndPtr->hwndSelf, pt.x, pt.y );
642 GetWindowRect16 (wndPtr->hwndSelf, &rect );
643 if (!PtInRect16( &rect, pt )) return HTNOWHERE;
645 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
647 if (!(wndPtr->flags & WIN_MANAGED))
650 if (HAS_THICKFRAME( wndPtr->dwStyle ))
652 InflateRect16( &rect, -SYSMETRICS_CXFRAME, -SYSMETRICS_CYFRAME );
653 if (wndPtr->dwStyle & WS_BORDER)
654 InflateRect16(&rect,-SYSMETRICS_CXBORDER,-SYSMETRICS_CYBORDER);
655 if (!PtInRect16( &rect, pt ))
657 /* Check top sizing border */
660 if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTTOPLEFT;
661 if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTTOPRIGHT;
664 /* Check bottom sizing border */
665 if (pt.y >= rect.bottom)
667 if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTBOTTOMLEFT;
668 if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTBOTTOMRIGHT;
671 /* Check left sizing border */
672 if (pt.x < rect.left)
674 if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPLEFT;
675 if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMLEFT;
678 /* Check right sizing border */
679 if (pt.x >= rect.right)
681 if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPRIGHT;
682 if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMRIGHT;
687 else /* No thick frame */
689 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
690 InflateRect16(&rect, -SYSMETRICS_CXDLGFRAME, -SYSMETRICS_CYDLGFRAME);
691 else if (wndPtr->dwStyle & WS_BORDER)
692 InflateRect16(&rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER);
693 if (!PtInRect16( &rect, pt )) return HTBORDER;
698 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
700 rect.top += sysMetrics[SM_CYCAPTION] - 1;
701 if (!PtInRect16( &rect, pt ))
703 /* Check system menu */
704 if (wndPtr->dwStyle & WS_SYSMENU)
705 rect.left += SYSMETRICS_CXSIZE;
706 if (pt.x <= rect.left) return HTSYSMENU;
707 /* Check maximize box */
708 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
709 rect.right -= SYSMETRICS_CXSIZE + 1;
710 if (pt.x >= rect.right) return HTMAXBUTTON;
711 /* Check minimize box */
712 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
713 rect.right -= SYSMETRICS_CXSIZE + 1;
714 if (pt.x >= rect.right) return HTMINBUTTON;
720 /* Check client area */
722 ScreenToClient16( wndPtr->hwndSelf, &pt );
723 GetClientRect16( wndPtr->hwndSelf, &rect );
724 if (PtInRect16( &rect, pt )) return HTCLIENT;
726 /* Check vertical scroll bar */
728 if (wndPtr->dwStyle & WS_VSCROLL)
730 rect.right += SYSMETRICS_CXVSCROLL;
731 if (PtInRect16( &rect, pt )) return HTVSCROLL;
734 /* Check horizontal scroll bar */
736 if (wndPtr->dwStyle & WS_HSCROLL)
738 rect.bottom += SYSMETRICS_CYHSCROLL;
739 if (PtInRect16( &rect, pt ))
742 if ((wndPtr->dwStyle & WS_VSCROLL) &&
743 (pt.x >= rect.right - SYSMETRICS_CXVSCROLL))
751 if (HAS_MENU(wndPtr))
753 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
757 /* Should never get here */
762 /***********************************************************************
765 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
767 * FIXME: Just a modified copy of the Win 3.1 version.
771 NC_DoNCHitTest95 (WND *wndPtr, POINT16 pt )
775 TRACE(nonclient, "hwnd=%04x pt=%d,%d\n",
776 wndPtr->hwndSelf, pt.x, pt.y );
778 GetWindowRect16 (wndPtr->hwndSelf, &rect );
779 if (!PtInRect16( &rect, pt )) return HTNOWHERE;
781 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
783 if (!(wndPtr->flags & WIN_MANAGED))
786 if (HAS_SIZEFRAME( wndPtr->dwStyle ))
788 InflateRect16( &rect, -SYSMETRICS_CXFRAME, -SYSMETRICS_CYFRAME );
789 /* if (wndPtr->dwStyle & WS_BORDER) */
790 /* InflateRect16(&rect,-SYSMETRICS_CXBORDER,-SYSMETRICS_CYBORDER); */
791 if (!PtInRect16( &rect, pt ))
793 /* Check top sizing border */
796 if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTTOPLEFT;
797 if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTTOPRIGHT;
800 /* Check bottom sizing border */
801 if (pt.y >= rect.bottom)
803 if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTBOTTOMLEFT;
804 if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTBOTTOMRIGHT;
807 /* Check left sizing border */
808 if (pt.x < rect.left)
810 if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPLEFT;
811 if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMLEFT;
814 /* Check right sizing border */
815 if (pt.x >= rect.right)
817 if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPRIGHT;
818 if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMRIGHT;
823 else /* No thick frame */
825 if (HAS_FIXEDFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
826 InflateRect16(&rect, -SYSMETRICS_CXDLGFRAME, -SYSMETRICS_CYDLGFRAME);
827 /* else if (wndPtr->dwStyle & WS_BORDER) */
828 /* InflateRect16(&rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER); */
829 if (!PtInRect16( &rect, pt )) return HTBORDER;
834 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
836 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
837 rect.top += sysMetrics[SM_CYSMCAPTION] - 1;
839 rect.top += sysMetrics[SM_CYCAPTION] - 1;
840 if (!PtInRect16( &rect, pt ))
842 /* Check system menu */
843 if ((wndPtr->dwStyle & WS_SYSMENU) &&
844 ((wndPtr->class->hIconSm) || (wndPtr->class->hIcon)))
845 rect.left += sysMetrics[SM_CYCAPTION] - 1;
846 if (pt.x < rect.left) return HTSYSMENU;
848 /* Check close button */
849 if (wndPtr->dwStyle & WS_SYSMENU)
850 rect.right -= sysMetrics[SM_CYCAPTION] - 1;
851 if (pt.x > rect.right) return HTCLOSE;
853 /* Check maximize box */
854 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
855 rect.right -= SYSMETRICS_CXSIZE + 1;
856 if (pt.x > rect.right) return HTMAXBUTTON;
858 /* Check minimize box */
859 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
860 rect.right -= SYSMETRICS_CXSIZE + 1;
861 if (pt.x > rect.right) return HTMINBUTTON;
867 /* Check client area */
869 ScreenToClient16( wndPtr->hwndSelf, &pt );
870 GetClientRect16( wndPtr->hwndSelf, &rect );
871 if (PtInRect16( &rect, pt )) return HTCLIENT;
873 /* Check vertical scroll bar */
875 if (wndPtr->dwStyle & WS_VSCROLL)
877 rect.right += SYSMETRICS_CXVSCROLL;
878 if (PtInRect16( &rect, pt )) return HTVSCROLL;
881 /* Check horizontal scroll bar */
883 if (wndPtr->dwStyle & WS_HSCROLL)
885 rect.bottom += SYSMETRICS_CYHSCROLL;
886 if (PtInRect16( &rect, pt ))
889 if ((wndPtr->dwStyle & WS_VSCROLL) &&
890 (pt.x >= rect.right - SYSMETRICS_CXVSCROLL))
898 if (HAS_MENU(wndPtr))
900 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
904 /* Should never get here */
909 /***********************************************************************
912 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
915 NC_HandleNCHitTest (HWND hwnd , POINT16 pt)
918 WND *wndPtr = WIN_FindWndPtr (hwnd);
923 if (TWEAK_WineLook == WIN31_LOOK)
924 retvalue = NC_DoNCHitTest (wndPtr, pt);
926 retvalue = NC_DoNCHitTest95 (wndPtr, pt);
927 WIN_ReleaseWndPtr(wndPtr);
932 /***********************************************************************
935 void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down )
940 WND *wndPtr = WIN_FindWndPtr( hwnd );
942 if( !(wndPtr->flags & WIN_MANAGED) )
944 NC_GetInsideRect( hwnd, &rect );
945 hdcMem = CreateCompatibleDC( hdc );
946 hbitmap = SelectObject( hdcMem, hbitmapClose );
947 BitBlt(hdc, rect.left, rect.top, SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE,
948 hdcMem, (wndPtr->dwStyle & WS_CHILD) ? SYSMETRICS_CXSIZE : 0, 0,
949 down ? NOTSRCCOPY : SRCCOPY );
950 SelectObject( hdcMem, hbitmap );
953 WIN_ReleaseWndPtr(wndPtr);
957 /***********************************************************************
960 static void NC_DrawMaxButton( HWND hwnd, HDC16 hdc, BOOL down )
963 WND *wndPtr = WIN_FindWndPtr( hwnd );
966 if( !(wndPtr->flags & WIN_MANAGED) )
968 NC_GetInsideRect( hwnd, &rect );
969 hdcMem = CreateCompatibleDC( hdc );
970 SelectObject( hdcMem, (IsZoomed(hwnd)
971 ? (down ? hbitmapRestoreD : hbitmapRestore)
972 : (down ? hbitmapMaximizeD : hbitmapMaximize)) );
973 BitBlt( hdc, rect.right - SYSMETRICS_CXSIZE - 1, rect.top,
974 SYSMETRICS_CXSIZE + 1, SYSMETRICS_CYSIZE, hdcMem, 0, 0,
978 WIN_ReleaseWndPtr(wndPtr);
983 /***********************************************************************
986 static void NC_DrawMinButton( HWND hwnd, HDC16 hdc, BOOL down )
989 WND *wndPtr = WIN_FindWndPtr( hwnd );
992 if( !(wndPtr->flags & WIN_MANAGED) )
994 NC_GetInsideRect( hwnd, &rect );
995 hdcMem = CreateCompatibleDC( hdc );
996 SelectObject( hdcMem, (down ? hbitmapMinimizeD : hbitmapMinimize) );
997 if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= SYSMETRICS_CXSIZE+1;
998 BitBlt( hdc, rect.right - SYSMETRICS_CXSIZE - 1, rect.top,
999 SYSMETRICS_CXSIZE + 1, SYSMETRICS_CYSIZE, hdcMem, 0, 0,
1003 WIN_ReleaseWndPtr(wndPtr);
1007 /******************************************************************************
1009 * void NC_DrawSysButton95(
1014 * Draws the Win95 system icon.
1017 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1018 * Original implementation from NC_DrawSysButton source.
1019 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1022 *****************************************************************************/
1025 NC_DrawSysButton95 (HWND hwnd, HDC hdc, BOOL down)
1027 WND *wndPtr = WIN_FindWndPtr( hwnd );
1029 if( !(wndPtr->flags & WIN_MANAGED) )
1034 NC_GetInsideRect95( hwnd, &rect );
1036 if (wndPtr->class->hIconSm)
1037 hIcon = wndPtr->class->hIconSm;
1038 else if (wndPtr->class->hIcon)
1039 hIcon = wndPtr->class->hIcon;
1042 DrawIconEx (hdc, rect.left + 2, rect.top + 2, hIcon,
1043 sysMetrics[SM_CXSMICON],
1044 sysMetrics[SM_CYSMICON],
1047 WIN_ReleaseWndPtr(wndPtr);
1048 return (hIcon != 0);
1050 WIN_ReleaseWndPtr(wndPtr);
1055 /******************************************************************************
1057 * void NC_DrawCloseButton95(
1062 * Draws the Win95 close button.
1065 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1066 * Original implementation from NC_DrawSysButton95 source.
1068 *****************************************************************************/
1070 void NC_DrawCloseButton95 (HWND hwnd, HDC hdc, BOOL down)
1074 WND *wndPtr = WIN_FindWndPtr( hwnd );
1076 if( !(wndPtr->flags & WIN_MANAGED) )
1079 HBITMAP hBmp, hOldBmp;
1081 NC_GetInsideRect95( hwnd, &rect );
1083 hdcMem = CreateCompatibleDC( hdc );
1084 hBmp = down ? hbitmapCloseD : hbitmapClose;
1085 hOldBmp = SelectObject (hdcMem, hBmp);
1086 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1087 BitBlt (hdc, rect.right - (sysMetrics[SM_CYCAPTION] + 1 + bmp.bmWidth) / 2,
1088 rect.top + (sysMetrics[SM_CYCAPTION] - 1 - bmp.bmHeight) / 2,
1089 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);
1091 SelectObject (hdcMem, hOldBmp);
1094 WIN_ReleaseWndPtr(wndPtr);
1097 /******************************************************************************
1099 * NC_DrawMaxButton95(
1104 * Draws the maximize button for Win95 style windows.
1107 * Many. Spacing might still be incorrect. Need to fit a close
1108 * button between the max button and the edge.
1109 * Should scale the image with the title bar. And more...
1112 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1113 * Original implementation.
1115 *****************************************************************************/
1117 static void NC_DrawMaxButton95(HWND hwnd,HDC16 hdc,BOOL down )
1121 WND *wndPtr = WIN_FindWndPtr( hwnd );
1123 if( !(wndPtr->flags & WIN_MANAGED))
1126 HBITMAP hBmp,hOldBmp;
1128 NC_GetInsideRect95( hwnd, &rect );
1129 hdcMem = CreateCompatibleDC( hdc );
1130 hBmp = IsZoomed(hwnd) ?
1131 (down ? hbitmapRestoreD : hbitmapRestore ) :
1132 (down ? hbitmapMaximizeD: hbitmapMaximize);
1133 hOldBmp=SelectObject( hdcMem, hBmp );
1134 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1136 if (wndPtr->dwStyle & WS_SYSMENU)
1137 rect.right -= sysMetrics[SM_CYCAPTION] + 1;
1139 BitBlt( hdc, rect.right - (sysMetrics[SM_CXSIZE] + bmp.bmWidth) / 2,
1140 rect.top + (sysMetrics[SM_CYCAPTION] - 1 - bmp.bmHeight) / 2,
1141 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1142 SelectObject (hdcMem, hOldBmp);
1145 WIN_ReleaseWndPtr(wndPtr);
1148 /******************************************************************************
1150 * NC_DrawMinButton95(
1155 * Draws the minimize button for Win95 style windows.
1158 * Many. Spacing is still incorrect. Should scale the image with the
1159 * title bar. And more...
1162 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1163 * Original implementation.
1165 *****************************************************************************/
1167 static void NC_DrawMinButton95(HWND hwnd,HDC16 hdc,BOOL down )
1171 WND *wndPtr = WIN_FindWndPtr( hwnd );
1173 if( !(wndPtr->flags & WIN_MANAGED))
1177 HBITMAP hBmp,hOldBmp;
1179 NC_GetInsideRect95( hwnd, &rect );
1181 hdcMem = CreateCompatibleDC( hdc );
1182 hBmp = down ? hbitmapMinimizeD : hbitmapMinimize;
1183 hOldBmp= SelectObject( hdcMem, hBmp );
1184 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1186 if (wndPtr->dwStyle & WS_SYSMENU)
1187 rect.right -= sysMetrics[SM_CYCAPTION] + 1;
1189 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
1190 rect.right += -1 - (sysMetrics[SM_CXSIZE] + bmp.bmWidth) / 2;
1192 BitBlt( hdc, rect.right - (sysMetrics[SM_CXSIZE] + bmp.bmWidth) / 2,
1193 rect.top + (sysMetrics[SM_CYCAPTION] - 1 - bmp.bmHeight) / 2,
1194 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1196 SelectObject (hdcMem, hOldBmp);
1199 WIN_ReleaseWndPtr(wndPtr);
1202 /***********************************************************************
1205 * Draw a window frame inside the given rectangle, and update the rectangle.
1206 * The correct pen for the frame must be selected in the DC.
1208 static void NC_DrawFrame( HDC hdc, RECT *rect, BOOL dlgFrame,
1213 if (TWEAK_WineLook != WIN31_LOOK)
1214 ERR (nonclient, "Called in Win95 mode. Aiee! Please report this.\n" );
1218 width = SYSMETRICS_CXDLGFRAME - 1;
1219 height = SYSMETRICS_CYDLGFRAME - 1;
1220 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1221 COLOR_INACTIVECAPTION) );
1225 width = SYSMETRICS_CXFRAME - 1;
1226 height = SYSMETRICS_CYFRAME - 1;
1227 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1228 COLOR_INACTIVEBORDER) );
1232 PatBlt( hdc, rect->left, rect->top,
1233 rect->right - rect->left, height, PATCOPY );
1234 PatBlt( hdc, rect->left, rect->top,
1235 width, rect->bottom - rect->top, PATCOPY );
1236 PatBlt( hdc, rect->left, rect->bottom - 1,
1237 rect->right - rect->left, -height, PATCOPY );
1238 PatBlt( hdc, rect->right - 1, rect->top,
1239 -width, rect->bottom - rect->top, PATCOPY );
1243 InflateRect( rect, -width, -height );
1247 INT decYOff = SYSMETRICS_CXFRAME + SYSMETRICS_CXSIZE;
1248 INT decXOff = SYSMETRICS_CYFRAME + SYSMETRICS_CYSIZE;
1250 /* Draw inner rectangle */
1252 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1253 Rectangle( hdc, rect->left + width, rect->top + height,
1254 rect->right - width , rect->bottom - height );
1256 /* Draw the decorations */
1258 MoveToEx( hdc, rect->left, rect->top + decYOff, NULL );
1259 LineTo( hdc, rect->left + width, rect->top + decYOff );
1260 MoveToEx( hdc, rect->right - 1, rect->top + decYOff, NULL );
1261 LineTo( hdc, rect->right - width - 1, rect->top + decYOff );
1262 MoveToEx( hdc, rect->left, rect->bottom - decYOff, NULL );
1263 LineTo( hdc, rect->left + width, rect->bottom - decYOff );
1264 MoveToEx( hdc, rect->right - 1, rect->bottom - decYOff, NULL );
1265 LineTo( hdc, rect->right - width - 1, rect->bottom - decYOff );
1267 MoveToEx( hdc, rect->left + decXOff, rect->top, NULL );
1268 LineTo( hdc, rect->left + decXOff, rect->top + height);
1269 MoveToEx( hdc, rect->left + decXOff, rect->bottom - 1, NULL );
1270 LineTo( hdc, rect->left + decXOff, rect->bottom - height - 1 );
1271 MoveToEx( hdc, rect->right - decXOff, rect->top, NULL );
1272 LineTo( hdc, rect->right - decXOff, rect->top + height );
1273 MoveToEx( hdc, rect->right - decXOff, rect->bottom - 1, NULL );
1274 LineTo( hdc, rect->right - decXOff, rect->bottom - height - 1 );
1276 InflateRect( rect, -width - 1, -height - 1 );
1281 /******************************************************************************
1283 * void NC_DrawFrame95(
1289 * Draw a window frame inside the given rectangle, and update the rectangle.
1290 * The correct pen for the frame must be selected in the DC.
1293 * Many. First, just what IS a frame in Win95? Note that the 3D look
1294 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1295 * edge. The inner rectangle just inside the frame is handled by the
1298 * In short, for most people, this function should be a nop (unless
1299 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1300 * them lately, but just to get this code right). Even so, it doesn't
1301 * appear to be so. It's being worked on...
1304 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1305 * Original implementation (based on NC_DrawFrame)
1306 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1309 *****************************************************************************/
1311 static void NC_DrawFrame95(
1321 width = sysMetrics[SM_CXDLGFRAME] - sysMetrics[SM_CXEDGE];
1322 height = sysMetrics[SM_CYDLGFRAME] - sysMetrics[SM_CYEDGE];
1326 width = sysMetrics[SM_CXFRAME] - sysMetrics[SM_CXEDGE];
1327 height = sysMetrics[SM_CYFRAME] - sysMetrics[SM_CYEDGE];
1330 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1331 COLOR_INACTIVEBORDER) );
1334 PatBlt( hdc, rect->left, rect->top,
1335 rect->right - rect->left, height, PATCOPY );
1336 PatBlt( hdc, rect->left, rect->top,
1337 width, rect->bottom - rect->top, PATCOPY );
1338 PatBlt( hdc, rect->left, rect->bottom - 1,
1339 rect->right - rect->left, -height, PATCOPY );
1340 PatBlt( hdc, rect->right - 1, rect->top - 1,
1341 -width, rect->bottom - rect->top, PATCOPY );
1343 InflateRect( rect, -width, -height );
1346 /***********************************************************************
1347 * NC_DrawMovingFrame
1349 * Draw the frame used when moving or resizing window.
1351 * FIXME: This causes problems in Win95 mode. (why?)
1353 static void NC_DrawMovingFrame( HDC hdc, RECT *rect, BOOL thickframe )
1358 CONV_RECT32TO16( rect, &r16 );
1359 FastWindowFrame16( hdc, &r16, SYSMETRICS_CXFRAME,
1360 SYSMETRICS_CYFRAME, PATINVERT );
1362 else DrawFocusRect( hdc, rect );
1366 /***********************************************************************
1369 * Draw the window caption.
1370 * The correct pen for the window frame must be selected in the DC.
1372 static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd,
1373 DWORD style, BOOL active )
1376 WND * wndPtr = WIN_FindWndPtr( hwnd );
1379 if (wndPtr->flags & WIN_MANAGED)
1381 WIN_ReleaseWndPtr(wndPtr);
1387 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1389 WIN_ReleaseWndPtr(wndPtr);
1392 hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED) );
1393 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1394 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1395 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1396 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1397 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1398 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1401 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
1403 HBRUSH hbrushOld = SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW) );
1404 PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
1405 PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
1406 PatBlt( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
1409 SelectObject( hdc, hbrushOld );
1411 WIN_ReleaseWndPtr(wndPtr);
1412 MoveTo16( hdc, r.left, r.bottom );
1413 LineTo( hdc, r.right, r.bottom );
1415 if (style & WS_SYSMENU)
1417 NC_DrawSysButton( hwnd, hdc, FALSE );
1418 r.left += SYSMETRICS_CXSIZE + 1;
1419 MoveTo16( hdc, r.left - 1, r.top );
1420 LineTo( hdc, r.left - 1, r.bottom );
1422 if (style & WS_MAXIMIZEBOX)
1424 NC_DrawMaxButton( hwnd, hdc, FALSE );
1425 r.right -= SYSMETRICS_CXSIZE + 1;
1427 if (style & WS_MINIMIZEBOX)
1429 NC_DrawMinButton( hwnd, hdc, FALSE );
1430 r.right -= SYSMETRICS_CXSIZE + 1;
1433 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1434 COLOR_INACTIVECAPTION) );
1436 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) ))
1438 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1439 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1440 SetBkMode( hdc, TRANSPARENT );
1441 DrawTextA( hdc, buffer, -1, &r,
1442 DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );
1447 /******************************************************************************
1456 * Draw the window caption for Win95 style windows.
1457 * The correct pen for the window frame must be selected in the DC.
1460 * Hey, a function that finally works! Well, almost.
1461 * It's being worked on.
1464 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1465 * Original implementation.
1466 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1469 *****************************************************************************/
1471 static void NC_DrawCaption95(
1480 WND *wndPtr = WIN_FindWndPtr( hwnd );
1484 if (wndPtr->flags & WIN_MANAGED)
1486 WIN_ReleaseWndPtr(wndPtr);
1489 WIN_ReleaseWndPtr(wndPtr);
1491 hPrevPen = SelectObject( hdc, GetSysColorPen(COLOR_3DFACE) );
1492 MoveToEx( hdc, r.left, r.bottom - 1, NULL );
1493 LineTo( hdc, r.right, r.bottom - 1 );
1494 SelectObject( hdc, hPrevPen );
1497 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1498 COLOR_INACTIVECAPTION) );
1500 if (!hbitmapClose) {
1501 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1503 hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED));
1504 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1505 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1506 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1507 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1508 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1509 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1512 if ((style & WS_SYSMENU) && !(exStyle & WS_EX_TOOLWINDOW)) {
1513 if (NC_DrawSysButton95 (hwnd, hdc, FALSE))
1514 r.left += sysMetrics[SM_CYCAPTION] - 1;
1516 if (style & WS_SYSMENU) {
1517 NC_DrawCloseButton95 (hwnd, hdc, FALSE);
1518 r.right -= sysMetrics[SM_CYCAPTION] - 1;
1520 if (style & WS_MAXIMIZEBOX) {
1521 NC_DrawMaxButton95( hwnd, hdc, FALSE );
1522 r.right -= SYSMETRICS_CXSIZE + 1;
1524 if (style & WS_MINIMIZEBOX) {
1525 NC_DrawMinButton95( hwnd, hdc, FALSE );
1526 r.right -= SYSMETRICS_CXSIZE + 1;
1529 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) )) {
1530 NONCLIENTMETRICSA nclm;
1531 HFONT hFont, hOldFont;
1532 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1533 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1534 if (exStyle & WS_EX_TOOLWINDOW)
1535 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
1537 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
1538 hOldFont = SelectObject (hdc, hFont);
1539 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1540 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1541 SetBkMode( hdc, TRANSPARENT );
1543 DrawTextA( hdc, buffer, -1, &r,
1544 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
1545 DeleteObject (SelectObject (hdc, hOldFont));
1551 /***********************************************************************
1554 * Paint the non-client area. clip is currently unused.
1556 void NC_DoNCPaint( WND* wndPtr, HRGN clip, BOOL suppress_menupaint )
1561 HWND hwnd = wndPtr->hwndSelf;
1563 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1564 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1566 active = wndPtr->flags & WIN_NCACTIVATED;
1568 TRACE(nonclient, "%04x %d\n", hwnd, active );
1570 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1571 ((clip > 1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN): 0) ))) return;
1573 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1574 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1575 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1576 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1579 ReleaseDC( hwnd, hdc );
1583 rect.top = rect.left = 0;
1584 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1585 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1587 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1589 if (!(wndPtr->flags & WIN_MANAGED))
1591 if ((wndPtr->dwStyle & WS_BORDER) || (wndPtr->dwStyle & WS_DLGFRAME) ||
1592 (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME))
1594 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1595 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1596 InflateRect( &rect, -1, -1 );
1599 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1600 NC_DrawFrame( hdc, &rect, TRUE, active );
1601 else if (wndPtr->dwStyle & WS_THICKFRAME)
1602 NC_DrawFrame(hdc, &rect, FALSE, active );
1604 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1607 r.bottom = rect.top + SYSMETRICS_CYSIZE;
1608 rect.top += SYSMETRICS_CYSIZE + SYSMETRICS_CYBORDER;
1609 NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active );
1613 if (HAS_MENU(wndPtr))
1616 r.bottom = rect.top + SYSMETRICS_CYMENU; /* default height */
1617 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint );
1620 /* Draw the scroll-bars */
1622 if (wndPtr->dwStyle & WS_VSCROLL)
1623 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1624 if (wndPtr->dwStyle & WS_HSCROLL)
1625 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1627 /* Draw the "size-box" */
1629 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1632 r.left = r.right - SYSMETRICS_CXVSCROLL + 1;
1633 r.top = r.bottom - SYSMETRICS_CYHSCROLL + 1;
1634 if(wndPtr->dwStyle & WS_BORDER) {
1638 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1641 ReleaseDC( hwnd, hdc );
1645 /******************************************************************************
1647 * void NC_DoNCPaint95(
1650 * BOOL32 suppress_menupaint )
1652 * Paint the non-client area for Win95 windows. The clip region is
1653 * currently ignored.
1656 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1657 * misc/tweak.c controls/menu.c # :-)
1660 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1661 * Original implementation
1662 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1665 *****************************************************************************/
1667 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(nonclient, "%04x %d\n", hwnd, active );
1684 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in the call to
1685 * GetDCEx implying that it is allowed not to use it either. However, the suggested
1686 * GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN) will cause clipRgn to be deleted
1687 * after ReleaseDC(). Now, how is the "system" supposed to tell what happened?
1690 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1691 ((clip > 1) ?(DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0) ))) return;
1694 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1695 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1696 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1697 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1700 ReleaseDC( hwnd, hdc );
1704 rect.top = rect.left = 0;
1705 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1706 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1709 GetRgnBox( clip, &rectClip );
1716 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1718 if(!(wndPtr->flags & WIN_MANAGED)) {
1719 if ((wndPtr->dwStyle & WS_BORDER) && ((wndPtr->dwStyle & WS_DLGFRAME) ||
1720 (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME) || (wndPtr->dwStyle & WS_THICKFRAME))) {
1721 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1724 if (HAS_FIXEDFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1725 NC_DrawFrame95( hdc, &rect, TRUE, active );
1726 else if (wndPtr->dwStyle & WS_THICKFRAME)
1727 NC_DrawFrame95(hdc, &rect, FALSE, active );
1729 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1732 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW) {
1733 r.bottom = rect.top + sysMetrics[SM_CYSMCAPTION];
1734 rect.top += sysMetrics[SM_CYSMCAPTION];
1737 r.bottom = rect.top + sysMetrics[SM_CYCAPTION];
1738 rect.top += sysMetrics[SM_CYCAPTION];
1740 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
1741 NC_DrawCaption95 (hdc, &r, hwnd, wndPtr->dwStyle,
1742 wndPtr->dwExStyle, active);
1746 if (HAS_MENU(wndPtr))
1749 r.bottom = rect.top + sysMetrics[SM_CYMENU];
1751 TRACE(nonclient, "Calling DrawMenuBar with "
1752 "rect (%d, %d)-(%d, %d)\n", r.left, r.top,
1755 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ) + 1;
1758 TRACE(nonclient, "After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1759 rect.left, rect.top, rect.right, rect.bottom );
1761 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
1762 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1764 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
1765 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1767 /* Draw the scroll-bars */
1769 if (wndPtr->dwStyle & WS_VSCROLL)
1770 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1771 if (wndPtr->dwStyle & WS_HSCROLL)
1772 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1774 /* Draw the "size-box" */
1775 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1778 r.left = r.right - SYSMETRICS_CXVSCROLL + 1;
1779 r.top = r.bottom - SYSMETRICS_CYHSCROLL + 1;
1780 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1783 ReleaseDC( hwnd, hdc );
1789 /***********************************************************************
1792 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1794 LONG NC_HandleNCPaint( HWND hwnd , HRGN clip)
1796 WND* wndPtr = WIN_FindWndPtr( hwnd );
1798 if( wndPtr && wndPtr->dwStyle & WS_VISIBLE )
1800 if( wndPtr->dwStyle & WS_MINIMIZE )
1801 WINPOS_RedrawIconTitle( hwnd );
1802 else if (TWEAK_WineLook == WIN31_LOOK)
1803 NC_DoNCPaint( wndPtr, clip, FALSE );
1805 NC_DoNCPaint95( wndPtr, clip, FALSE );
1807 WIN_ReleaseWndPtr(wndPtr);
1812 /***********************************************************************
1813 * NC_HandleNCActivate
1815 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1817 LONG NC_HandleNCActivate( WND *wndPtr, WPARAM16 wParam )
1821 if( wParam ) wStateChange = !(wndPtr->flags & WIN_NCACTIVATED);
1822 else wStateChange = wndPtr->flags & WIN_NCACTIVATED;
1826 if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
1827 else wndPtr->flags &= ~WIN_NCACTIVATED;
1829 if( wndPtr->dwStyle & WS_MINIMIZE )
1830 WINPOS_RedrawIconTitle( wndPtr->hwndSelf );
1831 else if (TWEAK_WineLook == WIN31_LOOK)
1832 NC_DoNCPaint( wndPtr, (HRGN)1, FALSE );
1834 NC_DoNCPaint95( wndPtr, (HRGN)1, FALSE );
1840 /***********************************************************************
1841 * NC_HandleSetCursor
1843 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1845 LONG NC_HandleSetCursor( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
1847 if (hwnd != (HWND)wParam) return 0; /* Don't set the cursor for child windows */
1849 switch(LOWORD(lParam))
1853 WORD msg = HIWORD( lParam );
1854 if ((msg == WM_LBUTTONDOWN) || (msg == WM_MBUTTONDOWN) ||
1855 (msg == WM_RBUTTONDOWN))
1865 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) break;
1866 if (wndPtr->class->hCursor)
1868 SetCursor16( wndPtr->class->hCursor );
1871 else retvalue = FALSE;
1872 WIN_ReleaseWndPtr(wndPtr);
1878 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZEWE16 ) );
1882 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENS16 ) );
1886 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENWSE16 ) );
1890 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENESW16 ) );
1893 /* Default cursor: arrow */
1894 return (LONG)SetCursor16( LoadCursor16( 0, IDC_ARROW16 ) );
1897 /***********************************************************************
1900 BOOL NC_GetSysPopupPos( WND* wndPtr, RECT* rect )
1902 if( wndPtr->hSysMenu )
1904 if( wndPtr->dwStyle & WS_MINIMIZE )
1905 GetWindowRect( wndPtr->hwndSelf, rect );
1908 if (TWEAK_WineLook == WIN31_LOOK)
1909 NC_GetInsideRect( wndPtr->hwndSelf, rect );
1911 NC_GetInsideRect95( wndPtr->hwndSelf, rect );
1912 OffsetRect( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
1913 if (wndPtr->dwStyle & WS_CHILD)
1914 ClientToScreen( wndPtr->parent->hwndSelf, (POINT *)rect );
1915 if (TWEAK_WineLook == WIN31_LOOK) {
1916 rect->right = rect->left + SYSMETRICS_CXSIZE;
1917 rect->bottom = rect->top + SYSMETRICS_CYSIZE;
1920 rect->right = rect->left + sysMetrics[SM_CYCAPTION] - 1;
1921 rect->bottom = rect->top + sysMetrics[SM_CYCAPTION] - 1;
1929 /***********************************************************************
1932 * Initialisation of a move or resize, when initiatied from a menu choice.
1933 * Return hit test code for caption or sizing border.
1935 static LONG NC_StartSizeMove( WND* wndPtr, WPARAM16 wParam,
1936 POINT16 *capturePoint )
1942 if ((wParam & 0xfff0) == SC_MOVE)
1944 /* Move pointer at the center of the caption */
1946 if (TWEAK_WineLook == WIN31_LOOK)
1947 NC_GetInsideRect( wndPtr->hwndSelf, &rect );
1949 NC_GetInsideRect95( wndPtr->hwndSelf, &rect );
1950 if (wndPtr->dwStyle & WS_SYSMENU)
1951 rect.left += SYSMETRICS_CXSIZE + 1;
1952 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
1953 rect.right -= SYSMETRICS_CXSIZE + 1;
1954 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
1955 rect.right -= SYSMETRICS_CXSIZE + 1;
1956 pt.x = wndPtr->rectWindow.left + (rect.right - rect.left) / 2;
1957 pt.y = wndPtr->rectWindow.top + rect.top + SYSMETRICS_CYSIZE/2;
1958 hittest = HTCAPTION;
1965 MSG_InternalGetMessage( &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE );
1969 CONV_POINT32TO16(&msg.pt, &pt);
1970 hittest = NC_HandleNCHitTest( wndPtr->hwndSelf, pt );
1971 if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
1983 pt.x =(wndPtr->rectWindow.left+wndPtr->rectWindow.right)/2;
1984 pt.y = wndPtr->rectWindow.top + SYSMETRICS_CYFRAME / 2;
1988 pt.x =(wndPtr->rectWindow.left+wndPtr->rectWindow.right)/2;
1989 pt.y = wndPtr->rectWindow.bottom - SYSMETRICS_CYFRAME / 2;
1993 pt.x = wndPtr->rectWindow.left + SYSMETRICS_CXFRAME / 2;
1994 pt.y =(wndPtr->rectWindow.top+wndPtr->rectWindow.bottom)/2;
1998 pt.x = wndPtr->rectWindow.right - SYSMETRICS_CXFRAME / 2;
1999 pt.y =(wndPtr->rectWindow.top+wndPtr->rectWindow.bottom)/2;
2002 case VK_ESCAPE: return 0;
2008 SetCursorPos( pt.x, pt.y );
2009 NC_HandleSetCursor( wndPtr->hwndSelf,
2010 wndPtr->hwndSelf, MAKELONG( hittest, WM_MOUSEMOVE ));
2015 /***********************************************************************
2018 * Perform SC_MOVE and SC_SIZE commands. `
2020 static void NC_DoSizeMove( HWND hwnd, WORD wParam )
2023 RECT sizingRect, mouseRect;
2025 LONG hittest = (LONG)(wParam & 0x0f);
2026 HCURSOR16 hDragCursor = 0, hOldCursor = 0;
2027 POINT minTrack, maxTrack;
2028 POINT16 capturePoint, pt;
2029 WND * wndPtr = WIN_FindWndPtr( hwnd );
2030 BOOL thickframe = HAS_THICKFRAME( wndPtr->dwStyle );
2031 BOOL iconic = wndPtr->dwStyle & WS_MINIMIZE;
2033 DWORD dwPoint = GetMessagePos ();
2035 capturePoint = pt = *(POINT16*)&dwPoint;
2037 if (IsZoomed(hwnd) || !IsWindowVisible(hwnd) ||
2038 (wndPtr->flags & WIN_MANAGED)) goto END;
2040 if ((wParam & 0xfff0) == SC_MOVE)
2042 if (!(wndPtr->dwStyle & WS_CAPTION)) goto END;
2044 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2045 if (!hittest) goto END;
2049 if (!thickframe) goto END;
2050 if ( hittest && hittest != HTSYSMENU ) hittest += 2;
2054 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2063 /* Get min/max info */
2065 WINPOS_GetMinMaxInfo( wndPtr, NULL, NULL, &minTrack, &maxTrack );
2066 sizingRect = wndPtr->rectWindow;
2067 if (wndPtr->dwStyle & WS_CHILD)
2068 GetClientRect( wndPtr->parent->hwndSelf, &mouseRect );
2070 SetRect(&mouseRect, 0, 0, SYSMETRICS_CXSCREEN, SYSMETRICS_CYSCREEN);
2071 if (ON_LEFT_BORDER(hittest))
2073 mouseRect.left = MAX( mouseRect.left, sizingRect.right-maxTrack.x );
2074 mouseRect.right = MIN( mouseRect.right, sizingRect.right-minTrack.x );
2076 else if (ON_RIGHT_BORDER(hittest))
2078 mouseRect.left = MAX( mouseRect.left, sizingRect.left+minTrack.x );
2079 mouseRect.right = MIN( mouseRect.right, sizingRect.left+maxTrack.x );
2081 if (ON_TOP_BORDER(hittest))
2083 mouseRect.top = MAX( mouseRect.top, sizingRect.bottom-maxTrack.y );
2084 mouseRect.bottom = MIN( mouseRect.bottom,sizingRect.bottom-minTrack.y);
2086 else if (ON_BOTTOM_BORDER(hittest))
2088 mouseRect.top = MAX( mouseRect.top, sizingRect.top+minTrack.y );
2089 mouseRect.bottom = MIN( mouseRect.bottom, sizingRect.top+maxTrack.y );
2091 if (wndPtr->dwStyle & WS_CHILD)
2093 MapWindowPoints( wndPtr->parent->hwndSelf, 0,
2094 (LPPOINT)&mouseRect, 2 );
2096 SendMessage16( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
2098 if (GetCapture() != hwnd) SetCapture( hwnd );
2100 if (wndPtr->dwStyle & WS_CHILD)
2102 /* Retrieve a default cache DC (without using the window style) */
2103 hdc = GetDCEx( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
2106 { /* Grab the server only when moving top-level windows without desktop */
2110 wndPtr->pDriver->pPreSizeMove(wndPtr);
2112 if( iconic ) /* create a cursor for dragging */
2114 HICON16 hIcon = (wndPtr->class->hIcon) ? wndPtr->class->hIcon
2115 : (HICON16)SendMessage16( hwnd, WM_QUERYDRAGICON, 0, 0L);
2116 if( hIcon ) hDragCursor = CURSORICON_IconToCursor( hIcon, TRUE );
2117 if( !hDragCursor ) iconic = FALSE;
2120 if( !iconic ) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2126 MSG_InternalGetMessage( &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE );
2128 /* Exit on button-up, Return, or Esc */
2129 if ((msg.message == WM_LBUTTONUP) ||
2130 ((msg.message == WM_KEYDOWN) &&
2131 ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
2133 if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
2134 continue; /* We are not interested in other messages */
2136 dwPoint = GetMessagePos ();
2137 pt = *(POINT16*)&dwPoint;
2139 if (msg.message == WM_KEYDOWN) switch(msg.wParam)
2141 case VK_UP: pt.y -= 8; break;
2142 case VK_DOWN: pt.y += 8; break;
2143 case VK_LEFT: pt.x -= 8; break;
2144 case VK_RIGHT: pt.x += 8; break;
2147 pt.x = MAX( pt.x, mouseRect.left );
2148 pt.x = MIN( pt.x, mouseRect.right );
2149 pt.y = MAX( pt.y, mouseRect.top );
2150 pt.y = MIN( pt.y, mouseRect.bottom );
2152 dx = pt.x - capturePoint.x;
2153 dy = pt.y - capturePoint.y;
2160 if( iconic ) /* ok, no system popup tracking */
2162 hOldCursor = SetCursor(hDragCursor);
2164 WINPOS_ShowIconTitle( wndPtr, FALSE );
2168 if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
2171 RECT newRect = sizingRect;
2173 if (hittest == HTCAPTION) OffsetRect( &newRect, dx, dy );
2174 if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
2175 else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
2176 if (ON_TOP_BORDER(hittest)) newRect.top += dy;
2177 else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
2180 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2181 NC_DrawMovingFrame( hdc, &newRect, thickframe );
2184 sizingRect = newRect;
2192 if( moved ) /* restore cursors, show icon title later on */
2194 ShowCursor( FALSE );
2195 SetCursor( hOldCursor );
2197 DestroyCursor( hDragCursor );
2200 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2202 if (wndPtr->dwStyle & WS_CHILD)
2203 ReleaseDC( wndPtr->parent->hwndSelf, hdc );
2206 ReleaseDC( 0, hdc );
2209 wndPtr->pDriver->pPostSizeMove(wndPtr);
2211 if (HOOK_IsHooked( WH_CBT ))
2213 RECT16* pr = SEGPTR_NEW(RECT16);
2216 CONV_RECT32TO16( &sizingRect, pr );
2217 if( HOOK_CallHooks16( WH_CBT, HCBT_MOVESIZE, hwnd,
2218 (LPARAM)SEGPTR_GET(pr)) )
2219 sizingRect = wndPtr->rectWindow;
2221 CONV_RECT16TO32( pr, &sizingRect );
2225 SendMessage16( hwnd, WM_EXITSIZEMOVE, 0, 0 );
2226 SendMessage16( hwnd, WM_SETVISIBLE, !IsIconic16(hwnd), 0L);
2228 if( moved && !((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
2230 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
2231 SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top,
2232 sizingRect.right - sizingRect.left,
2233 sizingRect.bottom - sizingRect.top,
2234 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
2237 if( IsWindow(hwnd) )
2238 if( wndPtr->dwStyle & WS_MINIMIZE )
2240 /* Single click brings up the system menu when iconized */
2244 if( wndPtr->dwStyle & WS_SYSMENU )
2245 SendMessage16( hwnd, WM_SYSCOMMAND,
2246 SC_MOUSEMENU + HTSYSMENU, *((LPARAM*)&pt));
2248 else WINPOS_ShowIconTitle( wndPtr, TRUE );
2252 WIN_ReleaseWndPtr(wndPtr);
2256 /***********************************************************************
2259 * Track a mouse button press on the minimize or maximize box.
2261 static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
2265 HDC hdc = GetWindowDC( hwnd );
2266 BOOL pressed = TRUE;
2267 void (*paintButton)(HWND, HDC16, BOOL);
2270 if (wParam == HTMINBUTTON)
2272 (TWEAK_WineLook == WIN31_LOOK) ? &NC_DrawMinButton : &NC_DrawMinButton95;
2275 (TWEAK_WineLook == WIN31_LOOK) ? &NC_DrawMaxButton : &NC_DrawMaxButton95;
2277 (*paintButton)( hwnd, hdc, TRUE );
2281 BOOL oldstate = pressed;
2282 MSG_InternalGetMessage( &msg, 0, 0, 0, PM_REMOVE, FALSE );
2283 CONV_POINT32TO16( &msg.pt, &pt16 );
2285 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2286 if (pressed != oldstate)
2287 (*paintButton)( hwnd, hdc, pressed );
2288 } while (msg.message != WM_LBUTTONUP);
2290 (*paintButton)( hwnd, hdc, FALSE );
2293 ReleaseDC( hwnd, hdc );
2294 if (!pressed) return;
2296 if (wParam == HTMINBUTTON)
2297 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&pt16 );
2299 SendMessage16( hwnd, WM_SYSCOMMAND,
2300 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, *(LONG*)&pt16 );
2304 /***********************************************************************
2305 * NC_TrackCloseButton95
2307 * Track a mouse button press on the Win95 close button.
2310 NC_TrackCloseButton95 (HWND hwnd, WORD wParam)
2314 HDC hdc = GetWindowDC( hwnd );
2315 BOOL pressed = TRUE;
2319 NC_DrawCloseButton95 (hwnd, hdc, TRUE);
2323 BOOL oldstate = pressed;
2324 MSG_InternalGetMessage( &msg, 0, 0, 0, PM_REMOVE, FALSE );
2325 CONV_POINT32TO16( &msg.pt, &pt16 );
2327 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2328 if (pressed != oldstate)
2329 NC_DrawCloseButton95 (hwnd, hdc, pressed);
2330 } while (msg.message != WM_LBUTTONUP);
2332 NC_DrawCloseButton95 (hwnd, hdc, FALSE);
2335 ReleaseDC( hwnd, hdc );
2336 if (!pressed) return;
2338 SendMessage16( hwnd, WM_SYSCOMMAND, SC_CLOSE, *(LONG*)&pt16 );
2342 /***********************************************************************
2345 * Track a mouse button press on the horizontal or vertical scroll-bar.
2347 static void NC_TrackScrollBar( HWND hwnd, WPARAM wParam, POINT pt )
2351 WND *wndPtr = WIN_FindWndPtr( hwnd );
2353 if ((wParam & 0xfff0) == SC_HSCROLL)
2355 if ((wParam & 0x0f) != HTHSCROLL) goto END;
2356 scrollbar = SB_HORZ;
2358 else /* SC_VSCROLL */
2360 if ((wParam & 0x0f) != HTVSCROLL) goto END;
2361 scrollbar = SB_VERT;
2364 if (!(msg = SEGPTR_NEW(MSG16))) goto END;
2365 pt.x -= wndPtr->rectWindow.left;
2366 pt.y -= wndPtr->rectWindow.top;
2368 SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt );
2372 GetMessage16( SEGPTR_GET(msg), 0, 0, 0 );
2373 switch(msg->message)
2378 pt.x = LOWORD(msg->lParam) + wndPtr->rectClient.left -
2379 wndPtr->rectWindow.left;
2380 pt.y = HIWORD(msg->lParam) + wndPtr->rectClient.top -
2381 wndPtr->rectWindow.top;
2382 SCROLL_HandleScrollEvent( hwnd, scrollbar, msg->message, pt );
2385 TranslateMessage16( msg );
2386 DispatchMessage16( msg );
2389 if (!IsWindow( hwnd ))
2394 } while (msg->message != WM_LBUTTONUP);
2397 WIN_ReleaseWndPtr(wndPtr);
2400 /***********************************************************************
2401 * NC_HandleNCLButtonDown
2403 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2405 LONG NC_HandleNCLButtonDown( WND* pWnd, WPARAM16 wParam, LPARAM lParam )
2407 HWND hwnd = pWnd->hwndSelf;
2409 switch(wParam) /* Hit test */
2412 hwnd = WIN_GetTopParent(hwnd);
2414 if( WINPOS_SetActiveWindow(hwnd, TRUE, TRUE) || (GetActiveWindow() == hwnd) )
2415 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
2419 if( pWnd->dwStyle & WS_SYSMENU )
2421 if( !(pWnd->dwStyle & WS_MINIMIZE) )
2423 HDC hDC = GetWindowDC(hwnd);
2424 if (TWEAK_WineLook == WIN31_LOOK)
2425 NC_DrawSysButton( hwnd, hDC, TRUE );
2427 NC_DrawSysButton95( hwnd, hDC, TRUE );
2428 ReleaseDC( hwnd, hDC );
2430 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
2435 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam );
2439 SendMessage16( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
2443 SendMessage16( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
2448 NC_TrackMinMaxBox( hwnd, wParam );
2452 if (TWEAK_WineLook >= WIN95_LOOK)
2453 NC_TrackCloseButton95 (hwnd, wParam);
2464 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2465 SendMessage16( hwnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam);
2475 /***********************************************************************
2476 * NC_HandleNCLButtonDblClk
2478 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2480 LONG NC_HandleNCLButtonDblClk( WND *pWnd, WPARAM16 wParam, LPARAM lParam )
2483 * if this is an icon, send a restore since we are handling
2486 if (pWnd->dwStyle & WS_MINIMIZE)
2488 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_RESTORE, lParam );
2492 switch(wParam) /* Hit test */
2495 /* stop processing if WS_MAXIMIZEBOX is missing */
2496 if (pWnd->dwStyle & WS_MAXIMIZEBOX)
2497 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND,
2498 (pWnd->dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
2503 if (!(pWnd->class->style & CS_NOCLOSE))
2504 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, lParam );
2508 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL,
2513 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL,
2521 /***********************************************************************
2522 * NC_HandleSysCommand
2524 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2526 LONG NC_HandleSysCommand( HWND hwnd, WPARAM16 wParam, POINT16 pt )
2528 WND *wndPtr = WIN_FindWndPtr( hwnd );
2530 UINT16 uCommand = wParam & 0xFFF0;
2532 TRACE(nonclient, "Handling WM_SYSCOMMAND %x %d,%d\n",
2533 wParam, pt.x, pt.y );
2535 if (wndPtr->dwStyle & WS_CHILD && uCommand != SC_KEYMENU )
2536 ScreenToClient16( wndPtr->parent->hwndSelf, &pt );
2542 NC_DoSizeMove( hwnd, wParam );
2546 ShowWindow( hwnd, SW_MINIMIZE );
2550 ShowWindow( hwnd, SW_MAXIMIZE );
2554 ShowWindow( hwnd, SW_RESTORE );
2558 WIN_ReleaseWndPtr(wndPtr);
2559 return SendMessage16( hwnd, WM_CLOSE, 0, 0 );
2563 CONV_POINT16TO32( &pt, &pt32 );
2564 NC_TrackScrollBar( hwnd, wParam, pt32 );
2568 CONV_POINT16TO32( &pt, &pt32 );
2569 MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt32 );
2573 MENU_TrackKbdMenuBar( wndPtr , wParam , pt.x );
2577 WinExec( "taskman.exe", SW_SHOWNORMAL );
2581 if (wParam == SC_ABOUTWINE)
2582 ShellAboutA(hwnd,"Wine", WINE_RELEASE_INFO, 0);
2584 if (wParam == SC_PUTMARK)
2585 TRACE(shell,"Mark requested by user\n");
2592 FIXME (nonclient, "unimplemented!\n");
2595 WIN_ReleaseWndPtr(wndPtr);