winmm.dll can now be properly separated.
[wine/gsoc_dplay.git] / windows / nonclient.c
blob86db5b323907865c93c3d2be2475586a868ae7de
1 /*
2 * Non-client area window functions
4 * Copyright 1994 Alexandre Julliard
6 */
8 #include "windef.h"
9 #include "wingdi.h"
10 #include "wine/winuser16.h"
11 #include "version.h"
12 #include "win.h"
13 #include "message.h"
14 #include "user.h"
15 #include "heap.h"
16 #include "dce.h"
17 #include "controls.h"
18 #include "cursoricon.h"
19 #include "winpos.h"
20 #include "hook.h"
21 #include "nonclient.h"
22 #include "queue.h"
23 #include "tweak.h"
24 #include "debugtools.h"
25 #include "options.h"
26 #include "shellapi.h"
27 #include "cache.h"
28 #include "bitmap.h"
30 DEFAULT_DEBUG_CHANNEL(nonclient);
31 DECLARE_DEBUG_CHANNEL(shell);
33 BOOL NC_DrawGrayButton(HDC hdc, int x, int y);
35 static HBITMAP16 hbitmapClose = 0;
36 static HBITMAP16 hbitmapCloseD = 0;
37 static HBITMAP16 hbitmapMinimize = 0;
38 static HBITMAP16 hbitmapMinimizeD = 0;
39 static HBITMAP16 hbitmapMaximize = 0;
40 static HBITMAP16 hbitmapMaximizeD = 0;
41 static HBITMAP16 hbitmapRestore = 0;
42 static HBITMAP16 hbitmapRestoreD = 0;
44 BYTE lpGrayMask[] = { 0xAA, 0xA0,
45 0x55, 0x50,
46 0xAA, 0xA0,
47 0x55, 0x50,
48 0xAA, 0xA0,
49 0x55, 0x50,
50 0xAA, 0xA0,
51 0x55, 0x50,
52 0xAA, 0xA0,
53 0x55, 0x50};
55 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
56 #define SC_PUTMARK (SC_SCREENSAVE+2)
58 /* Some useful macros */
59 #define HAS_DLGFRAME(style,exStyle) \
60 (((exStyle) & WS_EX_DLGMODALFRAME) || \
61 (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
63 #define HAS_THICKFRAME(style,exStyle) \
64 (((style) & WS_THICKFRAME) && \
65 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
67 #define HAS_THINFRAME(style) \
68 (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
70 #define HAS_BIGFRAME(style,exStyle) \
71 (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
72 ((exStyle) & WS_EX_DLGMODALFRAME))
74 #define HAS_ANYFRAME(style,exStyle) \
75 (((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
76 ((exStyle) & WS_EX_DLGMODALFRAME) || \
77 !((style) & (WS_CHILD | WS_POPUP)))
79 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
81 #define ON_LEFT_BORDER(hit) \
82 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
83 #define ON_RIGHT_BORDER(hit) \
84 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
85 #define ON_TOP_BORDER(hit) \
86 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
87 #define ON_BOTTOM_BORDER(hit) \
88 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
90 /***********************************************************************
91 * WIN_WindowNeedsWMBorder
93 * This method defines the rules for a window to have a WM border,
94 * caption... It is used for consitency purposes.
96 BOOL WIN_WindowNeedsWMBorder( DWORD style, DWORD exStyle )
98 if (!(style & WS_CHILD) &&
99 Options.managed &&
100 !(exStyle & WS_EX_TOOLWINDOW) &&
101 ( ((style & WS_CAPTION) == WS_CAPTION) ||
102 (style & WS_THICKFRAME)))
103 return TRUE;
104 if (exStyle & WS_EX_TRAYWINDOW)
105 return TRUE;
106 return FALSE;
109 /***********************************************************************
110 * NC_AdjustRect
112 * Compute the size of the window rectangle from the size of the
113 * client rectangle.
115 static void NC_AdjustRect( LPRECT16 rect, DWORD style, BOOL menu,
116 DWORD exStyle )
118 if (TWEAK_WineLook > WIN31_LOOK)
119 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
121 if(style & WS_ICONIC) return;
122 /* Decide if the window will be managed (see CreateWindowEx) */
123 if (!WIN_WindowNeedsWMBorder(style, exStyle))
125 if (HAS_THICKFRAME( style, exStyle ))
126 InflateRect16( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
127 else
128 if (HAS_DLGFRAME( style, exStyle ))
129 InflateRect16( rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
130 else
131 if (HAS_THINFRAME( style ))
132 InflateRect16( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
134 if ((style & WS_CAPTION) == WS_CAPTION)
135 rect->top -= GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
137 if (menu) rect->top -= GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYBORDER);
139 if (style & WS_VSCROLL) {
140 rect->right += GetSystemMetrics(SM_CXVSCROLL) - 1;
141 if(!HAS_ANYFRAME( style, exStyle ))
142 rect->right++;
145 if (style & WS_HSCROLL) {
146 rect->bottom += GetSystemMetrics(SM_CYHSCROLL) - 1;
147 if(!HAS_ANYFRAME( style, exStyle ))
148 rect->bottom++;
153 /******************************************************************************
154 * NC_AdjustRectOuter95
156 * Computes the size of the "outside" parts of the window based on the
157 * parameters of the client area.
159 + PARAMS
160 * LPRECT16 rect
161 * DWORD style
162 * BOOL menu
163 * DWORD exStyle
165 * NOTES
166 * "Outer" parts of a window means the whole window frame, caption and
167 * menu bar. It does not include "inner" parts of the frame like client
168 * edge, static edge or scroll bars.
170 * Revision history
171 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
172 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
174 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
175 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
176 * NC_AdjustRectInner95 and added handling of Win95 styles.
178 * 28-Jul-1999 Ove Kåven (ovek@arcticnet.no)
179 * Streamlined window style checks.
181 *****************************************************************************/
183 static void
184 NC_AdjustRectOuter95 (LPRECT16 rect, DWORD style, BOOL menu, DWORD exStyle)
186 if(style & WS_ICONIC) return;
188 /* Decide if the window will be managed (see CreateWindowEx) */
189 if (!WIN_WindowNeedsWMBorder(style, exStyle))
191 if (HAS_THICKFRAME( style, exStyle ))
192 InflateRect16( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
193 else
194 if (HAS_DLGFRAME( style, exStyle ))
195 InflateRect16(rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
196 else
197 if (HAS_THINFRAME( style ))
198 InflateRect16( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
200 if ((style & WS_CAPTION) == WS_CAPTION)
202 if (exStyle & WS_EX_TOOLWINDOW)
203 rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
204 else
205 rect->top -= GetSystemMetrics(SM_CYCAPTION);
209 if (menu)
210 rect->top -= GetSystemMetrics(SM_CYMENU);
214 /******************************************************************************
215 * NC_AdjustRectInner95
217 * Computes the size of the "inside" part of the window based on the
218 * parameters of the client area.
220 + PARAMS
221 * LPRECT16 rect
222 * DWORD style
223 * DWORD exStyle
225 * NOTES
226 * "Inner" part of a window means the window frame inside of the flat
227 * window frame. It includes the client edge, the static edge and the
228 * scroll bars.
230 * Revision history
231 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
232 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
234 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
235 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
236 * NC_AdjustRectInner95 and added handling of Win95 styles.
238 *****************************************************************************/
240 static void
241 NC_AdjustRectInner95 (LPRECT16 rect, DWORD style, DWORD exStyle)
243 if(style & WS_ICONIC) return;
245 if (exStyle & WS_EX_CLIENTEDGE)
246 InflateRect16 (rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
248 if (exStyle & WS_EX_STATICEDGE)
249 InflateRect16 (rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
251 if (style & WS_VSCROLL) rect->right += GetSystemMetrics(SM_CXVSCROLL);
252 if (style & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
256 /***********************************************************************
257 * DrawCaption (USER.660) Draws a caption bar
259 * PARAMS
260 * hwnd [I]
261 * hdc [I]
262 * lpRect [I]
263 * uFlags [I]
265 * RETURNS
266 * Success:
267 * Failure:
270 BOOL16 WINAPI
271 DrawCaption16 (HWND16 hwnd, HDC16 hdc, const RECT16 *rect, UINT16 uFlags)
273 RECT rect32;
275 if (rect)
276 CONV_RECT16TO32 (rect, &rect32);
278 return (BOOL16)DrawCaptionTempA (hwnd, hdc, rect ? &rect32 : NULL,
279 0, 0, NULL, uFlags & 0x1F);
283 /***********************************************************************
284 * DrawCaption (USER32.@) Draws a caption bar
286 * PARAMS
287 * hwnd [I]
288 * hdc [I]
289 * lpRect [I]
290 * uFlags [I]
292 * RETURNS
293 * Success:
294 * Failure:
297 BOOL WINAPI
298 DrawCaption (HWND hwnd, HDC hdc, const RECT *lpRect, UINT uFlags)
300 return DrawCaptionTempA (hwnd, hdc, lpRect, 0, 0, NULL, uFlags & 0x1F);
304 /***********************************************************************
305 * DrawCaptionTemp (USER.657)
307 * PARAMS
309 * RETURNS
310 * Success:
311 * Failure:
314 BOOL16 WINAPI
315 DrawCaptionTemp16 (HWND16 hwnd, HDC16 hdc, const RECT16 *rect, HFONT16 hFont,
316 HICON16 hIcon, LPCSTR str, UINT16 uFlags)
318 RECT rect32;
320 if (rect)
321 CONV_RECT16TO32(rect,&rect32);
323 return (BOOL16)DrawCaptionTempA (hwnd, hdc, rect?&rect32:NULL, hFont,
324 hIcon, str, uFlags & 0x1F);
328 /***********************************************************************
329 * DrawCaptionTempA (USER32.@)
331 * PARAMS
333 * RETURNS
334 * Success:
335 * Failure:
338 BOOL WINAPI
339 DrawCaptionTempA (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
340 HICON hIcon, LPCSTR str, UINT uFlags)
342 RECT rc = *rect;
344 TRACE("(%08x,%08x,%p,%08x,%08x,\"%s\",%08x)\n",
345 hwnd, hdc, rect, hFont, hIcon, str, uFlags);
347 /* drawing background */
348 if (uFlags & DC_INBUTTON) {
349 FillRect (hdc, &rc, GetSysColorBrush (COLOR_3DFACE));
351 if (uFlags & DC_ACTIVE) {
352 HBRUSH hbr = SelectObject (hdc, CACHE_GetPattern55AABrush ());
353 PatBlt (hdc, rc.left, rc.top,
354 rc.right-rc.left, rc.bottom-rc.top, 0xFA0089);
355 SelectObject (hdc, hbr);
358 else {
359 FillRect (hdc, &rc, GetSysColorBrush ((uFlags & DC_ACTIVE) ?
360 COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
364 /* drawing icon */
365 if ((uFlags & DC_ICON) && !(uFlags & DC_SMALLCAP)) {
366 POINT pt;
368 pt.x = rc.left + 2;
369 pt.y = (rc.bottom + rc.top - GetSystemMetrics(SM_CYSMICON)) / 2;
371 if (hIcon) {
372 DrawIconEx (hdc, pt.x, pt.y, hIcon, GetSystemMetrics(SM_CXSMICON),
373 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
375 else {
376 WND* wndPtr = WIN_FindWndPtr(hwnd);
377 HICON hAppIcon = (HICON) NC_IconForWindow(wndPtr);
378 DrawIconEx (hdc, pt.x, pt.y, hAppIcon, GetSystemMetrics(SM_CXSMICON),
379 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
380 WIN_ReleaseWndPtr(wndPtr);
383 rc.left += (rc.bottom - rc.top);
386 /* drawing text */
387 if (uFlags & DC_TEXT) {
388 HFONT hOldFont;
390 if (uFlags & DC_INBUTTON)
391 SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
392 else if (uFlags & DC_ACTIVE)
393 SetTextColor (hdc, GetSysColor (COLOR_CAPTIONTEXT));
394 else
395 SetTextColor (hdc, GetSysColor (COLOR_INACTIVECAPTIONTEXT));
397 SetBkMode (hdc, TRANSPARENT);
399 if (hFont)
400 hOldFont = SelectObject (hdc, hFont);
401 else {
402 NONCLIENTMETRICSA nclm;
403 HFONT hNewFont;
404 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
405 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
406 hNewFont = CreateFontIndirectA ((uFlags & DC_SMALLCAP) ?
407 &nclm.lfSmCaptionFont : &nclm.lfCaptionFont);
408 hOldFont = SelectObject (hdc, hNewFont);
411 if (str)
412 DrawTextA (hdc, str, -1, &rc,
413 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
414 else {
415 CHAR szText[128];
416 INT nLen;
417 nLen = GetWindowTextA (hwnd, szText, 128);
418 DrawTextA (hdc, szText, nLen, &rc,
419 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
422 if (hFont)
423 SelectObject (hdc, hOldFont);
424 else
425 DeleteObject (SelectObject (hdc, hOldFont));
428 /* drawing focus ??? */
429 if (uFlags & 0x2000)
430 FIXME("undocumented flag (0x2000)!\n");
432 return 0;
436 /***********************************************************************
437 * DrawCaptionTempW (USER32.@)
439 * PARAMS
441 * RETURNS
442 * Success:
443 * Failure:
446 BOOL WINAPI
447 DrawCaptionTempW (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
448 HICON hIcon, LPCWSTR str, UINT uFlags)
450 LPSTR p = HEAP_strdupWtoA (GetProcessHeap (), 0, str);
451 BOOL res = DrawCaptionTempA (hwnd, hdc, rect, hFont, hIcon, p, uFlags);
452 HeapFree (GetProcessHeap (), 0, p);
453 return res;
457 /***********************************************************************
458 * AdjustWindowRect (USER.102)
460 BOOL16 WINAPI AdjustWindowRect16( LPRECT16 rect, DWORD style, BOOL16 menu )
462 return AdjustWindowRectEx16( rect, style, menu, 0 );
466 /***********************************************************************
467 * AdjustWindowRect (USER32.@)
469 BOOL WINAPI AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu )
471 return AdjustWindowRectEx( rect, style, menu, 0 );
475 /***********************************************************************
476 * AdjustWindowRectEx (USER.454)
478 BOOL16 WINAPI AdjustWindowRectEx16( LPRECT16 rect, DWORD style,
479 BOOL16 menu, DWORD exStyle )
481 /* Correct the window style */
483 if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
484 style |= WS_CAPTION;
485 style &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD);
486 exStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE |
487 WS_EX_STATICEDGE | WS_EX_TOOLWINDOW);
488 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
490 TRACE("(%d,%d)-(%d,%d) %08lx %d %08lx\n",
491 rect->left, rect->top, rect->right, rect->bottom,
492 style, menu, exStyle );
494 if (TWEAK_WineLook == WIN31_LOOK)
495 NC_AdjustRect( rect, style, menu, exStyle );
496 else {
497 NC_AdjustRectOuter95( rect, style, menu, exStyle );
498 NC_AdjustRectInner95( rect, style, exStyle );
501 return TRUE;
505 /***********************************************************************
506 * AdjustWindowRectEx (USER32.@)
508 BOOL WINAPI AdjustWindowRectEx( LPRECT rect, DWORD style,
509 BOOL menu, DWORD exStyle )
511 RECT16 rect16;
512 BOOL ret;
514 CONV_RECT32TO16( rect, &rect16 );
515 ret = AdjustWindowRectEx16( &rect16, style, (BOOL16)menu, exStyle );
516 CONV_RECT16TO32( &rect16, rect );
517 return ret;
521 /***********************************************************************
522 * NC_HandleNCCalcSize
524 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
526 LONG NC_HandleNCCalcSize( WND *pWnd, RECT *winRect )
528 RECT16 tmpRect = { 0, 0, 0, 0 };
529 LONG result = 0;
530 UINT style = (UINT) GetClassLongA(pWnd->hwndSelf, GCL_STYLE);
532 if (style & CS_VREDRAW) result |= WVR_VREDRAW;
533 if (style & CS_HREDRAW) result |= WVR_HREDRAW;
535 if( !( pWnd->dwStyle & WS_MINIMIZE ) ) {
536 if (TWEAK_WineLook == WIN31_LOOK)
537 NC_AdjustRect( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
538 else
539 NC_AdjustRectOuter95( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
541 winRect->left -= tmpRect.left;
542 winRect->top -= tmpRect.top;
543 winRect->right -= tmpRect.right;
544 winRect->bottom -= tmpRect.bottom;
546 if (HAS_MENU(pWnd)) {
547 TRACE("Calling GetMenuBarHeight with HWND 0x%x, width %d, "
548 "at (%d, %d).\n", pWnd->hwndSelf,
549 winRect->right - winRect->left,
550 -tmpRect.left, -tmpRect.top );
552 winRect->top +=
553 MENU_GetMenuBarHeight( pWnd->hwndSelf,
554 winRect->right - winRect->left,
555 -tmpRect.left, -tmpRect.top ) + 1;
558 if (TWEAK_WineLook > WIN31_LOOK) {
559 SetRect16 (&tmpRect, 0, 0, 0, 0);
560 NC_AdjustRectInner95 (&tmpRect, pWnd->dwStyle, pWnd->dwExStyle);
561 winRect->left -= tmpRect.left;
562 winRect->top -= tmpRect.top;
563 winRect->right -= tmpRect.right;
564 winRect->bottom -= tmpRect.bottom;
567 if (winRect->top > winRect->bottom)
568 winRect->bottom = winRect->top;
570 if (winRect->left > winRect->right)
571 winRect->right = winRect->left;
573 return result;
577 /***********************************************************************
578 * NC_GetInsideRect
580 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
581 * but without the borders (if any).
582 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
584 static void NC_GetInsideRect( HWND hwnd, RECT *rect )
586 WND * wndPtr = WIN_FindWndPtr( hwnd );
588 rect->top = rect->left = 0;
589 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
590 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
592 if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->dwExStyle & WS_EX_MANAGED)) goto END;
594 /* Remove frame from rectangle */
595 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
596 InflateRect( rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
597 else
598 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
600 InflateRect( rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
601 /* FIXME: this isn't in NC_AdjustRect? why not? */
602 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
603 InflateRect( rect, -1, 0 );
605 else
606 if (HAS_THINFRAME( wndPtr->dwStyle ))
607 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
608 END:
609 WIN_ReleaseWndPtr(wndPtr);
610 return;
614 /***********************************************************************
615 * NC_GetInsideRect95
617 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
618 * but without the borders (if any).
619 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
622 static void
623 NC_GetInsideRect95 (HWND hwnd, RECT *rect)
625 WND * wndPtr = WIN_FindWndPtr( hwnd );
627 rect->top = rect->left = 0;
628 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
629 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
631 if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->dwExStyle & WS_EX_MANAGED)) goto END;
633 /* Remove frame from rectangle */
634 if (HAS_THICKFRAME (wndPtr->dwStyle, wndPtr->dwExStyle))
636 InflateRect( rect, -GetSystemMetrics(SM_CXSIZEFRAME), -GetSystemMetrics(SM_CYSIZEFRAME) );
638 else if (HAS_DLGFRAME (wndPtr->dwStyle, wndPtr->dwExStyle ))
640 InflateRect( rect, -GetSystemMetrics(SM_CXFIXEDFRAME), -GetSystemMetrics(SM_CYFIXEDFRAME));
642 else if (HAS_THINFRAME (wndPtr->dwStyle))
644 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
647 /* We have additional border information if the window
648 * is a child (but not an MDI child) */
649 if ( (wndPtr->dwStyle & WS_CHILD) &&
650 ( (wndPtr->dwExStyle & WS_EX_MDICHILD) == 0 ) )
652 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
653 InflateRect (rect, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE));
655 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
656 InflateRect (rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
658 END:
659 WIN_ReleaseWndPtr(wndPtr);
660 return;
664 /***********************************************************************
665 * NC_DoNCHitTest
667 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
670 static LONG NC_DoNCHitTest (WND *wndPtr, POINT pt )
672 RECT rect;
674 TRACE("hwnd=%04x pt=%ld,%ld\n", wndPtr->hwndSelf, pt.x, pt.y );
676 GetWindowRect(wndPtr->hwndSelf, &rect );
677 if (!PtInRect( &rect, pt )) return HTNOWHERE;
679 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
681 if (!(wndPtr->dwExStyle & WS_EX_MANAGED))
683 /* Check borders */
684 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
686 InflateRect( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
687 if (!PtInRect( &rect, pt ))
689 /* Check top sizing border */
690 if (pt.y < rect.top)
692 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
693 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
694 return HTTOP;
696 /* Check bottom sizing border */
697 if (pt.y >= rect.bottom)
699 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
700 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
701 return HTBOTTOM;
703 /* Check left sizing border */
704 if (pt.x < rect.left)
706 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
707 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
708 return HTLEFT;
710 /* Check right sizing border */
711 if (pt.x >= rect.right)
713 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
714 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
715 return HTRIGHT;
719 else /* No thick frame */
721 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
722 InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
723 else if (HAS_THINFRAME( wndPtr->dwStyle ))
724 InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
725 if (!PtInRect( &rect, pt )) return HTBORDER;
728 /* Check caption */
730 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
732 rect.top += GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
733 if (!PtInRect( &rect, pt ))
735 /* Check system menu */
736 if ((wndPtr->dwStyle & WS_SYSMENU) && !(wndPtr->dwExStyle & WS_EX_TOOLWINDOW))
737 rect.left += GetSystemMetrics(SM_CXSIZE);
738 if (pt.x <= rect.left) return HTSYSMENU;
740 /* Check maximize box */
741 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
742 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
744 if (pt.x >= rect.right) return HTMAXBUTTON;
745 /* Check minimize box */
746 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
747 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
748 if (pt.x >= rect.right) return HTMINBUTTON;
749 return HTCAPTION;
754 /* Check client area */
756 ScreenToClient( wndPtr->hwndSelf, &pt );
757 GetClientRect( wndPtr->hwndSelf, &rect );
758 if (PtInRect( &rect, pt )) return HTCLIENT;
760 /* Check vertical scroll bar */
762 if (wndPtr->dwStyle & WS_VSCROLL)
764 rect.right += GetSystemMetrics(SM_CXVSCROLL);
765 if (PtInRect( &rect, pt )) return HTVSCROLL;
768 /* Check horizontal scroll bar */
770 if (wndPtr->dwStyle & WS_HSCROLL)
772 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
773 if (PtInRect( &rect, pt ))
775 /* Check size box */
776 if ((wndPtr->dwStyle & WS_VSCROLL) &&
777 (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
778 return HTSIZE;
779 return HTHSCROLL;
783 /* Check menu bar */
785 if (HAS_MENU(wndPtr))
787 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
788 return HTMENU;
791 /* Has to return HTNOWHERE if nothing was found
792 Could happen when a window has a customized non client area */
793 return HTNOWHERE;
797 /***********************************************************************
798 * NC_DoNCHitTest95
800 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
802 * FIXME: Just a modified copy of the Win 3.1 version.
805 static LONG NC_DoNCHitTest95 (WND *wndPtr, POINT pt )
807 RECT rect;
809 TRACE("hwnd=%04x pt=%ld,%ld\n", wndPtr->hwndSelf, pt.x, pt.y );
811 GetWindowRect(wndPtr->hwndSelf, &rect );
812 if (!PtInRect( &rect, pt )) return HTNOWHERE;
814 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
816 if (!(wndPtr->dwExStyle & WS_EX_MANAGED))
818 /* Check borders */
819 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
821 InflateRect( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
822 if (!PtInRect( &rect, pt ))
824 /* Check top sizing border */
825 if (pt.y < rect.top)
827 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
828 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
829 return HTTOP;
831 /* Check bottom sizing border */
832 if (pt.y >= rect.bottom)
834 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
835 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
836 return HTBOTTOM;
838 /* Check left sizing border */
839 if (pt.x < rect.left)
841 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
842 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
843 return HTLEFT;
845 /* Check right sizing border */
846 if (pt.x >= rect.right)
848 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
849 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
850 return HTRIGHT;
854 else /* No thick frame */
856 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
857 InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
858 else if (HAS_THINFRAME( wndPtr->dwStyle ))
859 InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
860 if (!PtInRect( &rect, pt )) return HTBORDER;
863 /* Check caption */
865 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
867 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
868 rect.top += GetSystemMetrics(SM_CYSMCAPTION) - 1;
869 else
870 rect.top += GetSystemMetrics(SM_CYCAPTION) - 1;
871 if (!PtInRect( &rect, pt ))
873 /* Check system menu */
874 if ((wndPtr->dwStyle & WS_SYSMENU) && !(wndPtr->dwExStyle & WS_EX_TOOLWINDOW))
876 if (NC_IconForWindow(wndPtr))
877 rect.left += GetSystemMetrics(SM_CYCAPTION) - 1;
879 if (pt.x < rect.left) return HTSYSMENU;
881 /* Check close button */
882 if (wndPtr->dwStyle & WS_SYSMENU)
883 rect.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
884 if (pt.x > rect.right) return HTCLOSE;
886 /* Check maximize box */
887 /* In win95 there is automatically a Maximize button when there is a minimize one*/
888 if ((wndPtr->dwStyle & WS_MAXIMIZEBOX)|| (wndPtr->dwStyle & WS_MINIMIZEBOX))
889 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
890 if (pt.x > rect.right) return HTMAXBUTTON;
892 /* Check minimize box */
893 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
894 if ((wndPtr->dwStyle & WS_MINIMIZEBOX)||(wndPtr->dwStyle & WS_MAXIMIZEBOX))
895 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
897 if (pt.x > rect.right) return HTMINBUTTON;
898 return HTCAPTION;
903 /* Check client area */
905 ScreenToClient( wndPtr->hwndSelf, &pt );
906 GetClientRect( wndPtr->hwndSelf, &rect );
907 if (PtInRect( &rect, pt )) return HTCLIENT;
909 /* Check vertical scroll bar */
911 if (wndPtr->dwStyle & WS_VSCROLL)
913 rect.right += GetSystemMetrics(SM_CXVSCROLL);
914 if (PtInRect( &rect, pt )) return HTVSCROLL;
917 /* Check horizontal scroll bar */
919 if (wndPtr->dwStyle & WS_HSCROLL)
921 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
922 if (PtInRect( &rect, pt ))
924 /* Check size box */
925 if ((wndPtr->dwStyle & WS_VSCROLL) &&
926 (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
927 return HTSIZE;
928 return HTHSCROLL;
932 /* Check menu bar */
934 if (HAS_MENU(wndPtr))
936 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
937 return HTMENU;
940 /* Has to return HTNOWHERE if nothing was found
941 Could happen when a window has a customized non client area */
942 return HTNOWHERE;
946 /***********************************************************************
947 * NC_HandleNCHitTest
949 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
951 LONG NC_HandleNCHitTest (HWND hwnd , POINT pt)
953 LONG retvalue;
954 WND *wndPtr = WIN_FindWndPtr (hwnd);
956 if (!wndPtr)
957 return HTERROR;
959 if (TWEAK_WineLook == WIN31_LOOK)
960 retvalue = NC_DoNCHitTest (wndPtr, pt);
961 else
962 retvalue = NC_DoNCHitTest95 (wndPtr, pt);
963 WIN_ReleaseWndPtr(wndPtr);
964 return retvalue;
968 /***********************************************************************
969 * NC_DrawSysButton
971 void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down )
973 RECT rect;
974 HDC hdcMem;
975 HBITMAP hbitmap;
976 WND *wndPtr = WIN_FindWndPtr( hwnd );
978 if( !(wndPtr->dwExStyle & WS_EX_MANAGED) )
980 NC_GetInsideRect( hwnd, &rect );
981 hdcMem = CreateCompatibleDC( hdc );
982 hbitmap = SelectObject( hdcMem, hbitmapClose );
983 BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE), GetSystemMetrics(SM_CYSIZE),
984 hdcMem, (wndPtr->dwStyle & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE) : 0, 0,
985 down ? NOTSRCCOPY : SRCCOPY );
986 SelectObject( hdcMem, hbitmap );
987 DeleteDC( hdcMem );
989 WIN_ReleaseWndPtr(wndPtr);
993 /***********************************************************************
994 * NC_DrawMaxButton
996 static void NC_DrawMaxButton( HWND hwnd, HDC16 hdc, BOOL down )
998 RECT rect;
999 WND *wndPtr = WIN_FindWndPtr( hwnd );
1000 HDC hdcMem;
1002 if( !(wndPtr->dwExStyle & WS_EX_MANAGED) )
1004 NC_GetInsideRect( hwnd, &rect );
1005 hdcMem = CreateCompatibleDC( hdc );
1006 SelectObject( hdcMem, (IsZoomed(hwnd)
1007 ? (down ? hbitmapRestoreD : hbitmapRestore)
1008 : (down ? hbitmapMaximizeD : hbitmapMaximize)) );
1009 BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
1010 GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
1011 SRCCOPY );
1012 DeleteDC( hdcMem );
1014 WIN_ReleaseWndPtr(wndPtr);
1019 /***********************************************************************
1020 * NC_DrawMinButton
1022 static void NC_DrawMinButton( HWND hwnd, HDC16 hdc, BOOL down )
1024 RECT rect;
1025 WND *wndPtr = WIN_FindWndPtr( hwnd );
1026 HDC hdcMem;
1028 if( !(wndPtr->dwExStyle & WS_EX_MANAGED) )
1030 NC_GetInsideRect( hwnd, &rect );
1031 hdcMem = CreateCompatibleDC( hdc );
1032 SelectObject( hdcMem, (down ? hbitmapMinimizeD : hbitmapMinimize) );
1033 if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= GetSystemMetrics(SM_CXSIZE)+1;
1034 BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
1035 GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
1036 SRCCOPY );
1037 DeleteDC( hdcMem );
1039 WIN_ReleaseWndPtr(wndPtr);
1043 /******************************************************************************
1045 * void NC_DrawSysButton95(
1046 * HWND hwnd,
1047 * HDC hdc,
1048 * BOOL down )
1050 * Draws the Win95 system icon.
1052 * Revision history
1053 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1054 * Original implementation from NC_DrawSysButton source.
1055 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1056 * Fixed most bugs.
1058 *****************************************************************************/
1060 BOOL
1061 NC_DrawSysButton95 (HWND hwnd, HDC hdc, BOOL down)
1063 WND *wndPtr = WIN_FindWndPtr( hwnd );
1065 if( !(wndPtr->dwExStyle & WS_EX_MANAGED) )
1067 HICON hIcon;
1068 RECT rect;
1070 NC_GetInsideRect95( hwnd, &rect );
1072 hIcon = NC_IconForWindow( wndPtr );
1074 if (hIcon)
1075 DrawIconEx (hdc, rect.left + 2, rect.top + 2, hIcon,
1076 GetSystemMetrics(SM_CXSMICON),
1077 GetSystemMetrics(SM_CYSMICON),
1078 0, 0, DI_NORMAL);
1080 WIN_ReleaseWndPtr(wndPtr);
1081 return (hIcon != 0);
1083 WIN_ReleaseWndPtr(wndPtr);
1084 return FALSE;
1088 /******************************************************************************
1090 * void NC_DrawCloseButton95(
1091 * HWND hwnd,
1092 * HDC hdc,
1093 * BOOL down,
1094 * BOOL bGrayed )
1096 * Draws the Win95 close button.
1098 * If bGrayed is true, then draw a disabled Close button
1100 * Revision history
1101 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1102 * Original implementation from NC_DrawSysButton95 source.
1104 *****************************************************************************/
1106 static void NC_DrawCloseButton95 (HWND hwnd, HDC hdc, BOOL down, BOOL bGrayed)
1108 RECT rect;
1109 HDC hdcMem;
1110 WND *wndPtr = WIN_FindWndPtr( hwnd );
1112 if( !(wndPtr->dwExStyle & WS_EX_MANAGED) )
1114 BITMAP bmp;
1115 HBITMAP hBmp, hOldBmp;
1117 NC_GetInsideRect95( hwnd, &rect );
1119 /* A tool window has a smaller Close button */
1120 if(wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
1122 RECT toolRect;
1123 INT iBmpHeight = 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
1124 INT iBmpWidth = 11; /* it uses 11x11 for the close button in tool window */
1125 INT iCaptionHeight = GetSystemMetrics(SM_CYSMCAPTION);
1127 toolRect.top = rect.top + (iCaptionHeight - 1 - iBmpHeight) / 2;
1128 toolRect.left = rect.right - (iCaptionHeight + 1 + iBmpWidth) / 2;
1129 toolRect.bottom = toolRect.top + iBmpHeight;
1130 toolRect.right = toolRect.left + iBmpWidth;
1131 DrawFrameControl(hdc,&toolRect,
1132 DFC_CAPTION,DFCS_CAPTIONCLOSE |
1133 down ? DFCS_PUSHED : 0 |
1134 bGrayed ? DFCS_INACTIVE : 0);
1136 else
1138 hdcMem = CreateCompatibleDC( hdc );
1139 hBmp = down ? hbitmapCloseD : hbitmapClose;
1140 hOldBmp = SelectObject (hdcMem, hBmp);
1141 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1143 BitBlt (hdc, rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2,
1144 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1145 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);
1147 if(bGrayed)
1148 NC_DrawGrayButton(hdc,rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2 + 2,
1149 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1151 SelectObject (hdcMem, hOldBmp);
1152 DeleteDC (hdcMem);
1155 WIN_ReleaseWndPtr(wndPtr);
1158 /******************************************************************************
1160 * NC_DrawMaxButton95(
1161 * HWND hwnd,
1162 * HDC16 hdc,
1163 * BOOL down
1164 * BOOL bGrayed )
1166 * Draws the maximize button for Win95 style windows.
1168 * If bGrayed is true, then draw a disabled Maximize button
1170 * Bugs
1171 * Many. Spacing might still be incorrect. Need to fit a close
1172 * button between the max button and the edge.
1173 * Should scale the image with the title bar. And more...
1175 * Revision history
1176 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1177 * Original implementation.
1179 *****************************************************************************/
1181 static void NC_DrawMaxButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
1183 RECT rect;
1184 HDC hdcMem;
1185 WND *wndPtr = WIN_FindWndPtr( hwnd );
1187 if( !(wndPtr->dwExStyle & WS_EX_MANAGED))
1189 BITMAP bmp;
1190 HBITMAP hBmp,hOldBmp;
1192 NC_GetInsideRect95( hwnd, &rect );
1193 hdcMem = CreateCompatibleDC( hdc );
1194 hBmp = IsZoomed(hwnd) ?
1195 (down ? hbitmapRestoreD : hbitmapRestore ) :
1196 (down ? hbitmapMaximizeD: hbitmapMaximize);
1197 hOldBmp=SelectObject( hdcMem, hBmp );
1198 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1200 if (wndPtr->dwStyle & WS_SYSMENU)
1201 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1203 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1204 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1205 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1207 if(bGrayed)
1208 NC_DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
1209 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1212 SelectObject (hdcMem, hOldBmp);
1213 DeleteDC( hdcMem );
1215 WIN_ReleaseWndPtr(wndPtr);
1218 /******************************************************************************
1220 * NC_DrawMinButton95(
1221 * HWND hwnd,
1222 * HDC16 hdc,
1223 * BOOL down,
1224 * BOOL bGrayed )
1226 * Draws the minimize button for Win95 style windows.
1228 * If bGrayed is true, then draw a disabled Minimize button
1230 * Bugs
1231 * Many. Spacing is still incorrect. Should scale the image with the
1232 * title bar. And more...
1234 * Revision history
1235 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1236 * Original implementation.
1238 *****************************************************************************/
1240 static void NC_DrawMinButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
1242 RECT rect;
1243 HDC hdcMem;
1244 WND *wndPtr = WIN_FindWndPtr( hwnd );
1246 if( !(wndPtr->dwExStyle & WS_EX_MANAGED))
1249 BITMAP bmp;
1250 HBITMAP hBmp,hOldBmp;
1252 NC_GetInsideRect95( hwnd, &rect );
1254 hdcMem = CreateCompatibleDC( hdc );
1255 hBmp = down ? hbitmapMinimizeD : hbitmapMinimize;
1256 hOldBmp= SelectObject( hdcMem, hBmp );
1257 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1259 if (wndPtr->dwStyle & WS_SYSMENU)
1260 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1262 /* In win 95 there is always a Maximize box when there is a Minimize one */
1263 if ((wndPtr->dwStyle & WS_MAXIMIZEBOX) || (wndPtr->dwStyle & WS_MINIMIZEBOX))
1264 rect.right += -1 - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2;
1266 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1267 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1268 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1270 if(bGrayed)
1271 NC_DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
1272 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1275 SelectObject (hdcMem, hOldBmp);
1276 DeleteDC( hdcMem );
1278 WIN_ReleaseWndPtr(wndPtr);
1281 /***********************************************************************
1282 * NC_DrawFrame
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.
1287 static void NC_DrawFrame( HDC hdc, RECT *rect, BOOL dlgFrame,
1288 BOOL active )
1290 INT width, height;
1292 if (TWEAK_WineLook != WIN31_LOOK)
1293 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
1295 if (dlgFrame)
1297 width = GetSystemMetrics(SM_CXDLGFRAME) - 1;
1298 height = GetSystemMetrics(SM_CYDLGFRAME) - 1;
1299 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1300 COLOR_INACTIVECAPTION) );
1302 else
1304 width = GetSystemMetrics(SM_CXFRAME) - 2;
1305 height = GetSystemMetrics(SM_CYFRAME) - 2;
1306 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1307 COLOR_INACTIVEBORDER) );
1310 /* Draw frame */
1311 PatBlt( hdc, rect->left, rect->top,
1312 rect->right - rect->left, height, PATCOPY );
1313 PatBlt( hdc, rect->left, rect->top,
1314 width, rect->bottom - rect->top, PATCOPY );
1315 PatBlt( hdc, rect->left, rect->bottom - 1,
1316 rect->right - rect->left, -height, PATCOPY );
1317 PatBlt( hdc, rect->right - 1, rect->top,
1318 -width, rect->bottom - rect->top, PATCOPY );
1320 if (dlgFrame)
1322 InflateRect( rect, -width, -height );
1324 else
1326 INT decYOff = GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXSIZE) - 1;
1327 INT decXOff = GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYSIZE) - 1;
1329 /* Draw inner rectangle */
1331 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1332 Rectangle( hdc, rect->left + width, rect->top + height,
1333 rect->right - width , rect->bottom - height );
1335 /* Draw the decorations */
1337 MoveToEx( hdc, rect->left, rect->top + decYOff, NULL );
1338 LineTo( hdc, rect->left + width, rect->top + decYOff );
1339 MoveToEx( hdc, rect->right - 1, rect->top + decYOff, NULL );
1340 LineTo( hdc, rect->right - width - 1, rect->top + decYOff );
1341 MoveToEx( hdc, rect->left, rect->bottom - decYOff, NULL );
1342 LineTo( hdc, rect->left + width, rect->bottom - decYOff );
1343 MoveToEx( hdc, rect->right - 1, rect->bottom - decYOff, NULL );
1344 LineTo( hdc, rect->right - width - 1, rect->bottom - decYOff );
1346 MoveToEx( hdc, rect->left + decXOff, rect->top, NULL );
1347 LineTo( hdc, rect->left + decXOff, rect->top + height);
1348 MoveToEx( hdc, rect->left + decXOff, rect->bottom - 1, NULL );
1349 LineTo( hdc, rect->left + decXOff, rect->bottom - height - 1 );
1350 MoveToEx( hdc, rect->right - decXOff, rect->top, NULL );
1351 LineTo( hdc, rect->right - decXOff, rect->top + height );
1352 MoveToEx( hdc, rect->right - decXOff, rect->bottom - 1, NULL );
1353 LineTo( hdc, rect->right - decXOff, rect->bottom - height - 1 );
1355 InflateRect( rect, -width - 1, -height - 1 );
1360 /******************************************************************************
1362 * void NC_DrawFrame95(
1363 * HDC hdc,
1364 * RECT *rect,
1365 * BOOL dlgFrame,
1366 * BOOL active )
1368 * Draw a window frame inside the given rectangle, and update the rectangle.
1369 * The correct pen for the frame must be selected in the DC.
1371 * Bugs
1372 * Many. First, just what IS a frame in Win95? Note that the 3D look
1373 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1374 * edge. The inner rectangle just inside the frame is handled by the
1375 * Caption code.
1377 * In short, for most people, this function should be a nop (unless
1378 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1379 * them lately, but just to get this code right). Even so, it doesn't
1380 * appear to be so. It's being worked on...
1382 * Revision history
1383 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1384 * Original implementation (based on NC_DrawFrame)
1385 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1386 * Some minor fixes.
1387 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1388 * Fixed a fix or something.
1390 *****************************************************************************/
1392 static void NC_DrawFrame95(
1393 HDC hdc,
1394 RECT *rect,
1395 BOOL dlgFrame,
1396 BOOL active )
1398 INT width, height;
1400 if (dlgFrame)
1402 width = GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
1403 height = GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
1405 else
1407 width = GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXEDGE);
1408 height = GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYEDGE);
1411 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1412 COLOR_INACTIVEBORDER) );
1414 /* Draw frame */
1415 PatBlt( hdc, rect->left, rect->top,
1416 rect->right - rect->left, height, PATCOPY );
1417 PatBlt( hdc, rect->left, rect->top,
1418 width, rect->bottom - rect->top, PATCOPY );
1419 PatBlt( hdc, rect->left, rect->bottom - 1,
1420 rect->right - rect->left, -height, PATCOPY );
1421 PatBlt( hdc, rect->right - 1, rect->top,
1422 -width, rect->bottom - rect->top, PATCOPY );
1424 InflateRect( rect, -width, -height );
1427 /***********************************************************************
1428 * NC_DrawMovingFrame
1430 * Draw the frame used when moving or resizing window.
1432 * FIXME: This causes problems in Win95 mode. (why?)
1434 static void NC_DrawMovingFrame( HDC hdc, RECT *rect, BOOL thickframe )
1436 if (thickframe)
1438 RECT16 r16;
1439 CONV_RECT32TO16( rect, &r16 );
1440 FastWindowFrame16( hdc, &r16, GetSystemMetrics(SM_CXFRAME),
1441 GetSystemMetrics(SM_CYFRAME), PATINVERT );
1443 else DrawFocusRect( hdc, rect );
1447 /***********************************************************************
1448 * NC_DrawCaption
1450 * Draw the window caption.
1451 * The correct pen for the window frame must be selected in the DC.
1453 static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd,
1454 DWORD style, BOOL active )
1456 RECT r = *rect;
1457 WND * wndPtr = WIN_FindWndPtr( hwnd );
1458 char buffer[256];
1460 if (wndPtr->dwExStyle & WS_EX_MANAGED)
1462 WIN_ReleaseWndPtr(wndPtr);
1463 return;
1466 if (!hbitmapClose)
1468 if (!(hbitmapClose = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_CLOSE) )))
1470 WIN_ReleaseWndPtr(wndPtr);
1471 return;
1473 hbitmapCloseD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_CLOSED) );
1474 hbitmapMinimize = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_REDUCE) );
1475 hbitmapMinimizeD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_REDUCED) );
1476 hbitmapMaximize = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_ZOOM) );
1477 hbitmapMaximizeD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_ZOOMD) );
1478 hbitmapRestore = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RESTORE) );
1479 hbitmapRestoreD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RESTORED) );
1482 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
1484 HBRUSH hbrushOld = SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW) );
1485 PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
1486 PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
1487 PatBlt( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
1488 r.left++;
1489 r.right--;
1490 SelectObject( hdc, hbrushOld );
1492 WIN_ReleaseWndPtr(wndPtr);
1493 MoveToEx( hdc, r.left, r.bottom, NULL );
1494 LineTo( hdc, r.right, r.bottom );
1496 if (style & WS_SYSMENU)
1498 NC_DrawSysButton( hwnd, hdc, FALSE );
1499 r.left += GetSystemMetrics(SM_CXSIZE) + 1;
1500 MoveToEx( hdc, r.left - 1, r.top, NULL );
1501 LineTo( hdc, r.left - 1, r.bottom );
1503 if (style & WS_MAXIMIZEBOX)
1505 NC_DrawMaxButton( hwnd, hdc, FALSE );
1506 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1508 if (style & WS_MINIMIZEBOX)
1510 NC_DrawMinButton( hwnd, hdc, FALSE );
1511 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1514 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1515 COLOR_INACTIVECAPTION) );
1517 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) ))
1519 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1520 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1521 SetBkMode( hdc, TRANSPARENT );
1522 DrawTextA( hdc, buffer, -1, &r,
1523 DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );
1528 /******************************************************************************
1530 * NC_DrawCaption95(
1531 * HDC hdc,
1532 * RECT *rect,
1533 * HWND hwnd,
1534 * DWORD style,
1535 * BOOL active )
1537 * Draw the window caption for Win95 style windows.
1538 * The correct pen for the window frame must be selected in the DC.
1540 * Bugs
1541 * Hey, a function that finally works! Well, almost.
1542 * It's being worked on.
1544 * Revision history
1545 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1546 * Original implementation.
1547 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1548 * Some minor fixes.
1550 *****************************************************************************/
1552 static void NC_DrawCaption95(
1553 HDC hdc,
1554 RECT *rect,
1555 HWND hwnd,
1556 DWORD style,
1557 DWORD exStyle,
1558 BOOL active )
1560 RECT r = *rect;
1561 WND *wndPtr = WIN_FindWndPtr( hwnd );
1562 char buffer[256];
1563 HPEN hPrevPen;
1564 HMENU hSysMenu;
1566 if (wndPtr->dwExStyle & WS_EX_MANAGED)
1568 WIN_ReleaseWndPtr(wndPtr);
1569 return;
1571 WIN_ReleaseWndPtr(wndPtr);
1573 hPrevPen = SelectObject( hdc, GetSysColorPen(COLOR_3DFACE) );
1574 MoveToEx( hdc, r.left, r.bottom - 1, NULL );
1575 LineTo( hdc, r.right, r.bottom - 1 );
1576 SelectObject( hdc, hPrevPen );
1577 r.bottom--;
1579 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1580 COLOR_INACTIVECAPTION) );
1582 if (!hbitmapClose) {
1583 if (!(hbitmapClose = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_CLOSE) )))
1584 return;
1585 hbitmapCloseD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_CLOSED));
1586 hbitmapMinimize = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_REDUCE) );
1587 hbitmapMinimizeD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_REDUCED) );
1588 hbitmapMaximize = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_ZOOM) );
1589 hbitmapMaximizeD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_ZOOMD) );
1590 hbitmapRestore = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RESTORE) );
1591 hbitmapRestoreD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RESTORED) );
1594 if ((style & WS_SYSMENU) && !(exStyle & WS_EX_TOOLWINDOW)) {
1595 if (NC_DrawSysButton95 (hwnd, hdc, FALSE))
1596 r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
1599 if (style & WS_SYSMENU)
1601 UINT state;
1603 /* Go get the sysmenu */
1604 hSysMenu = GetSystemMenu(hwnd, FALSE);
1605 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
1607 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1608 NC_DrawCloseButton95 (hwnd, hdc, FALSE,
1609 ((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
1610 r.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
1612 if ((style & WS_MAXIMIZEBOX) || (style & WS_MINIMIZEBOX))
1614 /* In win95 the two buttons are always there */
1615 /* But if the menu item is not in the menu they're disabled*/
1617 NC_DrawMaxButton95( hwnd, hdc, FALSE, (!(style & WS_MAXIMIZEBOX)));
1618 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1620 NC_DrawMinButton95( hwnd, hdc, FALSE, (!(style & WS_MINIMIZEBOX)));
1621 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1625 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) )) {
1626 NONCLIENTMETRICSA nclm;
1627 HFONT hFont, hOldFont;
1628 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1629 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1630 if (exStyle & WS_EX_TOOLWINDOW)
1631 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
1632 else
1633 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
1634 hOldFont = SelectObject (hdc, hFont);
1635 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1636 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1637 SetBkMode( hdc, TRANSPARENT );
1638 r.left += 2;
1639 DrawTextA( hdc, buffer, -1, &r,
1640 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
1641 DeleteObject (SelectObject (hdc, hOldFont));
1647 /***********************************************************************
1648 * NC_DoNCPaint
1650 * Paint the non-client area. clip is currently unused.
1652 static void NC_DoNCPaint( WND* wndPtr, HRGN clip, BOOL suppress_menupaint )
1654 HDC hdc;
1655 RECT rect;
1656 BOOL active;
1657 HWND hwnd = wndPtr->hwndSelf;
1659 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1660 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1662 active = wndPtr->flags & WIN_NCACTIVATED;
1664 TRACE("%04x %d\n", hwnd, active );
1666 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1667 ((clip > 1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN): 0) ))) return;
1669 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1670 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1671 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1672 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1673 == NULLREGION)
1675 ReleaseDC( hwnd, hdc );
1676 return;
1679 rect.top = rect.left = 0;
1680 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1681 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1683 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1685 if (!(wndPtr->dwExStyle & WS_EX_MANAGED))
1687 if (HAS_ANYFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1689 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1690 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1691 InflateRect( &rect, -1, -1 );
1694 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1695 NC_DrawFrame(hdc, &rect, FALSE, active );
1696 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1697 NC_DrawFrame( hdc, &rect, TRUE, active );
1699 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1701 RECT r = rect;
1702 r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
1703 rect.top += GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYBORDER);
1704 NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active );
1708 if (HAS_MENU(wndPtr))
1710 RECT r = rect;
1711 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU); /* default height */
1712 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint );
1715 /* Draw the scroll-bars */
1717 if (wndPtr->dwStyle & WS_VSCROLL)
1718 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1719 if (wndPtr->dwStyle & WS_HSCROLL)
1720 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1722 /* Draw the "size-box" */
1724 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1726 RECT r = rect;
1727 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1728 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1729 if(wndPtr->dwStyle & WS_BORDER) {
1730 r.left++;
1731 r.top++;
1733 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1736 ReleaseDC( hwnd, hdc );
1740 /******************************************************************************
1742 * void NC_DoNCPaint95(
1743 * WND *wndPtr,
1744 * HRGN clip,
1745 * BOOL suppress_menupaint )
1747 * Paint the non-client area for Win95 windows. The clip region is
1748 * currently ignored.
1750 * Bugs
1751 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1752 * misc/tweak.c controls/menu.c # :-)
1754 * Revision history
1755 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1756 * Original implementation
1757 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1758 * Fixed some bugs.
1759 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1760 * Streamlined window style checks.
1762 *****************************************************************************/
1764 static void NC_DoNCPaint95(
1765 WND *wndPtr,
1766 HRGN clip,
1767 BOOL suppress_menupaint )
1769 HDC hdc;
1770 RECT rfuzz, rect, rectClip;
1771 BOOL active;
1772 HWND hwnd = wndPtr->hwndSelf;
1774 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1775 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1777 active = wndPtr->flags & WIN_NCACTIVATED;
1779 TRACE("%04x %d\n", hwnd, active );
1781 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1782 the call to GetDCEx implying that it is allowed not to use it either.
1783 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1784 will cause clipRgn to be deleted after ReleaseDC().
1785 Now, how is the "system" supposed to tell what happened?
1788 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1789 ((clip > 1) ?(DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0) ))) return;
1792 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1793 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1794 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1795 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1796 == NULLREGION)
1798 ReleaseDC( hwnd, hdc );
1799 return;
1802 rect.top = rect.left = 0;
1803 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1804 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1806 if( clip > 1 )
1807 GetRgnBox( clip, &rectClip );
1808 else
1810 clip = 0;
1811 rectClip = rect;
1814 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1816 if(!(wndPtr->dwExStyle & WS_EX_MANAGED)) {
1817 if (HAS_BIGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle)) {
1818 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1820 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1821 NC_DrawFrame95(hdc, &rect, FALSE, active );
1822 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1823 NC_DrawFrame95( hdc, &rect, TRUE, active );
1824 else if (HAS_THINFRAME( wndPtr->dwStyle )) {
1825 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1826 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1829 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1831 RECT r = rect;
1832 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW) {
1833 r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
1834 rect.top += GetSystemMetrics(SM_CYSMCAPTION);
1836 else {
1837 r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
1838 rect.top += GetSystemMetrics(SM_CYCAPTION);
1840 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
1841 NC_DrawCaption95 (hdc, &r, hwnd, wndPtr->dwStyle,
1842 wndPtr->dwExStyle, active);
1846 if (HAS_MENU(wndPtr))
1848 RECT r = rect;
1849 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
1851 TRACE("Calling DrawMenuBar with rect (%d, %d)-(%d, %d)\n",
1852 r.left, r.top, r.right, r.bottom);
1854 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ) + 1;
1857 TRACE("After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1858 rect.left, rect.top, rect.right, rect.bottom );
1860 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
1861 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1863 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
1864 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1866 /* Draw the scroll-bars */
1868 if (wndPtr->dwStyle & WS_VSCROLL)
1869 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1870 if (wndPtr->dwStyle & WS_HSCROLL)
1871 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1873 /* Draw the "size-box" */
1874 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1876 RECT r = rect;
1877 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1878 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1879 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1882 ReleaseDC( hwnd, hdc );
1888 /***********************************************************************
1889 * NC_HandleNCPaint
1891 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1893 LONG NC_HandleNCPaint( HWND hwnd , HRGN clip)
1895 WND* wndPtr = WIN_FindWndPtr( hwnd );
1897 if( wndPtr && wndPtr->dwStyle & WS_VISIBLE )
1899 if( wndPtr->dwStyle & WS_MINIMIZE )
1900 WINPOS_RedrawIconTitle( hwnd );
1901 else if (TWEAK_WineLook == WIN31_LOOK)
1902 NC_DoNCPaint( wndPtr, clip, FALSE );
1903 else
1904 NC_DoNCPaint95( wndPtr, clip, FALSE );
1906 WIN_ReleaseWndPtr(wndPtr);
1907 return 0;
1911 /***********************************************************************
1912 * NC_HandleNCActivate
1914 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1916 LONG NC_HandleNCActivate( WND *wndPtr, WPARAM16 wParam )
1918 WORD wStateChange;
1920 if( wParam ) wStateChange = !(wndPtr->flags & WIN_NCACTIVATED);
1921 else wStateChange = wndPtr->flags & WIN_NCACTIVATED;
1923 if( wStateChange )
1925 if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
1926 else wndPtr->flags &= ~WIN_NCACTIVATED;
1928 if( wndPtr->dwStyle & WS_MINIMIZE )
1929 WINPOS_RedrawIconTitle( wndPtr->hwndSelf );
1930 else if (TWEAK_WineLook == WIN31_LOOK)
1931 NC_DoNCPaint( wndPtr, (HRGN)1, FALSE );
1932 else
1933 NC_DoNCPaint95( wndPtr, (HRGN)1, FALSE );
1935 return TRUE;
1939 /***********************************************************************
1940 * NC_HandleSetCursor
1942 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1944 LONG NC_HandleSetCursor( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
1946 if (hwnd != (HWND)wParam) return 0; /* Don't set the cursor for child windows */
1948 switch(LOWORD(lParam))
1950 case HTERROR:
1952 WORD msg = HIWORD( lParam );
1953 if ((msg == WM_LBUTTONDOWN) || (msg == WM_MBUTTONDOWN) ||
1954 (msg == WM_RBUTTONDOWN))
1955 MessageBeep(0);
1957 break;
1959 case HTCLIENT:
1961 HICON16 hCursor = (HICON16) GetClassWord(hwnd, GCW_HCURSOR);
1962 if(hCursor) {
1963 SetCursor16(hCursor);
1964 return TRUE;
1966 return FALSE;
1969 case HTLEFT:
1970 case HTRIGHT:
1971 return (LONG)SetCursor( LoadCursorA( 0, IDC_SIZEWEA ) );
1973 case HTTOP:
1974 case HTBOTTOM:
1975 return (LONG)SetCursor( LoadCursorA( 0, IDC_SIZENSA ) );
1977 case HTTOPLEFT:
1978 case HTBOTTOMRIGHT:
1979 return (LONG)SetCursor( LoadCursorA( 0, IDC_SIZENWSEA ) );
1981 case HTTOPRIGHT:
1982 case HTBOTTOMLEFT:
1983 return (LONG)SetCursor( LoadCursorA( 0, IDC_SIZENESWA ) );
1986 /* Default cursor: arrow */
1987 return (LONG)SetCursor( LoadCursorA( 0, IDC_ARROWA ) );
1990 /***********************************************************************
1991 * NC_GetSysPopupPos
1993 BOOL NC_GetSysPopupPos( WND* wndPtr, RECT* rect )
1995 if( wndPtr->hSysMenu )
1997 if( wndPtr->dwStyle & WS_MINIMIZE )
1998 GetWindowRect( wndPtr->hwndSelf, rect );
1999 else
2001 if (TWEAK_WineLook == WIN31_LOOK)
2002 NC_GetInsideRect( wndPtr->hwndSelf, rect );
2003 else
2004 NC_GetInsideRect95( wndPtr->hwndSelf, rect );
2005 OffsetRect( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
2006 if (wndPtr->dwStyle & WS_CHILD)
2007 ClientToScreen( wndPtr->parent->hwndSelf, (POINT *)rect );
2008 if (TWEAK_WineLook == WIN31_LOOK) {
2009 rect->right = rect->left + GetSystemMetrics(SM_CXSIZE);
2010 rect->bottom = rect->top + GetSystemMetrics(SM_CYSIZE);
2012 else {
2013 rect->right = rect->left + GetSystemMetrics(SM_CYCAPTION) - 1;
2014 rect->bottom = rect->top + GetSystemMetrics(SM_CYCAPTION) - 1;
2017 return TRUE;
2019 return FALSE;
2022 /***********************************************************************
2023 * NC_StartSizeMove
2025 * Initialisation of a move or resize, when initiatied from a menu choice.
2026 * Return hit test code for caption or sizing border.
2028 static LONG NC_StartSizeMove( WND* wndPtr, WPARAM16 wParam,
2029 POINT *capturePoint )
2031 LONG hittest = 0;
2032 POINT pt;
2033 MSG msg;
2034 RECT rectWindow;
2036 GetWindowRect(wndPtr->hwndSelf,&rectWindow);
2038 if ((wParam & 0xfff0) == SC_MOVE)
2040 /* Move pointer at the center of the caption */
2041 RECT rect;
2042 if (TWEAK_WineLook == WIN31_LOOK)
2043 NC_GetInsideRect( wndPtr->hwndSelf, &rect );
2044 else
2045 NC_GetInsideRect95( wndPtr->hwndSelf, &rect );
2046 if (wndPtr->dwStyle & WS_SYSMENU)
2047 rect.left += GetSystemMetrics(SM_CXSIZE) + 1;
2048 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
2049 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
2050 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
2051 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
2052 pt.x = rectWindow.left + (rect.right - rect.left) / 2;
2053 pt.y = rectWindow.top + rect.top + GetSystemMetrics(SM_CYSIZE)/2;
2054 hittest = HTCAPTION;
2055 *capturePoint = pt;
2057 else /* SC_SIZE */
2059 while(!hittest)
2061 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE, NULL );
2062 switch(msg.message)
2064 case WM_MOUSEMOVE:
2065 hittest = NC_HandleNCHitTest( wndPtr->hwndSelf, msg.pt );
2066 if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
2067 hittest = 0;
2068 break;
2070 case WM_LBUTTONUP:
2071 return 0;
2073 case WM_KEYDOWN:
2074 switch(msg.wParam)
2076 case VK_UP:
2077 hittest = HTTOP;
2078 pt.x =(rectWindow.left+rectWindow.right)/2;
2079 pt.y = rectWindow.top + GetSystemMetrics(SM_CYFRAME) / 2;
2080 break;
2081 case VK_DOWN:
2082 hittest = HTBOTTOM;
2083 pt.x =(rectWindow.left+rectWindow.right)/2;
2084 pt.y = rectWindow.bottom - GetSystemMetrics(SM_CYFRAME) / 2;
2085 break;
2086 case VK_LEFT:
2087 hittest = HTLEFT;
2088 pt.x = rectWindow.left + GetSystemMetrics(SM_CXFRAME) / 2;
2089 pt.y =(rectWindow.top+rectWindow.bottom)/2;
2090 break;
2091 case VK_RIGHT:
2092 hittest = HTRIGHT;
2093 pt.x = rectWindow.right - GetSystemMetrics(SM_CXFRAME) / 2;
2094 pt.y =(rectWindow.top+rectWindow.bottom)/2;
2095 break;
2096 case VK_RETURN:
2097 case VK_ESCAPE: return 0;
2101 *capturePoint = pt;
2103 SetCursorPos( pt.x, pt.y );
2104 NC_HandleSetCursor( wndPtr->hwndSelf,
2105 wndPtr->hwndSelf, MAKELONG( hittest, WM_MOUSEMOVE ));
2106 return hittest;
2110 /***********************************************************************
2111 * NC_DoSizeMove
2113 * Perform SC_MOVE and SC_SIZE commands. `
2115 static void NC_DoSizeMove( HWND hwnd, WORD wParam )
2117 MSG msg;
2118 RECT sizingRect, mouseRect, origRect;
2119 HDC hdc;
2120 LONG hittest = (LONG)(wParam & 0x0f);
2121 HCURSOR16 hDragCursor = 0, hOldCursor = 0;
2122 POINT minTrack, maxTrack;
2123 POINT capturePoint, pt;
2124 WND * wndPtr = WIN_FindWndPtr( hwnd );
2125 BOOL thickframe = HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle );
2126 BOOL iconic = wndPtr->dwStyle & WS_MINIMIZE;
2127 BOOL moved = FALSE;
2128 DWORD dwPoint = GetMessagePos ();
2129 BOOL DragFullWindows = FALSE;
2130 int iWndsLocks;
2132 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS, 0, &DragFullWindows, 0);
2134 pt.x = SLOWORD(dwPoint);
2135 pt.y = SHIWORD(dwPoint);
2136 capturePoint = pt;
2138 if (IsZoomed(hwnd) || !IsWindowVisible(hwnd) ||
2139 (wndPtr->dwExStyle & WS_EX_MANAGED)) goto END;
2141 if ((wParam & 0xfff0) == SC_MOVE)
2143 if (!hittest)
2144 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2145 if (!hittest) goto END;
2147 else /* SC_SIZE */
2149 if (!thickframe) goto END;
2150 if ( hittest && hittest != HTSYSMENU ) hittest += 2;
2151 else
2153 SetCapture(hwnd);
2154 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2155 if (!hittest)
2157 ReleaseCapture();
2158 goto END;
2163 /* Get min/max info */
2165 WINPOS_GetMinMaxInfo( wndPtr, NULL, NULL, &minTrack, &maxTrack );
2166 sizingRect = wndPtr->rectWindow;
2167 origRect = sizingRect;
2168 if (wndPtr->dwStyle & WS_CHILD)
2169 GetClientRect( wndPtr->parent->hwndSelf, &mouseRect );
2170 else
2171 SetRect(&mouseRect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
2172 if (ON_LEFT_BORDER(hittest))
2174 mouseRect.left = max( mouseRect.left, sizingRect.right-maxTrack.x );
2175 mouseRect.right = min( mouseRect.right, sizingRect.right-minTrack.x );
2177 else if (ON_RIGHT_BORDER(hittest))
2179 mouseRect.left = max( mouseRect.left, sizingRect.left+minTrack.x );
2180 mouseRect.right = min( mouseRect.right, sizingRect.left+maxTrack.x );
2182 if (ON_TOP_BORDER(hittest))
2184 mouseRect.top = max( mouseRect.top, sizingRect.bottom-maxTrack.y );
2185 mouseRect.bottom = min( mouseRect.bottom,sizingRect.bottom-minTrack.y);
2187 else if (ON_BOTTOM_BORDER(hittest))
2189 mouseRect.top = max( mouseRect.top, sizingRect.top+minTrack.y );
2190 mouseRect.bottom = min( mouseRect.bottom, sizingRect.top+maxTrack.y );
2192 if (wndPtr->dwStyle & WS_CHILD)
2194 MapWindowPoints( wndPtr->parent->hwndSelf, 0,
2195 (LPPOINT)&mouseRect, 2 );
2197 SendMessageA( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
2199 if (GetCapture() != hwnd) SetCapture( hwnd );
2201 if (wndPtr->dwStyle & WS_CHILD)
2203 /* Retrieve a default cache DC (without using the window style) */
2204 hdc = GetDCEx( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
2206 else
2207 { /* Grab the server only when moving top-level windows without desktop */
2208 hdc = GetDC( 0 );
2211 wndPtr->pDriver->pPreSizeMove(wndPtr);
2213 if( iconic ) /* create a cursor for dragging */
2215 HICON16 hIcon = GetClassWord(wndPtr->hwndSelf, GCW_HICON);
2216 if(!hIcon) hIcon = (HICON16) SendMessage16( hwnd, WM_QUERYDRAGICON, 0, 0L);
2217 if( hIcon ) hDragCursor = CURSORICON_IconToCursor( hIcon, TRUE );
2218 if( !hDragCursor ) iconic = FALSE;
2221 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
2222 if( !iconic && TWEAK_WineLook == WIN31_LOOK )
2223 if(!DragFullWindows)
2224 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2226 while(1)
2228 int dx = 0, dy = 0;
2230 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE, NULL );
2232 /* Exit on button-up, Return, or Esc */
2233 if ((msg.message == WM_LBUTTONUP) ||
2234 ((msg.message == WM_KEYDOWN) &&
2235 ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
2237 if (msg.message == WM_PAINT)
2239 if(!iconic && !DragFullWindows) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2240 UpdateWindow( msg.hwnd );
2241 if(!iconic && !DragFullWindows) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2242 continue;
2245 if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
2246 continue; /* We are not interested in other messages */
2248 pt = msg.pt;
2250 if (msg.message == WM_KEYDOWN) switch(msg.wParam)
2252 case VK_UP: pt.y -= 8; break;
2253 case VK_DOWN: pt.y += 8; break;
2254 case VK_LEFT: pt.x -= 8; break;
2255 case VK_RIGHT: pt.x += 8; break;
2258 pt.x = max( pt.x, mouseRect.left );
2259 pt.x = min( pt.x, mouseRect.right );
2260 pt.y = max( pt.y, mouseRect.top );
2261 pt.y = min( pt.y, mouseRect.bottom );
2263 dx = pt.x - capturePoint.x;
2264 dy = pt.y - capturePoint.y;
2266 if (dx || dy)
2268 if( !moved )
2270 moved = TRUE;
2272 if( iconic ) /* ok, no system popup tracking */
2274 hOldCursor = SetCursor(hDragCursor);
2275 ShowCursor( TRUE );
2276 WINPOS_ShowIconTitle( wndPtr, FALSE );
2277 } else if(TWEAK_WineLook != WIN31_LOOK)
2279 if(!DragFullWindows)
2280 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2284 if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
2285 else
2287 RECT newRect = sizingRect;
2288 WPARAM wpSizingHit = 0;
2290 if (hittest == HTCAPTION) OffsetRect( &newRect, dx, dy );
2291 if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
2292 else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
2293 if (ON_TOP_BORDER(hittest)) newRect.top += dy;
2294 else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
2295 if(!iconic && !DragFullWindows) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2296 capturePoint = pt;
2298 /* determine the hit location */
2299 if (hittest >= HTLEFT && hittest <= HTBOTTOMRIGHT)
2300 wpSizingHit = WMSZ_LEFT + (hittest - HTLEFT);
2301 SendMessageA( hwnd, WM_SIZING, wpSizingHit, (LPARAM)&newRect );
2303 if (!iconic)
2305 if(!DragFullWindows)
2306 NC_DrawMovingFrame( hdc, &newRect, thickframe );
2307 else {
2308 /* To avoid any deadlocks, all the locks on the windows
2309 structures must be suspended before the SetWindowPos */
2310 iWndsLocks = WIN_SuspendWndsLock();
2311 SetWindowPos( hwnd, 0, newRect.left, newRect.top,
2312 newRect.right - newRect.left,
2313 newRect.bottom - newRect.top,
2314 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
2315 WIN_RestoreWndsLock(iWndsLocks);
2318 sizingRect = newRect;
2323 ReleaseCapture();
2324 if( iconic )
2326 if( moved ) /* restore cursors, show icon title later on */
2328 ShowCursor( FALSE );
2329 SetCursor( hOldCursor );
2331 DestroyCursor( hDragCursor );
2333 else if(moved || TWEAK_WineLook == WIN31_LOOK)
2334 if(!DragFullWindows)
2335 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2337 if (wndPtr->dwStyle & WS_CHILD)
2338 ReleaseDC( wndPtr->parent->hwndSelf, hdc );
2339 else
2340 ReleaseDC( 0, hdc );
2342 wndPtr->pDriver->pPostSizeMove(wndPtr);
2344 if (HOOK_IsHooked( WH_CBT ))
2346 RECT16* pr = SEGPTR_NEW(RECT16);
2347 if( pr )
2349 CONV_RECT32TO16( &sizingRect, pr );
2350 if( HOOK_CallHooks16( WH_CBT, HCBT_MOVESIZE, hwnd,
2351 (LPARAM)SEGPTR_GET(pr)) )
2352 sizingRect = wndPtr->rectWindow;
2353 else
2354 CONV_RECT16TO32( pr, &sizingRect );
2355 SEGPTR_FREE(pr);
2358 SendMessageA( hwnd, WM_EXITSIZEMOVE, 0, 0 );
2359 SendMessageA( hwnd, WM_SETVISIBLE, !IsIconic16(hwnd), 0L);
2361 /* window moved or resized */
2362 if (moved)
2364 /* To avoid any deadlocks, all the locks on the windows
2365 structures must be suspended before the SetWindowPos */
2366 iWndsLocks = WIN_SuspendWndsLock();
2368 /* if the moving/resizing isn't canceled call SetWindowPos
2369 * with the new position or the new size of the window
2371 if (!((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
2373 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
2374 if(!DragFullWindows)
2375 SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top,
2376 sizingRect.right - sizingRect.left,
2377 sizingRect.bottom - sizingRect.top,
2378 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
2380 else { /* restore previous size/position */
2381 if(DragFullWindows)
2382 SetWindowPos( hwnd, 0, origRect.left, origRect.top,
2383 origRect.right - origRect.left,
2384 origRect.bottom - origRect.top,
2385 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
2388 WIN_RestoreWndsLock(iWndsLocks);
2391 if( IsWindow(hwnd) )
2392 if( wndPtr->dwStyle & WS_MINIMIZE )
2394 /* Single click brings up the system menu when iconized */
2396 if( !moved )
2398 if( wndPtr->dwStyle & WS_SYSMENU )
2399 SendMessageA( hwnd, WM_SYSCOMMAND,
2400 SC_MOUSEMENU + HTSYSMENU, MAKELONG(pt.x,pt.y));
2402 else WINPOS_ShowIconTitle( wndPtr, TRUE );
2405 END:
2406 WIN_ReleaseWndPtr(wndPtr);
2410 /***********************************************************************
2411 * NC_TrackMinMaxBox95
2413 * Track a mouse button press on the minimize or maximize box.
2415 * The big difference between 3.1 and 95 is the disabled button state.
2416 * In win95 the system button can be disabled, so it can ignore the mouse
2417 * event.
2420 static void NC_TrackMinMaxBox95( HWND hwnd, WORD wParam )
2422 MSG msg;
2423 HDC hdc = GetWindowDC( hwnd );
2424 BOOL pressed = TRUE;
2425 UINT state;
2426 DWORD wndStyle = GetWindowLongA( hwnd, GWL_STYLE);
2427 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
2429 void (*paintButton)(HWND, HDC16, BOOL, BOOL);
2431 if (wParam == HTMINBUTTON)
2433 /* If the style is not present, do nothing */
2434 if (!(wndStyle & WS_MINIMIZEBOX))
2435 return;
2437 /* Check if the sysmenu item for minimize is there */
2438 state = GetMenuState(hSysMenu, SC_MINIMIZE, MF_BYCOMMAND);
2440 paintButton = &NC_DrawMinButton95;
2442 else
2444 /* If the style is not present, do nothing */
2445 if (!(wndStyle & WS_MAXIMIZEBOX))
2446 return;
2448 /* Check if the sysmenu item for maximize is there */
2449 state = GetMenuState(hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
2451 paintButton = &NC_DrawMaxButton95;
2454 SetCapture( hwnd );
2456 (*paintButton)( hwnd, hdc, TRUE, FALSE);
2458 while(1)
2460 BOOL oldstate = pressed;
2461 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2463 if(msg.message == WM_LBUTTONUP)
2464 break;
2466 if(msg.message != WM_MOUSEMOVE)
2467 continue;
2469 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
2470 if (pressed != oldstate)
2471 (*paintButton)( hwnd, hdc, pressed, FALSE);
2474 if(pressed)
2475 (*paintButton)(hwnd, hdc, FALSE, FALSE);
2477 ReleaseCapture();
2478 ReleaseDC( hwnd, hdc );
2480 /* If the item minimize or maximize of the sysmenu are not there */
2481 /* or if the style is not present, do nothing */
2482 if ((!pressed) || (state == 0xFFFFFFFF))
2483 return;
2485 if (wParam == HTMINBUTTON)
2486 SendMessageA( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
2487 else
2488 SendMessageA( hwnd, WM_SYSCOMMAND,
2489 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
2492 /***********************************************************************
2493 * NC_TrackMinMaxBox
2495 * Track a mouse button press on the minimize or maximize box.
2497 static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
2499 MSG msg;
2500 HDC hdc = GetWindowDC( hwnd );
2501 BOOL pressed = TRUE;
2502 void (*paintButton)(HWND, HDC16, BOOL);
2504 SetCapture( hwnd );
2506 if (wParam == HTMINBUTTON)
2507 paintButton = &NC_DrawMinButton;
2508 else
2509 paintButton = &NC_DrawMaxButton;
2511 (*paintButton)( hwnd, hdc, TRUE);
2513 while(1)
2515 BOOL oldstate = pressed;
2516 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2518 if(msg.message == WM_LBUTTONUP)
2519 break;
2521 if(msg.message != WM_MOUSEMOVE)
2522 continue;
2524 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
2525 if (pressed != oldstate)
2526 (*paintButton)( hwnd, hdc, pressed);
2529 if(pressed)
2530 (*paintButton)( hwnd, hdc, FALSE);
2532 ReleaseCapture();
2533 ReleaseDC( hwnd, hdc );
2535 if (!pressed) return;
2537 if (wParam == HTMINBUTTON)
2538 SendMessageA( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
2539 else
2540 SendMessageA( hwnd, WM_SYSCOMMAND,
2541 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
2545 /***********************************************************************
2546 * NC_TrackCloseButton95
2548 * Track a mouse button press on the Win95 close button.
2550 static void
2551 NC_TrackCloseButton95 (HWND hwnd, WORD wParam)
2553 MSG msg;
2554 HDC hdc;
2555 BOOL pressed = TRUE;
2556 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
2557 UINT state;
2559 if(hSysMenu == 0)
2560 return;
2562 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
2564 /* If the item close of the sysmenu is disabled or not there do nothing */
2565 if((state & MF_DISABLED) || (state & MF_GRAYED) || (state == 0xFFFFFFFF))
2566 return;
2568 hdc = GetWindowDC( hwnd );
2570 SetCapture( hwnd );
2572 NC_DrawCloseButton95 (hwnd, hdc, TRUE, FALSE);
2574 while(1)
2576 BOOL oldstate = pressed;
2577 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2579 if(msg.message == WM_LBUTTONUP)
2580 break;
2582 if(msg.message != WM_MOUSEMOVE)
2583 continue;
2585 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
2586 if (pressed != oldstate)
2587 NC_DrawCloseButton95 (hwnd, hdc, pressed, FALSE);
2590 if(pressed)
2591 NC_DrawCloseButton95 (hwnd, hdc, FALSE, FALSE);
2593 ReleaseCapture();
2594 ReleaseDC( hwnd, hdc );
2595 if (!pressed) return;
2597 SendMessageA( hwnd, WM_SYSCOMMAND, SC_CLOSE, MAKELONG(msg.pt.x,msg.pt.y) );
2601 /***********************************************************************
2602 * NC_TrackScrollBar
2604 * Track a mouse button press on the horizontal or vertical scroll-bar.
2606 static void NC_TrackScrollBar( HWND hwnd, WPARAM wParam, POINT pt )
2608 MSG16 *msg;
2609 INT scrollbar;
2610 WND *wndPtr = WIN_FindWndPtr( hwnd );
2612 if ((wParam & 0xfff0) == SC_HSCROLL)
2614 if ((wParam & 0x0f) != HTHSCROLL) goto END;
2615 scrollbar = SB_HORZ;
2617 else /* SC_VSCROLL */
2619 if ((wParam & 0x0f) != HTVSCROLL) goto END;
2620 scrollbar = SB_VERT;
2623 if (!(msg = SEGPTR_NEW(MSG16))) goto END;
2624 pt.x -= wndPtr->rectWindow.left;
2625 pt.y -= wndPtr->rectWindow.top;
2626 SetCapture( hwnd );
2627 SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt );
2631 GetMessage16( SEGPTR_GET(msg), 0, 0, 0 );
2632 switch(msg->message)
2634 case WM_LBUTTONUP:
2635 case WM_MOUSEMOVE:
2636 case WM_SYSTIMER:
2637 pt.x = LOWORD(msg->lParam) + wndPtr->rectClient.left -
2638 wndPtr->rectWindow.left;
2639 pt.y = HIWORD(msg->lParam) + wndPtr->rectClient.top -
2640 wndPtr->rectWindow.top;
2641 SCROLL_HandleScrollEvent( hwnd, scrollbar, msg->message, pt );
2642 break;
2643 default:
2644 TranslateMessage16( msg );
2645 DispatchMessage16( msg );
2646 break;
2648 if (!IsWindow( hwnd ))
2650 ReleaseCapture();
2651 break;
2653 } while (msg->message != WM_LBUTTONUP);
2654 SEGPTR_FREE(msg);
2655 END:
2656 WIN_ReleaseWndPtr(wndPtr);
2659 /***********************************************************************
2660 * NC_HandleNCLButtonDown
2662 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2664 LONG NC_HandleNCLButtonDown( WND* pWnd, WPARAM16 wParam, LPARAM lParam )
2666 HWND hwnd = pWnd->hwndSelf;
2668 switch(wParam) /* Hit test */
2670 case HTCAPTION:
2671 hwnd = WIN_GetTopParent(hwnd);
2673 if( WINPOS_SetActiveWindow(hwnd, TRUE, TRUE) || (GetActiveWindow() == hwnd) )
2674 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
2675 break;
2677 case HTSYSMENU:
2678 if( pWnd->dwStyle & WS_SYSMENU )
2680 if( !(pWnd->dwStyle & WS_MINIMIZE) )
2682 HDC hDC = GetWindowDC(hwnd);
2683 if (TWEAK_WineLook == WIN31_LOOK)
2684 NC_DrawSysButton( hwnd, hDC, TRUE );
2685 else
2686 NC_DrawSysButton95( hwnd, hDC, TRUE );
2687 ReleaseDC( hwnd, hDC );
2689 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
2691 break;
2693 case HTMENU:
2694 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam );
2695 break;
2697 case HTHSCROLL:
2698 SendMessage16( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
2699 break;
2701 case HTVSCROLL:
2702 SendMessage16( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
2703 break;
2705 case HTMINBUTTON:
2706 case HTMAXBUTTON:
2707 if (TWEAK_WineLook == WIN31_LOOK)
2708 NC_TrackMinMaxBox( hwnd, wParam );
2709 else
2710 NC_TrackMinMaxBox95( hwnd, wParam );
2711 break;
2713 case HTCLOSE:
2714 if (TWEAK_WineLook >= WIN95_LOOK)
2715 NC_TrackCloseButton95 (hwnd, wParam);
2716 break;
2718 case HTLEFT:
2719 case HTRIGHT:
2720 case HTTOP:
2721 case HTTOPLEFT:
2722 case HTTOPRIGHT:
2723 case HTBOTTOM:
2724 case HTBOTTOMLEFT:
2725 case HTBOTTOMRIGHT:
2726 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2727 SendMessage16( hwnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam);
2728 break;
2730 case HTBORDER:
2731 break;
2733 return 0;
2737 /***********************************************************************
2738 * NC_HandleNCLButtonDblClk
2740 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2742 LONG NC_HandleNCLButtonDblClk( WND *pWnd, WPARAM16 wParam, LPARAM lParam )
2745 * if this is an icon, send a restore since we are handling
2746 * a double click
2748 if (pWnd->dwStyle & WS_MINIMIZE)
2750 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_RESTORE, lParam );
2751 return 0;
2754 switch(wParam) /* Hit test */
2756 case HTCAPTION:
2757 /* stop processing if WS_MAXIMIZEBOX is missing */
2758 if (pWnd->dwStyle & WS_MAXIMIZEBOX)
2759 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND,
2760 (pWnd->dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
2761 lParam );
2762 break;
2764 case HTSYSMENU:
2765 if (!(GetClassWord(pWnd->hwndSelf, GCW_STYLE) & CS_NOCLOSE))
2766 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, lParam );
2767 break;
2769 case HTHSCROLL:
2770 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL,
2771 lParam );
2772 break;
2774 case HTVSCROLL:
2775 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL,
2776 lParam );
2777 break;
2779 return 0;
2783 /***********************************************************************
2784 * NC_HandleSysCommand
2786 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2788 LONG NC_HandleSysCommand( HWND hwnd, WPARAM wParam, POINT pt )
2790 WND *wndPtr = WIN_FindWndPtr( hwnd );
2791 UINT16 uCommand = wParam & 0xFFF0;
2793 TRACE("Handling WM_SYSCOMMAND %x %ld,%ld\n", wParam, pt.x, pt.y );
2795 if (wndPtr->dwStyle & WS_CHILD && uCommand != SC_KEYMENU )
2796 ScreenToClient( wndPtr->parent->hwndSelf, &pt );
2798 switch (uCommand)
2800 case SC_SIZE:
2801 case SC_MOVE:
2802 NC_DoSizeMove( hwnd, wParam );
2803 break;
2805 case SC_MINIMIZE:
2806 if (hwnd == GetForegroundWindow())
2807 ShowOwnedPopups(hwnd,FALSE);
2808 ShowWindow( hwnd, SW_MINIMIZE );
2809 break;
2811 case SC_MAXIMIZE:
2812 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2813 ShowOwnedPopups(hwnd,TRUE);
2814 ShowWindow( hwnd, SW_MAXIMIZE );
2815 break;
2817 case SC_RESTORE:
2818 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2819 ShowOwnedPopups(hwnd,TRUE);
2820 ShowWindow( hwnd, SW_RESTORE );
2821 break;
2823 case SC_CLOSE:
2824 WIN_ReleaseWndPtr(wndPtr);
2825 return SendMessageA( hwnd, WM_CLOSE, 0, 0 );
2827 case SC_VSCROLL:
2828 case SC_HSCROLL:
2829 NC_TrackScrollBar( hwnd, wParam, pt );
2830 break;
2832 case SC_MOUSEMENU:
2833 MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt );
2834 break;
2836 case SC_KEYMENU:
2837 MENU_TrackKbdMenuBar( wndPtr , wParam , pt.x );
2838 break;
2840 case SC_TASKLIST:
2841 WinExec( "taskman.exe", SW_SHOWNORMAL );
2842 break;
2844 case SC_SCREENSAVE:
2845 if (wParam == SC_ABOUTWINE)
2847 HMODULE hmodule = LoadLibraryA( "shell32.dll" );
2848 if (hmodule)
2850 FARPROC aboutproc = GetProcAddress( hmodule, "ShellAboutA" );
2851 if (aboutproc) aboutproc( hwnd, "Wine", WINE_RELEASE_INFO, 0 );
2852 FreeLibrary( hmodule );
2855 else
2856 if (wParam == SC_PUTMARK)
2857 TRACE_(shell)("Mark requested by user\n");
2858 break;
2860 case SC_HOTKEY:
2861 case SC_ARRANGE:
2862 case SC_NEXTWINDOW:
2863 case SC_PREVWINDOW:
2864 FIXME("unimplemented!\n");
2865 break;
2867 WIN_ReleaseWndPtr(wndPtr);
2868 return 0;
2871 /*************************************************************
2872 * NC_DrawGrayButton
2874 * Stub for the grayed button of the caption
2876 *************************************************************/
2878 BOOL NC_DrawGrayButton(HDC hdc, int x, int y)
2880 HBITMAP hMaskBmp;
2881 HDC hdcMask = CreateCompatibleDC (0);
2882 HBRUSH hOldBrush;
2884 hMaskBmp = CreateBitmap (12, 10, 1, 1, lpGrayMask);
2886 if(hMaskBmp == 0)
2887 return FALSE;
2889 SelectObject (hdcMask, hMaskBmp);
2891 /* Draw the grayed bitmap using the mask */
2892 hOldBrush = SelectObject (hdc, RGB(128, 128, 128));
2893 BitBlt (hdc, x, y, 12, 10,
2894 hdcMask, 0, 0, 0xB8074A);
2896 /* Clean up */
2897 SelectObject (hdc, hOldBrush);
2898 DeleteObject(hMaskBmp);
2899 DeleteDC (hdcMask);
2901 return TRUE;
2904 HICON16 NC_IconForWindow(WND *wndPtr)
2906 HICON16 hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICONSM);
2907 if(!hIcon) hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICON);
2909 /* If there is no hIcon specified and this is a modal dialog, */
2910 /* get the default one. */
2911 if (!hIcon && (wndPtr->dwStyle & DS_MODALFRAME))
2912 hIcon = LoadImageA(0, MAKEINTRESOURCEA(OIC_WINEICON), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
2914 return hIcon;