Remove file from cache when flushing it (based on a patch by Ian
[wine/wine-kai.git] / windows / nonclient.c
blob9a1546a6dd773748793d943dd39a22b8f0fbebf6
1 /*
2 * Non-client area window functions
4 * Copyright 1994 Alexandre Julliard
6 */
8 #include "wine/winuser16.h"
9 #include "version.h"
10 #include "win.h"
11 #include "message.h"
12 #include "user.h"
13 #include "heap.h"
14 #include "dce.h"
15 #include "cursoricon.h"
16 #include "dialog.h"
17 #include "menu.h"
18 #include "winpos.h"
19 #include "hook.h"
20 #include "scroll.h"
21 #include "nonclient.h"
22 #include "queue.h"
23 #include "selectors.h"
24 #include "tweak.h"
25 #include "debugtools.h"
26 #include "options.h"
27 #include "shellapi.h"
28 #include "cache.h"
29 #include "bitmap.h"
31 DECLARE_DEBUG_CHANNEL(nonclient)
32 DECLARE_DEBUG_CHANNEL(shell)
34 BOOL NC_DrawGrayButton(HDC hdc, int x, int y);
36 static HBITMAP16 hbitmapClose = 0;
37 static HBITMAP16 hbitmapCloseD = 0;
38 static HBITMAP16 hbitmapMinimize = 0;
39 static HBITMAP16 hbitmapMinimizeD = 0;
40 static HBITMAP16 hbitmapMaximize = 0;
41 static HBITMAP16 hbitmapMaximizeD = 0;
42 static HBITMAP16 hbitmapRestore = 0;
43 static HBITMAP16 hbitmapRestoreD = 0;
45 BYTE lpGrayMask[] = { 0xAA, 0xA0,
46 0x55, 0x50,
47 0xAA, 0xA0,
48 0x55, 0x50,
49 0xAA, 0xA0,
50 0x55, 0x50,
51 0xAA, 0xA0,
52 0x55, 0x50,
53 0xAA, 0xA0,
54 0x55, 0x50};
56 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
57 #define SC_PUTMARK (SC_SCREENSAVE+2)
59 /* Some useful macros */
60 #define HAS_DLGFRAME(style,exStyle) \
61 (((exStyle) & WS_EX_DLGMODALFRAME) || \
62 (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
64 #define HAS_THICKFRAME(style,exStyle) \
65 (((style) & WS_THICKFRAME) && \
66 !((exStyle) & WS_EX_DLGMODALFRAME))
68 #define HAS_THINFRAME(style) \
69 (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
71 #define HAS_BIGFRAME(style,exStyle) \
72 (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
73 ((exStyle) & WS_EX_DLGMODALFRAME))
75 #define HAS_ANYFRAME(style,exStyle) \
76 (((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
77 ((exStyle) & WS_EX_DLGMODALFRAME) || \
78 !((style) & (WS_CHILD | WS_POPUP)))
80 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
82 #define ON_LEFT_BORDER(hit) \
83 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
84 #define ON_RIGHT_BORDER(hit) \
85 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
86 #define ON_TOP_BORDER(hit) \
87 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
88 #define ON_BOTTOM_BORDER(hit) \
89 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
91 /***********************************************************************
92 * WIN_WindowNeedsWMBorder
94 * This method defines the rules for a window to have a WM border,
95 * caption... It is used for consitency purposes.
97 BOOL WIN_WindowNeedsWMBorder( DWORD style, DWORD exStyle )
99 if (!(style & WS_CHILD) && Options.managed &&
100 (((style & WS_CAPTION) == WS_CAPTION) ||
101 (style & WS_THICKFRAME) ||
102 (exStyle & WS_EX_DLGMODALFRAME))) return TRUE;
103 return FALSE;
106 /***********************************************************************
107 * NC_AdjustRect
109 * Compute the size of the window rectangle from the size of the
110 * client rectangle.
112 static void NC_AdjustRect( LPRECT16 rect, DWORD style, BOOL menu,
113 DWORD exStyle )
115 if (TWEAK_WineLook > WIN31_LOOK)
116 ERR_(nonclient)("Called in Win95 mode. Aiee! Please report this.\n" );
118 if(style & WS_ICONIC) return;
119 /* Decide if the window will be managed (see CreateWindowEx) */
120 if (!WIN_WindowNeedsWMBorder(style, exStyle))
122 if (HAS_THICKFRAME( style, exStyle ))
123 InflateRect16( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
124 else
125 if (HAS_DLGFRAME( style, exStyle ))
126 InflateRect16( rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
127 else
128 if (HAS_THINFRAME( style ))
129 InflateRect16( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
131 if ((style & WS_CAPTION) == WS_CAPTION)
132 rect->top -= GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
134 if (menu) rect->top -= GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYBORDER);
136 if (style & WS_VSCROLL) {
137 rect->right += GetSystemMetrics(SM_CXVSCROLL) - 1;
138 if(!HAS_ANYFRAME( style, exStyle ))
139 rect->right++;
142 if (style & WS_HSCROLL) {
143 rect->bottom += GetSystemMetrics(SM_CYHSCROLL) - 1;
144 if(!HAS_ANYFRAME( style, exStyle ))
145 rect->bottom++;
150 /******************************************************************************
151 * NC_AdjustRectOuter95
153 * Computes the size of the "outside" parts of the window based on the
154 * parameters of the client area.
156 + PARAMS
157 * LPRECT16 rect
158 * DWORD style
159 * BOOL32 menu
160 * DWORD exStyle
162 * NOTES
163 * "Outer" parts of a window means the whole window frame, caption and
164 * menu bar. It does not include "inner" parts of the frame like client
165 * edge, static edge or scroll bars.
167 * Revision history
168 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
169 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
171 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
172 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
173 * NC_AdjustRectInner95 and added handling of Win95 styles.
175 * 28-Jul-1999 Ove Kåven (ovek@arcticnet.no)
176 * Streamlined window style checks.
178 *****************************************************************************/
180 static void
181 NC_AdjustRectOuter95 (LPRECT16 rect, DWORD style, BOOL menu, DWORD exStyle)
183 if(style & WS_ICONIC) return;
185 /* Decide if the window will be managed (see CreateWindowEx) */
186 if (!WIN_WindowNeedsWMBorder(style, exStyle))
188 if (HAS_THICKFRAME( style, exStyle ))
189 InflateRect16( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
190 else
191 if (HAS_DLGFRAME( style, exStyle ))
192 InflateRect16(rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
193 else
194 if (HAS_THINFRAME( style ))
195 InflateRect16( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
197 if ((style & WS_CAPTION) == WS_CAPTION)
199 if (exStyle & WS_EX_TOOLWINDOW)
200 rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
201 else
202 rect->top -= GetSystemMetrics(SM_CYCAPTION);
206 if (menu)
207 rect->top -= GetSystemMetrics(SM_CYMENU);
211 /******************************************************************************
212 * NC_AdjustRectInner95
214 * Computes the size of the "inside" part of the window based on the
215 * parameters of the client area.
217 + PARAMS
218 * LPRECT16 rect
219 * DWORD style
220 * DWORD exStyle
222 * NOTES
223 * "Inner" part of a window means the window frame inside of the flat
224 * window frame. It includes the client edge, the static edge and the
225 * scroll bars.
227 * Revision history
228 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
229 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
231 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
232 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
233 * NC_AdjustRectInner95 and added handling of Win95 styles.
235 *****************************************************************************/
237 static void
238 NC_AdjustRectInner95 (LPRECT16 rect, DWORD style, DWORD exStyle)
240 if(style & WS_ICONIC) return;
242 if (exStyle & WS_EX_CLIENTEDGE)
243 InflateRect16 (rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
245 if (exStyle & WS_EX_STATICEDGE)
246 InflateRect16 (rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
248 if (style & WS_VSCROLL) rect->right += GetSystemMetrics(SM_CXVSCROLL);
249 if (style & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
253 /***********************************************************************
254 * DrawCaption16 [USER.660] Draws a caption bar
256 * PARAMS
257 * hwnd [I]
258 * hdc [I]
259 * lpRect [I]
260 * uFlags [I]
262 * RETURNS
263 * Success:
264 * Failure:
267 BOOL16 WINAPI
268 DrawCaption16 (HWND16 hwnd, HDC16 hdc, const RECT16 *rect, UINT16 uFlags)
270 RECT rect32;
272 if (rect)
273 CONV_RECT16TO32 (rect, &rect32);
275 return (BOOL16)DrawCaptionTempA (hwnd, hdc, rect ? &rect32 : NULL,
276 0, 0, NULL, uFlags & 0x1F);
280 /***********************************************************************
281 * DrawCaption32 [USER32.154] Draws a caption bar
283 * PARAMS
284 * hwnd [I]
285 * hdc [I]
286 * lpRect [I]
287 * uFlags [I]
289 * RETURNS
290 * Success:
291 * Failure:
294 BOOL WINAPI
295 DrawCaption (HWND hwnd, HDC hdc, const RECT *lpRect, UINT uFlags)
297 return DrawCaptionTempA (hwnd, hdc, lpRect, 0, 0, NULL, uFlags & 0x1F);
301 /***********************************************************************
302 * DrawCaptionTemp16 [USER.657]
304 * PARAMS
306 * RETURNS
307 * Success:
308 * Failure:
311 BOOL16 WINAPI
312 DrawCaptionTemp16 (HWND16 hwnd, HDC16 hdc, const RECT16 *rect, HFONT16 hFont,
313 HICON16 hIcon, LPCSTR str, UINT16 uFlags)
315 RECT rect32;
317 if (rect)
318 CONV_RECT16TO32(rect,&rect32);
320 return (BOOL16)DrawCaptionTempA (hwnd, hdc, rect?&rect32:NULL, hFont,
321 hIcon, str, uFlags & 0x1F);
325 /***********************************************************************
326 * DrawCaptionTemp32A [USER32.599]
328 * PARAMS
330 * RETURNS
331 * Success:
332 * Failure:
335 BOOL WINAPI
336 DrawCaptionTempA (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
337 HICON hIcon, LPCSTR str, UINT uFlags)
339 RECT rc = *rect;
341 TRACE_(nonclient)("(%08x,%08x,%p,%08x,%08x,\"%s\",%08x)\n",
342 hwnd, hdc, rect, hFont, hIcon, str, uFlags);
344 /* drawing background */
345 if (uFlags & DC_INBUTTON) {
346 FillRect (hdc, &rc, GetSysColorBrush (COLOR_3DFACE));
348 if (uFlags & DC_ACTIVE) {
349 HBRUSH hbr = SelectObject (hdc, CACHE_GetPattern55AABrush ());
350 PatBlt (hdc, rc.left, rc.top,
351 rc.right-rc.left, rc.bottom-rc.top, 0xFA0089);
352 SelectObject (hdc, hbr);
355 else {
356 FillRect (hdc, &rc, GetSysColorBrush ((uFlags & DC_ACTIVE) ?
357 COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
361 /* drawing icon */
362 if ((uFlags & DC_ICON) && !(uFlags & DC_SMALLCAP)) {
363 POINT pt;
365 pt.x = rc.left + 2;
366 pt.y = (rc.bottom + rc.top - GetSystemMetrics(SM_CYSMICON)) / 2;
368 if (hIcon) {
369 DrawIconEx (hdc, pt.x, pt.y, hIcon, GetSystemMetrics(SM_CXSMICON),
370 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
372 else {
373 HICON hAppIcon = (HICON) GetClassLongA(hwnd, GCL_HICONSM);
374 if(!hAppIcon) hAppIcon = (HICON) GetClassLongA(hwnd, GCL_HICON);
376 DrawIconEx (hdc, pt.x, pt.y, hAppIcon, GetSystemMetrics(SM_CXSMICON),
377 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
380 rc.left += (rc.bottom - rc.top);
383 /* drawing text */
384 if (uFlags & DC_TEXT) {
385 HFONT hOldFont;
387 if (uFlags & DC_INBUTTON)
388 SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
389 else if (uFlags & DC_ACTIVE)
390 SetTextColor (hdc, GetSysColor (COLOR_CAPTIONTEXT));
391 else
392 SetTextColor (hdc, GetSysColor (COLOR_INACTIVECAPTIONTEXT));
394 SetBkMode (hdc, TRANSPARENT);
396 if (hFont)
397 hOldFont = SelectObject (hdc, hFont);
398 else {
399 NONCLIENTMETRICSA nclm;
400 HFONT hNewFont;
401 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
402 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
403 hNewFont = CreateFontIndirectA ((uFlags & DC_SMALLCAP) ?
404 &nclm.lfSmCaptionFont : &nclm.lfCaptionFont);
405 hOldFont = SelectObject (hdc, hNewFont);
408 if (str)
409 DrawTextA (hdc, str, -1, &rc,
410 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
411 else {
412 CHAR szText[128];
413 INT nLen;
414 nLen = GetWindowTextA (hwnd, szText, 128);
415 DrawTextA (hdc, szText, nLen, &rc,
416 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
419 if (hFont)
420 SelectObject (hdc, hOldFont);
421 else
422 DeleteObject (SelectObject (hdc, hOldFont));
425 /* drawing focus ??? */
426 if (uFlags & 0x2000)
427 FIXME_(nonclient)("undocumented flag (0x2000)!\n");
429 return 0;
433 /***********************************************************************
434 * DrawCaptionTemp32W [USER32.602]
436 * PARAMS
438 * RETURNS
439 * Success:
440 * Failure:
443 BOOL WINAPI
444 DrawCaptionTempW (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
445 HICON hIcon, LPCWSTR str, UINT uFlags)
447 LPSTR p = HEAP_strdupWtoA (GetProcessHeap (), 0, str);
448 BOOL res = DrawCaptionTempA (hwnd, hdc, rect, hFont, hIcon, p, uFlags);
449 HeapFree (GetProcessHeap (), 0, p);
450 return res;
454 /***********************************************************************
455 * AdjustWindowRect16 (USER.102)
457 BOOL16 WINAPI AdjustWindowRect16( LPRECT16 rect, DWORD style, BOOL16 menu )
459 return AdjustWindowRectEx16( rect, style, menu, 0 );
463 /***********************************************************************
464 * AdjustWindowRect32 (USER32.2)
466 BOOL WINAPI AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu )
468 return AdjustWindowRectEx( rect, style, menu, 0 );
472 /***********************************************************************
473 * AdjustWindowRectEx16 (USER.454)
475 BOOL16 WINAPI AdjustWindowRectEx16( LPRECT16 rect, DWORD style,
476 BOOL16 menu, DWORD exStyle )
478 /* Correct the window style */
480 if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
481 style |= WS_CAPTION;
482 style &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD);
483 exStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE |
484 WS_EX_STATICEDGE | WS_EX_TOOLWINDOW);
485 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
487 TRACE_(nonclient)("(%d,%d)-(%d,%d) %08lx %d %08lx\n",
488 rect->left, rect->top, rect->right, rect->bottom,
489 style, menu, exStyle );
491 if (TWEAK_WineLook == WIN31_LOOK)
492 NC_AdjustRect( rect, style, menu, exStyle );
493 else {
494 NC_AdjustRectOuter95( rect, style, menu, exStyle );
495 NC_AdjustRectInner95( rect, style, exStyle );
498 return TRUE;
502 /***********************************************************************
503 * AdjustWindowRectEx32 (USER32.3)
505 BOOL WINAPI AdjustWindowRectEx( LPRECT rect, DWORD style,
506 BOOL menu, DWORD exStyle )
508 RECT16 rect16;
509 BOOL ret;
511 CONV_RECT32TO16( rect, &rect16 );
512 ret = AdjustWindowRectEx16( &rect16, style, (BOOL16)menu, exStyle );
513 CONV_RECT16TO32( &rect16, rect );
514 return ret;
518 /***********************************************************************
519 * NC_HandleNCCalcSize
521 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
523 LONG NC_HandleNCCalcSize( WND *pWnd, RECT *winRect )
525 RECT16 tmpRect = { 0, 0, 0, 0 };
526 LONG result = 0;
527 UINT style = (UINT) GetClassLongA(pWnd->hwndSelf, GCL_STYLE);
529 if (style & CS_VREDRAW) result |= WVR_VREDRAW;
530 if (style & CS_HREDRAW) result |= WVR_HREDRAW;
532 if( !( pWnd->dwStyle & WS_MINIMIZE ) ) {
533 if (TWEAK_WineLook == WIN31_LOOK)
534 NC_AdjustRect( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
535 else
536 NC_AdjustRectOuter95( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
538 winRect->left -= tmpRect.left;
539 winRect->top -= tmpRect.top;
540 winRect->right -= tmpRect.right;
541 winRect->bottom -= tmpRect.bottom;
543 if (HAS_MENU(pWnd)) {
544 TRACE_(nonclient)("Calling "
545 "GetMenuBarHeight with HWND 0x%x, width %d, "
546 "at (%d, %d).\n", pWnd->hwndSelf,
547 winRect->right - winRect->left,
548 -tmpRect.left, -tmpRect.top );
550 winRect->top +=
551 MENU_GetMenuBarHeight( pWnd->hwndSelf,
552 winRect->right - winRect->left,
553 -tmpRect.left, -tmpRect.top ) + 1;
556 if (TWEAK_WineLook > WIN31_LOOK) {
557 SetRect16 (&tmpRect, 0, 0, 0, 0);
558 NC_AdjustRectInner95 (&tmpRect, pWnd->dwStyle, pWnd->dwExStyle);
559 winRect->left -= tmpRect.left;
560 winRect->top -= tmpRect.top;
561 winRect->right -= tmpRect.right;
562 winRect->bottom -= tmpRect.bottom;
565 return result;
569 /***********************************************************************
570 * NC_GetInsideRect
572 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
573 * but without the borders (if any).
574 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
576 static void NC_GetInsideRect( HWND hwnd, RECT *rect )
578 WND * wndPtr = WIN_FindWndPtr( hwnd );
580 rect->top = rect->left = 0;
581 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
582 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
584 if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) goto END;
586 /* Remove frame from rectangle */
587 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
588 InflateRect( rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
589 else
590 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
592 InflateRect( rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
593 /* FIXME: this isn't in NC_AdjustRect? why not? */
594 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
595 InflateRect( rect, -1, 0 );
597 else
598 if (HAS_THINFRAME( wndPtr->dwStyle ))
599 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
600 END:
601 WIN_ReleaseWndPtr(wndPtr);
602 return;
606 /***********************************************************************
607 * NC_GetInsideRect95
609 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
610 * but without the borders (if any).
611 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
614 static void
615 NC_GetInsideRect95 (HWND hwnd, RECT *rect)
617 WND * wndPtr = WIN_FindWndPtr( hwnd );
619 rect->top = rect->left = 0;
620 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
621 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
623 if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) goto END;
625 /* Remove frame from rectangle */
626 if (HAS_THICKFRAME (wndPtr->dwStyle, wndPtr->dwExStyle))
628 InflateRect( rect, -GetSystemMetrics(SM_CXSIZEFRAME), -GetSystemMetrics(SM_CYSIZEFRAME) );
630 else if (HAS_DLGFRAME (wndPtr->dwStyle, wndPtr->dwExStyle ))
632 InflateRect( rect, -GetSystemMetrics(SM_CXFIXEDFRAME), -GetSystemMetrics(SM_CYFIXEDFRAME));
634 else if (HAS_THINFRAME (wndPtr->dwStyle))
636 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
639 if (wndPtr->dwStyle & WS_CHILD) {
640 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
641 InflateRect (rect, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE));
643 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
644 InflateRect (rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
646 END:
647 WIN_ReleaseWndPtr(wndPtr);
648 return;
652 /***********************************************************************
653 * NC_DoNCHitTest
655 * Handle a WM_NCHITTEST message. Called from NC_HandleNcHitTest().
658 static LONG NC_DoNCHitTest (WND *wndPtr, POINT16 pt )
660 RECT16 rect;
662 TRACE_(nonclient)("hwnd=%04x pt=%d,%d\n",
663 wndPtr->hwndSelf, pt.x, pt.y );
665 GetWindowRect16 (wndPtr->hwndSelf, &rect );
666 if (!PtInRect16( &rect, pt )) return HTNOWHERE;
668 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
670 if (!(wndPtr->flags & WIN_MANAGED))
672 /* Check borders */
673 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
675 InflateRect16( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
676 if (!PtInRect16( &rect, pt ))
678 /* Check top sizing border */
679 if (pt.y < rect.top)
681 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
682 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
683 return HTTOP;
685 /* Check bottom sizing border */
686 if (pt.y >= rect.bottom)
688 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
689 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
690 return HTBOTTOM;
692 /* Check left sizing border */
693 if (pt.x < rect.left)
695 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
696 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
697 return HTLEFT;
699 /* Check right sizing border */
700 if (pt.x >= rect.right)
702 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
703 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
704 return HTRIGHT;
708 else /* No thick frame */
710 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
711 InflateRect16(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
712 else if (HAS_THINFRAME( wndPtr->dwStyle ))
713 InflateRect16(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
714 if (!PtInRect16( &rect, pt )) return HTBORDER;
717 /* Check caption */
719 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
721 rect.top += GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
722 if (!PtInRect16( &rect, pt ))
724 /* Check system menu */
725 if (wndPtr->dwStyle & WS_SYSMENU)
726 rect.left += GetSystemMetrics(SM_CXSIZE);
727 if (pt.x <= rect.left) return HTSYSMENU;
729 /* Check maximize box */
730 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
731 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
733 if (pt.x >= rect.right) return HTMAXBUTTON;
734 /* Check minimize box */
735 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
736 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
737 if (pt.x >= rect.right) return HTMINBUTTON;
738 return HTCAPTION;
743 /* Check client area */
745 ScreenToClient16( wndPtr->hwndSelf, &pt );
746 GetClientRect16( wndPtr->hwndSelf, &rect );
747 if (PtInRect16( &rect, pt )) return HTCLIENT;
749 /* Check vertical scroll bar */
751 if (wndPtr->dwStyle & WS_VSCROLL)
753 rect.right += GetSystemMetrics(SM_CXVSCROLL);
754 if (PtInRect16( &rect, pt )) return HTVSCROLL;
757 /* Check horizontal scroll bar */
759 if (wndPtr->dwStyle & WS_HSCROLL)
761 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
762 if (PtInRect16( &rect, pt ))
764 /* Check size box */
765 if ((wndPtr->dwStyle & WS_VSCROLL) &&
766 (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
767 return HTSIZE;
768 return HTHSCROLL;
772 /* Check menu bar */
774 if (HAS_MENU(wndPtr))
776 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
777 return HTMENU;
780 /* Should never get here */
781 return HTERROR;
785 /***********************************************************************
786 * NC_DoNCHitTest95
788 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
790 * FIXME: Just a modified copy of the Win 3.1 version.
793 static LONG
794 NC_DoNCHitTest95 (WND *wndPtr, POINT16 pt )
796 RECT16 rect;
798 TRACE_(nonclient)("hwnd=%04x pt=%d,%d\n",
799 wndPtr->hwndSelf, pt.x, pt.y );
801 GetWindowRect16 (wndPtr->hwndSelf, &rect );
802 if (!PtInRect16( &rect, pt )) return HTNOWHERE;
804 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
806 if (!(wndPtr->flags & WIN_MANAGED))
808 /* Check borders */
809 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
811 InflateRect16( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
812 if (!PtInRect16( &rect, pt ))
814 /* Check top sizing border */
815 if (pt.y < rect.top)
817 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
818 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
819 return HTTOP;
821 /* Check bottom sizing border */
822 if (pt.y >= rect.bottom)
824 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
825 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
826 return HTBOTTOM;
828 /* Check left sizing border */
829 if (pt.x < rect.left)
831 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
832 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
833 return HTLEFT;
835 /* Check right sizing border */
836 if (pt.x >= rect.right)
838 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
839 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
840 return HTRIGHT;
844 else /* No thick frame */
846 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
847 InflateRect16(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
848 else if (HAS_THINFRAME( wndPtr->dwStyle ))
849 InflateRect16(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
850 if (!PtInRect16( &rect, pt )) return HTBORDER;
853 /* Check caption */
855 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
857 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
858 rect.top += GetSystemMetrics(SM_CYSMCAPTION) - 1;
859 else
860 rect.top += GetSystemMetrics(SM_CYCAPTION) - 1;
861 if (!PtInRect16( &rect, pt ))
863 /* Check system menu */
864 if ((wndPtr->dwStyle & WS_SYSMENU) &&
865 (((HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICONSM)) ||
866 ((HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICON))))
867 rect.left += GetSystemMetrics(SM_CYCAPTION) - 1;
868 if (pt.x < rect.left) return HTSYSMENU;
870 /* Check close button */
871 if (wndPtr->dwStyle & WS_SYSMENU)
872 rect.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
873 if (pt.x > rect.right) return HTCLOSE;
875 /* Check maximize box */
876 /* In win95 there is automatically a Maximize button when there is a minimize one*/
877 if ((wndPtr->dwStyle & WS_MAXIMIZEBOX)|| (wndPtr->dwStyle & WS_MINIMIZEBOX))
878 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
879 if (pt.x > rect.right) return HTMAXBUTTON;
881 /* Check minimize box */
882 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
883 if ((wndPtr->dwStyle & WS_MINIMIZEBOX)||(wndPtr->dwStyle & WS_MAXIMIZEBOX))
884 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
886 if (pt.x > rect.right) return HTMINBUTTON;
887 return HTCAPTION;
892 /* Check client area */
894 ScreenToClient16( wndPtr->hwndSelf, &pt );
895 GetClientRect16( wndPtr->hwndSelf, &rect );
896 if (PtInRect16( &rect, pt )) return HTCLIENT;
898 /* Check vertical scroll bar */
900 if (wndPtr->dwStyle & WS_VSCROLL)
902 rect.right += GetSystemMetrics(SM_CXVSCROLL);
903 if (PtInRect16( &rect, pt )) return HTVSCROLL;
906 /* Check horizontal scroll bar */
908 if (wndPtr->dwStyle & WS_HSCROLL)
910 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
911 if (PtInRect16( &rect, pt ))
913 /* Check size box */
914 if ((wndPtr->dwStyle & WS_VSCROLL) &&
915 (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
916 return HTSIZE;
917 return HTHSCROLL;
921 /* Check menu bar */
923 if (HAS_MENU(wndPtr))
925 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
926 return HTMENU;
929 /* Should never get here */
930 return HTERROR;
934 /***********************************************************************
935 * NC_HandleNCHitTest
937 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
939 LONG
940 NC_HandleNCHitTest (HWND hwnd , POINT16 pt)
942 LONG retvalue;
943 WND *wndPtr = WIN_FindWndPtr (hwnd);
945 if (!wndPtr)
946 return HTERROR;
948 if (TWEAK_WineLook == WIN31_LOOK)
949 retvalue = NC_DoNCHitTest (wndPtr, pt);
950 else
951 retvalue = NC_DoNCHitTest95 (wndPtr, pt);
952 WIN_ReleaseWndPtr(wndPtr);
953 return retvalue;
957 /***********************************************************************
958 * NC_DrawSysButton
960 void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down )
962 RECT rect;
963 HDC hdcMem;
964 HBITMAP hbitmap;
965 WND *wndPtr = WIN_FindWndPtr( hwnd );
967 if( !(wndPtr->flags & WIN_MANAGED) )
969 NC_GetInsideRect( hwnd, &rect );
970 hdcMem = CreateCompatibleDC( hdc );
971 hbitmap = SelectObject( hdcMem, hbitmapClose );
972 BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE), GetSystemMetrics(SM_CYSIZE),
973 hdcMem, (wndPtr->dwStyle & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE) : 0, 0,
974 down ? NOTSRCCOPY : SRCCOPY );
975 SelectObject( hdcMem, hbitmap );
976 DeleteDC( hdcMem );
978 WIN_ReleaseWndPtr(wndPtr);
982 /***********************************************************************
983 * NC_DrawMaxButton
985 static void NC_DrawMaxButton( HWND hwnd, HDC16 hdc, BOOL down )
987 RECT rect;
988 WND *wndPtr = WIN_FindWndPtr( hwnd );
989 HDC hdcMem;
991 if( !(wndPtr->flags & WIN_MANAGED) )
993 NC_GetInsideRect( hwnd, &rect );
994 hdcMem = CreateCompatibleDC( hdc );
995 SelectObject( hdcMem, (IsZoomed(hwnd)
996 ? (down ? hbitmapRestoreD : hbitmapRestore)
997 : (down ? hbitmapMaximizeD : hbitmapMaximize)) );
998 BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
999 GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
1000 SRCCOPY );
1001 DeleteDC( hdcMem );
1003 WIN_ReleaseWndPtr(wndPtr);
1008 /***********************************************************************
1009 * NC_DrawMinButton
1011 static void NC_DrawMinButton( HWND hwnd, HDC16 hdc, BOOL down )
1013 RECT rect;
1014 WND *wndPtr = WIN_FindWndPtr( hwnd );
1015 HDC hdcMem;
1017 if( !(wndPtr->flags & WIN_MANAGED) )
1019 NC_GetInsideRect( hwnd, &rect );
1020 hdcMem = CreateCompatibleDC( hdc );
1021 SelectObject( hdcMem, (down ? hbitmapMinimizeD : hbitmapMinimize) );
1022 if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= GetSystemMetrics(SM_CXSIZE)+1;
1023 BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
1024 GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
1025 SRCCOPY );
1026 DeleteDC( hdcMem );
1028 WIN_ReleaseWndPtr(wndPtr);
1032 /******************************************************************************
1034 * void NC_DrawSysButton95(
1035 * HWND32 hwnd,
1036 * HDC32 hdc,
1037 * BOOL32 down )
1039 * Draws the Win95 system icon.
1041 * Revision history
1042 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1043 * Original implementation from NC_DrawSysButton source.
1044 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1045 * Fixed most bugs.
1047 *****************************************************************************/
1049 BOOL
1050 NC_DrawSysButton95 (HWND hwnd, HDC hdc, BOOL down)
1052 WND *wndPtr = WIN_FindWndPtr( hwnd );
1054 if( !(wndPtr->flags & WIN_MANAGED) )
1056 HICON hIcon;
1057 RECT rect;
1059 NC_GetInsideRect95( hwnd, &rect );
1061 hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICONSM);
1062 if(!hIcon) hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICON);
1064 if (hIcon)
1065 DrawIconEx (hdc, rect.left + 2, rect.top + 2, hIcon,
1066 GetSystemMetrics(SM_CXSMICON),
1067 GetSystemMetrics(SM_CYSMICON),
1068 0, 0, DI_NORMAL);
1070 WIN_ReleaseWndPtr(wndPtr);
1071 return (hIcon != 0);
1073 WIN_ReleaseWndPtr(wndPtr);
1074 return FALSE;
1078 /******************************************************************************
1080 * void NC_DrawCloseButton95(
1081 * HWND32 hwnd,
1082 * HDC32 hdc,
1083 * BOOL32 down,
1084 * BOOL bGrayed )
1086 * Draws the Win95 close button.
1088 * If bGrayed is true, then draw a disabled Close button
1090 * Revision history
1091 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1092 * Original implementation from NC_DrawSysButton95 source.
1094 *****************************************************************************/
1096 static void NC_DrawCloseButton95 (HWND hwnd, HDC hdc, BOOL down, BOOL bGrayed)
1098 RECT rect;
1099 HDC hdcMem;
1100 WND *wndPtr = WIN_FindWndPtr( hwnd );
1102 if( !(wndPtr->flags & WIN_MANAGED) )
1104 BITMAP bmp;
1105 HBITMAP hBmp, hOldBmp;
1107 NC_GetInsideRect95( hwnd, &rect );
1109 hdcMem = CreateCompatibleDC( hdc );
1110 hBmp = down ? hbitmapCloseD : hbitmapClose;
1111 hOldBmp = SelectObject (hdcMem, hBmp);
1112 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1114 BitBlt (hdc, rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2,
1115 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1116 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);
1118 if(bGrayed)
1119 NC_DrawGrayButton(hdc,rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2 + 2,
1120 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1122 SelectObject (hdcMem, hOldBmp);
1123 DeleteDC (hdcMem);
1125 WIN_ReleaseWndPtr(wndPtr);
1128 /******************************************************************************
1130 * NC_DrawMaxButton95(
1131 * HWND32 hwnd,
1132 * HDC16 hdc,
1133 * BOOL32 down
1134 * BOOL bGrayed )
1136 * Draws the maximize button for Win95 style windows.
1138 * If bGrayed is true, then draw a disabled Maximize button
1140 * Bugs
1141 * Many. Spacing might still be incorrect. Need to fit a close
1142 * button between the max button and the edge.
1143 * Should scale the image with the title bar. And more...
1145 * Revision history
1146 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1147 * Original implementation.
1149 *****************************************************************************/
1151 static void NC_DrawMaxButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
1153 RECT rect;
1154 HDC hdcMem;
1155 WND *wndPtr = WIN_FindWndPtr( hwnd );
1157 if( !(wndPtr->flags & WIN_MANAGED))
1159 BITMAP bmp;
1160 HBITMAP hBmp,hOldBmp;
1162 NC_GetInsideRect95( hwnd, &rect );
1163 hdcMem = CreateCompatibleDC( hdc );
1164 hBmp = IsZoomed(hwnd) ?
1165 (down ? hbitmapRestoreD : hbitmapRestore ) :
1166 (down ? hbitmapMaximizeD: hbitmapMaximize);
1167 hOldBmp=SelectObject( hdcMem, hBmp );
1168 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1170 if (wndPtr->dwStyle & WS_SYSMENU)
1171 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1173 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1174 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1175 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1177 if(bGrayed)
1178 NC_DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
1179 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1182 SelectObject (hdcMem, hOldBmp);
1183 DeleteDC( hdcMem );
1185 WIN_ReleaseWndPtr(wndPtr);
1188 /******************************************************************************
1190 * NC_DrawMinButton95(
1191 * HWND32 hwnd,
1192 * HDC16 hdc,
1193 * BOOL32 down,
1194 * BOOL bGrayed )
1196 * Draws the minimize button for Win95 style windows.
1198 * If bGrayed is true, then draw a disabled Minimize button
1200 * Bugs
1201 * Many. Spacing is still incorrect. Should scale the image with the
1202 * title bar. And more...
1204 * Revision history
1205 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1206 * Original implementation.
1208 *****************************************************************************/
1210 static void NC_DrawMinButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
1212 RECT rect;
1213 HDC hdcMem;
1214 WND *wndPtr = WIN_FindWndPtr( hwnd );
1216 if( !(wndPtr->flags & WIN_MANAGED))
1219 BITMAP bmp;
1220 HBITMAP hBmp,hOldBmp;
1222 NC_GetInsideRect95( hwnd, &rect );
1224 hdcMem = CreateCompatibleDC( hdc );
1225 hBmp = down ? hbitmapMinimizeD : hbitmapMinimize;
1226 hOldBmp= SelectObject( hdcMem, hBmp );
1227 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1229 if (wndPtr->dwStyle & WS_SYSMENU)
1230 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1232 /* In win 95 there is always a Maximize box when there is a Minimize one */
1233 if ((wndPtr->dwStyle & WS_MAXIMIZEBOX) || (wndPtr->dwStyle & WS_MINIMIZEBOX))
1234 rect.right += -1 - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2;
1236 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1237 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1238 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1240 if(bGrayed)
1241 NC_DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
1242 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1245 SelectObject (hdcMem, hOldBmp);
1246 DeleteDC( hdcMem );
1248 WIN_ReleaseWndPtr(wndPtr);
1251 /***********************************************************************
1252 * NC_DrawFrame
1254 * Draw a window frame inside the given rectangle, and update the rectangle.
1255 * The correct pen for the frame must be selected in the DC.
1257 static void NC_DrawFrame( HDC hdc, RECT *rect, BOOL dlgFrame,
1258 BOOL active )
1260 INT width, height;
1262 if (TWEAK_WineLook != WIN31_LOOK)
1263 ERR_(nonclient)("Called in Win95 mode. Aiee! Please report this.\n" );
1265 if (dlgFrame)
1267 width = GetSystemMetrics(SM_CXDLGFRAME) - 1;
1268 height = GetSystemMetrics(SM_CYDLGFRAME) - 1;
1269 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1270 COLOR_INACTIVECAPTION) );
1272 else
1274 width = GetSystemMetrics(SM_CXFRAME) - 2;
1275 height = GetSystemMetrics(SM_CYFRAME) - 2;
1276 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1277 COLOR_INACTIVEBORDER) );
1280 /* Draw frame */
1281 PatBlt( hdc, rect->left, rect->top,
1282 rect->right - rect->left, height, PATCOPY );
1283 PatBlt( hdc, rect->left, rect->top,
1284 width, rect->bottom - rect->top, PATCOPY );
1285 PatBlt( hdc, rect->left, rect->bottom - 1,
1286 rect->right - rect->left, -height, PATCOPY );
1287 PatBlt( hdc, rect->right - 1, rect->top,
1288 -width, rect->bottom - rect->top, PATCOPY );
1290 if (dlgFrame)
1292 InflateRect( rect, -width, -height );
1294 else
1296 INT decYOff = GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXSIZE) - 1;
1297 INT decXOff = GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYSIZE) - 1;
1299 /* Draw inner rectangle */
1301 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1302 Rectangle( hdc, rect->left + width, rect->top + height,
1303 rect->right - width , rect->bottom - height );
1305 /* Draw the decorations */
1307 MoveToEx( hdc, rect->left, rect->top + decYOff, NULL );
1308 LineTo( hdc, rect->left + width, rect->top + decYOff );
1309 MoveToEx( hdc, rect->right - 1, rect->top + decYOff, NULL );
1310 LineTo( hdc, rect->right - width - 1, rect->top + decYOff );
1311 MoveToEx( hdc, rect->left, rect->bottom - decYOff, NULL );
1312 LineTo( hdc, rect->left + width, rect->bottom - decYOff );
1313 MoveToEx( hdc, rect->right - 1, rect->bottom - decYOff, NULL );
1314 LineTo( hdc, rect->right - width - 1, rect->bottom - decYOff );
1316 MoveToEx( hdc, rect->left + decXOff, rect->top, NULL );
1317 LineTo( hdc, rect->left + decXOff, rect->top + height);
1318 MoveToEx( hdc, rect->left + decXOff, rect->bottom - 1, NULL );
1319 LineTo( hdc, rect->left + decXOff, rect->bottom - height - 1 );
1320 MoveToEx( hdc, rect->right - decXOff, rect->top, NULL );
1321 LineTo( hdc, rect->right - decXOff, rect->top + height );
1322 MoveToEx( hdc, rect->right - decXOff, rect->bottom - 1, NULL );
1323 LineTo( hdc, rect->right - decXOff, rect->bottom - height - 1 );
1325 InflateRect( rect, -width - 1, -height - 1 );
1330 /******************************************************************************
1332 * void NC_DrawFrame95(
1333 * HDC32 hdc,
1334 * RECT32 *rect,
1335 * BOOL32 dlgFrame,
1336 * BOOL32 active )
1338 * Draw a window frame inside the given rectangle, and update the rectangle.
1339 * The correct pen for the frame must be selected in the DC.
1341 * Bugs
1342 * Many. First, just what IS a frame in Win95? Note that the 3D look
1343 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1344 * edge. The inner rectangle just inside the frame is handled by the
1345 * Caption code.
1347 * In short, for most people, this function should be a nop (unless
1348 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1349 * them lately, but just to get this code right). Even so, it doesn't
1350 * appear to be so. It's being worked on...
1352 * Revision history
1353 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1354 * Original implementation (based on NC_DrawFrame)
1355 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1356 * Some minor fixes.
1357 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1358 * Fixed a fix or something.
1360 *****************************************************************************/
1362 static void NC_DrawFrame95(
1363 HDC hdc,
1364 RECT *rect,
1365 BOOL dlgFrame,
1366 BOOL active )
1368 INT width, height;
1370 if (dlgFrame)
1372 width = GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
1373 height = GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
1375 else
1377 width = GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXEDGE);
1378 height = GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYEDGE);
1381 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1382 COLOR_INACTIVEBORDER) );
1384 /* Draw frame */
1385 PatBlt( hdc, rect->left, rect->top,
1386 rect->right - rect->left, height, PATCOPY );
1387 PatBlt( hdc, rect->left, rect->top,
1388 width, rect->bottom - rect->top, PATCOPY );
1389 PatBlt( hdc, rect->left, rect->bottom - 1,
1390 rect->right - rect->left, -height, PATCOPY );
1391 PatBlt( hdc, rect->right - 1, rect->top,
1392 -width, rect->bottom - rect->top, PATCOPY );
1394 InflateRect( rect, -width, -height );
1397 /***********************************************************************
1398 * NC_DrawMovingFrame
1400 * Draw the frame used when moving or resizing window.
1402 * FIXME: This causes problems in Win95 mode. (why?)
1404 static void NC_DrawMovingFrame( HDC hdc, RECT *rect, BOOL thickframe )
1406 if (thickframe)
1408 RECT16 r16;
1409 CONV_RECT32TO16( rect, &r16 );
1410 FastWindowFrame16( hdc, &r16, GetSystemMetrics(SM_CXFRAME),
1411 GetSystemMetrics(SM_CYFRAME), PATINVERT );
1413 else DrawFocusRect( hdc, rect );
1417 /***********************************************************************
1418 * NC_DrawCaption
1420 * Draw the window caption.
1421 * The correct pen for the window frame must be selected in the DC.
1423 static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd,
1424 DWORD style, BOOL active )
1426 RECT r = *rect;
1427 WND * wndPtr = WIN_FindWndPtr( hwnd );
1428 char buffer[256];
1430 if (wndPtr->flags & WIN_MANAGED)
1432 WIN_ReleaseWndPtr(wndPtr);
1433 return;
1436 if (!hbitmapClose)
1438 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1440 WIN_ReleaseWndPtr(wndPtr);
1441 return;
1443 hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED) );
1444 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1445 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1446 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1447 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1448 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1449 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1452 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
1454 HBRUSH hbrushOld = SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW) );
1455 PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
1456 PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
1457 PatBlt( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
1458 r.left++;
1459 r.right--;
1460 SelectObject( hdc, hbrushOld );
1462 WIN_ReleaseWndPtr(wndPtr);
1463 MoveTo16( hdc, r.left, r.bottom );
1464 LineTo( hdc, r.right, r.bottom );
1466 if (style & WS_SYSMENU)
1468 NC_DrawSysButton( hwnd, hdc, FALSE );
1469 r.left += GetSystemMetrics(SM_CXSIZE) + 1;
1470 MoveTo16( hdc, r.left - 1, r.top );
1471 LineTo( hdc, r.left - 1, r.bottom );
1473 if (style & WS_MAXIMIZEBOX)
1475 NC_DrawMaxButton( hwnd, hdc, FALSE );
1476 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1478 if (style & WS_MINIMIZEBOX)
1480 NC_DrawMinButton( hwnd, hdc, FALSE );
1481 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1484 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1485 COLOR_INACTIVECAPTION) );
1487 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) ))
1489 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1490 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1491 SetBkMode( hdc, TRANSPARENT );
1492 DrawTextA( hdc, buffer, -1, &r,
1493 DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );
1498 /******************************************************************************
1500 * NC_DrawCaption95(
1501 * HDC32 hdc,
1502 * RECT32 *rect,
1503 * HWND32 hwnd,
1504 * DWORD style,
1505 * BOOL32 active )
1507 * Draw the window caption for Win95 style windows.
1508 * The correct pen for the window frame must be selected in the DC.
1510 * Bugs
1511 * Hey, a function that finally works! Well, almost.
1512 * It's being worked on.
1514 * Revision history
1515 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1516 * Original implementation.
1517 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1518 * Some minor fixes.
1520 *****************************************************************************/
1522 static void NC_DrawCaption95(
1523 HDC hdc,
1524 RECT *rect,
1525 HWND hwnd,
1526 DWORD style,
1527 DWORD exStyle,
1528 BOOL active )
1530 RECT r = *rect;
1531 WND *wndPtr = WIN_FindWndPtr( hwnd );
1532 char buffer[256];
1533 HPEN hPrevPen;
1534 HMENU hSysMenu;
1536 if (wndPtr->flags & WIN_MANAGED)
1538 WIN_ReleaseWndPtr(wndPtr);
1539 return;
1541 WIN_ReleaseWndPtr(wndPtr);
1543 hPrevPen = SelectObject( hdc, GetSysColorPen(COLOR_3DFACE) );
1544 MoveToEx( hdc, r.left, r.bottom - 1, NULL );
1545 LineTo( hdc, r.right, r.bottom - 1 );
1546 SelectObject( hdc, hPrevPen );
1547 r.bottom--;
1549 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1550 COLOR_INACTIVECAPTION) );
1552 if (!hbitmapClose) {
1553 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1554 return;
1555 hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED));
1556 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1557 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1558 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1559 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1560 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1561 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1564 if ((style & WS_SYSMENU) && !(exStyle & WS_EX_TOOLWINDOW)) {
1565 if (NC_DrawSysButton95 (hwnd, hdc, FALSE))
1566 r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
1569 if (style & WS_SYSMENU)
1571 UINT state;
1573 /* Go get the sysmenu */
1574 hSysMenu = GetSystemMenu(hwnd, FALSE);
1575 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
1577 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1578 NC_DrawCloseButton95 (hwnd, hdc, FALSE,
1579 ((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
1580 r.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
1582 if ((style & WS_MAXIMIZEBOX) || (style & WS_MINIMIZEBOX))
1584 /* In win95 the two buttons are always there */
1585 /* But if the menu item is not in the menu they're disabled*/
1587 NC_DrawMaxButton95( hwnd, hdc, FALSE, (!(style & WS_MAXIMIZEBOX)));
1588 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1590 NC_DrawMinButton95( hwnd, hdc, FALSE, (!(style & WS_MINIMIZEBOX)));
1591 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1595 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) )) {
1596 NONCLIENTMETRICSA nclm;
1597 HFONT hFont, hOldFont;
1598 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1599 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1600 if (exStyle & WS_EX_TOOLWINDOW)
1601 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
1602 else
1603 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
1604 hOldFont = SelectObject (hdc, hFont);
1605 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1606 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1607 SetBkMode( hdc, TRANSPARENT );
1608 r.left += 2;
1609 DrawTextA( hdc, buffer, -1, &r,
1610 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
1611 DeleteObject (SelectObject (hdc, hOldFont));
1617 /***********************************************************************
1618 * NC_DoNCPaint
1620 * Paint the non-client area. clip is currently unused.
1622 static void NC_DoNCPaint( WND* wndPtr, HRGN clip, BOOL suppress_menupaint )
1624 HDC hdc;
1625 RECT rect;
1626 BOOL active;
1627 HWND hwnd = wndPtr->hwndSelf;
1629 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1630 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1632 active = wndPtr->flags & WIN_NCACTIVATED;
1634 TRACE_(nonclient)("%04x %d\n", hwnd, active );
1636 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1637 ((clip > 1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN): 0) ))) return;
1639 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1640 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1641 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1642 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1643 == NULLREGION)
1645 ReleaseDC( hwnd, hdc );
1646 return;
1649 rect.top = rect.left = 0;
1650 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1651 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1653 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1655 if (!(wndPtr->flags & WIN_MANAGED))
1657 if (HAS_ANYFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1659 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1660 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1661 InflateRect( &rect, -1, -1 );
1664 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1665 NC_DrawFrame(hdc, &rect, FALSE, active );
1666 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1667 NC_DrawFrame( hdc, &rect, TRUE, active );
1669 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1671 RECT r = rect;
1672 r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
1673 rect.top += GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYBORDER);
1674 NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active );
1678 if (HAS_MENU(wndPtr))
1680 RECT r = rect;
1681 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU); /* default height */
1682 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint );
1685 /* Draw the scroll-bars */
1687 if (wndPtr->dwStyle & WS_VSCROLL)
1688 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1689 if (wndPtr->dwStyle & WS_HSCROLL)
1690 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1692 /* Draw the "size-box" */
1694 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1696 RECT r = rect;
1697 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1698 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1699 if(wndPtr->dwStyle & WS_BORDER) {
1700 r.left++;
1701 r.top++;
1703 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1706 ReleaseDC( hwnd, hdc );
1710 /******************************************************************************
1712 * void NC_DoNCPaint95(
1713 * WND *wndPtr,
1714 * HRGN32 clip,
1715 * BOOL32 suppress_menupaint )
1717 * Paint the non-client area for Win95 windows. The clip region is
1718 * currently ignored.
1720 * Bugs
1721 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1722 * misc/tweak.c controls/menu.c # :-)
1724 * Revision history
1725 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1726 * Original implementation
1727 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1728 * Fixed some bugs.
1729 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1730 * Streamlined window style checks.
1732 *****************************************************************************/
1734 static void NC_DoNCPaint95(
1735 WND *wndPtr,
1736 HRGN clip,
1737 BOOL suppress_menupaint )
1739 HDC hdc;
1740 RECT rfuzz, rect, rectClip;
1741 BOOL active;
1742 HWND hwnd = wndPtr->hwndSelf;
1744 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1745 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1747 active = wndPtr->flags & WIN_NCACTIVATED;
1749 TRACE_(nonclient)("%04x %d\n", hwnd, active );
1751 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in the call to
1752 * GetDCEx implying that it is allowed not to use it either. However, the suggested
1753 * GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN) will cause clipRgn to be deleted
1754 * after ReleaseDC(). Now, how is the "system" supposed to tell what happened?
1757 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1758 ((clip > 1) ?(DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0) ))) return;
1761 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1762 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1763 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1764 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1765 == NULLREGION)
1767 ReleaseDC( hwnd, hdc );
1768 return;
1771 rect.top = rect.left = 0;
1772 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1773 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1775 if( clip > 1 )
1776 GetRgnBox( clip, &rectClip );
1777 else
1779 clip = 0;
1780 rectClip = rect;
1783 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1785 if(!(wndPtr->flags & WIN_MANAGED)) {
1786 if (HAS_BIGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle)) {
1787 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1789 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1790 NC_DrawFrame95(hdc, &rect, FALSE, active );
1791 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1792 NC_DrawFrame95( hdc, &rect, TRUE, active );
1793 else if (HAS_THINFRAME( wndPtr->dwStyle )) {
1794 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1795 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1798 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1800 RECT r = rect;
1801 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW) {
1802 r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
1803 rect.top += GetSystemMetrics(SM_CYSMCAPTION);
1805 else {
1806 r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
1807 rect.top += GetSystemMetrics(SM_CYCAPTION);
1809 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
1810 NC_DrawCaption95 (hdc, &r, hwnd, wndPtr->dwStyle,
1811 wndPtr->dwExStyle, active);
1815 if (HAS_MENU(wndPtr))
1817 RECT r = rect;
1818 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
1820 TRACE_(nonclient)("Calling DrawMenuBar with "
1821 "rect (%d, %d)-(%d, %d)\n", r.left, r.top,
1822 r.right, r.bottom);
1824 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ) + 1;
1827 TRACE_(nonclient)("After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1828 rect.left, rect.top, rect.right, rect.bottom );
1830 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
1831 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1833 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
1834 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1836 /* Draw the scroll-bars */
1838 if (wndPtr->dwStyle & WS_VSCROLL)
1839 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1840 if (wndPtr->dwStyle & WS_HSCROLL)
1841 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1843 /* Draw the "size-box" */
1844 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1846 RECT r = rect;
1847 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1848 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1849 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1852 ReleaseDC( hwnd, hdc );
1858 /***********************************************************************
1859 * NC_HandleNCPaint
1861 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1863 LONG NC_HandleNCPaint( HWND hwnd , HRGN clip)
1865 WND* wndPtr = WIN_FindWndPtr( hwnd );
1867 if( wndPtr && wndPtr->dwStyle & WS_VISIBLE )
1869 if( wndPtr->dwStyle & WS_MINIMIZE )
1870 WINPOS_RedrawIconTitle( hwnd );
1871 else if (TWEAK_WineLook == WIN31_LOOK)
1872 NC_DoNCPaint( wndPtr, clip, FALSE );
1873 else
1874 NC_DoNCPaint95( wndPtr, clip, FALSE );
1876 WIN_ReleaseWndPtr(wndPtr);
1877 return 0;
1881 /***********************************************************************
1882 * NC_HandleNCActivate
1884 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1886 LONG NC_HandleNCActivate( WND *wndPtr, WPARAM16 wParam )
1888 WORD wStateChange;
1890 if( wParam ) wStateChange = !(wndPtr->flags & WIN_NCACTIVATED);
1891 else wStateChange = wndPtr->flags & WIN_NCACTIVATED;
1893 if( wStateChange )
1895 if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
1896 else wndPtr->flags &= ~WIN_NCACTIVATED;
1898 if( wndPtr->dwStyle & WS_MINIMIZE )
1899 WINPOS_RedrawIconTitle( wndPtr->hwndSelf );
1900 else if (TWEAK_WineLook == WIN31_LOOK)
1901 NC_DoNCPaint( wndPtr, (HRGN)1, FALSE );
1902 else
1903 NC_DoNCPaint95( wndPtr, (HRGN)1, FALSE );
1905 return TRUE;
1909 /***********************************************************************
1910 * NC_HandleSetCursor
1912 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1914 LONG NC_HandleSetCursor( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
1916 if (hwnd != (HWND)wParam) return 0; /* Don't set the cursor for child windows */
1918 switch(LOWORD(lParam))
1920 case HTERROR:
1922 WORD msg = HIWORD( lParam );
1923 if ((msg == WM_LBUTTONDOWN) || (msg == WM_MBUTTONDOWN) ||
1924 (msg == WM_RBUTTONDOWN))
1925 MessageBeep(0);
1927 break;
1929 case HTCLIENT:
1931 HICON16 hCursor = (HICON16) GetClassWord(hwnd, GCW_HCURSOR);
1932 if(hCursor) {
1933 SetCursor16(hCursor);
1934 return TRUE;
1936 return FALSE;
1939 case HTLEFT:
1940 case HTRIGHT:
1941 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZEWE16 ) );
1943 case HTTOP:
1944 case HTBOTTOM:
1945 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENS16 ) );
1947 case HTTOPLEFT:
1948 case HTBOTTOMRIGHT:
1949 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENWSE16 ) );
1951 case HTTOPRIGHT:
1952 case HTBOTTOMLEFT:
1953 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENESW16 ) );
1956 /* Default cursor: arrow */
1957 return (LONG)SetCursor16( LoadCursor16( 0, IDC_ARROW16 ) );
1960 /***********************************************************************
1961 * NC_GetSysPopupPos
1963 BOOL NC_GetSysPopupPos( WND* wndPtr, RECT* rect )
1965 if( wndPtr->hSysMenu )
1967 if( wndPtr->dwStyle & WS_MINIMIZE )
1968 GetWindowRect( wndPtr->hwndSelf, rect );
1969 else
1971 if (TWEAK_WineLook == WIN31_LOOK)
1972 NC_GetInsideRect( wndPtr->hwndSelf, rect );
1973 else
1974 NC_GetInsideRect95( wndPtr->hwndSelf, rect );
1975 OffsetRect( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
1976 if (wndPtr->dwStyle & WS_CHILD)
1977 ClientToScreen( wndPtr->parent->hwndSelf, (POINT *)rect );
1978 if (TWEAK_WineLook == WIN31_LOOK) {
1979 rect->right = rect->left + GetSystemMetrics(SM_CXSIZE);
1980 rect->bottom = rect->top + GetSystemMetrics(SM_CYSIZE);
1982 else {
1983 rect->right = rect->left + GetSystemMetrics(SM_CYCAPTION) - 1;
1984 rect->bottom = rect->top + GetSystemMetrics(SM_CYCAPTION) - 1;
1987 return TRUE;
1989 return FALSE;
1992 /***********************************************************************
1993 * NC_StartSizeMove
1995 * Initialisation of a move or resize, when initiatied from a menu choice.
1996 * Return hit test code for caption or sizing border.
1998 static LONG NC_StartSizeMove( WND* wndPtr, WPARAM16 wParam,
1999 POINT16 *capturePoint )
2001 LONG hittest = 0;
2002 POINT16 pt;
2003 MSG msg;
2004 RECT rectWindow;
2006 GetWindowRect(wndPtr->hwndSelf,&rectWindow);
2008 if ((wParam & 0xfff0) == SC_MOVE)
2010 /* Move pointer at the center of the caption */
2011 RECT rect;
2012 if (TWEAK_WineLook == WIN31_LOOK)
2013 NC_GetInsideRect( wndPtr->hwndSelf, &rect );
2014 else
2015 NC_GetInsideRect95( wndPtr->hwndSelf, &rect );
2016 if (wndPtr->dwStyle & WS_SYSMENU)
2017 rect.left += GetSystemMetrics(SM_CXSIZE) + 1;
2018 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
2019 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
2020 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
2021 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
2022 pt.x = rectWindow.left + (rect.right - rect.left) / 2;
2023 pt.y = rectWindow.top + rect.top + GetSystemMetrics(SM_CYSIZE)/2;
2024 hittest = HTCAPTION;
2025 *capturePoint = pt;
2027 else /* SC_SIZE */
2029 while(!hittest)
2031 MSG_InternalGetMessage( &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE );
2032 switch(msg.message)
2034 case WM_MOUSEMOVE:
2035 CONV_POINT32TO16(&msg.pt, &pt);
2036 hittest = NC_HandleNCHitTest( wndPtr->hwndSelf, pt );
2037 if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
2038 hittest = 0;
2039 break;
2041 case WM_LBUTTONUP:
2042 return 0;
2044 case WM_KEYDOWN:
2045 switch(msg.wParam)
2047 case VK_UP:
2048 hittest = HTTOP;
2049 pt.x =(rectWindow.left+rectWindow.right)/2;
2050 pt.y = rectWindow.top + GetSystemMetrics(SM_CYFRAME) / 2;
2051 break;
2052 case VK_DOWN:
2053 hittest = HTBOTTOM;
2054 pt.x =(rectWindow.left+rectWindow.right)/2;
2055 pt.y = rectWindow.bottom - GetSystemMetrics(SM_CYFRAME) / 2;
2056 break;
2057 case VK_LEFT:
2058 hittest = HTLEFT;
2059 pt.x = rectWindow.left + GetSystemMetrics(SM_CXFRAME) / 2;
2060 pt.y =(rectWindow.top+rectWindow.bottom)/2;
2061 break;
2062 case VK_RIGHT:
2063 hittest = HTRIGHT;
2064 pt.x = rectWindow.right - GetSystemMetrics(SM_CXFRAME) / 2;
2065 pt.y =(rectWindow.top+rectWindow.bottom)/2;
2066 break;
2067 case VK_RETURN:
2068 case VK_ESCAPE: return 0;
2072 *capturePoint = pt;
2074 SetCursorPos( pt.x, pt.y );
2075 NC_HandleSetCursor( wndPtr->hwndSelf,
2076 wndPtr->hwndSelf, MAKELONG( hittest, WM_MOUSEMOVE ));
2077 return hittest;
2081 /***********************************************************************
2082 * NC_DoSizeMove
2084 * Perform SC_MOVE and SC_SIZE commands. `
2086 static void NC_DoSizeMove( HWND hwnd, WORD wParam )
2088 MSG msg;
2089 RECT sizingRect, mouseRect;
2090 HDC hdc;
2091 LONG hittest = (LONG)(wParam & 0x0f);
2092 HCURSOR16 hDragCursor = 0, hOldCursor = 0;
2093 POINT minTrack, maxTrack;
2094 POINT16 capturePoint, pt;
2095 WND * wndPtr = WIN_FindWndPtr( hwnd );
2096 BOOL thickframe = HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle );
2097 BOOL iconic = wndPtr->dwStyle & WS_MINIMIZE;
2098 BOOL moved = FALSE;
2099 DWORD dwPoint = GetMessagePos ();
2101 capturePoint = pt = *(POINT16*)&dwPoint;
2103 if (IsZoomed(hwnd) || !IsWindowVisible(hwnd) ||
2104 (wndPtr->flags & WIN_MANAGED)) goto END;
2106 if ((wParam & 0xfff0) == SC_MOVE)
2108 if (!(wndPtr->dwStyle & WS_CAPTION)) goto END;
2109 if (!hittest)
2110 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2111 if (!hittest) goto END;
2113 else /* SC_SIZE */
2115 if (!thickframe) goto END;
2116 if ( hittest && hittest != HTSYSMENU ) hittest += 2;
2117 else
2119 SetCapture(hwnd);
2120 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2121 if (!hittest)
2123 ReleaseCapture();
2124 goto END;
2129 /* Get min/max info */
2131 WINPOS_GetMinMaxInfo( wndPtr, NULL, NULL, &minTrack, &maxTrack );
2132 sizingRect = wndPtr->rectWindow;
2133 if (wndPtr->dwStyle & WS_CHILD)
2134 GetClientRect( wndPtr->parent->hwndSelf, &mouseRect );
2135 else
2136 SetRect(&mouseRect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
2137 if (ON_LEFT_BORDER(hittest))
2139 mouseRect.left = MAX( mouseRect.left, sizingRect.right-maxTrack.x );
2140 mouseRect.right = MIN( mouseRect.right, sizingRect.right-minTrack.x );
2142 else if (ON_RIGHT_BORDER(hittest))
2144 mouseRect.left = MAX( mouseRect.left, sizingRect.left+minTrack.x );
2145 mouseRect.right = MIN( mouseRect.right, sizingRect.left+maxTrack.x );
2147 if (ON_TOP_BORDER(hittest))
2149 mouseRect.top = MAX( mouseRect.top, sizingRect.bottom-maxTrack.y );
2150 mouseRect.bottom = MIN( mouseRect.bottom,sizingRect.bottom-minTrack.y);
2152 else if (ON_BOTTOM_BORDER(hittest))
2154 mouseRect.top = MAX( mouseRect.top, sizingRect.top+minTrack.y );
2155 mouseRect.bottom = MIN( mouseRect.bottom, sizingRect.top+maxTrack.y );
2157 if (wndPtr->dwStyle & WS_CHILD)
2159 MapWindowPoints( wndPtr->parent->hwndSelf, 0,
2160 (LPPOINT)&mouseRect, 2 );
2162 SendMessage16( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
2164 if (GetCapture() != hwnd) SetCapture( hwnd );
2166 if (wndPtr->dwStyle & WS_CHILD)
2168 /* Retrieve a default cache DC (without using the window style) */
2169 hdc = GetDCEx( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
2171 else
2172 { /* Grab the server only when moving top-level windows without desktop */
2173 hdc = GetDC( 0 );
2176 wndPtr->pDriver->pPreSizeMove(wndPtr);
2178 if( iconic ) /* create a cursor for dragging */
2180 HICON16 hIcon = GetClassWord(wndPtr->hwndSelf, GCW_HICON);
2181 if(!hIcon) hIcon = (HICON16) SendMessage16( hwnd, WM_QUERYDRAGICON, 0, 0L);
2182 if( hIcon ) hDragCursor = CURSORICON_IconToCursor( hIcon, TRUE );
2183 if( !hDragCursor ) iconic = FALSE;
2186 if( !iconic ) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2188 while(1)
2190 int dx = 0, dy = 0;
2192 MSG_InternalGetMessage( &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE );
2194 /* Exit on button-up, Return, or Esc */
2195 if ((msg.message == WM_LBUTTONUP) ||
2196 ((msg.message == WM_KEYDOWN) &&
2197 ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
2199 if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
2200 continue; /* We are not interested in other messages */
2202 dwPoint = GetMessagePos ();
2203 pt = *(POINT16*)&dwPoint;
2205 if (msg.message == WM_KEYDOWN) switch(msg.wParam)
2207 case VK_UP: pt.y -= 8; break;
2208 case VK_DOWN: pt.y += 8; break;
2209 case VK_LEFT: pt.x -= 8; break;
2210 case VK_RIGHT: pt.x += 8; break;
2213 pt.x = MAX( pt.x, mouseRect.left );
2214 pt.x = MIN( pt.x, mouseRect.right );
2215 pt.y = MAX( pt.y, mouseRect.top );
2216 pt.y = MIN( pt.y, mouseRect.bottom );
2218 dx = pt.x - capturePoint.x;
2219 dy = pt.y - capturePoint.y;
2221 if (dx || dy)
2223 if( !moved )
2225 moved = TRUE;
2226 if( iconic ) /* ok, no system popup tracking */
2228 hOldCursor = SetCursor(hDragCursor);
2229 ShowCursor( TRUE );
2230 WINPOS_ShowIconTitle( wndPtr, FALSE );
2234 if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
2235 else
2237 RECT newRect = sizingRect;
2239 if (hittest == HTCAPTION) OffsetRect( &newRect, dx, dy );
2240 if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
2241 else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
2242 if (ON_TOP_BORDER(hittest)) newRect.top += dy;
2243 else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
2244 if( !iconic )
2246 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2247 NC_DrawMovingFrame( hdc, &newRect, thickframe );
2249 capturePoint = pt;
2250 sizingRect = newRect;
2255 ReleaseCapture();
2256 if( iconic )
2258 if( moved ) /* restore cursors, show icon title later on */
2260 ShowCursor( FALSE );
2261 SetCursor( hOldCursor );
2263 DestroyCursor( hDragCursor );
2265 else
2266 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2268 if (wndPtr->dwStyle & WS_CHILD)
2269 ReleaseDC( wndPtr->parent->hwndSelf, hdc );
2270 else
2272 ReleaseDC( 0, hdc );
2275 wndPtr->pDriver->pPostSizeMove(wndPtr);
2277 if (HOOK_IsHooked( WH_CBT ))
2279 RECT16* pr = SEGPTR_NEW(RECT16);
2280 if( pr )
2282 CONV_RECT32TO16( &sizingRect, pr );
2283 if( HOOK_CallHooks16( WH_CBT, HCBT_MOVESIZE, hwnd,
2284 (LPARAM)SEGPTR_GET(pr)) )
2285 sizingRect = wndPtr->rectWindow;
2286 else
2287 CONV_RECT16TO32( pr, &sizingRect );
2288 SEGPTR_FREE(pr);
2291 SendMessage16( hwnd, WM_EXITSIZEMOVE, 0, 0 );
2292 SendMessage16( hwnd, WM_SETVISIBLE, !IsIconic16(hwnd), 0L);
2294 /* window moved or resized */
2295 if (moved)
2297 /* if the moving/resizing isn't canceled call SetWindowPos
2298 * with the new position or the new size of the window
2300 if (!((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
2302 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
2303 SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top,
2304 sizingRect.right - sizingRect.left,
2305 sizingRect.bottom - sizingRect.top,
2306 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
2308 else
2310 /* if the moving/resizing is canceled and the window is not active
2311 * call SetWindowPos to activate and to show this window
2313 if (GetActiveWindow() != hwnd)
2314 SetWindowPos( hwnd, 0, 0, 0,0,0,SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
2317 else
2319 /* show the window if it is not moved/resized and it is not active */
2320 if (GetActiveWindow() != hwnd)
2321 SetWindowPos( hwnd, 0, 0, 0,0,0,SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
2324 if( IsWindow(hwnd) )
2325 if( wndPtr->dwStyle & WS_MINIMIZE )
2327 /* Single click brings up the system menu when iconized */
2329 if( !moved )
2331 if( wndPtr->dwStyle & WS_SYSMENU )
2332 SendMessage16( hwnd, WM_SYSCOMMAND,
2333 SC_MOUSEMENU + HTSYSMENU, *((LPARAM*)&pt));
2335 else WINPOS_ShowIconTitle( wndPtr, TRUE );
2338 END:
2339 WIN_ReleaseWndPtr(wndPtr);
2343 /***********************************************************************
2344 * NC_TrackMinMaxBox95
2346 * Track a mouse button press on the minimize or maximize box.
2348 * The big difference between 3.1 and 95 is the disabled button state.
2349 * In win95 the system button can be disabled, so it can ignore the mouse
2350 * event.
2353 static void NC_TrackMinMaxBox95( HWND hwnd, WORD wParam )
2355 MSG msg;
2356 POINT16 pt16;
2357 HDC hdc = GetWindowDC( hwnd );
2358 BOOL pressed = TRUE;
2359 UINT state;
2360 DWORD wndStyle = GetWindowLongA( hwnd, GWL_STYLE);
2361 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
2363 void (*paintButton)(HWND, HDC16, BOOL, BOOL);
2365 if (wParam == HTMINBUTTON)
2367 /* If the style is not present, do nothing */
2368 if (!(wndStyle & WS_MINIMIZEBOX))
2369 return;
2371 /* Check if the sysmenu item for minimize is there */
2372 state = GetMenuState(hSysMenu, SC_MINIMIZE, MF_BYCOMMAND);
2374 paintButton = &NC_DrawMinButton95;
2376 else
2378 /* If the style is not present, do nothing */
2379 if (!(wndStyle & WS_MAXIMIZEBOX))
2380 return;
2382 /* Check if the sysmenu item for maximize is there */
2383 state = GetMenuState(hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
2385 paintButton = &NC_DrawMaxButton95;
2388 SetCapture( hwnd );
2390 (*paintButton)( hwnd, hdc, TRUE, FALSE);
2394 BOOL oldstate = pressed;
2395 MSG_InternalGetMessage( &msg, 0, 0, 0, PM_REMOVE, FALSE );
2396 CONV_POINT32TO16( &msg.pt, &pt16 );
2398 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2399 if (pressed != oldstate)
2400 (*paintButton)( hwnd, hdc, pressed, FALSE);
2401 } while (msg.message != WM_LBUTTONUP);
2403 (*paintButton)( hwnd, hdc, FALSE, FALSE);
2405 ReleaseCapture();
2406 ReleaseDC( hwnd, hdc );
2408 /* If the item minimize or maximize of the sysmenu are not there */
2409 /* or if the style is not present, do nothing */
2410 if ((!pressed) || (state == 0xFFFFFFFF))
2411 return;
2413 if (wParam == HTMINBUTTON)
2414 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&pt16 );
2415 else
2416 SendMessage16( hwnd, WM_SYSCOMMAND,
2417 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, *(LONG*)&pt16 );
2420 /***********************************************************************
2421 * NC_TrackMinMaxBox
2423 * Track a mouse button press on the minimize or maximize box.
2425 static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
2427 MSG msg;
2428 POINT16 pt16;
2429 HDC hdc = GetWindowDC( hwnd );
2430 BOOL pressed = TRUE;
2431 void (*paintButton)(HWND, HDC16, BOOL);
2433 SetCapture( hwnd );
2435 if (wParam == HTMINBUTTON)
2436 paintButton = &NC_DrawMinButton;
2437 else
2438 paintButton = &NC_DrawMaxButton;
2440 (*paintButton)( hwnd, hdc, TRUE);
2444 BOOL oldstate = pressed;
2445 MSG_InternalGetMessage( &msg, 0, 0, 0, PM_REMOVE, FALSE );
2446 CONV_POINT32TO16( &msg.pt, &pt16 );
2448 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2449 if (pressed != oldstate)
2450 (*paintButton)( hwnd, hdc, pressed);
2451 } while (msg.message != WM_LBUTTONUP);
2453 (*paintButton)( hwnd, hdc, FALSE);
2455 ReleaseCapture();
2456 ReleaseDC( hwnd, hdc );
2458 if (!pressed) return;
2460 if (wParam == HTMINBUTTON)
2461 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&pt16 );
2462 else
2463 SendMessage16( hwnd, WM_SYSCOMMAND,
2464 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, *(LONG*)&pt16 );
2468 /***********************************************************************
2469 * NC_TrackCloseButton95
2471 * Track a mouse button press on the Win95 close button.
2473 static void
2474 NC_TrackCloseButton95 (HWND hwnd, WORD wParam)
2476 MSG msg;
2477 POINT16 pt16;
2478 HDC hdc;
2479 BOOL pressed = TRUE;
2480 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
2481 UINT state;
2483 if(hSysMenu == 0)
2484 return;
2486 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
2488 /* If the item close of the sysmenu is disabled or not there do nothing */
2489 if((state & MF_DISABLED) || (state & MF_GRAYED) || (state == 0xFFFFFFFF))
2490 return;
2492 hdc = GetWindowDC( hwnd );
2494 SetCapture( hwnd );
2496 NC_DrawCloseButton95 (hwnd, hdc, TRUE, FALSE);
2500 BOOL oldstate = pressed;
2501 MSG_InternalGetMessage( &msg, 0, 0, 0, PM_REMOVE, FALSE );
2502 CONV_POINT32TO16( &msg.pt, &pt16 );
2504 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2505 if (pressed != oldstate)
2506 NC_DrawCloseButton95 (hwnd, hdc, pressed, FALSE);
2507 } while (msg.message != WM_LBUTTONUP);
2509 NC_DrawCloseButton95 (hwnd, hdc, FALSE, FALSE);
2511 ReleaseCapture();
2512 ReleaseDC( hwnd, hdc );
2513 if (!pressed) return;
2515 SendMessage16( hwnd, WM_SYSCOMMAND, SC_CLOSE, *(LONG*)&pt16 );
2519 /***********************************************************************
2520 * NC_TrackScrollBar
2522 * Track a mouse button press on the horizontal or vertical scroll-bar.
2524 static void NC_TrackScrollBar( HWND hwnd, WPARAM wParam, POINT pt )
2526 MSG16 *msg;
2527 INT scrollbar;
2528 WND *wndPtr = WIN_FindWndPtr( hwnd );
2530 if ((wParam & 0xfff0) == SC_HSCROLL)
2532 if ((wParam & 0x0f) != HTHSCROLL) goto END;
2533 scrollbar = SB_HORZ;
2535 else /* SC_VSCROLL */
2537 if ((wParam & 0x0f) != HTVSCROLL) goto END;
2538 scrollbar = SB_VERT;
2541 if (!(msg = SEGPTR_NEW(MSG16))) goto END;
2542 pt.x -= wndPtr->rectWindow.left;
2543 pt.y -= wndPtr->rectWindow.top;
2544 SetCapture( hwnd );
2545 SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt );
2549 GetMessage16( SEGPTR_GET(msg), 0, 0, 0 );
2550 switch(msg->message)
2552 case WM_LBUTTONUP:
2553 case WM_MOUSEMOVE:
2554 case WM_SYSTIMER:
2555 pt.x = LOWORD(msg->lParam) + wndPtr->rectClient.left -
2556 wndPtr->rectWindow.left;
2557 pt.y = HIWORD(msg->lParam) + wndPtr->rectClient.top -
2558 wndPtr->rectWindow.top;
2559 SCROLL_HandleScrollEvent( hwnd, scrollbar, msg->message, pt );
2560 break;
2561 default:
2562 TranslateMessage16( msg );
2563 DispatchMessage16( msg );
2564 break;
2566 if (!IsWindow( hwnd ))
2568 ReleaseCapture();
2569 break;
2571 } while (msg->message != WM_LBUTTONUP);
2572 SEGPTR_FREE(msg);
2573 END:
2574 WIN_ReleaseWndPtr(wndPtr);
2577 /***********************************************************************
2578 * NC_HandleNCLButtonDown
2580 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2582 LONG NC_HandleNCLButtonDown( WND* pWnd, WPARAM16 wParam, LPARAM lParam )
2584 HWND hwnd = pWnd->hwndSelf;
2586 switch(wParam) /* Hit test */
2588 case HTCAPTION:
2589 hwnd = WIN_GetTopParent(hwnd);
2591 if( WINPOS_SetActiveWindow(hwnd, TRUE, TRUE) || (GetActiveWindow() == hwnd) )
2592 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
2593 break;
2595 case HTSYSMENU:
2596 if( pWnd->dwStyle & WS_SYSMENU )
2598 if( !(pWnd->dwStyle & WS_MINIMIZE) )
2600 HDC hDC = GetWindowDC(hwnd);
2601 if (TWEAK_WineLook == WIN31_LOOK)
2602 NC_DrawSysButton( hwnd, hDC, TRUE );
2603 else
2604 NC_DrawSysButton95( hwnd, hDC, TRUE );
2605 ReleaseDC( hwnd, hDC );
2607 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
2609 break;
2611 case HTMENU:
2612 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam );
2613 break;
2615 case HTHSCROLL:
2616 SendMessage16( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
2617 break;
2619 case HTVSCROLL:
2620 SendMessage16( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
2621 break;
2623 case HTMINBUTTON:
2624 case HTMAXBUTTON:
2625 if (TWEAK_WineLook == WIN31_LOOK)
2626 NC_TrackMinMaxBox( hwnd, wParam );
2627 else
2628 NC_TrackMinMaxBox95( hwnd, wParam );
2629 break;
2631 case HTCLOSE:
2632 if (TWEAK_WineLook >= WIN95_LOOK)
2633 NC_TrackCloseButton95 (hwnd, wParam);
2634 break;
2636 case HTLEFT:
2637 case HTRIGHT:
2638 case HTTOP:
2639 case HTTOPLEFT:
2640 case HTTOPRIGHT:
2641 case HTBOTTOM:
2642 case HTBOTTOMLEFT:
2643 case HTBOTTOMRIGHT:
2644 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2645 SendMessage16( hwnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam);
2646 break;
2648 case HTBORDER:
2649 break;
2651 return 0;
2655 /***********************************************************************
2656 * NC_HandleNCLButtonDblClk
2658 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2660 LONG NC_HandleNCLButtonDblClk( WND *pWnd, WPARAM16 wParam, LPARAM lParam )
2663 * if this is an icon, send a restore since we are handling
2664 * a double click
2666 if (pWnd->dwStyle & WS_MINIMIZE)
2668 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_RESTORE, lParam );
2669 return 0;
2672 switch(wParam) /* Hit test */
2674 case HTCAPTION:
2675 /* stop processing if WS_MAXIMIZEBOX is missing */
2676 if (pWnd->dwStyle & WS_MAXIMIZEBOX)
2677 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND,
2678 (pWnd->dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
2679 lParam );
2680 break;
2682 case HTSYSMENU:
2683 if (!(GetClassWord(pWnd->hwndSelf, GCW_STYLE) & CS_NOCLOSE))
2684 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, lParam );
2685 break;
2687 case HTHSCROLL:
2688 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL,
2689 lParam );
2690 break;
2692 case HTVSCROLL:
2693 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL,
2694 lParam );
2695 break;
2697 return 0;
2701 /***********************************************************************
2702 * NC_HandleSysCommand
2704 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2706 LONG NC_HandleSysCommand( HWND hwnd, WPARAM16 wParam, POINT16 pt )
2708 WND *wndPtr = WIN_FindWndPtr( hwnd );
2709 POINT pt32;
2710 UINT16 uCommand = wParam & 0xFFF0;
2712 TRACE_(nonclient)("Handling WM_SYSCOMMAND %x %d,%d\n",
2713 wParam, pt.x, pt.y );
2715 if (wndPtr->dwStyle & WS_CHILD && uCommand != SC_KEYMENU )
2716 ScreenToClient16( wndPtr->parent->hwndSelf, &pt );
2718 switch (uCommand)
2720 case SC_SIZE:
2721 case SC_MOVE:
2722 NC_DoSizeMove( hwnd, wParam );
2723 break;
2725 case SC_MINIMIZE:
2726 ShowWindow( hwnd, SW_MINIMIZE );
2727 break;
2729 case SC_MAXIMIZE:
2730 ShowWindow( hwnd, SW_MAXIMIZE );
2731 break;
2733 case SC_RESTORE:
2734 ShowWindow( hwnd, SW_RESTORE );
2735 break;
2737 case SC_CLOSE:
2738 WIN_ReleaseWndPtr(wndPtr);
2739 return SendMessage16( hwnd, WM_CLOSE, 0, 0 );
2741 case SC_VSCROLL:
2742 case SC_HSCROLL:
2743 CONV_POINT16TO32( &pt, &pt32 );
2744 NC_TrackScrollBar( hwnd, wParam, pt32 );
2745 break;
2747 case SC_MOUSEMENU:
2748 CONV_POINT16TO32( &pt, &pt32 );
2749 MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt32 );
2750 break;
2752 case SC_KEYMENU:
2753 MENU_TrackKbdMenuBar( wndPtr , wParam , pt.x );
2754 break;
2756 case SC_TASKLIST:
2757 WinExec( "taskman.exe", SW_SHOWNORMAL );
2758 break;
2760 case SC_SCREENSAVE:
2761 if (wParam == SC_ABOUTWINE)
2762 ShellAboutA(hwnd,"Wine", WINE_RELEASE_INFO, 0);
2763 else
2764 if (wParam == SC_PUTMARK)
2765 TRACE_(shell)("Mark requested by user\n");
2766 break;
2768 case SC_HOTKEY:
2769 case SC_ARRANGE:
2770 case SC_NEXTWINDOW:
2771 case SC_PREVWINDOW:
2772 FIXME_(nonclient)("unimplemented!\n");
2773 break;
2775 WIN_ReleaseWndPtr(wndPtr);
2776 return 0;
2779 /*************************************************************
2780 * NC_DrawGrayButton
2782 * Stub for the grayed button of the caption
2784 *************************************************************/
2786 BOOL NC_DrawGrayButton(HDC hdc, int x, int y)
2788 HBITMAP hMaskBmp;
2789 HDC hdcMask = CreateCompatibleDC (0);
2790 HBRUSH hOldBrush;
2792 hMaskBmp = CreateBitmap (12, 10, 1, 1, lpGrayMask);
2794 if(hMaskBmp == 0)
2795 return FALSE;
2797 SelectObject (hdcMask, hMaskBmp);
2799 /* Draw the grayed bitmap using the mask */
2800 hOldBrush = SelectObject (hdc, RGB(128, 128, 128));
2801 BitBlt (hdc, x, y, 12, 10,
2802 hdcMask, 0, 0, 0xB8074A);
2804 /* Clean up */
2805 SelectObject (hdc, hOldBrush);
2806 DeleteObject(hMaskBmp);
2807 DeleteDC (hdcMask);
2809 return TRUE;