wineinstall now properly configures no-windows installs, and should now
[wine/multimedia.git] / windows / nonclient.c
blobf35caef3ed1e37ed3f6aa6cec7cdcd6386909225
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 "cursoricon.h"
18 #include "dialog.h"
19 #include "menu.h"
20 #include "winpos.h"
21 #include "hook.h"
22 #include "scroll.h"
23 #include "nonclient.h"
24 #include "queue.h"
25 #include "selectors.h"
26 #include "tweak.h"
27 #include "debugtools.h"
28 #include "options.h"
29 #include "shellapi.h"
30 #include "cache.h"
31 #include "bitmap.h"
33 DEFAULT_DEBUG_CHANNEL(nonclient)
34 DECLARE_DEBUG_CHANNEL(shell)
36 BOOL NC_DrawGrayButton(HDC hdc, int x, int y);
38 static HBITMAP16 hbitmapClose = 0;
39 static HBITMAP16 hbitmapCloseD = 0;
40 static HBITMAP16 hbitmapMinimize = 0;
41 static HBITMAP16 hbitmapMinimizeD = 0;
42 static HBITMAP16 hbitmapMaximize = 0;
43 static HBITMAP16 hbitmapMaximizeD = 0;
44 static HBITMAP16 hbitmapRestore = 0;
45 static HBITMAP16 hbitmapRestoreD = 0;
47 BYTE lpGrayMask[] = { 0xAA, 0xA0,
48 0x55, 0x50,
49 0xAA, 0xA0,
50 0x55, 0x50,
51 0xAA, 0xA0,
52 0x55, 0x50,
53 0xAA, 0xA0,
54 0x55, 0x50,
55 0xAA, 0xA0,
56 0x55, 0x50};
58 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
59 #define SC_PUTMARK (SC_SCREENSAVE+2)
61 /* Some useful macros */
62 #define HAS_DLGFRAME(style,exStyle) \
63 (((exStyle) & WS_EX_DLGMODALFRAME) || \
64 (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
66 #define HAS_THICKFRAME(style,exStyle) \
67 (((style) & WS_THICKFRAME) && \
68 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
70 #define HAS_THINFRAME(style) \
71 (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
73 #define HAS_BIGFRAME(style,exStyle) \
74 (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
75 ((exStyle) & WS_EX_DLGMODALFRAME))
77 #define HAS_ANYFRAME(style,exStyle) \
78 (((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
79 ((exStyle) & WS_EX_DLGMODALFRAME) || \
80 !((style) & (WS_CHILD | WS_POPUP)))
82 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
84 #define ON_LEFT_BORDER(hit) \
85 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
86 #define ON_RIGHT_BORDER(hit) \
87 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
88 #define ON_TOP_BORDER(hit) \
89 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
90 #define ON_BOTTOM_BORDER(hit) \
91 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
93 /***********************************************************************
94 * WIN_WindowNeedsWMBorder
96 * This method defines the rules for a window to have a WM border,
97 * caption... It is used for consitency purposes.
99 BOOL WIN_WindowNeedsWMBorder( DWORD style, DWORD exStyle )
101 if (!(style & WS_CHILD) &&
102 Options.managed &&
103 !(exStyle & WS_EX_TOOLWINDOW) &&
104 ( ((style & WS_CAPTION) == WS_CAPTION) ||
105 (style & WS_THICKFRAME)))
106 return TRUE;
107 if (exStyle & WS_EX_TRAYWINDOW)
108 return TRUE;
109 return FALSE;
112 /***********************************************************************
113 * NC_AdjustRect
115 * Compute the size of the window rectangle from the size of the
116 * client rectangle.
118 static void NC_AdjustRect( LPRECT16 rect, DWORD style, BOOL menu,
119 DWORD exStyle )
121 if (TWEAK_WineLook > WIN31_LOOK)
122 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
124 if(style & WS_ICONIC) return;
125 /* Decide if the window will be managed (see CreateWindowEx) */
126 if (!WIN_WindowNeedsWMBorder(style, exStyle))
128 if (HAS_THICKFRAME( style, exStyle ))
129 InflateRect16( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
130 else
131 if (HAS_DLGFRAME( style, exStyle ))
132 InflateRect16( rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
133 else
134 if (HAS_THINFRAME( style ))
135 InflateRect16( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
137 if ((style & WS_CAPTION) == WS_CAPTION)
138 rect->top -= GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
140 if (menu) rect->top -= GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYBORDER);
142 if (style & WS_VSCROLL) {
143 rect->right += GetSystemMetrics(SM_CXVSCROLL) - 1;
144 if(!HAS_ANYFRAME( style, exStyle ))
145 rect->right++;
148 if (style & WS_HSCROLL) {
149 rect->bottom += GetSystemMetrics(SM_CYHSCROLL) - 1;
150 if(!HAS_ANYFRAME( style, exStyle ))
151 rect->bottom++;
156 /******************************************************************************
157 * NC_AdjustRectOuter95
159 * Computes the size of the "outside" parts of the window based on the
160 * parameters of the client area.
162 + PARAMS
163 * LPRECT16 rect
164 * DWORD style
165 * BOOL menu
166 * DWORD exStyle
168 * NOTES
169 * "Outer" parts of a window means the whole window frame, caption and
170 * menu bar. It does not include "inner" parts of the frame like client
171 * edge, static edge or scroll bars.
173 * Revision history
174 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
175 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
177 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
178 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
179 * NC_AdjustRectInner95 and added handling of Win95 styles.
181 * 28-Jul-1999 Ove Kåven (ovek@arcticnet.no)
182 * Streamlined window style checks.
184 *****************************************************************************/
186 static void
187 NC_AdjustRectOuter95 (LPRECT16 rect, DWORD style, BOOL menu, DWORD exStyle)
189 if(style & WS_ICONIC) return;
191 /* Decide if the window will be managed (see CreateWindowEx) */
192 if (!WIN_WindowNeedsWMBorder(style, exStyle))
194 if (HAS_THICKFRAME( style, exStyle ))
195 InflateRect16( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
196 else
197 if (HAS_DLGFRAME( style, exStyle ))
198 InflateRect16(rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
199 else
200 if (HAS_THINFRAME( style ))
201 InflateRect16( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
203 if ((style & WS_CAPTION) == WS_CAPTION)
205 if (exStyle & WS_EX_TOOLWINDOW)
206 rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
207 else
208 rect->top -= GetSystemMetrics(SM_CYCAPTION);
212 if (menu)
213 rect->top -= GetSystemMetrics(SM_CYMENU);
217 /******************************************************************************
218 * NC_AdjustRectInner95
220 * Computes the size of the "inside" part of the window based on the
221 * parameters of the client area.
223 + PARAMS
224 * LPRECT16 rect
225 * DWORD style
226 * DWORD exStyle
228 * NOTES
229 * "Inner" part of a window means the window frame inside of the flat
230 * window frame. It includes the client edge, the static edge and the
231 * scroll bars.
233 * Revision history
234 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
235 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
237 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
238 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
239 * NC_AdjustRectInner95 and added handling of Win95 styles.
241 *****************************************************************************/
243 static void
244 NC_AdjustRectInner95 (LPRECT16 rect, DWORD style, DWORD exStyle)
246 if(style & WS_ICONIC) return;
248 if (exStyle & WS_EX_CLIENTEDGE)
249 InflateRect16 (rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
251 if (exStyle & WS_EX_STATICEDGE)
252 InflateRect16 (rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
254 if (style & WS_VSCROLL) rect->right += GetSystemMetrics(SM_CXVSCROLL);
255 if (style & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
259 /***********************************************************************
260 * DrawCaption16 [USER.660] Draws a caption bar
262 * PARAMS
263 * hwnd [I]
264 * hdc [I]
265 * lpRect [I]
266 * uFlags [I]
268 * RETURNS
269 * Success:
270 * Failure:
273 BOOL16 WINAPI
274 DrawCaption16 (HWND16 hwnd, HDC16 hdc, const RECT16 *rect, UINT16 uFlags)
276 RECT rect32;
278 if (rect)
279 CONV_RECT16TO32 (rect, &rect32);
281 return (BOOL16)DrawCaptionTempA (hwnd, hdc, rect ? &rect32 : NULL,
282 0, 0, NULL, uFlags & 0x1F);
286 /***********************************************************************
287 * DrawCaption [USER32.154] Draws a caption bar
289 * PARAMS
290 * hwnd [I]
291 * hdc [I]
292 * lpRect [I]
293 * uFlags [I]
295 * RETURNS
296 * Success:
297 * Failure:
300 BOOL WINAPI
301 DrawCaption (HWND hwnd, HDC hdc, const RECT *lpRect, UINT uFlags)
303 return DrawCaptionTempA (hwnd, hdc, lpRect, 0, 0, NULL, uFlags & 0x1F);
307 /***********************************************************************
308 * DrawCaptionTemp16 [USER.657]
310 * PARAMS
312 * RETURNS
313 * Success:
314 * Failure:
317 BOOL16 WINAPI
318 DrawCaptionTemp16 (HWND16 hwnd, HDC16 hdc, const RECT16 *rect, HFONT16 hFont,
319 HICON16 hIcon, LPCSTR str, UINT16 uFlags)
321 RECT rect32;
323 if (rect)
324 CONV_RECT16TO32(rect,&rect32);
326 return (BOOL16)DrawCaptionTempA (hwnd, hdc, rect?&rect32:NULL, hFont,
327 hIcon, str, uFlags & 0x1F);
331 /***********************************************************************
332 * DrawCaptionTempA [USER32.599]
334 * PARAMS
336 * RETURNS
337 * Success:
338 * Failure:
341 BOOL WINAPI
342 DrawCaptionTempA (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
343 HICON hIcon, LPCSTR str, UINT uFlags)
345 RECT rc = *rect;
347 TRACE("(%08x,%08x,%p,%08x,%08x,\"%s\",%08x)\n",
348 hwnd, hdc, rect, hFont, hIcon, str, uFlags);
350 /* drawing background */
351 if (uFlags & DC_INBUTTON) {
352 FillRect (hdc, &rc, GetSysColorBrush (COLOR_3DFACE));
354 if (uFlags & DC_ACTIVE) {
355 HBRUSH hbr = SelectObject (hdc, CACHE_GetPattern55AABrush ());
356 PatBlt (hdc, rc.left, rc.top,
357 rc.right-rc.left, rc.bottom-rc.top, 0xFA0089);
358 SelectObject (hdc, hbr);
361 else {
362 FillRect (hdc, &rc, GetSysColorBrush ((uFlags & DC_ACTIVE) ?
363 COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
367 /* drawing icon */
368 if ((uFlags & DC_ICON) && !(uFlags & DC_SMALLCAP)) {
369 POINT pt;
371 pt.x = rc.left + 2;
372 pt.y = (rc.bottom + rc.top - GetSystemMetrics(SM_CYSMICON)) / 2;
374 if (hIcon) {
375 DrawIconEx (hdc, pt.x, pt.y, hIcon, GetSystemMetrics(SM_CXSMICON),
376 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
378 else {
379 HICON hAppIcon = (HICON) GetClassLongA(hwnd, GCL_HICONSM);
380 if(!hAppIcon) hAppIcon = (HICON) GetClassLongA(hwnd, GCL_HICON);
382 DrawIconEx (hdc, pt.x, pt.y, hAppIcon, GetSystemMetrics(SM_CXSMICON),
383 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
386 rc.left += (rc.bottom - rc.top);
389 /* drawing text */
390 if (uFlags & DC_TEXT) {
391 HFONT hOldFont;
393 if (uFlags & DC_INBUTTON)
394 SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
395 else if (uFlags & DC_ACTIVE)
396 SetTextColor (hdc, GetSysColor (COLOR_CAPTIONTEXT));
397 else
398 SetTextColor (hdc, GetSysColor (COLOR_INACTIVECAPTIONTEXT));
400 SetBkMode (hdc, TRANSPARENT);
402 if (hFont)
403 hOldFont = SelectObject (hdc, hFont);
404 else {
405 NONCLIENTMETRICSA nclm;
406 HFONT hNewFont;
407 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
408 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
409 hNewFont = CreateFontIndirectA ((uFlags & DC_SMALLCAP) ?
410 &nclm.lfSmCaptionFont : &nclm.lfCaptionFont);
411 hOldFont = SelectObject (hdc, hNewFont);
414 if (str)
415 DrawTextA (hdc, str, -1, &rc,
416 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
417 else {
418 CHAR szText[128];
419 INT nLen;
420 nLen = GetWindowTextA (hwnd, szText, 128);
421 DrawTextA (hdc, szText, nLen, &rc,
422 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
425 if (hFont)
426 SelectObject (hdc, hOldFont);
427 else
428 DeleteObject (SelectObject (hdc, hOldFont));
431 /* drawing focus ??? */
432 if (uFlags & 0x2000)
433 FIXME("undocumented flag (0x2000)!\n");
435 return 0;
439 /***********************************************************************
440 * DrawCaptionTempW [USER32.602]
442 * PARAMS
444 * RETURNS
445 * Success:
446 * Failure:
449 BOOL WINAPI
450 DrawCaptionTempW (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
451 HICON hIcon, LPCWSTR str, UINT uFlags)
453 LPSTR p = HEAP_strdupWtoA (GetProcessHeap (), 0, str);
454 BOOL res = DrawCaptionTempA (hwnd, hdc, rect, hFont, hIcon, p, uFlags);
455 HeapFree (GetProcessHeap (), 0, p);
456 return res;
460 /***********************************************************************
461 * AdjustWindowRect16 (USER.102)
463 BOOL16 WINAPI AdjustWindowRect16( LPRECT16 rect, DWORD style, BOOL16 menu )
465 return AdjustWindowRectEx16( rect, style, menu, 0 );
469 /***********************************************************************
470 * AdjustWindowRect (USER32.2)
472 BOOL WINAPI AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu )
474 return AdjustWindowRectEx( rect, style, menu, 0 );
478 /***********************************************************************
479 * AdjustWindowRectEx16 (USER.454)
481 BOOL16 WINAPI AdjustWindowRectEx16( LPRECT16 rect, DWORD style,
482 BOOL16 menu, DWORD exStyle )
484 /* Correct the window style */
486 if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
487 style |= WS_CAPTION;
488 style &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD);
489 exStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE |
490 WS_EX_STATICEDGE | WS_EX_TOOLWINDOW);
491 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
493 TRACE("(%d,%d)-(%d,%d) %08lx %d %08lx\n",
494 rect->left, rect->top, rect->right, rect->bottom,
495 style, menu, exStyle );
497 if (TWEAK_WineLook == WIN31_LOOK)
498 NC_AdjustRect( rect, style, menu, exStyle );
499 else {
500 NC_AdjustRectOuter95( rect, style, menu, exStyle );
501 NC_AdjustRectInner95( rect, style, exStyle );
504 return TRUE;
508 /***********************************************************************
509 * AdjustWindowRectEx (USER32.3)
511 BOOL WINAPI AdjustWindowRectEx( LPRECT rect, DWORD style,
512 BOOL menu, DWORD exStyle )
514 RECT16 rect16;
515 BOOL ret;
517 CONV_RECT32TO16( rect, &rect16 );
518 ret = AdjustWindowRectEx16( &rect16, style, (BOOL16)menu, exStyle );
519 CONV_RECT16TO32( &rect16, rect );
520 return ret;
524 /***********************************************************************
525 * NC_HandleNCCalcSize
527 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
529 LONG NC_HandleNCCalcSize( WND *pWnd, RECT *winRect )
531 RECT16 tmpRect = { 0, 0, 0, 0 };
532 LONG result = 0;
533 UINT style = (UINT) GetClassLongA(pWnd->hwndSelf, GCL_STYLE);
535 if (style & CS_VREDRAW) result |= WVR_VREDRAW;
536 if (style & CS_HREDRAW) result |= WVR_HREDRAW;
538 if( !( pWnd->dwStyle & WS_MINIMIZE ) ) {
539 if (TWEAK_WineLook == WIN31_LOOK)
540 NC_AdjustRect( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
541 else
542 NC_AdjustRectOuter95( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
544 winRect->left -= tmpRect.left;
545 winRect->top -= tmpRect.top;
546 winRect->right -= tmpRect.right;
547 winRect->bottom -= tmpRect.bottom;
549 if (HAS_MENU(pWnd)) {
550 TRACE("Calling GetMenuBarHeight with HWND 0x%x, width %d, "
551 "at (%d, %d).\n", pWnd->hwndSelf,
552 winRect->right - winRect->left,
553 -tmpRect.left, -tmpRect.top );
555 winRect->top +=
556 MENU_GetMenuBarHeight( pWnd->hwndSelf,
557 winRect->right - winRect->left,
558 -tmpRect.left, -tmpRect.top ) + 1;
561 if (TWEAK_WineLook > WIN31_LOOK) {
562 SetRect16 (&tmpRect, 0, 0, 0, 0);
563 NC_AdjustRectInner95 (&tmpRect, pWnd->dwStyle, pWnd->dwExStyle);
564 winRect->left -= tmpRect.left;
565 winRect->top -= tmpRect.top;
566 winRect->right -= tmpRect.right;
567 winRect->bottom -= tmpRect.bottom;
570 return result;
574 /***********************************************************************
575 * NC_GetInsideRect
577 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
578 * but without the borders (if any).
579 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
581 static void NC_GetInsideRect( HWND hwnd, RECT *rect )
583 WND * wndPtr = WIN_FindWndPtr( hwnd );
585 rect->top = rect->left = 0;
586 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
587 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
589 if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) goto END;
591 /* Remove frame from rectangle */
592 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
593 InflateRect( rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
594 else
595 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
597 InflateRect( rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
598 /* FIXME: this isn't in NC_AdjustRect? why not? */
599 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
600 InflateRect( rect, -1, 0 );
602 else
603 if (HAS_THINFRAME( wndPtr->dwStyle ))
604 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
605 END:
606 WIN_ReleaseWndPtr(wndPtr);
607 return;
611 /***********************************************************************
612 * NC_GetInsideRect95
614 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
615 * but without the borders (if any).
616 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
619 static void
620 NC_GetInsideRect95 (HWND hwnd, RECT *rect)
622 WND * wndPtr = WIN_FindWndPtr( hwnd );
624 rect->top = rect->left = 0;
625 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
626 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
628 if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) goto END;
630 /* Remove frame from rectangle */
631 if (HAS_THICKFRAME (wndPtr->dwStyle, wndPtr->dwExStyle))
633 InflateRect( rect, -GetSystemMetrics(SM_CXSIZEFRAME), -GetSystemMetrics(SM_CYSIZEFRAME) );
635 else if (HAS_DLGFRAME (wndPtr->dwStyle, wndPtr->dwExStyle ))
637 InflateRect( rect, -GetSystemMetrics(SM_CXFIXEDFRAME), -GetSystemMetrics(SM_CYFIXEDFRAME));
639 else if (HAS_THINFRAME (wndPtr->dwStyle))
641 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
644 /* We have additional border information if the window
645 * is a child (but not an MDI child) */
646 if ( (wndPtr->dwStyle & WS_CHILD) &&
647 ( (wndPtr->dwExStyle & WS_EX_MDICHILD) == 0 ) )
649 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
650 InflateRect (rect, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE));
652 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
653 InflateRect (rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
655 END:
656 WIN_ReleaseWndPtr(wndPtr);
657 return;
661 /***********************************************************************
662 * NC_DoNCHitTest
664 * Handle a WM_NCHITTEST message. Called from NC_HandleNcHitTest().
667 static LONG NC_DoNCHitTest (WND *wndPtr, POINT16 pt )
669 RECT16 rect;
671 TRACE("hwnd=%04x pt=%d,%d\n", wndPtr->hwndSelf, pt.x, pt.y );
673 GetWindowRect16 (wndPtr->hwndSelf, &rect );
674 if (!PtInRect16( &rect, pt )) return HTNOWHERE;
676 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
678 if (!(wndPtr->flags & WIN_MANAGED))
680 /* Check borders */
681 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
683 InflateRect16( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
684 if (!PtInRect16( &rect, pt ))
686 /* Check top sizing border */
687 if (pt.y < rect.top)
689 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
690 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
691 return HTTOP;
693 /* Check bottom sizing border */
694 if (pt.y >= rect.bottom)
696 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
697 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
698 return HTBOTTOM;
700 /* Check left sizing border */
701 if (pt.x < rect.left)
703 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
704 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
705 return HTLEFT;
707 /* Check right sizing border */
708 if (pt.x >= rect.right)
710 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
711 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
712 return HTRIGHT;
716 else /* No thick frame */
718 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
719 InflateRect16(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
720 else if (HAS_THINFRAME( wndPtr->dwStyle ))
721 InflateRect16(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
722 if (!PtInRect16( &rect, pt )) return HTBORDER;
725 /* Check caption */
727 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
729 rect.top += GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
730 if (!PtInRect16( &rect, pt ))
732 /* Check system menu */
733 if (wndPtr->dwStyle & WS_SYSMENU)
734 rect.left += GetSystemMetrics(SM_CXSIZE);
735 if (pt.x <= rect.left) return HTSYSMENU;
737 /* Check maximize box */
738 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
739 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
741 if (pt.x >= rect.right) return HTMAXBUTTON;
742 /* Check minimize box */
743 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
744 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
745 if (pt.x >= rect.right) return HTMINBUTTON;
746 return HTCAPTION;
751 /* Check client area */
753 ScreenToClient16( wndPtr->hwndSelf, &pt );
754 GetClientRect16( wndPtr->hwndSelf, &rect );
755 if (PtInRect16( &rect, pt )) return HTCLIENT;
757 /* Check vertical scroll bar */
759 if (wndPtr->dwStyle & WS_VSCROLL)
761 rect.right += GetSystemMetrics(SM_CXVSCROLL);
762 if (PtInRect16( &rect, pt )) return HTVSCROLL;
765 /* Check horizontal scroll bar */
767 if (wndPtr->dwStyle & WS_HSCROLL)
769 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
770 if (PtInRect16( &rect, pt ))
772 /* Check size box */
773 if ((wndPtr->dwStyle & WS_VSCROLL) &&
774 (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
775 return HTSIZE;
776 return HTHSCROLL;
780 /* Check menu bar */
782 if (HAS_MENU(wndPtr))
784 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
785 return HTMENU;
788 /* Should never get here */
789 return HTERROR;
793 /***********************************************************************
794 * NC_DoNCHitTest95
796 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
798 * FIXME: Just a modified copy of the Win 3.1 version.
801 static LONG
802 NC_DoNCHitTest95 (WND *wndPtr, POINT16 pt )
804 RECT16 rect;
806 TRACE("hwnd=%04x pt=%d,%d\n", wndPtr->hwndSelf, pt.x, pt.y );
808 GetWindowRect16 (wndPtr->hwndSelf, &rect );
809 if (!PtInRect16( &rect, pt )) return HTNOWHERE;
811 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
813 if (!(wndPtr->flags & WIN_MANAGED))
815 /* Check borders */
816 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
818 InflateRect16( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
819 if (!PtInRect16( &rect, pt ))
821 /* Check top sizing border */
822 if (pt.y < rect.top)
824 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
825 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
826 return HTTOP;
828 /* Check bottom sizing border */
829 if (pt.y >= rect.bottom)
831 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
832 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
833 return HTBOTTOM;
835 /* Check left sizing border */
836 if (pt.x < rect.left)
838 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
839 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
840 return HTLEFT;
842 /* Check right sizing border */
843 if (pt.x >= rect.right)
845 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
846 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
847 return HTRIGHT;
851 else /* No thick frame */
853 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
854 InflateRect16(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
855 else if (HAS_THINFRAME( wndPtr->dwStyle ))
856 InflateRect16(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
857 if (!PtInRect16( &rect, pt )) return HTBORDER;
860 /* Check caption */
862 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
864 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
865 rect.top += GetSystemMetrics(SM_CYSMCAPTION) - 1;
866 else
867 rect.top += GetSystemMetrics(SM_CYCAPTION) - 1;
868 if (!PtInRect16( &rect, pt ))
870 /* Check system menu */
871 if(wndPtr->dwStyle & WS_SYSMENU)
873 /* Check if there is an user icon */
874 HICON hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICONSM);
875 if(!hIcon) hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICON);
877 /* If there is an icon associated with the window OR */
878 /* If there is no hIcon specified and this is not a modal dialog, */
879 /* there is a system menu icon. */
880 if((hIcon != 0) || (!(wndPtr->dwStyle & DS_MODALFRAME)))
881 rect.left += GetSystemMetrics(SM_CYCAPTION) - 1;
883 if (pt.x < rect.left) return HTSYSMENU;
885 /* Check close button */
886 if (wndPtr->dwStyle & WS_SYSMENU)
887 rect.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
888 if (pt.x > rect.right) return HTCLOSE;
890 /* Check maximize box */
891 /* In win95 there is automatically a Maximize button when there is a minimize one*/
892 if ((wndPtr->dwStyle & WS_MAXIMIZEBOX)|| (wndPtr->dwStyle & WS_MINIMIZEBOX))
893 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
894 if (pt.x > rect.right) return HTMAXBUTTON;
896 /* Check minimize box */
897 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
898 if ((wndPtr->dwStyle & WS_MINIMIZEBOX)||(wndPtr->dwStyle & WS_MAXIMIZEBOX))
899 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
901 if (pt.x > rect.right) return HTMINBUTTON;
902 return HTCAPTION;
907 /* Check client area */
909 ScreenToClient16( wndPtr->hwndSelf, &pt );
910 GetClientRect16( wndPtr->hwndSelf, &rect );
911 if (PtInRect16( &rect, pt )) return HTCLIENT;
913 /* Check vertical scroll bar */
915 if (wndPtr->dwStyle & WS_VSCROLL)
917 rect.right += GetSystemMetrics(SM_CXVSCROLL);
918 if (PtInRect16( &rect, pt )) return HTVSCROLL;
921 /* Check horizontal scroll bar */
923 if (wndPtr->dwStyle & WS_HSCROLL)
925 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
926 if (PtInRect16( &rect, pt ))
928 /* Check size box */
929 if ((wndPtr->dwStyle & WS_VSCROLL) &&
930 (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
931 return HTSIZE;
932 return HTHSCROLL;
936 /* Check menu bar */
938 if (HAS_MENU(wndPtr))
940 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
941 return HTMENU;
944 /* Should never get here */
945 return HTERROR;
949 /***********************************************************************
950 * NC_HandleNCHitTest
952 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
954 LONG
955 NC_HandleNCHitTest (HWND hwnd , POINT16 pt)
957 LONG retvalue;
958 WND *wndPtr = WIN_FindWndPtr (hwnd);
960 if (!wndPtr)
961 return HTERROR;
963 if (TWEAK_WineLook == WIN31_LOOK)
964 retvalue = NC_DoNCHitTest (wndPtr, pt);
965 else
966 retvalue = NC_DoNCHitTest95 (wndPtr, pt);
967 WIN_ReleaseWndPtr(wndPtr);
968 return retvalue;
972 /***********************************************************************
973 * NC_DrawSysButton
975 void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down )
977 RECT rect;
978 HDC hdcMem;
979 HBITMAP hbitmap;
980 WND *wndPtr = WIN_FindWndPtr( hwnd );
982 if( !(wndPtr->flags & WIN_MANAGED) )
984 NC_GetInsideRect( hwnd, &rect );
985 hdcMem = CreateCompatibleDC( hdc );
986 hbitmap = SelectObject( hdcMem, hbitmapClose );
987 BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE), GetSystemMetrics(SM_CYSIZE),
988 hdcMem, (wndPtr->dwStyle & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE) : 0, 0,
989 down ? NOTSRCCOPY : SRCCOPY );
990 SelectObject( hdcMem, hbitmap );
991 DeleteDC( hdcMem );
993 WIN_ReleaseWndPtr(wndPtr);
997 /***********************************************************************
998 * NC_DrawMaxButton
1000 static void NC_DrawMaxButton( HWND hwnd, HDC16 hdc, BOOL down )
1002 RECT rect;
1003 WND *wndPtr = WIN_FindWndPtr( hwnd );
1004 HDC hdcMem;
1006 if( !(wndPtr->flags & WIN_MANAGED) )
1008 NC_GetInsideRect( hwnd, &rect );
1009 hdcMem = CreateCompatibleDC( hdc );
1010 SelectObject( hdcMem, (IsZoomed(hwnd)
1011 ? (down ? hbitmapRestoreD : hbitmapRestore)
1012 : (down ? hbitmapMaximizeD : hbitmapMaximize)) );
1013 BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
1014 GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
1015 SRCCOPY );
1016 DeleteDC( hdcMem );
1018 WIN_ReleaseWndPtr(wndPtr);
1023 /***********************************************************************
1024 * NC_DrawMinButton
1026 static void NC_DrawMinButton( HWND hwnd, HDC16 hdc, BOOL down )
1028 RECT rect;
1029 WND *wndPtr = WIN_FindWndPtr( hwnd );
1030 HDC hdcMem;
1032 if( !(wndPtr->flags & WIN_MANAGED) )
1034 NC_GetInsideRect( hwnd, &rect );
1035 hdcMem = CreateCompatibleDC( hdc );
1036 SelectObject( hdcMem, (down ? hbitmapMinimizeD : hbitmapMinimize) );
1037 if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= GetSystemMetrics(SM_CXSIZE)+1;
1038 BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
1039 GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
1040 SRCCOPY );
1041 DeleteDC( hdcMem );
1043 WIN_ReleaseWndPtr(wndPtr);
1047 /******************************************************************************
1049 * void NC_DrawSysButton95(
1050 * HWND hwnd,
1051 * HDC hdc,
1052 * BOOL down )
1054 * Draws the Win95 system icon.
1056 * Revision history
1057 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1058 * Original implementation from NC_DrawSysButton source.
1059 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1060 * Fixed most bugs.
1062 *****************************************************************************/
1064 BOOL
1065 NC_DrawSysButton95 (HWND hwnd, HDC hdc, BOOL down)
1067 WND *wndPtr = WIN_FindWndPtr( hwnd );
1069 if( !(wndPtr->flags & WIN_MANAGED) )
1071 HICON hIcon;
1072 RECT rect;
1074 NC_GetInsideRect95( hwnd, &rect );
1076 hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICONSM);
1077 if(!hIcon) hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICON);
1079 /* If there is no hIcon specified or this is not a modal dialog, */
1080 /* get the default one. */
1081 if(hIcon == 0)
1082 if (!(wndPtr->dwStyle & DS_MODALFRAME))
1083 hIcon = LoadImageA(0, MAKEINTRESOURCEA(OIC_WINEICON), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
1085 if (hIcon)
1086 DrawIconEx (hdc, rect.left + 2, rect.top + 2, hIcon,
1087 GetSystemMetrics(SM_CXSMICON),
1088 GetSystemMetrics(SM_CYSMICON),
1089 0, 0, DI_NORMAL);
1091 WIN_ReleaseWndPtr(wndPtr);
1092 return (hIcon != 0);
1094 WIN_ReleaseWndPtr(wndPtr);
1095 return FALSE;
1099 /******************************************************************************
1101 * void NC_DrawCloseButton95(
1102 * HWND hwnd,
1103 * HDC hdc,
1104 * BOOL down,
1105 * BOOL bGrayed )
1107 * Draws the Win95 close button.
1109 * If bGrayed is true, then draw a disabled Close button
1111 * Revision history
1112 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1113 * Original implementation from NC_DrawSysButton95 source.
1115 *****************************************************************************/
1117 static void NC_DrawCloseButton95 (HWND hwnd, HDC hdc, BOOL down, BOOL bGrayed)
1119 RECT rect;
1120 HDC hdcMem;
1121 WND *wndPtr = WIN_FindWndPtr( hwnd );
1123 if( !(wndPtr->flags & WIN_MANAGED) )
1125 BITMAP bmp;
1126 HBITMAP hBmp, hOldBmp;
1128 NC_GetInsideRect95( hwnd, &rect );
1130 hdcMem = CreateCompatibleDC( hdc );
1131 hBmp = down ? hbitmapCloseD : hbitmapClose;
1132 hOldBmp = SelectObject (hdcMem, hBmp);
1133 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1135 BitBlt (hdc, rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2,
1136 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1137 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);
1139 if(bGrayed)
1140 NC_DrawGrayButton(hdc,rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2 + 2,
1141 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1143 SelectObject (hdcMem, hOldBmp);
1144 DeleteDC (hdcMem);
1146 WIN_ReleaseWndPtr(wndPtr);
1149 /******************************************************************************
1151 * NC_DrawMaxButton95(
1152 * HWND hwnd,
1153 * HDC16 hdc,
1154 * BOOL down
1155 * BOOL bGrayed )
1157 * Draws the maximize button for Win95 style windows.
1159 * If bGrayed is true, then draw a disabled Maximize button
1161 * Bugs
1162 * Many. Spacing might still be incorrect. Need to fit a close
1163 * button between the max button and the edge.
1164 * Should scale the image with the title bar. And more...
1166 * Revision history
1167 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1168 * Original implementation.
1170 *****************************************************************************/
1172 static void NC_DrawMaxButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
1174 RECT rect;
1175 HDC hdcMem;
1176 WND *wndPtr = WIN_FindWndPtr( hwnd );
1178 if( !(wndPtr->flags & WIN_MANAGED))
1180 BITMAP bmp;
1181 HBITMAP hBmp,hOldBmp;
1183 NC_GetInsideRect95( hwnd, &rect );
1184 hdcMem = CreateCompatibleDC( hdc );
1185 hBmp = IsZoomed(hwnd) ?
1186 (down ? hbitmapRestoreD : hbitmapRestore ) :
1187 (down ? hbitmapMaximizeD: hbitmapMaximize);
1188 hOldBmp=SelectObject( hdcMem, hBmp );
1189 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1191 if (wndPtr->dwStyle & WS_SYSMENU)
1192 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1194 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1195 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1196 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1198 if(bGrayed)
1199 NC_DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
1200 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1203 SelectObject (hdcMem, hOldBmp);
1204 DeleteDC( hdcMem );
1206 WIN_ReleaseWndPtr(wndPtr);
1209 /******************************************************************************
1211 * NC_DrawMinButton95(
1212 * HWND hwnd,
1213 * HDC16 hdc,
1214 * BOOL down,
1215 * BOOL bGrayed )
1217 * Draws the minimize button for Win95 style windows.
1219 * If bGrayed is true, then draw a disabled Minimize button
1221 * Bugs
1222 * Many. Spacing is still incorrect. Should scale the image with the
1223 * title bar. And more...
1225 * Revision history
1226 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1227 * Original implementation.
1229 *****************************************************************************/
1231 static void NC_DrawMinButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
1233 RECT rect;
1234 HDC hdcMem;
1235 WND *wndPtr = WIN_FindWndPtr( hwnd );
1237 if( !(wndPtr->flags & WIN_MANAGED))
1240 BITMAP bmp;
1241 HBITMAP hBmp,hOldBmp;
1243 NC_GetInsideRect95( hwnd, &rect );
1245 hdcMem = CreateCompatibleDC( hdc );
1246 hBmp = down ? hbitmapMinimizeD : hbitmapMinimize;
1247 hOldBmp= SelectObject( hdcMem, hBmp );
1248 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1250 if (wndPtr->dwStyle & WS_SYSMENU)
1251 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1253 /* In win 95 there is always a Maximize box when there is a Minimize one */
1254 if ((wndPtr->dwStyle & WS_MAXIMIZEBOX) || (wndPtr->dwStyle & WS_MINIMIZEBOX))
1255 rect.right += -1 - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2;
1257 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1258 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1259 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1261 if(bGrayed)
1262 NC_DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
1263 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1266 SelectObject (hdcMem, hOldBmp);
1267 DeleteDC( hdcMem );
1269 WIN_ReleaseWndPtr(wndPtr);
1272 /***********************************************************************
1273 * NC_DrawFrame
1275 * Draw a window frame inside the given rectangle, and update the rectangle.
1276 * The correct pen for the frame must be selected in the DC.
1278 static void NC_DrawFrame( HDC hdc, RECT *rect, BOOL dlgFrame,
1279 BOOL active )
1281 INT width, height;
1283 if (TWEAK_WineLook != WIN31_LOOK)
1284 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
1286 if (dlgFrame)
1288 width = GetSystemMetrics(SM_CXDLGFRAME) - 1;
1289 height = GetSystemMetrics(SM_CYDLGFRAME) - 1;
1290 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1291 COLOR_INACTIVECAPTION) );
1293 else
1295 width = GetSystemMetrics(SM_CXFRAME) - 2;
1296 height = GetSystemMetrics(SM_CYFRAME) - 2;
1297 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1298 COLOR_INACTIVEBORDER) );
1301 /* Draw frame */
1302 PatBlt( hdc, rect->left, rect->top,
1303 rect->right - rect->left, height, PATCOPY );
1304 PatBlt( hdc, rect->left, rect->top,
1305 width, rect->bottom - rect->top, PATCOPY );
1306 PatBlt( hdc, rect->left, rect->bottom - 1,
1307 rect->right - rect->left, -height, PATCOPY );
1308 PatBlt( hdc, rect->right - 1, rect->top,
1309 -width, rect->bottom - rect->top, PATCOPY );
1311 if (dlgFrame)
1313 InflateRect( rect, -width, -height );
1315 else
1317 INT decYOff = GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXSIZE) - 1;
1318 INT decXOff = GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYSIZE) - 1;
1320 /* Draw inner rectangle */
1322 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1323 Rectangle( hdc, rect->left + width, rect->top + height,
1324 rect->right - width , rect->bottom - height );
1326 /* Draw the decorations */
1328 MoveToEx( hdc, rect->left, rect->top + decYOff, NULL );
1329 LineTo( hdc, rect->left + width, rect->top + decYOff );
1330 MoveToEx( hdc, rect->right - 1, rect->top + decYOff, NULL );
1331 LineTo( hdc, rect->right - width - 1, rect->top + decYOff );
1332 MoveToEx( hdc, rect->left, rect->bottom - decYOff, NULL );
1333 LineTo( hdc, rect->left + width, rect->bottom - decYOff );
1334 MoveToEx( hdc, rect->right - 1, rect->bottom - decYOff, NULL );
1335 LineTo( hdc, rect->right - width - 1, rect->bottom - decYOff );
1337 MoveToEx( hdc, rect->left + decXOff, rect->top, NULL );
1338 LineTo( hdc, rect->left + decXOff, rect->top + height);
1339 MoveToEx( hdc, rect->left + decXOff, rect->bottom - 1, NULL );
1340 LineTo( hdc, rect->left + decXOff, rect->bottom - height - 1 );
1341 MoveToEx( hdc, rect->right - decXOff, rect->top, NULL );
1342 LineTo( hdc, rect->right - decXOff, rect->top + height );
1343 MoveToEx( hdc, rect->right - decXOff, rect->bottom - 1, NULL );
1344 LineTo( hdc, rect->right - decXOff, rect->bottom - height - 1 );
1346 InflateRect( rect, -width - 1, -height - 1 );
1351 /******************************************************************************
1353 * void NC_DrawFrame95(
1354 * HDC hdc,
1355 * RECT *rect,
1356 * BOOL dlgFrame,
1357 * BOOL active )
1359 * Draw a window frame inside the given rectangle, and update the rectangle.
1360 * The correct pen for the frame must be selected in the DC.
1362 * Bugs
1363 * Many. First, just what IS a frame in Win95? Note that the 3D look
1364 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1365 * edge. The inner rectangle just inside the frame is handled by the
1366 * Caption code.
1368 * In short, for most people, this function should be a nop (unless
1369 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1370 * them lately, but just to get this code right). Even so, it doesn't
1371 * appear to be so. It's being worked on...
1373 * Revision history
1374 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1375 * Original implementation (based on NC_DrawFrame)
1376 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1377 * Some minor fixes.
1378 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1379 * Fixed a fix or something.
1381 *****************************************************************************/
1383 static void NC_DrawFrame95(
1384 HDC hdc,
1385 RECT *rect,
1386 BOOL dlgFrame,
1387 BOOL active )
1389 INT width, height;
1391 if (dlgFrame)
1393 width = GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
1394 height = GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
1396 else
1398 width = GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXEDGE);
1399 height = GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYEDGE);
1402 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1403 COLOR_INACTIVEBORDER) );
1405 /* Draw frame */
1406 PatBlt( hdc, rect->left, rect->top,
1407 rect->right - rect->left, height, PATCOPY );
1408 PatBlt( hdc, rect->left, rect->top,
1409 width, rect->bottom - rect->top, PATCOPY );
1410 PatBlt( hdc, rect->left, rect->bottom - 1,
1411 rect->right - rect->left, -height, PATCOPY );
1412 PatBlt( hdc, rect->right - 1, rect->top,
1413 -width, rect->bottom - rect->top, PATCOPY );
1415 InflateRect( rect, -width, -height );
1418 /***********************************************************************
1419 * NC_DrawMovingFrame
1421 * Draw the frame used when moving or resizing window.
1423 * FIXME: This causes problems in Win95 mode. (why?)
1425 static void NC_DrawMovingFrame( HDC hdc, RECT *rect, BOOL thickframe )
1427 if (thickframe)
1429 RECT16 r16;
1430 CONV_RECT32TO16( rect, &r16 );
1431 FastWindowFrame16( hdc, &r16, GetSystemMetrics(SM_CXFRAME),
1432 GetSystemMetrics(SM_CYFRAME), PATINVERT );
1434 else DrawFocusRect( hdc, rect );
1438 /***********************************************************************
1439 * NC_DrawCaption
1441 * Draw the window caption.
1442 * The correct pen for the window frame must be selected in the DC.
1444 static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd,
1445 DWORD style, BOOL active )
1447 RECT r = *rect;
1448 WND * wndPtr = WIN_FindWndPtr( hwnd );
1449 char buffer[256];
1451 if (wndPtr->flags & WIN_MANAGED)
1453 WIN_ReleaseWndPtr(wndPtr);
1454 return;
1457 if (!hbitmapClose)
1459 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1461 WIN_ReleaseWndPtr(wndPtr);
1462 return;
1464 hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED) );
1465 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1466 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1467 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1468 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1469 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1470 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1473 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
1475 HBRUSH hbrushOld = SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW) );
1476 PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
1477 PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
1478 PatBlt( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
1479 r.left++;
1480 r.right--;
1481 SelectObject( hdc, hbrushOld );
1483 WIN_ReleaseWndPtr(wndPtr);
1484 MoveTo16( hdc, r.left, r.bottom );
1485 LineTo( hdc, r.right, r.bottom );
1487 if (style & WS_SYSMENU)
1489 NC_DrawSysButton( hwnd, hdc, FALSE );
1490 r.left += GetSystemMetrics(SM_CXSIZE) + 1;
1491 MoveTo16( hdc, r.left - 1, r.top );
1492 LineTo( hdc, r.left - 1, r.bottom );
1494 if (style & WS_MAXIMIZEBOX)
1496 NC_DrawMaxButton( hwnd, hdc, FALSE );
1497 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1499 if (style & WS_MINIMIZEBOX)
1501 NC_DrawMinButton( hwnd, hdc, FALSE );
1502 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1505 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1506 COLOR_INACTIVECAPTION) );
1508 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) ))
1510 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1511 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1512 SetBkMode( hdc, TRANSPARENT );
1513 DrawTextA( hdc, buffer, -1, &r,
1514 DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );
1519 /******************************************************************************
1521 * NC_DrawCaption95(
1522 * HDC hdc,
1523 * RECT *rect,
1524 * HWND hwnd,
1525 * DWORD style,
1526 * BOOL active )
1528 * Draw the window caption for Win95 style windows.
1529 * The correct pen for the window frame must be selected in the DC.
1531 * Bugs
1532 * Hey, a function that finally works! Well, almost.
1533 * It's being worked on.
1535 * Revision history
1536 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1537 * Original implementation.
1538 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1539 * Some minor fixes.
1541 *****************************************************************************/
1543 static void NC_DrawCaption95(
1544 HDC hdc,
1545 RECT *rect,
1546 HWND hwnd,
1547 DWORD style,
1548 DWORD exStyle,
1549 BOOL active )
1551 RECT r = *rect;
1552 WND *wndPtr = WIN_FindWndPtr( hwnd );
1553 char buffer[256];
1554 HPEN hPrevPen;
1555 HMENU hSysMenu;
1557 if (wndPtr->flags & WIN_MANAGED)
1559 WIN_ReleaseWndPtr(wndPtr);
1560 return;
1562 WIN_ReleaseWndPtr(wndPtr);
1564 hPrevPen = SelectObject( hdc, GetSysColorPen(COLOR_3DFACE) );
1565 MoveToEx( hdc, r.left, r.bottom - 1, NULL );
1566 LineTo( hdc, r.right, r.bottom - 1 );
1567 SelectObject( hdc, hPrevPen );
1568 r.bottom--;
1570 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1571 COLOR_INACTIVECAPTION) );
1573 if (!hbitmapClose) {
1574 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1575 return;
1576 hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED));
1577 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1578 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1579 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1580 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1581 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1582 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1585 if ((style & WS_SYSMENU) && !(exStyle & WS_EX_TOOLWINDOW)) {
1586 if (NC_DrawSysButton95 (hwnd, hdc, FALSE))
1587 r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
1590 if (style & WS_SYSMENU)
1592 UINT state;
1594 /* Go get the sysmenu */
1595 hSysMenu = GetSystemMenu(hwnd, FALSE);
1596 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
1598 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1599 NC_DrawCloseButton95 (hwnd, hdc, FALSE,
1600 ((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
1601 r.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
1603 if ((style & WS_MAXIMIZEBOX) || (style & WS_MINIMIZEBOX))
1605 /* In win95 the two buttons are always there */
1606 /* But if the menu item is not in the menu they're disabled*/
1608 NC_DrawMaxButton95( hwnd, hdc, FALSE, (!(style & WS_MAXIMIZEBOX)));
1609 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1611 NC_DrawMinButton95( hwnd, hdc, FALSE, (!(style & WS_MINIMIZEBOX)));
1612 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1616 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) )) {
1617 NONCLIENTMETRICSA nclm;
1618 HFONT hFont, hOldFont;
1619 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1620 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1621 if (exStyle & WS_EX_TOOLWINDOW)
1622 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
1623 else
1624 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
1625 hOldFont = SelectObject (hdc, hFont);
1626 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1627 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1628 SetBkMode( hdc, TRANSPARENT );
1629 r.left += 2;
1630 DrawTextA( hdc, buffer, -1, &r,
1631 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
1632 DeleteObject (SelectObject (hdc, hOldFont));
1638 /***********************************************************************
1639 * NC_DoNCPaint
1641 * Paint the non-client area. clip is currently unused.
1643 static void NC_DoNCPaint( WND* wndPtr, HRGN clip, BOOL suppress_menupaint )
1645 HDC hdc;
1646 RECT rect;
1647 BOOL active;
1648 HWND hwnd = wndPtr->hwndSelf;
1650 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1651 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1653 active = wndPtr->flags & WIN_NCACTIVATED;
1655 TRACE("%04x %d\n", hwnd, active );
1657 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1658 ((clip > 1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN): 0) ))) return;
1660 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1661 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1662 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1663 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1664 == NULLREGION)
1666 ReleaseDC( hwnd, hdc );
1667 return;
1670 rect.top = rect.left = 0;
1671 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1672 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1674 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1676 if (!(wndPtr->flags & WIN_MANAGED))
1678 if (HAS_ANYFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1680 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1681 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1682 InflateRect( &rect, -1, -1 );
1685 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1686 NC_DrawFrame(hdc, &rect, FALSE, active );
1687 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1688 NC_DrawFrame( hdc, &rect, TRUE, active );
1690 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1692 RECT r = rect;
1693 r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
1694 rect.top += GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYBORDER);
1695 NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active );
1699 if (HAS_MENU(wndPtr))
1701 RECT r = rect;
1702 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU); /* default height */
1703 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint );
1706 /* Draw the scroll-bars */
1708 if (wndPtr->dwStyle & WS_VSCROLL)
1709 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1710 if (wndPtr->dwStyle & WS_HSCROLL)
1711 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1713 /* Draw the "size-box" */
1715 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1717 RECT r = rect;
1718 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1719 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1720 if(wndPtr->dwStyle & WS_BORDER) {
1721 r.left++;
1722 r.top++;
1724 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1727 ReleaseDC( hwnd, hdc );
1731 /******************************************************************************
1733 * void NC_DoNCPaint95(
1734 * WND *wndPtr,
1735 * HRGN clip,
1736 * BOOL suppress_menupaint )
1738 * Paint the non-client area for Win95 windows. The clip region is
1739 * currently ignored.
1741 * Bugs
1742 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1743 * misc/tweak.c controls/menu.c # :-)
1745 * Revision history
1746 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1747 * Original implementation
1748 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1749 * Fixed some bugs.
1750 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1751 * Streamlined window style checks.
1753 *****************************************************************************/
1755 static void NC_DoNCPaint95(
1756 WND *wndPtr,
1757 HRGN clip,
1758 BOOL suppress_menupaint )
1760 HDC hdc;
1761 RECT rfuzz, rect, rectClip;
1762 BOOL active;
1763 HWND hwnd = wndPtr->hwndSelf;
1765 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1766 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1768 active = wndPtr->flags & WIN_NCACTIVATED;
1770 TRACE("%04x %d\n", hwnd, active );
1772 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1773 the call to GetDCEx implying that it is allowed not to use it either.
1774 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1775 will cause clipRgn to be deleted after ReleaseDC().
1776 Now, how is the "system" supposed to tell what happened?
1779 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1780 ((clip > 1) ?(DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0) ))) return;
1783 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1784 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1785 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1786 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1787 == NULLREGION)
1789 ReleaseDC( hwnd, hdc );
1790 return;
1793 rect.top = rect.left = 0;
1794 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1795 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1797 if( clip > 1 )
1798 GetRgnBox( clip, &rectClip );
1799 else
1801 clip = 0;
1802 rectClip = rect;
1805 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1807 if(!(wndPtr->flags & WIN_MANAGED)) {
1808 if (HAS_BIGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle)) {
1809 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1811 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1812 NC_DrawFrame95(hdc, &rect, FALSE, active );
1813 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1814 NC_DrawFrame95( hdc, &rect, TRUE, active );
1815 else if (HAS_THINFRAME( wndPtr->dwStyle )) {
1816 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1817 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1820 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1822 RECT r = rect;
1823 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW) {
1824 r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
1825 rect.top += GetSystemMetrics(SM_CYSMCAPTION);
1827 else {
1828 r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
1829 rect.top += GetSystemMetrics(SM_CYCAPTION);
1831 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
1832 NC_DrawCaption95 (hdc, &r, hwnd, wndPtr->dwStyle,
1833 wndPtr->dwExStyle, active);
1837 if (HAS_MENU(wndPtr))
1839 RECT r = rect;
1840 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
1842 TRACE("Calling DrawMenuBar with rect (%d, %d)-(%d, %d)\n",
1843 r.left, r.top, r.right, r.bottom);
1845 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ) + 1;
1848 TRACE("After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1849 rect.left, rect.top, rect.right, rect.bottom );
1851 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
1852 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1854 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
1855 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1857 /* Draw the scroll-bars */
1859 if (wndPtr->dwStyle & WS_VSCROLL)
1860 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1861 if (wndPtr->dwStyle & WS_HSCROLL)
1862 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1864 /* Draw the "size-box" */
1865 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1867 RECT r = rect;
1868 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1869 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1870 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1873 ReleaseDC( hwnd, hdc );
1879 /***********************************************************************
1880 * NC_HandleNCPaint
1882 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1884 LONG NC_HandleNCPaint( HWND hwnd , HRGN clip)
1886 WND* wndPtr = WIN_FindWndPtr( hwnd );
1888 if( wndPtr && wndPtr->dwStyle & WS_VISIBLE )
1890 if( wndPtr->dwStyle & WS_MINIMIZE )
1891 WINPOS_RedrawIconTitle( hwnd );
1892 else if (TWEAK_WineLook == WIN31_LOOK)
1893 NC_DoNCPaint( wndPtr, clip, FALSE );
1894 else
1895 NC_DoNCPaint95( wndPtr, clip, FALSE );
1897 WIN_ReleaseWndPtr(wndPtr);
1898 return 0;
1902 /***********************************************************************
1903 * NC_HandleNCActivate
1905 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1907 LONG NC_HandleNCActivate( WND *wndPtr, WPARAM16 wParam )
1909 WORD wStateChange;
1911 if( wParam ) wStateChange = !(wndPtr->flags & WIN_NCACTIVATED);
1912 else wStateChange = wndPtr->flags & WIN_NCACTIVATED;
1914 if( wStateChange )
1916 if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
1917 else wndPtr->flags &= ~WIN_NCACTIVATED;
1919 if( wndPtr->dwStyle & WS_MINIMIZE )
1920 WINPOS_RedrawIconTitle( wndPtr->hwndSelf );
1921 else if (TWEAK_WineLook == WIN31_LOOK)
1922 NC_DoNCPaint( wndPtr, (HRGN)1, FALSE );
1923 else
1924 NC_DoNCPaint95( wndPtr, (HRGN)1, FALSE );
1926 return TRUE;
1930 /***********************************************************************
1931 * NC_HandleSetCursor
1933 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1935 LONG NC_HandleSetCursor( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
1937 if (hwnd != (HWND)wParam) return 0; /* Don't set the cursor for child windows */
1939 switch(LOWORD(lParam))
1941 case HTERROR:
1943 WORD msg = HIWORD( lParam );
1944 if ((msg == WM_LBUTTONDOWN) || (msg == WM_MBUTTONDOWN) ||
1945 (msg == WM_RBUTTONDOWN))
1946 MessageBeep(0);
1948 break;
1950 case HTCLIENT:
1952 HICON16 hCursor = (HICON16) GetClassWord(hwnd, GCW_HCURSOR);
1953 if(hCursor) {
1954 SetCursor16(hCursor);
1955 return TRUE;
1957 return FALSE;
1960 case HTLEFT:
1961 case HTRIGHT:
1962 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZEWE16 ) );
1964 case HTTOP:
1965 case HTBOTTOM:
1966 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENS16 ) );
1968 case HTTOPLEFT:
1969 case HTBOTTOMRIGHT:
1970 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENWSE16 ) );
1972 case HTTOPRIGHT:
1973 case HTBOTTOMLEFT:
1974 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENESW16 ) );
1977 /* Default cursor: arrow */
1978 return (LONG)SetCursor16( LoadCursor16( 0, IDC_ARROW16 ) );
1981 /***********************************************************************
1982 * NC_GetSysPopupPos
1984 BOOL NC_GetSysPopupPos( WND* wndPtr, RECT* rect )
1986 if( wndPtr->hSysMenu )
1988 if( wndPtr->dwStyle & WS_MINIMIZE )
1989 GetWindowRect( wndPtr->hwndSelf, rect );
1990 else
1992 if (TWEAK_WineLook == WIN31_LOOK)
1993 NC_GetInsideRect( wndPtr->hwndSelf, rect );
1994 else
1995 NC_GetInsideRect95( wndPtr->hwndSelf, rect );
1996 OffsetRect( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
1997 if (wndPtr->dwStyle & WS_CHILD)
1998 ClientToScreen( wndPtr->parent->hwndSelf, (POINT *)rect );
1999 if (TWEAK_WineLook == WIN31_LOOK) {
2000 rect->right = rect->left + GetSystemMetrics(SM_CXSIZE);
2001 rect->bottom = rect->top + GetSystemMetrics(SM_CYSIZE);
2003 else {
2004 rect->right = rect->left + GetSystemMetrics(SM_CYCAPTION) - 1;
2005 rect->bottom = rect->top + GetSystemMetrics(SM_CYCAPTION) - 1;
2008 return TRUE;
2010 return FALSE;
2013 /***********************************************************************
2014 * NC_StartSizeMove
2016 * Initialisation of a move or resize, when initiatied from a menu choice.
2017 * Return hit test code for caption or sizing border.
2019 static LONG NC_StartSizeMove( WND* wndPtr, WPARAM16 wParam,
2020 POINT16 *capturePoint )
2022 LONG hittest = 0;
2023 POINT16 pt;
2024 MSG msg;
2025 RECT rectWindow;
2027 GetWindowRect(wndPtr->hwndSelf,&rectWindow);
2029 if ((wParam & 0xfff0) == SC_MOVE)
2031 /* Move pointer at the center of the caption */
2032 RECT rect;
2033 if (TWEAK_WineLook == WIN31_LOOK)
2034 NC_GetInsideRect( wndPtr->hwndSelf, &rect );
2035 else
2036 NC_GetInsideRect95( wndPtr->hwndSelf, &rect );
2037 if (wndPtr->dwStyle & WS_SYSMENU)
2038 rect.left += GetSystemMetrics(SM_CXSIZE) + 1;
2039 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
2040 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
2041 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
2042 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
2043 pt.x = rectWindow.left + (rect.right - rect.left) / 2;
2044 pt.y = rectWindow.top + rect.top + GetSystemMetrics(SM_CYSIZE)/2;
2045 hittest = HTCAPTION;
2046 *capturePoint = pt;
2048 else /* SC_SIZE */
2050 while(!hittest)
2052 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE, NULL );
2053 switch(msg.message)
2055 case WM_MOUSEMOVE:
2056 CONV_POINT32TO16(&msg.pt, &pt);
2057 hittest = NC_HandleNCHitTest( wndPtr->hwndSelf, pt );
2058 if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
2059 hittest = 0;
2060 break;
2062 case WM_LBUTTONUP:
2063 return 0;
2065 case WM_KEYDOWN:
2066 switch(msg.wParam)
2068 case VK_UP:
2069 hittest = HTTOP;
2070 pt.x =(rectWindow.left+rectWindow.right)/2;
2071 pt.y = rectWindow.top + GetSystemMetrics(SM_CYFRAME) / 2;
2072 break;
2073 case VK_DOWN:
2074 hittest = HTBOTTOM;
2075 pt.x =(rectWindow.left+rectWindow.right)/2;
2076 pt.y = rectWindow.bottom - GetSystemMetrics(SM_CYFRAME) / 2;
2077 break;
2078 case VK_LEFT:
2079 hittest = HTLEFT;
2080 pt.x = rectWindow.left + GetSystemMetrics(SM_CXFRAME) / 2;
2081 pt.y =(rectWindow.top+rectWindow.bottom)/2;
2082 break;
2083 case VK_RIGHT:
2084 hittest = HTRIGHT;
2085 pt.x = rectWindow.right - GetSystemMetrics(SM_CXFRAME) / 2;
2086 pt.y =(rectWindow.top+rectWindow.bottom)/2;
2087 break;
2088 case VK_RETURN:
2089 case VK_ESCAPE: return 0;
2093 *capturePoint = pt;
2095 SetCursorPos( pt.x, pt.y );
2096 NC_HandleSetCursor( wndPtr->hwndSelf,
2097 wndPtr->hwndSelf, MAKELONG( hittest, WM_MOUSEMOVE ));
2098 return hittest;
2102 /***********************************************************************
2103 * NC_DoSizeMove
2105 * Perform SC_MOVE and SC_SIZE commands. `
2107 static void NC_DoSizeMove( HWND hwnd, WORD wParam )
2109 MSG msg;
2110 RECT sizingRect, mouseRect;
2111 HDC hdc;
2112 LONG hittest = (LONG)(wParam & 0x0f);
2113 HCURSOR16 hDragCursor = 0, hOldCursor = 0;
2114 POINT minTrack, maxTrack;
2115 POINT16 capturePoint, pt;
2116 WND * wndPtr = WIN_FindWndPtr( hwnd );
2117 BOOL thickframe = HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle );
2118 BOOL iconic = wndPtr->dwStyle & WS_MINIMIZE;
2119 BOOL moved = FALSE;
2120 DWORD dwPoint = GetMessagePos ();
2122 capturePoint = pt = *(POINT16*)&dwPoint;
2124 if (IsZoomed(hwnd) || !IsWindowVisible(hwnd) ||
2125 (wndPtr->flags & WIN_MANAGED)) goto END;
2127 if ((wParam & 0xfff0) == SC_MOVE)
2129 if (!(wndPtr->dwStyle & WS_CAPTION)) goto END;
2130 if (!hittest)
2131 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2132 if (!hittest) goto END;
2134 else /* SC_SIZE */
2136 if (!thickframe) goto END;
2137 if ( hittest && hittest != HTSYSMENU ) hittest += 2;
2138 else
2140 SetCapture(hwnd);
2141 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2142 if (!hittest)
2144 ReleaseCapture();
2145 goto END;
2150 /* Get min/max info */
2152 WINPOS_GetMinMaxInfo( wndPtr, NULL, NULL, &minTrack, &maxTrack );
2153 sizingRect = wndPtr->rectWindow;
2154 if (wndPtr->dwStyle & WS_CHILD)
2155 GetClientRect( wndPtr->parent->hwndSelf, &mouseRect );
2156 else
2157 SetRect(&mouseRect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
2158 if (ON_LEFT_BORDER(hittest))
2160 mouseRect.left = max( mouseRect.left, sizingRect.right-maxTrack.x );
2161 mouseRect.right = min( mouseRect.right, sizingRect.right-minTrack.x );
2163 else if (ON_RIGHT_BORDER(hittest))
2165 mouseRect.left = max( mouseRect.left, sizingRect.left+minTrack.x );
2166 mouseRect.right = min( mouseRect.right, sizingRect.left+maxTrack.x );
2168 if (ON_TOP_BORDER(hittest))
2170 mouseRect.top = max( mouseRect.top, sizingRect.bottom-maxTrack.y );
2171 mouseRect.bottom = min( mouseRect.bottom,sizingRect.bottom-minTrack.y);
2173 else if (ON_BOTTOM_BORDER(hittest))
2175 mouseRect.top = max( mouseRect.top, sizingRect.top+minTrack.y );
2176 mouseRect.bottom = min( mouseRect.bottom, sizingRect.top+maxTrack.y );
2178 if (wndPtr->dwStyle & WS_CHILD)
2180 MapWindowPoints( wndPtr->parent->hwndSelf, 0,
2181 (LPPOINT)&mouseRect, 2 );
2183 SendMessage16( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
2185 if (GetCapture() != hwnd) SetCapture( hwnd );
2187 if (wndPtr->dwStyle & WS_CHILD)
2189 /* Retrieve a default cache DC (without using the window style) */
2190 hdc = GetDCEx( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
2192 else
2193 { /* Grab the server only when moving top-level windows without desktop */
2194 hdc = GetDC( 0 );
2197 wndPtr->pDriver->pPreSizeMove(wndPtr);
2199 if( iconic ) /* create a cursor for dragging */
2201 HICON16 hIcon = GetClassWord(wndPtr->hwndSelf, GCW_HICON);
2202 if(!hIcon) hIcon = (HICON16) SendMessage16( hwnd, WM_QUERYDRAGICON, 0, 0L);
2203 if( hIcon ) hDragCursor = CURSORICON_IconToCursor( hIcon, TRUE );
2204 if( !hDragCursor ) iconic = FALSE;
2207 if( !iconic ) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2209 while(1)
2211 int dx = 0, dy = 0;
2213 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE, NULL );
2215 /* Exit on button-up, Return, or Esc */
2216 if ((msg.message == WM_LBUTTONUP) ||
2217 ((msg.message == WM_KEYDOWN) &&
2218 ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
2220 if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
2221 continue; /* We are not interested in other messages */
2223 dwPoint = GetMessagePos ();
2224 pt = *(POINT16*)&dwPoint;
2226 if (msg.message == WM_KEYDOWN) switch(msg.wParam)
2228 case VK_UP: pt.y -= 8; break;
2229 case VK_DOWN: pt.y += 8; break;
2230 case VK_LEFT: pt.x -= 8; break;
2231 case VK_RIGHT: pt.x += 8; break;
2234 pt.x = max( pt.x, mouseRect.left );
2235 pt.x = min( pt.x, mouseRect.right );
2236 pt.y = max( pt.y, mouseRect.top );
2237 pt.y = min( pt.y, mouseRect.bottom );
2239 dx = pt.x - capturePoint.x;
2240 dy = pt.y - capturePoint.y;
2242 if (dx || dy)
2244 if( !moved )
2246 moved = TRUE;
2247 if( iconic ) /* ok, no system popup tracking */
2249 hOldCursor = SetCursor(hDragCursor);
2250 ShowCursor( TRUE );
2251 WINPOS_ShowIconTitle( wndPtr, FALSE );
2255 if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
2256 else
2258 RECT newRect = sizingRect;
2260 if (hittest == HTCAPTION) OffsetRect( &newRect, dx, dy );
2261 if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
2262 else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
2263 if (ON_TOP_BORDER(hittest)) newRect.top += dy;
2264 else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
2265 if( !iconic )
2267 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2268 NC_DrawMovingFrame( hdc, &newRect, thickframe );
2270 capturePoint = pt;
2271 sizingRect = newRect;
2276 ReleaseCapture();
2277 if( iconic )
2279 if( moved ) /* restore cursors, show icon title later on */
2281 ShowCursor( FALSE );
2282 SetCursor( hOldCursor );
2284 DestroyCursor( hDragCursor );
2286 else
2287 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2289 if (wndPtr->dwStyle & WS_CHILD)
2290 ReleaseDC( wndPtr->parent->hwndSelf, hdc );
2291 else
2293 ReleaseDC( 0, hdc );
2296 wndPtr->pDriver->pPostSizeMove(wndPtr);
2298 if (HOOK_IsHooked( WH_CBT ))
2300 RECT16* pr = SEGPTR_NEW(RECT16);
2301 if( pr )
2303 CONV_RECT32TO16( &sizingRect, pr );
2304 if( HOOK_CallHooks16( WH_CBT, HCBT_MOVESIZE, hwnd,
2305 (LPARAM)SEGPTR_GET(pr)) )
2306 sizingRect = wndPtr->rectWindow;
2307 else
2308 CONV_RECT16TO32( pr, &sizingRect );
2309 SEGPTR_FREE(pr);
2312 SendMessage16( hwnd, WM_EXITSIZEMOVE, 0, 0 );
2313 SendMessage16( hwnd, WM_SETVISIBLE, !IsIconic16(hwnd), 0L);
2315 /* window moved or resized */
2316 if (moved)
2318 /* if the moving/resizing isn't canceled call SetWindowPos
2319 * with the new position or the new size of the window
2321 if (!((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
2323 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
2324 SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top,
2325 sizingRect.right - sizingRect.left,
2326 sizingRect.bottom - sizingRect.top,
2327 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
2331 if( IsWindow(hwnd) )
2332 if( wndPtr->dwStyle & WS_MINIMIZE )
2334 /* Single click brings up the system menu when iconized */
2336 if( !moved )
2338 if( wndPtr->dwStyle & WS_SYSMENU )
2339 SendMessage16( hwnd, WM_SYSCOMMAND,
2340 SC_MOUSEMENU + HTSYSMENU, *((LPARAM*)&pt));
2342 else WINPOS_ShowIconTitle( wndPtr, TRUE );
2345 END:
2346 WIN_ReleaseWndPtr(wndPtr);
2350 /***********************************************************************
2351 * NC_TrackMinMaxBox95
2353 * Track a mouse button press on the minimize or maximize box.
2355 * The big difference between 3.1 and 95 is the disabled button state.
2356 * In win95 the system button can be disabled, so it can ignore the mouse
2357 * event.
2360 static void NC_TrackMinMaxBox95( HWND hwnd, WORD wParam )
2362 MSG msg;
2363 POINT16 pt16;
2364 HDC hdc = GetWindowDC( hwnd );
2365 BOOL pressed = TRUE;
2366 UINT state;
2367 DWORD wndStyle = GetWindowLongA( hwnd, GWL_STYLE);
2368 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
2370 void (*paintButton)(HWND, HDC16, BOOL, BOOL);
2372 if (wParam == HTMINBUTTON)
2374 /* If the style is not present, do nothing */
2375 if (!(wndStyle & WS_MINIMIZEBOX))
2376 return;
2378 /* Check if the sysmenu item for minimize is there */
2379 state = GetMenuState(hSysMenu, SC_MINIMIZE, MF_BYCOMMAND);
2381 paintButton = &NC_DrawMinButton95;
2383 else
2385 /* If the style is not present, do nothing */
2386 if (!(wndStyle & WS_MAXIMIZEBOX))
2387 return;
2389 /* Check if the sysmenu item for maximize is there */
2390 state = GetMenuState(hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
2392 paintButton = &NC_DrawMaxButton95;
2395 SetCapture( hwnd );
2397 (*paintButton)( hwnd, hdc, TRUE, FALSE);
2401 BOOL oldstate = pressed;
2402 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2403 CONV_POINT32TO16( &msg.pt, &pt16 );
2405 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2406 if (pressed != oldstate)
2407 (*paintButton)( hwnd, hdc, pressed, FALSE);
2408 } while (msg.message != WM_LBUTTONUP);
2410 (*paintButton)( hwnd, hdc, FALSE, FALSE);
2412 ReleaseCapture();
2413 ReleaseDC( hwnd, hdc );
2415 /* If the item minimize or maximize of the sysmenu are not there */
2416 /* or if the style is not present, do nothing */
2417 if ((!pressed) || (state == 0xFFFFFFFF))
2418 return;
2420 if (wParam == HTMINBUTTON)
2421 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&pt16 );
2422 else
2423 SendMessage16( hwnd, WM_SYSCOMMAND,
2424 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, *(LONG*)&pt16 );
2427 /***********************************************************************
2428 * NC_TrackMinMaxBox
2430 * Track a mouse button press on the minimize or maximize box.
2432 static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
2434 MSG msg;
2435 POINT16 pt16;
2436 HDC hdc = GetWindowDC( hwnd );
2437 BOOL pressed = TRUE;
2438 void (*paintButton)(HWND, HDC16, BOOL);
2440 SetCapture( hwnd );
2442 if (wParam == HTMINBUTTON)
2443 paintButton = &NC_DrawMinButton;
2444 else
2445 paintButton = &NC_DrawMaxButton;
2447 (*paintButton)( hwnd, hdc, TRUE);
2451 BOOL oldstate = pressed;
2452 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2453 CONV_POINT32TO16( &msg.pt, &pt16 );
2455 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2456 if (pressed != oldstate)
2457 (*paintButton)( hwnd, hdc, pressed);
2458 } while (msg.message != WM_LBUTTONUP);
2460 (*paintButton)( hwnd, hdc, FALSE);
2462 ReleaseCapture();
2463 ReleaseDC( hwnd, hdc );
2465 if (!pressed) return;
2467 if (wParam == HTMINBUTTON)
2468 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&pt16 );
2469 else
2470 SendMessage16( hwnd, WM_SYSCOMMAND,
2471 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, *(LONG*)&pt16 );
2475 /***********************************************************************
2476 * NC_TrackCloseButton95
2478 * Track a mouse button press on the Win95 close button.
2480 static void
2481 NC_TrackCloseButton95 (HWND hwnd, WORD wParam)
2483 MSG msg;
2484 POINT16 pt16;
2485 HDC hdc;
2486 BOOL pressed = TRUE;
2487 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
2488 UINT state;
2490 if(hSysMenu == 0)
2491 return;
2493 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
2495 /* If the item close of the sysmenu is disabled or not there do nothing */
2496 if((state & MF_DISABLED) || (state & MF_GRAYED) || (state == 0xFFFFFFFF))
2497 return;
2499 hdc = GetWindowDC( hwnd );
2501 SetCapture( hwnd );
2503 NC_DrawCloseButton95 (hwnd, hdc, TRUE, FALSE);
2507 BOOL oldstate = pressed;
2508 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2509 CONV_POINT32TO16( &msg.pt, &pt16 );
2511 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2512 if (pressed != oldstate)
2513 NC_DrawCloseButton95 (hwnd, hdc, pressed, FALSE);
2514 } while (msg.message != WM_LBUTTONUP);
2516 NC_DrawCloseButton95 (hwnd, hdc, FALSE, FALSE);
2518 ReleaseCapture();
2519 ReleaseDC( hwnd, hdc );
2520 if (!pressed) return;
2522 SendMessage16( hwnd, WM_SYSCOMMAND, SC_CLOSE, *(LONG*)&pt16 );
2526 /***********************************************************************
2527 * NC_TrackScrollBar
2529 * Track a mouse button press on the horizontal or vertical scroll-bar.
2531 static void NC_TrackScrollBar( HWND hwnd, WPARAM wParam, POINT pt )
2533 MSG16 *msg;
2534 INT scrollbar;
2535 WND *wndPtr = WIN_FindWndPtr( hwnd );
2537 if ((wParam & 0xfff0) == SC_HSCROLL)
2539 if ((wParam & 0x0f) != HTHSCROLL) goto END;
2540 scrollbar = SB_HORZ;
2542 else /* SC_VSCROLL */
2544 if ((wParam & 0x0f) != HTVSCROLL) goto END;
2545 scrollbar = SB_VERT;
2548 if (!(msg = SEGPTR_NEW(MSG16))) goto END;
2549 pt.x -= wndPtr->rectWindow.left;
2550 pt.y -= wndPtr->rectWindow.top;
2551 SetCapture( hwnd );
2552 SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt );
2556 GetMessage16( SEGPTR_GET(msg), 0, 0, 0 );
2557 switch(msg->message)
2559 case WM_LBUTTONUP:
2560 case WM_MOUSEMOVE:
2561 case WM_SYSTIMER:
2562 pt.x = LOWORD(msg->lParam) + wndPtr->rectClient.left -
2563 wndPtr->rectWindow.left;
2564 pt.y = HIWORD(msg->lParam) + wndPtr->rectClient.top -
2565 wndPtr->rectWindow.top;
2566 SCROLL_HandleScrollEvent( hwnd, scrollbar, msg->message, pt );
2567 break;
2568 default:
2569 TranslateMessage16( msg );
2570 DispatchMessage16( msg );
2571 break;
2573 if (!IsWindow( hwnd ))
2575 ReleaseCapture();
2576 break;
2578 } while (msg->message != WM_LBUTTONUP);
2579 SEGPTR_FREE(msg);
2580 END:
2581 WIN_ReleaseWndPtr(wndPtr);
2584 /***********************************************************************
2585 * NC_HandleNCLButtonDown
2587 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2589 LONG NC_HandleNCLButtonDown( WND* pWnd, WPARAM16 wParam, LPARAM lParam )
2591 HWND hwnd = pWnd->hwndSelf;
2593 switch(wParam) /* Hit test */
2595 case HTCAPTION:
2596 hwnd = WIN_GetTopParent(hwnd);
2598 if( WINPOS_SetActiveWindow(hwnd, TRUE, TRUE) || (GetActiveWindow() == hwnd) )
2599 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
2600 break;
2602 case HTSYSMENU:
2603 if( pWnd->dwStyle & WS_SYSMENU )
2605 if( !(pWnd->dwStyle & WS_MINIMIZE) )
2607 HDC hDC = GetWindowDC(hwnd);
2608 if (TWEAK_WineLook == WIN31_LOOK)
2609 NC_DrawSysButton( hwnd, hDC, TRUE );
2610 else
2611 NC_DrawSysButton95( hwnd, hDC, TRUE );
2612 ReleaseDC( hwnd, hDC );
2614 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
2616 break;
2618 case HTMENU:
2619 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam );
2620 break;
2622 case HTHSCROLL:
2623 SendMessage16( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
2624 break;
2626 case HTVSCROLL:
2627 SendMessage16( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
2628 break;
2630 case HTMINBUTTON:
2631 case HTMAXBUTTON:
2632 if (TWEAK_WineLook == WIN31_LOOK)
2633 NC_TrackMinMaxBox( hwnd, wParam );
2634 else
2635 NC_TrackMinMaxBox95( hwnd, wParam );
2636 break;
2638 case HTCLOSE:
2639 if (TWEAK_WineLook >= WIN95_LOOK)
2640 NC_TrackCloseButton95 (hwnd, wParam);
2641 break;
2643 case HTLEFT:
2644 case HTRIGHT:
2645 case HTTOP:
2646 case HTTOPLEFT:
2647 case HTTOPRIGHT:
2648 case HTBOTTOM:
2649 case HTBOTTOMLEFT:
2650 case HTBOTTOMRIGHT:
2651 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2652 SendMessage16( hwnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam);
2653 break;
2655 case HTBORDER:
2656 break;
2658 return 0;
2662 /***********************************************************************
2663 * NC_HandleNCLButtonDblClk
2665 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2667 LONG NC_HandleNCLButtonDblClk( WND *pWnd, WPARAM16 wParam, LPARAM lParam )
2670 * if this is an icon, send a restore since we are handling
2671 * a double click
2673 if (pWnd->dwStyle & WS_MINIMIZE)
2675 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_RESTORE, lParam );
2676 return 0;
2679 switch(wParam) /* Hit test */
2681 case HTCAPTION:
2682 /* stop processing if WS_MAXIMIZEBOX is missing */
2683 if (pWnd->dwStyle & WS_MAXIMIZEBOX)
2684 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND,
2685 (pWnd->dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
2686 lParam );
2687 break;
2689 case HTSYSMENU:
2690 if (!(GetClassWord(pWnd->hwndSelf, GCW_STYLE) & CS_NOCLOSE))
2691 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, lParam );
2692 break;
2694 case HTHSCROLL:
2695 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL,
2696 lParam );
2697 break;
2699 case HTVSCROLL:
2700 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL,
2701 lParam );
2702 break;
2704 return 0;
2708 /***********************************************************************
2709 * NC_HandleSysCommand
2711 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2713 LONG NC_HandleSysCommand( HWND hwnd, WPARAM16 wParam, POINT16 pt )
2715 WND *wndPtr = WIN_FindWndPtr( hwnd );
2716 POINT pt32;
2717 UINT16 uCommand = wParam & 0xFFF0;
2719 TRACE("Handling WM_SYSCOMMAND %x %d,%d\n", wParam, pt.x, pt.y );
2721 if (wndPtr->dwStyle & WS_CHILD && uCommand != SC_KEYMENU )
2722 ScreenToClient16( wndPtr->parent->hwndSelf, &pt );
2724 switch (uCommand)
2726 case SC_SIZE:
2727 case SC_MOVE:
2728 NC_DoSizeMove( hwnd, wParam );
2729 break;
2731 case SC_MINIMIZE:
2732 if (hwnd == GetForegroundWindow())
2733 ShowOwnedPopups(hwnd,FALSE);
2734 ShowWindow( hwnd, SW_MINIMIZE );
2735 break;
2737 case SC_MAXIMIZE:
2738 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2739 ShowOwnedPopups(hwnd,TRUE);
2740 ShowWindow( hwnd, SW_MAXIMIZE );
2741 break;
2743 case SC_RESTORE:
2744 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2745 ShowOwnedPopups(hwnd,TRUE);
2746 ShowWindow( hwnd, SW_RESTORE );
2747 break;
2749 case SC_CLOSE:
2750 WIN_ReleaseWndPtr(wndPtr);
2751 return SendMessage16( hwnd, WM_CLOSE, 0, 0 );
2753 case SC_VSCROLL:
2754 case SC_HSCROLL:
2755 CONV_POINT16TO32( &pt, &pt32 );
2756 NC_TrackScrollBar( hwnd, wParam, pt32 );
2757 break;
2759 case SC_MOUSEMENU:
2760 CONV_POINT16TO32( &pt, &pt32 );
2761 MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt32 );
2762 break;
2764 case SC_KEYMENU:
2765 MENU_TrackKbdMenuBar( wndPtr , wParam , pt.x );
2766 break;
2768 case SC_TASKLIST:
2769 WinExec( "taskman.exe", SW_SHOWNORMAL );
2770 break;
2772 case SC_SCREENSAVE:
2773 if (wParam == SC_ABOUTWINE)
2775 HMODULE hmodule = LoadLibraryA( "shell32.dll" );
2776 if (hmodule)
2778 FARPROC aboutproc = GetProcAddress( hmodule, "ShellAboutA" );
2779 if (aboutproc) aboutproc( hwnd, "Wine", WINE_RELEASE_INFO, 0 );
2780 FreeLibrary( hmodule );
2783 else
2784 if (wParam == SC_PUTMARK)
2785 TRACE_(shell)("Mark requested by user\n");
2786 break;
2788 case SC_HOTKEY:
2789 case SC_ARRANGE:
2790 case SC_NEXTWINDOW:
2791 case SC_PREVWINDOW:
2792 FIXME("unimplemented!\n");
2793 break;
2795 WIN_ReleaseWndPtr(wndPtr);
2796 return 0;
2799 /*************************************************************
2800 * NC_DrawGrayButton
2802 * Stub for the grayed button of the caption
2804 *************************************************************/
2806 BOOL NC_DrawGrayButton(HDC hdc, int x, int y)
2808 HBITMAP hMaskBmp;
2809 HDC hdcMask = CreateCompatibleDC (0);
2810 HBRUSH hOldBrush;
2812 hMaskBmp = CreateBitmap (12, 10, 1, 1, lpGrayMask);
2814 if(hMaskBmp == 0)
2815 return FALSE;
2817 SelectObject (hdcMask, hMaskBmp);
2819 /* Draw the grayed bitmap using the mask */
2820 hOldBrush = SelectObject (hdc, RGB(128, 128, 128));
2821 BitBlt (hdc, x, y, 12, 10,
2822 hdcMask, 0, 0, 0xB8074A);
2824 /* Clean up */
2825 SelectObject (hdc, hOldBrush);
2826 DeleteObject(hMaskBmp);
2827 DeleteDC (hdcMask);
2829 return TRUE;