Use libwine and libwine_unicode directly from their build directory
[wine/multimedia.git] / windows / nonclient.c
blob9cfc8095230543c40e8e2455dbc51df6664c48d3
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->dwExStyle & WS_EX_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->dwExStyle & WS_EX_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, POINT pt )
675 RECT rect;
677 TRACE("hwnd=%04x pt=%ld,%ld\n", wndPtr->hwndSelf, pt.x, pt.y );
679 GetWindowRect(wndPtr->hwndSelf, &rect );
680 if (!PtInRect( &rect, pt )) return HTNOWHERE;
682 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
684 if (!(wndPtr->dwExStyle & WS_EX_MANAGED))
686 /* Check borders */
687 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
689 InflateRect( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
690 if (!PtInRect( &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 InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
726 else if (HAS_THINFRAME( wndPtr->dwStyle ))
727 InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
728 if (!PtInRect( &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 (!PtInRect( &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 ScreenToClient( wndPtr->hwndSelf, &pt );
760 GetClientRect( wndPtr->hwndSelf, &rect );
761 if (PtInRect( &rect, pt )) return HTCLIENT;
763 /* Check vertical scroll bar */
765 if (wndPtr->dwStyle & WS_VSCROLL)
767 rect.right += GetSystemMetrics(SM_CXVSCROLL);
768 if (PtInRect( &rect, pt )) return HTVSCROLL;
771 /* Check horizontal scroll bar */
773 if (wndPtr->dwStyle & WS_HSCROLL)
775 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
776 if (PtInRect( &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 NC_DoNCHitTest95 (WND *wndPtr, POINT pt )
810 RECT rect;
812 TRACE("hwnd=%04x pt=%ld,%ld\n", wndPtr->hwndSelf, pt.x, pt.y );
814 GetWindowRect(wndPtr->hwndSelf, &rect );
815 if (!PtInRect( &rect, pt )) return HTNOWHERE;
817 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
819 if (!(wndPtr->dwExStyle & WS_EX_MANAGED))
821 /* Check borders */
822 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
824 InflateRect( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
825 if (!PtInRect( &rect, pt ))
827 /* Check top sizing border */
828 if (pt.y < rect.top)
830 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
831 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
832 return HTTOP;
834 /* Check bottom sizing border */
835 if (pt.y >= rect.bottom)
837 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
838 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
839 return HTBOTTOM;
841 /* Check left sizing border */
842 if (pt.x < rect.left)
844 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
845 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
846 return HTLEFT;
848 /* Check right sizing border */
849 if (pt.x >= rect.right)
851 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
852 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
853 return HTRIGHT;
857 else /* No thick frame */
859 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
860 InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
861 else if (HAS_THINFRAME( wndPtr->dwStyle ))
862 InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
863 if (!PtInRect( &rect, pt )) return HTBORDER;
866 /* Check caption */
868 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
870 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
871 rect.top += GetSystemMetrics(SM_CYSMCAPTION) - 1;
872 else
873 rect.top += GetSystemMetrics(SM_CYCAPTION) - 1;
874 if (!PtInRect( &rect, pt ))
876 /* Check system menu */
877 if ((wndPtr->dwStyle & WS_SYSMENU) && !(wndPtr->dwExStyle & WS_EX_TOOLWINDOW))
879 if (NC_IconForWindow(wndPtr))
880 rect.left += GetSystemMetrics(SM_CYCAPTION) - 1;
882 if (pt.x < rect.left) return HTSYSMENU;
884 /* Check close button */
885 if (wndPtr->dwStyle & WS_SYSMENU)
886 rect.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
887 if (pt.x > rect.right) return HTCLOSE;
889 /* Check maximize box */
890 /* In win95 there is automatically a Maximize button when there is a minimize one*/
891 if ((wndPtr->dwStyle & WS_MAXIMIZEBOX)|| (wndPtr->dwStyle & WS_MINIMIZEBOX))
892 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
893 if (pt.x > rect.right) return HTMAXBUTTON;
895 /* Check minimize box */
896 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
897 if ((wndPtr->dwStyle & WS_MINIMIZEBOX)||(wndPtr->dwStyle & WS_MAXIMIZEBOX))
898 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
900 if (pt.x > rect.right) return HTMINBUTTON;
901 return HTCAPTION;
906 /* Check client area */
908 ScreenToClient( wndPtr->hwndSelf, &pt );
909 GetClientRect( wndPtr->hwndSelf, &rect );
910 if (PtInRect( &rect, pt )) return HTCLIENT;
912 /* Check vertical scroll bar */
914 if (wndPtr->dwStyle & WS_VSCROLL)
916 rect.right += GetSystemMetrics(SM_CXVSCROLL);
917 if (PtInRect( &rect, pt )) return HTVSCROLL;
920 /* Check horizontal scroll bar */
922 if (wndPtr->dwStyle & WS_HSCROLL)
924 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
925 if (PtInRect( &rect, pt ))
927 /* Check size box */
928 if ((wndPtr->dwStyle & WS_VSCROLL) &&
929 (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
930 return HTSIZE;
931 return HTHSCROLL;
935 /* Check menu bar */
937 if (HAS_MENU(wndPtr))
939 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
940 return HTMENU;
943 /* Has to return HTNOWHERE if nothing was found
944 Could happen when a window has a customized non client area */
945 return HTNOWHERE;
949 /***********************************************************************
950 * NC_HandleNCHitTest
952 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
954 LONG NC_HandleNCHitTest (HWND hwnd , POINT pt)
956 LONG retvalue;
957 WND *wndPtr = WIN_FindWndPtr (hwnd);
959 if (!wndPtr)
960 return HTERROR;
962 if (TWEAK_WineLook == WIN31_LOOK)
963 retvalue = NC_DoNCHitTest (wndPtr, pt);
964 else
965 retvalue = NC_DoNCHitTest95 (wndPtr, pt);
966 WIN_ReleaseWndPtr(wndPtr);
967 return retvalue;
971 /***********************************************************************
972 * NC_DrawSysButton
974 void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down )
976 RECT rect;
977 HDC hdcMem;
978 HBITMAP hbitmap;
979 WND *wndPtr = WIN_FindWndPtr( hwnd );
981 if( !(wndPtr->dwExStyle & WS_EX_MANAGED) )
983 NC_GetInsideRect( hwnd, &rect );
984 hdcMem = CreateCompatibleDC( hdc );
985 hbitmap = SelectObject( hdcMem, hbitmapClose );
986 BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE), GetSystemMetrics(SM_CYSIZE),
987 hdcMem, (wndPtr->dwStyle & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE) : 0, 0,
988 down ? NOTSRCCOPY : SRCCOPY );
989 SelectObject( hdcMem, hbitmap );
990 DeleteDC( hdcMem );
992 WIN_ReleaseWndPtr(wndPtr);
996 /***********************************************************************
997 * NC_DrawMaxButton
999 static void NC_DrawMaxButton( HWND hwnd, HDC16 hdc, BOOL down )
1001 RECT rect;
1002 WND *wndPtr = WIN_FindWndPtr( hwnd );
1003 HDC hdcMem;
1005 if( !(wndPtr->dwExStyle & WS_EX_MANAGED) )
1007 NC_GetInsideRect( hwnd, &rect );
1008 hdcMem = CreateCompatibleDC( hdc );
1009 SelectObject( hdcMem, (IsZoomed(hwnd)
1010 ? (down ? hbitmapRestoreD : hbitmapRestore)
1011 : (down ? hbitmapMaximizeD : hbitmapMaximize)) );
1012 BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
1013 GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
1014 SRCCOPY );
1015 DeleteDC( hdcMem );
1017 WIN_ReleaseWndPtr(wndPtr);
1022 /***********************************************************************
1023 * NC_DrawMinButton
1025 static void NC_DrawMinButton( HWND hwnd, HDC16 hdc, BOOL down )
1027 RECT rect;
1028 WND *wndPtr = WIN_FindWndPtr( hwnd );
1029 HDC hdcMem;
1031 if( !(wndPtr->dwExStyle & WS_EX_MANAGED) )
1033 NC_GetInsideRect( hwnd, &rect );
1034 hdcMem = CreateCompatibleDC( hdc );
1035 SelectObject( hdcMem, (down ? hbitmapMinimizeD : hbitmapMinimize) );
1036 if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= GetSystemMetrics(SM_CXSIZE)+1;
1037 BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
1038 GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
1039 SRCCOPY );
1040 DeleteDC( hdcMem );
1042 WIN_ReleaseWndPtr(wndPtr);
1046 /******************************************************************************
1048 * void NC_DrawSysButton95(
1049 * HWND hwnd,
1050 * HDC hdc,
1051 * BOOL down )
1053 * Draws the Win95 system icon.
1055 * Revision history
1056 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1057 * Original implementation from NC_DrawSysButton source.
1058 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1059 * Fixed most bugs.
1061 *****************************************************************************/
1063 BOOL
1064 NC_DrawSysButton95 (HWND hwnd, HDC hdc, BOOL down)
1066 WND *wndPtr = WIN_FindWndPtr( hwnd );
1068 if( !(wndPtr->dwExStyle & WS_EX_MANAGED) )
1070 HICON hIcon;
1071 RECT rect;
1073 NC_GetInsideRect95( hwnd, &rect );
1075 hIcon = NC_IconForWindow( wndPtr );
1077 if (hIcon)
1078 DrawIconEx (hdc, rect.left + 2, rect.top + 2, hIcon,
1079 GetSystemMetrics(SM_CXSMICON),
1080 GetSystemMetrics(SM_CYSMICON),
1081 0, 0, DI_NORMAL);
1083 WIN_ReleaseWndPtr(wndPtr);
1084 return (hIcon != 0);
1086 WIN_ReleaseWndPtr(wndPtr);
1087 return FALSE;
1091 /******************************************************************************
1093 * void NC_DrawCloseButton95(
1094 * HWND hwnd,
1095 * HDC hdc,
1096 * BOOL down,
1097 * BOOL bGrayed )
1099 * Draws the Win95 close button.
1101 * If bGrayed is true, then draw a disabled Close button
1103 * Revision history
1104 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1105 * Original implementation from NC_DrawSysButton95 source.
1107 *****************************************************************************/
1109 static void NC_DrawCloseButton95 (HWND hwnd, HDC hdc, BOOL down, BOOL bGrayed)
1111 RECT rect;
1112 HDC hdcMem;
1113 WND *wndPtr = WIN_FindWndPtr( hwnd );
1115 if( !(wndPtr->dwExStyle & WS_EX_MANAGED) )
1117 BITMAP bmp;
1118 HBITMAP hBmp, hOldBmp;
1120 NC_GetInsideRect95( hwnd, &rect );
1122 /* A tool window has a smaller Close button */
1123 if(wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
1125 RECT toolRect;
1126 INT iBmpHeight = 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
1127 INT iBmpWidth = 11; /* it uses 11x11 for the close button in tool window */
1128 INT iCaptionHeight = GetSystemMetrics(SM_CYSMCAPTION);
1130 toolRect.top = rect.top + (iCaptionHeight - 1 - iBmpHeight) / 2;
1131 toolRect.left = rect.right - (iCaptionHeight + 1 + iBmpWidth) / 2;
1132 toolRect.bottom = toolRect.top + iBmpHeight;
1133 toolRect.right = toolRect.left + iBmpWidth;
1134 DrawFrameControl(hdc,&toolRect,
1135 DFC_CAPTION,DFCS_CAPTIONCLOSE |
1136 down ? DFCS_PUSHED : 0 |
1137 bGrayed ? DFCS_INACTIVE : 0);
1139 else
1141 hdcMem = CreateCompatibleDC( hdc );
1142 hBmp = down ? hbitmapCloseD : hbitmapClose;
1143 hOldBmp = SelectObject (hdcMem, hBmp);
1144 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1146 BitBlt (hdc, rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2,
1147 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1148 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);
1150 if(bGrayed)
1151 NC_DrawGrayButton(hdc,rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2 + 2,
1152 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1154 SelectObject (hdcMem, hOldBmp);
1155 DeleteDC (hdcMem);
1158 WIN_ReleaseWndPtr(wndPtr);
1161 /******************************************************************************
1163 * NC_DrawMaxButton95(
1164 * HWND hwnd,
1165 * HDC16 hdc,
1166 * BOOL down
1167 * BOOL bGrayed )
1169 * Draws the maximize button for Win95 style windows.
1171 * If bGrayed is true, then draw a disabled Maximize button
1173 * Bugs
1174 * Many. Spacing might still be incorrect. Need to fit a close
1175 * button between the max button and the edge.
1176 * Should scale the image with the title bar. And more...
1178 * Revision history
1179 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1180 * Original implementation.
1182 *****************************************************************************/
1184 static void NC_DrawMaxButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
1186 RECT rect;
1187 HDC hdcMem;
1188 WND *wndPtr = WIN_FindWndPtr( hwnd );
1190 if( !(wndPtr->dwExStyle & WS_EX_MANAGED))
1192 BITMAP bmp;
1193 HBITMAP hBmp,hOldBmp;
1195 NC_GetInsideRect95( hwnd, &rect );
1196 hdcMem = CreateCompatibleDC( hdc );
1197 hBmp = IsZoomed(hwnd) ?
1198 (down ? hbitmapRestoreD : hbitmapRestore ) :
1199 (down ? hbitmapMaximizeD: hbitmapMaximize);
1200 hOldBmp=SelectObject( hdcMem, hBmp );
1201 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1203 if (wndPtr->dwStyle & WS_SYSMENU)
1204 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1206 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1207 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1208 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1210 if(bGrayed)
1211 NC_DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
1212 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1215 SelectObject (hdcMem, hOldBmp);
1216 DeleteDC( hdcMem );
1218 WIN_ReleaseWndPtr(wndPtr);
1221 /******************************************************************************
1223 * NC_DrawMinButton95(
1224 * HWND hwnd,
1225 * HDC16 hdc,
1226 * BOOL down,
1227 * BOOL bGrayed )
1229 * Draws the minimize button for Win95 style windows.
1231 * If bGrayed is true, then draw a disabled Minimize button
1233 * Bugs
1234 * Many. Spacing is still incorrect. Should scale the image with the
1235 * title bar. And more...
1237 * Revision history
1238 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1239 * Original implementation.
1241 *****************************************************************************/
1243 static void NC_DrawMinButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
1245 RECT rect;
1246 HDC hdcMem;
1247 WND *wndPtr = WIN_FindWndPtr( hwnd );
1249 if( !(wndPtr->dwExStyle & WS_EX_MANAGED))
1252 BITMAP bmp;
1253 HBITMAP hBmp,hOldBmp;
1255 NC_GetInsideRect95( hwnd, &rect );
1257 hdcMem = CreateCompatibleDC( hdc );
1258 hBmp = down ? hbitmapMinimizeD : hbitmapMinimize;
1259 hOldBmp= SelectObject( hdcMem, hBmp );
1260 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1262 if (wndPtr->dwStyle & WS_SYSMENU)
1263 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1265 /* In win 95 there is always a Maximize box when there is a Minimize one */
1266 if ((wndPtr->dwStyle & WS_MAXIMIZEBOX) || (wndPtr->dwStyle & WS_MINIMIZEBOX))
1267 rect.right += -1 - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2;
1269 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1270 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1271 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1273 if(bGrayed)
1274 NC_DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
1275 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1278 SelectObject (hdcMem, hOldBmp);
1279 DeleteDC( hdcMem );
1281 WIN_ReleaseWndPtr(wndPtr);
1284 /***********************************************************************
1285 * NC_DrawFrame
1287 * Draw a window frame inside the given rectangle, and update the rectangle.
1288 * The correct pen for the frame must be selected in the DC.
1290 static void NC_DrawFrame( HDC hdc, RECT *rect, BOOL dlgFrame,
1291 BOOL active )
1293 INT width, height;
1295 if (TWEAK_WineLook != WIN31_LOOK)
1296 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
1298 if (dlgFrame)
1300 width = GetSystemMetrics(SM_CXDLGFRAME) - 1;
1301 height = GetSystemMetrics(SM_CYDLGFRAME) - 1;
1302 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1303 COLOR_INACTIVECAPTION) );
1305 else
1307 width = GetSystemMetrics(SM_CXFRAME) - 2;
1308 height = GetSystemMetrics(SM_CYFRAME) - 2;
1309 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1310 COLOR_INACTIVEBORDER) );
1313 /* Draw frame */
1314 PatBlt( hdc, rect->left, rect->top,
1315 rect->right - rect->left, height, PATCOPY );
1316 PatBlt( hdc, rect->left, rect->top,
1317 width, rect->bottom - rect->top, PATCOPY );
1318 PatBlt( hdc, rect->left, rect->bottom - 1,
1319 rect->right - rect->left, -height, PATCOPY );
1320 PatBlt( hdc, rect->right - 1, rect->top,
1321 -width, rect->bottom - rect->top, PATCOPY );
1323 if (dlgFrame)
1325 InflateRect( rect, -width, -height );
1327 else
1329 INT decYOff = GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXSIZE) - 1;
1330 INT decXOff = GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYSIZE) - 1;
1332 /* Draw inner rectangle */
1334 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1335 Rectangle( hdc, rect->left + width, rect->top + height,
1336 rect->right - width , rect->bottom - height );
1338 /* Draw the decorations */
1340 MoveToEx( hdc, rect->left, rect->top + decYOff, NULL );
1341 LineTo( hdc, rect->left + width, rect->top + decYOff );
1342 MoveToEx( hdc, rect->right - 1, rect->top + decYOff, NULL );
1343 LineTo( hdc, rect->right - width - 1, rect->top + decYOff );
1344 MoveToEx( hdc, rect->left, rect->bottom - decYOff, NULL );
1345 LineTo( hdc, rect->left + width, rect->bottom - decYOff );
1346 MoveToEx( hdc, rect->right - 1, rect->bottom - decYOff, NULL );
1347 LineTo( hdc, rect->right - width - 1, rect->bottom - decYOff );
1349 MoveToEx( hdc, rect->left + decXOff, rect->top, NULL );
1350 LineTo( hdc, rect->left + decXOff, rect->top + height);
1351 MoveToEx( hdc, rect->left + decXOff, rect->bottom - 1, NULL );
1352 LineTo( hdc, rect->left + decXOff, rect->bottom - height - 1 );
1353 MoveToEx( hdc, rect->right - decXOff, rect->top, NULL );
1354 LineTo( hdc, rect->right - decXOff, rect->top + height );
1355 MoveToEx( hdc, rect->right - decXOff, rect->bottom - 1, NULL );
1356 LineTo( hdc, rect->right - decXOff, rect->bottom - height - 1 );
1358 InflateRect( rect, -width - 1, -height - 1 );
1363 /******************************************************************************
1365 * void NC_DrawFrame95(
1366 * HDC hdc,
1367 * RECT *rect,
1368 * BOOL dlgFrame,
1369 * BOOL active )
1371 * Draw a window frame inside the given rectangle, and update the rectangle.
1372 * The correct pen for the frame must be selected in the DC.
1374 * Bugs
1375 * Many. First, just what IS a frame in Win95? Note that the 3D look
1376 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1377 * edge. The inner rectangle just inside the frame is handled by the
1378 * Caption code.
1380 * In short, for most people, this function should be a nop (unless
1381 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1382 * them lately, but just to get this code right). Even so, it doesn't
1383 * appear to be so. It's being worked on...
1385 * Revision history
1386 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1387 * Original implementation (based on NC_DrawFrame)
1388 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1389 * Some minor fixes.
1390 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1391 * Fixed a fix or something.
1393 *****************************************************************************/
1395 static void NC_DrawFrame95(
1396 HDC hdc,
1397 RECT *rect,
1398 BOOL dlgFrame,
1399 BOOL active )
1401 INT width, height;
1403 if (dlgFrame)
1405 width = GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
1406 height = GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
1408 else
1410 width = GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXEDGE);
1411 height = GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYEDGE);
1414 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1415 COLOR_INACTIVEBORDER) );
1417 /* Draw frame */
1418 PatBlt( hdc, rect->left, rect->top,
1419 rect->right - rect->left, height, PATCOPY );
1420 PatBlt( hdc, rect->left, rect->top,
1421 width, rect->bottom - rect->top, PATCOPY );
1422 PatBlt( hdc, rect->left, rect->bottom - 1,
1423 rect->right - rect->left, -height, PATCOPY );
1424 PatBlt( hdc, rect->right - 1, rect->top,
1425 -width, rect->bottom - rect->top, PATCOPY );
1427 InflateRect( rect, -width, -height );
1430 /***********************************************************************
1431 * NC_DrawMovingFrame
1433 * Draw the frame used when moving or resizing window.
1435 * FIXME: This causes problems in Win95 mode. (why?)
1437 static void NC_DrawMovingFrame( HDC hdc, RECT *rect, BOOL thickframe )
1439 if (thickframe)
1441 RECT16 r16;
1442 CONV_RECT32TO16( rect, &r16 );
1443 FastWindowFrame16( hdc, &r16, GetSystemMetrics(SM_CXFRAME),
1444 GetSystemMetrics(SM_CYFRAME), PATINVERT );
1446 else DrawFocusRect( hdc, rect );
1450 /***********************************************************************
1451 * NC_DrawCaption
1453 * Draw the window caption.
1454 * The correct pen for the window frame must be selected in the DC.
1456 static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd,
1457 DWORD style, BOOL active )
1459 RECT r = *rect;
1460 WND * wndPtr = WIN_FindWndPtr( hwnd );
1461 char buffer[256];
1463 if (wndPtr->dwExStyle & WS_EX_MANAGED)
1465 WIN_ReleaseWndPtr(wndPtr);
1466 return;
1469 if (!hbitmapClose)
1471 if (!(hbitmapClose = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_CLOSE) )))
1473 WIN_ReleaseWndPtr(wndPtr);
1474 return;
1476 hbitmapCloseD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_CLOSED) );
1477 hbitmapMinimize = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_REDUCE) );
1478 hbitmapMinimizeD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_REDUCED) );
1479 hbitmapMaximize = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_ZOOM) );
1480 hbitmapMaximizeD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_ZOOMD) );
1481 hbitmapRestore = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RESTORE) );
1482 hbitmapRestoreD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RESTORED) );
1485 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
1487 HBRUSH hbrushOld = SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW) );
1488 PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
1489 PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
1490 PatBlt( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
1491 r.left++;
1492 r.right--;
1493 SelectObject( hdc, hbrushOld );
1495 WIN_ReleaseWndPtr(wndPtr);
1496 MoveToEx( hdc, r.left, r.bottom, NULL );
1497 LineTo( hdc, r.right, r.bottom );
1499 if (style & WS_SYSMENU)
1501 NC_DrawSysButton( hwnd, hdc, FALSE );
1502 r.left += GetSystemMetrics(SM_CXSIZE) + 1;
1503 MoveToEx( hdc, r.left - 1, r.top, NULL );
1504 LineTo( hdc, r.left - 1, r.bottom );
1506 if (style & WS_MAXIMIZEBOX)
1508 NC_DrawMaxButton( hwnd, hdc, FALSE );
1509 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1511 if (style & WS_MINIMIZEBOX)
1513 NC_DrawMinButton( hwnd, hdc, FALSE );
1514 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1517 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1518 COLOR_INACTIVECAPTION) );
1520 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) ))
1522 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1523 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1524 SetBkMode( hdc, TRANSPARENT );
1525 DrawTextA( hdc, buffer, -1, &r,
1526 DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );
1531 /******************************************************************************
1533 * NC_DrawCaption95(
1534 * HDC hdc,
1535 * RECT *rect,
1536 * HWND hwnd,
1537 * DWORD style,
1538 * BOOL active )
1540 * Draw the window caption for Win95 style windows.
1541 * The correct pen for the window frame must be selected in the DC.
1543 * Bugs
1544 * Hey, a function that finally works! Well, almost.
1545 * It's being worked on.
1547 * Revision history
1548 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1549 * Original implementation.
1550 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1551 * Some minor fixes.
1553 *****************************************************************************/
1555 static void NC_DrawCaption95(
1556 HDC hdc,
1557 RECT *rect,
1558 HWND hwnd,
1559 DWORD style,
1560 DWORD exStyle,
1561 BOOL active )
1563 RECT r = *rect;
1564 WND *wndPtr = WIN_FindWndPtr( hwnd );
1565 char buffer[256];
1566 HPEN hPrevPen;
1567 HMENU hSysMenu;
1569 if (wndPtr->dwExStyle & WS_EX_MANAGED)
1571 WIN_ReleaseWndPtr(wndPtr);
1572 return;
1574 WIN_ReleaseWndPtr(wndPtr);
1576 hPrevPen = SelectObject( hdc, GetSysColorPen(COLOR_3DFACE) );
1577 MoveToEx( hdc, r.left, r.bottom - 1, NULL );
1578 LineTo( hdc, r.right, r.bottom - 1 );
1579 SelectObject( hdc, hPrevPen );
1580 r.bottom--;
1582 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1583 COLOR_INACTIVECAPTION) );
1585 if (!hbitmapClose) {
1586 if (!(hbitmapClose = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_CLOSE) )))
1587 return;
1588 hbitmapCloseD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_CLOSED));
1589 hbitmapMinimize = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_REDUCE) );
1590 hbitmapMinimizeD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_REDUCED) );
1591 hbitmapMaximize = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_ZOOM) );
1592 hbitmapMaximizeD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_ZOOMD) );
1593 hbitmapRestore = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RESTORE) );
1594 hbitmapRestoreD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RESTORED) );
1597 if ((style & WS_SYSMENU) && !(exStyle & WS_EX_TOOLWINDOW)) {
1598 if (NC_DrawSysButton95 (hwnd, hdc, FALSE))
1599 r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
1602 if (style & WS_SYSMENU)
1604 UINT state;
1606 /* Go get the sysmenu */
1607 hSysMenu = GetSystemMenu(hwnd, FALSE);
1608 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
1610 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1611 NC_DrawCloseButton95 (hwnd, hdc, FALSE,
1612 ((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
1613 r.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
1615 if ((style & WS_MAXIMIZEBOX) || (style & WS_MINIMIZEBOX))
1617 /* In win95 the two buttons are always there */
1618 /* But if the menu item is not in the menu they're disabled*/
1620 NC_DrawMaxButton95( hwnd, hdc, FALSE, (!(style & WS_MAXIMIZEBOX)));
1621 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1623 NC_DrawMinButton95( hwnd, hdc, FALSE, (!(style & WS_MINIMIZEBOX)));
1624 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1628 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) )) {
1629 NONCLIENTMETRICSA nclm;
1630 HFONT hFont, hOldFont;
1631 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1632 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1633 if (exStyle & WS_EX_TOOLWINDOW)
1634 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
1635 else
1636 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
1637 hOldFont = SelectObject (hdc, hFont);
1638 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1639 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1640 SetBkMode( hdc, TRANSPARENT );
1641 r.left += 2;
1642 DrawTextA( hdc, buffer, -1, &r,
1643 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
1644 DeleteObject (SelectObject (hdc, hOldFont));
1650 /***********************************************************************
1651 * NC_DoNCPaint
1653 * Paint the non-client area. clip is currently unused.
1655 static void NC_DoNCPaint( WND* wndPtr, HRGN clip, BOOL suppress_menupaint )
1657 HDC hdc;
1658 RECT rect;
1659 BOOL active;
1660 HWND hwnd = wndPtr->hwndSelf;
1662 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1663 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1665 active = wndPtr->flags & WIN_NCACTIVATED;
1667 TRACE("%04x %d\n", hwnd, active );
1669 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1670 ((clip > 1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN): 0) ))) return;
1672 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1673 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1674 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1675 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1676 == NULLREGION)
1678 ReleaseDC( hwnd, hdc );
1679 return;
1682 rect.top = rect.left = 0;
1683 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1684 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1686 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1688 if (!(wndPtr->dwExStyle & WS_EX_MANAGED))
1690 if (HAS_ANYFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1692 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1693 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1694 InflateRect( &rect, -1, -1 );
1697 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1698 NC_DrawFrame(hdc, &rect, FALSE, active );
1699 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1700 NC_DrawFrame( hdc, &rect, TRUE, active );
1702 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1704 RECT r = rect;
1705 r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
1706 rect.top += GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYBORDER);
1707 NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active );
1711 if (HAS_MENU(wndPtr))
1713 RECT r = rect;
1714 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU); /* default height */
1715 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint );
1718 /* Draw the scroll-bars */
1720 if (wndPtr->dwStyle & WS_VSCROLL)
1721 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1722 if (wndPtr->dwStyle & WS_HSCROLL)
1723 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1725 /* Draw the "size-box" */
1727 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1729 RECT r = rect;
1730 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1731 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1732 if(wndPtr->dwStyle & WS_BORDER) {
1733 r.left++;
1734 r.top++;
1736 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1739 ReleaseDC( hwnd, hdc );
1743 /******************************************************************************
1745 * void NC_DoNCPaint95(
1746 * WND *wndPtr,
1747 * HRGN clip,
1748 * BOOL suppress_menupaint )
1750 * Paint the non-client area for Win95 windows. The clip region is
1751 * currently ignored.
1753 * Bugs
1754 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1755 * misc/tweak.c controls/menu.c # :-)
1757 * Revision history
1758 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1759 * Original implementation
1760 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1761 * Fixed some bugs.
1762 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1763 * Streamlined window style checks.
1765 *****************************************************************************/
1767 static void NC_DoNCPaint95(
1768 WND *wndPtr,
1769 HRGN clip,
1770 BOOL suppress_menupaint )
1772 HDC hdc;
1773 RECT rfuzz, rect, rectClip;
1774 BOOL active;
1775 HWND hwnd = wndPtr->hwndSelf;
1777 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1778 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1780 active = wndPtr->flags & WIN_NCACTIVATED;
1782 TRACE("%04x %d\n", hwnd, active );
1784 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1785 the call to GetDCEx implying that it is allowed not to use it either.
1786 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1787 will cause clipRgn to be deleted after ReleaseDC().
1788 Now, how is the "system" supposed to tell what happened?
1791 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1792 ((clip > 1) ?(DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0) ))) return;
1795 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1796 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1797 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1798 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1799 == NULLREGION)
1801 ReleaseDC( hwnd, hdc );
1802 return;
1805 rect.top = rect.left = 0;
1806 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1807 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1809 if( clip > 1 )
1810 GetRgnBox( clip, &rectClip );
1811 else
1813 clip = 0;
1814 rectClip = rect;
1817 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1819 if(!(wndPtr->dwExStyle & WS_EX_MANAGED)) {
1820 if (HAS_BIGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle)) {
1821 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1823 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1824 NC_DrawFrame95(hdc, &rect, FALSE, active );
1825 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1826 NC_DrawFrame95( hdc, &rect, TRUE, active );
1827 else if (HAS_THINFRAME( wndPtr->dwStyle )) {
1828 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1829 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1832 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1834 RECT r = rect;
1835 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW) {
1836 r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
1837 rect.top += GetSystemMetrics(SM_CYSMCAPTION);
1839 else {
1840 r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
1841 rect.top += GetSystemMetrics(SM_CYCAPTION);
1843 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
1844 NC_DrawCaption95 (hdc, &r, hwnd, wndPtr->dwStyle,
1845 wndPtr->dwExStyle, active);
1849 if (HAS_MENU(wndPtr))
1851 RECT r = rect;
1852 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
1854 TRACE("Calling DrawMenuBar with rect (%d, %d)-(%d, %d)\n",
1855 r.left, r.top, r.right, r.bottom);
1857 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ) + 1;
1860 TRACE("After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1861 rect.left, rect.top, rect.right, rect.bottom );
1863 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
1864 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1866 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
1867 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1869 /* Draw the scroll-bars */
1871 if (wndPtr->dwStyle & WS_VSCROLL)
1872 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1873 if (wndPtr->dwStyle & WS_HSCROLL)
1874 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1876 /* Draw the "size-box" */
1877 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1879 RECT r = rect;
1880 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1881 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1882 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1885 ReleaseDC( hwnd, hdc );
1891 /***********************************************************************
1892 * NC_HandleNCPaint
1894 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1896 LONG NC_HandleNCPaint( HWND hwnd , HRGN clip)
1898 WND* wndPtr = WIN_FindWndPtr( hwnd );
1900 if( wndPtr && wndPtr->dwStyle & WS_VISIBLE )
1902 if( wndPtr->dwStyle & WS_MINIMIZE )
1903 WINPOS_RedrawIconTitle( hwnd );
1904 else if (TWEAK_WineLook == WIN31_LOOK)
1905 NC_DoNCPaint( wndPtr, clip, FALSE );
1906 else
1907 NC_DoNCPaint95( wndPtr, clip, FALSE );
1909 WIN_ReleaseWndPtr(wndPtr);
1910 return 0;
1914 /***********************************************************************
1915 * NC_HandleNCActivate
1917 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1919 LONG NC_HandleNCActivate( WND *wndPtr, WPARAM16 wParam )
1921 WORD wStateChange;
1923 if( wParam ) wStateChange = !(wndPtr->flags & WIN_NCACTIVATED);
1924 else wStateChange = wndPtr->flags & WIN_NCACTIVATED;
1926 if( wStateChange )
1928 if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
1929 else wndPtr->flags &= ~WIN_NCACTIVATED;
1931 if( wndPtr->dwStyle & WS_MINIMIZE )
1932 WINPOS_RedrawIconTitle( wndPtr->hwndSelf );
1933 else if (TWEAK_WineLook == WIN31_LOOK)
1934 NC_DoNCPaint( wndPtr, (HRGN)1, FALSE );
1935 else
1936 NC_DoNCPaint95( wndPtr, (HRGN)1, FALSE );
1938 return TRUE;
1942 /***********************************************************************
1943 * NC_HandleSetCursor
1945 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1947 LONG NC_HandleSetCursor( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
1949 if (hwnd != (HWND)wParam) return 0; /* Don't set the cursor for child windows */
1951 switch(LOWORD(lParam))
1953 case HTERROR:
1955 WORD msg = HIWORD( lParam );
1956 if ((msg == WM_LBUTTONDOWN) || (msg == WM_MBUTTONDOWN) ||
1957 (msg == WM_RBUTTONDOWN))
1958 MessageBeep(0);
1960 break;
1962 case HTCLIENT:
1964 HICON16 hCursor = (HICON16) GetClassWord(hwnd, GCW_HCURSOR);
1965 if(hCursor) {
1966 SetCursor16(hCursor);
1967 return TRUE;
1969 return FALSE;
1972 case HTLEFT:
1973 case HTRIGHT:
1974 return (LONG)SetCursor( LoadCursorA( 0, IDC_SIZEWEA ) );
1976 case HTTOP:
1977 case HTBOTTOM:
1978 return (LONG)SetCursor( LoadCursorA( 0, IDC_SIZENSA ) );
1980 case HTTOPLEFT:
1981 case HTBOTTOMRIGHT:
1982 return (LONG)SetCursor( LoadCursorA( 0, IDC_SIZENWSEA ) );
1984 case HTTOPRIGHT:
1985 case HTBOTTOMLEFT:
1986 return (LONG)SetCursor( LoadCursorA( 0, IDC_SIZENESWA ) );
1989 /* Default cursor: arrow */
1990 return (LONG)SetCursor( LoadCursorA( 0, IDC_ARROWA ) );
1993 /***********************************************************************
1994 * NC_GetSysPopupPos
1996 BOOL NC_GetSysPopupPos( WND* wndPtr, RECT* rect )
1998 if( wndPtr->hSysMenu )
2000 if( wndPtr->dwStyle & WS_MINIMIZE )
2001 GetWindowRect( wndPtr->hwndSelf, rect );
2002 else
2004 if (TWEAK_WineLook == WIN31_LOOK)
2005 NC_GetInsideRect( wndPtr->hwndSelf, rect );
2006 else
2007 NC_GetInsideRect95( wndPtr->hwndSelf, rect );
2008 OffsetRect( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
2009 if (wndPtr->dwStyle & WS_CHILD)
2010 ClientToScreen( wndPtr->parent->hwndSelf, (POINT *)rect );
2011 if (TWEAK_WineLook == WIN31_LOOK) {
2012 rect->right = rect->left + GetSystemMetrics(SM_CXSIZE);
2013 rect->bottom = rect->top + GetSystemMetrics(SM_CYSIZE);
2015 else {
2016 rect->right = rect->left + GetSystemMetrics(SM_CYCAPTION) - 1;
2017 rect->bottom = rect->top + GetSystemMetrics(SM_CYCAPTION) - 1;
2020 return TRUE;
2022 return FALSE;
2025 /***********************************************************************
2026 * NC_StartSizeMove
2028 * Initialisation of a move or resize, when initiatied from a menu choice.
2029 * Return hit test code for caption or sizing border.
2031 static LONG NC_StartSizeMove( WND* wndPtr, WPARAM16 wParam,
2032 POINT *capturePoint )
2034 LONG hittest = 0;
2035 POINT pt;
2036 MSG msg;
2037 RECT rectWindow;
2039 GetWindowRect(wndPtr->hwndSelf,&rectWindow);
2041 if ((wParam & 0xfff0) == SC_MOVE)
2043 /* Move pointer at the center of the caption */
2044 RECT rect;
2045 if (TWEAK_WineLook == WIN31_LOOK)
2046 NC_GetInsideRect( wndPtr->hwndSelf, &rect );
2047 else
2048 NC_GetInsideRect95( wndPtr->hwndSelf, &rect );
2049 if (wndPtr->dwStyle & WS_SYSMENU)
2050 rect.left += GetSystemMetrics(SM_CXSIZE) + 1;
2051 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
2052 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
2053 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
2054 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
2055 pt.x = rectWindow.left + (rect.right - rect.left) / 2;
2056 pt.y = rectWindow.top + rect.top + GetSystemMetrics(SM_CYSIZE)/2;
2057 hittest = HTCAPTION;
2058 *capturePoint = pt;
2060 else /* SC_SIZE */
2062 while(!hittest)
2064 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE, NULL );
2065 switch(msg.message)
2067 case WM_MOUSEMOVE:
2068 hittest = NC_HandleNCHitTest( wndPtr->hwndSelf, msg.pt );
2069 if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
2070 hittest = 0;
2071 break;
2073 case WM_LBUTTONUP:
2074 return 0;
2076 case WM_KEYDOWN:
2077 switch(msg.wParam)
2079 case VK_UP:
2080 hittest = HTTOP;
2081 pt.x =(rectWindow.left+rectWindow.right)/2;
2082 pt.y = rectWindow.top + GetSystemMetrics(SM_CYFRAME) / 2;
2083 break;
2084 case VK_DOWN:
2085 hittest = HTBOTTOM;
2086 pt.x =(rectWindow.left+rectWindow.right)/2;
2087 pt.y = rectWindow.bottom - GetSystemMetrics(SM_CYFRAME) / 2;
2088 break;
2089 case VK_LEFT:
2090 hittest = HTLEFT;
2091 pt.x = rectWindow.left + GetSystemMetrics(SM_CXFRAME) / 2;
2092 pt.y =(rectWindow.top+rectWindow.bottom)/2;
2093 break;
2094 case VK_RIGHT:
2095 hittest = HTRIGHT;
2096 pt.x = rectWindow.right - GetSystemMetrics(SM_CXFRAME) / 2;
2097 pt.y =(rectWindow.top+rectWindow.bottom)/2;
2098 break;
2099 case VK_RETURN:
2100 case VK_ESCAPE: return 0;
2104 *capturePoint = pt;
2106 SetCursorPos( pt.x, pt.y );
2107 NC_HandleSetCursor( wndPtr->hwndSelf,
2108 wndPtr->hwndSelf, MAKELONG( hittest, WM_MOUSEMOVE ));
2109 return hittest;
2113 /***********************************************************************
2114 * NC_DoSizeMove
2116 * Perform SC_MOVE and SC_SIZE commands. `
2118 static void NC_DoSizeMove( HWND hwnd, WORD wParam )
2120 MSG msg;
2121 RECT sizingRect, mouseRect, origRect;
2122 HDC hdc;
2123 LONG hittest = (LONG)(wParam & 0x0f);
2124 HCURSOR16 hDragCursor = 0, hOldCursor = 0;
2125 POINT minTrack, maxTrack;
2126 POINT capturePoint, pt;
2127 WND * wndPtr = WIN_FindWndPtr( hwnd );
2128 BOOL thickframe = HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle );
2129 BOOL iconic = wndPtr->dwStyle & WS_MINIMIZE;
2130 BOOL moved = FALSE;
2131 DWORD dwPoint = GetMessagePos ();
2132 BOOL DragFullWindows = FALSE;
2133 int iWndsLocks;
2135 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS, 0, &DragFullWindows, 0);
2137 pt.x = SLOWORD(dwPoint);
2138 pt.y = SHIWORD(dwPoint);
2139 capturePoint = pt;
2141 if (IsZoomed(hwnd) || !IsWindowVisible(hwnd) ||
2142 (wndPtr->dwExStyle & WS_EX_MANAGED)) goto END;
2144 if ((wParam & 0xfff0) == SC_MOVE)
2146 if (!hittest)
2147 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2148 if (!hittest) goto END;
2150 else /* SC_SIZE */
2152 if (!thickframe) goto END;
2153 if ( hittest && hittest != HTSYSMENU ) hittest += 2;
2154 else
2156 SetCapture(hwnd);
2157 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2158 if (!hittest)
2160 ReleaseCapture();
2161 goto END;
2166 /* Get min/max info */
2168 WINPOS_GetMinMaxInfo( wndPtr, NULL, NULL, &minTrack, &maxTrack );
2169 sizingRect = wndPtr->rectWindow;
2170 origRect = sizingRect;
2171 if (wndPtr->dwStyle & WS_CHILD)
2172 GetClientRect( wndPtr->parent->hwndSelf, &mouseRect );
2173 else
2174 SetRect(&mouseRect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
2175 if (ON_LEFT_BORDER(hittest))
2177 mouseRect.left = max( mouseRect.left, sizingRect.right-maxTrack.x );
2178 mouseRect.right = min( mouseRect.right, sizingRect.right-minTrack.x );
2180 else if (ON_RIGHT_BORDER(hittest))
2182 mouseRect.left = max( mouseRect.left, sizingRect.left+minTrack.x );
2183 mouseRect.right = min( mouseRect.right, sizingRect.left+maxTrack.x );
2185 if (ON_TOP_BORDER(hittest))
2187 mouseRect.top = max( mouseRect.top, sizingRect.bottom-maxTrack.y );
2188 mouseRect.bottom = min( mouseRect.bottom,sizingRect.bottom-minTrack.y);
2190 else if (ON_BOTTOM_BORDER(hittest))
2192 mouseRect.top = max( mouseRect.top, sizingRect.top+minTrack.y );
2193 mouseRect.bottom = min( mouseRect.bottom, sizingRect.top+maxTrack.y );
2195 if (wndPtr->dwStyle & WS_CHILD)
2197 MapWindowPoints( wndPtr->parent->hwndSelf, 0,
2198 (LPPOINT)&mouseRect, 2 );
2200 SendMessageA( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
2202 if (GetCapture() != hwnd) SetCapture( hwnd );
2204 if (wndPtr->dwStyle & WS_CHILD)
2206 /* Retrieve a default cache DC (without using the window style) */
2207 hdc = GetDCEx( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
2209 else
2210 { /* Grab the server only when moving top-level windows without desktop */
2211 hdc = GetDC( 0 );
2214 wndPtr->pDriver->pPreSizeMove(wndPtr);
2216 if( iconic ) /* create a cursor for dragging */
2218 HICON16 hIcon = GetClassWord(wndPtr->hwndSelf, GCW_HICON);
2219 if(!hIcon) hIcon = (HICON16) SendMessage16( hwnd, WM_QUERYDRAGICON, 0, 0L);
2220 if( hIcon ) hDragCursor = CURSORICON_IconToCursor( hIcon, TRUE );
2221 if( !hDragCursor ) iconic = FALSE;
2224 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
2225 if( !iconic && TWEAK_WineLook == WIN31_LOOK )
2226 if(!DragFullWindows)
2227 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2229 while(1)
2231 int dx = 0, dy = 0;
2233 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE, NULL );
2235 /* Exit on button-up, Return, or Esc */
2236 if ((msg.message == WM_LBUTTONUP) ||
2237 ((msg.message == WM_KEYDOWN) &&
2238 ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
2240 if (msg.message == WM_PAINT)
2242 if(!iconic && !DragFullWindows) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2243 UpdateWindow( msg.hwnd );
2244 if(!iconic && !DragFullWindows) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2245 continue;
2248 if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
2249 continue; /* We are not interested in other messages */
2251 pt = msg.pt;
2253 if (msg.message == WM_KEYDOWN) switch(msg.wParam)
2255 case VK_UP: pt.y -= 8; break;
2256 case VK_DOWN: pt.y += 8; break;
2257 case VK_LEFT: pt.x -= 8; break;
2258 case VK_RIGHT: pt.x += 8; break;
2261 pt.x = max( pt.x, mouseRect.left );
2262 pt.x = min( pt.x, mouseRect.right );
2263 pt.y = max( pt.y, mouseRect.top );
2264 pt.y = min( pt.y, mouseRect.bottom );
2266 dx = pt.x - capturePoint.x;
2267 dy = pt.y - capturePoint.y;
2269 if (dx || dy)
2271 if( !moved )
2273 moved = TRUE;
2275 if( iconic ) /* ok, no system popup tracking */
2277 hOldCursor = SetCursor(hDragCursor);
2278 ShowCursor( TRUE );
2279 WINPOS_ShowIconTitle( wndPtr, FALSE );
2280 } else if(TWEAK_WineLook != WIN31_LOOK)
2282 if(!DragFullWindows)
2283 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2287 if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
2288 else
2290 RECT newRect = sizingRect;
2291 WPARAM wpSizingHit = 0;
2293 if (hittest == HTCAPTION) OffsetRect( &newRect, dx, dy );
2294 if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
2295 else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
2296 if (ON_TOP_BORDER(hittest)) newRect.top += dy;
2297 else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
2298 if(!iconic && !DragFullWindows) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2299 capturePoint = pt;
2301 /* determine the hit location */
2302 if (hittest >= HTLEFT && hittest <= HTBOTTOMRIGHT)
2303 wpSizingHit = WMSZ_LEFT + (hittest - HTLEFT);
2304 SendMessageA( hwnd, WM_SIZING, wpSizingHit, (LPARAM)&newRect );
2306 if (!iconic)
2308 if(!DragFullWindows)
2309 NC_DrawMovingFrame( hdc, &newRect, thickframe );
2310 else {
2311 /* To avoid any deadlocks, all the locks on the windows
2312 structures must be suspended before the SetWindowPos */
2313 iWndsLocks = WIN_SuspendWndsLock();
2314 SetWindowPos( hwnd, 0, newRect.left, newRect.top,
2315 newRect.right - newRect.left,
2316 newRect.bottom - newRect.top,
2317 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
2318 WIN_RestoreWndsLock(iWndsLocks);
2321 sizingRect = newRect;
2326 ReleaseCapture();
2327 if( iconic )
2329 if( moved ) /* restore cursors, show icon title later on */
2331 ShowCursor( FALSE );
2332 SetCursor( hOldCursor );
2334 DestroyCursor( hDragCursor );
2336 else if(moved || TWEAK_WineLook == WIN31_LOOK)
2337 if(!DragFullWindows)
2338 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2340 if (wndPtr->dwStyle & WS_CHILD)
2341 ReleaseDC( wndPtr->parent->hwndSelf, hdc );
2342 else
2343 ReleaseDC( 0, hdc );
2345 wndPtr->pDriver->pPostSizeMove(wndPtr);
2347 if (HOOK_IsHooked( WH_CBT ))
2349 RECT16* pr = SEGPTR_NEW(RECT16);
2350 if( pr )
2352 CONV_RECT32TO16( &sizingRect, pr );
2353 if( HOOK_CallHooks16( WH_CBT, HCBT_MOVESIZE, hwnd,
2354 (LPARAM)SEGPTR_GET(pr)) )
2355 sizingRect = wndPtr->rectWindow;
2356 else
2357 CONV_RECT16TO32( pr, &sizingRect );
2358 SEGPTR_FREE(pr);
2361 SendMessageA( hwnd, WM_EXITSIZEMOVE, 0, 0 );
2362 SendMessageA( hwnd, WM_SETVISIBLE, !IsIconic16(hwnd), 0L);
2364 /* window moved or resized */
2365 if (moved)
2367 /* To avoid any deadlocks, all the locks on the windows
2368 structures must be suspended before the SetWindowPos */
2369 iWndsLocks = WIN_SuspendWndsLock();
2371 /* if the moving/resizing isn't canceled call SetWindowPos
2372 * with the new position or the new size of the window
2374 if (!((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
2376 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
2377 if(!DragFullWindows)
2378 SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top,
2379 sizingRect.right - sizingRect.left,
2380 sizingRect.bottom - sizingRect.top,
2381 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
2383 else { /* restore previous size/position */
2384 if(DragFullWindows)
2385 SetWindowPos( hwnd, 0, origRect.left, origRect.top,
2386 origRect.right - origRect.left,
2387 origRect.bottom - origRect.top,
2388 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
2391 WIN_RestoreWndsLock(iWndsLocks);
2394 if( IsWindow(hwnd) )
2395 if( wndPtr->dwStyle & WS_MINIMIZE )
2397 /* Single click brings up the system menu when iconized */
2399 if( !moved )
2401 if( wndPtr->dwStyle & WS_SYSMENU )
2402 SendMessageA( hwnd, WM_SYSCOMMAND,
2403 SC_MOUSEMENU + HTSYSMENU, MAKELONG(pt.x,pt.y));
2405 else WINPOS_ShowIconTitle( wndPtr, TRUE );
2408 END:
2409 WIN_ReleaseWndPtr(wndPtr);
2413 /***********************************************************************
2414 * NC_TrackMinMaxBox95
2416 * Track a mouse button press on the minimize or maximize box.
2418 * The big difference between 3.1 and 95 is the disabled button state.
2419 * In win95 the system button can be disabled, so it can ignore the mouse
2420 * event.
2423 static void NC_TrackMinMaxBox95( HWND hwnd, WORD wParam )
2425 MSG msg;
2426 HDC hdc = GetWindowDC( hwnd );
2427 BOOL pressed = TRUE;
2428 UINT state;
2429 DWORD wndStyle = GetWindowLongA( hwnd, GWL_STYLE);
2430 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
2432 void (*paintButton)(HWND, HDC16, BOOL, BOOL);
2434 if (wParam == HTMINBUTTON)
2436 /* If the style is not present, do nothing */
2437 if (!(wndStyle & WS_MINIMIZEBOX))
2438 return;
2440 /* Check if the sysmenu item for minimize is there */
2441 state = GetMenuState(hSysMenu, SC_MINIMIZE, MF_BYCOMMAND);
2443 paintButton = &NC_DrawMinButton95;
2445 else
2447 /* If the style is not present, do nothing */
2448 if (!(wndStyle & WS_MAXIMIZEBOX))
2449 return;
2451 /* Check if the sysmenu item for maximize is there */
2452 state = GetMenuState(hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
2454 paintButton = &NC_DrawMaxButton95;
2457 SetCapture( hwnd );
2459 (*paintButton)( hwnd, hdc, TRUE, FALSE);
2461 while(1)
2463 BOOL oldstate = pressed;
2464 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2466 if(msg.message == WM_LBUTTONUP)
2467 break;
2469 if(msg.message != WM_MOUSEMOVE)
2470 continue;
2472 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
2473 if (pressed != oldstate)
2474 (*paintButton)( hwnd, hdc, pressed, FALSE);
2477 if(pressed)
2478 (*paintButton)(hwnd, hdc, FALSE, FALSE);
2480 ReleaseCapture();
2481 ReleaseDC( hwnd, hdc );
2483 /* If the item minimize or maximize of the sysmenu are not there */
2484 /* or if the style is not present, do nothing */
2485 if ((!pressed) || (state == 0xFFFFFFFF))
2486 return;
2488 if (wParam == HTMINBUTTON)
2489 SendMessageA( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
2490 else
2491 SendMessageA( hwnd, WM_SYSCOMMAND,
2492 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
2495 /***********************************************************************
2496 * NC_TrackMinMaxBox
2498 * Track a mouse button press on the minimize or maximize box.
2500 static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
2502 MSG msg;
2503 HDC hdc = GetWindowDC( hwnd );
2504 BOOL pressed = TRUE;
2505 void (*paintButton)(HWND, HDC16, BOOL);
2507 SetCapture( hwnd );
2509 if (wParam == HTMINBUTTON)
2510 paintButton = &NC_DrawMinButton;
2511 else
2512 paintButton = &NC_DrawMaxButton;
2514 (*paintButton)( hwnd, hdc, TRUE);
2516 while(1)
2518 BOOL oldstate = pressed;
2519 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2521 if(msg.message == WM_LBUTTONUP)
2522 break;
2524 if(msg.message != WM_MOUSEMOVE)
2525 continue;
2527 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
2528 if (pressed != oldstate)
2529 (*paintButton)( hwnd, hdc, pressed);
2532 if(pressed)
2533 (*paintButton)( hwnd, hdc, FALSE);
2535 ReleaseCapture();
2536 ReleaseDC( hwnd, hdc );
2538 if (!pressed) return;
2540 if (wParam == HTMINBUTTON)
2541 SendMessageA( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
2542 else
2543 SendMessageA( hwnd, WM_SYSCOMMAND,
2544 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
2548 /***********************************************************************
2549 * NC_TrackCloseButton95
2551 * Track a mouse button press on the Win95 close button.
2553 static void
2554 NC_TrackCloseButton95 (HWND hwnd, WORD wParam)
2556 MSG msg;
2557 HDC hdc;
2558 BOOL pressed = TRUE;
2559 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
2560 UINT state;
2562 if(hSysMenu == 0)
2563 return;
2565 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
2567 /* If the item close of the sysmenu is disabled or not there do nothing */
2568 if((state & MF_DISABLED) || (state & MF_GRAYED) || (state == 0xFFFFFFFF))
2569 return;
2571 hdc = GetWindowDC( hwnd );
2573 SetCapture( hwnd );
2575 NC_DrawCloseButton95 (hwnd, hdc, TRUE, FALSE);
2577 while(1)
2579 BOOL oldstate = pressed;
2580 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2582 if(msg.message == WM_LBUTTONUP)
2583 break;
2585 if(msg.message != WM_MOUSEMOVE)
2586 continue;
2588 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
2589 if (pressed != oldstate)
2590 NC_DrawCloseButton95 (hwnd, hdc, pressed, FALSE);
2593 if(pressed)
2594 NC_DrawCloseButton95 (hwnd, hdc, FALSE, FALSE);
2596 ReleaseCapture();
2597 ReleaseDC( hwnd, hdc );
2598 if (!pressed) return;
2600 SendMessageA( hwnd, WM_SYSCOMMAND, SC_CLOSE, MAKELONG(msg.pt.x,msg.pt.y) );
2604 /***********************************************************************
2605 * NC_TrackScrollBar
2607 * Track a mouse button press on the horizontal or vertical scroll-bar.
2609 static void NC_TrackScrollBar( HWND hwnd, WPARAM wParam, POINT pt )
2611 MSG16 *msg;
2612 INT scrollbar;
2613 WND *wndPtr = WIN_FindWndPtr( hwnd );
2615 if ((wParam & 0xfff0) == SC_HSCROLL)
2617 if ((wParam & 0x0f) != HTHSCROLL) goto END;
2618 scrollbar = SB_HORZ;
2620 else /* SC_VSCROLL */
2622 if ((wParam & 0x0f) != HTVSCROLL) goto END;
2623 scrollbar = SB_VERT;
2626 if (!(msg = SEGPTR_NEW(MSG16))) goto END;
2627 pt.x -= wndPtr->rectWindow.left;
2628 pt.y -= wndPtr->rectWindow.top;
2629 SetCapture( hwnd );
2630 SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt );
2634 GetMessage16( SEGPTR_GET(msg), 0, 0, 0 );
2635 switch(msg->message)
2637 case WM_LBUTTONUP:
2638 case WM_MOUSEMOVE:
2639 case WM_SYSTIMER:
2640 pt.x = LOWORD(msg->lParam) + wndPtr->rectClient.left -
2641 wndPtr->rectWindow.left;
2642 pt.y = HIWORD(msg->lParam) + wndPtr->rectClient.top -
2643 wndPtr->rectWindow.top;
2644 SCROLL_HandleScrollEvent( hwnd, scrollbar, msg->message, pt );
2645 break;
2646 default:
2647 TranslateMessage16( msg );
2648 DispatchMessage16( msg );
2649 break;
2651 if (!IsWindow( hwnd ))
2653 ReleaseCapture();
2654 break;
2656 } while (msg->message != WM_LBUTTONUP);
2657 SEGPTR_FREE(msg);
2658 END:
2659 WIN_ReleaseWndPtr(wndPtr);
2662 /***********************************************************************
2663 * NC_HandleNCLButtonDown
2665 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2667 LONG NC_HandleNCLButtonDown( WND* pWnd, WPARAM16 wParam, LPARAM lParam )
2669 HWND hwnd = pWnd->hwndSelf;
2671 switch(wParam) /* Hit test */
2673 case HTCAPTION:
2674 hwnd = WIN_GetTopParent(hwnd);
2676 if( WINPOS_SetActiveWindow(hwnd, TRUE, TRUE) || (GetActiveWindow() == hwnd) )
2677 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
2678 break;
2680 case HTSYSMENU:
2681 if( pWnd->dwStyle & WS_SYSMENU )
2683 if( !(pWnd->dwStyle & WS_MINIMIZE) )
2685 HDC hDC = GetWindowDC(hwnd);
2686 if (TWEAK_WineLook == WIN31_LOOK)
2687 NC_DrawSysButton( hwnd, hDC, TRUE );
2688 else
2689 NC_DrawSysButton95( hwnd, hDC, TRUE );
2690 ReleaseDC( hwnd, hDC );
2692 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
2694 break;
2696 case HTMENU:
2697 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam );
2698 break;
2700 case HTHSCROLL:
2701 SendMessage16( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
2702 break;
2704 case HTVSCROLL:
2705 SendMessage16( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
2706 break;
2708 case HTMINBUTTON:
2709 case HTMAXBUTTON:
2710 if (TWEAK_WineLook == WIN31_LOOK)
2711 NC_TrackMinMaxBox( hwnd, wParam );
2712 else
2713 NC_TrackMinMaxBox95( hwnd, wParam );
2714 break;
2716 case HTCLOSE:
2717 if (TWEAK_WineLook >= WIN95_LOOK)
2718 NC_TrackCloseButton95 (hwnd, wParam);
2719 break;
2721 case HTLEFT:
2722 case HTRIGHT:
2723 case HTTOP:
2724 case HTTOPLEFT:
2725 case HTTOPRIGHT:
2726 case HTBOTTOM:
2727 case HTBOTTOMLEFT:
2728 case HTBOTTOMRIGHT:
2729 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2730 SendMessage16( hwnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam);
2731 break;
2733 case HTBORDER:
2734 break;
2736 return 0;
2740 /***********************************************************************
2741 * NC_HandleNCLButtonDblClk
2743 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2745 LONG NC_HandleNCLButtonDblClk( WND *pWnd, WPARAM16 wParam, LPARAM lParam )
2748 * if this is an icon, send a restore since we are handling
2749 * a double click
2751 if (pWnd->dwStyle & WS_MINIMIZE)
2753 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_RESTORE, lParam );
2754 return 0;
2757 switch(wParam) /* Hit test */
2759 case HTCAPTION:
2760 /* stop processing if WS_MAXIMIZEBOX is missing */
2761 if (pWnd->dwStyle & WS_MAXIMIZEBOX)
2762 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND,
2763 (pWnd->dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
2764 lParam );
2765 break;
2767 case HTSYSMENU:
2768 if (!(GetClassWord(pWnd->hwndSelf, GCW_STYLE) & CS_NOCLOSE))
2769 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, lParam );
2770 break;
2772 case HTHSCROLL:
2773 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL,
2774 lParam );
2775 break;
2777 case HTVSCROLL:
2778 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL,
2779 lParam );
2780 break;
2782 return 0;
2786 /***********************************************************************
2787 * NC_HandleSysCommand
2789 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2791 LONG NC_HandleSysCommand( HWND hwnd, WPARAM wParam, POINT pt )
2793 WND *wndPtr = WIN_FindWndPtr( hwnd );
2794 UINT16 uCommand = wParam & 0xFFF0;
2796 TRACE("Handling WM_SYSCOMMAND %x %ld,%ld\n", wParam, pt.x, pt.y );
2798 if (wndPtr->dwStyle & WS_CHILD && uCommand != SC_KEYMENU )
2799 ScreenToClient( wndPtr->parent->hwndSelf, &pt );
2801 switch (uCommand)
2803 case SC_SIZE:
2804 case SC_MOVE:
2805 NC_DoSizeMove( hwnd, wParam );
2806 break;
2808 case SC_MINIMIZE:
2809 if (hwnd == GetForegroundWindow())
2810 ShowOwnedPopups(hwnd,FALSE);
2811 ShowWindow( hwnd, SW_MINIMIZE );
2812 break;
2814 case SC_MAXIMIZE:
2815 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2816 ShowOwnedPopups(hwnd,TRUE);
2817 ShowWindow( hwnd, SW_MAXIMIZE );
2818 break;
2820 case SC_RESTORE:
2821 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2822 ShowOwnedPopups(hwnd,TRUE);
2823 ShowWindow( hwnd, SW_RESTORE );
2824 break;
2826 case SC_CLOSE:
2827 WIN_ReleaseWndPtr(wndPtr);
2828 return SendMessageA( hwnd, WM_CLOSE, 0, 0 );
2830 case SC_VSCROLL:
2831 case SC_HSCROLL:
2832 NC_TrackScrollBar( hwnd, wParam, pt );
2833 break;
2835 case SC_MOUSEMENU:
2836 MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt );
2837 break;
2839 case SC_KEYMENU:
2840 MENU_TrackKbdMenuBar( wndPtr , wParam , pt.x );
2841 break;
2843 case SC_TASKLIST:
2844 WinExec( "taskman.exe", SW_SHOWNORMAL );
2845 break;
2847 case SC_SCREENSAVE:
2848 if (wParam == SC_ABOUTWINE)
2850 HMODULE hmodule = LoadLibraryA( "shell32.dll" );
2851 if (hmodule)
2853 FARPROC aboutproc = GetProcAddress( hmodule, "ShellAboutA" );
2854 if (aboutproc) aboutproc( hwnd, "Wine", WINE_RELEASE_INFO, 0 );
2855 FreeLibrary( hmodule );
2858 else
2859 if (wParam == SC_PUTMARK)
2860 TRACE_(shell)("Mark requested by user\n");
2861 break;
2863 case SC_HOTKEY:
2864 case SC_ARRANGE:
2865 case SC_NEXTWINDOW:
2866 case SC_PREVWINDOW:
2867 FIXME("unimplemented!\n");
2868 break;
2870 WIN_ReleaseWndPtr(wndPtr);
2871 return 0;
2874 /*************************************************************
2875 * NC_DrawGrayButton
2877 * Stub for the grayed button of the caption
2879 *************************************************************/
2881 BOOL NC_DrawGrayButton(HDC hdc, int x, int y)
2883 HBITMAP hMaskBmp;
2884 HDC hdcMask = CreateCompatibleDC (0);
2885 HBRUSH hOldBrush;
2887 hMaskBmp = CreateBitmap (12, 10, 1, 1, lpGrayMask);
2889 if(hMaskBmp == 0)
2890 return FALSE;
2892 SelectObject (hdcMask, hMaskBmp);
2894 /* Draw the grayed bitmap using the mask */
2895 hOldBrush = SelectObject (hdc, RGB(128, 128, 128));
2896 BitBlt (hdc, x, y, 12, 10,
2897 hdcMask, 0, 0, 0xB8074A);
2899 /* Clean up */
2900 SelectObject (hdc, hOldBrush);
2901 DeleteObject(hMaskBmp);
2902 DeleteDC (hdcMask);
2904 return TRUE;
2907 HICON16 NC_IconForWindow(WND *wndPtr)
2909 HICON16 hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICONSM);
2910 if(!hIcon) hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICON);
2912 /* If there is no hIcon specified and this is a modal dialog, */
2913 /* get the default one. */
2914 if (!hIcon && (wndPtr->dwStyle & DS_MODALFRAME))
2915 hIcon = LoadImageA(0, MAKEINTRESOURCEA(OIC_WINEICON), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
2917 return hIcon;