Documentation ordinal fixes (using winapi_fixup).
[wine/gsoc_dplay.git] / windows / nonclient.c
blobe8f8c8732c727c922b041a558c47afddd41807ef
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 "controls.h"
18 #include "cursoricon.h"
19 #include "winpos.h"
20 #include "hook.h"
21 #include "nonclient.h"
22 #include "debugtools.h"
23 #include "options.h"
24 #include "shellapi.h"
25 #include "bitmap.h"
27 DEFAULT_DEBUG_CHANNEL(nonclient);
28 DECLARE_DEBUG_CHANNEL(shell);
30 BOOL NC_DrawGrayButton(HDC hdc, int x, int y);
32 static HBITMAP hbitmapClose;
33 static HBITMAP hbitmapMinimize;
34 static HBITMAP hbitmapMinimizeD;
35 static HBITMAP hbitmapMaximize;
36 static HBITMAP hbitmapMaximizeD;
37 static HBITMAP hbitmapRestore;
38 static HBITMAP hbitmapRestoreD;
40 static const BYTE lpGrayMask[] = { 0xAA, 0xA0,
41 0x55, 0x50,
42 0xAA, 0xA0,
43 0x55, 0x50,
44 0xAA, 0xA0,
45 0x55, 0x50,
46 0xAA, 0xA0,
47 0x55, 0x50,
48 0xAA, 0xA0,
49 0x55, 0x50};
51 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
52 #define SC_PUTMARK (SC_SCREENSAVE+2)
54 /* Some useful macros */
55 #define HAS_DLGFRAME(style,exStyle) \
56 (((exStyle) & WS_EX_DLGMODALFRAME) || \
57 (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
59 #define HAS_THICKFRAME(style,exStyle) \
60 (((style) & WS_THICKFRAME) && \
61 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
63 #define HAS_THINFRAME(style) \
64 (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
66 #define HAS_BIGFRAME(style,exStyle) \
67 (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
68 ((exStyle) & WS_EX_DLGMODALFRAME))
70 #define HAS_ANYFRAME(style,exStyle) \
71 (((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
72 ((exStyle) & WS_EX_DLGMODALFRAME) || \
73 !((style) & (WS_CHILD | WS_POPUP)))
75 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
78 /***********************************************************************
79 * NC_AdjustRect
81 * Compute the size of the window rectangle from the size of the
82 * client rectangle.
84 static void NC_AdjustRect( LPRECT rect, DWORD style, BOOL menu, DWORD exStyle )
86 if (TWEAK_WineLook > WIN31_LOOK)
87 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
89 if(style & WS_ICONIC) return;
91 if (HAS_THICKFRAME( style, exStyle ))
92 InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
93 else if (HAS_DLGFRAME( style, exStyle ))
94 InflateRect( rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
95 else if (HAS_THINFRAME( style ))
96 InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
98 if ((style & WS_CAPTION) == WS_CAPTION)
99 rect->top -= GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
101 if (menu) rect->top -= GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYBORDER);
103 if (style & WS_VSCROLL) {
104 rect->right += GetSystemMetrics(SM_CXVSCROLL) - 1;
105 if(!HAS_ANYFRAME( style, exStyle ))
106 rect->right++;
109 if (style & WS_HSCROLL) {
110 rect->bottom += GetSystemMetrics(SM_CYHSCROLL) - 1;
111 if(!HAS_ANYFRAME( style, exStyle ))
112 rect->bottom++;
117 /******************************************************************************
118 * NC_AdjustRectOuter95
120 * Computes the size of the "outside" parts of the window based on the
121 * parameters of the client area.
123 + PARAMS
124 * LPRECT16 rect
125 * DWORD style
126 * BOOL menu
127 * DWORD exStyle
129 * NOTES
130 * "Outer" parts of a window means the whole window frame, caption and
131 * menu bar. It does not include "inner" parts of the frame like client
132 * edge, static edge or scroll bars.
134 * Revision history
135 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
136 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
138 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
139 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
140 * NC_AdjustRectInner95 and added handling of Win95 styles.
142 * 28-Jul-1999 Ove Kåven (ovek@arcticnet.no)
143 * Streamlined window style checks.
145 *****************************************************************************/
147 static void
148 NC_AdjustRectOuter95 (LPRECT rect, DWORD style, BOOL menu, DWORD exStyle)
150 if(style & WS_ICONIC) return;
152 if (HAS_THICKFRAME( style, exStyle ))
153 InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
154 else if (HAS_DLGFRAME( style, exStyle ))
155 InflateRect(rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
156 else if (HAS_THINFRAME( style ))
157 InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
159 if ((style & WS_CAPTION) == WS_CAPTION)
161 if (exStyle & WS_EX_TOOLWINDOW)
162 rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
163 else
164 rect->top -= GetSystemMetrics(SM_CYCAPTION);
166 if (menu) rect->top -= GetSystemMetrics(SM_CYMENU);
170 /******************************************************************************
171 * NC_AdjustRectInner95
173 * Computes the size of the "inside" part of the window based on the
174 * parameters of the client area.
176 + PARAMS
177 * LPRECT16 rect
178 * DWORD style
179 * DWORD exStyle
181 * NOTES
182 * "Inner" part of a window means the window frame inside of the flat
183 * window frame. It includes the client edge, the static edge and the
184 * scroll bars.
186 * Revision history
187 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
188 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
190 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
191 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
192 * NC_AdjustRectInner95 and added handling of Win95 styles.
194 *****************************************************************************/
196 static void
197 NC_AdjustRectInner95 (LPRECT rect, DWORD style, DWORD exStyle)
199 if(style & WS_ICONIC) return;
201 if (exStyle & WS_EX_CLIENTEDGE)
202 InflateRect(rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
204 if (exStyle & WS_EX_STATICEDGE)
205 InflateRect(rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
207 if (style & WS_VSCROLL) rect->right += GetSystemMetrics(SM_CXVSCROLL);
208 if (style & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
213 static HICON NC_IconForWindow( HWND hwnd )
215 HICON hIcon = (HICON) GetClassLongA( hwnd, GCL_HICONSM );
216 if (!hIcon) hIcon = (HICON) GetClassLongA( hwnd, GCL_HICON );
218 /* If there is no hIcon specified and this is a modal dialog,
219 * get the default one.
221 if (!hIcon && (GetWindowLongA( hwnd, GWL_STYLE ) & DS_MODALFRAME))
222 hIcon = LoadImageA(0, IDI_WINLOGOA, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
223 return hIcon;
226 /***********************************************************************
227 * DrawCaption (USER.660) Draws a caption bar
229 * PARAMS
230 * hwnd [I]
231 * hdc [I]
232 * lpRect [I]
233 * uFlags [I]
235 * RETURNS
236 * Success:
237 * Failure:
240 BOOL16 WINAPI
241 DrawCaption16 (HWND16 hwnd, HDC16 hdc, const RECT16 *rect, UINT16 uFlags)
243 RECT rect32;
245 if (rect)
246 CONV_RECT16TO32 (rect, &rect32);
248 return (BOOL16)DrawCaptionTempA (hwnd, hdc, rect ? &rect32 : NULL,
249 0, 0, NULL, uFlags & 0x1F);
253 /***********************************************************************
254 * DrawCaption (USER32.@) Draws a caption bar
256 * PARAMS
257 * hwnd [I]
258 * hdc [I]
259 * lpRect [I]
260 * uFlags [I]
262 * RETURNS
263 * Success:
264 * Failure:
267 BOOL WINAPI
268 DrawCaption (HWND hwnd, HDC hdc, const RECT *lpRect, UINT uFlags)
270 return DrawCaptionTempA (hwnd, hdc, lpRect, 0, 0, NULL, uFlags & 0x1F);
274 /***********************************************************************
275 * DrawCaptionTemp (USER.657)
277 * PARAMS
279 * RETURNS
280 * Success:
281 * Failure:
284 BOOL16 WINAPI
285 DrawCaptionTemp16 (HWND16 hwnd, HDC16 hdc, const RECT16 *rect, HFONT16 hFont,
286 HICON16 hIcon, LPCSTR str, UINT16 uFlags)
288 RECT rect32;
290 if (rect)
291 CONV_RECT16TO32(rect,&rect32);
293 return (BOOL16)DrawCaptionTempA (hwnd, hdc, rect?&rect32:NULL, hFont,
294 hIcon, str, uFlags & 0x1F);
298 /***********************************************************************
299 * DrawCaptionTempA (USER32.@)
301 * PARAMS
303 * RETURNS
304 * Success:
305 * Failure:
308 BOOL WINAPI
309 DrawCaptionTempA (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
310 HICON hIcon, LPCSTR str, UINT uFlags)
312 RECT rc = *rect;
314 TRACE("(%08x,%08x,%p,%08x,%08x,\"%s\",%08x)\n",
315 hwnd, hdc, rect, hFont, hIcon, str, uFlags);
317 /* drawing background */
318 if (uFlags & DC_INBUTTON) {
319 FillRect (hdc, &rc, GetSysColorBrush (COLOR_3DFACE));
321 if (uFlags & DC_ACTIVE) {
322 HBRUSH hbr = SelectObject (hdc, CACHE_GetPattern55AABrush ());
323 PatBlt (hdc, rc.left, rc.top,
324 rc.right-rc.left, rc.bottom-rc.top, 0xFA0089);
325 SelectObject (hdc, hbr);
328 else {
329 FillRect (hdc, &rc, GetSysColorBrush ((uFlags & DC_ACTIVE) ?
330 COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
334 /* drawing icon */
335 if ((uFlags & DC_ICON) && !(uFlags & DC_SMALLCAP)) {
336 POINT pt;
338 pt.x = rc.left + 2;
339 pt.y = (rc.bottom + rc.top - GetSystemMetrics(SM_CYSMICON)) / 2;
341 if (!hIcon) hIcon = NC_IconForWindow(hwnd);
342 DrawIconEx (hdc, pt.x, pt.y, hIcon, GetSystemMetrics(SM_CXSMICON),
343 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
344 rc.left += (rc.bottom - rc.top);
347 /* drawing text */
348 if (uFlags & DC_TEXT) {
349 HFONT hOldFont;
351 if (uFlags & DC_INBUTTON)
352 SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
353 else if (uFlags & DC_ACTIVE)
354 SetTextColor (hdc, GetSysColor (COLOR_CAPTIONTEXT));
355 else
356 SetTextColor (hdc, GetSysColor (COLOR_INACTIVECAPTIONTEXT));
358 SetBkMode (hdc, TRANSPARENT);
360 if (hFont)
361 hOldFont = SelectObject (hdc, hFont);
362 else {
363 NONCLIENTMETRICSA nclm;
364 HFONT hNewFont;
365 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
366 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
367 hNewFont = CreateFontIndirectA ((uFlags & DC_SMALLCAP) ?
368 &nclm.lfSmCaptionFont : &nclm.lfCaptionFont);
369 hOldFont = SelectObject (hdc, hNewFont);
372 if (str)
373 DrawTextA (hdc, str, -1, &rc,
374 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
375 else {
376 CHAR szText[128];
377 INT nLen;
378 nLen = GetWindowTextA (hwnd, szText, 128);
379 DrawTextA (hdc, szText, nLen, &rc,
380 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
383 if (hFont)
384 SelectObject (hdc, hOldFont);
385 else
386 DeleteObject (SelectObject (hdc, hOldFont));
389 /* drawing focus ??? */
390 if (uFlags & 0x2000)
391 FIXME("undocumented flag (0x2000)!\n");
393 return 0;
397 /***********************************************************************
398 * DrawCaptionTempW (USER32.@)
400 * PARAMS
402 * RETURNS
403 * Success:
404 * Failure:
407 BOOL WINAPI
408 DrawCaptionTempW (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
409 HICON hIcon, LPCWSTR str, UINT uFlags)
411 LPSTR p = HEAP_strdupWtoA (GetProcessHeap (), 0, str);
412 BOOL res = DrawCaptionTempA (hwnd, hdc, rect, hFont, hIcon, p, uFlags);
413 HeapFree (GetProcessHeap (), 0, p);
414 return res;
418 /***********************************************************************
419 * AdjustWindowRect (USER.102)
421 BOOL16 WINAPI AdjustWindowRect16( LPRECT16 rect, DWORD style, BOOL16 menu )
423 return AdjustWindowRectEx16( rect, style, menu, 0 );
427 /***********************************************************************
428 * AdjustWindowRect (USER32.@)
430 BOOL WINAPI AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu )
432 return AdjustWindowRectEx( rect, style, menu, 0 );
436 /***********************************************************************
437 * AdjustWindowRectEx (USER.454)
439 BOOL16 WINAPI AdjustWindowRectEx16( LPRECT16 rect, DWORD style,
440 BOOL16 menu, DWORD exStyle )
442 RECT rect32;
443 BOOL ret;
445 CONV_RECT16TO32( rect, &rect32 );
446 ret = AdjustWindowRectEx( &rect32, style, menu, exStyle );
447 CONV_RECT32TO16( &rect32, rect );
448 return ret;
452 /***********************************************************************
453 * AdjustWindowRectEx (USER32.@)
455 BOOL WINAPI AdjustWindowRectEx( LPRECT rect, DWORD style, BOOL menu, DWORD exStyle )
457 /* Correct the window style */
459 if (!(style & (WS_POPUP | WS_CHILD))) style |= WS_CAPTION; /* Overlapped window */
460 style &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD);
461 exStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE |
462 WS_EX_STATICEDGE | WS_EX_TOOLWINDOW);
463 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
465 TRACE("(%d,%d)-(%d,%d) %08lx %d %08lx\n",
466 rect->left, rect->top, rect->right, rect->bottom,
467 style, menu, exStyle );
469 if (TWEAK_WineLook == WIN31_LOOK)
470 NC_AdjustRect( rect, style, menu, exStyle );
471 else
473 NC_AdjustRectOuter95( rect, style, menu, exStyle );
474 NC_AdjustRectInner95( rect, style, exStyle );
476 return TRUE;
480 /***********************************************************************
481 * NC_HandleNCCalcSize
483 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
485 LONG NC_HandleNCCalcSize( WND *pWnd, RECT *winRect )
487 RECT tmpRect = { 0, 0, 0, 0 };
488 LONG result = 0;
489 UINT style = (UINT) GetClassLongA(pWnd->hwndSelf, GCL_STYLE);
491 if (style & CS_VREDRAW) result |= WVR_VREDRAW;
492 if (style & CS_HREDRAW) result |= WVR_HREDRAW;
494 if( !( pWnd->dwStyle & WS_MINIMIZE ) ) {
495 if (TWEAK_WineLook == WIN31_LOOK)
496 NC_AdjustRect( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
497 else
498 NC_AdjustRectOuter95( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
500 winRect->left -= tmpRect.left;
501 winRect->top -= tmpRect.top;
502 winRect->right -= tmpRect.right;
503 winRect->bottom -= tmpRect.bottom;
505 if (HAS_MENU(pWnd)) {
506 TRACE("Calling GetMenuBarHeight with HWND 0x%x, width %d, "
507 "at (%d, %d).\n", pWnd->hwndSelf,
508 winRect->right - winRect->left,
509 -tmpRect.left, -tmpRect.top );
511 winRect->top +=
512 MENU_GetMenuBarHeight( pWnd->hwndSelf,
513 winRect->right - winRect->left,
514 -tmpRect.left, -tmpRect.top ) + 1;
517 if (TWEAK_WineLook > WIN31_LOOK) {
518 SetRect(&tmpRect, 0, 0, 0, 0);
519 NC_AdjustRectInner95 (&tmpRect, pWnd->dwStyle, pWnd->dwExStyle);
520 winRect->left -= tmpRect.left;
521 winRect->top -= tmpRect.top;
522 winRect->right -= tmpRect.right;
523 winRect->bottom -= tmpRect.bottom;
526 if (winRect->top > winRect->bottom)
527 winRect->bottom = winRect->top;
529 if (winRect->left > winRect->right)
530 winRect->right = winRect->left;
532 return result;
536 /***********************************************************************
537 * NC_GetInsideRect
539 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
540 * but without the borders (if any).
541 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
543 void NC_GetInsideRect( HWND hwnd, RECT *rect )
545 WND * wndPtr = WIN_FindWndPtr( hwnd );
547 rect->top = rect->left = 0;
548 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
549 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
551 if (wndPtr->dwStyle & WS_ICONIC) goto END;
553 /* Remove frame from rectangle */
554 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
556 InflateRect( rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
558 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
560 InflateRect( rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
561 /* FIXME: this isn't in NC_AdjustRect? why not? */
562 if ((TWEAK_WineLook == WIN31_LOOK) && (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME))
563 InflateRect( rect, -1, 0 );
565 else if (HAS_THINFRAME( wndPtr->dwStyle ))
567 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
570 /* We have additional border information if the window
571 * is a child (but not an MDI child) */
572 if (TWEAK_WineLook != WIN31_LOOK)
574 if ( (wndPtr->dwStyle & WS_CHILD) &&
575 ( (wndPtr->dwExStyle & WS_EX_MDICHILD) == 0 ) )
577 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
578 InflateRect (rect, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE));
579 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
580 InflateRect (rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
584 END:
585 WIN_ReleaseWndPtr(wndPtr);
586 return;
590 /***********************************************************************
591 * NC_DoNCHitTest
593 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
596 static LONG NC_DoNCHitTest (WND *wndPtr, POINT pt )
598 RECT rect;
600 TRACE("hwnd=%04x pt=%ld,%ld\n", wndPtr->hwndSelf, pt.x, pt.y );
602 GetWindowRect(wndPtr->hwndSelf, &rect );
603 if (!PtInRect( &rect, pt )) return HTNOWHERE;
605 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
607 /* Check borders */
608 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
610 InflateRect( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
611 if (!PtInRect( &rect, pt ))
613 /* Check top sizing border */
614 if (pt.y < rect.top)
616 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
617 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
618 return HTTOP;
620 /* Check bottom sizing border */
621 if (pt.y >= rect.bottom)
623 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
624 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
625 return HTBOTTOM;
627 /* Check left sizing border */
628 if (pt.x < rect.left)
630 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
631 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
632 return HTLEFT;
634 /* Check right sizing border */
635 if (pt.x >= rect.right)
637 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
638 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
639 return HTRIGHT;
643 else /* No thick frame */
645 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
646 InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
647 else if (HAS_THINFRAME( wndPtr->dwStyle ))
648 InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
649 if (!PtInRect( &rect, pt )) return HTBORDER;
652 /* Check caption */
654 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
656 rect.top += GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
657 if (!PtInRect( &rect, pt ))
659 /* Check system menu */
660 if ((wndPtr->dwStyle & WS_SYSMENU) && !(wndPtr->dwExStyle & WS_EX_TOOLWINDOW))
661 rect.left += GetSystemMetrics(SM_CXSIZE);
662 if (pt.x <= rect.left) return HTSYSMENU;
664 /* Check maximize box */
665 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
666 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
668 if (pt.x >= rect.right) return HTMAXBUTTON;
669 /* Check minimize box */
670 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
671 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
672 if (pt.x >= rect.right) return HTMINBUTTON;
673 return HTCAPTION;
677 /* Check client area */
679 ScreenToClient( wndPtr->hwndSelf, &pt );
680 GetClientRect( wndPtr->hwndSelf, &rect );
681 if (PtInRect( &rect, pt )) return HTCLIENT;
683 /* Check vertical scroll bar */
685 if (wndPtr->dwStyle & WS_VSCROLL)
687 rect.right += GetSystemMetrics(SM_CXVSCROLL);
688 if (PtInRect( &rect, pt )) return HTVSCROLL;
691 /* Check horizontal scroll bar */
693 if (wndPtr->dwStyle & WS_HSCROLL)
695 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
696 if (PtInRect( &rect, pt ))
698 /* Check size box */
699 if ((wndPtr->dwStyle & WS_VSCROLL) &&
700 (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
701 return HTSIZE;
702 return HTHSCROLL;
706 /* Check menu bar */
708 if (HAS_MENU(wndPtr))
710 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
711 return HTMENU;
714 /* Has to return HTNOWHERE if nothing was found
715 Could happen when a window has a customized non client area */
716 return HTNOWHERE;
720 /***********************************************************************
721 * NC_DoNCHitTest95
723 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
725 * FIXME: Just a modified copy of the Win 3.1 version.
728 static LONG NC_DoNCHitTest95 (WND *wndPtr, POINT pt )
730 RECT rect;
732 TRACE("hwnd=%04x pt=%ld,%ld\n", wndPtr->hwndSelf, pt.x, pt.y );
734 GetWindowRect(wndPtr->hwndSelf, &rect );
735 if (!PtInRect( &rect, pt )) return HTNOWHERE;
737 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
739 /* Check borders */
740 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
742 InflateRect( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
743 if (!PtInRect( &rect, pt ))
745 /* Check top sizing border */
746 if (pt.y < rect.top)
748 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
749 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
750 return HTTOP;
752 /* Check bottom sizing border */
753 if (pt.y >= rect.bottom)
755 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
756 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
757 return HTBOTTOM;
759 /* Check left sizing border */
760 if (pt.x < rect.left)
762 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
763 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
764 return HTLEFT;
766 /* Check right sizing border */
767 if (pt.x >= rect.right)
769 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
770 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
771 return HTRIGHT;
775 else /* No thick frame */
777 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
778 InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
779 else if (HAS_THINFRAME( wndPtr->dwStyle ))
780 InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
781 if (!PtInRect( &rect, pt )) return HTBORDER;
784 /* Check caption */
786 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
788 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
789 rect.top += GetSystemMetrics(SM_CYSMCAPTION) - 1;
790 else
791 rect.top += GetSystemMetrics(SM_CYCAPTION) - 1;
792 if (!PtInRect( &rect, pt ))
794 /* Check system menu */
795 if ((wndPtr->dwStyle & WS_SYSMENU) && !(wndPtr->dwExStyle & WS_EX_TOOLWINDOW))
797 if (NC_IconForWindow(wndPtr->hwndSelf))
798 rect.left += GetSystemMetrics(SM_CYCAPTION) - 1;
800 if (pt.x < rect.left) return HTSYSMENU;
802 /* Check close button */
803 if (wndPtr->dwStyle & WS_SYSMENU)
804 rect.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
805 if (pt.x > rect.right) return HTCLOSE;
807 /* Check maximize box */
808 /* In win95 there is automatically a Maximize button when there is a minimize one*/
809 if ((wndPtr->dwStyle & WS_MAXIMIZEBOX)|| (wndPtr->dwStyle & WS_MINIMIZEBOX))
810 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
811 if (pt.x > rect.right) return HTMAXBUTTON;
813 /* Check minimize box */
814 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
815 if ((wndPtr->dwStyle & WS_MINIMIZEBOX)||(wndPtr->dwStyle & WS_MAXIMIZEBOX))
816 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
818 if (pt.x > rect.right) return HTMINBUTTON;
819 return HTCAPTION;
823 /* Check client area */
825 ScreenToClient( wndPtr->hwndSelf, &pt );
826 GetClientRect( wndPtr->hwndSelf, &rect );
827 if (PtInRect( &rect, pt )) return HTCLIENT;
829 /* Check vertical scroll bar */
831 if (wndPtr->dwStyle & WS_VSCROLL)
833 rect.right += GetSystemMetrics(SM_CXVSCROLL);
834 if (PtInRect( &rect, pt )) return HTVSCROLL;
837 /* Check horizontal scroll bar */
839 if (wndPtr->dwStyle & WS_HSCROLL)
841 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
842 if (PtInRect( &rect, pt ))
844 /* Check size box */
845 if ((wndPtr->dwStyle & WS_VSCROLL) &&
846 (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
847 return HTSIZE;
848 return HTHSCROLL;
852 /* Check menu bar */
854 if (HAS_MENU(wndPtr))
856 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
857 return HTMENU;
860 /* Has to return HTNOWHERE if nothing was found
861 Could happen when a window has a customized non client area */
862 return HTNOWHERE;
866 /***********************************************************************
867 * NC_HandleNCHitTest
869 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
871 LONG NC_HandleNCHitTest (HWND hwnd , POINT pt)
873 LONG retvalue;
874 WND *wndPtr = WIN_FindWndPtr (hwnd);
876 if (!wndPtr)
877 return HTERROR;
879 if (TWEAK_WineLook == WIN31_LOOK)
880 retvalue = NC_DoNCHitTest (wndPtr, pt);
881 else
882 retvalue = NC_DoNCHitTest95 (wndPtr, pt);
883 WIN_ReleaseWndPtr(wndPtr);
884 return retvalue;
888 /***********************************************************************
889 * NC_DrawSysButton
891 void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down )
893 RECT rect;
894 HDC hdcMem;
895 HBITMAP hbitmap;
897 NC_GetInsideRect( hwnd, &rect );
898 hdcMem = CreateCompatibleDC( hdc );
899 hbitmap = SelectObject( hdcMem, hbitmapClose );
900 BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE), GetSystemMetrics(SM_CYSIZE),
901 hdcMem, (GetWindowLongA(hwnd,GWL_STYLE) & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE) : 0, 0,
902 down ? NOTSRCCOPY : SRCCOPY );
903 SelectObject( hdcMem, hbitmap );
904 DeleteDC( hdcMem );
908 /***********************************************************************
909 * NC_DrawMaxButton
911 static void NC_DrawMaxButton( HWND hwnd, HDC16 hdc, BOOL down )
913 RECT rect;
914 HDC hdcMem;
916 NC_GetInsideRect( hwnd, &rect );
917 hdcMem = CreateCompatibleDC( hdc );
918 SelectObject( hdcMem, (IsZoomed(hwnd)
919 ? (down ? hbitmapRestoreD : hbitmapRestore)
920 : (down ? hbitmapMaximizeD : hbitmapMaximize)) );
921 BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
922 GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
923 SRCCOPY );
924 DeleteDC( hdcMem );
929 /***********************************************************************
930 * NC_DrawMinButton
932 static void NC_DrawMinButton( HWND hwnd, HDC16 hdc, BOOL down )
934 RECT rect;
935 HDC hdcMem;
937 NC_GetInsideRect( hwnd, &rect );
938 hdcMem = CreateCompatibleDC( hdc );
939 SelectObject( hdcMem, (down ? hbitmapMinimizeD : hbitmapMinimize) );
940 if (GetWindowLongA(hwnd,GWL_STYLE) & WS_MAXIMIZEBOX)
941 rect.right -= GetSystemMetrics(SM_CXSIZE)+1;
942 BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
943 GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
944 SRCCOPY );
945 DeleteDC( hdcMem );
949 /******************************************************************************
951 * void NC_DrawSysButton95(
952 * HWND hwnd,
953 * HDC hdc,
954 * BOOL down )
956 * Draws the Win95 system icon.
958 * Revision history
959 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
960 * Original implementation from NC_DrawSysButton source.
961 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
962 * Fixed most bugs.
964 *****************************************************************************/
966 BOOL
967 NC_DrawSysButton95 (HWND hwnd, HDC hdc, BOOL down)
969 HICON hIcon = NC_IconForWindow( hwnd );
971 if (hIcon)
973 RECT rect;
974 NC_GetInsideRect( hwnd, &rect );
975 DrawIconEx (hdc, rect.left + 2, rect.top + 2, hIcon,
976 GetSystemMetrics(SM_CXSMICON),
977 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
979 return (hIcon != 0);
983 /******************************************************************************
985 * void NC_DrawCloseButton95(
986 * HWND hwnd,
987 * HDC hdc,
988 * BOOL down,
989 * BOOL bGrayed )
991 * Draws the Win95 close button.
993 * If bGrayed is true, then draw a disabled Close button
995 * Revision history
996 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
997 * Original implementation from NC_DrawSysButton95 source.
999 *****************************************************************************/
1001 static void NC_DrawCloseButton95 (HWND hwnd, HDC hdc, BOOL down, BOOL bGrayed)
1003 RECT rect;
1005 NC_GetInsideRect( hwnd, &rect );
1007 /* A tool window has a smaller Close button */
1008 if (GetWindowLongA( hwnd, GWL_EXSTYLE ) & WS_EX_TOOLWINDOW)
1010 INT iBmpHeight = 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
1011 INT iBmpWidth = 11; /* it uses 11x11 for the close button in tool window */
1012 INT iCaptionHeight = GetSystemMetrics(SM_CYSMCAPTION);
1014 rect.top = rect.top + (iCaptionHeight - 1 - iBmpHeight) / 2;
1015 rect.left = rect.right - (iCaptionHeight + 1 + iBmpWidth) / 2;
1016 rect.bottom = rect.top + iBmpHeight;
1017 rect.right = rect.left + iBmpWidth;
1019 else
1021 rect.left = rect.right - GetSystemMetrics(SM_CXSIZE) - 1;
1022 rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
1023 rect.top += 2;
1024 rect.right -= 2;
1026 DrawFrameControl( hdc, &rect, DFC_CAPTION,
1027 (DFCS_CAPTIONCLOSE |
1028 (down ? DFCS_PUSHED : 0) |
1029 (bGrayed ? DFCS_INACTIVE : 0)) );
1032 /******************************************************************************
1033 * NC_DrawMaxButton95
1035 * Draws the maximize button for Win95 style windows.
1036 * If bGrayed is true, then draw a disabled Maximize button
1038 static void NC_DrawMaxButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
1040 RECT rect;
1041 UINT flags = IsZoomed(hwnd) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMAX;
1043 NC_GetInsideRect( hwnd, &rect );
1044 if (GetWindowLongA( hwnd, GWL_STYLE) & WS_SYSMENU)
1045 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1046 rect.left = rect.right - GetSystemMetrics(SM_CXSIZE);
1047 rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
1048 rect.top += 2;
1049 rect.right -= 2;
1050 if (down) flags |= DFCS_PUSHED;
1051 if (bGrayed) flags |= DFCS_INACTIVE;
1052 DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
1055 /******************************************************************************
1056 * NC_DrawMinButton95
1058 * Draws the minimize button for Win95 style windows.
1059 * If bGrayed is true, then draw a disabled Minimize button
1061 static void NC_DrawMinButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
1063 RECT rect;
1064 UINT flags = DFCS_CAPTIONMIN;
1065 DWORD style = GetWindowLongA( hwnd, GWL_STYLE );
1067 NC_GetInsideRect( hwnd, &rect );
1068 if (style & WS_SYSMENU)
1069 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1070 if (style & (WS_MAXIMIZEBOX|WS_MINIMIZEBOX))
1071 rect.right -= GetSystemMetrics(SM_CXSIZE) - 2;
1072 rect.left = rect.right - GetSystemMetrics(SM_CXSIZE);
1073 rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
1074 rect.top += 2;
1075 rect.right -= 2;
1076 if (down) flags |= DFCS_PUSHED;
1077 if (bGrayed) flags |= DFCS_INACTIVE;
1078 DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
1081 /***********************************************************************
1082 * NC_DrawFrame
1084 * Draw a window frame inside the given rectangle, and update the rectangle.
1085 * The correct pen for the frame must be selected in the DC.
1087 static void NC_DrawFrame( HDC hdc, RECT *rect, BOOL dlgFrame,
1088 BOOL active )
1090 INT width, height;
1092 if (TWEAK_WineLook != WIN31_LOOK)
1093 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
1095 if (dlgFrame)
1097 width = GetSystemMetrics(SM_CXDLGFRAME) - 1;
1098 height = GetSystemMetrics(SM_CYDLGFRAME) - 1;
1099 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1100 COLOR_INACTIVECAPTION) );
1102 else
1104 width = GetSystemMetrics(SM_CXFRAME) - 2;
1105 height = GetSystemMetrics(SM_CYFRAME) - 2;
1106 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1107 COLOR_INACTIVEBORDER) );
1110 /* Draw frame */
1111 PatBlt( hdc, rect->left, rect->top,
1112 rect->right - rect->left, height, PATCOPY );
1113 PatBlt( hdc, rect->left, rect->top,
1114 width, rect->bottom - rect->top, PATCOPY );
1115 PatBlt( hdc, rect->left, rect->bottom - 1,
1116 rect->right - rect->left, -height, PATCOPY );
1117 PatBlt( hdc, rect->right - 1, rect->top,
1118 -width, rect->bottom - rect->top, PATCOPY );
1120 if (dlgFrame)
1122 InflateRect( rect, -width, -height );
1124 else
1126 INT decYOff = GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXSIZE) - 1;
1127 INT decXOff = GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYSIZE) - 1;
1129 /* Draw inner rectangle */
1131 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1132 Rectangle( hdc, rect->left + width, rect->top + height,
1133 rect->right - width , rect->bottom - height );
1135 /* Draw the decorations */
1137 MoveToEx( hdc, rect->left, rect->top + decYOff, NULL );
1138 LineTo( hdc, rect->left + width, rect->top + decYOff );
1139 MoveToEx( hdc, rect->right - 1, rect->top + decYOff, NULL );
1140 LineTo( hdc, rect->right - width - 1, rect->top + decYOff );
1141 MoveToEx( hdc, rect->left, rect->bottom - decYOff, NULL );
1142 LineTo( hdc, rect->left + width, rect->bottom - decYOff );
1143 MoveToEx( hdc, rect->right - 1, rect->bottom - decYOff, NULL );
1144 LineTo( hdc, rect->right - width - 1, rect->bottom - decYOff );
1146 MoveToEx( hdc, rect->left + decXOff, rect->top, NULL );
1147 LineTo( hdc, rect->left + decXOff, rect->top + height);
1148 MoveToEx( hdc, rect->left + decXOff, rect->bottom - 1, NULL );
1149 LineTo( hdc, rect->left + decXOff, rect->bottom - height - 1 );
1150 MoveToEx( hdc, rect->right - decXOff, rect->top, NULL );
1151 LineTo( hdc, rect->right - decXOff, rect->top + height );
1152 MoveToEx( hdc, rect->right - decXOff, rect->bottom - 1, NULL );
1153 LineTo( hdc, rect->right - decXOff, rect->bottom - height - 1 );
1155 InflateRect( rect, -width - 1, -height - 1 );
1160 /******************************************************************************
1162 * void NC_DrawFrame95(
1163 * HDC hdc,
1164 * RECT *rect,
1165 * BOOL dlgFrame,
1166 * BOOL active )
1168 * Draw a window frame inside the given rectangle, and update the rectangle.
1169 * The correct pen for the frame must be selected in the DC.
1171 * Bugs
1172 * Many. First, just what IS a frame in Win95? Note that the 3D look
1173 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1174 * edge. The inner rectangle just inside the frame is handled by the
1175 * Caption code.
1177 * In short, for most people, this function should be a nop (unless
1178 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1179 * them lately, but just to get this code right). Even so, it doesn't
1180 * appear to be so. It's being worked on...
1182 * Revision history
1183 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1184 * Original implementation (based on NC_DrawFrame)
1185 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1186 * Some minor fixes.
1187 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1188 * Fixed a fix or something.
1190 *****************************************************************************/
1192 static void NC_DrawFrame95(
1193 HDC hdc,
1194 RECT *rect,
1195 BOOL dlgFrame,
1196 BOOL active )
1198 INT width, height;
1200 if (dlgFrame)
1202 width = GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
1203 height = GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
1205 else
1207 width = GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXEDGE);
1208 height = GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYEDGE);
1211 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1212 COLOR_INACTIVEBORDER) );
1214 /* Draw frame */
1215 PatBlt( hdc, rect->left, rect->top,
1216 rect->right - rect->left, height, PATCOPY );
1217 PatBlt( hdc, rect->left, rect->top,
1218 width, rect->bottom - rect->top, PATCOPY );
1219 PatBlt( hdc, rect->left, rect->bottom - 1,
1220 rect->right - rect->left, -height, PATCOPY );
1221 PatBlt( hdc, rect->right - 1, rect->top,
1222 -width, rect->bottom - rect->top, PATCOPY );
1224 InflateRect( rect, -width, -height );
1228 /***********************************************************************
1229 * NC_DrawCaption
1231 * Draw the window caption.
1232 * The correct pen for the window frame must be selected in the DC.
1234 static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd,
1235 DWORD style, BOOL active )
1237 RECT r = *rect;
1238 char buffer[256];
1240 if (!hbitmapClose)
1242 if (!(hbitmapClose = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_CLOSE) ))) return;
1243 hbitmapMinimize = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_REDUCE) );
1244 hbitmapMinimizeD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_REDUCED) );
1245 hbitmapMaximize = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_ZOOM) );
1246 hbitmapMaximizeD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_ZOOMD) );
1247 hbitmapRestore = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RESTORE) );
1248 hbitmapRestoreD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RESTORED) );
1251 if (GetWindowLongA( hwnd, GWL_EXSTYLE) & WS_EX_DLGMODALFRAME)
1253 HBRUSH hbrushOld = SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW) );
1254 PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
1255 PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
1256 PatBlt( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
1257 r.left++;
1258 r.right--;
1259 SelectObject( hdc, hbrushOld );
1261 MoveToEx( hdc, r.left, r.bottom, NULL );
1262 LineTo( hdc, r.right, r.bottom );
1264 if (style & WS_SYSMENU)
1266 NC_DrawSysButton( hwnd, hdc, FALSE );
1267 r.left += GetSystemMetrics(SM_CXSIZE) + 1;
1268 MoveToEx( hdc, r.left - 1, r.top, NULL );
1269 LineTo( hdc, r.left - 1, r.bottom );
1271 if (style & WS_MAXIMIZEBOX)
1273 NC_DrawMaxButton( hwnd, hdc, FALSE );
1274 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1276 if (style & WS_MINIMIZEBOX)
1278 NC_DrawMinButton( hwnd, hdc, FALSE );
1279 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1282 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1283 COLOR_INACTIVECAPTION) );
1285 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) ))
1287 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1288 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1289 SetBkMode( hdc, TRANSPARENT );
1290 DrawTextA( hdc, buffer, -1, &r,
1291 DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );
1296 /******************************************************************************
1298 * NC_DrawCaption95(
1299 * HDC hdc,
1300 * RECT *rect,
1301 * HWND hwnd,
1302 * DWORD style,
1303 * BOOL active )
1305 * Draw the window caption for Win95 style windows.
1306 * The correct pen for the window frame must be selected in the DC.
1308 * Bugs
1309 * Hey, a function that finally works! Well, almost.
1310 * It's being worked on.
1312 * Revision history
1313 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1314 * Original implementation.
1315 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1316 * Some minor fixes.
1318 *****************************************************************************/
1320 static void NC_DrawCaption95(
1321 HDC hdc,
1322 RECT *rect,
1323 HWND hwnd,
1324 DWORD style,
1325 DWORD exStyle,
1326 BOOL active )
1328 RECT r = *rect;
1329 char buffer[256];
1330 HPEN hPrevPen;
1331 HMENU hSysMenu;
1333 hPrevPen = SelectObject( hdc, GetSysColorPen(COLOR_3DFACE) );
1334 MoveToEx( hdc, r.left, r.bottom - 1, NULL );
1335 LineTo( hdc, r.right, r.bottom - 1 );
1336 SelectObject( hdc, hPrevPen );
1337 r.bottom--;
1339 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1340 COLOR_INACTIVECAPTION) );
1342 if ((style & WS_SYSMENU) && !(exStyle & WS_EX_TOOLWINDOW)) {
1343 if (NC_DrawSysButton95 (hwnd, hdc, FALSE))
1344 r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
1347 if (style & WS_SYSMENU)
1349 UINT state;
1351 /* Go get the sysmenu */
1352 hSysMenu = GetSystemMenu(hwnd, FALSE);
1353 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
1355 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1356 NC_DrawCloseButton95 (hwnd, hdc, FALSE,
1357 ((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
1358 r.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
1360 if ((style & WS_MAXIMIZEBOX) || (style & WS_MINIMIZEBOX))
1362 /* In win95 the two buttons are always there */
1363 /* But if the menu item is not in the menu they're disabled*/
1365 NC_DrawMaxButton95( hwnd, hdc, FALSE, (!(style & WS_MAXIMIZEBOX)));
1366 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1368 NC_DrawMinButton95( hwnd, hdc, FALSE, (!(style & WS_MINIMIZEBOX)));
1369 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1373 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) )) {
1374 NONCLIENTMETRICSA nclm;
1375 HFONT hFont, hOldFont;
1376 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1377 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1378 if (exStyle & WS_EX_TOOLWINDOW)
1379 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
1380 else
1381 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
1382 hOldFont = SelectObject (hdc, hFont);
1383 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1384 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1385 SetBkMode( hdc, TRANSPARENT );
1386 r.left += 2;
1387 DrawTextA( hdc, buffer, -1, &r,
1388 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
1389 DeleteObject (SelectObject (hdc, hOldFont));
1395 /***********************************************************************
1396 * NC_DoNCPaint
1398 * Paint the non-client area. clip is currently unused.
1400 static void NC_DoNCPaint( WND* wndPtr, HRGN clip, BOOL suppress_menupaint )
1402 HDC hdc;
1403 RECT rect;
1404 BOOL active;
1405 HWND hwnd = wndPtr->hwndSelf;
1407 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1408 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1410 active = wndPtr->flags & WIN_NCACTIVATED;
1412 TRACE("%04x %d\n", hwnd, active );
1414 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1415 ((clip > 1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN): 0) ))) return;
1417 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1418 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1419 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1420 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1421 == NULLREGION)
1423 ReleaseDC( hwnd, hdc );
1424 return;
1427 rect.top = rect.left = 0;
1428 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1429 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1431 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1433 if (HAS_ANYFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1435 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1436 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1437 InflateRect( &rect, -1, -1 );
1440 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1441 NC_DrawFrame(hdc, &rect, FALSE, active );
1442 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1443 NC_DrawFrame( hdc, &rect, TRUE, active );
1445 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1447 RECT r = rect;
1448 r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
1449 rect.top += GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYBORDER);
1450 NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active );
1453 if (HAS_MENU(wndPtr))
1455 RECT r = rect;
1456 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU); /* default height */
1457 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint );
1460 /* Draw the scroll-bars */
1462 if (wndPtr->dwStyle & WS_VSCROLL)
1463 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1464 if (wndPtr->dwStyle & WS_HSCROLL)
1465 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1467 /* Draw the "size-box" */
1469 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1471 RECT r = rect;
1472 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1473 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1474 if(wndPtr->dwStyle & WS_BORDER) {
1475 r.left++;
1476 r.top++;
1478 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1481 ReleaseDC( hwnd, hdc );
1485 /******************************************************************************
1487 * void NC_DoNCPaint95(
1488 * WND *wndPtr,
1489 * HRGN clip,
1490 * BOOL suppress_menupaint )
1492 * Paint the non-client area for Win95 windows. The clip region is
1493 * currently ignored.
1495 * Bugs
1496 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1497 * misc/tweak.c controls/menu.c # :-)
1499 * Revision history
1500 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1501 * Original implementation
1502 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1503 * Fixed some bugs.
1504 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1505 * Streamlined window style checks.
1507 *****************************************************************************/
1509 static void NC_DoNCPaint95(
1510 WND *wndPtr,
1511 HRGN clip,
1512 BOOL suppress_menupaint )
1514 HDC hdc;
1515 RECT rfuzz, rect, rectClip;
1516 BOOL active;
1517 HWND hwnd = wndPtr->hwndSelf;
1519 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1520 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1522 active = wndPtr->flags & WIN_NCACTIVATED;
1524 TRACE("%04x %d\n", hwnd, active );
1526 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1527 the call to GetDCEx implying that it is allowed not to use it either.
1528 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1529 will cause clipRgn to be deleted after ReleaseDC().
1530 Now, how is the "system" supposed to tell what happened?
1533 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1534 ((clip > 1) ?(DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0) ))) return;
1537 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1538 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1539 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1540 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1541 == NULLREGION)
1543 ReleaseDC( hwnd, hdc );
1544 return;
1547 rect.top = rect.left = 0;
1548 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1549 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1551 if( clip > 1 )
1552 GetRgnBox( clip, &rectClip );
1553 else
1555 clip = 0;
1556 rectClip = rect;
1559 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1561 if (HAS_BIGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle)) {
1562 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1564 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1565 NC_DrawFrame95(hdc, &rect, FALSE, active );
1566 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1567 NC_DrawFrame95( hdc, &rect, TRUE, active );
1568 else if (HAS_THINFRAME( wndPtr->dwStyle )) {
1569 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1570 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1573 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1575 RECT r = rect;
1576 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW) {
1577 r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
1578 rect.top += GetSystemMetrics(SM_CYSMCAPTION);
1580 else {
1581 r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
1582 rect.top += GetSystemMetrics(SM_CYCAPTION);
1584 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
1585 NC_DrawCaption95 (hdc, &r, hwnd, wndPtr->dwStyle,
1586 wndPtr->dwExStyle, active);
1589 if (HAS_MENU(wndPtr))
1591 RECT r = rect;
1592 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
1594 TRACE("Calling DrawMenuBar with rect (%d, %d)-(%d, %d)\n",
1595 r.left, r.top, r.right, r.bottom);
1597 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ) + 1;
1600 TRACE("After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1601 rect.left, rect.top, rect.right, rect.bottom );
1603 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
1604 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1606 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
1607 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1609 /* Draw the scroll-bars */
1611 if (wndPtr->dwStyle & WS_VSCROLL)
1612 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1613 if (wndPtr->dwStyle & WS_HSCROLL)
1614 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1616 /* Draw the "size-box" */
1617 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1619 RECT r = rect;
1620 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1621 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1622 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1625 ReleaseDC( hwnd, hdc );
1631 /***********************************************************************
1632 * NC_HandleNCPaint
1634 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1636 LONG NC_HandleNCPaint( HWND hwnd , HRGN clip)
1638 WND* wndPtr = WIN_FindWndPtr( hwnd );
1640 if( wndPtr && wndPtr->dwStyle & WS_VISIBLE )
1642 if( wndPtr->dwStyle & WS_MINIMIZE )
1643 WINPOS_RedrawIconTitle( hwnd );
1644 else if (TWEAK_WineLook == WIN31_LOOK)
1645 NC_DoNCPaint( wndPtr, clip, FALSE );
1646 else
1647 NC_DoNCPaint95( wndPtr, clip, FALSE );
1649 WIN_ReleaseWndPtr(wndPtr);
1650 return 0;
1654 /***********************************************************************
1655 * NC_HandleNCActivate
1657 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1659 LONG NC_HandleNCActivate( WND *wndPtr, WPARAM16 wParam )
1661 /* Lotus Notes draws menu descriptions in the caption of its main
1662 * window. When it wants to restore original "system" view, it just
1663 * sends WM_NCACTIVATE message to itself. Any optimizations here in
1664 * attempt to minimize redrawings lead to a not restored caption.
1667 if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
1668 else wndPtr->flags &= ~WIN_NCACTIVATED;
1670 if( wndPtr->dwStyle & WS_MINIMIZE )
1671 WINPOS_RedrawIconTitle( wndPtr->hwndSelf );
1672 else if (TWEAK_WineLook == WIN31_LOOK)
1673 NC_DoNCPaint( wndPtr, (HRGN)1, FALSE );
1674 else
1675 NC_DoNCPaint95( wndPtr, (HRGN)1, FALSE );
1677 return TRUE;
1681 /***********************************************************************
1682 * NC_HandleSetCursor
1684 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1686 LONG NC_HandleSetCursor( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
1688 if (hwnd != (HWND)wParam) return 0; /* Don't set the cursor for child windows */
1690 switch(LOWORD(lParam))
1692 case HTERROR:
1694 WORD msg = HIWORD( lParam );
1695 if ((msg == WM_LBUTTONDOWN) || (msg == WM_MBUTTONDOWN) ||
1696 (msg == WM_RBUTTONDOWN))
1697 MessageBeep(0);
1699 break;
1701 case HTCLIENT:
1703 HICON16 hCursor = (HICON16) GetClassWord(hwnd, GCW_HCURSOR);
1704 if(hCursor) {
1705 SetCursor16(hCursor);
1706 return TRUE;
1708 return FALSE;
1711 case HTLEFT:
1712 case HTRIGHT:
1713 return (LONG)SetCursor( LoadCursorA( 0, IDC_SIZEWEA ) );
1715 case HTTOP:
1716 case HTBOTTOM:
1717 return (LONG)SetCursor( LoadCursorA( 0, IDC_SIZENSA ) );
1719 case HTTOPLEFT:
1720 case HTBOTTOMRIGHT:
1721 return (LONG)SetCursor( LoadCursorA( 0, IDC_SIZENWSEA ) );
1723 case HTTOPRIGHT:
1724 case HTBOTTOMLEFT:
1725 return (LONG)SetCursor( LoadCursorA( 0, IDC_SIZENESWA ) );
1728 /* Default cursor: arrow */
1729 return (LONG)SetCursor( LoadCursorA( 0, IDC_ARROWA ) );
1732 /***********************************************************************
1733 * NC_GetSysPopupPos
1735 BOOL NC_GetSysPopupPos( WND* wndPtr, RECT* rect )
1737 if( wndPtr->hSysMenu )
1739 if( wndPtr->dwStyle & WS_MINIMIZE )
1740 GetWindowRect( wndPtr->hwndSelf, rect );
1741 else
1743 NC_GetInsideRect( wndPtr->hwndSelf, rect );
1744 OffsetRect( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
1745 if (wndPtr->dwStyle & WS_CHILD)
1746 ClientToScreen( wndPtr->parent->hwndSelf, (POINT *)rect );
1747 if (TWEAK_WineLook == WIN31_LOOK) {
1748 rect->right = rect->left + GetSystemMetrics(SM_CXSIZE);
1749 rect->bottom = rect->top + GetSystemMetrics(SM_CYSIZE);
1751 else {
1752 rect->right = rect->left + GetSystemMetrics(SM_CYCAPTION) - 1;
1753 rect->bottom = rect->top + GetSystemMetrics(SM_CYCAPTION) - 1;
1756 return TRUE;
1758 return FALSE;
1761 /***********************************************************************
1762 * NC_TrackMinMaxBox95
1764 * Track a mouse button press on the minimize or maximize box.
1766 * The big difference between 3.1 and 95 is the disabled button state.
1767 * In win95 the system button can be disabled, so it can ignore the mouse
1768 * event.
1771 static void NC_TrackMinMaxBox95( HWND hwnd, WORD wParam )
1773 MSG msg;
1774 HDC hdc = GetWindowDC( hwnd );
1775 BOOL pressed = TRUE;
1776 UINT state;
1777 DWORD wndStyle = GetWindowLongA( hwnd, GWL_STYLE);
1778 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
1780 void (*paintButton)(HWND, HDC16, BOOL, BOOL);
1782 if (wParam == HTMINBUTTON)
1784 /* If the style is not present, do nothing */
1785 if (!(wndStyle & WS_MINIMIZEBOX))
1786 return;
1788 /* Check if the sysmenu item for minimize is there */
1789 state = GetMenuState(hSysMenu, SC_MINIMIZE, MF_BYCOMMAND);
1791 paintButton = &NC_DrawMinButton95;
1793 else
1795 /* If the style is not present, do nothing */
1796 if (!(wndStyle & WS_MAXIMIZEBOX))
1797 return;
1799 /* Check if the sysmenu item for maximize is there */
1800 state = GetMenuState(hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
1802 paintButton = &NC_DrawMaxButton95;
1805 SetCapture( hwnd );
1807 (*paintButton)( hwnd, hdc, TRUE, FALSE);
1809 while(1)
1811 BOOL oldstate = pressed;
1812 MSG_InternalGetMessage( &msg, 0, 0, WM_MOUSEFIRST, WM_MOUSELAST,
1813 0, PM_REMOVE, FALSE, NULL );
1815 if(msg.message == WM_LBUTTONUP)
1816 break;
1818 if(msg.message != WM_MOUSEMOVE)
1819 continue;
1821 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
1822 if (pressed != oldstate)
1823 (*paintButton)( hwnd, hdc, pressed, FALSE);
1826 if(pressed)
1827 (*paintButton)(hwnd, hdc, FALSE, FALSE);
1829 ReleaseCapture();
1830 ReleaseDC( hwnd, hdc );
1832 /* If the item minimize or maximize of the sysmenu are not there */
1833 /* or if the style is not present, do nothing */
1834 if ((!pressed) || (state == 0xFFFFFFFF))
1835 return;
1837 if (wParam == HTMINBUTTON)
1838 SendMessageA( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
1839 else
1840 SendMessageA( hwnd, WM_SYSCOMMAND,
1841 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
1844 /***********************************************************************
1845 * NC_TrackMinMaxBox
1847 * Track a mouse button press on the minimize or maximize box.
1849 static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
1851 MSG msg;
1852 HDC hdc = GetWindowDC( hwnd );
1853 BOOL pressed = TRUE;
1854 void (*paintButton)(HWND, HDC16, BOOL);
1856 SetCapture( hwnd );
1858 if (wParam == HTMINBUTTON)
1859 paintButton = &NC_DrawMinButton;
1860 else
1861 paintButton = &NC_DrawMaxButton;
1863 (*paintButton)( hwnd, hdc, TRUE);
1865 while(1)
1867 BOOL oldstate = pressed;
1868 MSG_InternalGetMessage( &msg, 0, 0, WM_MOUSEFIRST, WM_MOUSELAST,
1869 0, PM_REMOVE, FALSE, NULL );
1871 if(msg.message == WM_LBUTTONUP)
1872 break;
1874 if(msg.message != WM_MOUSEMOVE)
1875 continue;
1877 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
1878 if (pressed != oldstate)
1879 (*paintButton)( hwnd, hdc, pressed);
1882 if(pressed)
1883 (*paintButton)( hwnd, hdc, FALSE);
1885 ReleaseCapture();
1886 ReleaseDC( hwnd, hdc );
1888 if (!pressed) return;
1890 if (wParam == HTMINBUTTON)
1891 SendMessageA( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
1892 else
1893 SendMessageA( hwnd, WM_SYSCOMMAND,
1894 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
1898 /***********************************************************************
1899 * NC_TrackCloseButton95
1901 * Track a mouse button press on the Win95 close button.
1903 static void
1904 NC_TrackCloseButton95 (HWND hwnd, WORD wParam)
1906 MSG msg;
1907 HDC hdc;
1908 BOOL pressed = TRUE;
1909 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
1910 UINT state;
1912 if(hSysMenu == 0)
1913 return;
1915 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
1917 /* If the item close of the sysmenu is disabled or not there do nothing */
1918 if((state & MF_DISABLED) || (state & MF_GRAYED) || (state == 0xFFFFFFFF))
1919 return;
1921 hdc = GetWindowDC( hwnd );
1923 SetCapture( hwnd );
1925 NC_DrawCloseButton95 (hwnd, hdc, TRUE, FALSE);
1927 while(1)
1929 BOOL oldstate = pressed;
1930 MSG_InternalGetMessage( &msg, 0, 0, WM_MOUSEFIRST, WM_MOUSELAST,
1931 0, PM_REMOVE, FALSE, NULL );
1933 if(msg.message == WM_LBUTTONUP)
1934 break;
1936 if(msg.message != WM_MOUSEMOVE)
1937 continue;
1939 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
1940 if (pressed != oldstate)
1941 NC_DrawCloseButton95 (hwnd, hdc, pressed, FALSE);
1944 if(pressed)
1945 NC_DrawCloseButton95 (hwnd, hdc, FALSE, FALSE);
1947 ReleaseCapture();
1948 ReleaseDC( hwnd, hdc );
1949 if (!pressed) return;
1951 SendMessageA( hwnd, WM_SYSCOMMAND, SC_CLOSE, MAKELONG(msg.pt.x,msg.pt.y) );
1955 /***********************************************************************
1956 * NC_TrackScrollBar
1958 * Track a mouse button press on the horizontal or vertical scroll-bar.
1960 static void NC_TrackScrollBar( HWND hwnd, WPARAM wParam, POINT pt )
1962 MSG16 *msg;
1963 INT scrollbar;
1964 WND *wndPtr = WIN_FindWndPtr( hwnd );
1966 if ((wParam & 0xfff0) == SC_HSCROLL)
1968 if ((wParam & 0x0f) != HTHSCROLL) goto END;
1969 scrollbar = SB_HORZ;
1971 else /* SC_VSCROLL */
1973 if ((wParam & 0x0f) != HTVSCROLL) goto END;
1974 scrollbar = SB_VERT;
1977 if (!(msg = SEGPTR_NEW(MSG16))) goto END;
1978 pt.x -= wndPtr->rectWindow.left;
1979 pt.y -= wndPtr->rectWindow.top;
1980 SetCapture( hwnd );
1981 SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt );
1985 GetMessage16( SEGPTR_GET(msg), 0, 0, 0 );
1986 switch(msg->message)
1988 case WM_LBUTTONUP:
1989 case WM_MOUSEMOVE:
1990 case WM_SYSTIMER:
1991 pt.x = LOWORD(msg->lParam) + wndPtr->rectClient.left -
1992 wndPtr->rectWindow.left;
1993 pt.y = HIWORD(msg->lParam) + wndPtr->rectClient.top -
1994 wndPtr->rectWindow.top;
1995 SCROLL_HandleScrollEvent( hwnd, scrollbar, msg->message, pt );
1996 break;
1997 default:
1998 TranslateMessage16( msg );
1999 DispatchMessage16( msg );
2000 break;
2002 if (!IsWindow( hwnd ))
2004 ReleaseCapture();
2005 break;
2007 } while (msg->message != WM_LBUTTONUP);
2008 SEGPTR_FREE(msg);
2009 END:
2010 WIN_ReleaseWndPtr(wndPtr);
2013 /***********************************************************************
2014 * NC_HandleNCLButtonDown
2016 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2018 LONG NC_HandleNCLButtonDown( WND* pWnd, WPARAM16 wParam, LPARAM lParam )
2020 HWND hwnd = pWnd->hwndSelf;
2022 switch(wParam) /* Hit test */
2024 case HTCAPTION:
2025 hwnd = WIN_GetTopParent(hwnd);
2027 if( WINPOS_SetActiveWindow(hwnd, TRUE, TRUE) || (GetActiveWindow() == hwnd) )
2028 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
2029 break;
2031 case HTSYSMENU:
2032 if( pWnd->dwStyle & WS_SYSMENU )
2034 if( !(pWnd->dwStyle & WS_MINIMIZE) )
2036 HDC hDC = GetWindowDC(hwnd);
2037 if (TWEAK_WineLook == WIN31_LOOK)
2038 NC_DrawSysButton( hwnd, hDC, TRUE );
2039 else
2040 NC_DrawSysButton95( hwnd, hDC, TRUE );
2041 ReleaseDC( hwnd, hDC );
2043 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
2045 break;
2047 case HTMENU:
2048 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam );
2049 break;
2051 case HTHSCROLL:
2052 SendMessage16( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
2053 break;
2055 case HTVSCROLL:
2056 SendMessage16( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
2057 break;
2059 case HTMINBUTTON:
2060 case HTMAXBUTTON:
2061 if (TWEAK_WineLook == WIN31_LOOK)
2062 NC_TrackMinMaxBox( hwnd, wParam );
2063 else
2064 NC_TrackMinMaxBox95( hwnd, wParam );
2065 break;
2067 case HTCLOSE:
2068 if (TWEAK_WineLook >= WIN95_LOOK)
2069 NC_TrackCloseButton95 (hwnd, wParam);
2070 break;
2072 case HTLEFT:
2073 case HTRIGHT:
2074 case HTTOP:
2075 case HTTOPLEFT:
2076 case HTTOPRIGHT:
2077 case HTBOTTOM:
2078 case HTBOTTOMLEFT:
2079 case HTBOTTOMRIGHT:
2080 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2081 SendMessage16( hwnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam);
2082 break;
2084 case HTBORDER:
2085 break;
2087 return 0;
2091 /***********************************************************************
2092 * NC_HandleNCLButtonDblClk
2094 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2096 LONG NC_HandleNCLButtonDblClk( WND *pWnd, WPARAM16 wParam, LPARAM lParam )
2099 * if this is an icon, send a restore since we are handling
2100 * a double click
2102 if (pWnd->dwStyle & WS_MINIMIZE)
2104 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_RESTORE, lParam );
2105 return 0;
2108 switch(wParam) /* Hit test */
2110 case HTCAPTION:
2111 /* stop processing if WS_MAXIMIZEBOX is missing */
2112 if (pWnd->dwStyle & WS_MAXIMIZEBOX)
2113 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND,
2114 (pWnd->dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
2115 lParam );
2116 break;
2118 case HTSYSMENU:
2119 if (!(GetClassWord(pWnd->hwndSelf, GCW_STYLE) & CS_NOCLOSE))
2120 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, lParam );
2121 break;
2123 case HTHSCROLL:
2124 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL,
2125 lParam );
2126 break;
2128 case HTVSCROLL:
2129 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL,
2130 lParam );
2131 break;
2133 return 0;
2137 /***********************************************************************
2138 * NC_HandleSysCommand
2140 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2142 LONG NC_HandleSysCommand( HWND hwnd, WPARAM wParam, POINT pt )
2144 WND *wndPtr = WIN_FindWndPtr( hwnd );
2145 UINT16 uCommand = wParam & 0xFFF0;
2147 TRACE("Handling WM_SYSCOMMAND %x %ld,%ld\n", wParam, pt.x, pt.y );
2149 if (wndPtr->parent && (uCommand != SC_KEYMENU))
2150 ScreenToClient( wndPtr->parent->hwndSelf, &pt );
2152 switch (uCommand)
2154 case SC_SIZE:
2155 case SC_MOVE:
2156 if (USER_Driver.pSysCommandSizeMove)
2157 USER_Driver.pSysCommandSizeMove( hwnd, wParam );
2158 break;
2160 case SC_MINIMIZE:
2161 if (hwnd == GetForegroundWindow())
2162 ShowOwnedPopups(hwnd,FALSE);
2163 ShowWindow( hwnd, SW_MINIMIZE );
2164 break;
2166 case SC_MAXIMIZE:
2167 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2168 ShowOwnedPopups(hwnd,TRUE);
2169 ShowWindow( hwnd, SW_MAXIMIZE );
2170 break;
2172 case SC_RESTORE:
2173 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2174 ShowOwnedPopups(hwnd,TRUE);
2175 ShowWindow( hwnd, SW_RESTORE );
2176 break;
2178 case SC_CLOSE:
2179 WIN_ReleaseWndPtr(wndPtr);
2180 return SendMessageA( hwnd, WM_CLOSE, 0, 0 );
2182 case SC_VSCROLL:
2183 case SC_HSCROLL:
2184 NC_TrackScrollBar( hwnd, wParam, pt );
2185 break;
2187 case SC_MOUSEMENU:
2188 MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt );
2189 break;
2191 case SC_KEYMENU:
2192 MENU_TrackKbdMenuBar( wndPtr , wParam , pt.x );
2193 break;
2195 case SC_TASKLIST:
2196 WinExec( "taskman.exe", SW_SHOWNORMAL );
2197 break;
2199 case SC_SCREENSAVE:
2200 if (wParam == SC_ABOUTWINE)
2202 HMODULE hmodule = LoadLibraryA( "shell32.dll" );
2203 if (hmodule)
2205 FARPROC aboutproc = GetProcAddress( hmodule, "ShellAboutA" );
2206 if (aboutproc) aboutproc( hwnd, "Wine", WINE_RELEASE_INFO, 0 );
2207 FreeLibrary( hmodule );
2210 else
2211 if (wParam == SC_PUTMARK)
2212 TRACE_(shell)("Mark requested by user\n");
2213 break;
2215 case SC_HOTKEY:
2216 case SC_ARRANGE:
2217 case SC_NEXTWINDOW:
2218 case SC_PREVWINDOW:
2219 FIXME("unimplemented!\n");
2220 break;
2222 WIN_ReleaseWndPtr(wndPtr);
2223 return 0;
2226 /*************************************************************
2227 * NC_DrawGrayButton
2229 * Stub for the grayed button of the caption
2231 *************************************************************/
2233 BOOL NC_DrawGrayButton(HDC hdc, int x, int y)
2235 HBITMAP hMaskBmp;
2236 HDC hdcMask = CreateCompatibleDC (0);
2237 HBRUSH hOldBrush;
2239 hMaskBmp = CreateBitmap (12, 10, 1, 1, lpGrayMask);
2241 if(hMaskBmp == 0)
2242 return FALSE;
2244 SelectObject (hdcMask, hMaskBmp);
2246 /* Draw the grayed bitmap using the mask */
2247 hOldBrush = SelectObject (hdc, RGB(128, 128, 128));
2248 BitBlt (hdc, x, y, 12, 10,
2249 hdcMask, 0, 0, 0xB8074A);
2251 /* Clean up */
2252 SelectObject (hdc, hOldBrush);
2253 DeleteObject(hMaskBmp);
2254 DeleteDC (hdcMask);
2256 return TRUE;