Francois Boisvert
[wine/multimedia.git] / windows / nonclient.c
blob8fc3eb0b3f4dfa9d19068ca17b2c9dc76948645c
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 /* A tool window has a smaller Close button */
1131 if(wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
1133 RECT toolRect;
1134 INT iBmpHeight = 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
1135 INT iBmpWidth = 11; /* it uses 11x11 for the close button in tool window */
1136 INT iCaptionHeight = GetSystemMetrics(SM_CYSMCAPTION);
1138 toolRect.top = rect.top + (iCaptionHeight - 1 - iBmpHeight) / 2;
1139 toolRect.left = rect.right - (iCaptionHeight + 1 + iBmpWidth) / 2;
1140 toolRect.bottom = toolRect.top + iBmpHeight;
1141 toolRect.right = toolRect.left + iBmpWidth;
1142 DrawFrameControl(hdc,&toolRect,
1143 DFC_CAPTION,DFCS_CAPTIONCLOSE |
1144 down ? DFCS_PUSHED : 0 |
1145 bGrayed ? DFCS_INACTIVE : 0);
1147 else
1149 hdcMem = CreateCompatibleDC( hdc );
1150 hBmp = down ? hbitmapCloseD : hbitmapClose;
1151 hOldBmp = SelectObject (hdcMem, hBmp);
1152 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1154 BitBlt (hdc, rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2,
1155 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1156 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);
1158 if(bGrayed)
1159 NC_DrawGrayButton(hdc,rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2 + 2,
1160 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1162 SelectObject (hdcMem, hOldBmp);
1163 DeleteDC (hdcMem);
1166 WIN_ReleaseWndPtr(wndPtr);
1169 /******************************************************************************
1171 * NC_DrawMaxButton95(
1172 * HWND hwnd,
1173 * HDC16 hdc,
1174 * BOOL down
1175 * BOOL bGrayed )
1177 * Draws the maximize button for Win95 style windows.
1179 * If bGrayed is true, then draw a disabled Maximize button
1181 * Bugs
1182 * Many. Spacing might still be incorrect. Need to fit a close
1183 * button between the max button and the edge.
1184 * Should scale the image with the title bar. And more...
1186 * Revision history
1187 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1188 * Original implementation.
1190 *****************************************************************************/
1192 static void NC_DrawMaxButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
1194 RECT rect;
1195 HDC hdcMem;
1196 WND *wndPtr = WIN_FindWndPtr( hwnd );
1198 if( !(wndPtr->flags & WIN_MANAGED))
1200 BITMAP bmp;
1201 HBITMAP hBmp,hOldBmp;
1203 NC_GetInsideRect95( hwnd, &rect );
1204 hdcMem = CreateCompatibleDC( hdc );
1205 hBmp = IsZoomed(hwnd) ?
1206 (down ? hbitmapRestoreD : hbitmapRestore ) :
1207 (down ? hbitmapMaximizeD: hbitmapMaximize);
1208 hOldBmp=SelectObject( hdcMem, hBmp );
1209 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1211 if (wndPtr->dwStyle & WS_SYSMENU)
1212 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1214 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1215 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1216 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1218 if(bGrayed)
1219 NC_DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
1220 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1223 SelectObject (hdcMem, hOldBmp);
1224 DeleteDC( hdcMem );
1226 WIN_ReleaseWndPtr(wndPtr);
1229 /******************************************************************************
1231 * NC_DrawMinButton95(
1232 * HWND hwnd,
1233 * HDC16 hdc,
1234 * BOOL down,
1235 * BOOL bGrayed )
1237 * Draws the minimize button for Win95 style windows.
1239 * If bGrayed is true, then draw a disabled Minimize button
1241 * Bugs
1242 * Many. Spacing is still incorrect. Should scale the image with the
1243 * title bar. And more...
1245 * Revision history
1246 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1247 * Original implementation.
1249 *****************************************************************************/
1251 static void NC_DrawMinButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
1253 RECT rect;
1254 HDC hdcMem;
1255 WND *wndPtr = WIN_FindWndPtr( hwnd );
1257 if( !(wndPtr->flags & WIN_MANAGED))
1260 BITMAP bmp;
1261 HBITMAP hBmp,hOldBmp;
1263 NC_GetInsideRect95( hwnd, &rect );
1265 hdcMem = CreateCompatibleDC( hdc );
1266 hBmp = down ? hbitmapMinimizeD : hbitmapMinimize;
1267 hOldBmp= SelectObject( hdcMem, hBmp );
1268 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1270 if (wndPtr->dwStyle & WS_SYSMENU)
1271 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1273 /* In win 95 there is always a Maximize box when there is a Minimize one */
1274 if ((wndPtr->dwStyle & WS_MAXIMIZEBOX) || (wndPtr->dwStyle & WS_MINIMIZEBOX))
1275 rect.right += -1 - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2;
1277 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1278 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1279 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1281 if(bGrayed)
1282 NC_DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
1283 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1286 SelectObject (hdcMem, hOldBmp);
1287 DeleteDC( hdcMem );
1289 WIN_ReleaseWndPtr(wndPtr);
1292 /***********************************************************************
1293 * NC_DrawFrame
1295 * Draw a window frame inside the given rectangle, and update the rectangle.
1296 * The correct pen for the frame must be selected in the DC.
1298 static void NC_DrawFrame( HDC hdc, RECT *rect, BOOL dlgFrame,
1299 BOOL active )
1301 INT width, height;
1303 if (TWEAK_WineLook != WIN31_LOOK)
1304 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
1306 if (dlgFrame)
1308 width = GetSystemMetrics(SM_CXDLGFRAME) - 1;
1309 height = GetSystemMetrics(SM_CYDLGFRAME) - 1;
1310 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1311 COLOR_INACTIVECAPTION) );
1313 else
1315 width = GetSystemMetrics(SM_CXFRAME) - 2;
1316 height = GetSystemMetrics(SM_CYFRAME) - 2;
1317 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1318 COLOR_INACTIVEBORDER) );
1321 /* Draw frame */
1322 PatBlt( hdc, rect->left, rect->top,
1323 rect->right - rect->left, height, PATCOPY );
1324 PatBlt( hdc, rect->left, rect->top,
1325 width, rect->bottom - rect->top, PATCOPY );
1326 PatBlt( hdc, rect->left, rect->bottom - 1,
1327 rect->right - rect->left, -height, PATCOPY );
1328 PatBlt( hdc, rect->right - 1, rect->top,
1329 -width, rect->bottom - rect->top, PATCOPY );
1331 if (dlgFrame)
1333 InflateRect( rect, -width, -height );
1335 else
1337 INT decYOff = GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXSIZE) - 1;
1338 INT decXOff = GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYSIZE) - 1;
1340 /* Draw inner rectangle */
1342 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1343 Rectangle( hdc, rect->left + width, rect->top + height,
1344 rect->right - width , rect->bottom - height );
1346 /* Draw the decorations */
1348 MoveToEx( hdc, rect->left, rect->top + decYOff, NULL );
1349 LineTo( hdc, rect->left + width, rect->top + decYOff );
1350 MoveToEx( hdc, rect->right - 1, rect->top + decYOff, NULL );
1351 LineTo( hdc, rect->right - width - 1, rect->top + decYOff );
1352 MoveToEx( hdc, rect->left, rect->bottom - decYOff, NULL );
1353 LineTo( hdc, rect->left + width, rect->bottom - decYOff );
1354 MoveToEx( hdc, rect->right - 1, rect->bottom - decYOff, NULL );
1355 LineTo( hdc, rect->right - width - 1, rect->bottom - decYOff );
1357 MoveToEx( hdc, rect->left + decXOff, rect->top, NULL );
1358 LineTo( hdc, rect->left + decXOff, rect->top + height);
1359 MoveToEx( hdc, rect->left + decXOff, rect->bottom - 1, NULL );
1360 LineTo( hdc, rect->left + decXOff, rect->bottom - height - 1 );
1361 MoveToEx( hdc, rect->right - decXOff, rect->top, NULL );
1362 LineTo( hdc, rect->right - decXOff, rect->top + height );
1363 MoveToEx( hdc, rect->right - decXOff, rect->bottom - 1, NULL );
1364 LineTo( hdc, rect->right - decXOff, rect->bottom - height - 1 );
1366 InflateRect( rect, -width - 1, -height - 1 );
1371 /******************************************************************************
1373 * void NC_DrawFrame95(
1374 * HDC hdc,
1375 * RECT *rect,
1376 * BOOL dlgFrame,
1377 * BOOL active )
1379 * Draw a window frame inside the given rectangle, and update the rectangle.
1380 * The correct pen for the frame must be selected in the DC.
1382 * Bugs
1383 * Many. First, just what IS a frame in Win95? Note that the 3D look
1384 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1385 * edge. The inner rectangle just inside the frame is handled by the
1386 * Caption code.
1388 * In short, for most people, this function should be a nop (unless
1389 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1390 * them lately, but just to get this code right). Even so, it doesn't
1391 * appear to be so. It's being worked on...
1393 * Revision history
1394 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1395 * Original implementation (based on NC_DrawFrame)
1396 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1397 * Some minor fixes.
1398 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1399 * Fixed a fix or something.
1401 *****************************************************************************/
1403 static void NC_DrawFrame95(
1404 HDC hdc,
1405 RECT *rect,
1406 BOOL dlgFrame,
1407 BOOL active )
1409 INT width, height;
1411 if (dlgFrame)
1413 width = GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
1414 height = GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
1416 else
1418 width = GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXEDGE);
1419 height = GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYEDGE);
1422 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1423 COLOR_INACTIVEBORDER) );
1425 /* Draw frame */
1426 PatBlt( hdc, rect->left, rect->top,
1427 rect->right - rect->left, height, PATCOPY );
1428 PatBlt( hdc, rect->left, rect->top,
1429 width, rect->bottom - rect->top, PATCOPY );
1430 PatBlt( hdc, rect->left, rect->bottom - 1,
1431 rect->right - rect->left, -height, PATCOPY );
1432 PatBlt( hdc, rect->right - 1, rect->top,
1433 -width, rect->bottom - rect->top, PATCOPY );
1435 InflateRect( rect, -width, -height );
1438 /***********************************************************************
1439 * NC_DrawMovingFrame
1441 * Draw the frame used when moving or resizing window.
1443 * FIXME: This causes problems in Win95 mode. (why?)
1445 static void NC_DrawMovingFrame( HDC hdc, RECT *rect, BOOL thickframe )
1447 if (thickframe)
1449 RECT16 r16;
1450 CONV_RECT32TO16( rect, &r16 );
1451 FastWindowFrame16( hdc, &r16, GetSystemMetrics(SM_CXFRAME),
1452 GetSystemMetrics(SM_CYFRAME), PATINVERT );
1454 else DrawFocusRect( hdc, rect );
1458 /***********************************************************************
1459 * NC_DrawCaption
1461 * Draw the window caption.
1462 * The correct pen for the window frame must be selected in the DC.
1464 static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd,
1465 DWORD style, BOOL active )
1467 RECT r = *rect;
1468 WND * wndPtr = WIN_FindWndPtr( hwnd );
1469 char buffer[256];
1471 if (wndPtr->flags & WIN_MANAGED)
1473 WIN_ReleaseWndPtr(wndPtr);
1474 return;
1477 if (!hbitmapClose)
1479 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1481 WIN_ReleaseWndPtr(wndPtr);
1482 return;
1484 hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED) );
1485 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1486 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1487 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1488 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1489 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1490 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1493 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
1495 HBRUSH hbrushOld = SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW) );
1496 PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
1497 PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
1498 PatBlt( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
1499 r.left++;
1500 r.right--;
1501 SelectObject( hdc, hbrushOld );
1503 WIN_ReleaseWndPtr(wndPtr);
1504 MoveTo16( hdc, r.left, r.bottom );
1505 LineTo( hdc, r.right, r.bottom );
1507 if (style & WS_SYSMENU)
1509 NC_DrawSysButton( hwnd, hdc, FALSE );
1510 r.left += GetSystemMetrics(SM_CXSIZE) + 1;
1511 MoveTo16( hdc, r.left - 1, r.top );
1512 LineTo( hdc, r.left - 1, r.bottom );
1514 if (style & WS_MAXIMIZEBOX)
1516 NC_DrawMaxButton( hwnd, hdc, FALSE );
1517 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1519 if (style & WS_MINIMIZEBOX)
1521 NC_DrawMinButton( hwnd, hdc, FALSE );
1522 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1525 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1526 COLOR_INACTIVECAPTION) );
1528 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) ))
1530 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1531 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1532 SetBkMode( hdc, TRANSPARENT );
1533 DrawTextA( hdc, buffer, -1, &r,
1534 DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );
1539 /******************************************************************************
1541 * NC_DrawCaption95(
1542 * HDC hdc,
1543 * RECT *rect,
1544 * HWND hwnd,
1545 * DWORD style,
1546 * BOOL active )
1548 * Draw the window caption for Win95 style windows.
1549 * The correct pen for the window frame must be selected in the DC.
1551 * Bugs
1552 * Hey, a function that finally works! Well, almost.
1553 * It's being worked on.
1555 * Revision history
1556 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1557 * Original implementation.
1558 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1559 * Some minor fixes.
1561 *****************************************************************************/
1563 static void NC_DrawCaption95(
1564 HDC hdc,
1565 RECT *rect,
1566 HWND hwnd,
1567 DWORD style,
1568 DWORD exStyle,
1569 BOOL active )
1571 RECT r = *rect;
1572 WND *wndPtr = WIN_FindWndPtr( hwnd );
1573 char buffer[256];
1574 HPEN hPrevPen;
1575 HMENU hSysMenu;
1577 if (wndPtr->flags & WIN_MANAGED)
1579 WIN_ReleaseWndPtr(wndPtr);
1580 return;
1582 WIN_ReleaseWndPtr(wndPtr);
1584 hPrevPen = SelectObject( hdc, GetSysColorPen(COLOR_3DFACE) );
1585 MoveToEx( hdc, r.left, r.bottom - 1, NULL );
1586 LineTo( hdc, r.right, r.bottom - 1 );
1587 SelectObject( hdc, hPrevPen );
1588 r.bottom--;
1590 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1591 COLOR_INACTIVECAPTION) );
1593 if (!hbitmapClose) {
1594 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1595 return;
1596 hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED));
1597 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1598 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1599 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1600 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1601 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1602 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1605 if ((style & WS_SYSMENU) && !(exStyle & WS_EX_TOOLWINDOW)) {
1606 if (NC_DrawSysButton95 (hwnd, hdc, FALSE))
1607 r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
1610 if (style & WS_SYSMENU)
1612 UINT state;
1614 /* Go get the sysmenu */
1615 hSysMenu = GetSystemMenu(hwnd, FALSE);
1616 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
1618 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1619 NC_DrawCloseButton95 (hwnd, hdc, FALSE,
1620 ((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
1621 r.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
1623 if ((style & WS_MAXIMIZEBOX) || (style & WS_MINIMIZEBOX))
1625 /* In win95 the two buttons are always there */
1626 /* But if the menu item is not in the menu they're disabled*/
1628 NC_DrawMaxButton95( hwnd, hdc, FALSE, (!(style & WS_MAXIMIZEBOX)));
1629 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1631 NC_DrawMinButton95( hwnd, hdc, FALSE, (!(style & WS_MINIMIZEBOX)));
1632 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1636 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) )) {
1637 NONCLIENTMETRICSA nclm;
1638 HFONT hFont, hOldFont;
1639 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1640 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1641 if (exStyle & WS_EX_TOOLWINDOW)
1642 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
1643 else
1644 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
1645 hOldFont = SelectObject (hdc, hFont);
1646 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1647 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1648 SetBkMode( hdc, TRANSPARENT );
1649 r.left += 2;
1650 DrawTextA( hdc, buffer, -1, &r,
1651 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
1652 DeleteObject (SelectObject (hdc, hOldFont));
1658 /***********************************************************************
1659 * NC_DoNCPaint
1661 * Paint the non-client area. clip is currently unused.
1663 static void NC_DoNCPaint( WND* wndPtr, HRGN clip, BOOL suppress_menupaint )
1665 HDC hdc;
1666 RECT rect;
1667 BOOL active;
1668 HWND hwnd = wndPtr->hwndSelf;
1670 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1671 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1673 active = wndPtr->flags & WIN_NCACTIVATED;
1675 TRACE("%04x %d\n", hwnd, active );
1677 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1678 ((clip > 1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN): 0) ))) return;
1680 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1681 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1682 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1683 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1684 == NULLREGION)
1686 ReleaseDC( hwnd, hdc );
1687 return;
1690 rect.top = rect.left = 0;
1691 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1692 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1694 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1696 if (!(wndPtr->flags & WIN_MANAGED))
1698 if (HAS_ANYFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1700 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1701 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1702 InflateRect( &rect, -1, -1 );
1705 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1706 NC_DrawFrame(hdc, &rect, FALSE, active );
1707 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1708 NC_DrawFrame( hdc, &rect, TRUE, active );
1710 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1712 RECT r = rect;
1713 r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
1714 rect.top += GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYBORDER);
1715 NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active );
1719 if (HAS_MENU(wndPtr))
1721 RECT r = rect;
1722 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU); /* default height */
1723 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint );
1726 /* Draw the scroll-bars */
1728 if (wndPtr->dwStyle & WS_VSCROLL)
1729 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1730 if (wndPtr->dwStyle & WS_HSCROLL)
1731 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1733 /* Draw the "size-box" */
1735 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1737 RECT r = rect;
1738 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1739 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1740 if(wndPtr->dwStyle & WS_BORDER) {
1741 r.left++;
1742 r.top++;
1744 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1747 ReleaseDC( hwnd, hdc );
1751 /******************************************************************************
1753 * void NC_DoNCPaint95(
1754 * WND *wndPtr,
1755 * HRGN clip,
1756 * BOOL suppress_menupaint )
1758 * Paint the non-client area for Win95 windows. The clip region is
1759 * currently ignored.
1761 * Bugs
1762 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1763 * misc/tweak.c controls/menu.c # :-)
1765 * Revision history
1766 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1767 * Original implementation
1768 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1769 * Fixed some bugs.
1770 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1771 * Streamlined window style checks.
1773 *****************************************************************************/
1775 static void NC_DoNCPaint95(
1776 WND *wndPtr,
1777 HRGN clip,
1778 BOOL suppress_menupaint )
1780 HDC hdc;
1781 RECT rfuzz, rect, rectClip;
1782 BOOL active;
1783 HWND hwnd = wndPtr->hwndSelf;
1785 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1786 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1788 active = wndPtr->flags & WIN_NCACTIVATED;
1790 TRACE("%04x %d\n", hwnd, active );
1792 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1793 the call to GetDCEx implying that it is allowed not to use it either.
1794 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1795 will cause clipRgn to be deleted after ReleaseDC().
1796 Now, how is the "system" supposed to tell what happened?
1799 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1800 ((clip > 1) ?(DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0) ))) return;
1803 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1804 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1805 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1806 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1807 == NULLREGION)
1809 ReleaseDC( hwnd, hdc );
1810 return;
1813 rect.top = rect.left = 0;
1814 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1815 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1817 if( clip > 1 )
1818 GetRgnBox( clip, &rectClip );
1819 else
1821 clip = 0;
1822 rectClip = rect;
1825 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1827 if(!(wndPtr->flags & WIN_MANAGED)) {
1828 if (HAS_BIGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle)) {
1829 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1831 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1832 NC_DrawFrame95(hdc, &rect, FALSE, active );
1833 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1834 NC_DrawFrame95( hdc, &rect, TRUE, active );
1835 else if (HAS_THINFRAME( wndPtr->dwStyle )) {
1836 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1837 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1840 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1842 RECT r = rect;
1843 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW) {
1844 r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
1845 rect.top += GetSystemMetrics(SM_CYSMCAPTION);
1847 else {
1848 r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
1849 rect.top += GetSystemMetrics(SM_CYCAPTION);
1851 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
1852 NC_DrawCaption95 (hdc, &r, hwnd, wndPtr->dwStyle,
1853 wndPtr->dwExStyle, active);
1857 if (HAS_MENU(wndPtr))
1859 RECT r = rect;
1860 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
1862 TRACE("Calling DrawMenuBar with rect (%d, %d)-(%d, %d)\n",
1863 r.left, r.top, r.right, r.bottom);
1865 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ) + 1;
1868 TRACE("After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1869 rect.left, rect.top, rect.right, rect.bottom );
1871 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
1872 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1874 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
1875 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1877 /* Draw the scroll-bars */
1879 if (wndPtr->dwStyle & WS_VSCROLL)
1880 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1881 if (wndPtr->dwStyle & WS_HSCROLL)
1882 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1884 /* Draw the "size-box" */
1885 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1887 RECT r = rect;
1888 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1889 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1890 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1893 ReleaseDC( hwnd, hdc );
1899 /***********************************************************************
1900 * NC_HandleNCPaint
1902 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1904 LONG NC_HandleNCPaint( HWND hwnd , HRGN clip)
1906 WND* wndPtr = WIN_FindWndPtr( hwnd );
1908 if( wndPtr && wndPtr->dwStyle & WS_VISIBLE )
1910 if( wndPtr->dwStyle & WS_MINIMIZE )
1911 WINPOS_RedrawIconTitle( hwnd );
1912 else if (TWEAK_WineLook == WIN31_LOOK)
1913 NC_DoNCPaint( wndPtr, clip, FALSE );
1914 else
1915 NC_DoNCPaint95( wndPtr, clip, FALSE );
1917 WIN_ReleaseWndPtr(wndPtr);
1918 return 0;
1922 /***********************************************************************
1923 * NC_HandleNCActivate
1925 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1927 LONG NC_HandleNCActivate( WND *wndPtr, WPARAM16 wParam )
1929 WORD wStateChange;
1931 if( wParam ) wStateChange = !(wndPtr->flags & WIN_NCACTIVATED);
1932 else wStateChange = wndPtr->flags & WIN_NCACTIVATED;
1934 if( wStateChange )
1936 if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
1937 else wndPtr->flags &= ~WIN_NCACTIVATED;
1939 if( wndPtr->dwStyle & WS_MINIMIZE )
1940 WINPOS_RedrawIconTitle( wndPtr->hwndSelf );
1941 else if (TWEAK_WineLook == WIN31_LOOK)
1942 NC_DoNCPaint( wndPtr, (HRGN)1, FALSE );
1943 else
1944 NC_DoNCPaint95( wndPtr, (HRGN)1, FALSE );
1946 return TRUE;
1950 /***********************************************************************
1951 * NC_HandleSetCursor
1953 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1955 LONG NC_HandleSetCursor( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
1957 if (hwnd != (HWND)wParam) return 0; /* Don't set the cursor for child windows */
1959 switch(LOWORD(lParam))
1961 case HTERROR:
1963 WORD msg = HIWORD( lParam );
1964 if ((msg == WM_LBUTTONDOWN) || (msg == WM_MBUTTONDOWN) ||
1965 (msg == WM_RBUTTONDOWN))
1966 MessageBeep(0);
1968 break;
1970 case HTCLIENT:
1972 HICON16 hCursor = (HICON16) GetClassWord(hwnd, GCW_HCURSOR);
1973 if(hCursor) {
1974 SetCursor16(hCursor);
1975 return TRUE;
1977 return FALSE;
1980 case HTLEFT:
1981 case HTRIGHT:
1982 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZEWE16 ) );
1984 case HTTOP:
1985 case HTBOTTOM:
1986 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENS16 ) );
1988 case HTTOPLEFT:
1989 case HTBOTTOMRIGHT:
1990 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENWSE16 ) );
1992 case HTTOPRIGHT:
1993 case HTBOTTOMLEFT:
1994 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENESW16 ) );
1997 /* Default cursor: arrow */
1998 return (LONG)SetCursor16( LoadCursor16( 0, IDC_ARROW16 ) );
2001 /***********************************************************************
2002 * NC_GetSysPopupPos
2004 BOOL NC_GetSysPopupPos( WND* wndPtr, RECT* rect )
2006 if( wndPtr->hSysMenu )
2008 if( wndPtr->dwStyle & WS_MINIMIZE )
2009 GetWindowRect( wndPtr->hwndSelf, rect );
2010 else
2012 if (TWEAK_WineLook == WIN31_LOOK)
2013 NC_GetInsideRect( wndPtr->hwndSelf, rect );
2014 else
2015 NC_GetInsideRect95( wndPtr->hwndSelf, rect );
2016 OffsetRect( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
2017 if (wndPtr->dwStyle & WS_CHILD)
2018 ClientToScreen( wndPtr->parent->hwndSelf, (POINT *)rect );
2019 if (TWEAK_WineLook == WIN31_LOOK) {
2020 rect->right = rect->left + GetSystemMetrics(SM_CXSIZE);
2021 rect->bottom = rect->top + GetSystemMetrics(SM_CYSIZE);
2023 else {
2024 rect->right = rect->left + GetSystemMetrics(SM_CYCAPTION) - 1;
2025 rect->bottom = rect->top + GetSystemMetrics(SM_CYCAPTION) - 1;
2028 return TRUE;
2030 return FALSE;
2033 /***********************************************************************
2034 * NC_StartSizeMove
2036 * Initialisation of a move or resize, when initiatied from a menu choice.
2037 * Return hit test code for caption or sizing border.
2039 static LONG NC_StartSizeMove( WND* wndPtr, WPARAM16 wParam,
2040 POINT16 *capturePoint )
2042 LONG hittest = 0;
2043 POINT16 pt;
2044 MSG msg;
2045 RECT rectWindow;
2047 GetWindowRect(wndPtr->hwndSelf,&rectWindow);
2049 if ((wParam & 0xfff0) == SC_MOVE)
2051 /* Move pointer at the center of the caption */
2052 RECT rect;
2053 if (TWEAK_WineLook == WIN31_LOOK)
2054 NC_GetInsideRect( wndPtr->hwndSelf, &rect );
2055 else
2056 NC_GetInsideRect95( wndPtr->hwndSelf, &rect );
2057 if (wndPtr->dwStyle & WS_SYSMENU)
2058 rect.left += GetSystemMetrics(SM_CXSIZE) + 1;
2059 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
2060 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
2061 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
2062 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
2063 pt.x = rectWindow.left + (rect.right - rect.left) / 2;
2064 pt.y = rectWindow.top + rect.top + GetSystemMetrics(SM_CYSIZE)/2;
2065 hittest = HTCAPTION;
2066 *capturePoint = pt;
2068 else /* SC_SIZE */
2070 while(!hittest)
2072 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE, NULL );
2073 switch(msg.message)
2075 case WM_MOUSEMOVE:
2076 CONV_POINT32TO16(&msg.pt, &pt);
2077 hittest = NC_HandleNCHitTest( wndPtr->hwndSelf, pt );
2078 if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
2079 hittest = 0;
2080 break;
2082 case WM_LBUTTONUP:
2083 return 0;
2085 case WM_KEYDOWN:
2086 switch(msg.wParam)
2088 case VK_UP:
2089 hittest = HTTOP;
2090 pt.x =(rectWindow.left+rectWindow.right)/2;
2091 pt.y = rectWindow.top + GetSystemMetrics(SM_CYFRAME) / 2;
2092 break;
2093 case VK_DOWN:
2094 hittest = HTBOTTOM;
2095 pt.x =(rectWindow.left+rectWindow.right)/2;
2096 pt.y = rectWindow.bottom - GetSystemMetrics(SM_CYFRAME) / 2;
2097 break;
2098 case VK_LEFT:
2099 hittest = HTLEFT;
2100 pt.x = rectWindow.left + GetSystemMetrics(SM_CXFRAME) / 2;
2101 pt.y =(rectWindow.top+rectWindow.bottom)/2;
2102 break;
2103 case VK_RIGHT:
2104 hittest = HTRIGHT;
2105 pt.x = rectWindow.right - GetSystemMetrics(SM_CXFRAME) / 2;
2106 pt.y =(rectWindow.top+rectWindow.bottom)/2;
2107 break;
2108 case VK_RETURN:
2109 case VK_ESCAPE: return 0;
2113 *capturePoint = pt;
2115 SetCursorPos( pt.x, pt.y );
2116 NC_HandleSetCursor( wndPtr->hwndSelf,
2117 wndPtr->hwndSelf, MAKELONG( hittest, WM_MOUSEMOVE ));
2118 return hittest;
2122 /***********************************************************************
2123 * NC_DoSizeMove
2125 * Perform SC_MOVE and SC_SIZE commands. `
2127 static void NC_DoSizeMove( HWND hwnd, WORD wParam )
2129 MSG msg;
2130 RECT sizingRect, mouseRect;
2131 HDC hdc;
2132 LONG hittest = (LONG)(wParam & 0x0f);
2133 HCURSOR16 hDragCursor = 0, hOldCursor = 0;
2134 POINT minTrack, maxTrack;
2135 POINT16 capturePoint, pt;
2136 WND * wndPtr = WIN_FindWndPtr( hwnd );
2137 BOOL thickframe = HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle );
2138 BOOL iconic = wndPtr->dwStyle & WS_MINIMIZE;
2139 BOOL moved = FALSE;
2140 DWORD dwPoint = GetMessagePos ();
2142 capturePoint = pt = *(POINT16*)&dwPoint;
2144 if (IsZoomed(hwnd) || !IsWindowVisible(hwnd) ||
2145 (wndPtr->flags & WIN_MANAGED)) goto END;
2147 if ((wParam & 0xfff0) == SC_MOVE)
2149 if (!(wndPtr->dwStyle & WS_CAPTION)) goto END;
2150 if (!hittest)
2151 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2152 if (!hittest) goto END;
2154 else /* SC_SIZE */
2156 if (!thickframe) goto END;
2157 if ( hittest && hittest != HTSYSMENU ) hittest += 2;
2158 else
2160 SetCapture(hwnd);
2161 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2162 if (!hittest)
2164 ReleaseCapture();
2165 goto END;
2170 /* Get min/max info */
2172 WINPOS_GetMinMaxInfo( wndPtr, NULL, NULL, &minTrack, &maxTrack );
2173 sizingRect = wndPtr->rectWindow;
2174 if (wndPtr->dwStyle & WS_CHILD)
2175 GetClientRect( wndPtr->parent->hwndSelf, &mouseRect );
2176 else
2177 SetRect(&mouseRect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
2178 if (ON_LEFT_BORDER(hittest))
2180 mouseRect.left = max( mouseRect.left, sizingRect.right-maxTrack.x );
2181 mouseRect.right = min( mouseRect.right, sizingRect.right-minTrack.x );
2183 else if (ON_RIGHT_BORDER(hittest))
2185 mouseRect.left = max( mouseRect.left, sizingRect.left+minTrack.x );
2186 mouseRect.right = min( mouseRect.right, sizingRect.left+maxTrack.x );
2188 if (ON_TOP_BORDER(hittest))
2190 mouseRect.top = max( mouseRect.top, sizingRect.bottom-maxTrack.y );
2191 mouseRect.bottom = min( mouseRect.bottom,sizingRect.bottom-minTrack.y);
2193 else if (ON_BOTTOM_BORDER(hittest))
2195 mouseRect.top = max( mouseRect.top, sizingRect.top+minTrack.y );
2196 mouseRect.bottom = min( mouseRect.bottom, sizingRect.top+maxTrack.y );
2198 if (wndPtr->dwStyle & WS_CHILD)
2200 MapWindowPoints( wndPtr->parent->hwndSelf, 0,
2201 (LPPOINT)&mouseRect, 2 );
2203 SendMessage16( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
2205 if (GetCapture() != hwnd) SetCapture( hwnd );
2207 if (wndPtr->dwStyle & WS_CHILD)
2209 /* Retrieve a default cache DC (without using the window style) */
2210 hdc = GetDCEx( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
2212 else
2213 { /* Grab the server only when moving top-level windows without desktop */
2214 hdc = GetDC( 0 );
2217 wndPtr->pDriver->pPreSizeMove(wndPtr);
2219 if( iconic ) /* create a cursor for dragging */
2221 HICON16 hIcon = GetClassWord(wndPtr->hwndSelf, GCW_HICON);
2222 if(!hIcon) hIcon = (HICON16) SendMessage16( hwnd, WM_QUERYDRAGICON, 0, 0L);
2223 if( hIcon ) hDragCursor = CURSORICON_IconToCursor( hIcon, TRUE );
2224 if( !hDragCursor ) iconic = FALSE;
2227 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
2228 if( !iconic && TWEAK_WineLook == WIN31_LOOK )
2229 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2231 while(1)
2233 int dx = 0, dy = 0;
2235 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE, NULL );
2237 /* Exit on button-up, Return, or Esc */
2238 if ((msg.message == WM_LBUTTONUP) ||
2239 ((msg.message == WM_KEYDOWN) &&
2240 ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
2242 if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
2243 continue; /* We are not interested in other messages */
2245 dwPoint = GetMessagePos ();
2246 pt = *(POINT16*)&dwPoint;
2248 if (msg.message == WM_KEYDOWN) switch(msg.wParam)
2250 case VK_UP: pt.y -= 8; break;
2251 case VK_DOWN: pt.y += 8; break;
2252 case VK_LEFT: pt.x -= 8; break;
2253 case VK_RIGHT: pt.x += 8; break;
2256 pt.x = max( pt.x, mouseRect.left );
2257 pt.x = min( pt.x, mouseRect.right );
2258 pt.y = max( pt.y, mouseRect.top );
2259 pt.y = min( pt.y, mouseRect.bottom );
2261 dx = pt.x - capturePoint.x;
2262 dy = pt.y - capturePoint.y;
2264 if (dx || dy)
2266 if( !moved )
2268 moved = TRUE;
2270 if( iconic ) /* ok, no system popup tracking */
2272 hOldCursor = SetCursor(hDragCursor);
2273 ShowCursor( TRUE );
2274 WINPOS_ShowIconTitle( wndPtr, FALSE );
2275 } else if(TWEAK_WineLook != WIN31_LOOK)
2277 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2281 if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
2282 else
2284 RECT newRect = sizingRect;
2285 WPARAM wpSizingHit = 0;
2287 if (hittest == HTCAPTION) OffsetRect( &newRect, dx, dy );
2288 if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
2289 else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
2290 if (ON_TOP_BORDER(hittest)) newRect.top += dy;
2291 else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
2292 if(!iconic) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2293 capturePoint = pt;
2295 /* determine the hit location */
2296 if (hittest >= HTLEFT && hittest <= HTBOTTOMRIGHT)
2297 wpSizingHit = WMSZ_LEFT + (hittest - HTLEFT);
2298 SendMessageA( hwnd, WM_SIZING, wpSizingHit, (LPARAM)&newRect );
2300 if (!iconic) NC_DrawMovingFrame( hdc, &newRect, thickframe );
2301 sizingRect = newRect;
2306 ReleaseCapture();
2307 if( iconic )
2309 if( moved ) /* restore cursors, show icon title later on */
2311 ShowCursor( FALSE );
2312 SetCursor( hOldCursor );
2314 DestroyCursor( hDragCursor );
2316 else if(moved || TWEAK_WineLook == WIN31_LOOK)
2317 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2319 if (wndPtr->dwStyle & WS_CHILD)
2320 ReleaseDC( wndPtr->parent->hwndSelf, hdc );
2321 else
2322 ReleaseDC( 0, hdc );
2324 wndPtr->pDriver->pPostSizeMove(wndPtr);
2326 if (HOOK_IsHooked( WH_CBT ))
2328 RECT16* pr = SEGPTR_NEW(RECT16);
2329 if( pr )
2331 CONV_RECT32TO16( &sizingRect, pr );
2332 if( HOOK_CallHooks16( WH_CBT, HCBT_MOVESIZE, hwnd,
2333 (LPARAM)SEGPTR_GET(pr)) )
2334 sizingRect = wndPtr->rectWindow;
2335 else
2336 CONV_RECT16TO32( pr, &sizingRect );
2337 SEGPTR_FREE(pr);
2340 SendMessage16( hwnd, WM_EXITSIZEMOVE, 0, 0 );
2341 SendMessage16( hwnd, WM_SETVISIBLE, !IsIconic16(hwnd), 0L);
2343 /* window moved or resized */
2344 if (moved)
2346 /* if the moving/resizing isn't canceled call SetWindowPos
2347 * with the new position or the new size of the window
2349 if (!((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
2351 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
2352 SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top,
2353 sizingRect.right - sizingRect.left,
2354 sizingRect.bottom - sizingRect.top,
2355 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
2359 if( IsWindow(hwnd) )
2360 if( wndPtr->dwStyle & WS_MINIMIZE )
2362 /* Single click brings up the system menu when iconized */
2364 if( !moved )
2366 if( wndPtr->dwStyle & WS_SYSMENU )
2367 SendMessage16( hwnd, WM_SYSCOMMAND,
2368 SC_MOUSEMENU + HTSYSMENU, *((LPARAM*)&pt));
2370 else WINPOS_ShowIconTitle( wndPtr, TRUE );
2373 END:
2374 WIN_ReleaseWndPtr(wndPtr);
2378 /***********************************************************************
2379 * NC_TrackMinMaxBox95
2381 * Track a mouse button press on the minimize or maximize box.
2383 * The big difference between 3.1 and 95 is the disabled button state.
2384 * In win95 the system button can be disabled, so it can ignore the mouse
2385 * event.
2388 static void NC_TrackMinMaxBox95( HWND hwnd, WORD wParam )
2390 MSG msg;
2391 POINT16 pt16;
2392 HDC hdc = GetWindowDC( hwnd );
2393 BOOL pressed = TRUE;
2394 UINT state;
2395 DWORD wndStyle = GetWindowLongA( hwnd, GWL_STYLE);
2396 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
2398 void (*paintButton)(HWND, HDC16, BOOL, BOOL);
2400 if (wParam == HTMINBUTTON)
2402 /* If the style is not present, do nothing */
2403 if (!(wndStyle & WS_MINIMIZEBOX))
2404 return;
2406 /* Check if the sysmenu item for minimize is there */
2407 state = GetMenuState(hSysMenu, SC_MINIMIZE, MF_BYCOMMAND);
2409 paintButton = &NC_DrawMinButton95;
2411 else
2413 /* If the style is not present, do nothing */
2414 if (!(wndStyle & WS_MAXIMIZEBOX))
2415 return;
2417 /* Check if the sysmenu item for maximize is there */
2418 state = GetMenuState(hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
2420 paintButton = &NC_DrawMaxButton95;
2423 SetCapture( hwnd );
2425 (*paintButton)( hwnd, hdc, TRUE, FALSE);
2429 BOOL oldstate = pressed;
2430 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2431 CONV_POINT32TO16( &msg.pt, &pt16 );
2433 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2434 if (pressed != oldstate)
2435 (*paintButton)( hwnd, hdc, pressed, FALSE);
2436 } while (msg.message != WM_LBUTTONUP);
2438 (*paintButton)( hwnd, hdc, FALSE, FALSE);
2440 ReleaseCapture();
2441 ReleaseDC( hwnd, hdc );
2443 /* If the item minimize or maximize of the sysmenu are not there */
2444 /* or if the style is not present, do nothing */
2445 if ((!pressed) || (state == 0xFFFFFFFF))
2446 return;
2448 if (wParam == HTMINBUTTON)
2449 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&pt16 );
2450 else
2451 SendMessage16( hwnd, WM_SYSCOMMAND,
2452 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, *(LONG*)&pt16 );
2455 /***********************************************************************
2456 * NC_TrackMinMaxBox
2458 * Track a mouse button press on the minimize or maximize box.
2460 static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
2462 MSG msg;
2463 POINT16 pt16;
2464 HDC hdc = GetWindowDC( hwnd );
2465 BOOL pressed = TRUE;
2466 void (*paintButton)(HWND, HDC16, BOOL);
2468 SetCapture( hwnd );
2470 if (wParam == HTMINBUTTON)
2471 paintButton = &NC_DrawMinButton;
2472 else
2473 paintButton = &NC_DrawMaxButton;
2475 (*paintButton)( hwnd, hdc, TRUE);
2479 BOOL oldstate = pressed;
2480 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2481 CONV_POINT32TO16( &msg.pt, &pt16 );
2483 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2484 if (pressed != oldstate)
2485 (*paintButton)( hwnd, hdc, pressed);
2486 } while (msg.message != WM_LBUTTONUP);
2488 (*paintButton)( hwnd, hdc, FALSE);
2490 ReleaseCapture();
2491 ReleaseDC( hwnd, hdc );
2493 if (!pressed) return;
2495 if (wParam == HTMINBUTTON)
2496 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&pt16 );
2497 else
2498 SendMessage16( hwnd, WM_SYSCOMMAND,
2499 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, *(LONG*)&pt16 );
2503 /***********************************************************************
2504 * NC_TrackCloseButton95
2506 * Track a mouse button press on the Win95 close button.
2508 static void
2509 NC_TrackCloseButton95 (HWND hwnd, WORD wParam)
2511 MSG msg;
2512 POINT16 pt16;
2513 HDC hdc;
2514 BOOL pressed = TRUE;
2515 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
2516 UINT state;
2518 if(hSysMenu == 0)
2519 return;
2521 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
2523 /* If the item close of the sysmenu is disabled or not there do nothing */
2524 if((state & MF_DISABLED) || (state & MF_GRAYED) || (state == 0xFFFFFFFF))
2525 return;
2527 hdc = GetWindowDC( hwnd );
2529 SetCapture( hwnd );
2531 NC_DrawCloseButton95 (hwnd, hdc, TRUE, FALSE);
2535 BOOL oldstate = pressed;
2536 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2537 CONV_POINT32TO16( &msg.pt, &pt16 );
2539 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2540 if (pressed != oldstate)
2541 NC_DrawCloseButton95 (hwnd, hdc, pressed, FALSE);
2542 } while (msg.message != WM_LBUTTONUP);
2544 NC_DrawCloseButton95 (hwnd, hdc, FALSE, FALSE);
2546 ReleaseCapture();
2547 ReleaseDC( hwnd, hdc );
2548 if (!pressed) return;
2550 SendMessage16( hwnd, WM_SYSCOMMAND, SC_CLOSE, *(LONG*)&pt16 );
2554 /***********************************************************************
2555 * NC_TrackScrollBar
2557 * Track a mouse button press on the horizontal or vertical scroll-bar.
2559 static void NC_TrackScrollBar( HWND hwnd, WPARAM wParam, POINT pt )
2561 MSG16 *msg;
2562 INT scrollbar;
2563 WND *wndPtr = WIN_FindWndPtr( hwnd );
2565 if ((wParam & 0xfff0) == SC_HSCROLL)
2567 if ((wParam & 0x0f) != HTHSCROLL) goto END;
2568 scrollbar = SB_HORZ;
2570 else /* SC_VSCROLL */
2572 if ((wParam & 0x0f) != HTVSCROLL) goto END;
2573 scrollbar = SB_VERT;
2576 if (!(msg = SEGPTR_NEW(MSG16))) goto END;
2577 pt.x -= wndPtr->rectWindow.left;
2578 pt.y -= wndPtr->rectWindow.top;
2579 SetCapture( hwnd );
2580 SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt );
2584 GetMessage16( SEGPTR_GET(msg), 0, 0, 0 );
2585 switch(msg->message)
2587 case WM_LBUTTONUP:
2588 case WM_MOUSEMOVE:
2589 case WM_SYSTIMER:
2590 pt.x = LOWORD(msg->lParam) + wndPtr->rectClient.left -
2591 wndPtr->rectWindow.left;
2592 pt.y = HIWORD(msg->lParam) + wndPtr->rectClient.top -
2593 wndPtr->rectWindow.top;
2594 SCROLL_HandleScrollEvent( hwnd, scrollbar, msg->message, pt );
2595 break;
2596 default:
2597 TranslateMessage16( msg );
2598 DispatchMessage16( msg );
2599 break;
2601 if (!IsWindow( hwnd ))
2603 ReleaseCapture();
2604 break;
2606 } while (msg->message != WM_LBUTTONUP);
2607 SEGPTR_FREE(msg);
2608 END:
2609 WIN_ReleaseWndPtr(wndPtr);
2612 /***********************************************************************
2613 * NC_HandleNCLButtonDown
2615 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2617 LONG NC_HandleNCLButtonDown( WND* pWnd, WPARAM16 wParam, LPARAM lParam )
2619 HWND hwnd = pWnd->hwndSelf;
2621 switch(wParam) /* Hit test */
2623 case HTCAPTION:
2624 hwnd = WIN_GetTopParent(hwnd);
2626 if( WINPOS_SetActiveWindow(hwnd, TRUE, TRUE) || (GetActiveWindow() == hwnd) )
2627 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
2628 break;
2630 case HTSYSMENU:
2631 if( pWnd->dwStyle & WS_SYSMENU )
2633 if( !(pWnd->dwStyle & WS_MINIMIZE) )
2635 HDC hDC = GetWindowDC(hwnd);
2636 if (TWEAK_WineLook == WIN31_LOOK)
2637 NC_DrawSysButton( hwnd, hDC, TRUE );
2638 else
2639 NC_DrawSysButton95( hwnd, hDC, TRUE );
2640 ReleaseDC( hwnd, hDC );
2642 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
2644 break;
2646 case HTMENU:
2647 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam );
2648 break;
2650 case HTHSCROLL:
2651 SendMessage16( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
2652 break;
2654 case HTVSCROLL:
2655 SendMessage16( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
2656 break;
2658 case HTMINBUTTON:
2659 case HTMAXBUTTON:
2660 if (TWEAK_WineLook == WIN31_LOOK)
2661 NC_TrackMinMaxBox( hwnd, wParam );
2662 else
2663 NC_TrackMinMaxBox95( hwnd, wParam );
2664 break;
2666 case HTCLOSE:
2667 if (TWEAK_WineLook >= WIN95_LOOK)
2668 NC_TrackCloseButton95 (hwnd, wParam);
2669 break;
2671 case HTLEFT:
2672 case HTRIGHT:
2673 case HTTOP:
2674 case HTTOPLEFT:
2675 case HTTOPRIGHT:
2676 case HTBOTTOM:
2677 case HTBOTTOMLEFT:
2678 case HTBOTTOMRIGHT:
2679 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2680 SendMessage16( hwnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam);
2681 break;
2683 case HTBORDER:
2684 break;
2686 return 0;
2690 /***********************************************************************
2691 * NC_HandleNCLButtonDblClk
2693 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2695 LONG NC_HandleNCLButtonDblClk( WND *pWnd, WPARAM16 wParam, LPARAM lParam )
2698 * if this is an icon, send a restore since we are handling
2699 * a double click
2701 if (pWnd->dwStyle & WS_MINIMIZE)
2703 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_RESTORE, lParam );
2704 return 0;
2707 switch(wParam) /* Hit test */
2709 case HTCAPTION:
2710 /* stop processing if WS_MAXIMIZEBOX is missing */
2711 if (pWnd->dwStyle & WS_MAXIMIZEBOX)
2712 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND,
2713 (pWnd->dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
2714 lParam );
2715 break;
2717 case HTSYSMENU:
2718 if (!(GetClassWord(pWnd->hwndSelf, GCW_STYLE) & CS_NOCLOSE))
2719 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, lParam );
2720 break;
2722 case HTHSCROLL:
2723 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL,
2724 lParam );
2725 break;
2727 case HTVSCROLL:
2728 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL,
2729 lParam );
2730 break;
2732 return 0;
2736 /***********************************************************************
2737 * NC_HandleSysCommand
2739 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2741 LONG NC_HandleSysCommand( HWND hwnd, WPARAM16 wParam, POINT16 pt )
2743 WND *wndPtr = WIN_FindWndPtr( hwnd );
2744 POINT pt32;
2745 UINT16 uCommand = wParam & 0xFFF0;
2747 TRACE("Handling WM_SYSCOMMAND %x %d,%d\n", wParam, pt.x, pt.y );
2749 if (wndPtr->dwStyle & WS_CHILD && uCommand != SC_KEYMENU )
2750 ScreenToClient16( wndPtr->parent->hwndSelf, &pt );
2752 switch (uCommand)
2754 case SC_SIZE:
2755 case SC_MOVE:
2756 NC_DoSizeMove( hwnd, wParam );
2757 break;
2759 case SC_MINIMIZE:
2760 if (hwnd == GetForegroundWindow())
2761 ShowOwnedPopups(hwnd,FALSE);
2762 ShowWindow( hwnd, SW_MINIMIZE );
2763 break;
2765 case SC_MAXIMIZE:
2766 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2767 ShowOwnedPopups(hwnd,TRUE);
2768 ShowWindow( hwnd, SW_MAXIMIZE );
2769 break;
2771 case SC_RESTORE:
2772 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2773 ShowOwnedPopups(hwnd,TRUE);
2774 ShowWindow( hwnd, SW_RESTORE );
2775 break;
2777 case SC_CLOSE:
2778 WIN_ReleaseWndPtr(wndPtr);
2779 return SendMessage16( hwnd, WM_CLOSE, 0, 0 );
2781 case SC_VSCROLL:
2782 case SC_HSCROLL:
2783 CONV_POINT16TO32( &pt, &pt32 );
2784 NC_TrackScrollBar( hwnd, wParam, pt32 );
2785 break;
2787 case SC_MOUSEMENU:
2788 CONV_POINT16TO32( &pt, &pt32 );
2789 MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt32 );
2790 break;
2792 case SC_KEYMENU:
2793 MENU_TrackKbdMenuBar( wndPtr , wParam , pt.x );
2794 break;
2796 case SC_TASKLIST:
2797 WinExec( "taskman.exe", SW_SHOWNORMAL );
2798 break;
2800 case SC_SCREENSAVE:
2801 if (wParam == SC_ABOUTWINE)
2803 HMODULE hmodule = LoadLibraryA( "shell32.dll" );
2804 if (hmodule)
2806 FARPROC aboutproc = GetProcAddress( hmodule, "ShellAboutA" );
2807 if (aboutproc) aboutproc( hwnd, "Wine", WINE_RELEASE_INFO, 0 );
2808 FreeLibrary( hmodule );
2811 else
2812 if (wParam == SC_PUTMARK)
2813 TRACE_(shell)("Mark requested by user\n");
2814 break;
2816 case SC_HOTKEY:
2817 case SC_ARRANGE:
2818 case SC_NEXTWINDOW:
2819 case SC_PREVWINDOW:
2820 FIXME("unimplemented!\n");
2821 break;
2823 WIN_ReleaseWndPtr(wndPtr);
2824 return 0;
2827 /*************************************************************
2828 * NC_DrawGrayButton
2830 * Stub for the grayed button of the caption
2832 *************************************************************/
2834 BOOL NC_DrawGrayButton(HDC hdc, int x, int y)
2836 HBITMAP hMaskBmp;
2837 HDC hdcMask = CreateCompatibleDC (0);
2838 HBRUSH hOldBrush;
2840 hMaskBmp = CreateBitmap (12, 10, 1, 1, lpGrayMask);
2842 if(hMaskBmp == 0)
2843 return FALSE;
2845 SelectObject (hdcMask, hMaskBmp);
2847 /* Draw the grayed bitmap using the mask */
2848 hOldBrush = SelectObject (hdc, RGB(128, 128, 128));
2849 BitBlt (hdc, x, y, 12, 10,
2850 hdcMask, 0, 0, 0xB8074A);
2852 /* Clean up */
2853 SelectObject (hdc, hOldBrush);
2854 DeleteObject(hMaskBmp);
2855 DeleteDC (hdcMask);
2857 return TRUE;