Upgrade also 15bpp to 16bpp surfaces.
[wine/wine-kai.git] / windows / nonclient.c
blob942c0d39eeeb93fcd47e1a68a72dcc0043c4e533
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 if (winRect->top > winRect->bottom)
571 winRect->bottom = winRect->top;
573 if (winRect->left > winRect->right)
574 winRect->right = winRect->left;
576 return result;
580 /***********************************************************************
581 * NC_GetInsideRect
583 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
584 * but without the borders (if any).
585 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
587 static void NC_GetInsideRect( HWND hwnd, RECT *rect )
589 WND * wndPtr = WIN_FindWndPtr( hwnd );
591 rect->top = rect->left = 0;
592 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
593 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
595 if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) goto END;
597 /* Remove frame from rectangle */
598 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
599 InflateRect( rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
600 else
601 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
603 InflateRect( rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
604 /* FIXME: this isn't in NC_AdjustRect? why not? */
605 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
606 InflateRect( rect, -1, 0 );
608 else
609 if (HAS_THINFRAME( wndPtr->dwStyle ))
610 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
611 END:
612 WIN_ReleaseWndPtr(wndPtr);
613 return;
617 /***********************************************************************
618 * NC_GetInsideRect95
620 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
621 * but without the borders (if any).
622 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
625 static void
626 NC_GetInsideRect95 (HWND hwnd, RECT *rect)
628 WND * wndPtr = WIN_FindWndPtr( hwnd );
630 rect->top = rect->left = 0;
631 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
632 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
634 if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) goto END;
636 /* Remove frame from rectangle */
637 if (HAS_THICKFRAME (wndPtr->dwStyle, wndPtr->dwExStyle))
639 InflateRect( rect, -GetSystemMetrics(SM_CXSIZEFRAME), -GetSystemMetrics(SM_CYSIZEFRAME) );
641 else if (HAS_DLGFRAME (wndPtr->dwStyle, wndPtr->dwExStyle ))
643 InflateRect( rect, -GetSystemMetrics(SM_CXFIXEDFRAME), -GetSystemMetrics(SM_CYFIXEDFRAME));
645 else if (HAS_THINFRAME (wndPtr->dwStyle))
647 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
650 /* We have additional border information if the window
651 * is a child (but not an MDI child) */
652 if ( (wndPtr->dwStyle & WS_CHILD) &&
653 ( (wndPtr->dwExStyle & WS_EX_MDICHILD) == 0 ) )
655 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
656 InflateRect (rect, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE));
658 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
659 InflateRect (rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
661 END:
662 WIN_ReleaseWndPtr(wndPtr);
663 return;
667 /***********************************************************************
668 * NC_DoNCHitTest
670 * Handle a WM_NCHITTEST message. Called from NC_HandleNcHitTest().
673 static LONG NC_DoNCHitTest (WND *wndPtr, POINT16 pt )
675 RECT16 rect;
677 TRACE("hwnd=%04x pt=%d,%d\n", wndPtr->hwndSelf, pt.x, pt.y );
679 GetWindowRect16 (wndPtr->hwndSelf, &rect );
680 if (!PtInRect16( &rect, pt )) return HTNOWHERE;
682 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
684 if (!(wndPtr->flags & WIN_MANAGED))
686 /* Check borders */
687 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
689 InflateRect16( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
690 if (!PtInRect16( &rect, pt ))
692 /* Check top sizing border */
693 if (pt.y < rect.top)
695 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
696 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
697 return HTTOP;
699 /* Check bottom sizing border */
700 if (pt.y >= rect.bottom)
702 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
703 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
704 return HTBOTTOM;
706 /* Check left sizing border */
707 if (pt.x < rect.left)
709 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
710 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
711 return HTLEFT;
713 /* Check right sizing border */
714 if (pt.x >= rect.right)
716 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
717 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
718 return HTRIGHT;
722 else /* No thick frame */
724 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
725 InflateRect16(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
726 else if (HAS_THINFRAME( wndPtr->dwStyle ))
727 InflateRect16(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
728 if (!PtInRect16( &rect, pt )) return HTBORDER;
731 /* Check caption */
733 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
735 rect.top += GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
736 if (!PtInRect16( &rect, pt ))
738 /* Check system menu */
739 if ((wndPtr->dwStyle & WS_SYSMENU) && !(wndPtr->dwExStyle & WS_EX_TOOLWINDOW))
740 rect.left += GetSystemMetrics(SM_CXSIZE);
741 if (pt.x <= rect.left) return HTSYSMENU;
743 /* Check maximize box */
744 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
745 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
747 if (pt.x >= rect.right) return HTMAXBUTTON;
748 /* Check minimize box */
749 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
750 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
751 if (pt.x >= rect.right) return HTMINBUTTON;
752 return HTCAPTION;
757 /* Check client area */
759 ScreenToClient16( wndPtr->hwndSelf, &pt );
760 GetClientRect16( wndPtr->hwndSelf, &rect );
761 if (PtInRect16( &rect, pt )) return HTCLIENT;
763 /* Check vertical scroll bar */
765 if (wndPtr->dwStyle & WS_VSCROLL)
767 rect.right += GetSystemMetrics(SM_CXVSCROLL);
768 if (PtInRect16( &rect, pt )) return HTVSCROLL;
771 /* Check horizontal scroll bar */
773 if (wndPtr->dwStyle & WS_HSCROLL)
775 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
776 if (PtInRect16( &rect, pt ))
778 /* Check size box */
779 if ((wndPtr->dwStyle & WS_VSCROLL) &&
780 (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
781 return HTSIZE;
782 return HTHSCROLL;
786 /* Check menu bar */
788 if (HAS_MENU(wndPtr))
790 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
791 return HTMENU;
794 /* Has to return HTNOWHERE if nothing was found
795 Could happen when a window has a customized non client area */
796 return HTNOWHERE;
800 /***********************************************************************
801 * NC_DoNCHitTest95
803 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
805 * FIXME: Just a modified copy of the Win 3.1 version.
808 static LONG
809 NC_DoNCHitTest95 (WND *wndPtr, POINT16 pt )
811 RECT16 rect;
813 TRACE("hwnd=%04x pt=%d,%d\n", wndPtr->hwndSelf, pt.x, pt.y );
815 GetWindowRect16 (wndPtr->hwndSelf, &rect );
816 if (!PtInRect16( &rect, pt )) return HTNOWHERE;
818 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
820 if (!(wndPtr->flags & WIN_MANAGED))
822 /* Check borders */
823 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
825 InflateRect16( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
826 if (!PtInRect16( &rect, pt ))
828 /* Check top sizing border */
829 if (pt.y < rect.top)
831 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
832 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
833 return HTTOP;
835 /* Check bottom sizing border */
836 if (pt.y >= rect.bottom)
838 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
839 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
840 return HTBOTTOM;
842 /* Check left sizing border */
843 if (pt.x < rect.left)
845 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
846 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
847 return HTLEFT;
849 /* Check right sizing border */
850 if (pt.x >= rect.right)
852 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
853 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
854 return HTRIGHT;
858 else /* No thick frame */
860 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
861 InflateRect16(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
862 else if (HAS_THINFRAME( wndPtr->dwStyle ))
863 InflateRect16(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
864 if (!PtInRect16( &rect, pt )) return HTBORDER;
867 /* Check caption */
869 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
871 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
872 rect.top += GetSystemMetrics(SM_CYSMCAPTION) - 1;
873 else
874 rect.top += GetSystemMetrics(SM_CYCAPTION) - 1;
875 if (!PtInRect16( &rect, pt ))
877 /* Check system menu */
878 if ((wndPtr->dwStyle & WS_SYSMENU) && !(wndPtr->dwExStyle & WS_EX_TOOLWINDOW))
880 if (NC_IconForWindow(wndPtr))
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 /* Has to return HTNOWHERE if nothing was found
945 Could happen when a window has a customized non client area */
946 return HTNOWHERE;
950 /***********************************************************************
951 * NC_HandleNCHitTest
953 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
955 LONG
956 NC_HandleNCHitTest (HWND hwnd , POINT16 pt)
958 LONG retvalue;
959 WND *wndPtr = WIN_FindWndPtr (hwnd);
961 if (!wndPtr)
962 return HTERROR;
964 if (TWEAK_WineLook == WIN31_LOOK)
965 retvalue = NC_DoNCHitTest (wndPtr, pt);
966 else
967 retvalue = NC_DoNCHitTest95 (wndPtr, pt);
968 WIN_ReleaseWndPtr(wndPtr);
969 return retvalue;
973 /***********************************************************************
974 * NC_DrawSysButton
976 void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down )
978 RECT rect;
979 HDC hdcMem;
980 HBITMAP hbitmap;
981 WND *wndPtr = WIN_FindWndPtr( hwnd );
983 if( !(wndPtr->flags & WIN_MANAGED) )
985 NC_GetInsideRect( hwnd, &rect );
986 hdcMem = CreateCompatibleDC( hdc );
987 hbitmap = SelectObject( hdcMem, hbitmapClose );
988 BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE), GetSystemMetrics(SM_CYSIZE),
989 hdcMem, (wndPtr->dwStyle & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE) : 0, 0,
990 down ? NOTSRCCOPY : SRCCOPY );
991 SelectObject( hdcMem, hbitmap );
992 DeleteDC( hdcMem );
994 WIN_ReleaseWndPtr(wndPtr);
998 /***********************************************************************
999 * NC_DrawMaxButton
1001 static void NC_DrawMaxButton( HWND hwnd, HDC16 hdc, BOOL down )
1003 RECT rect;
1004 WND *wndPtr = WIN_FindWndPtr( hwnd );
1005 HDC hdcMem;
1007 if( !(wndPtr->flags & WIN_MANAGED) )
1009 NC_GetInsideRect( hwnd, &rect );
1010 hdcMem = CreateCompatibleDC( hdc );
1011 SelectObject( hdcMem, (IsZoomed(hwnd)
1012 ? (down ? hbitmapRestoreD : hbitmapRestore)
1013 : (down ? hbitmapMaximizeD : hbitmapMaximize)) );
1014 BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
1015 GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
1016 SRCCOPY );
1017 DeleteDC( hdcMem );
1019 WIN_ReleaseWndPtr(wndPtr);
1024 /***********************************************************************
1025 * NC_DrawMinButton
1027 static void NC_DrawMinButton( HWND hwnd, HDC16 hdc, BOOL down )
1029 RECT rect;
1030 WND *wndPtr = WIN_FindWndPtr( hwnd );
1031 HDC hdcMem;
1033 if( !(wndPtr->flags & WIN_MANAGED) )
1035 NC_GetInsideRect( hwnd, &rect );
1036 hdcMem = CreateCompatibleDC( hdc );
1037 SelectObject( hdcMem, (down ? hbitmapMinimizeD : hbitmapMinimize) );
1038 if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= GetSystemMetrics(SM_CXSIZE)+1;
1039 BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
1040 GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
1041 SRCCOPY );
1042 DeleteDC( hdcMem );
1044 WIN_ReleaseWndPtr(wndPtr);
1048 /******************************************************************************
1050 * void NC_DrawSysButton95(
1051 * HWND hwnd,
1052 * HDC hdc,
1053 * BOOL down )
1055 * Draws the Win95 system icon.
1057 * Revision history
1058 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1059 * Original implementation from NC_DrawSysButton source.
1060 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1061 * Fixed most bugs.
1063 *****************************************************************************/
1065 BOOL
1066 NC_DrawSysButton95 (HWND hwnd, HDC hdc, BOOL down)
1068 WND *wndPtr = WIN_FindWndPtr( hwnd );
1070 if( !(wndPtr->flags & WIN_MANAGED) )
1072 HICON hIcon;
1073 RECT rect;
1075 NC_GetInsideRect95( hwnd, &rect );
1077 hIcon = NC_IconForWindow( wndPtr );
1079 if (hIcon)
1080 DrawIconEx (hdc, rect.left + 2, rect.top + 2, hIcon,
1081 GetSystemMetrics(SM_CXSMICON),
1082 GetSystemMetrics(SM_CYSMICON),
1083 0, 0, DI_NORMAL);
1085 WIN_ReleaseWndPtr(wndPtr);
1086 return (hIcon != 0);
1088 WIN_ReleaseWndPtr(wndPtr);
1089 return FALSE;
1093 /******************************************************************************
1095 * void NC_DrawCloseButton95(
1096 * HWND hwnd,
1097 * HDC hdc,
1098 * BOOL down,
1099 * BOOL bGrayed )
1101 * Draws the Win95 close button.
1103 * If bGrayed is true, then draw a disabled Close button
1105 * Revision history
1106 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1107 * Original implementation from NC_DrawSysButton95 source.
1109 *****************************************************************************/
1111 static void NC_DrawCloseButton95 (HWND hwnd, HDC hdc, BOOL down, BOOL bGrayed)
1113 RECT rect;
1114 HDC hdcMem;
1115 WND *wndPtr = WIN_FindWndPtr( hwnd );
1117 if( !(wndPtr->flags & WIN_MANAGED) )
1119 BITMAP bmp;
1120 HBITMAP hBmp, hOldBmp;
1122 NC_GetInsideRect95( hwnd, &rect );
1124 /* A tool window has a smaller Close button */
1125 if(wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
1127 RECT toolRect;
1128 INT iBmpHeight = 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
1129 INT iBmpWidth = 11; /* it uses 11x11 for the close button in tool window */
1130 INT iCaptionHeight = GetSystemMetrics(SM_CYSMCAPTION);
1132 toolRect.top = rect.top + (iCaptionHeight - 1 - iBmpHeight) / 2;
1133 toolRect.left = rect.right - (iCaptionHeight + 1 + iBmpWidth) / 2;
1134 toolRect.bottom = toolRect.top + iBmpHeight;
1135 toolRect.right = toolRect.left + iBmpWidth;
1136 DrawFrameControl(hdc,&toolRect,
1137 DFC_CAPTION,DFCS_CAPTIONCLOSE |
1138 down ? DFCS_PUSHED : 0 |
1139 bGrayed ? DFCS_INACTIVE : 0);
1141 else
1143 hdcMem = CreateCompatibleDC( hdc );
1144 hBmp = down ? hbitmapCloseD : hbitmapClose;
1145 hOldBmp = SelectObject (hdcMem, hBmp);
1146 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1148 BitBlt (hdc, rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2,
1149 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1150 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);
1152 if(bGrayed)
1153 NC_DrawGrayButton(hdc,rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2 + 2,
1154 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1156 SelectObject (hdcMem, hOldBmp);
1157 DeleteDC (hdcMem);
1160 WIN_ReleaseWndPtr(wndPtr);
1163 /******************************************************************************
1165 * NC_DrawMaxButton95(
1166 * HWND hwnd,
1167 * HDC16 hdc,
1168 * BOOL down
1169 * BOOL bGrayed )
1171 * Draws the maximize button for Win95 style windows.
1173 * If bGrayed is true, then draw a disabled Maximize button
1175 * Bugs
1176 * Many. Spacing might still be incorrect. Need to fit a close
1177 * button between the max button and the edge.
1178 * Should scale the image with the title bar. And more...
1180 * Revision history
1181 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1182 * Original implementation.
1184 *****************************************************************************/
1186 static void NC_DrawMaxButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
1188 RECT rect;
1189 HDC hdcMem;
1190 WND *wndPtr = WIN_FindWndPtr( hwnd );
1192 if( !(wndPtr->flags & WIN_MANAGED))
1194 BITMAP bmp;
1195 HBITMAP hBmp,hOldBmp;
1197 NC_GetInsideRect95( hwnd, &rect );
1198 hdcMem = CreateCompatibleDC( hdc );
1199 hBmp = IsZoomed(hwnd) ?
1200 (down ? hbitmapRestoreD : hbitmapRestore ) :
1201 (down ? hbitmapMaximizeD: hbitmapMaximize);
1202 hOldBmp=SelectObject( hdcMem, hBmp );
1203 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1205 if (wndPtr->dwStyle & WS_SYSMENU)
1206 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1208 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1209 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1210 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1212 if(bGrayed)
1213 NC_DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
1214 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1217 SelectObject (hdcMem, hOldBmp);
1218 DeleteDC( hdcMem );
1220 WIN_ReleaseWndPtr(wndPtr);
1223 /******************************************************************************
1225 * NC_DrawMinButton95(
1226 * HWND hwnd,
1227 * HDC16 hdc,
1228 * BOOL down,
1229 * BOOL bGrayed )
1231 * Draws the minimize button for Win95 style windows.
1233 * If bGrayed is true, then draw a disabled Minimize button
1235 * Bugs
1236 * Many. Spacing is still incorrect. Should scale the image with the
1237 * title bar. And more...
1239 * Revision history
1240 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1241 * Original implementation.
1243 *****************************************************************************/
1245 static void NC_DrawMinButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
1247 RECT rect;
1248 HDC hdcMem;
1249 WND *wndPtr = WIN_FindWndPtr( hwnd );
1251 if( !(wndPtr->flags & WIN_MANAGED))
1254 BITMAP bmp;
1255 HBITMAP hBmp,hOldBmp;
1257 NC_GetInsideRect95( hwnd, &rect );
1259 hdcMem = CreateCompatibleDC( hdc );
1260 hBmp = down ? hbitmapMinimizeD : hbitmapMinimize;
1261 hOldBmp= SelectObject( hdcMem, hBmp );
1262 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1264 if (wndPtr->dwStyle & WS_SYSMENU)
1265 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1267 /* In win 95 there is always a Maximize box when there is a Minimize one */
1268 if ((wndPtr->dwStyle & WS_MAXIMIZEBOX) || (wndPtr->dwStyle & WS_MINIMIZEBOX))
1269 rect.right += -1 - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2;
1271 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1272 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1273 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1275 if(bGrayed)
1276 NC_DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
1277 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1280 SelectObject (hdcMem, hOldBmp);
1281 DeleteDC( hdcMem );
1283 WIN_ReleaseWndPtr(wndPtr);
1286 /***********************************************************************
1287 * NC_DrawFrame
1289 * Draw a window frame inside the given rectangle, and update the rectangle.
1290 * The correct pen for the frame must be selected in the DC.
1292 static void NC_DrawFrame( HDC hdc, RECT *rect, BOOL dlgFrame,
1293 BOOL active )
1295 INT width, height;
1297 if (TWEAK_WineLook != WIN31_LOOK)
1298 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
1300 if (dlgFrame)
1302 width = GetSystemMetrics(SM_CXDLGFRAME) - 1;
1303 height = GetSystemMetrics(SM_CYDLGFRAME) - 1;
1304 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1305 COLOR_INACTIVECAPTION) );
1307 else
1309 width = GetSystemMetrics(SM_CXFRAME) - 2;
1310 height = GetSystemMetrics(SM_CYFRAME) - 2;
1311 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1312 COLOR_INACTIVEBORDER) );
1315 /* Draw frame */
1316 PatBlt( hdc, rect->left, rect->top,
1317 rect->right - rect->left, height, PATCOPY );
1318 PatBlt( hdc, rect->left, rect->top,
1319 width, rect->bottom - rect->top, PATCOPY );
1320 PatBlt( hdc, rect->left, rect->bottom - 1,
1321 rect->right - rect->left, -height, PATCOPY );
1322 PatBlt( hdc, rect->right - 1, rect->top,
1323 -width, rect->bottom - rect->top, PATCOPY );
1325 if (dlgFrame)
1327 InflateRect( rect, -width, -height );
1329 else
1331 INT decYOff = GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXSIZE) - 1;
1332 INT decXOff = GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYSIZE) - 1;
1334 /* Draw inner rectangle */
1336 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1337 Rectangle( hdc, rect->left + width, rect->top + height,
1338 rect->right - width , rect->bottom - height );
1340 /* Draw the decorations */
1342 MoveToEx( hdc, rect->left, rect->top + decYOff, NULL );
1343 LineTo( hdc, rect->left + width, rect->top + decYOff );
1344 MoveToEx( hdc, rect->right - 1, rect->top + decYOff, NULL );
1345 LineTo( hdc, rect->right - width - 1, rect->top + decYOff );
1346 MoveToEx( hdc, rect->left, rect->bottom - decYOff, NULL );
1347 LineTo( hdc, rect->left + width, rect->bottom - decYOff );
1348 MoveToEx( hdc, rect->right - 1, rect->bottom - decYOff, NULL );
1349 LineTo( hdc, rect->right - width - 1, rect->bottom - decYOff );
1351 MoveToEx( hdc, rect->left + decXOff, rect->top, NULL );
1352 LineTo( hdc, rect->left + decXOff, rect->top + height);
1353 MoveToEx( hdc, rect->left + decXOff, rect->bottom - 1, NULL );
1354 LineTo( hdc, rect->left + decXOff, rect->bottom - height - 1 );
1355 MoveToEx( hdc, rect->right - decXOff, rect->top, NULL );
1356 LineTo( hdc, rect->right - decXOff, rect->top + height );
1357 MoveToEx( hdc, rect->right - decXOff, rect->bottom - 1, NULL );
1358 LineTo( hdc, rect->right - decXOff, rect->bottom - height - 1 );
1360 InflateRect( rect, -width - 1, -height - 1 );
1365 /******************************************************************************
1367 * void NC_DrawFrame95(
1368 * HDC hdc,
1369 * RECT *rect,
1370 * BOOL dlgFrame,
1371 * BOOL active )
1373 * Draw a window frame inside the given rectangle, and update the rectangle.
1374 * The correct pen for the frame must be selected in the DC.
1376 * Bugs
1377 * Many. First, just what IS a frame in Win95? Note that the 3D look
1378 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1379 * edge. The inner rectangle just inside the frame is handled by the
1380 * Caption code.
1382 * In short, for most people, this function should be a nop (unless
1383 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1384 * them lately, but just to get this code right). Even so, it doesn't
1385 * appear to be so. It's being worked on...
1387 * Revision history
1388 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1389 * Original implementation (based on NC_DrawFrame)
1390 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1391 * Some minor fixes.
1392 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1393 * Fixed a fix or something.
1395 *****************************************************************************/
1397 static void NC_DrawFrame95(
1398 HDC hdc,
1399 RECT *rect,
1400 BOOL dlgFrame,
1401 BOOL active )
1403 INT width, height;
1405 if (dlgFrame)
1407 width = GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
1408 height = GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
1410 else
1412 width = GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXEDGE);
1413 height = GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYEDGE);
1416 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1417 COLOR_INACTIVEBORDER) );
1419 /* Draw frame */
1420 PatBlt( hdc, rect->left, rect->top,
1421 rect->right - rect->left, height, PATCOPY );
1422 PatBlt( hdc, rect->left, rect->top,
1423 width, rect->bottom - rect->top, PATCOPY );
1424 PatBlt( hdc, rect->left, rect->bottom - 1,
1425 rect->right - rect->left, -height, PATCOPY );
1426 PatBlt( hdc, rect->right - 1, rect->top,
1427 -width, rect->bottom - rect->top, PATCOPY );
1429 InflateRect( rect, -width, -height );
1432 /***********************************************************************
1433 * NC_DrawMovingFrame
1435 * Draw the frame used when moving or resizing window.
1437 * FIXME: This causes problems in Win95 mode. (why?)
1439 static void NC_DrawMovingFrame( HDC hdc, RECT *rect, BOOL thickframe )
1441 if (thickframe)
1443 RECT16 r16;
1444 CONV_RECT32TO16( rect, &r16 );
1445 FastWindowFrame16( hdc, &r16, GetSystemMetrics(SM_CXFRAME),
1446 GetSystemMetrics(SM_CYFRAME), PATINVERT );
1448 else DrawFocusRect( hdc, rect );
1452 /***********************************************************************
1453 * NC_DrawCaption
1455 * Draw the window caption.
1456 * The correct pen for the window frame must be selected in the DC.
1458 static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd,
1459 DWORD style, BOOL active )
1461 RECT r = *rect;
1462 WND * wndPtr = WIN_FindWndPtr( hwnd );
1463 char buffer[256];
1465 if (wndPtr->flags & WIN_MANAGED)
1467 WIN_ReleaseWndPtr(wndPtr);
1468 return;
1471 if (!hbitmapClose)
1473 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1475 WIN_ReleaseWndPtr(wndPtr);
1476 return;
1478 hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED) );
1479 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1480 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1481 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1482 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1483 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1484 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1487 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
1489 HBRUSH hbrushOld = SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW) );
1490 PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
1491 PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
1492 PatBlt( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
1493 r.left++;
1494 r.right--;
1495 SelectObject( hdc, hbrushOld );
1497 WIN_ReleaseWndPtr(wndPtr);
1498 MoveToEx( hdc, r.left, r.bottom, NULL );
1499 LineTo( hdc, r.right, r.bottom );
1501 if (style & WS_SYSMENU)
1503 NC_DrawSysButton( hwnd, hdc, FALSE );
1504 r.left += GetSystemMetrics(SM_CXSIZE) + 1;
1505 MoveToEx( hdc, r.left - 1, r.top, NULL );
1506 LineTo( hdc, r.left - 1, r.bottom );
1508 if (style & WS_MAXIMIZEBOX)
1510 NC_DrawMaxButton( hwnd, hdc, FALSE );
1511 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1513 if (style & WS_MINIMIZEBOX)
1515 NC_DrawMinButton( hwnd, hdc, FALSE );
1516 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1519 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1520 COLOR_INACTIVECAPTION) );
1522 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) ))
1524 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1525 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1526 SetBkMode( hdc, TRANSPARENT );
1527 DrawTextA( hdc, buffer, -1, &r,
1528 DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );
1533 /******************************************************************************
1535 * NC_DrawCaption95(
1536 * HDC hdc,
1537 * RECT *rect,
1538 * HWND hwnd,
1539 * DWORD style,
1540 * BOOL active )
1542 * Draw the window caption for Win95 style windows.
1543 * The correct pen for the window frame must be selected in the DC.
1545 * Bugs
1546 * Hey, a function that finally works! Well, almost.
1547 * It's being worked on.
1549 * Revision history
1550 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1551 * Original implementation.
1552 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1553 * Some minor fixes.
1555 *****************************************************************************/
1557 static void NC_DrawCaption95(
1558 HDC hdc,
1559 RECT *rect,
1560 HWND hwnd,
1561 DWORD style,
1562 DWORD exStyle,
1563 BOOL active )
1565 RECT r = *rect;
1566 WND *wndPtr = WIN_FindWndPtr( hwnd );
1567 char buffer[256];
1568 HPEN hPrevPen;
1569 HMENU hSysMenu;
1571 if (wndPtr->flags & WIN_MANAGED)
1573 WIN_ReleaseWndPtr(wndPtr);
1574 return;
1576 WIN_ReleaseWndPtr(wndPtr);
1578 hPrevPen = SelectObject( hdc, GetSysColorPen(COLOR_3DFACE) );
1579 MoveToEx( hdc, r.left, r.bottom - 1, NULL );
1580 LineTo( hdc, r.right, r.bottom - 1 );
1581 SelectObject( hdc, hPrevPen );
1582 r.bottom--;
1584 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1585 COLOR_INACTIVECAPTION) );
1587 if (!hbitmapClose) {
1588 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1589 return;
1590 hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED));
1591 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1592 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1593 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1594 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1595 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1596 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1599 if ((style & WS_SYSMENU) && !(exStyle & WS_EX_TOOLWINDOW)) {
1600 if (NC_DrawSysButton95 (hwnd, hdc, FALSE))
1601 r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
1604 if (style & WS_SYSMENU)
1606 UINT state;
1608 /* Go get the sysmenu */
1609 hSysMenu = GetSystemMenu(hwnd, FALSE);
1610 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
1612 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1613 NC_DrawCloseButton95 (hwnd, hdc, FALSE,
1614 ((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
1615 r.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
1617 if ((style & WS_MAXIMIZEBOX) || (style & WS_MINIMIZEBOX))
1619 /* In win95 the two buttons are always there */
1620 /* But if the menu item is not in the menu they're disabled*/
1622 NC_DrawMaxButton95( hwnd, hdc, FALSE, (!(style & WS_MAXIMIZEBOX)));
1623 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1625 NC_DrawMinButton95( hwnd, hdc, FALSE, (!(style & WS_MINIMIZEBOX)));
1626 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1630 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) )) {
1631 NONCLIENTMETRICSA nclm;
1632 HFONT hFont, hOldFont;
1633 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1634 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1635 if (exStyle & WS_EX_TOOLWINDOW)
1636 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
1637 else
1638 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
1639 hOldFont = SelectObject (hdc, hFont);
1640 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1641 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1642 SetBkMode( hdc, TRANSPARENT );
1643 r.left += 2;
1644 DrawTextA( hdc, buffer, -1, &r,
1645 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
1646 DeleteObject (SelectObject (hdc, hOldFont));
1652 /***********************************************************************
1653 * NC_DoNCPaint
1655 * Paint the non-client area. clip is currently unused.
1657 static void NC_DoNCPaint( WND* wndPtr, HRGN clip, BOOL suppress_menupaint )
1659 HDC hdc;
1660 RECT rect;
1661 BOOL active;
1662 HWND hwnd = wndPtr->hwndSelf;
1664 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1665 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1667 active = wndPtr->flags & WIN_NCACTIVATED;
1669 TRACE("%04x %d\n", hwnd, active );
1671 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1672 ((clip > 1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN): 0) ))) return;
1674 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1675 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1676 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1677 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1678 == NULLREGION)
1680 ReleaseDC( hwnd, hdc );
1681 return;
1684 rect.top = rect.left = 0;
1685 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1686 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1688 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1690 if (!(wndPtr->flags & WIN_MANAGED))
1692 if (HAS_ANYFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1694 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1695 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1696 InflateRect( &rect, -1, -1 );
1699 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1700 NC_DrawFrame(hdc, &rect, FALSE, active );
1701 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1702 NC_DrawFrame( hdc, &rect, TRUE, active );
1704 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1706 RECT r = rect;
1707 r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
1708 rect.top += GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYBORDER);
1709 NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active );
1713 if (HAS_MENU(wndPtr))
1715 RECT r = rect;
1716 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU); /* default height */
1717 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint );
1720 /* Draw the scroll-bars */
1722 if (wndPtr->dwStyle & WS_VSCROLL)
1723 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1724 if (wndPtr->dwStyle & WS_HSCROLL)
1725 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1727 /* Draw the "size-box" */
1729 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1731 RECT r = rect;
1732 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1733 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1734 if(wndPtr->dwStyle & WS_BORDER) {
1735 r.left++;
1736 r.top++;
1738 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1741 ReleaseDC( hwnd, hdc );
1745 /******************************************************************************
1747 * void NC_DoNCPaint95(
1748 * WND *wndPtr,
1749 * HRGN clip,
1750 * BOOL suppress_menupaint )
1752 * Paint the non-client area for Win95 windows. The clip region is
1753 * currently ignored.
1755 * Bugs
1756 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1757 * misc/tweak.c controls/menu.c # :-)
1759 * Revision history
1760 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1761 * Original implementation
1762 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1763 * Fixed some bugs.
1764 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1765 * Streamlined window style checks.
1767 *****************************************************************************/
1769 static void NC_DoNCPaint95(
1770 WND *wndPtr,
1771 HRGN clip,
1772 BOOL suppress_menupaint )
1774 HDC hdc;
1775 RECT rfuzz, rect, rectClip;
1776 BOOL active;
1777 HWND hwnd = wndPtr->hwndSelf;
1779 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1780 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1782 active = wndPtr->flags & WIN_NCACTIVATED;
1784 TRACE("%04x %d\n", hwnd, active );
1786 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1787 the call to GetDCEx implying that it is allowed not to use it either.
1788 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1789 will cause clipRgn to be deleted after ReleaseDC().
1790 Now, how is the "system" supposed to tell what happened?
1793 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1794 ((clip > 1) ?(DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0) ))) return;
1797 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1798 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1799 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1800 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1801 == NULLREGION)
1803 ReleaseDC( hwnd, hdc );
1804 return;
1807 rect.top = rect.left = 0;
1808 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1809 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1811 if( clip > 1 )
1812 GetRgnBox( clip, &rectClip );
1813 else
1815 clip = 0;
1816 rectClip = rect;
1819 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1821 if(!(wndPtr->flags & WIN_MANAGED)) {
1822 if (HAS_BIGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle)) {
1823 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1825 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1826 NC_DrawFrame95(hdc, &rect, FALSE, active );
1827 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1828 NC_DrawFrame95( hdc, &rect, TRUE, active );
1829 else if (HAS_THINFRAME( wndPtr->dwStyle )) {
1830 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1831 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1834 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1836 RECT r = rect;
1837 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW) {
1838 r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
1839 rect.top += GetSystemMetrics(SM_CYSMCAPTION);
1841 else {
1842 r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
1843 rect.top += GetSystemMetrics(SM_CYCAPTION);
1845 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
1846 NC_DrawCaption95 (hdc, &r, hwnd, wndPtr->dwStyle,
1847 wndPtr->dwExStyle, active);
1851 if (HAS_MENU(wndPtr))
1853 RECT r = rect;
1854 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
1856 TRACE("Calling DrawMenuBar with rect (%d, %d)-(%d, %d)\n",
1857 r.left, r.top, r.right, r.bottom);
1859 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ) + 1;
1862 TRACE("After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1863 rect.left, rect.top, rect.right, rect.bottom );
1865 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
1866 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1868 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
1869 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1871 /* Draw the scroll-bars */
1873 if (wndPtr->dwStyle & WS_VSCROLL)
1874 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1875 if (wndPtr->dwStyle & WS_HSCROLL)
1876 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1878 /* Draw the "size-box" */
1879 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1881 RECT r = rect;
1882 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1883 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1884 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1887 ReleaseDC( hwnd, hdc );
1893 /***********************************************************************
1894 * NC_HandleNCPaint
1896 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1898 LONG NC_HandleNCPaint( HWND hwnd , HRGN clip)
1900 WND* wndPtr = WIN_FindWndPtr( hwnd );
1902 if( wndPtr && wndPtr->dwStyle & WS_VISIBLE )
1904 if( wndPtr->dwStyle & WS_MINIMIZE )
1905 WINPOS_RedrawIconTitle( hwnd );
1906 else if (TWEAK_WineLook == WIN31_LOOK)
1907 NC_DoNCPaint( wndPtr, clip, FALSE );
1908 else
1909 NC_DoNCPaint95( wndPtr, clip, FALSE );
1911 WIN_ReleaseWndPtr(wndPtr);
1912 return 0;
1916 /***********************************************************************
1917 * NC_HandleNCActivate
1919 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1921 LONG NC_HandleNCActivate( WND *wndPtr, WPARAM16 wParam )
1923 WORD wStateChange;
1925 if( wParam ) wStateChange = !(wndPtr->flags & WIN_NCACTIVATED);
1926 else wStateChange = wndPtr->flags & WIN_NCACTIVATED;
1928 if( wStateChange )
1930 if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
1931 else wndPtr->flags &= ~WIN_NCACTIVATED;
1933 if( wndPtr->dwStyle & WS_MINIMIZE )
1934 WINPOS_RedrawIconTitle( wndPtr->hwndSelf );
1935 else if (TWEAK_WineLook == WIN31_LOOK)
1936 NC_DoNCPaint( wndPtr, (HRGN)1, FALSE );
1937 else
1938 NC_DoNCPaint95( wndPtr, (HRGN)1, FALSE );
1940 return TRUE;
1944 /***********************************************************************
1945 * NC_HandleSetCursor
1947 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1949 LONG NC_HandleSetCursor( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
1951 if (hwnd != (HWND)wParam) return 0; /* Don't set the cursor for child windows */
1953 switch(LOWORD(lParam))
1955 case HTERROR:
1957 WORD msg = HIWORD( lParam );
1958 if ((msg == WM_LBUTTONDOWN) || (msg == WM_MBUTTONDOWN) ||
1959 (msg == WM_RBUTTONDOWN))
1960 MessageBeep(0);
1962 break;
1964 case HTCLIENT:
1966 HICON16 hCursor = (HICON16) GetClassWord(hwnd, GCW_HCURSOR);
1967 if(hCursor) {
1968 SetCursor16(hCursor);
1969 return TRUE;
1971 return FALSE;
1974 case HTLEFT:
1975 case HTRIGHT:
1976 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZEWE16 ) );
1978 case HTTOP:
1979 case HTBOTTOM:
1980 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENS16 ) );
1982 case HTTOPLEFT:
1983 case HTBOTTOMRIGHT:
1984 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENWSE16 ) );
1986 case HTTOPRIGHT:
1987 case HTBOTTOMLEFT:
1988 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENESW16 ) );
1991 /* Default cursor: arrow */
1992 return (LONG)SetCursor16( LoadCursor16( 0, IDC_ARROW16 ) );
1995 /***********************************************************************
1996 * NC_GetSysPopupPos
1998 BOOL NC_GetSysPopupPos( WND* wndPtr, RECT* rect )
2000 if( wndPtr->hSysMenu )
2002 if( wndPtr->dwStyle & WS_MINIMIZE )
2003 GetWindowRect( wndPtr->hwndSelf, rect );
2004 else
2006 if (TWEAK_WineLook == WIN31_LOOK)
2007 NC_GetInsideRect( wndPtr->hwndSelf, rect );
2008 else
2009 NC_GetInsideRect95( wndPtr->hwndSelf, rect );
2010 OffsetRect( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
2011 if (wndPtr->dwStyle & WS_CHILD)
2012 ClientToScreen( wndPtr->parent->hwndSelf, (POINT *)rect );
2013 if (TWEAK_WineLook == WIN31_LOOK) {
2014 rect->right = rect->left + GetSystemMetrics(SM_CXSIZE);
2015 rect->bottom = rect->top + GetSystemMetrics(SM_CYSIZE);
2017 else {
2018 rect->right = rect->left + GetSystemMetrics(SM_CYCAPTION) - 1;
2019 rect->bottom = rect->top + GetSystemMetrics(SM_CYCAPTION) - 1;
2022 return TRUE;
2024 return FALSE;
2027 /***********************************************************************
2028 * NC_StartSizeMove
2030 * Initialisation of a move or resize, when initiatied from a menu choice.
2031 * Return hit test code for caption or sizing border.
2033 static LONG NC_StartSizeMove( WND* wndPtr, WPARAM16 wParam,
2034 POINT16 *capturePoint )
2036 LONG hittest = 0;
2037 POINT16 pt;
2038 MSG msg;
2039 RECT rectWindow;
2041 GetWindowRect(wndPtr->hwndSelf,&rectWindow);
2043 if ((wParam & 0xfff0) == SC_MOVE)
2045 /* Move pointer at the center of the caption */
2046 RECT rect;
2047 if (TWEAK_WineLook == WIN31_LOOK)
2048 NC_GetInsideRect( wndPtr->hwndSelf, &rect );
2049 else
2050 NC_GetInsideRect95( wndPtr->hwndSelf, &rect );
2051 if (wndPtr->dwStyle & WS_SYSMENU)
2052 rect.left += GetSystemMetrics(SM_CXSIZE) + 1;
2053 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
2054 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
2055 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
2056 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
2057 pt.x = rectWindow.left + (rect.right - rect.left) / 2;
2058 pt.y = rectWindow.top + rect.top + GetSystemMetrics(SM_CYSIZE)/2;
2059 hittest = HTCAPTION;
2060 *capturePoint = pt;
2062 else /* SC_SIZE */
2064 while(!hittest)
2066 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE, NULL );
2067 switch(msg.message)
2069 case WM_MOUSEMOVE:
2070 CONV_POINT32TO16(&msg.pt, &pt);
2071 hittest = NC_HandleNCHitTest( wndPtr->hwndSelf, pt );
2072 if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
2073 hittest = 0;
2074 break;
2076 case WM_LBUTTONUP:
2077 return 0;
2079 case WM_KEYDOWN:
2080 switch(msg.wParam)
2082 case VK_UP:
2083 hittest = HTTOP;
2084 pt.x =(rectWindow.left+rectWindow.right)/2;
2085 pt.y = rectWindow.top + GetSystemMetrics(SM_CYFRAME) / 2;
2086 break;
2087 case VK_DOWN:
2088 hittest = HTBOTTOM;
2089 pt.x =(rectWindow.left+rectWindow.right)/2;
2090 pt.y = rectWindow.bottom - GetSystemMetrics(SM_CYFRAME) / 2;
2091 break;
2092 case VK_LEFT:
2093 hittest = HTLEFT;
2094 pt.x = rectWindow.left + GetSystemMetrics(SM_CXFRAME) / 2;
2095 pt.y =(rectWindow.top+rectWindow.bottom)/2;
2096 break;
2097 case VK_RIGHT:
2098 hittest = HTRIGHT;
2099 pt.x = rectWindow.right - GetSystemMetrics(SM_CXFRAME) / 2;
2100 pt.y =(rectWindow.top+rectWindow.bottom)/2;
2101 break;
2102 case VK_RETURN:
2103 case VK_ESCAPE: return 0;
2107 *capturePoint = pt;
2109 SetCursorPos( pt.x, pt.y );
2110 NC_HandleSetCursor( wndPtr->hwndSelf,
2111 wndPtr->hwndSelf, MAKELONG( hittest, WM_MOUSEMOVE ));
2112 return hittest;
2116 /***********************************************************************
2117 * NC_DoSizeMove
2119 * Perform SC_MOVE and SC_SIZE commands. `
2121 static void NC_DoSizeMove( HWND hwnd, WORD wParam )
2123 MSG msg;
2124 RECT sizingRect, mouseRect, origRect;
2125 HDC hdc;
2126 LONG hittest = (LONG)(wParam & 0x0f);
2127 HCURSOR16 hDragCursor = 0, hOldCursor = 0;
2128 POINT minTrack, maxTrack;
2129 POINT16 capturePoint, pt;
2130 WND * wndPtr = WIN_FindWndPtr( hwnd );
2131 BOOL thickframe = HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle );
2132 BOOL iconic = wndPtr->dwStyle & WS_MINIMIZE;
2133 BOOL moved = FALSE;
2134 DWORD dwPoint = GetMessagePos ();
2135 BOOL DragFullWindows = FALSE;
2136 int iWndsLocks;
2138 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS, 0, &DragFullWindows, 0);
2140 capturePoint = pt = *(POINT16*)&dwPoint;
2142 if (IsZoomed(hwnd) || !IsWindowVisible(hwnd) ||
2143 (wndPtr->flags & WIN_MANAGED)) goto END;
2145 if ((wParam & 0xfff0) == SC_MOVE)
2147 if (!hittest)
2148 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2149 if (!hittest) goto END;
2151 else /* SC_SIZE */
2153 if (!thickframe) goto END;
2154 if ( hittest && hittest != HTSYSMENU ) hittest += 2;
2155 else
2157 SetCapture(hwnd);
2158 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2159 if (!hittest)
2161 ReleaseCapture();
2162 goto END;
2167 /* Get min/max info */
2169 WINPOS_GetMinMaxInfo( wndPtr, NULL, NULL, &minTrack, &maxTrack );
2170 sizingRect = wndPtr->rectWindow;
2171 origRect = sizingRect;
2172 if (wndPtr->dwStyle & WS_CHILD)
2173 GetClientRect( wndPtr->parent->hwndSelf, &mouseRect );
2174 else
2175 SetRect(&mouseRect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
2176 if (ON_LEFT_BORDER(hittest))
2178 mouseRect.left = max( mouseRect.left, sizingRect.right-maxTrack.x );
2179 mouseRect.right = min( mouseRect.right, sizingRect.right-minTrack.x );
2181 else if (ON_RIGHT_BORDER(hittest))
2183 mouseRect.left = max( mouseRect.left, sizingRect.left+minTrack.x );
2184 mouseRect.right = min( mouseRect.right, sizingRect.left+maxTrack.x );
2186 if (ON_TOP_BORDER(hittest))
2188 mouseRect.top = max( mouseRect.top, sizingRect.bottom-maxTrack.y );
2189 mouseRect.bottom = min( mouseRect.bottom,sizingRect.bottom-minTrack.y);
2191 else if (ON_BOTTOM_BORDER(hittest))
2193 mouseRect.top = max( mouseRect.top, sizingRect.top+minTrack.y );
2194 mouseRect.bottom = min( mouseRect.bottom, sizingRect.top+maxTrack.y );
2196 if (wndPtr->dwStyle & WS_CHILD)
2198 MapWindowPoints( wndPtr->parent->hwndSelf, 0,
2199 (LPPOINT)&mouseRect, 2 );
2201 SendMessage16( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
2203 if (GetCapture() != hwnd) SetCapture( hwnd );
2205 if (wndPtr->dwStyle & WS_CHILD)
2207 /* Retrieve a default cache DC (without using the window style) */
2208 hdc = GetDCEx( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
2210 else
2211 { /* Grab the server only when moving top-level windows without desktop */
2212 hdc = GetDC( 0 );
2215 wndPtr->pDriver->pPreSizeMove(wndPtr);
2217 if( iconic ) /* create a cursor for dragging */
2219 HICON16 hIcon = GetClassWord(wndPtr->hwndSelf, GCW_HICON);
2220 if(!hIcon) hIcon = (HICON16) SendMessage16( hwnd, WM_QUERYDRAGICON, 0, 0L);
2221 if( hIcon ) hDragCursor = CURSORICON_IconToCursor( hIcon, TRUE );
2222 if( !hDragCursor ) iconic = FALSE;
2225 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
2226 if( !iconic && TWEAK_WineLook == WIN31_LOOK )
2227 if(!DragFullWindows)
2228 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2230 while(1)
2232 int dx = 0, dy = 0;
2234 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE, NULL );
2236 /* Exit on button-up, Return, or Esc */
2237 if ((msg.message == WM_LBUTTONUP) ||
2238 ((msg.message == WM_KEYDOWN) &&
2239 ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
2241 if (msg.message == WM_PAINT)
2243 if(!iconic && !DragFullWindows) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2244 UpdateWindow( msg.hwnd );
2245 if(!iconic && !DragFullWindows) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2246 continue;
2249 if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
2250 continue; /* We are not interested in other messages */
2252 CONV_POINT32TO16(&msg.pt, &pt);
2254 if (msg.message == WM_KEYDOWN) switch(msg.wParam)
2256 case VK_UP: pt.y -= 8; break;
2257 case VK_DOWN: pt.y += 8; break;
2258 case VK_LEFT: pt.x -= 8; break;
2259 case VK_RIGHT: pt.x += 8; break;
2262 pt.x = max( pt.x, mouseRect.left );
2263 pt.x = min( pt.x, mouseRect.right );
2264 pt.y = max( pt.y, mouseRect.top );
2265 pt.y = min( pt.y, mouseRect.bottom );
2267 dx = pt.x - capturePoint.x;
2268 dy = pt.y - capturePoint.y;
2270 if (dx || dy)
2272 if( !moved )
2274 moved = TRUE;
2276 if( iconic ) /* ok, no system popup tracking */
2278 hOldCursor = SetCursor(hDragCursor);
2279 ShowCursor( TRUE );
2280 WINPOS_ShowIconTitle( wndPtr, FALSE );
2281 } else if(TWEAK_WineLook != WIN31_LOOK)
2283 if(!DragFullWindows)
2284 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2288 if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
2289 else
2291 RECT newRect = sizingRect;
2292 WPARAM wpSizingHit = 0;
2294 if (hittest == HTCAPTION) OffsetRect( &newRect, dx, dy );
2295 if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
2296 else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
2297 if (ON_TOP_BORDER(hittest)) newRect.top += dy;
2298 else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
2299 if(!iconic && !DragFullWindows) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2300 capturePoint = pt;
2302 /* determine the hit location */
2303 if (hittest >= HTLEFT && hittest <= HTBOTTOMRIGHT)
2304 wpSizingHit = WMSZ_LEFT + (hittest - HTLEFT);
2305 SendMessageA( hwnd, WM_SIZING, wpSizingHit, (LPARAM)&newRect );
2307 if (!iconic)
2309 if(!DragFullWindows)
2310 NC_DrawMovingFrame( hdc, &newRect, thickframe );
2311 else {
2312 /* To avoid any deadlocks, all the locks on the windows
2313 structures must be suspended before the SetWindowPos */
2314 iWndsLocks = WIN_SuspendWndsLock();
2315 SetWindowPos( hwnd, 0, newRect.left, newRect.top,
2316 newRect.right - newRect.left,
2317 newRect.bottom - newRect.top,
2318 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
2319 WIN_RestoreWndsLock(iWndsLocks);
2322 sizingRect = newRect;
2327 ReleaseCapture();
2328 if( iconic )
2330 if( moved ) /* restore cursors, show icon title later on */
2332 ShowCursor( FALSE );
2333 SetCursor( hOldCursor );
2335 DestroyCursor( hDragCursor );
2337 else if(moved || TWEAK_WineLook == WIN31_LOOK)
2338 if(!DragFullWindows)
2339 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2341 if (wndPtr->dwStyle & WS_CHILD)
2342 ReleaseDC( wndPtr->parent->hwndSelf, hdc );
2343 else
2344 ReleaseDC( 0, hdc );
2346 wndPtr->pDriver->pPostSizeMove(wndPtr);
2348 if (HOOK_IsHooked( WH_CBT ))
2350 RECT16* pr = SEGPTR_NEW(RECT16);
2351 if( pr )
2353 CONV_RECT32TO16( &sizingRect, pr );
2354 if( HOOK_CallHooks16( WH_CBT, HCBT_MOVESIZE, hwnd,
2355 (LPARAM)SEGPTR_GET(pr)) )
2356 sizingRect = wndPtr->rectWindow;
2357 else
2358 CONV_RECT16TO32( pr, &sizingRect );
2359 SEGPTR_FREE(pr);
2362 SendMessage16( hwnd, WM_EXITSIZEMOVE, 0, 0 );
2363 SendMessage16( hwnd, WM_SETVISIBLE, !IsIconic16(hwnd), 0L);
2365 /* window moved or resized */
2366 if (moved)
2368 /* To avoid any deadlocks, all the locks on the windows
2369 structures must be suspended before the SetWindowPos */
2370 iWndsLocks = WIN_SuspendWndsLock();
2372 /* if the moving/resizing isn't canceled call SetWindowPos
2373 * with the new position or the new size of the window
2375 if (!((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
2377 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
2378 if(!DragFullWindows)
2379 SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top,
2380 sizingRect.right - sizingRect.left,
2381 sizingRect.bottom - sizingRect.top,
2382 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
2384 else { /* restore previous size/position */
2385 if(DragFullWindows)
2386 SetWindowPos( hwnd, 0, origRect.left, origRect.top,
2387 origRect.right - origRect.left,
2388 origRect.bottom - origRect.top,
2389 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
2392 WIN_RestoreWndsLock(iWndsLocks);
2395 if( IsWindow(hwnd) )
2396 if( wndPtr->dwStyle & WS_MINIMIZE )
2398 /* Single click brings up the system menu when iconized */
2400 if( !moved )
2402 if( wndPtr->dwStyle & WS_SYSMENU )
2403 SendMessage16( hwnd, WM_SYSCOMMAND,
2404 SC_MOUSEMENU + HTSYSMENU, *((LPARAM*)&pt));
2406 else WINPOS_ShowIconTitle( wndPtr, TRUE );
2409 END:
2410 WIN_ReleaseWndPtr(wndPtr);
2414 /***********************************************************************
2415 * NC_TrackMinMaxBox95
2417 * Track a mouse button press on the minimize or maximize box.
2419 * The big difference between 3.1 and 95 is the disabled button state.
2420 * In win95 the system button can be disabled, so it can ignore the mouse
2421 * event.
2424 static void NC_TrackMinMaxBox95( HWND hwnd, WORD wParam )
2426 MSG msg;
2427 POINT16 pt16;
2428 HDC hdc = GetWindowDC( hwnd );
2429 BOOL pressed = TRUE;
2430 UINT state;
2431 DWORD wndStyle = GetWindowLongA( hwnd, GWL_STYLE);
2432 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
2434 void (*paintButton)(HWND, HDC16, BOOL, BOOL);
2436 if (wParam == HTMINBUTTON)
2438 /* If the style is not present, do nothing */
2439 if (!(wndStyle & WS_MINIMIZEBOX))
2440 return;
2442 /* Check if the sysmenu item for minimize is there */
2443 state = GetMenuState(hSysMenu, SC_MINIMIZE, MF_BYCOMMAND);
2445 paintButton = &NC_DrawMinButton95;
2447 else
2449 /* If the style is not present, do nothing */
2450 if (!(wndStyle & WS_MAXIMIZEBOX))
2451 return;
2453 /* Check if the sysmenu item for maximize is there */
2454 state = GetMenuState(hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
2456 paintButton = &NC_DrawMaxButton95;
2459 SetCapture( hwnd );
2461 (*paintButton)( hwnd, hdc, TRUE, FALSE);
2465 BOOL oldstate = pressed;
2466 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2467 CONV_POINT32TO16( &msg.pt, &pt16 );
2469 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2470 if (pressed != oldstate)
2471 (*paintButton)( hwnd, hdc, pressed, FALSE);
2472 } while (msg.message != WM_LBUTTONUP);
2474 (*paintButton)( hwnd, hdc, FALSE, FALSE);
2476 ReleaseCapture();
2477 ReleaseDC( hwnd, hdc );
2479 /* If the item minimize or maximize of the sysmenu are not there */
2480 /* or if the style is not present, do nothing */
2481 if ((!pressed) || (state == 0xFFFFFFFF))
2482 return;
2484 if (wParam == HTMINBUTTON)
2485 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&pt16 );
2486 else
2487 SendMessage16( hwnd, WM_SYSCOMMAND,
2488 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, *(LONG*)&pt16 );
2491 /***********************************************************************
2492 * NC_TrackMinMaxBox
2494 * Track a mouse button press on the minimize or maximize box.
2496 static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
2498 MSG msg;
2499 POINT16 pt16;
2500 HDC hdc = GetWindowDC( hwnd );
2501 BOOL pressed = TRUE;
2502 void (*paintButton)(HWND, HDC16, BOOL);
2504 SetCapture( hwnd );
2506 if (wParam == HTMINBUTTON)
2507 paintButton = &NC_DrawMinButton;
2508 else
2509 paintButton = &NC_DrawMaxButton;
2511 (*paintButton)( hwnd, hdc, TRUE);
2515 BOOL oldstate = pressed;
2516 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2517 CONV_POINT32TO16( &msg.pt, &pt16 );
2519 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2520 if (pressed != oldstate)
2521 (*paintButton)( hwnd, hdc, pressed);
2522 } while (msg.message != WM_LBUTTONUP);
2524 (*paintButton)( hwnd, hdc, FALSE);
2526 ReleaseCapture();
2527 ReleaseDC( hwnd, hdc );
2529 if (!pressed) return;
2531 if (wParam == HTMINBUTTON)
2532 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&pt16 );
2533 else
2534 SendMessage16( hwnd, WM_SYSCOMMAND,
2535 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, *(LONG*)&pt16 );
2539 /***********************************************************************
2540 * NC_TrackCloseButton95
2542 * Track a mouse button press on the Win95 close button.
2544 static void
2545 NC_TrackCloseButton95 (HWND hwnd, WORD wParam)
2547 MSG msg;
2548 POINT16 pt16;
2549 HDC hdc;
2550 BOOL pressed = TRUE;
2551 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
2552 UINT state;
2554 if(hSysMenu == 0)
2555 return;
2557 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
2559 /* If the item close of the sysmenu is disabled or not there do nothing */
2560 if((state & MF_DISABLED) || (state & MF_GRAYED) || (state == 0xFFFFFFFF))
2561 return;
2563 hdc = GetWindowDC( hwnd );
2565 SetCapture( hwnd );
2567 NC_DrawCloseButton95 (hwnd, hdc, TRUE, FALSE);
2571 BOOL oldstate = pressed;
2572 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2573 CONV_POINT32TO16( &msg.pt, &pt16 );
2575 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2576 if (pressed != oldstate)
2577 NC_DrawCloseButton95 (hwnd, hdc, pressed, FALSE);
2578 } while (msg.message != WM_LBUTTONUP);
2580 NC_DrawCloseButton95 (hwnd, hdc, FALSE, FALSE);
2582 ReleaseCapture();
2583 ReleaseDC( hwnd, hdc );
2584 if (!pressed) return;
2586 SendMessage16( hwnd, WM_SYSCOMMAND, SC_CLOSE, *(LONG*)&pt16 );
2590 /***********************************************************************
2591 * NC_TrackScrollBar
2593 * Track a mouse button press on the horizontal or vertical scroll-bar.
2595 static void NC_TrackScrollBar( HWND hwnd, WPARAM wParam, POINT pt )
2597 MSG16 *msg;
2598 INT scrollbar;
2599 WND *wndPtr = WIN_FindWndPtr( hwnd );
2601 if ((wParam & 0xfff0) == SC_HSCROLL)
2603 if ((wParam & 0x0f) != HTHSCROLL) goto END;
2604 scrollbar = SB_HORZ;
2606 else /* SC_VSCROLL */
2608 if ((wParam & 0x0f) != HTVSCROLL) goto END;
2609 scrollbar = SB_VERT;
2612 if (!(msg = SEGPTR_NEW(MSG16))) goto END;
2613 pt.x -= wndPtr->rectWindow.left;
2614 pt.y -= wndPtr->rectWindow.top;
2615 SetCapture( hwnd );
2616 SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt );
2620 GetMessage16( SEGPTR_GET(msg), 0, 0, 0 );
2621 switch(msg->message)
2623 case WM_LBUTTONUP:
2624 case WM_MOUSEMOVE:
2625 case WM_SYSTIMER:
2626 pt.x = LOWORD(msg->lParam) + wndPtr->rectClient.left -
2627 wndPtr->rectWindow.left;
2628 pt.y = HIWORD(msg->lParam) + wndPtr->rectClient.top -
2629 wndPtr->rectWindow.top;
2630 SCROLL_HandleScrollEvent( hwnd, scrollbar, msg->message, pt );
2631 break;
2632 default:
2633 TranslateMessage16( msg );
2634 DispatchMessage16( msg );
2635 break;
2637 if (!IsWindow( hwnd ))
2639 ReleaseCapture();
2640 break;
2642 } while (msg->message != WM_LBUTTONUP);
2643 SEGPTR_FREE(msg);
2644 END:
2645 WIN_ReleaseWndPtr(wndPtr);
2648 /***********************************************************************
2649 * NC_HandleNCLButtonDown
2651 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2653 LONG NC_HandleNCLButtonDown( WND* pWnd, WPARAM16 wParam, LPARAM lParam )
2655 HWND hwnd = pWnd->hwndSelf;
2657 switch(wParam) /* Hit test */
2659 case HTCAPTION:
2660 hwnd = WIN_GetTopParent(hwnd);
2662 if( WINPOS_SetActiveWindow(hwnd, TRUE, TRUE) || (GetActiveWindow() == hwnd) )
2663 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
2664 break;
2666 case HTSYSMENU:
2667 if( pWnd->dwStyle & WS_SYSMENU )
2669 if( !(pWnd->dwStyle & WS_MINIMIZE) )
2671 HDC hDC = GetWindowDC(hwnd);
2672 if (TWEAK_WineLook == WIN31_LOOK)
2673 NC_DrawSysButton( hwnd, hDC, TRUE );
2674 else
2675 NC_DrawSysButton95( hwnd, hDC, TRUE );
2676 ReleaseDC( hwnd, hDC );
2678 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
2680 break;
2682 case HTMENU:
2683 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam );
2684 break;
2686 case HTHSCROLL:
2687 SendMessage16( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
2688 break;
2690 case HTVSCROLL:
2691 SendMessage16( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
2692 break;
2694 case HTMINBUTTON:
2695 case HTMAXBUTTON:
2696 if (TWEAK_WineLook == WIN31_LOOK)
2697 NC_TrackMinMaxBox( hwnd, wParam );
2698 else
2699 NC_TrackMinMaxBox95( hwnd, wParam );
2700 break;
2702 case HTCLOSE:
2703 if (TWEAK_WineLook >= WIN95_LOOK)
2704 NC_TrackCloseButton95 (hwnd, wParam);
2705 break;
2707 case HTLEFT:
2708 case HTRIGHT:
2709 case HTTOP:
2710 case HTTOPLEFT:
2711 case HTTOPRIGHT:
2712 case HTBOTTOM:
2713 case HTBOTTOMLEFT:
2714 case HTBOTTOMRIGHT:
2715 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2716 SendMessage16( hwnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam);
2717 break;
2719 case HTBORDER:
2720 break;
2722 return 0;
2726 /***********************************************************************
2727 * NC_HandleNCLButtonDblClk
2729 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2731 LONG NC_HandleNCLButtonDblClk( WND *pWnd, WPARAM16 wParam, LPARAM lParam )
2734 * if this is an icon, send a restore since we are handling
2735 * a double click
2737 if (pWnd->dwStyle & WS_MINIMIZE)
2739 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_RESTORE, lParam );
2740 return 0;
2743 switch(wParam) /* Hit test */
2745 case HTCAPTION:
2746 /* stop processing if WS_MAXIMIZEBOX is missing */
2747 if (pWnd->dwStyle & WS_MAXIMIZEBOX)
2748 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND,
2749 (pWnd->dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
2750 lParam );
2751 break;
2753 case HTSYSMENU:
2754 if (!(GetClassWord(pWnd->hwndSelf, GCW_STYLE) & CS_NOCLOSE))
2755 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, lParam );
2756 break;
2758 case HTHSCROLL:
2759 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL,
2760 lParam );
2761 break;
2763 case HTVSCROLL:
2764 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL,
2765 lParam );
2766 break;
2768 return 0;
2772 /***********************************************************************
2773 * NC_HandleSysCommand
2775 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2777 LONG NC_HandleSysCommand( HWND hwnd, WPARAM16 wParam, POINT16 pt )
2779 WND *wndPtr = WIN_FindWndPtr( hwnd );
2780 POINT pt32;
2781 UINT16 uCommand = wParam & 0xFFF0;
2783 TRACE("Handling WM_SYSCOMMAND %x %d,%d\n", wParam, pt.x, pt.y );
2785 if (wndPtr->dwStyle & WS_CHILD && uCommand != SC_KEYMENU )
2786 ScreenToClient16( wndPtr->parent->hwndSelf, &pt );
2788 switch (uCommand)
2790 case SC_SIZE:
2791 case SC_MOVE:
2792 NC_DoSizeMove( hwnd, wParam );
2793 break;
2795 case SC_MINIMIZE:
2796 if (hwnd == GetForegroundWindow())
2797 ShowOwnedPopups(hwnd,FALSE);
2798 ShowWindow( hwnd, SW_MINIMIZE );
2799 break;
2801 case SC_MAXIMIZE:
2802 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2803 ShowOwnedPopups(hwnd,TRUE);
2804 ShowWindow( hwnd, SW_MAXIMIZE );
2805 break;
2807 case SC_RESTORE:
2808 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2809 ShowOwnedPopups(hwnd,TRUE);
2810 ShowWindow( hwnd, SW_RESTORE );
2811 break;
2813 case SC_CLOSE:
2814 WIN_ReleaseWndPtr(wndPtr);
2815 return SendMessage16( hwnd, WM_CLOSE, 0, 0 );
2817 case SC_VSCROLL:
2818 case SC_HSCROLL:
2819 CONV_POINT16TO32( &pt, &pt32 );
2820 NC_TrackScrollBar( hwnd, wParam, pt32 );
2821 break;
2823 case SC_MOUSEMENU:
2824 CONV_POINT16TO32( &pt, &pt32 );
2825 MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt32 );
2826 break;
2828 case SC_KEYMENU:
2829 MENU_TrackKbdMenuBar( wndPtr , wParam , pt.x );
2830 break;
2832 case SC_TASKLIST:
2833 WinExec( "taskman.exe", SW_SHOWNORMAL );
2834 break;
2836 case SC_SCREENSAVE:
2837 if (wParam == SC_ABOUTWINE)
2839 HMODULE hmodule = LoadLibraryA( "shell32.dll" );
2840 if (hmodule)
2842 FARPROC aboutproc = GetProcAddress( hmodule, "ShellAboutA" );
2843 if (aboutproc) aboutproc( hwnd, "Wine", WINE_RELEASE_INFO, 0 );
2844 FreeLibrary( hmodule );
2847 else
2848 if (wParam == SC_PUTMARK)
2849 TRACE_(shell)("Mark requested by user\n");
2850 break;
2852 case SC_HOTKEY:
2853 case SC_ARRANGE:
2854 case SC_NEXTWINDOW:
2855 case SC_PREVWINDOW:
2856 FIXME("unimplemented!\n");
2857 break;
2859 WIN_ReleaseWndPtr(wndPtr);
2860 return 0;
2863 /*************************************************************
2864 * NC_DrawGrayButton
2866 * Stub for the grayed button of the caption
2868 *************************************************************/
2870 BOOL NC_DrawGrayButton(HDC hdc, int x, int y)
2872 HBITMAP hMaskBmp;
2873 HDC hdcMask = CreateCompatibleDC (0);
2874 HBRUSH hOldBrush;
2876 hMaskBmp = CreateBitmap (12, 10, 1, 1, lpGrayMask);
2878 if(hMaskBmp == 0)
2879 return FALSE;
2881 SelectObject (hdcMask, hMaskBmp);
2883 /* Draw the grayed bitmap using the mask */
2884 hOldBrush = SelectObject (hdc, RGB(128, 128, 128));
2885 BitBlt (hdc, x, y, 12, 10,
2886 hdcMask, 0, 0, 0xB8074A);
2888 /* Clean up */
2889 SelectObject (hdc, hOldBrush);
2890 DeleteObject(hMaskBmp);
2891 DeleteDC (hdcMask);
2893 return TRUE;
2896 HICON16 NC_IconForWindow(WND *wndPtr)
2898 HICON16 hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICONSM);
2899 if(!hIcon) hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICON);
2901 /* If there is no hIcon specified and this is a modal dialog, */
2902 /* get the default one. */
2903 if (!hIcon && (wndPtr->dwStyle & DS_MODALFRAME))
2904 hIcon = LoadImageA(0, MAKEINTRESOURCEA(OIC_WINEICON), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
2906 return hIcon;