Removed @PROGEXT@ (it was broken anyway).
[wine.git] / windows / nonclient.c
blob8a7b6c53001952c2e14bef8b50dae7dc1fa96b39
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 WND* wndPtr = WIN_FindWndPtr(hwnd);
380 HICON hAppIcon = (HICON) NC_IconForWindow(wndPtr);
381 DrawIconEx (hdc, pt.x, pt.y, hAppIcon, GetSystemMetrics(SM_CXSMICON),
382 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
383 WIN_ReleaseWndPtr(wndPtr);
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 if (NC_IconForWindow(wndPtr))
874 rect.left += GetSystemMetrics(SM_CYCAPTION) - 1;
876 if (pt.x < rect.left) return HTSYSMENU;
878 /* Check close button */
879 if (wndPtr->dwStyle & WS_SYSMENU)
880 rect.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
881 if (pt.x > rect.right) return HTCLOSE;
883 /* Check maximize box */
884 /* In win95 there is automatically a Maximize button when there is a minimize one*/
885 if ((wndPtr->dwStyle & WS_MAXIMIZEBOX)|| (wndPtr->dwStyle & WS_MINIMIZEBOX))
886 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
887 if (pt.x > rect.right) return HTMAXBUTTON;
889 /* Check minimize box */
890 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
891 if ((wndPtr->dwStyle & WS_MINIMIZEBOX)||(wndPtr->dwStyle & WS_MAXIMIZEBOX))
892 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
894 if (pt.x > rect.right) return HTMINBUTTON;
895 return HTCAPTION;
900 /* Check client area */
902 ScreenToClient16( wndPtr->hwndSelf, &pt );
903 GetClientRect16( wndPtr->hwndSelf, &rect );
904 if (PtInRect16( &rect, pt )) return HTCLIENT;
906 /* Check vertical scroll bar */
908 if (wndPtr->dwStyle & WS_VSCROLL)
910 rect.right += GetSystemMetrics(SM_CXVSCROLL);
911 if (PtInRect16( &rect, pt )) return HTVSCROLL;
914 /* Check horizontal scroll bar */
916 if (wndPtr->dwStyle & WS_HSCROLL)
918 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
919 if (PtInRect16( &rect, pt ))
921 /* Check size box */
922 if ((wndPtr->dwStyle & WS_VSCROLL) &&
923 (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
924 return HTSIZE;
925 return HTHSCROLL;
929 /* Check menu bar */
931 if (HAS_MENU(wndPtr))
933 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
934 return HTMENU;
937 /* Should never get here */
938 return HTERROR;
942 /***********************************************************************
943 * NC_HandleNCHitTest
945 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
947 LONG
948 NC_HandleNCHitTest (HWND hwnd , POINT16 pt)
950 LONG retvalue;
951 WND *wndPtr = WIN_FindWndPtr (hwnd);
953 if (!wndPtr)
954 return HTERROR;
956 if (TWEAK_WineLook == WIN31_LOOK)
957 retvalue = NC_DoNCHitTest (wndPtr, pt);
958 else
959 retvalue = NC_DoNCHitTest95 (wndPtr, pt);
960 WIN_ReleaseWndPtr(wndPtr);
961 return retvalue;
965 /***********************************************************************
966 * NC_DrawSysButton
968 void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down )
970 RECT rect;
971 HDC hdcMem;
972 HBITMAP hbitmap;
973 WND *wndPtr = WIN_FindWndPtr( hwnd );
975 if( !(wndPtr->flags & WIN_MANAGED) )
977 NC_GetInsideRect( hwnd, &rect );
978 hdcMem = CreateCompatibleDC( hdc );
979 hbitmap = SelectObject( hdcMem, hbitmapClose );
980 BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE), GetSystemMetrics(SM_CYSIZE),
981 hdcMem, (wndPtr->dwStyle & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE) : 0, 0,
982 down ? NOTSRCCOPY : SRCCOPY );
983 SelectObject( hdcMem, hbitmap );
984 DeleteDC( hdcMem );
986 WIN_ReleaseWndPtr(wndPtr);
990 /***********************************************************************
991 * NC_DrawMaxButton
993 static void NC_DrawMaxButton( HWND hwnd, HDC16 hdc, BOOL down )
995 RECT rect;
996 WND *wndPtr = WIN_FindWndPtr( hwnd );
997 HDC hdcMem;
999 if( !(wndPtr->flags & WIN_MANAGED) )
1001 NC_GetInsideRect( hwnd, &rect );
1002 hdcMem = CreateCompatibleDC( hdc );
1003 SelectObject( hdcMem, (IsZoomed(hwnd)
1004 ? (down ? hbitmapRestoreD : hbitmapRestore)
1005 : (down ? hbitmapMaximizeD : hbitmapMaximize)) );
1006 BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
1007 GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
1008 SRCCOPY );
1009 DeleteDC( hdcMem );
1011 WIN_ReleaseWndPtr(wndPtr);
1016 /***********************************************************************
1017 * NC_DrawMinButton
1019 static void NC_DrawMinButton( HWND hwnd, HDC16 hdc, BOOL down )
1021 RECT rect;
1022 WND *wndPtr = WIN_FindWndPtr( hwnd );
1023 HDC hdcMem;
1025 if( !(wndPtr->flags & WIN_MANAGED) )
1027 NC_GetInsideRect( hwnd, &rect );
1028 hdcMem = CreateCompatibleDC( hdc );
1029 SelectObject( hdcMem, (down ? hbitmapMinimizeD : hbitmapMinimize) );
1030 if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= GetSystemMetrics(SM_CXSIZE)+1;
1031 BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
1032 GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
1033 SRCCOPY );
1034 DeleteDC( hdcMem );
1036 WIN_ReleaseWndPtr(wndPtr);
1040 /******************************************************************************
1042 * void NC_DrawSysButton95(
1043 * HWND hwnd,
1044 * HDC hdc,
1045 * BOOL down )
1047 * Draws the Win95 system icon.
1049 * Revision history
1050 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1051 * Original implementation from NC_DrawSysButton source.
1052 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1053 * Fixed most bugs.
1055 *****************************************************************************/
1057 BOOL
1058 NC_DrawSysButton95 (HWND hwnd, HDC hdc, BOOL down)
1060 WND *wndPtr = WIN_FindWndPtr( hwnd );
1062 if( !(wndPtr->flags & WIN_MANAGED) )
1064 HICON hIcon;
1065 RECT rect;
1067 NC_GetInsideRect95( hwnd, &rect );
1069 hIcon = NC_IconForWindow( wndPtr );
1071 if (hIcon)
1072 DrawIconEx (hdc, rect.left + 2, rect.top + 2, hIcon,
1073 GetSystemMetrics(SM_CXSMICON),
1074 GetSystemMetrics(SM_CYSMICON),
1075 0, 0, DI_NORMAL);
1077 WIN_ReleaseWndPtr(wndPtr);
1078 return (hIcon != 0);
1080 WIN_ReleaseWndPtr(wndPtr);
1081 return FALSE;
1085 /******************************************************************************
1087 * void NC_DrawCloseButton95(
1088 * HWND hwnd,
1089 * HDC hdc,
1090 * BOOL down,
1091 * BOOL bGrayed )
1093 * Draws the Win95 close button.
1095 * If bGrayed is true, then draw a disabled Close button
1097 * Revision history
1098 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1099 * Original implementation from NC_DrawSysButton95 source.
1101 *****************************************************************************/
1103 static void NC_DrawCloseButton95 (HWND hwnd, HDC hdc, BOOL down, BOOL bGrayed)
1105 RECT rect;
1106 HDC hdcMem;
1107 WND *wndPtr = WIN_FindWndPtr( hwnd );
1109 if( !(wndPtr->flags & WIN_MANAGED) )
1111 BITMAP bmp;
1112 HBITMAP hBmp, hOldBmp;
1114 NC_GetInsideRect95( hwnd, &rect );
1116 /* A tool window has a smaller Close button */
1117 if(wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
1119 RECT toolRect;
1120 INT iBmpHeight = 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
1121 INT iBmpWidth = 11; /* it uses 11x11 for the close button in tool window */
1122 INT iCaptionHeight = GetSystemMetrics(SM_CYSMCAPTION);
1124 toolRect.top = rect.top + (iCaptionHeight - 1 - iBmpHeight) / 2;
1125 toolRect.left = rect.right - (iCaptionHeight + 1 + iBmpWidth) / 2;
1126 toolRect.bottom = toolRect.top + iBmpHeight;
1127 toolRect.right = toolRect.left + iBmpWidth;
1128 DrawFrameControl(hdc,&toolRect,
1129 DFC_CAPTION,DFCS_CAPTIONCLOSE |
1130 down ? DFCS_PUSHED : 0 |
1131 bGrayed ? DFCS_INACTIVE : 0);
1133 else
1135 hdcMem = CreateCompatibleDC( hdc );
1136 hBmp = down ? hbitmapCloseD : hbitmapClose;
1137 hOldBmp = SelectObject (hdcMem, hBmp);
1138 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1140 BitBlt (hdc, rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2,
1141 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1142 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);
1144 if(bGrayed)
1145 NC_DrawGrayButton(hdc,rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2 + 2,
1146 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1148 SelectObject (hdcMem, hOldBmp);
1149 DeleteDC (hdcMem);
1152 WIN_ReleaseWndPtr(wndPtr);
1155 /******************************************************************************
1157 * NC_DrawMaxButton95(
1158 * HWND hwnd,
1159 * HDC16 hdc,
1160 * BOOL down
1161 * BOOL bGrayed )
1163 * Draws the maximize button for Win95 style windows.
1165 * If bGrayed is true, then draw a disabled Maximize button
1167 * Bugs
1168 * Many. Spacing might still be incorrect. Need to fit a close
1169 * button between the max button and the edge.
1170 * Should scale the image with the title bar. And more...
1172 * Revision history
1173 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1174 * Original implementation.
1176 *****************************************************************************/
1178 static void NC_DrawMaxButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
1180 RECT rect;
1181 HDC hdcMem;
1182 WND *wndPtr = WIN_FindWndPtr( hwnd );
1184 if( !(wndPtr->flags & WIN_MANAGED))
1186 BITMAP bmp;
1187 HBITMAP hBmp,hOldBmp;
1189 NC_GetInsideRect95( hwnd, &rect );
1190 hdcMem = CreateCompatibleDC( hdc );
1191 hBmp = IsZoomed(hwnd) ?
1192 (down ? hbitmapRestoreD : hbitmapRestore ) :
1193 (down ? hbitmapMaximizeD: hbitmapMaximize);
1194 hOldBmp=SelectObject( hdcMem, hBmp );
1195 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1197 if (wndPtr->dwStyle & WS_SYSMENU)
1198 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1200 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1201 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1202 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1204 if(bGrayed)
1205 NC_DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
1206 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1209 SelectObject (hdcMem, hOldBmp);
1210 DeleteDC( hdcMem );
1212 WIN_ReleaseWndPtr(wndPtr);
1215 /******************************************************************************
1217 * NC_DrawMinButton95(
1218 * HWND hwnd,
1219 * HDC16 hdc,
1220 * BOOL down,
1221 * BOOL bGrayed )
1223 * Draws the minimize button for Win95 style windows.
1225 * If bGrayed is true, then draw a disabled Minimize button
1227 * Bugs
1228 * Many. Spacing is still incorrect. Should scale the image with the
1229 * title bar. And more...
1231 * Revision history
1232 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1233 * Original implementation.
1235 *****************************************************************************/
1237 static void NC_DrawMinButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
1239 RECT rect;
1240 HDC hdcMem;
1241 WND *wndPtr = WIN_FindWndPtr( hwnd );
1243 if( !(wndPtr->flags & WIN_MANAGED))
1246 BITMAP bmp;
1247 HBITMAP hBmp,hOldBmp;
1249 NC_GetInsideRect95( hwnd, &rect );
1251 hdcMem = CreateCompatibleDC( hdc );
1252 hBmp = down ? hbitmapMinimizeD : hbitmapMinimize;
1253 hOldBmp= SelectObject( hdcMem, hBmp );
1254 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1256 if (wndPtr->dwStyle & WS_SYSMENU)
1257 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1259 /* In win 95 there is always a Maximize box when there is a Minimize one */
1260 if ((wndPtr->dwStyle & WS_MAXIMIZEBOX) || (wndPtr->dwStyle & WS_MINIMIZEBOX))
1261 rect.right += -1 - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2;
1263 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1264 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1265 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1267 if(bGrayed)
1268 NC_DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
1269 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1272 SelectObject (hdcMem, hOldBmp);
1273 DeleteDC( hdcMem );
1275 WIN_ReleaseWndPtr(wndPtr);
1278 /***********************************************************************
1279 * NC_DrawFrame
1281 * Draw a window frame inside the given rectangle, and update the rectangle.
1282 * The correct pen for the frame must be selected in the DC.
1284 static void NC_DrawFrame( HDC hdc, RECT *rect, BOOL dlgFrame,
1285 BOOL active )
1287 INT width, height;
1289 if (TWEAK_WineLook != WIN31_LOOK)
1290 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
1292 if (dlgFrame)
1294 width = GetSystemMetrics(SM_CXDLGFRAME) - 1;
1295 height = GetSystemMetrics(SM_CYDLGFRAME) - 1;
1296 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1297 COLOR_INACTIVECAPTION) );
1299 else
1301 width = GetSystemMetrics(SM_CXFRAME) - 2;
1302 height = GetSystemMetrics(SM_CYFRAME) - 2;
1303 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1304 COLOR_INACTIVEBORDER) );
1307 /* Draw frame */
1308 PatBlt( hdc, rect->left, rect->top,
1309 rect->right - rect->left, height, PATCOPY );
1310 PatBlt( hdc, rect->left, rect->top,
1311 width, rect->bottom - rect->top, PATCOPY );
1312 PatBlt( hdc, rect->left, rect->bottom - 1,
1313 rect->right - rect->left, -height, PATCOPY );
1314 PatBlt( hdc, rect->right - 1, rect->top,
1315 -width, rect->bottom - rect->top, PATCOPY );
1317 if (dlgFrame)
1319 InflateRect( rect, -width, -height );
1321 else
1323 INT decYOff = GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXSIZE) - 1;
1324 INT decXOff = GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYSIZE) - 1;
1326 /* Draw inner rectangle */
1328 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1329 Rectangle( hdc, rect->left + width, rect->top + height,
1330 rect->right - width , rect->bottom - height );
1332 /* Draw the decorations */
1334 MoveToEx( hdc, rect->left, rect->top + decYOff, NULL );
1335 LineTo( hdc, rect->left + width, rect->top + decYOff );
1336 MoveToEx( hdc, rect->right - 1, rect->top + decYOff, NULL );
1337 LineTo( hdc, rect->right - width - 1, rect->top + decYOff );
1338 MoveToEx( hdc, rect->left, rect->bottom - decYOff, NULL );
1339 LineTo( hdc, rect->left + width, rect->bottom - decYOff );
1340 MoveToEx( hdc, rect->right - 1, rect->bottom - decYOff, NULL );
1341 LineTo( hdc, rect->right - width - 1, rect->bottom - decYOff );
1343 MoveToEx( hdc, rect->left + decXOff, rect->top, NULL );
1344 LineTo( hdc, rect->left + decXOff, rect->top + height);
1345 MoveToEx( hdc, rect->left + decXOff, rect->bottom - 1, NULL );
1346 LineTo( hdc, rect->left + decXOff, rect->bottom - height - 1 );
1347 MoveToEx( hdc, rect->right - decXOff, rect->top, NULL );
1348 LineTo( hdc, rect->right - decXOff, rect->top + height );
1349 MoveToEx( hdc, rect->right - decXOff, rect->bottom - 1, NULL );
1350 LineTo( hdc, rect->right - decXOff, rect->bottom - height - 1 );
1352 InflateRect( rect, -width - 1, -height - 1 );
1357 /******************************************************************************
1359 * void NC_DrawFrame95(
1360 * HDC hdc,
1361 * RECT *rect,
1362 * BOOL dlgFrame,
1363 * BOOL active )
1365 * Draw a window frame inside the given rectangle, and update the rectangle.
1366 * The correct pen for the frame must be selected in the DC.
1368 * Bugs
1369 * Many. First, just what IS a frame in Win95? Note that the 3D look
1370 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1371 * edge. The inner rectangle just inside the frame is handled by the
1372 * Caption code.
1374 * In short, for most people, this function should be a nop (unless
1375 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1376 * them lately, but just to get this code right). Even so, it doesn't
1377 * appear to be so. It's being worked on...
1379 * Revision history
1380 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1381 * Original implementation (based on NC_DrawFrame)
1382 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1383 * Some minor fixes.
1384 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1385 * Fixed a fix or something.
1387 *****************************************************************************/
1389 static void NC_DrawFrame95(
1390 HDC hdc,
1391 RECT *rect,
1392 BOOL dlgFrame,
1393 BOOL active )
1395 INT width, height;
1397 if (dlgFrame)
1399 width = GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
1400 height = GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
1402 else
1404 width = GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXEDGE);
1405 height = GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYEDGE);
1408 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1409 COLOR_INACTIVEBORDER) );
1411 /* Draw frame */
1412 PatBlt( hdc, rect->left, rect->top,
1413 rect->right - rect->left, height, PATCOPY );
1414 PatBlt( hdc, rect->left, rect->top,
1415 width, rect->bottom - rect->top, PATCOPY );
1416 PatBlt( hdc, rect->left, rect->bottom - 1,
1417 rect->right - rect->left, -height, PATCOPY );
1418 PatBlt( hdc, rect->right - 1, rect->top,
1419 -width, rect->bottom - rect->top, PATCOPY );
1421 InflateRect( rect, -width, -height );
1424 /***********************************************************************
1425 * NC_DrawMovingFrame
1427 * Draw the frame used when moving or resizing window.
1429 * FIXME: This causes problems in Win95 mode. (why?)
1431 static void NC_DrawMovingFrame( HDC hdc, RECT *rect, BOOL thickframe )
1433 if (thickframe)
1435 RECT16 r16;
1436 CONV_RECT32TO16( rect, &r16 );
1437 FastWindowFrame16( hdc, &r16, GetSystemMetrics(SM_CXFRAME),
1438 GetSystemMetrics(SM_CYFRAME), PATINVERT );
1440 else DrawFocusRect( hdc, rect );
1444 /***********************************************************************
1445 * NC_DrawCaption
1447 * Draw the window caption.
1448 * The correct pen for the window frame must be selected in the DC.
1450 static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd,
1451 DWORD style, BOOL active )
1453 RECT r = *rect;
1454 WND * wndPtr = WIN_FindWndPtr( hwnd );
1455 char buffer[256];
1457 if (wndPtr->flags & WIN_MANAGED)
1459 WIN_ReleaseWndPtr(wndPtr);
1460 return;
1463 if (!hbitmapClose)
1465 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1467 WIN_ReleaseWndPtr(wndPtr);
1468 return;
1470 hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED) );
1471 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1472 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1473 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1474 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1475 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1476 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1479 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
1481 HBRUSH hbrushOld = SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW) );
1482 PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
1483 PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
1484 PatBlt( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
1485 r.left++;
1486 r.right--;
1487 SelectObject( hdc, hbrushOld );
1489 WIN_ReleaseWndPtr(wndPtr);
1490 MoveTo16( hdc, r.left, r.bottom );
1491 LineTo( hdc, r.right, r.bottom );
1493 if (style & WS_SYSMENU)
1495 NC_DrawSysButton( hwnd, hdc, FALSE );
1496 r.left += GetSystemMetrics(SM_CXSIZE) + 1;
1497 MoveTo16( hdc, r.left - 1, r.top );
1498 LineTo( hdc, r.left - 1, r.bottom );
1500 if (style & WS_MAXIMIZEBOX)
1502 NC_DrawMaxButton( hwnd, hdc, FALSE );
1503 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1505 if (style & WS_MINIMIZEBOX)
1507 NC_DrawMinButton( hwnd, hdc, FALSE );
1508 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1511 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1512 COLOR_INACTIVECAPTION) );
1514 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) ))
1516 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1517 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1518 SetBkMode( hdc, TRANSPARENT );
1519 DrawTextA( hdc, buffer, -1, &r,
1520 DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );
1525 /******************************************************************************
1527 * NC_DrawCaption95(
1528 * HDC hdc,
1529 * RECT *rect,
1530 * HWND hwnd,
1531 * DWORD style,
1532 * BOOL active )
1534 * Draw the window caption for Win95 style windows.
1535 * The correct pen for the window frame must be selected in the DC.
1537 * Bugs
1538 * Hey, a function that finally works! Well, almost.
1539 * It's being worked on.
1541 * Revision history
1542 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1543 * Original implementation.
1544 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1545 * Some minor fixes.
1547 *****************************************************************************/
1549 static void NC_DrawCaption95(
1550 HDC hdc,
1551 RECT *rect,
1552 HWND hwnd,
1553 DWORD style,
1554 DWORD exStyle,
1555 BOOL active )
1557 RECT r = *rect;
1558 WND *wndPtr = WIN_FindWndPtr( hwnd );
1559 char buffer[256];
1560 HPEN hPrevPen;
1561 HMENU hSysMenu;
1563 if (wndPtr->flags & WIN_MANAGED)
1565 WIN_ReleaseWndPtr(wndPtr);
1566 return;
1568 WIN_ReleaseWndPtr(wndPtr);
1570 hPrevPen = SelectObject( hdc, GetSysColorPen(COLOR_3DFACE) );
1571 MoveToEx( hdc, r.left, r.bottom - 1, NULL );
1572 LineTo( hdc, r.right, r.bottom - 1 );
1573 SelectObject( hdc, hPrevPen );
1574 r.bottom--;
1576 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1577 COLOR_INACTIVECAPTION) );
1579 if (!hbitmapClose) {
1580 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1581 return;
1582 hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED));
1583 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1584 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1585 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1586 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1587 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1588 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1591 if ((style & WS_SYSMENU) && !(exStyle & WS_EX_TOOLWINDOW)) {
1592 if (NC_DrawSysButton95 (hwnd, hdc, FALSE))
1593 r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
1596 if (style & WS_SYSMENU)
1598 UINT state;
1600 /* Go get the sysmenu */
1601 hSysMenu = GetSystemMenu(hwnd, FALSE);
1602 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
1604 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1605 NC_DrawCloseButton95 (hwnd, hdc, FALSE,
1606 ((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
1607 r.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
1609 if ((style & WS_MAXIMIZEBOX) || (style & WS_MINIMIZEBOX))
1611 /* In win95 the two buttons are always there */
1612 /* But if the menu item is not in the menu they're disabled*/
1614 NC_DrawMaxButton95( hwnd, hdc, FALSE, (!(style & WS_MAXIMIZEBOX)));
1615 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1617 NC_DrawMinButton95( hwnd, hdc, FALSE, (!(style & WS_MINIMIZEBOX)));
1618 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1622 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) )) {
1623 NONCLIENTMETRICSA nclm;
1624 HFONT hFont, hOldFont;
1625 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1626 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1627 if (exStyle & WS_EX_TOOLWINDOW)
1628 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
1629 else
1630 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
1631 hOldFont = SelectObject (hdc, hFont);
1632 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1633 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1634 SetBkMode( hdc, TRANSPARENT );
1635 r.left += 2;
1636 DrawTextA( hdc, buffer, -1, &r,
1637 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
1638 DeleteObject (SelectObject (hdc, hOldFont));
1644 /***********************************************************************
1645 * NC_DoNCPaint
1647 * Paint the non-client area. clip is currently unused.
1649 static void NC_DoNCPaint( WND* wndPtr, HRGN clip, BOOL suppress_menupaint )
1651 HDC hdc;
1652 RECT rect;
1653 BOOL active;
1654 HWND hwnd = wndPtr->hwndSelf;
1656 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1657 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1659 active = wndPtr->flags & WIN_NCACTIVATED;
1661 TRACE("%04x %d\n", hwnd, active );
1663 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1664 ((clip > 1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN): 0) ))) return;
1666 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1667 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1668 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1669 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1670 == NULLREGION)
1672 ReleaseDC( hwnd, hdc );
1673 return;
1676 rect.top = rect.left = 0;
1677 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1678 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1680 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1682 if (!(wndPtr->flags & WIN_MANAGED))
1684 if (HAS_ANYFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1686 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1687 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1688 InflateRect( &rect, -1, -1 );
1691 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1692 NC_DrawFrame(hdc, &rect, FALSE, active );
1693 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1694 NC_DrawFrame( hdc, &rect, TRUE, active );
1696 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1698 RECT r = rect;
1699 r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
1700 rect.top += GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYBORDER);
1701 NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active );
1705 if (HAS_MENU(wndPtr))
1707 RECT r = rect;
1708 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU); /* default height */
1709 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint );
1712 /* Draw the scroll-bars */
1714 if (wndPtr->dwStyle & WS_VSCROLL)
1715 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1716 if (wndPtr->dwStyle & WS_HSCROLL)
1717 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1719 /* Draw the "size-box" */
1721 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1723 RECT r = rect;
1724 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1725 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1726 if(wndPtr->dwStyle & WS_BORDER) {
1727 r.left++;
1728 r.top++;
1730 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1733 ReleaseDC( hwnd, hdc );
1737 /******************************************************************************
1739 * void NC_DoNCPaint95(
1740 * WND *wndPtr,
1741 * HRGN clip,
1742 * BOOL suppress_menupaint )
1744 * Paint the non-client area for Win95 windows. The clip region is
1745 * currently ignored.
1747 * Bugs
1748 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1749 * misc/tweak.c controls/menu.c # :-)
1751 * Revision history
1752 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1753 * Original implementation
1754 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1755 * Fixed some bugs.
1756 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1757 * Streamlined window style checks.
1759 *****************************************************************************/
1761 static void NC_DoNCPaint95(
1762 WND *wndPtr,
1763 HRGN clip,
1764 BOOL suppress_menupaint )
1766 HDC hdc;
1767 RECT rfuzz, rect, rectClip;
1768 BOOL active;
1769 HWND hwnd = wndPtr->hwndSelf;
1771 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1772 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1774 active = wndPtr->flags & WIN_NCACTIVATED;
1776 TRACE("%04x %d\n", hwnd, active );
1778 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1779 the call to GetDCEx implying that it is allowed not to use it either.
1780 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1781 will cause clipRgn to be deleted after ReleaseDC().
1782 Now, how is the "system" supposed to tell what happened?
1785 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1786 ((clip > 1) ?(DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0) ))) return;
1789 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1790 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1791 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1792 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1793 == NULLREGION)
1795 ReleaseDC( hwnd, hdc );
1796 return;
1799 rect.top = rect.left = 0;
1800 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1801 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1803 if( clip > 1 )
1804 GetRgnBox( clip, &rectClip );
1805 else
1807 clip = 0;
1808 rectClip = rect;
1811 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1813 if(!(wndPtr->flags & WIN_MANAGED)) {
1814 if (HAS_BIGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle)) {
1815 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1817 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1818 NC_DrawFrame95(hdc, &rect, FALSE, active );
1819 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1820 NC_DrawFrame95( hdc, &rect, TRUE, active );
1821 else if (HAS_THINFRAME( wndPtr->dwStyle )) {
1822 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1823 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1826 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1828 RECT r = rect;
1829 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW) {
1830 r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
1831 rect.top += GetSystemMetrics(SM_CYSMCAPTION);
1833 else {
1834 r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
1835 rect.top += GetSystemMetrics(SM_CYCAPTION);
1837 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
1838 NC_DrawCaption95 (hdc, &r, hwnd, wndPtr->dwStyle,
1839 wndPtr->dwExStyle, active);
1843 if (HAS_MENU(wndPtr))
1845 RECT r = rect;
1846 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
1848 TRACE("Calling DrawMenuBar with rect (%d, %d)-(%d, %d)\n",
1849 r.left, r.top, r.right, r.bottom);
1851 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ) + 1;
1854 TRACE("After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1855 rect.left, rect.top, rect.right, rect.bottom );
1857 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
1858 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1860 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
1861 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1863 /* Draw the scroll-bars */
1865 if (wndPtr->dwStyle & WS_VSCROLL)
1866 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1867 if (wndPtr->dwStyle & WS_HSCROLL)
1868 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1870 /* Draw the "size-box" */
1871 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1873 RECT r = rect;
1874 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1875 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1876 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1879 ReleaseDC( hwnd, hdc );
1885 /***********************************************************************
1886 * NC_HandleNCPaint
1888 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1890 LONG NC_HandleNCPaint( HWND hwnd , HRGN clip)
1892 WND* wndPtr = WIN_FindWndPtr( hwnd );
1894 if( wndPtr && wndPtr->dwStyle & WS_VISIBLE )
1896 if( wndPtr->dwStyle & WS_MINIMIZE )
1897 WINPOS_RedrawIconTitle( hwnd );
1898 else if (TWEAK_WineLook == WIN31_LOOK)
1899 NC_DoNCPaint( wndPtr, clip, FALSE );
1900 else
1901 NC_DoNCPaint95( wndPtr, clip, FALSE );
1903 WIN_ReleaseWndPtr(wndPtr);
1904 return 0;
1908 /***********************************************************************
1909 * NC_HandleNCActivate
1911 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1913 LONG NC_HandleNCActivate( WND *wndPtr, WPARAM16 wParam )
1915 WORD wStateChange;
1917 if( wParam ) wStateChange = !(wndPtr->flags & WIN_NCACTIVATED);
1918 else wStateChange = wndPtr->flags & WIN_NCACTIVATED;
1920 if( wStateChange )
1922 if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
1923 else wndPtr->flags &= ~WIN_NCACTIVATED;
1925 if( wndPtr->dwStyle & WS_MINIMIZE )
1926 WINPOS_RedrawIconTitle( wndPtr->hwndSelf );
1927 else if (TWEAK_WineLook == WIN31_LOOK)
1928 NC_DoNCPaint( wndPtr, (HRGN)1, FALSE );
1929 else
1930 NC_DoNCPaint95( wndPtr, (HRGN)1, FALSE );
1932 return TRUE;
1936 /***********************************************************************
1937 * NC_HandleSetCursor
1939 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1941 LONG NC_HandleSetCursor( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
1943 if (hwnd != (HWND)wParam) return 0; /* Don't set the cursor for child windows */
1945 switch(LOWORD(lParam))
1947 case HTERROR:
1949 WORD msg = HIWORD( lParam );
1950 if ((msg == WM_LBUTTONDOWN) || (msg == WM_MBUTTONDOWN) ||
1951 (msg == WM_RBUTTONDOWN))
1952 MessageBeep(0);
1954 break;
1956 case HTCLIENT:
1958 HICON16 hCursor = (HICON16) GetClassWord(hwnd, GCW_HCURSOR);
1959 if(hCursor) {
1960 SetCursor16(hCursor);
1961 return TRUE;
1963 return FALSE;
1966 case HTLEFT:
1967 case HTRIGHT:
1968 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZEWE16 ) );
1970 case HTTOP:
1971 case HTBOTTOM:
1972 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENS16 ) );
1974 case HTTOPLEFT:
1975 case HTBOTTOMRIGHT:
1976 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENWSE16 ) );
1978 case HTTOPRIGHT:
1979 case HTBOTTOMLEFT:
1980 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENESW16 ) );
1983 /* Default cursor: arrow */
1984 return (LONG)SetCursor16( LoadCursor16( 0, IDC_ARROW16 ) );
1987 /***********************************************************************
1988 * NC_GetSysPopupPos
1990 BOOL NC_GetSysPopupPos( WND* wndPtr, RECT* rect )
1992 if( wndPtr->hSysMenu )
1994 if( wndPtr->dwStyle & WS_MINIMIZE )
1995 GetWindowRect( wndPtr->hwndSelf, rect );
1996 else
1998 if (TWEAK_WineLook == WIN31_LOOK)
1999 NC_GetInsideRect( wndPtr->hwndSelf, rect );
2000 else
2001 NC_GetInsideRect95( wndPtr->hwndSelf, rect );
2002 OffsetRect( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
2003 if (wndPtr->dwStyle & WS_CHILD)
2004 ClientToScreen( wndPtr->parent->hwndSelf, (POINT *)rect );
2005 if (TWEAK_WineLook == WIN31_LOOK) {
2006 rect->right = rect->left + GetSystemMetrics(SM_CXSIZE);
2007 rect->bottom = rect->top + GetSystemMetrics(SM_CYSIZE);
2009 else {
2010 rect->right = rect->left + GetSystemMetrics(SM_CYCAPTION) - 1;
2011 rect->bottom = rect->top + GetSystemMetrics(SM_CYCAPTION) - 1;
2014 return TRUE;
2016 return FALSE;
2019 /***********************************************************************
2020 * NC_StartSizeMove
2022 * Initialisation of a move or resize, when initiatied from a menu choice.
2023 * Return hit test code for caption or sizing border.
2025 static LONG NC_StartSizeMove( WND* wndPtr, WPARAM16 wParam,
2026 POINT16 *capturePoint )
2028 LONG hittest = 0;
2029 POINT16 pt;
2030 MSG msg;
2031 RECT rectWindow;
2033 GetWindowRect(wndPtr->hwndSelf,&rectWindow);
2035 if ((wParam & 0xfff0) == SC_MOVE)
2037 /* Move pointer at the center of the caption */
2038 RECT rect;
2039 if (TWEAK_WineLook == WIN31_LOOK)
2040 NC_GetInsideRect( wndPtr->hwndSelf, &rect );
2041 else
2042 NC_GetInsideRect95( wndPtr->hwndSelf, &rect );
2043 if (wndPtr->dwStyle & WS_SYSMENU)
2044 rect.left += GetSystemMetrics(SM_CXSIZE) + 1;
2045 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
2046 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
2047 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
2048 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
2049 pt.x = rectWindow.left + (rect.right - rect.left) / 2;
2050 pt.y = rectWindow.top + rect.top + GetSystemMetrics(SM_CYSIZE)/2;
2051 hittest = HTCAPTION;
2052 *capturePoint = pt;
2054 else /* SC_SIZE */
2056 while(!hittest)
2058 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE, NULL );
2059 switch(msg.message)
2061 case WM_MOUSEMOVE:
2062 CONV_POINT32TO16(&msg.pt, &pt);
2063 hittest = NC_HandleNCHitTest( wndPtr->hwndSelf, pt );
2064 if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
2065 hittest = 0;
2066 break;
2068 case WM_LBUTTONUP:
2069 return 0;
2071 case WM_KEYDOWN:
2072 switch(msg.wParam)
2074 case VK_UP:
2075 hittest = HTTOP;
2076 pt.x =(rectWindow.left+rectWindow.right)/2;
2077 pt.y = rectWindow.top + GetSystemMetrics(SM_CYFRAME) / 2;
2078 break;
2079 case VK_DOWN:
2080 hittest = HTBOTTOM;
2081 pt.x =(rectWindow.left+rectWindow.right)/2;
2082 pt.y = rectWindow.bottom - GetSystemMetrics(SM_CYFRAME) / 2;
2083 break;
2084 case VK_LEFT:
2085 hittest = HTLEFT;
2086 pt.x = rectWindow.left + GetSystemMetrics(SM_CXFRAME) / 2;
2087 pt.y =(rectWindow.top+rectWindow.bottom)/2;
2088 break;
2089 case VK_RIGHT:
2090 hittest = HTRIGHT;
2091 pt.x = rectWindow.right - GetSystemMetrics(SM_CXFRAME) / 2;
2092 pt.y =(rectWindow.top+rectWindow.bottom)/2;
2093 break;
2094 case VK_RETURN:
2095 case VK_ESCAPE: return 0;
2099 *capturePoint = pt;
2101 SetCursorPos( pt.x, pt.y );
2102 NC_HandleSetCursor( wndPtr->hwndSelf,
2103 wndPtr->hwndSelf, MAKELONG( hittest, WM_MOUSEMOVE ));
2104 return hittest;
2108 /***********************************************************************
2109 * NC_DoSizeMove
2111 * Perform SC_MOVE and SC_SIZE commands. `
2113 static void NC_DoSizeMove( HWND hwnd, WORD wParam )
2115 MSG msg;
2116 RECT sizingRect, mouseRect;
2117 HDC hdc;
2118 LONG hittest = (LONG)(wParam & 0x0f);
2119 HCURSOR16 hDragCursor = 0, hOldCursor = 0;
2120 POINT minTrack, maxTrack;
2121 POINT16 capturePoint, pt;
2122 WND * wndPtr = WIN_FindWndPtr( hwnd );
2123 BOOL thickframe = HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle );
2124 BOOL iconic = wndPtr->dwStyle & WS_MINIMIZE;
2125 BOOL moved = FALSE;
2126 DWORD dwPoint = GetMessagePos ();
2128 capturePoint = pt = *(POINT16*)&dwPoint;
2130 if (IsZoomed(hwnd) || !IsWindowVisible(hwnd) ||
2131 (wndPtr->flags & WIN_MANAGED)) goto END;
2133 if ((wParam & 0xfff0) == SC_MOVE)
2135 if (!(wndPtr->dwStyle & WS_CAPTION)) goto END;
2136 if (!hittest)
2137 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2138 if (!hittest) goto END;
2140 else /* SC_SIZE */
2142 if (!thickframe) goto END;
2143 if ( hittest && hittest != HTSYSMENU ) hittest += 2;
2144 else
2146 SetCapture(hwnd);
2147 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2148 if (!hittest)
2150 ReleaseCapture();
2151 goto END;
2156 /* Get min/max info */
2158 WINPOS_GetMinMaxInfo( wndPtr, NULL, NULL, &minTrack, &maxTrack );
2159 sizingRect = wndPtr->rectWindow;
2160 if (wndPtr->dwStyle & WS_CHILD)
2161 GetClientRect( wndPtr->parent->hwndSelf, &mouseRect );
2162 else
2163 SetRect(&mouseRect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
2164 if (ON_LEFT_BORDER(hittest))
2166 mouseRect.left = max( mouseRect.left, sizingRect.right-maxTrack.x );
2167 mouseRect.right = min( mouseRect.right, sizingRect.right-minTrack.x );
2169 else if (ON_RIGHT_BORDER(hittest))
2171 mouseRect.left = max( mouseRect.left, sizingRect.left+minTrack.x );
2172 mouseRect.right = min( mouseRect.right, sizingRect.left+maxTrack.x );
2174 if (ON_TOP_BORDER(hittest))
2176 mouseRect.top = max( mouseRect.top, sizingRect.bottom-maxTrack.y );
2177 mouseRect.bottom = min( mouseRect.bottom,sizingRect.bottom-minTrack.y);
2179 else if (ON_BOTTOM_BORDER(hittest))
2181 mouseRect.top = max( mouseRect.top, sizingRect.top+minTrack.y );
2182 mouseRect.bottom = min( mouseRect.bottom, sizingRect.top+maxTrack.y );
2184 if (wndPtr->dwStyle & WS_CHILD)
2186 MapWindowPoints( wndPtr->parent->hwndSelf, 0,
2187 (LPPOINT)&mouseRect, 2 );
2189 SendMessage16( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
2191 if (GetCapture() != hwnd) SetCapture( hwnd );
2193 if (wndPtr->dwStyle & WS_CHILD)
2195 /* Retrieve a default cache DC (without using the window style) */
2196 hdc = GetDCEx( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
2198 else
2199 { /* Grab the server only when moving top-level windows without desktop */
2200 hdc = GetDC( 0 );
2203 wndPtr->pDriver->pPreSizeMove(wndPtr);
2205 if( iconic ) /* create a cursor for dragging */
2207 HICON16 hIcon = GetClassWord(wndPtr->hwndSelf, GCW_HICON);
2208 if(!hIcon) hIcon = (HICON16) SendMessage16( hwnd, WM_QUERYDRAGICON, 0, 0L);
2209 if( hIcon ) hDragCursor = CURSORICON_IconToCursor( hIcon, TRUE );
2210 if( !hDragCursor ) iconic = FALSE;
2213 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
2214 if( !iconic && TWEAK_WineLook == WIN31_LOOK )
2215 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2217 while(1)
2219 int dx = 0, dy = 0;
2221 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE, NULL );
2223 /* Exit on button-up, Return, or Esc */
2224 if ((msg.message == WM_LBUTTONUP) ||
2225 ((msg.message == WM_KEYDOWN) &&
2226 ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
2228 if (msg.message == WM_PAINT)
2230 if(!iconic) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2231 UpdateWindow( msg.hwnd );
2232 if(!iconic) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2233 continue;
2235 if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
2236 continue; /* We are not interested in other messages */
2238 dwPoint = GetMessagePos ();
2239 pt = *(POINT16*)&dwPoint;
2241 if (msg.message == WM_KEYDOWN) switch(msg.wParam)
2243 case VK_UP: pt.y -= 8; break;
2244 case VK_DOWN: pt.y += 8; break;
2245 case VK_LEFT: pt.x -= 8; break;
2246 case VK_RIGHT: pt.x += 8; break;
2249 pt.x = max( pt.x, mouseRect.left );
2250 pt.x = min( pt.x, mouseRect.right );
2251 pt.y = max( pt.y, mouseRect.top );
2252 pt.y = min( pt.y, mouseRect.bottom );
2254 dx = pt.x - capturePoint.x;
2255 dy = pt.y - capturePoint.y;
2257 if (dx || dy)
2259 if( !moved )
2261 moved = TRUE;
2263 if( iconic ) /* ok, no system popup tracking */
2265 hOldCursor = SetCursor(hDragCursor);
2266 ShowCursor( TRUE );
2267 WINPOS_ShowIconTitle( wndPtr, FALSE );
2268 } else if(TWEAK_WineLook != WIN31_LOOK)
2270 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2274 if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
2275 else
2277 RECT newRect = sizingRect;
2278 WPARAM wpSizingHit = 0;
2280 if (hittest == HTCAPTION) OffsetRect( &newRect, dx, dy );
2281 if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
2282 else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
2283 if (ON_TOP_BORDER(hittest)) newRect.top += dy;
2284 else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
2285 if(!iconic) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2286 capturePoint = pt;
2288 /* determine the hit location */
2289 if (hittest >= HTLEFT && hittest <= HTBOTTOMRIGHT)
2290 wpSizingHit = WMSZ_LEFT + (hittest - HTLEFT);
2291 SendMessageA( hwnd, WM_SIZING, wpSizingHit, (LPARAM)&newRect );
2293 if (!iconic) NC_DrawMovingFrame( hdc, &newRect, thickframe );
2294 sizingRect = newRect;
2299 ReleaseCapture();
2300 if( iconic )
2302 if( moved ) /* restore cursors, show icon title later on */
2304 ShowCursor( FALSE );
2305 SetCursor( hOldCursor );
2307 DestroyCursor( hDragCursor );
2309 else if(moved || TWEAK_WineLook == WIN31_LOOK)
2310 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2312 if (wndPtr->dwStyle & WS_CHILD)
2313 ReleaseDC( wndPtr->parent->hwndSelf, hdc );
2314 else
2315 ReleaseDC( 0, hdc );
2317 wndPtr->pDriver->pPostSizeMove(wndPtr);
2319 if (HOOK_IsHooked( WH_CBT ))
2321 RECT16* pr = SEGPTR_NEW(RECT16);
2322 if( pr )
2324 CONV_RECT32TO16( &sizingRect, pr );
2325 if( HOOK_CallHooks16( WH_CBT, HCBT_MOVESIZE, hwnd,
2326 (LPARAM)SEGPTR_GET(pr)) )
2327 sizingRect = wndPtr->rectWindow;
2328 else
2329 CONV_RECT16TO32( pr, &sizingRect );
2330 SEGPTR_FREE(pr);
2333 SendMessage16( hwnd, WM_EXITSIZEMOVE, 0, 0 );
2334 SendMessage16( hwnd, WM_SETVISIBLE, !IsIconic16(hwnd), 0L);
2336 /* window moved or resized */
2337 if (moved)
2339 /* if the moving/resizing isn't canceled call SetWindowPos
2340 * with the new position or the new size of the window
2342 if (!((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
2344 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
2345 SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top,
2346 sizingRect.right - sizingRect.left,
2347 sizingRect.bottom - sizingRect.top,
2348 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
2352 if( IsWindow(hwnd) )
2353 if( wndPtr->dwStyle & WS_MINIMIZE )
2355 /* Single click brings up the system menu when iconized */
2357 if( !moved )
2359 if( wndPtr->dwStyle & WS_SYSMENU )
2360 SendMessage16( hwnd, WM_SYSCOMMAND,
2361 SC_MOUSEMENU + HTSYSMENU, *((LPARAM*)&pt));
2363 else WINPOS_ShowIconTitle( wndPtr, TRUE );
2366 END:
2367 WIN_ReleaseWndPtr(wndPtr);
2371 /***********************************************************************
2372 * NC_TrackMinMaxBox95
2374 * Track a mouse button press on the minimize or maximize box.
2376 * The big difference between 3.1 and 95 is the disabled button state.
2377 * In win95 the system button can be disabled, so it can ignore the mouse
2378 * event.
2381 static void NC_TrackMinMaxBox95( HWND hwnd, WORD wParam )
2383 MSG msg;
2384 POINT16 pt16;
2385 HDC hdc = GetWindowDC( hwnd );
2386 BOOL pressed = TRUE;
2387 UINT state;
2388 DWORD wndStyle = GetWindowLongA( hwnd, GWL_STYLE);
2389 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
2391 void (*paintButton)(HWND, HDC16, BOOL, BOOL);
2393 if (wParam == HTMINBUTTON)
2395 /* If the style is not present, do nothing */
2396 if (!(wndStyle & WS_MINIMIZEBOX))
2397 return;
2399 /* Check if the sysmenu item for minimize is there */
2400 state = GetMenuState(hSysMenu, SC_MINIMIZE, MF_BYCOMMAND);
2402 paintButton = &NC_DrawMinButton95;
2404 else
2406 /* If the style is not present, do nothing */
2407 if (!(wndStyle & WS_MAXIMIZEBOX))
2408 return;
2410 /* Check if the sysmenu item for maximize is there */
2411 state = GetMenuState(hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
2413 paintButton = &NC_DrawMaxButton95;
2416 SetCapture( hwnd );
2418 (*paintButton)( hwnd, hdc, TRUE, FALSE);
2422 BOOL oldstate = pressed;
2423 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2424 CONV_POINT32TO16( &msg.pt, &pt16 );
2426 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2427 if (pressed != oldstate)
2428 (*paintButton)( hwnd, hdc, pressed, FALSE);
2429 } while (msg.message != WM_LBUTTONUP);
2431 (*paintButton)( hwnd, hdc, FALSE, FALSE);
2433 ReleaseCapture();
2434 ReleaseDC( hwnd, hdc );
2436 /* If the item minimize or maximize of the sysmenu are not there */
2437 /* or if the style is not present, do nothing */
2438 if ((!pressed) || (state == 0xFFFFFFFF))
2439 return;
2441 if (wParam == HTMINBUTTON)
2442 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&pt16 );
2443 else
2444 SendMessage16( hwnd, WM_SYSCOMMAND,
2445 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, *(LONG*)&pt16 );
2448 /***********************************************************************
2449 * NC_TrackMinMaxBox
2451 * Track a mouse button press on the minimize or maximize box.
2453 static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
2455 MSG msg;
2456 POINT16 pt16;
2457 HDC hdc = GetWindowDC( hwnd );
2458 BOOL pressed = TRUE;
2459 void (*paintButton)(HWND, HDC16, BOOL);
2461 SetCapture( hwnd );
2463 if (wParam == HTMINBUTTON)
2464 paintButton = &NC_DrawMinButton;
2465 else
2466 paintButton = &NC_DrawMaxButton;
2468 (*paintButton)( hwnd, hdc, TRUE);
2472 BOOL oldstate = pressed;
2473 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2474 CONV_POINT32TO16( &msg.pt, &pt16 );
2476 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2477 if (pressed != oldstate)
2478 (*paintButton)( hwnd, hdc, pressed);
2479 } while (msg.message != WM_LBUTTONUP);
2481 (*paintButton)( hwnd, hdc, FALSE);
2483 ReleaseCapture();
2484 ReleaseDC( hwnd, hdc );
2486 if (!pressed) return;
2488 if (wParam == HTMINBUTTON)
2489 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&pt16 );
2490 else
2491 SendMessage16( hwnd, WM_SYSCOMMAND,
2492 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, *(LONG*)&pt16 );
2496 /***********************************************************************
2497 * NC_TrackCloseButton95
2499 * Track a mouse button press on the Win95 close button.
2501 static void
2502 NC_TrackCloseButton95 (HWND hwnd, WORD wParam)
2504 MSG msg;
2505 POINT16 pt16;
2506 HDC hdc;
2507 BOOL pressed = TRUE;
2508 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
2509 UINT state;
2511 if(hSysMenu == 0)
2512 return;
2514 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
2516 /* If the item close of the sysmenu is disabled or not there do nothing */
2517 if((state & MF_DISABLED) || (state & MF_GRAYED) || (state == 0xFFFFFFFF))
2518 return;
2520 hdc = GetWindowDC( hwnd );
2522 SetCapture( hwnd );
2524 NC_DrawCloseButton95 (hwnd, hdc, TRUE, FALSE);
2528 BOOL oldstate = pressed;
2529 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2530 CONV_POINT32TO16( &msg.pt, &pt16 );
2532 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2533 if (pressed != oldstate)
2534 NC_DrawCloseButton95 (hwnd, hdc, pressed, FALSE);
2535 } while (msg.message != WM_LBUTTONUP);
2537 NC_DrawCloseButton95 (hwnd, hdc, FALSE, FALSE);
2539 ReleaseCapture();
2540 ReleaseDC( hwnd, hdc );
2541 if (!pressed) return;
2543 SendMessage16( hwnd, WM_SYSCOMMAND, SC_CLOSE, *(LONG*)&pt16 );
2547 /***********************************************************************
2548 * NC_TrackScrollBar
2550 * Track a mouse button press on the horizontal or vertical scroll-bar.
2552 static void NC_TrackScrollBar( HWND hwnd, WPARAM wParam, POINT pt )
2554 MSG16 *msg;
2555 INT scrollbar;
2556 WND *wndPtr = WIN_FindWndPtr( hwnd );
2558 if ((wParam & 0xfff0) == SC_HSCROLL)
2560 if ((wParam & 0x0f) != HTHSCROLL) goto END;
2561 scrollbar = SB_HORZ;
2563 else /* SC_VSCROLL */
2565 if ((wParam & 0x0f) != HTVSCROLL) goto END;
2566 scrollbar = SB_VERT;
2569 if (!(msg = SEGPTR_NEW(MSG16))) goto END;
2570 pt.x -= wndPtr->rectWindow.left;
2571 pt.y -= wndPtr->rectWindow.top;
2572 SetCapture( hwnd );
2573 SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt );
2577 GetMessage16( SEGPTR_GET(msg), 0, 0, 0 );
2578 switch(msg->message)
2580 case WM_LBUTTONUP:
2581 case WM_MOUSEMOVE:
2582 case WM_SYSTIMER:
2583 pt.x = LOWORD(msg->lParam) + wndPtr->rectClient.left -
2584 wndPtr->rectWindow.left;
2585 pt.y = HIWORD(msg->lParam) + wndPtr->rectClient.top -
2586 wndPtr->rectWindow.top;
2587 SCROLL_HandleScrollEvent( hwnd, scrollbar, msg->message, pt );
2588 break;
2589 default:
2590 TranslateMessage16( msg );
2591 DispatchMessage16( msg );
2592 break;
2594 if (!IsWindow( hwnd ))
2596 ReleaseCapture();
2597 break;
2599 } while (msg->message != WM_LBUTTONUP);
2600 SEGPTR_FREE(msg);
2601 END:
2602 WIN_ReleaseWndPtr(wndPtr);
2605 /***********************************************************************
2606 * NC_HandleNCLButtonDown
2608 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2610 LONG NC_HandleNCLButtonDown( WND* pWnd, WPARAM16 wParam, LPARAM lParam )
2612 HWND hwnd = pWnd->hwndSelf;
2614 switch(wParam) /* Hit test */
2616 case HTCAPTION:
2617 hwnd = WIN_GetTopParent(hwnd);
2619 if( WINPOS_SetActiveWindow(hwnd, TRUE, TRUE) || (GetActiveWindow() == hwnd) )
2620 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
2621 break;
2623 case HTSYSMENU:
2624 if( pWnd->dwStyle & WS_SYSMENU )
2626 if( !(pWnd->dwStyle & WS_MINIMIZE) )
2628 HDC hDC = GetWindowDC(hwnd);
2629 if (TWEAK_WineLook == WIN31_LOOK)
2630 NC_DrawSysButton( hwnd, hDC, TRUE );
2631 else
2632 NC_DrawSysButton95( hwnd, hDC, TRUE );
2633 ReleaseDC( hwnd, hDC );
2635 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
2637 break;
2639 case HTMENU:
2640 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam );
2641 break;
2643 case HTHSCROLL:
2644 SendMessage16( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
2645 break;
2647 case HTVSCROLL:
2648 SendMessage16( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
2649 break;
2651 case HTMINBUTTON:
2652 case HTMAXBUTTON:
2653 if (TWEAK_WineLook == WIN31_LOOK)
2654 NC_TrackMinMaxBox( hwnd, wParam );
2655 else
2656 NC_TrackMinMaxBox95( hwnd, wParam );
2657 break;
2659 case HTCLOSE:
2660 if (TWEAK_WineLook >= WIN95_LOOK)
2661 NC_TrackCloseButton95 (hwnd, wParam);
2662 break;
2664 case HTLEFT:
2665 case HTRIGHT:
2666 case HTTOP:
2667 case HTTOPLEFT:
2668 case HTTOPRIGHT:
2669 case HTBOTTOM:
2670 case HTBOTTOMLEFT:
2671 case HTBOTTOMRIGHT:
2672 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2673 SendMessage16( hwnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam);
2674 break;
2676 case HTBORDER:
2677 break;
2679 return 0;
2683 /***********************************************************************
2684 * NC_HandleNCLButtonDblClk
2686 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2688 LONG NC_HandleNCLButtonDblClk( WND *pWnd, WPARAM16 wParam, LPARAM lParam )
2691 * if this is an icon, send a restore since we are handling
2692 * a double click
2694 if (pWnd->dwStyle & WS_MINIMIZE)
2696 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_RESTORE, lParam );
2697 return 0;
2700 switch(wParam) /* Hit test */
2702 case HTCAPTION:
2703 /* stop processing if WS_MAXIMIZEBOX is missing */
2704 if (pWnd->dwStyle & WS_MAXIMIZEBOX)
2705 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND,
2706 (pWnd->dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
2707 lParam );
2708 break;
2710 case HTSYSMENU:
2711 if (!(GetClassWord(pWnd->hwndSelf, GCW_STYLE) & CS_NOCLOSE))
2712 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, lParam );
2713 break;
2715 case HTHSCROLL:
2716 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL,
2717 lParam );
2718 break;
2720 case HTVSCROLL:
2721 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL,
2722 lParam );
2723 break;
2725 return 0;
2729 /***********************************************************************
2730 * NC_HandleSysCommand
2732 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2734 LONG NC_HandleSysCommand( HWND hwnd, WPARAM16 wParam, POINT16 pt )
2736 WND *wndPtr = WIN_FindWndPtr( hwnd );
2737 POINT pt32;
2738 UINT16 uCommand = wParam & 0xFFF0;
2740 TRACE("Handling WM_SYSCOMMAND %x %d,%d\n", wParam, pt.x, pt.y );
2742 if (wndPtr->dwStyle & WS_CHILD && uCommand != SC_KEYMENU )
2743 ScreenToClient16( wndPtr->parent->hwndSelf, &pt );
2745 switch (uCommand)
2747 case SC_SIZE:
2748 case SC_MOVE:
2749 NC_DoSizeMove( hwnd, wParam );
2750 break;
2752 case SC_MINIMIZE:
2753 if (hwnd == GetForegroundWindow())
2754 ShowOwnedPopups(hwnd,FALSE);
2755 ShowWindow( hwnd, SW_MINIMIZE );
2756 break;
2758 case SC_MAXIMIZE:
2759 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2760 ShowOwnedPopups(hwnd,TRUE);
2761 ShowWindow( hwnd, SW_MAXIMIZE );
2762 break;
2764 case SC_RESTORE:
2765 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2766 ShowOwnedPopups(hwnd,TRUE);
2767 ShowWindow( hwnd, SW_RESTORE );
2768 break;
2770 case SC_CLOSE:
2771 WIN_ReleaseWndPtr(wndPtr);
2772 return SendMessage16( hwnd, WM_CLOSE, 0, 0 );
2774 case SC_VSCROLL:
2775 case SC_HSCROLL:
2776 CONV_POINT16TO32( &pt, &pt32 );
2777 NC_TrackScrollBar( hwnd, wParam, pt32 );
2778 break;
2780 case SC_MOUSEMENU:
2781 CONV_POINT16TO32( &pt, &pt32 );
2782 MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt32 );
2783 break;
2785 case SC_KEYMENU:
2786 MENU_TrackKbdMenuBar( wndPtr , wParam , pt.x );
2787 break;
2789 case SC_TASKLIST:
2790 WinExec( "taskman.exe", SW_SHOWNORMAL );
2791 break;
2793 case SC_SCREENSAVE:
2794 if (wParam == SC_ABOUTWINE)
2796 HMODULE hmodule = LoadLibraryA( "shell32.dll" );
2797 if (hmodule)
2799 FARPROC aboutproc = GetProcAddress( hmodule, "ShellAboutA" );
2800 if (aboutproc) aboutproc( hwnd, "Wine", WINE_RELEASE_INFO, 0 );
2801 FreeLibrary( hmodule );
2804 else
2805 if (wParam == SC_PUTMARK)
2806 TRACE_(shell)("Mark requested by user\n");
2807 break;
2809 case SC_HOTKEY:
2810 case SC_ARRANGE:
2811 case SC_NEXTWINDOW:
2812 case SC_PREVWINDOW:
2813 FIXME("unimplemented!\n");
2814 break;
2816 WIN_ReleaseWndPtr(wndPtr);
2817 return 0;
2820 /*************************************************************
2821 * NC_DrawGrayButton
2823 * Stub for the grayed button of the caption
2825 *************************************************************/
2827 BOOL NC_DrawGrayButton(HDC hdc, int x, int y)
2829 HBITMAP hMaskBmp;
2830 HDC hdcMask = CreateCompatibleDC (0);
2831 HBRUSH hOldBrush;
2833 hMaskBmp = CreateBitmap (12, 10, 1, 1, lpGrayMask);
2835 if(hMaskBmp == 0)
2836 return FALSE;
2838 SelectObject (hdcMask, hMaskBmp);
2840 /* Draw the grayed bitmap using the mask */
2841 hOldBrush = SelectObject (hdc, RGB(128, 128, 128));
2842 BitBlt (hdc, x, y, 12, 10,
2843 hdcMask, 0, 0, 0xB8074A);
2845 /* Clean up */
2846 SelectObject (hdc, hOldBrush);
2847 DeleteObject(hMaskBmp);
2848 DeleteDC (hdcMask);
2850 return TRUE;
2853 HICON16 NC_IconForWindow(WND *wndPtr)
2855 HICON16 hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICONSM);
2856 if(!hIcon) hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICON);
2858 /* If there is no hIcon specified and this is a modal dialog, */
2859 /* get the default one. */
2860 if (!hIcon && (wndPtr->dwStyle & DS_MODALFRAME))
2861 hIcon = LoadImageA(0, MAKEINTRESOURCEA(OIC_WINEICON), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
2863 return hIcon;