Fixed the height of the dropped list when there are few items in the
[wine/wine64.git] / windows / nonclient.c
blob0ba158fbe3c94d5421ca83b08e22c349d02714be
1 /*
2 * Non-client area window functions
4 * Copyright 1994 Alexandre Julliard
6 */
8 #include "wine/winuser16.h"
9 #include "version.h"
10 #include "win.h"
11 #include "message.h"
12 #include "user.h"
13 #include "heap.h"
14 #include "dce.h"
15 #include "cursoricon.h"
16 #include "dialog.h"
17 #include "menu.h"
18 #include "winpos.h"
19 #include "hook.h"
20 #include "scroll.h"
21 #include "nonclient.h"
22 #include "queue.h"
23 #include "selectors.h"
24 #include "tweak.h"
25 #include "debugtools.h"
26 #include "options.h"
27 #include "shellapi.h"
28 #include "cache.h"
30 DECLARE_DEBUG_CHANNEL(nonclient)
31 DECLARE_DEBUG_CHANNEL(shell)
33 static HBITMAP16 hbitmapClose = 0;
34 static HBITMAP16 hbitmapCloseD = 0;
35 static HBITMAP16 hbitmapMinimize = 0;
36 static HBITMAP16 hbitmapMinimizeD = 0;
37 static HBITMAP16 hbitmapMaximize = 0;
38 static HBITMAP16 hbitmapMaximizeD = 0;
39 static HBITMAP16 hbitmapRestore = 0;
40 static HBITMAP16 hbitmapRestoreD = 0;
42 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
43 #define SC_PUTMARK (SC_SCREENSAVE+2)
45 /* Some useful macros */
46 #define HAS_DLGFRAME(style,exStyle) \
47 (((exStyle) & WS_EX_DLGMODALFRAME) || \
48 (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
50 #define HAS_THICKFRAME(style,exStyle) \
51 (((style) & WS_THICKFRAME) && \
52 !((exStyle) & WS_EX_DLGMODALFRAME))
54 #define HAS_THINFRAME(style) \
55 (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
57 #define HAS_BIGFRAME(style,exStyle) \
58 (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
59 ((exStyle) & WS_EX_DLGMODALFRAME))
61 #define HAS_ANYFRAME(style,exStyle) \
62 (((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
63 ((exStyle) & WS_EX_DLGMODALFRAME) || \
64 !((style) & (WS_CHILD | WS_POPUP)))
66 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
68 #define ON_LEFT_BORDER(hit) \
69 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
70 #define ON_RIGHT_BORDER(hit) \
71 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
72 #define ON_TOP_BORDER(hit) \
73 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
74 #define ON_BOTTOM_BORDER(hit) \
75 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
77 /***********************************************************************
78 * NC_AdjustRect
80 * Compute the size of the window rectangle from the size of the
81 * client rectangle.
83 static void NC_AdjustRect( LPRECT16 rect, DWORD style, BOOL menu,
84 DWORD exStyle )
86 if (TWEAK_WineLook > WIN31_LOOK)
87 ERR_(nonclient)("Called in Win95 mode. Aiee! Please report this.\n" );
89 if(style & WS_ICONIC) return;
90 /* Decide if the window will be managed (see CreateWindowEx) */
91 if (!(Options.managed && !(style & WS_CHILD) &&
92 ((style & (WS_DLGFRAME | WS_THICKFRAME)) ||
93 (exStyle & WS_EX_DLGMODALFRAME))))
95 if (HAS_THICKFRAME( style, exStyle ))
96 InflateRect16( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
97 else
98 if (HAS_DLGFRAME( style, exStyle ))
99 InflateRect16( rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
100 else
101 if (HAS_THINFRAME( style ))
102 InflateRect16( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
104 if ((style & WS_CAPTION) == WS_CAPTION)
105 rect->top -= GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
107 if (menu) rect->top -= GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYBORDER);
109 if (style & WS_VSCROLL) {
110 rect->right += GetSystemMetrics(SM_CXVSCROLL) - 1;
111 if(!HAS_ANYFRAME( style, exStyle ))
112 rect->right++;
115 if (style & WS_HSCROLL) {
116 rect->bottom += GetSystemMetrics(SM_CYHSCROLL) - 1;
117 if(!HAS_ANYFRAME( style, exStyle ))
118 rect->bottom++;
123 /******************************************************************************
124 * NC_AdjustRectOuter95
126 * Computes the size of the "outside" parts of the window based on the
127 * parameters of the client area.
129 + PARAMS
130 * LPRECT16 rect
131 * DWORD style
132 * BOOL32 menu
133 * DWORD exStyle
135 * NOTES
136 * "Outer" parts of a window means the whole window frame, caption and
137 * menu bar. It does not include "inner" parts of the frame like client
138 * edge, static edge or scroll bars.
140 * Revision history
141 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
142 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
144 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
145 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
146 * NC_AdjustRectInner95 and added handling of Win95 styles.
148 * 28-Jul-1999 Ove Kåven (ovek@arcticnet.no)
149 * Streamlined window style checks.
151 *****************************************************************************/
153 static void
154 NC_AdjustRectOuter95 (LPRECT16 rect, DWORD style, BOOL menu, DWORD exStyle)
156 if(style & WS_ICONIC) return;
158 /* Decide if the window will be managed (see CreateWindowEx) */
159 if (!(Options.managed && !(style & WS_CHILD) &&
160 ((style & (WS_DLGFRAME | WS_THICKFRAME)) ||
161 (exStyle & WS_EX_DLGMODALFRAME))))
163 if (HAS_THICKFRAME( style, exStyle ))
164 InflateRect16( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
165 else
166 if (HAS_DLGFRAME( style, exStyle ))
167 InflateRect16(rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
168 else
169 if (HAS_THINFRAME( style ))
170 InflateRect16( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
172 if ((style & WS_CAPTION) == WS_CAPTION)
174 if (exStyle & WS_EX_TOOLWINDOW)
175 rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
176 else
177 rect->top -= GetSystemMetrics(SM_CYCAPTION);
181 if (menu)
182 rect->top -= GetSystemMetrics(SM_CYMENU);
186 /******************************************************************************
187 * NC_AdjustRectInner95
189 * Computes the size of the "inside" part of the window based on the
190 * parameters of the client area.
192 + PARAMS
193 * LPRECT16 rect
194 * DWORD style
195 * DWORD exStyle
197 * NOTES
198 * "Inner" part of a window means the window frame inside of the flat
199 * window frame. It includes the client edge, the static edge and the
200 * scroll bars.
202 * Revision history
203 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
204 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
206 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
207 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
208 * NC_AdjustRectInner95 and added handling of Win95 styles.
210 *****************************************************************************/
212 static void
213 NC_AdjustRectInner95 (LPRECT16 rect, DWORD style, DWORD exStyle)
215 if(style & WS_ICONIC) return;
217 if (exStyle & WS_EX_CLIENTEDGE)
218 InflateRect16 (rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
220 if (exStyle & WS_EX_STATICEDGE)
221 InflateRect16 (rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
223 if (style & WS_VSCROLL) rect->right += GetSystemMetrics(SM_CXVSCROLL);
224 if (style & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
228 /***********************************************************************
229 * DrawCaption16 [USER.660] Draws a caption bar
231 * PARAMS
232 * hwnd [I]
233 * hdc [I]
234 * lpRect [I]
235 * uFlags [I]
237 * RETURNS
238 * Success:
239 * Failure:
242 BOOL16 WINAPI
243 DrawCaption16 (HWND16 hwnd, HDC16 hdc, const RECT16 *rect, UINT16 uFlags)
245 RECT rect32;
247 if (rect)
248 CONV_RECT16TO32 (rect, &rect32);
250 return (BOOL16)DrawCaptionTempA (hwnd, hdc, rect ? &rect32 : NULL,
251 0, 0, NULL, uFlags & 0x1F);
255 /***********************************************************************
256 * DrawCaption32 [USER32.154] Draws a caption bar
258 * PARAMS
259 * hwnd [I]
260 * hdc [I]
261 * lpRect [I]
262 * uFlags [I]
264 * RETURNS
265 * Success:
266 * Failure:
269 BOOL WINAPI
270 DrawCaption (HWND hwnd, HDC hdc, const RECT *lpRect, UINT uFlags)
272 return DrawCaptionTempA (hwnd, hdc, lpRect, 0, 0, NULL, uFlags & 0x1F);
276 /***********************************************************************
277 * DrawCaptionTemp16 [USER.657]
279 * PARAMS
281 * RETURNS
282 * Success:
283 * Failure:
286 BOOL16 WINAPI
287 DrawCaptionTemp16 (HWND16 hwnd, HDC16 hdc, const RECT16 *rect, HFONT16 hFont,
288 HICON16 hIcon, LPCSTR str, UINT16 uFlags)
290 RECT rect32;
292 if (rect)
293 CONV_RECT16TO32(rect,&rect32);
295 return (BOOL16)DrawCaptionTempA (hwnd, hdc, rect?&rect32:NULL, hFont,
296 hIcon, str, uFlags & 0x1F);
300 /***********************************************************************
301 * DrawCaptionTemp32A [USER32.599]
303 * PARAMS
305 * RETURNS
306 * Success:
307 * Failure:
310 BOOL WINAPI
311 DrawCaptionTempA (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
312 HICON hIcon, LPCSTR str, UINT uFlags)
314 RECT rc = *rect;
316 TRACE_(nonclient)("(%08x,%08x,%p,%08x,%08x,\"%s\",%08x)\n",
317 hwnd, hdc, rect, hFont, hIcon, str, uFlags);
319 /* drawing background */
320 if (uFlags & DC_INBUTTON) {
321 FillRect (hdc, &rc, GetSysColorBrush (COLOR_3DFACE));
323 if (uFlags & DC_ACTIVE) {
324 HBRUSH hbr = SelectObject (hdc, CACHE_GetPattern55AABrush ());
325 PatBlt (hdc, rc.left, rc.top,
326 rc.right-rc.left, rc.bottom-rc.top, 0xFA0089);
327 SelectObject (hdc, hbr);
330 else {
331 FillRect (hdc, &rc, GetSysColorBrush ((uFlags & DC_ACTIVE) ?
332 COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
336 /* drawing icon */
337 if ((uFlags & DC_ICON) && !(uFlags & DC_SMALLCAP)) {
338 POINT pt;
340 pt.x = rc.left + 2;
341 pt.y = (rc.bottom + rc.top - GetSystemMetrics(SM_CYSMICON)) / 2;
343 if (hIcon) {
344 DrawIconEx (hdc, pt.x, pt.y, hIcon, GetSystemMetrics(SM_CXSMICON),
345 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
347 else {
348 HICON hAppIcon = (HICON) GetClassLongA(hwnd, GCL_HICONSM);
349 if(!hAppIcon) hAppIcon = (HICON) GetClassLongA(hwnd, GCL_HICON);
351 DrawIconEx (hdc, pt.x, pt.y, hAppIcon, GetSystemMetrics(SM_CXSMICON),
352 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
355 rc.left += (rc.bottom - rc.top);
358 /* drawing text */
359 if (uFlags & DC_TEXT) {
360 HFONT hOldFont;
362 if (uFlags & DC_INBUTTON)
363 SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
364 else if (uFlags & DC_ACTIVE)
365 SetTextColor (hdc, GetSysColor (COLOR_CAPTIONTEXT));
366 else
367 SetTextColor (hdc, GetSysColor (COLOR_INACTIVECAPTIONTEXT));
369 SetBkMode (hdc, TRANSPARENT);
371 if (hFont)
372 hOldFont = SelectObject (hdc, hFont);
373 else {
374 NONCLIENTMETRICSA nclm;
375 HFONT hNewFont;
376 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
377 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
378 hNewFont = CreateFontIndirectA ((uFlags & DC_SMALLCAP) ?
379 &nclm.lfSmCaptionFont : &nclm.lfCaptionFont);
380 hOldFont = SelectObject (hdc, hNewFont);
383 if (str)
384 DrawTextA (hdc, str, -1, &rc,
385 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
386 else {
387 CHAR szText[128];
388 INT nLen;
389 nLen = GetWindowTextA (hwnd, szText, 128);
390 DrawTextA (hdc, szText, nLen, &rc,
391 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
394 if (hFont)
395 SelectObject (hdc, hOldFont);
396 else
397 DeleteObject (SelectObject (hdc, hOldFont));
400 /* drawing focus ??? */
401 if (uFlags & 0x2000)
402 FIXME_(nonclient)("undocumented flag (0x2000)!\n");
404 return 0;
408 /***********************************************************************
409 * DrawCaptionTemp32W [USER32.602]
411 * PARAMS
413 * RETURNS
414 * Success:
415 * Failure:
418 BOOL WINAPI
419 DrawCaptionTempW (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
420 HICON hIcon, LPCWSTR str, UINT uFlags)
422 LPSTR p = HEAP_strdupWtoA (GetProcessHeap (), 0, str);
423 BOOL res = DrawCaptionTempA (hwnd, hdc, rect, hFont, hIcon, p, uFlags);
424 HeapFree (GetProcessHeap (), 0, p);
425 return res;
429 /***********************************************************************
430 * AdjustWindowRect16 (USER.102)
432 BOOL16 WINAPI AdjustWindowRect16( LPRECT16 rect, DWORD style, BOOL16 menu )
434 return AdjustWindowRectEx16( rect, style, menu, 0 );
438 /***********************************************************************
439 * AdjustWindowRect32 (USER32.2)
441 BOOL WINAPI AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu )
443 return AdjustWindowRectEx( rect, style, menu, 0 );
447 /***********************************************************************
448 * AdjustWindowRectEx16 (USER.454)
450 BOOL16 WINAPI AdjustWindowRectEx16( LPRECT16 rect, DWORD style,
451 BOOL16 menu, DWORD exStyle )
453 /* Correct the window style */
455 if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
456 style |= WS_CAPTION;
457 style &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD);
458 exStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE |
459 WS_EX_STATICEDGE | WS_EX_TOOLWINDOW);
460 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
462 TRACE_(nonclient)("(%d,%d)-(%d,%d) %08lx %d %08lx\n",
463 rect->left, rect->top, rect->right, rect->bottom,
464 style, menu, exStyle );
466 if (TWEAK_WineLook == WIN31_LOOK)
467 NC_AdjustRect( rect, style, menu, exStyle );
468 else {
469 NC_AdjustRectOuter95( rect, style, menu, exStyle );
470 NC_AdjustRectInner95( rect, style, exStyle );
473 return TRUE;
477 /***********************************************************************
478 * AdjustWindowRectEx32 (USER32.3)
480 BOOL WINAPI AdjustWindowRectEx( LPRECT rect, DWORD style,
481 BOOL menu, DWORD exStyle )
483 RECT16 rect16;
484 BOOL ret;
486 CONV_RECT32TO16( rect, &rect16 );
487 ret = AdjustWindowRectEx16( &rect16, style, (BOOL16)menu, exStyle );
488 CONV_RECT16TO32( &rect16, rect );
489 return ret;
493 /***********************************************************************
494 * NC_HandleNCCalcSize
496 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
498 LONG NC_HandleNCCalcSize( WND *pWnd, RECT *winRect )
500 RECT16 tmpRect = { 0, 0, 0, 0 };
501 LONG result = 0;
502 UINT style = (UINT) GetClassLongA(pWnd->hwndSelf, GCL_STYLE);
504 if (style & CS_VREDRAW) result |= WVR_VREDRAW;
505 if (style & CS_HREDRAW) result |= WVR_HREDRAW;
507 if( !( pWnd->dwStyle & WS_MINIMIZE ) ) {
508 if (TWEAK_WineLook == WIN31_LOOK)
509 NC_AdjustRect( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
510 else
511 NC_AdjustRectOuter95( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
513 winRect->left -= tmpRect.left;
514 winRect->top -= tmpRect.top;
515 winRect->right -= tmpRect.right;
516 winRect->bottom -= tmpRect.bottom;
518 if (HAS_MENU(pWnd)) {
519 TRACE_(nonclient)("Calling "
520 "GetMenuBarHeight with HWND 0x%x, width %d, "
521 "at (%d, %d).\n", pWnd->hwndSelf,
522 winRect->right - winRect->left,
523 -tmpRect.left, -tmpRect.top );
525 winRect->top +=
526 MENU_GetMenuBarHeight( pWnd->hwndSelf,
527 winRect->right - winRect->left,
528 -tmpRect.left, -tmpRect.top ) + 1;
531 if (TWEAK_WineLook > WIN31_LOOK) {
532 SetRect16 (&tmpRect, 0, 0, 0, 0);
533 NC_AdjustRectInner95 (&tmpRect, pWnd->dwStyle, pWnd->dwExStyle);
534 winRect->left -= tmpRect.left;
535 winRect->top -= tmpRect.top;
536 winRect->right -= tmpRect.right;
537 winRect->bottom -= tmpRect.bottom;
540 return result;
544 /***********************************************************************
545 * NC_GetInsideRect
547 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
548 * but without the borders (if any).
549 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
551 static void NC_GetInsideRect( HWND hwnd, RECT *rect )
553 WND * wndPtr = WIN_FindWndPtr( hwnd );
555 rect->top = rect->left = 0;
556 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
557 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
559 if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) goto END;
561 /* Remove frame from rectangle */
562 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
563 InflateRect( rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
564 else
565 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
567 InflateRect( rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
568 /* FIXME: this isn't in NC_AdjustRect? why not? */
569 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
570 InflateRect( rect, -1, 0 );
572 else
573 if (HAS_THINFRAME( wndPtr->dwStyle ))
574 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
575 END:
576 WIN_ReleaseWndPtr(wndPtr);
577 return;
581 /***********************************************************************
582 * NC_GetInsideRect95
584 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
585 * but without the borders (if any).
586 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
589 static void
590 NC_GetInsideRect95 (HWND hwnd, RECT *rect)
592 WND * wndPtr = WIN_FindWndPtr( hwnd );
594 rect->top = rect->left = 0;
595 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
596 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
598 if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) goto END;
600 /* Remove frame from rectangle */
601 if (HAS_THICKFRAME (wndPtr->dwStyle, wndPtr->dwExStyle))
603 InflateRect( rect, -GetSystemMetrics(SM_CXSIZEFRAME), -GetSystemMetrics(SM_CYSIZEFRAME) );
605 else if (HAS_DLGFRAME (wndPtr->dwStyle, wndPtr->dwExStyle ))
607 InflateRect( rect, -GetSystemMetrics(SM_CXFIXEDFRAME), -GetSystemMetrics(SM_CYFIXEDFRAME));
609 else if (HAS_THINFRAME (wndPtr->dwStyle))
611 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
614 if (wndPtr->dwStyle & WS_CHILD) {
615 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
616 InflateRect (rect, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE));
618 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
619 InflateRect (rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
621 END:
622 WIN_ReleaseWndPtr(wndPtr);
623 return;
627 /***********************************************************************
628 * NC_DoNCHitTest
630 * Handle a WM_NCHITTEST message. Called from NC_HandleNcHitTest().
633 static LONG NC_DoNCHitTest (WND *wndPtr, POINT16 pt )
635 RECT16 rect;
637 TRACE_(nonclient)("hwnd=%04x pt=%d,%d\n",
638 wndPtr->hwndSelf, pt.x, pt.y );
640 GetWindowRect16 (wndPtr->hwndSelf, &rect );
641 if (!PtInRect16( &rect, pt )) return HTNOWHERE;
643 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
645 if (!(wndPtr->flags & WIN_MANAGED))
647 /* Check borders */
648 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
650 InflateRect16( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
651 if (!PtInRect16( &rect, pt ))
653 /* Check top sizing border */
654 if (pt.y < rect.top)
656 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
657 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
658 return HTTOP;
660 /* Check bottom sizing border */
661 if (pt.y >= rect.bottom)
663 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
664 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
665 return HTBOTTOM;
667 /* Check left sizing border */
668 if (pt.x < rect.left)
670 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
671 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
672 return HTLEFT;
674 /* Check right sizing border */
675 if (pt.x >= rect.right)
677 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
678 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
679 return HTRIGHT;
683 else /* No thick frame */
685 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
686 InflateRect16(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
687 else if (HAS_THINFRAME( wndPtr->dwStyle ))
688 InflateRect16(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
689 if (!PtInRect16( &rect, pt )) return HTBORDER;
692 /* Check caption */
694 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
696 rect.top += GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
697 if (!PtInRect16( &rect, pt ))
699 /* Check system menu */
700 if (wndPtr->dwStyle & WS_SYSMENU)
701 rect.left += GetSystemMetrics(SM_CXSIZE);
702 if (pt.x <= rect.left) return HTSYSMENU;
703 /* Check maximize box */
704 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
705 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
706 if (pt.x >= rect.right) return HTMAXBUTTON;
707 /* Check minimize box */
708 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
709 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
710 if (pt.x >= rect.right) return HTMINBUTTON;
711 return HTCAPTION;
716 /* Check client area */
718 ScreenToClient16( wndPtr->hwndSelf, &pt );
719 GetClientRect16( wndPtr->hwndSelf, &rect );
720 if (PtInRect16( &rect, pt )) return HTCLIENT;
722 /* Check vertical scroll bar */
724 if (wndPtr->dwStyle & WS_VSCROLL)
726 rect.right += GetSystemMetrics(SM_CXVSCROLL);
727 if (PtInRect16( &rect, pt )) return HTVSCROLL;
730 /* Check horizontal scroll bar */
732 if (wndPtr->dwStyle & WS_HSCROLL)
734 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
735 if (PtInRect16( &rect, pt ))
737 /* Check size box */
738 if ((wndPtr->dwStyle & WS_VSCROLL) &&
739 (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
740 return HTSIZE;
741 return HTHSCROLL;
745 /* Check menu bar */
747 if (HAS_MENU(wndPtr))
749 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
750 return HTMENU;
753 /* Should never get here */
754 return HTERROR;
758 /***********************************************************************
759 * NC_DoNCHitTest95
761 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
763 * FIXME: Just a modified copy of the Win 3.1 version.
766 static LONG
767 NC_DoNCHitTest95 (WND *wndPtr, POINT16 pt )
769 RECT16 rect;
771 TRACE_(nonclient)("hwnd=%04x pt=%d,%d\n",
772 wndPtr->hwndSelf, pt.x, pt.y );
774 GetWindowRect16 (wndPtr->hwndSelf, &rect );
775 if (!PtInRect16( &rect, pt )) return HTNOWHERE;
777 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
779 if (!(wndPtr->flags & WIN_MANAGED))
781 /* Check borders */
782 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
784 InflateRect16( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
785 if (!PtInRect16( &rect, pt ))
787 /* Check top sizing border */
788 if (pt.y < rect.top)
790 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
791 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
792 return HTTOP;
794 /* Check bottom sizing border */
795 if (pt.y >= rect.bottom)
797 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
798 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
799 return HTBOTTOM;
801 /* Check left sizing border */
802 if (pt.x < rect.left)
804 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
805 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
806 return HTLEFT;
808 /* Check right sizing border */
809 if (pt.x >= rect.right)
811 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
812 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
813 return HTRIGHT;
817 else /* No thick frame */
819 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
820 InflateRect16(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
821 else if (HAS_THINFRAME( wndPtr->dwStyle ))
822 InflateRect16(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
823 if (!PtInRect16( &rect, pt )) return HTBORDER;
826 /* Check caption */
828 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
830 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
831 rect.top += GetSystemMetrics(SM_CYSMCAPTION) - 1;
832 else
833 rect.top += GetSystemMetrics(SM_CYCAPTION) - 1;
834 if (!PtInRect16( &rect, pt ))
836 /* Check system menu */
837 if ((wndPtr->dwStyle & WS_SYSMENU) &&
838 (((HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICONSM)) ||
839 ((HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICON))))
840 rect.left += GetSystemMetrics(SM_CYCAPTION) - 1;
841 if (pt.x < rect.left) return HTSYSMENU;
843 /* Check close button */
844 if (wndPtr->dwStyle & WS_SYSMENU)
845 rect.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
846 if (pt.x > rect.right) return HTCLOSE;
848 /* Check maximize box */
849 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
850 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
851 if (pt.x > rect.right) return HTMAXBUTTON;
853 /* Check minimize box */
854 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
855 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
856 if (pt.x > rect.right) return HTMINBUTTON;
857 return HTCAPTION;
862 /* Check client area */
864 ScreenToClient16( wndPtr->hwndSelf, &pt );
865 GetClientRect16( wndPtr->hwndSelf, &rect );
866 if (PtInRect16( &rect, pt )) return HTCLIENT;
868 /* Check vertical scroll bar */
870 if (wndPtr->dwStyle & WS_VSCROLL)
872 rect.right += GetSystemMetrics(SM_CXVSCROLL);
873 if (PtInRect16( &rect, pt )) return HTVSCROLL;
876 /* Check horizontal scroll bar */
878 if (wndPtr->dwStyle & WS_HSCROLL)
880 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
881 if (PtInRect16( &rect, pt ))
883 /* Check size box */
884 if ((wndPtr->dwStyle & WS_VSCROLL) &&
885 (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
886 return HTSIZE;
887 return HTHSCROLL;
891 /* Check menu bar */
893 if (HAS_MENU(wndPtr))
895 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
896 return HTMENU;
899 /* Should never get here */
900 return HTERROR;
904 /***********************************************************************
905 * NC_HandleNCHitTest
907 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
909 LONG
910 NC_HandleNCHitTest (HWND hwnd , POINT16 pt)
912 LONG retvalue;
913 WND *wndPtr = WIN_FindWndPtr (hwnd);
915 if (!wndPtr)
916 return HTERROR;
918 if (TWEAK_WineLook == WIN31_LOOK)
919 retvalue = NC_DoNCHitTest (wndPtr, pt);
920 else
921 retvalue = NC_DoNCHitTest95 (wndPtr, pt);
922 WIN_ReleaseWndPtr(wndPtr);
923 return retvalue;
927 /***********************************************************************
928 * NC_DrawSysButton
930 void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down )
932 RECT rect;
933 HDC hdcMem;
934 HBITMAP hbitmap;
935 WND *wndPtr = WIN_FindWndPtr( hwnd );
937 if( !(wndPtr->flags & WIN_MANAGED) )
939 NC_GetInsideRect( hwnd, &rect );
940 hdcMem = CreateCompatibleDC( hdc );
941 hbitmap = SelectObject( hdcMem, hbitmapClose );
942 BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE), GetSystemMetrics(SM_CYSIZE),
943 hdcMem, (wndPtr->dwStyle & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE) : 0, 0,
944 down ? NOTSRCCOPY : SRCCOPY );
945 SelectObject( hdcMem, hbitmap );
946 DeleteDC( hdcMem );
948 WIN_ReleaseWndPtr(wndPtr);
952 /***********************************************************************
953 * NC_DrawMaxButton
955 static void NC_DrawMaxButton( HWND hwnd, HDC16 hdc, BOOL down )
957 RECT rect;
958 WND *wndPtr = WIN_FindWndPtr( hwnd );
959 HDC hdcMem;
961 if( !(wndPtr->flags & WIN_MANAGED) )
963 NC_GetInsideRect( hwnd, &rect );
964 hdcMem = CreateCompatibleDC( hdc );
965 SelectObject( hdcMem, (IsZoomed(hwnd)
966 ? (down ? hbitmapRestoreD : hbitmapRestore)
967 : (down ? hbitmapMaximizeD : hbitmapMaximize)) );
968 BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
969 GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
970 SRCCOPY );
971 DeleteDC( hdcMem );
973 WIN_ReleaseWndPtr(wndPtr);
978 /***********************************************************************
979 * NC_DrawMinButton
981 static void NC_DrawMinButton( HWND hwnd, HDC16 hdc, BOOL down )
983 RECT rect;
984 WND *wndPtr = WIN_FindWndPtr( hwnd );
985 HDC hdcMem;
987 if( !(wndPtr->flags & WIN_MANAGED) )
989 NC_GetInsideRect( hwnd, &rect );
990 hdcMem = CreateCompatibleDC( hdc );
991 SelectObject( hdcMem, (down ? hbitmapMinimizeD : hbitmapMinimize) );
992 if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= GetSystemMetrics(SM_CXSIZE)+1;
993 BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
994 GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
995 SRCCOPY );
996 DeleteDC( hdcMem );
998 WIN_ReleaseWndPtr(wndPtr);
1002 /******************************************************************************
1004 * void NC_DrawSysButton95(
1005 * HWND32 hwnd,
1006 * HDC32 hdc,
1007 * BOOL32 down )
1009 * Draws the Win95 system icon.
1011 * Revision history
1012 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1013 * Original implementation from NC_DrawSysButton source.
1014 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1015 * Fixed most bugs.
1017 *****************************************************************************/
1019 BOOL
1020 NC_DrawSysButton95 (HWND hwnd, HDC hdc, BOOL down)
1022 WND *wndPtr = WIN_FindWndPtr( hwnd );
1024 if( !(wndPtr->flags & WIN_MANAGED) )
1026 HICON hIcon;
1027 RECT rect;
1029 NC_GetInsideRect95( hwnd, &rect );
1031 hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICONSM);
1032 if(!hIcon) hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICON);
1034 if (hIcon)
1035 DrawIconEx (hdc, rect.left + 2, rect.top + 2, hIcon,
1036 GetSystemMetrics(SM_CXSMICON),
1037 GetSystemMetrics(SM_CYSMICON),
1038 0, 0, DI_NORMAL);
1040 WIN_ReleaseWndPtr(wndPtr);
1041 return (hIcon != 0);
1043 WIN_ReleaseWndPtr(wndPtr);
1044 return FALSE;
1048 /******************************************************************************
1050 * void NC_DrawCloseButton95(
1051 * HWND32 hwnd,
1052 * HDC32 hdc,
1053 * BOOL32 down )
1055 * Draws the Win95 close button.
1057 * Revision history
1058 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1059 * Original implementation from NC_DrawSysButton95 source.
1061 *****************************************************************************/
1063 static void NC_DrawCloseButton95 (HWND hwnd, HDC hdc, BOOL down)
1065 RECT rect;
1066 HDC hdcMem;
1067 WND *wndPtr = WIN_FindWndPtr( hwnd );
1069 if( !(wndPtr->flags & WIN_MANAGED) )
1071 BITMAP bmp;
1072 HBITMAP hBmp, hOldBmp;
1074 NC_GetInsideRect95( hwnd, &rect );
1076 hdcMem = CreateCompatibleDC( hdc );
1077 hBmp = down ? hbitmapCloseD : hbitmapClose;
1078 hOldBmp = SelectObject (hdcMem, hBmp);
1079 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1080 BitBlt (hdc, rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2,
1081 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1082 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);
1084 SelectObject (hdcMem, hOldBmp);
1085 DeleteDC (hdcMem);
1087 WIN_ReleaseWndPtr(wndPtr);
1090 /******************************************************************************
1092 * NC_DrawMaxButton95(
1093 * HWND32 hwnd,
1094 * HDC16 hdc,
1095 * BOOL32 down )
1097 * Draws the maximize button for Win95 style windows.
1099 * Bugs
1100 * Many. Spacing might still be incorrect. Need to fit a close
1101 * button between the max button and the edge.
1102 * Should scale the image with the title bar. And more...
1104 * Revision history
1105 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1106 * Original implementation.
1108 *****************************************************************************/
1110 static void NC_DrawMaxButton95(HWND hwnd,HDC16 hdc,BOOL down )
1112 RECT rect;
1113 HDC hdcMem;
1114 WND *wndPtr = WIN_FindWndPtr( hwnd );
1116 if( !(wndPtr->flags & WIN_MANAGED))
1118 BITMAP bmp;
1119 HBITMAP hBmp,hOldBmp;
1121 NC_GetInsideRect95( hwnd, &rect );
1122 hdcMem = CreateCompatibleDC( hdc );
1123 hBmp = IsZoomed(hwnd) ?
1124 (down ? hbitmapRestoreD : hbitmapRestore ) :
1125 (down ? hbitmapMaximizeD: hbitmapMaximize);
1126 hOldBmp=SelectObject( hdcMem, hBmp );
1127 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1129 if (wndPtr->dwStyle & WS_SYSMENU)
1130 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1132 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1133 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1134 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1135 SelectObject (hdcMem, hOldBmp);
1136 DeleteDC( hdcMem );
1138 WIN_ReleaseWndPtr(wndPtr);
1141 /******************************************************************************
1143 * NC_DrawMinButton95(
1144 * HWND32 hwnd,
1145 * HDC16 hdc,
1146 * BOOL32 down )
1148 * Draws the minimize button for Win95 style windows.
1150 * Bugs
1151 * Many. Spacing is still incorrect. Should scale the image with the
1152 * title bar. And more...
1154 * Revision history
1155 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1156 * Original implementation.
1158 *****************************************************************************/
1160 static void NC_DrawMinButton95(HWND hwnd,HDC16 hdc,BOOL down )
1162 RECT rect;
1163 HDC hdcMem;
1164 WND *wndPtr = WIN_FindWndPtr( hwnd );
1166 if( !(wndPtr->flags & WIN_MANAGED))
1169 BITMAP bmp;
1170 HBITMAP hBmp,hOldBmp;
1172 NC_GetInsideRect95( hwnd, &rect );
1174 hdcMem = CreateCompatibleDC( hdc );
1175 hBmp = down ? hbitmapMinimizeD : hbitmapMinimize;
1176 hOldBmp= SelectObject( hdcMem, hBmp );
1177 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1179 if (wndPtr->dwStyle & WS_SYSMENU)
1180 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1182 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
1183 rect.right += -1 - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2;
1185 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1186 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1187 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1189 SelectObject (hdcMem, hOldBmp);
1190 DeleteDC( hdcMem );
1192 WIN_ReleaseWndPtr(wndPtr);
1195 /***********************************************************************
1196 * NC_DrawFrame
1198 * Draw a window frame inside the given rectangle, and update the rectangle.
1199 * The correct pen for the frame must be selected in the DC.
1201 static void NC_DrawFrame( HDC hdc, RECT *rect, BOOL dlgFrame,
1202 BOOL active )
1204 INT width, height;
1206 if (TWEAK_WineLook != WIN31_LOOK)
1207 ERR_(nonclient)("Called in Win95 mode. Aiee! Please report this.\n" );
1209 if (dlgFrame)
1211 width = GetSystemMetrics(SM_CXDLGFRAME) - 1;
1212 height = GetSystemMetrics(SM_CYDLGFRAME) - 1;
1213 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1214 COLOR_INACTIVECAPTION) );
1216 else
1218 width = GetSystemMetrics(SM_CXFRAME) - 2;
1219 height = GetSystemMetrics(SM_CYFRAME) - 2;
1220 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1221 COLOR_INACTIVEBORDER) );
1224 /* Draw frame */
1225 PatBlt( hdc, rect->left, rect->top,
1226 rect->right - rect->left, height, PATCOPY );
1227 PatBlt( hdc, rect->left, rect->top,
1228 width, rect->bottom - rect->top, PATCOPY );
1229 PatBlt( hdc, rect->left, rect->bottom - 1,
1230 rect->right - rect->left, -height, PATCOPY );
1231 PatBlt( hdc, rect->right - 1, rect->top,
1232 -width, rect->bottom - rect->top, PATCOPY );
1234 if (dlgFrame)
1236 InflateRect( rect, -width, -height );
1238 else
1240 INT decYOff = GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXSIZE) - 1;
1241 INT decXOff = GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYSIZE) - 1;
1243 /* Draw inner rectangle */
1245 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1246 Rectangle( hdc, rect->left + width, rect->top + height,
1247 rect->right - width , rect->bottom - height );
1249 /* Draw the decorations */
1251 MoveToEx( hdc, rect->left, rect->top + decYOff, NULL );
1252 LineTo( hdc, rect->left + width, rect->top + decYOff );
1253 MoveToEx( hdc, rect->right - 1, rect->top + decYOff, NULL );
1254 LineTo( hdc, rect->right - width - 1, rect->top + decYOff );
1255 MoveToEx( hdc, rect->left, rect->bottom - decYOff, NULL );
1256 LineTo( hdc, rect->left + width, rect->bottom - decYOff );
1257 MoveToEx( hdc, rect->right - 1, rect->bottom - decYOff, NULL );
1258 LineTo( hdc, rect->right - width - 1, rect->bottom - decYOff );
1260 MoveToEx( hdc, rect->left + decXOff, rect->top, NULL );
1261 LineTo( hdc, rect->left + decXOff, rect->top + height);
1262 MoveToEx( hdc, rect->left + decXOff, rect->bottom - 1, NULL );
1263 LineTo( hdc, rect->left + decXOff, rect->bottom - height - 1 );
1264 MoveToEx( hdc, rect->right - decXOff, rect->top, NULL );
1265 LineTo( hdc, rect->right - decXOff, rect->top + height );
1266 MoveToEx( hdc, rect->right - decXOff, rect->bottom - 1, NULL );
1267 LineTo( hdc, rect->right - decXOff, rect->bottom - height - 1 );
1269 InflateRect( rect, -width - 1, -height - 1 );
1274 /******************************************************************************
1276 * void NC_DrawFrame95(
1277 * HDC32 hdc,
1278 * RECT32 *rect,
1279 * BOOL32 dlgFrame,
1280 * BOOL32 active )
1282 * Draw a window frame inside the given rectangle, and update the rectangle.
1283 * The correct pen for the frame must be selected in the DC.
1285 * Bugs
1286 * Many. First, just what IS a frame in Win95? Note that the 3D look
1287 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1288 * edge. The inner rectangle just inside the frame is handled by the
1289 * Caption code.
1291 * In short, for most people, this function should be a nop (unless
1292 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1293 * them lately, but just to get this code right). Even so, it doesn't
1294 * appear to be so. It's being worked on...
1296 * Revision history
1297 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1298 * Original implementation (based on NC_DrawFrame)
1299 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1300 * Some minor fixes.
1301 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1302 * Fixed a fix or something.
1304 *****************************************************************************/
1306 static void NC_DrawFrame95(
1307 HDC hdc,
1308 RECT *rect,
1309 BOOL dlgFrame,
1310 BOOL active )
1312 INT width, height;
1314 if (dlgFrame)
1316 width = GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
1317 height = GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
1319 else
1321 width = GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXEDGE);
1322 height = GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYEDGE);
1325 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1326 COLOR_INACTIVEBORDER) );
1328 /* Draw frame */
1329 PatBlt( hdc, rect->left, rect->top,
1330 rect->right - rect->left, height, PATCOPY );
1331 PatBlt( hdc, rect->left, rect->top,
1332 width, rect->bottom - rect->top, PATCOPY );
1333 PatBlt( hdc, rect->left, rect->bottom - 1,
1334 rect->right - rect->left, -height, PATCOPY );
1335 PatBlt( hdc, rect->right - 1, rect->top,
1336 -width, rect->bottom - rect->top, PATCOPY );
1338 InflateRect( rect, -width, -height );
1341 /***********************************************************************
1342 * NC_DrawMovingFrame
1344 * Draw the frame used when moving or resizing window.
1346 * FIXME: This causes problems in Win95 mode. (why?)
1348 static void NC_DrawMovingFrame( HDC hdc, RECT *rect, BOOL thickframe )
1350 if (thickframe)
1352 RECT16 r16;
1353 CONV_RECT32TO16( rect, &r16 );
1354 FastWindowFrame16( hdc, &r16, GetSystemMetrics(SM_CXFRAME),
1355 GetSystemMetrics(SM_CYFRAME), PATINVERT );
1357 else DrawFocusRect( hdc, rect );
1361 /***********************************************************************
1362 * NC_DrawCaption
1364 * Draw the window caption.
1365 * The correct pen for the window frame must be selected in the DC.
1367 static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd,
1368 DWORD style, BOOL active )
1370 RECT r = *rect;
1371 WND * wndPtr = WIN_FindWndPtr( hwnd );
1372 char buffer[256];
1374 if (wndPtr->flags & WIN_MANAGED)
1376 WIN_ReleaseWndPtr(wndPtr);
1377 return;
1380 if (!hbitmapClose)
1382 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1384 WIN_ReleaseWndPtr(wndPtr);
1385 return;
1387 hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED) );
1388 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1389 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1390 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1391 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1392 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1393 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1396 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
1398 HBRUSH hbrushOld = SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW) );
1399 PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
1400 PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
1401 PatBlt( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
1402 r.left++;
1403 r.right--;
1404 SelectObject( hdc, hbrushOld );
1406 WIN_ReleaseWndPtr(wndPtr);
1407 MoveTo16( hdc, r.left, r.bottom );
1408 LineTo( hdc, r.right, r.bottom );
1410 if (style & WS_SYSMENU)
1412 NC_DrawSysButton( hwnd, hdc, FALSE );
1413 r.left += GetSystemMetrics(SM_CXSIZE) + 1;
1414 MoveTo16( hdc, r.left - 1, r.top );
1415 LineTo( hdc, r.left - 1, r.bottom );
1417 if (style & WS_MAXIMIZEBOX)
1419 NC_DrawMaxButton( hwnd, hdc, FALSE );
1420 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1422 if (style & WS_MINIMIZEBOX)
1424 NC_DrawMinButton( hwnd, hdc, FALSE );
1425 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1428 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1429 COLOR_INACTIVECAPTION) );
1431 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) ))
1433 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1434 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1435 SetBkMode( hdc, TRANSPARENT );
1436 DrawTextA( hdc, buffer, -1, &r,
1437 DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );
1442 /******************************************************************************
1444 * NC_DrawCaption95(
1445 * HDC32 hdc,
1446 * RECT32 *rect,
1447 * HWND32 hwnd,
1448 * DWORD style,
1449 * BOOL32 active )
1451 * Draw the window caption for Win95 style windows.
1452 * The correct pen for the window frame must be selected in the DC.
1454 * Bugs
1455 * Hey, a function that finally works! Well, almost.
1456 * It's being worked on.
1458 * Revision history
1459 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1460 * Original implementation.
1461 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1462 * Some minor fixes.
1464 *****************************************************************************/
1466 static void NC_DrawCaption95(
1467 HDC hdc,
1468 RECT *rect,
1469 HWND hwnd,
1470 DWORD style,
1471 DWORD exStyle,
1472 BOOL active )
1474 RECT r = *rect;
1475 WND *wndPtr = WIN_FindWndPtr( hwnd );
1476 char buffer[256];
1477 HPEN hPrevPen;
1479 if (wndPtr->flags & WIN_MANAGED)
1481 WIN_ReleaseWndPtr(wndPtr);
1482 return;
1484 WIN_ReleaseWndPtr(wndPtr);
1486 hPrevPen = SelectObject( hdc, GetSysColorPen(COLOR_3DFACE) );
1487 MoveToEx( hdc, r.left, r.bottom - 1, NULL );
1488 LineTo( hdc, r.right, r.bottom - 1 );
1489 SelectObject( hdc, hPrevPen );
1490 r.bottom--;
1492 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1493 COLOR_INACTIVECAPTION) );
1495 if (!hbitmapClose) {
1496 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1497 return;
1498 hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED));
1499 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1500 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1501 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1502 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1503 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1504 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1507 if ((style & WS_SYSMENU) && !(exStyle & WS_EX_TOOLWINDOW)) {
1508 if (NC_DrawSysButton95 (hwnd, hdc, FALSE))
1509 r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
1511 if (style & WS_SYSMENU) {
1512 NC_DrawCloseButton95 (hwnd, hdc, FALSE);
1513 r.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
1515 if (style & WS_MAXIMIZEBOX) {
1516 NC_DrawMaxButton95( hwnd, hdc, FALSE );
1517 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1519 if (style & WS_MINIMIZEBOX) {
1520 NC_DrawMinButton95( hwnd, hdc, FALSE );
1521 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1524 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) )) {
1525 NONCLIENTMETRICSA nclm;
1526 HFONT hFont, hOldFont;
1527 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1528 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1529 if (exStyle & WS_EX_TOOLWINDOW)
1530 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
1531 else
1532 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
1533 hOldFont = SelectObject (hdc, hFont);
1534 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1535 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1536 SetBkMode( hdc, TRANSPARENT );
1537 r.left += 2;
1538 DrawTextA( hdc, buffer, -1, &r,
1539 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
1540 DeleteObject (SelectObject (hdc, hOldFont));
1546 /***********************************************************************
1547 * NC_DoNCPaint
1549 * Paint the non-client area. clip is currently unused.
1551 static void NC_DoNCPaint( WND* wndPtr, HRGN clip, BOOL suppress_menupaint )
1553 HDC hdc;
1554 RECT rect;
1555 BOOL active;
1556 HWND hwnd = wndPtr->hwndSelf;
1558 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1559 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1561 active = wndPtr->flags & WIN_NCACTIVATED;
1563 TRACE_(nonclient)("%04x %d\n", hwnd, active );
1565 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1566 ((clip > 1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN): 0) ))) return;
1568 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1569 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1570 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1571 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1572 == NULLREGION)
1574 ReleaseDC( hwnd, hdc );
1575 return;
1578 rect.top = rect.left = 0;
1579 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1580 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1582 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1584 if (!(wndPtr->flags & WIN_MANAGED))
1586 if (HAS_ANYFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1588 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1589 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1590 InflateRect( &rect, -1, -1 );
1593 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1594 NC_DrawFrame(hdc, &rect, FALSE, active );
1595 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1596 NC_DrawFrame( hdc, &rect, TRUE, active );
1598 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1600 RECT r = rect;
1601 r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
1602 rect.top += GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYBORDER);
1603 NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active );
1607 if (HAS_MENU(wndPtr))
1609 RECT r = rect;
1610 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU); /* default height */
1611 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint );
1614 /* Draw the scroll-bars */
1616 if (wndPtr->dwStyle & WS_VSCROLL)
1617 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1618 if (wndPtr->dwStyle & WS_HSCROLL)
1619 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1621 /* Draw the "size-box" */
1623 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1625 RECT r = rect;
1626 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1627 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1628 if(wndPtr->dwStyle & WS_BORDER) {
1629 r.left++;
1630 r.top++;
1632 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1635 ReleaseDC( hwnd, hdc );
1639 /******************************************************************************
1641 * void NC_DoNCPaint95(
1642 * WND *wndPtr,
1643 * HRGN32 clip,
1644 * BOOL32 suppress_menupaint )
1646 * Paint the non-client area for Win95 windows. The clip region is
1647 * currently ignored.
1649 * Bugs
1650 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1651 * misc/tweak.c controls/menu.c # :-)
1653 * Revision history
1654 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1655 * Original implementation
1656 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1657 * Fixed some bugs.
1658 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1659 * Streamlined window style checks.
1661 *****************************************************************************/
1663 static void NC_DoNCPaint95(
1664 WND *wndPtr,
1665 HRGN clip,
1666 BOOL suppress_menupaint )
1668 HDC hdc;
1669 RECT rfuzz, rect, rectClip;
1670 BOOL active;
1671 HWND hwnd = wndPtr->hwndSelf;
1673 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1674 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1676 active = wndPtr->flags & WIN_NCACTIVATED;
1678 TRACE_(nonclient)("%04x %d\n", hwnd, active );
1680 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in the call to
1681 * GetDCEx implying that it is allowed not to use it either. However, the suggested
1682 * GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN) will cause clipRgn to be deleted
1683 * after ReleaseDC(). Now, how is the "system" supposed to tell what happened?
1686 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1687 ((clip > 1) ?(DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0) ))) return;
1690 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1691 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1692 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1693 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1694 == NULLREGION)
1696 ReleaseDC( hwnd, hdc );
1697 return;
1700 rect.top = rect.left = 0;
1701 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1702 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1704 if( clip > 1 )
1705 GetRgnBox( clip, &rectClip );
1706 else
1708 clip = 0;
1709 rectClip = rect;
1712 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1714 if(!(wndPtr->flags & WIN_MANAGED)) {
1715 if (HAS_BIGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle)) {
1716 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1718 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1719 NC_DrawFrame95(hdc, &rect, FALSE, active );
1720 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1721 NC_DrawFrame95( hdc, &rect, TRUE, active );
1722 else if (HAS_THINFRAME( wndPtr->dwStyle )) {
1723 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1724 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1727 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1729 RECT r = rect;
1730 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW) {
1731 r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
1732 rect.top += GetSystemMetrics(SM_CYSMCAPTION);
1734 else {
1735 r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
1736 rect.top += GetSystemMetrics(SM_CYCAPTION);
1738 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
1739 NC_DrawCaption95 (hdc, &r, hwnd, wndPtr->dwStyle,
1740 wndPtr->dwExStyle, active);
1744 if (HAS_MENU(wndPtr))
1746 RECT r = rect;
1747 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
1749 TRACE_(nonclient)("Calling DrawMenuBar with "
1750 "rect (%d, %d)-(%d, %d)\n", r.left, r.top,
1751 r.right, r.bottom);
1753 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ) + 1;
1756 TRACE_(nonclient)("After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1757 rect.left, rect.top, rect.right, rect.bottom );
1759 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
1760 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1762 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
1763 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1765 /* Draw the scroll-bars */
1767 if (wndPtr->dwStyle & WS_VSCROLL)
1768 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1769 if (wndPtr->dwStyle & WS_HSCROLL)
1770 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1772 /* Draw the "size-box" */
1773 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1775 RECT r = rect;
1776 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1777 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1778 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1781 ReleaseDC( hwnd, hdc );
1787 /***********************************************************************
1788 * NC_HandleNCPaint
1790 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1792 LONG NC_HandleNCPaint( HWND hwnd , HRGN clip)
1794 WND* wndPtr = WIN_FindWndPtr( hwnd );
1796 if( wndPtr && wndPtr->dwStyle & WS_VISIBLE )
1798 if( wndPtr->dwStyle & WS_MINIMIZE )
1799 WINPOS_RedrawIconTitle( hwnd );
1800 else if (TWEAK_WineLook == WIN31_LOOK)
1801 NC_DoNCPaint( wndPtr, clip, FALSE );
1802 else
1803 NC_DoNCPaint95( wndPtr, clip, FALSE );
1805 WIN_ReleaseWndPtr(wndPtr);
1806 return 0;
1810 /***********************************************************************
1811 * NC_HandleNCActivate
1813 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1815 LONG NC_HandleNCActivate( WND *wndPtr, WPARAM16 wParam )
1817 WORD wStateChange;
1819 if( wParam ) wStateChange = !(wndPtr->flags & WIN_NCACTIVATED);
1820 else wStateChange = wndPtr->flags & WIN_NCACTIVATED;
1822 if( wStateChange )
1824 if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
1825 else wndPtr->flags &= ~WIN_NCACTIVATED;
1827 if( wndPtr->dwStyle & WS_MINIMIZE )
1828 WINPOS_RedrawIconTitle( wndPtr->hwndSelf );
1829 else if (TWEAK_WineLook == WIN31_LOOK)
1830 NC_DoNCPaint( wndPtr, (HRGN)1, FALSE );
1831 else
1832 NC_DoNCPaint95( wndPtr, (HRGN)1, FALSE );
1834 return TRUE;
1838 /***********************************************************************
1839 * NC_HandleSetCursor
1841 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1843 LONG NC_HandleSetCursor( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
1845 if (hwnd != (HWND)wParam) return 0; /* Don't set the cursor for child windows */
1847 switch(LOWORD(lParam))
1849 case HTERROR:
1851 WORD msg = HIWORD( lParam );
1852 if ((msg == WM_LBUTTONDOWN) || (msg == WM_MBUTTONDOWN) ||
1853 (msg == WM_RBUTTONDOWN))
1854 MessageBeep(0);
1856 break;
1858 case HTCLIENT:
1860 HICON16 hCursor = (HICON16) GetClassWord(hwnd, GCW_HCURSOR);
1861 if(hCursor) {
1862 SetCursor16(hCursor);
1863 return TRUE;
1865 return FALSE;
1868 case HTLEFT:
1869 case HTRIGHT:
1870 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZEWE16 ) );
1872 case HTTOP:
1873 case HTBOTTOM:
1874 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENS16 ) );
1876 case HTTOPLEFT:
1877 case HTBOTTOMRIGHT:
1878 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENWSE16 ) );
1880 case HTTOPRIGHT:
1881 case HTBOTTOMLEFT:
1882 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENESW16 ) );
1885 /* Default cursor: arrow */
1886 return (LONG)SetCursor16( LoadCursor16( 0, IDC_ARROW16 ) );
1889 /***********************************************************************
1890 * NC_GetSysPopupPos
1892 BOOL NC_GetSysPopupPos( WND* wndPtr, RECT* rect )
1894 if( wndPtr->hSysMenu )
1896 if( wndPtr->dwStyle & WS_MINIMIZE )
1897 GetWindowRect( wndPtr->hwndSelf, rect );
1898 else
1900 if (TWEAK_WineLook == WIN31_LOOK)
1901 NC_GetInsideRect( wndPtr->hwndSelf, rect );
1902 else
1903 NC_GetInsideRect95( wndPtr->hwndSelf, rect );
1904 OffsetRect( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
1905 if (wndPtr->dwStyle & WS_CHILD)
1906 ClientToScreen( wndPtr->parent->hwndSelf, (POINT *)rect );
1907 if (TWEAK_WineLook == WIN31_LOOK) {
1908 rect->right = rect->left + GetSystemMetrics(SM_CXSIZE);
1909 rect->bottom = rect->top + GetSystemMetrics(SM_CYSIZE);
1911 else {
1912 rect->right = rect->left + GetSystemMetrics(SM_CYCAPTION) - 1;
1913 rect->bottom = rect->top + GetSystemMetrics(SM_CYCAPTION) - 1;
1916 return TRUE;
1918 return FALSE;
1921 /***********************************************************************
1922 * NC_StartSizeMove
1924 * Initialisation of a move or resize, when initiatied from a menu choice.
1925 * Return hit test code for caption or sizing border.
1927 static LONG NC_StartSizeMove( WND* wndPtr, WPARAM16 wParam,
1928 POINT16 *capturePoint )
1930 LONG hittest = 0;
1931 POINT16 pt;
1932 MSG msg;
1933 RECT rectWindow;
1935 GetWindowRect(wndPtr->hwndSelf,&rectWindow);
1937 if ((wParam & 0xfff0) == SC_MOVE)
1939 /* Move pointer at the center of the caption */
1940 RECT rect;
1941 if (TWEAK_WineLook == WIN31_LOOK)
1942 NC_GetInsideRect( wndPtr->hwndSelf, &rect );
1943 else
1944 NC_GetInsideRect95( wndPtr->hwndSelf, &rect );
1945 if (wndPtr->dwStyle & WS_SYSMENU)
1946 rect.left += GetSystemMetrics(SM_CXSIZE) + 1;
1947 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
1948 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1949 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
1950 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1951 pt.x = rectWindow.left + (rect.right - rect.left) / 2;
1952 pt.y = rectWindow.top + rect.top + GetSystemMetrics(SM_CYSIZE)/2;
1953 hittest = HTCAPTION;
1954 *capturePoint = pt;
1956 else /* SC_SIZE */
1958 while(!hittest)
1960 MSG_InternalGetMessage( &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE );
1961 switch(msg.message)
1963 case WM_MOUSEMOVE:
1964 CONV_POINT32TO16(&msg.pt, &pt);
1965 hittest = NC_HandleNCHitTest( wndPtr->hwndSelf, pt );
1966 if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
1967 hittest = 0;
1968 break;
1970 case WM_LBUTTONUP:
1971 return 0;
1973 case WM_KEYDOWN:
1974 switch(msg.wParam)
1976 case VK_UP:
1977 hittest = HTTOP;
1978 pt.x =(rectWindow.left+rectWindow.right)/2;
1979 pt.y = rectWindow.top + GetSystemMetrics(SM_CYFRAME) / 2;
1980 break;
1981 case VK_DOWN:
1982 hittest = HTBOTTOM;
1983 pt.x =(rectWindow.left+rectWindow.right)/2;
1984 pt.y = rectWindow.bottom - GetSystemMetrics(SM_CYFRAME) / 2;
1985 break;
1986 case VK_LEFT:
1987 hittest = HTLEFT;
1988 pt.x = rectWindow.left + GetSystemMetrics(SM_CXFRAME) / 2;
1989 pt.y =(rectWindow.top+rectWindow.bottom)/2;
1990 break;
1991 case VK_RIGHT:
1992 hittest = HTRIGHT;
1993 pt.x = rectWindow.right - GetSystemMetrics(SM_CXFRAME) / 2;
1994 pt.y =(rectWindow.top+rectWindow.bottom)/2;
1995 break;
1996 case VK_RETURN:
1997 case VK_ESCAPE: return 0;
2001 *capturePoint = pt;
2003 SetCursorPos( pt.x, pt.y );
2004 NC_HandleSetCursor( wndPtr->hwndSelf,
2005 wndPtr->hwndSelf, MAKELONG( hittest, WM_MOUSEMOVE ));
2006 return hittest;
2010 /***********************************************************************
2011 * NC_DoSizeMove
2013 * Perform SC_MOVE and SC_SIZE commands. `
2015 static void NC_DoSizeMove( HWND hwnd, WORD wParam )
2017 MSG msg;
2018 RECT sizingRect, mouseRect;
2019 HDC hdc;
2020 LONG hittest = (LONG)(wParam & 0x0f);
2021 HCURSOR16 hDragCursor = 0, hOldCursor = 0;
2022 POINT minTrack, maxTrack;
2023 POINT16 capturePoint, pt;
2024 WND * wndPtr = WIN_FindWndPtr( hwnd );
2025 BOOL thickframe = HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle );
2026 BOOL iconic = wndPtr->dwStyle & WS_MINIMIZE;
2027 BOOL moved = FALSE;
2028 DWORD dwPoint = GetMessagePos ();
2030 capturePoint = pt = *(POINT16*)&dwPoint;
2032 if (IsZoomed(hwnd) || !IsWindowVisible(hwnd) ||
2033 (wndPtr->flags & WIN_MANAGED)) goto END;
2035 if ((wParam & 0xfff0) == SC_MOVE)
2037 if (!(wndPtr->dwStyle & WS_CAPTION)) goto END;
2038 if (!hittest)
2039 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2040 if (!hittest) goto END;
2042 else /* SC_SIZE */
2044 if (!thickframe) goto END;
2045 if ( hittest && hittest != HTSYSMENU ) hittest += 2;
2046 else
2048 SetCapture(hwnd);
2049 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2050 if (!hittest)
2052 ReleaseCapture();
2053 goto END;
2058 /* Get min/max info */
2060 WINPOS_GetMinMaxInfo( wndPtr, NULL, NULL, &minTrack, &maxTrack );
2061 sizingRect = wndPtr->rectWindow;
2062 if (wndPtr->dwStyle & WS_CHILD)
2063 GetClientRect( wndPtr->parent->hwndSelf, &mouseRect );
2064 else
2065 SetRect(&mouseRect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
2066 if (ON_LEFT_BORDER(hittest))
2068 mouseRect.left = MAX( mouseRect.left, sizingRect.right-maxTrack.x );
2069 mouseRect.right = MIN( mouseRect.right, sizingRect.right-minTrack.x );
2071 else if (ON_RIGHT_BORDER(hittest))
2073 mouseRect.left = MAX( mouseRect.left, sizingRect.left+minTrack.x );
2074 mouseRect.right = MIN( mouseRect.right, sizingRect.left+maxTrack.x );
2076 if (ON_TOP_BORDER(hittest))
2078 mouseRect.top = MAX( mouseRect.top, sizingRect.bottom-maxTrack.y );
2079 mouseRect.bottom = MIN( mouseRect.bottom,sizingRect.bottom-minTrack.y);
2081 else if (ON_BOTTOM_BORDER(hittest))
2083 mouseRect.top = MAX( mouseRect.top, sizingRect.top+minTrack.y );
2084 mouseRect.bottom = MIN( mouseRect.bottom, sizingRect.top+maxTrack.y );
2086 if (wndPtr->dwStyle & WS_CHILD)
2088 MapWindowPoints( wndPtr->parent->hwndSelf, 0,
2089 (LPPOINT)&mouseRect, 2 );
2091 SendMessage16( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
2093 if (GetCapture() != hwnd) SetCapture( hwnd );
2095 if (wndPtr->dwStyle & WS_CHILD)
2097 /* Retrieve a default cache DC (without using the window style) */
2098 hdc = GetDCEx( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
2100 else
2101 { /* Grab the server only when moving top-level windows without desktop */
2102 hdc = GetDC( 0 );
2105 wndPtr->pDriver->pPreSizeMove(wndPtr);
2107 if( iconic ) /* create a cursor for dragging */
2109 HICON16 hIcon = GetClassWord(wndPtr->hwndSelf, GCW_HICON);
2110 if(!hIcon) hIcon = (HICON16) SendMessage16( hwnd, WM_QUERYDRAGICON, 0, 0L);
2111 if( hIcon ) hDragCursor = CURSORICON_IconToCursor( hIcon, TRUE );
2112 if( !hDragCursor ) iconic = FALSE;
2115 if( !iconic ) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2117 while(1)
2119 int dx = 0, dy = 0;
2121 MSG_InternalGetMessage( &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE );
2123 /* Exit on button-up, Return, or Esc */
2124 if ((msg.message == WM_LBUTTONUP) ||
2125 ((msg.message == WM_KEYDOWN) &&
2126 ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
2128 if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
2129 continue; /* We are not interested in other messages */
2131 dwPoint = GetMessagePos ();
2132 pt = *(POINT16*)&dwPoint;
2134 if (msg.message == WM_KEYDOWN) switch(msg.wParam)
2136 case VK_UP: pt.y -= 8; break;
2137 case VK_DOWN: pt.y += 8; break;
2138 case VK_LEFT: pt.x -= 8; break;
2139 case VK_RIGHT: pt.x += 8; break;
2142 pt.x = MAX( pt.x, mouseRect.left );
2143 pt.x = MIN( pt.x, mouseRect.right );
2144 pt.y = MAX( pt.y, mouseRect.top );
2145 pt.y = MIN( pt.y, mouseRect.bottom );
2147 dx = pt.x - capturePoint.x;
2148 dy = pt.y - capturePoint.y;
2150 if (dx || dy)
2152 if( !moved )
2154 moved = TRUE;
2155 if( iconic ) /* ok, no system popup tracking */
2157 hOldCursor = SetCursor(hDragCursor);
2158 ShowCursor( TRUE );
2159 WINPOS_ShowIconTitle( wndPtr, FALSE );
2163 if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
2164 else
2166 RECT newRect = sizingRect;
2168 if (hittest == HTCAPTION) OffsetRect( &newRect, dx, dy );
2169 if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
2170 else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
2171 if (ON_TOP_BORDER(hittest)) newRect.top += dy;
2172 else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
2173 if( !iconic )
2175 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2176 NC_DrawMovingFrame( hdc, &newRect, thickframe );
2178 capturePoint = pt;
2179 sizingRect = newRect;
2184 ReleaseCapture();
2185 if( iconic )
2187 if( moved ) /* restore cursors, show icon title later on */
2189 ShowCursor( FALSE );
2190 SetCursor( hOldCursor );
2192 DestroyCursor( hDragCursor );
2194 else
2195 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2197 if (wndPtr->dwStyle & WS_CHILD)
2198 ReleaseDC( wndPtr->parent->hwndSelf, hdc );
2199 else
2201 ReleaseDC( 0, hdc );
2204 wndPtr->pDriver->pPostSizeMove(wndPtr);
2206 if (HOOK_IsHooked( WH_CBT ))
2208 RECT16* pr = SEGPTR_NEW(RECT16);
2209 if( pr )
2211 CONV_RECT32TO16( &sizingRect, pr );
2212 if( HOOK_CallHooks16( WH_CBT, HCBT_MOVESIZE, hwnd,
2213 (LPARAM)SEGPTR_GET(pr)) )
2214 sizingRect = wndPtr->rectWindow;
2215 else
2216 CONV_RECT16TO32( pr, &sizingRect );
2217 SEGPTR_FREE(pr);
2220 SendMessage16( hwnd, WM_EXITSIZEMOVE, 0, 0 );
2221 SendMessage16( hwnd, WM_SETVISIBLE, !IsIconic16(hwnd), 0L);
2223 /* window moved or resized */
2224 if (moved)
2226 /* if the moving/resizing isn't canceled call SetWindowPos
2227 * with the new position or the new size of the window
2229 if (!((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
2231 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
2232 SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top,
2233 sizingRect.right - sizingRect.left,
2234 sizingRect.bottom - sizingRect.top,
2235 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
2237 else
2239 /* if the moving/resizing is canceled and the window is not active
2240 * call SetWindowPos to activate and to show this window
2242 if (GetActiveWindow() != hwnd)
2243 SetWindowPos( hwnd, 0, 0, 0,0,0,SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
2246 else
2248 /* show the window if it is not moved/resized and it is not active */
2249 if (GetActiveWindow() != hwnd)
2250 SetWindowPos( hwnd, 0, 0, 0,0,0,SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
2253 if( IsWindow(hwnd) )
2254 if( wndPtr->dwStyle & WS_MINIMIZE )
2256 /* Single click brings up the system menu when iconized */
2258 if( !moved )
2260 if( wndPtr->dwStyle & WS_SYSMENU )
2261 SendMessage16( hwnd, WM_SYSCOMMAND,
2262 SC_MOUSEMENU + HTSYSMENU, *((LPARAM*)&pt));
2264 else WINPOS_ShowIconTitle( wndPtr, TRUE );
2267 END:
2268 WIN_ReleaseWndPtr(wndPtr);
2272 /***********************************************************************
2273 * NC_TrackMinMaxBox
2275 * Track a mouse button press on the minimize or maximize box.
2277 static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
2279 MSG msg;
2280 POINT16 pt16;
2281 HDC hdc = GetWindowDC( hwnd );
2282 BOOL pressed = TRUE;
2283 void (*paintButton)(HWND, HDC16, BOOL);
2285 SetCapture( hwnd );
2286 if (wParam == HTMINBUTTON)
2287 paintButton =
2288 (TWEAK_WineLook == WIN31_LOOK) ? &NC_DrawMinButton : &NC_DrawMinButton95;
2289 else
2290 paintButton =
2291 (TWEAK_WineLook == WIN31_LOOK) ? &NC_DrawMaxButton : &NC_DrawMaxButton95;
2293 (*paintButton)( hwnd, hdc, TRUE );
2297 BOOL oldstate = pressed;
2298 MSG_InternalGetMessage( &msg, 0, 0, 0, PM_REMOVE, FALSE );
2299 CONV_POINT32TO16( &msg.pt, &pt16 );
2301 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2302 if (pressed != oldstate)
2303 (*paintButton)( hwnd, hdc, pressed );
2304 } while (msg.message != WM_LBUTTONUP);
2306 (*paintButton)( hwnd, hdc, FALSE );
2308 ReleaseCapture();
2309 ReleaseDC( hwnd, hdc );
2310 if (!pressed) return;
2312 if (wParam == HTMINBUTTON)
2313 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&pt16 );
2314 else
2315 SendMessage16( hwnd, WM_SYSCOMMAND,
2316 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, *(LONG*)&pt16 );
2320 /***********************************************************************
2321 * NC_TrackCloseButton95
2323 * Track a mouse button press on the Win95 close button.
2325 static void
2326 NC_TrackCloseButton95 (HWND hwnd, WORD wParam)
2328 MSG msg;
2329 POINT16 pt16;
2330 HDC hdc = GetWindowDC( hwnd );
2331 BOOL pressed = TRUE;
2333 SetCapture( hwnd );
2335 NC_DrawCloseButton95 (hwnd, hdc, TRUE);
2339 BOOL oldstate = pressed;
2340 MSG_InternalGetMessage( &msg, 0, 0, 0, PM_REMOVE, FALSE );
2341 CONV_POINT32TO16( &msg.pt, &pt16 );
2343 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2344 if (pressed != oldstate)
2345 NC_DrawCloseButton95 (hwnd, hdc, pressed);
2346 } while (msg.message != WM_LBUTTONUP);
2348 NC_DrawCloseButton95 (hwnd, hdc, FALSE);
2350 ReleaseCapture();
2351 ReleaseDC( hwnd, hdc );
2352 if (!pressed) return;
2354 SendMessage16( hwnd, WM_SYSCOMMAND, SC_CLOSE, *(LONG*)&pt16 );
2358 /***********************************************************************
2359 * NC_TrackScrollBar
2361 * Track a mouse button press on the horizontal or vertical scroll-bar.
2363 static void NC_TrackScrollBar( HWND hwnd, WPARAM wParam, POINT pt )
2365 MSG16 *msg;
2366 INT scrollbar;
2367 WND *wndPtr = WIN_FindWndPtr( hwnd );
2369 if ((wParam & 0xfff0) == SC_HSCROLL)
2371 if ((wParam & 0x0f) != HTHSCROLL) goto END;
2372 scrollbar = SB_HORZ;
2374 else /* SC_VSCROLL */
2376 if ((wParam & 0x0f) != HTVSCROLL) goto END;
2377 scrollbar = SB_VERT;
2380 if (!(msg = SEGPTR_NEW(MSG16))) goto END;
2381 pt.x -= wndPtr->rectWindow.left;
2382 pt.y -= wndPtr->rectWindow.top;
2383 SetCapture( hwnd );
2384 SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt );
2388 GetMessage16( SEGPTR_GET(msg), 0, 0, 0 );
2389 switch(msg->message)
2391 case WM_LBUTTONUP:
2392 case WM_MOUSEMOVE:
2393 case WM_SYSTIMER:
2394 pt.x = LOWORD(msg->lParam) + wndPtr->rectClient.left -
2395 wndPtr->rectWindow.left;
2396 pt.y = HIWORD(msg->lParam) + wndPtr->rectClient.top -
2397 wndPtr->rectWindow.top;
2398 SCROLL_HandleScrollEvent( hwnd, scrollbar, msg->message, pt );
2399 break;
2400 default:
2401 TranslateMessage16( msg );
2402 DispatchMessage16( msg );
2403 break;
2405 if (!IsWindow( hwnd ))
2407 ReleaseCapture();
2408 break;
2410 } while (msg->message != WM_LBUTTONUP);
2411 SEGPTR_FREE(msg);
2412 END:
2413 WIN_ReleaseWndPtr(wndPtr);
2416 /***********************************************************************
2417 * NC_HandleNCLButtonDown
2419 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2421 LONG NC_HandleNCLButtonDown( WND* pWnd, WPARAM16 wParam, LPARAM lParam )
2423 HWND hwnd = pWnd->hwndSelf;
2425 switch(wParam) /* Hit test */
2427 case HTCAPTION:
2428 hwnd = WIN_GetTopParent(hwnd);
2430 if( WINPOS_SetActiveWindow(hwnd, TRUE, TRUE) || (GetActiveWindow() == hwnd) )
2431 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
2432 break;
2434 case HTSYSMENU:
2435 if( pWnd->dwStyle & WS_SYSMENU )
2437 if( !(pWnd->dwStyle & WS_MINIMIZE) )
2439 HDC hDC = GetWindowDC(hwnd);
2440 if (TWEAK_WineLook == WIN31_LOOK)
2441 NC_DrawSysButton( hwnd, hDC, TRUE );
2442 else
2443 NC_DrawSysButton95( hwnd, hDC, TRUE );
2444 ReleaseDC( hwnd, hDC );
2446 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
2448 break;
2450 case HTMENU:
2451 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam );
2452 break;
2454 case HTHSCROLL:
2455 SendMessage16( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
2456 break;
2458 case HTVSCROLL:
2459 SendMessage16( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
2460 break;
2462 case HTMINBUTTON:
2463 case HTMAXBUTTON:
2464 NC_TrackMinMaxBox( hwnd, wParam );
2465 break;
2467 case HTCLOSE:
2468 if (TWEAK_WineLook >= WIN95_LOOK)
2469 NC_TrackCloseButton95 (hwnd, wParam);
2470 break;
2472 case HTLEFT:
2473 case HTRIGHT:
2474 case HTTOP:
2475 case HTTOPLEFT:
2476 case HTTOPRIGHT:
2477 case HTBOTTOM:
2478 case HTBOTTOMLEFT:
2479 case HTBOTTOMRIGHT:
2480 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2481 SendMessage16( hwnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam);
2482 break;
2484 case HTBORDER:
2485 break;
2487 return 0;
2491 /***********************************************************************
2492 * NC_HandleNCLButtonDblClk
2494 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2496 LONG NC_HandleNCLButtonDblClk( WND *pWnd, WPARAM16 wParam, LPARAM lParam )
2499 * if this is an icon, send a restore since we are handling
2500 * a double click
2502 if (pWnd->dwStyle & WS_MINIMIZE)
2504 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_RESTORE, lParam );
2505 return 0;
2508 switch(wParam) /* Hit test */
2510 case HTCAPTION:
2511 /* stop processing if WS_MAXIMIZEBOX is missing */
2512 if (pWnd->dwStyle & WS_MAXIMIZEBOX)
2513 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND,
2514 (pWnd->dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
2515 lParam );
2516 break;
2518 case HTSYSMENU:
2519 if (!(GetClassWord(pWnd->hwndSelf, GCW_STYLE) & CS_NOCLOSE))
2520 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, lParam );
2521 break;
2523 case HTHSCROLL:
2524 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL,
2525 lParam );
2526 break;
2528 case HTVSCROLL:
2529 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL,
2530 lParam );
2531 break;
2533 return 0;
2537 /***********************************************************************
2538 * NC_HandleSysCommand
2540 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2542 LONG NC_HandleSysCommand( HWND hwnd, WPARAM16 wParam, POINT16 pt )
2544 WND *wndPtr = WIN_FindWndPtr( hwnd );
2545 POINT pt32;
2546 UINT16 uCommand = wParam & 0xFFF0;
2548 TRACE_(nonclient)("Handling WM_SYSCOMMAND %x %d,%d\n",
2549 wParam, pt.x, pt.y );
2551 if (wndPtr->dwStyle & WS_CHILD && uCommand != SC_KEYMENU )
2552 ScreenToClient16( wndPtr->parent->hwndSelf, &pt );
2554 switch (uCommand)
2556 case SC_SIZE:
2557 case SC_MOVE:
2558 NC_DoSizeMove( hwnd, wParam );
2559 break;
2561 case SC_MINIMIZE:
2562 ShowWindow( hwnd, SW_MINIMIZE );
2563 break;
2565 case SC_MAXIMIZE:
2566 ShowWindow( hwnd, SW_MAXIMIZE );
2567 break;
2569 case SC_RESTORE:
2570 ShowWindow( hwnd, SW_RESTORE );
2571 break;
2573 case SC_CLOSE:
2574 WIN_ReleaseWndPtr(wndPtr);
2575 return SendMessage16( hwnd, WM_CLOSE, 0, 0 );
2577 case SC_VSCROLL:
2578 case SC_HSCROLL:
2579 CONV_POINT16TO32( &pt, &pt32 );
2580 NC_TrackScrollBar( hwnd, wParam, pt32 );
2581 break;
2583 case SC_MOUSEMENU:
2584 CONV_POINT16TO32( &pt, &pt32 );
2585 MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt32 );
2586 break;
2588 case SC_KEYMENU:
2589 MENU_TrackKbdMenuBar( wndPtr , wParam , pt.x );
2590 break;
2592 case SC_TASKLIST:
2593 WinExec( "taskman.exe", SW_SHOWNORMAL );
2594 break;
2596 case SC_SCREENSAVE:
2597 if (wParam == SC_ABOUTWINE)
2598 ShellAboutA(hwnd,"Wine", WINE_RELEASE_INFO, 0);
2599 else
2600 if (wParam == SC_PUTMARK)
2601 TRACE_(shell)("Mark requested by user\n");
2602 break;
2604 case SC_HOTKEY:
2605 case SC_ARRANGE:
2606 case SC_NEXTWINDOW:
2607 case SC_PREVWINDOW:
2608 FIXME_(nonclient)("unimplemented!\n");
2609 break;
2611 WIN_ReleaseWndPtr(wndPtr);
2612 return 0;