Added change notifications.
[wine.git] / windows / nonclient.c
blob2f55fe5c9d243cd49f8d470f3be63ade4252711f
1 /*
2 * Non-client area window functions
4 * Copyright 1994 Alexandre Julliard
6 */
8 #include "version.h"
9 #include "win.h"
10 #include "message.h"
11 #include "sysmetrics.h"
12 #include "user.h"
13 #include "heap.h"
14 #include "cursoricon.h"
15 #include "dialog.h"
16 #include "menu.h"
17 #include "winpos.h"
18 #include "hook.h"
19 #include "scroll.h"
20 #include "nonclient.h"
21 #include "queue.h"
22 #include "selectors.h"
23 #include "tweak.h"
24 #include "debug.h"
25 #include "options.h"
26 #include "cache.h"
28 static HBITMAP16 hbitmapClose = 0;
29 static HBITMAP16 hbitmapCloseD = 0;
30 static HBITMAP16 hbitmapMinimize = 0;
31 static HBITMAP16 hbitmapMinimizeD = 0;
32 static HBITMAP16 hbitmapMaximize = 0;
33 static HBITMAP16 hbitmapMaximizeD = 0;
34 static HBITMAP16 hbitmapRestore = 0;
35 static HBITMAP16 hbitmapRestoreD = 0;
37 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
38 #define SC_PUTMARK (SC_SCREENSAVE+2)
40 /* Some useful macros */
41 #define HAS_DLGFRAME(style,exStyle) \
42 (((exStyle) & WS_EX_DLGMODALFRAME) || \
43 (((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
45 #define HAS_THICKFRAME(style) \
46 (((style) & WS_THICKFRAME) && \
47 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
49 #define HAS_FIXEDFRAME(style,exStyle) \
50 (((((exStyle) & WS_EX_DLGMODALFRAME) || \
51 ((style) & WS_DLGFRAME)) && ((style) & WS_BORDER)) && \
52 !((style) & WS_THICKFRAME))
54 #define HAS_SIZEFRAME(style) \
55 (((style) & WS_THICKFRAME) && \
56 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
58 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
60 #define ON_LEFT_BORDER(hit) \
61 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
62 #define ON_RIGHT_BORDER(hit) \
63 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
64 #define ON_TOP_BORDER(hit) \
65 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
66 #define ON_BOTTOM_BORDER(hit) \
67 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
69 /***********************************************************************
70 * NC_AdjustRect
72 * Compute the size of the window rectangle from the size of the
73 * client rectangle.
75 static void NC_AdjustRect( LPRECT16 rect, DWORD style, BOOL32 menu,
76 DWORD exStyle )
78 if (TWEAK_WineLook > WIN31_LOOK)
79 ERR(nonclient, "Called in Win95 mode. Aiee! Please report this.\n" );
81 if(style & WS_ICONIC) return;
82 /* Decide if the window will be managed (see CreateWindowEx) */
83 if (!(Options.managed && !(style & WS_CHILD) &&
84 ((style & (WS_DLGFRAME | WS_THICKFRAME)) ||
85 (exStyle & WS_EX_DLGMODALFRAME))))
87 if (HAS_DLGFRAME( style, exStyle ))
88 InflateRect16(rect, SYSMETRICS_CXDLGFRAME, SYSMETRICS_CYDLGFRAME );
89 else
91 if (HAS_THICKFRAME(style))
92 InflateRect16( rect, SYSMETRICS_CXFRAME, SYSMETRICS_CYFRAME );
93 if (style & WS_BORDER)
94 InflateRect16( rect, SYSMETRICS_CXBORDER, SYSMETRICS_CYBORDER);
97 if ((style & WS_CAPTION) == WS_CAPTION)
98 rect->top -= SYSMETRICS_CYCAPTION - SYSMETRICS_CYBORDER;
100 if (menu) rect->top -= SYSMETRICS_CYMENU + SYSMETRICS_CYBORDER;
102 if (style & WS_VSCROLL) {
103 rect->right += SYSMETRICS_CXVSCROLL - 1;
104 if(!(style & WS_BORDER))
105 rect->right++;
108 if (style & WS_HSCROLL) {
109 rect->bottom += SYSMETRICS_CYHSCROLL - 1;
110 if(!(style & WS_BORDER))
111 rect->bottom++;
116 /******************************************************************************
117 * NC_AdjustRectOuter95
119 * Computes the size of the "outside" parts of the window based on the
120 * parameters of the client area.
122 + PARAMS
123 * LPRECT16 rect
124 * DWORD style
125 * BOOL32 menu
126 * DWORD exStyle
128 * NOTES
129 * "Outer" parts of a window means the whole window frame, caption and
130 * menu bar. It does not include "inner" parts of the frame like client
131 * edge, static edge or scroll bars.
133 * Revision history
134 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
135 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
137 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
138 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
139 * NC_AdjustRectInner95 and added handling of Win95 styles.
141 *****************************************************************************/
143 static void
144 NC_AdjustRectOuter95 (LPRECT16 rect, DWORD style, BOOL32 menu, DWORD exStyle)
146 if(style & WS_ICONIC) return;
148 /* Decide if the window will be managed (see CreateWindowEx) */
149 if (!(Options.managed && !(style & WS_CHILD) &&
150 ((style & (WS_DLGFRAME | WS_THICKFRAME)) ||
151 (exStyle & WS_EX_DLGMODALFRAME))))
153 if (HAS_FIXEDFRAME( style, exStyle ))
154 InflateRect16(rect, SYSMETRICS_CXDLGFRAME, SYSMETRICS_CYDLGFRAME );
155 else
157 if (HAS_SIZEFRAME(style))
158 InflateRect16( rect, SYSMETRICS_CXFRAME, SYSMETRICS_CYFRAME );
159 #if 0
160 if (style & WS_BORDER)
161 InflateRect16( rect, SYSMETRICS_CXBORDER, SYSMETRICS_CYBORDER);
162 #endif
165 if ((style & WS_CAPTION) == WS_CAPTION)
167 if (exStyle & WS_EX_TOOLWINDOW)
168 rect->top -= SYSMETRICS_CYSMCAPTION;
169 else
170 rect->top -= SYSMETRICS_CYCAPTION;
174 if (menu)
175 rect->top -= sysMetrics[SM_CYMENU];
179 /******************************************************************************
180 * NC_AdjustRectInner95
182 * Computes the size of the "inside" part of the window based on the
183 * parameters of the client area.
185 + PARAMS
186 * LPRECT16 rect
187 * DWORD style
188 * DWORD exStyle
190 * NOTES
191 * "Inner" part of a window means the window frame inside of the flat
192 * window frame. It includes the client edge, the static edge and the
193 * scroll bars.
195 * Revision history
196 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
197 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
199 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
200 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
201 * NC_AdjustRectInner95 and added handling of Win95 styles.
203 *****************************************************************************/
205 static void
206 NC_AdjustRectInner95 (LPRECT16 rect, DWORD style, DWORD exStyle)
208 if(style & WS_ICONIC) return;
210 if (exStyle & WS_EX_CLIENTEDGE)
211 InflateRect16 (rect, sysMetrics[SM_CXEDGE], sysMetrics[SM_CYEDGE]);
213 if (exStyle & WS_EX_STATICEDGE)
214 InflateRect16 (rect, sysMetrics[SM_CXBORDER], sysMetrics[SM_CYBORDER]);
216 if (style & WS_VSCROLL) rect->right += SYSMETRICS_CXVSCROLL;
217 if (style & WS_HSCROLL) rect->bottom += SYSMETRICS_CYHSCROLL;
221 /***********************************************************************
222 * DrawCaption16 [USER.660] Draws a caption bar
224 * PARAMS
225 * hwnd [I]
226 * hdc [I]
227 * lpRect [I]
228 * uFlags [I]
230 * RETURNS
231 * Success:
232 * Failure:
235 BOOL16 WINAPI
236 DrawCaption16 (HWND16 hwnd, HDC16 hdc, const RECT16 *rect, UINT16 uFlags)
238 RECT32 rect32;
240 if (rect)
241 CONV_RECT16TO32 (rect, &rect32);
243 return (BOOL16)DrawCaptionTemp32A (hwnd, hdc, rect ? &rect32 : NULL,
244 0, 0, NULL, uFlags & 0x1F);
248 /***********************************************************************
249 * DrawCaption32 [USER32.154] Draws a caption bar
251 * PARAMS
252 * hwnd [I]
253 * hdc [I]
254 * lpRect [I]
255 * uFlags [I]
257 * RETURNS
258 * Success:
259 * Failure:
262 BOOL32 WINAPI
263 DrawCaption32 (HWND32 hwnd, HDC32 hdc, const RECT32 *lpRect, UINT32 uFlags)
265 return DrawCaptionTemp32A (hwnd, hdc, lpRect, 0, 0, NULL, uFlags & 0x1F);
269 /***********************************************************************
270 * DrawCaptionTemp16 [USER.657]
272 * PARAMS
274 * RETURNS
275 * Success:
276 * Failure:
279 BOOL16 WINAPI
280 DrawCaptionTemp16 (HWND16 hwnd, HDC16 hdc, const RECT16 *rect, HFONT16 hFont,
281 HICON16 hIcon, LPCSTR str, UINT16 uFlags)
283 RECT32 rect32;
285 if (rect)
286 CONV_RECT16TO32(rect,&rect32);
288 return (BOOL16)DrawCaptionTemp32A (hwnd, hdc, rect?&rect32:NULL, hFont,
289 hIcon, str, uFlags & 0x1F);
293 /***********************************************************************
294 * DrawCaptionTemp32A [USER32.599]
296 * PARAMS
298 * RETURNS
299 * Success:
300 * Failure:
303 BOOL32 WINAPI
304 DrawCaptionTemp32A (HWND32 hwnd, HDC32 hdc, const RECT32 *rect, HFONT32 hFont,
305 HICON32 hIcon, LPCSTR str, UINT32 uFlags)
307 RECT32 rc = *rect;
309 TRACE (nonclient, "(%08x,%08x,%p,%08x,%08x,\"%s\",%08x)\n",
310 hwnd, hdc, rect, hFont, hIcon, str, uFlags);
312 /* drawing background */
313 if (uFlags & DC_INBUTTON) {
314 FillRect32 (hdc, &rc, GetSysColorBrush32 (COLOR_3DFACE));
316 if (uFlags & DC_ACTIVE) {
317 HBRUSH32 hbr = SelectObject32 (hdc, CACHE_GetPattern55AABrush ());
318 PatBlt32 (hdc, rc.left, rc.top,
319 rc.right-rc.left, rc.bottom-rc.top, 0xFA0089);
320 SelectObject32 (hdc, hbr);
323 else {
324 FillRect32 (hdc, &rc, GetSysColorBrush32 ((uFlags & DC_ACTIVE) ?
325 COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
329 /* drawing icon */
330 if ((uFlags & DC_ICON) && !(uFlags & DC_SMALLCAP)) {
331 POINT32 pt;
333 pt.x = rc.left + 2;
334 pt.y = (rc.bottom + rc.top - sysMetrics[SM_CYSMICON]) / 2;
336 if (hIcon) {
337 DrawIconEx32 (hdc, pt.x, pt.y, hIcon, sysMetrics[SM_CXSMICON],
338 sysMetrics[SM_CYSMICON], 0, 0, DI_NORMAL);
340 else {
341 WND *wndPtr = WIN_FindWndPtr(hwnd);
342 HICON32 hAppIcon = 0;
344 if (wndPtr->class->hIconSm)
345 hAppIcon = wndPtr->class->hIconSm;
346 else if (wndPtr->class->hIcon)
347 hAppIcon = wndPtr->class->hIcon;
349 DrawIconEx32 (hdc, pt.x, pt.y, hAppIcon, sysMetrics[SM_CXSMICON],
350 sysMetrics[SM_CYSMICON], 0, 0, DI_NORMAL);
353 rc.left += (rc.bottom - rc.top);
356 /* drawing text */
357 if (uFlags & DC_TEXT) {
358 HFONT32 hOldFont;
360 if (uFlags & DC_INBUTTON)
361 SetTextColor32 (hdc, GetSysColor32 (COLOR_BTNTEXT));
362 else if (uFlags & DC_ACTIVE)
363 SetTextColor32 (hdc, GetSysColor32 (COLOR_CAPTIONTEXT));
364 else
365 SetTextColor32 (hdc, GetSysColor32 (COLOR_INACTIVECAPTIONTEXT));
367 SetBkMode32 (hdc, TRANSPARENT);
369 if (hFont)
370 hOldFont = SelectObject32 (hdc, hFont);
371 else {
372 NONCLIENTMETRICS32A nclm;
373 HFONT32 hNewFont;
374 nclm.cbSize = sizeof(NONCLIENTMETRICS32A);
375 SystemParametersInfo32A (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
376 hNewFont = CreateFontIndirect32A ((uFlags & DC_SMALLCAP) ?
377 &nclm.lfSmCaptionFont : &nclm.lfCaptionFont);
378 hOldFont = SelectObject32 (hdc, hNewFont);
381 if (str)
382 DrawText32A (hdc, str, -1, &rc,
383 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
384 else {
385 CHAR szText[128];
386 INT32 nLen;
387 nLen = GetWindowText32A (hwnd, szText, 128);
388 DrawText32A (hdc, szText, nLen, &rc,
389 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
392 if (hFont)
393 SelectObject32 (hdc, hOldFont);
394 else
395 DeleteObject32 (SelectObject32 (hdc, hOldFont));
398 /* drawing focus ??? */
399 if (uFlags & 0x2000)
400 FIXME (nonclient, "undocumented flag (0x2000)!\n");
402 return 0;
406 /***********************************************************************
407 * DrawCaptionTemp32W [USER32.602]
409 * PARAMS
411 * RETURNS
412 * Success:
413 * Failure:
416 BOOL32 WINAPI
417 DrawCaptionTemp32W (HWND32 hwnd, HDC32 hdc, const RECT32 *rect, HFONT32 hFont,
418 HICON32 hIcon, LPCWSTR str, UINT32 uFlags)
420 LPSTR p = HEAP_strdupWtoA (GetProcessHeap (), 0, str);
421 BOOL32 res = DrawCaptionTemp32A (hwnd, hdc, rect, hFont, hIcon, p, uFlags);
422 HeapFree (GetProcessHeap (), 0, p);
423 return res;
427 /***********************************************************************
428 * AdjustWindowRect16 (USER.102)
430 BOOL16 WINAPI AdjustWindowRect16( LPRECT16 rect, DWORD style, BOOL16 menu )
432 return AdjustWindowRectEx16( rect, style, menu, 0 );
436 /***********************************************************************
437 * AdjustWindowRect32 (USER32.2)
439 BOOL32 WINAPI AdjustWindowRect32( LPRECT32 rect, DWORD style, BOOL32 menu )
441 return AdjustWindowRectEx32( rect, style, menu, 0 );
445 /***********************************************************************
446 * AdjustWindowRectEx16 (USER.454)
448 BOOL16 WINAPI AdjustWindowRectEx16( LPRECT16 rect, DWORD style,
449 BOOL16 menu, DWORD exStyle )
451 /* Correct the window style */
453 if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
454 style |= WS_CAPTION;
455 style &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD);
456 exStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE |
457 WS_EX_STATICEDGE | WS_EX_TOOLWINDOW);
458 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
460 TRACE(nonclient, "(%d,%d)-(%d,%d) %08lx %d %08lx\n",
461 rect->left, rect->top, rect->right, rect->bottom,
462 style, menu, exStyle );
464 if (TWEAK_WineLook == WIN31_LOOK)
465 NC_AdjustRect( rect, style, menu, exStyle );
466 else {
467 NC_AdjustRectOuter95( rect, style, menu, exStyle );
468 NC_AdjustRectInner95( rect, style, exStyle );
471 return TRUE;
475 /***********************************************************************
476 * AdjustWindowRectEx32 (USER32.3)
478 BOOL32 WINAPI AdjustWindowRectEx32( LPRECT32 rect, DWORD style,
479 BOOL32 menu, DWORD exStyle )
481 RECT16 rect16;
482 BOOL32 ret;
484 CONV_RECT32TO16( rect, &rect16 );
485 ret = AdjustWindowRectEx16( &rect16, style, (BOOL16)menu, exStyle );
486 CONV_RECT16TO32( &rect16, rect );
487 return ret;
491 /***********************************************************************
492 * NC_HandleNCCalcSize
494 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
496 LONG NC_HandleNCCalcSize( WND *pWnd, RECT32 *winRect )
498 RECT16 tmpRect = { 0, 0, 0, 0 };
499 LONG result = 0;
501 if (pWnd->class->style & CS_VREDRAW) result |= WVR_VREDRAW;
502 if (pWnd->class->style & CS_HREDRAW) result |= WVR_HREDRAW;
504 if( !( pWnd->dwStyle & WS_MINIMIZE ) ) {
505 if (TWEAK_WineLook == WIN31_LOOK)
506 NC_AdjustRect( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
507 else
508 NC_AdjustRectOuter95( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
510 winRect->left -= tmpRect.left;
511 winRect->top -= tmpRect.top;
512 winRect->right -= tmpRect.right;
513 winRect->bottom -= tmpRect.bottom;
515 if (HAS_MENU(pWnd)) {
516 TRACE(nonclient, "Calling "
517 "GetMenuBarHeight with HWND 0x%x, width %d, "
518 "at (%d, %d).\n", pWnd->hwndSelf,
519 winRect->right - winRect->left,
520 -tmpRect.left, -tmpRect.top );
522 winRect->top +=
523 MENU_GetMenuBarHeight( pWnd->hwndSelf,
524 winRect->right - winRect->left,
525 -tmpRect.left, -tmpRect.top ) + 1;
528 if (TWEAK_WineLook > WIN31_LOOK) {
529 SetRect16 (&tmpRect, 0, 0, 0, 0);
530 NC_AdjustRectInner95 (&tmpRect, pWnd->dwStyle, pWnd->dwExStyle);
531 winRect->left -= tmpRect.left;
532 winRect->top -= tmpRect.top;
533 winRect->right -= tmpRect.right;
534 winRect->bottom -= tmpRect.bottom;
537 return result;
541 /***********************************************************************
542 * NC_GetInsideRect
544 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
545 * but without the borders (if any).
546 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
548 static void NC_GetInsideRect( HWND32 hwnd, RECT32 *rect )
550 WND * wndPtr = WIN_FindWndPtr( hwnd );
552 rect->top = rect->left = 0;
553 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
554 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
556 if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) return;
558 /* Remove frame from rectangle */
559 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
561 InflateRect32( rect, -SYSMETRICS_CXDLGFRAME, -SYSMETRICS_CYDLGFRAME);
562 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
563 InflateRect32( rect, -1, 0 );
565 else
567 if (HAS_THICKFRAME( wndPtr->dwStyle ))
568 InflateRect32( rect, -SYSMETRICS_CXFRAME, -SYSMETRICS_CYFRAME );
569 if (wndPtr->dwStyle & WS_BORDER)
570 InflateRect32( rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER );
573 return;
577 /***********************************************************************
578 * NC_GetInsideRect95
580 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
581 * but without the borders (if any).
582 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
585 static void
586 NC_GetInsideRect95 (HWND32 hwnd, RECT32 *rect)
588 WND * wndPtr = WIN_FindWndPtr( hwnd );
590 rect->top = rect->left = 0;
591 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
592 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
594 if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) return;
596 /* Remove frame from rectangle */
597 if (HAS_FIXEDFRAME (wndPtr->dwStyle, wndPtr->dwExStyle ))
599 InflateRect32( rect, -SYSMETRICS_CXFIXEDFRAME, -SYSMETRICS_CYFIXEDFRAME);
601 else if (HAS_SIZEFRAME (wndPtr->dwStyle))
603 InflateRect32( rect, -SYSMETRICS_CXSIZEFRAME, -SYSMETRICS_CYSIZEFRAME );
605 /* if (wndPtr->dwStyle & WS_BORDER)
606 InflateRect32( rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER );*/
609 if (wndPtr->dwStyle & WS_CHILD) {
610 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
611 InflateRect32 (rect, -SYSMETRICS_CXEDGE, -SYSMETRICS_CYEDGE);
613 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
614 InflateRect32 (rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER);
617 return;
621 /***********************************************************************
622 * NC_DoNCHitTest
624 * Handle a WM_NCHITTEST message. Called from NC_HandleNcHitTest().
627 LONG NC_DoNCHitTest (WND *wndPtr, POINT16 pt )
629 RECT16 rect;
631 TRACE(nonclient, "hwnd=%04x pt=%d,%d\n",
632 wndPtr->hwndSelf, pt.x, pt.y );
634 GetWindowRect16 (wndPtr->hwndSelf, &rect );
635 if (!PtInRect16( &rect, pt )) return HTNOWHERE;
637 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
639 if (!(wndPtr->flags & WIN_MANAGED))
641 /* Check borders */
642 if (HAS_THICKFRAME( wndPtr->dwStyle ))
644 InflateRect16( &rect, -SYSMETRICS_CXFRAME, -SYSMETRICS_CYFRAME );
645 if (wndPtr->dwStyle & WS_BORDER)
646 InflateRect16(&rect,-SYSMETRICS_CXBORDER,-SYSMETRICS_CYBORDER);
647 if (!PtInRect16( &rect, pt ))
649 /* Check top sizing border */
650 if (pt.y < rect.top)
652 if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTTOPLEFT;
653 if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTTOPRIGHT;
654 return HTTOP;
656 /* Check bottom sizing border */
657 if (pt.y >= rect.bottom)
659 if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTBOTTOMLEFT;
660 if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTBOTTOMRIGHT;
661 return HTBOTTOM;
663 /* Check left sizing border */
664 if (pt.x < rect.left)
666 if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPLEFT;
667 if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMLEFT;
668 return HTLEFT;
670 /* Check right sizing border */
671 if (pt.x >= rect.right)
673 if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPRIGHT;
674 if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMRIGHT;
675 return HTRIGHT;
679 else /* No thick frame */
681 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
682 InflateRect16(&rect, -SYSMETRICS_CXDLGFRAME, -SYSMETRICS_CYDLGFRAME);
683 else if (wndPtr->dwStyle & WS_BORDER)
684 InflateRect16(&rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER);
685 if (!PtInRect16( &rect, pt )) return HTBORDER;
688 /* Check caption */
690 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
692 rect.top += sysMetrics[SM_CYCAPTION] - 1;
693 if (!PtInRect16( &rect, pt ))
695 /* Check system menu */
696 if (wndPtr->dwStyle & WS_SYSMENU)
697 rect.left += SYSMETRICS_CXSIZE;
698 if (pt.x <= rect.left) return HTSYSMENU;
699 /* Check maximize box */
700 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
701 rect.right -= SYSMETRICS_CXSIZE + 1;
702 if (pt.x >= rect.right) return HTMAXBUTTON;
703 /* Check minimize box */
704 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
705 rect.right -= SYSMETRICS_CXSIZE + 1;
706 if (pt.x >= rect.right) return HTMINBUTTON;
707 return HTCAPTION;
712 /* Check client area */
714 ScreenToClient16( wndPtr->hwndSelf, &pt );
715 GetClientRect16( wndPtr->hwndSelf, &rect );
716 if (PtInRect16( &rect, pt )) return HTCLIENT;
718 /* Check vertical scroll bar */
720 if (wndPtr->dwStyle & WS_VSCROLL)
722 rect.right += SYSMETRICS_CXVSCROLL;
723 if (PtInRect16( &rect, pt )) return HTVSCROLL;
726 /* Check horizontal scroll bar */
728 if (wndPtr->dwStyle & WS_HSCROLL)
730 rect.bottom += SYSMETRICS_CYHSCROLL;
731 if (PtInRect16( &rect, pt ))
733 /* Check size box */
734 if ((wndPtr->dwStyle & WS_VSCROLL) &&
735 (pt.x >= rect.right - SYSMETRICS_CXVSCROLL))
736 return HTSIZE;
737 return HTHSCROLL;
741 /* Check menu bar */
743 if (HAS_MENU(wndPtr))
745 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
746 return HTMENU;
749 /* Should never get here */
750 return HTERROR;
754 /***********************************************************************
755 * NC_DoNCHitTest95
757 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
759 * FIXME: Just a modified copy of the Win 3.1 version.
762 LONG
763 NC_DoNCHitTest95 (WND *wndPtr, POINT16 pt )
765 RECT16 rect;
767 TRACE(nonclient, "hwnd=%04x pt=%d,%d\n",
768 wndPtr->hwndSelf, pt.x, pt.y );
770 GetWindowRect16 (wndPtr->hwndSelf, &rect );
771 if (!PtInRect16( &rect, pt )) return HTNOWHERE;
773 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
775 if (!(wndPtr->flags & WIN_MANAGED))
777 /* Check borders */
778 if (HAS_SIZEFRAME( wndPtr->dwStyle ))
780 InflateRect16( &rect, -SYSMETRICS_CXFRAME, -SYSMETRICS_CYFRAME );
781 /* if (wndPtr->dwStyle & WS_BORDER) */
782 /* InflateRect16(&rect,-SYSMETRICS_CXBORDER,-SYSMETRICS_CYBORDER); */
783 if (!PtInRect16( &rect, pt ))
785 /* Check top sizing border */
786 if (pt.y < rect.top)
788 if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTTOPLEFT;
789 if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTTOPRIGHT;
790 return HTTOP;
792 /* Check bottom sizing border */
793 if (pt.y >= rect.bottom)
795 if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTBOTTOMLEFT;
796 if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTBOTTOMRIGHT;
797 return HTBOTTOM;
799 /* Check left sizing border */
800 if (pt.x < rect.left)
802 if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPLEFT;
803 if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMLEFT;
804 return HTLEFT;
806 /* Check right sizing border */
807 if (pt.x >= rect.right)
809 if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPRIGHT;
810 if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMRIGHT;
811 return HTRIGHT;
815 else /* No thick frame */
817 if (HAS_FIXEDFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
818 InflateRect16(&rect, -SYSMETRICS_CXDLGFRAME, -SYSMETRICS_CYDLGFRAME);
819 /* else if (wndPtr->dwStyle & WS_BORDER) */
820 /* InflateRect16(&rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER); */
821 if (!PtInRect16( &rect, pt )) return HTBORDER;
824 /* Check caption */
826 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
828 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
829 rect.top += sysMetrics[SM_CYSMCAPTION] - 1;
830 else
831 rect.top += sysMetrics[SM_CYCAPTION] - 1;
832 if (!PtInRect16( &rect, pt ))
834 /* Check system menu */
835 if ((wndPtr->dwStyle & WS_SYSMENU) &&
836 ((wndPtr->class->hIconSm) || (wndPtr->class->hIcon)))
837 rect.left += sysMetrics[SM_CYCAPTION] - 1;
838 if (pt.x < rect.left) return HTSYSMENU;
840 /* Check close button */
841 if (wndPtr->dwStyle & WS_SYSMENU)
842 rect.right -= sysMetrics[SM_CYCAPTION] - 1;
843 if (pt.x > rect.right) return HTCLOSE;
845 /* Check maximize box */
846 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
847 rect.right -= SYSMETRICS_CXSIZE + 1;
848 if (pt.x > rect.right) return HTMAXBUTTON;
850 /* Check minimize box */
851 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
852 rect.right -= SYSMETRICS_CXSIZE + 1;
853 if (pt.x > rect.right) return HTMINBUTTON;
854 return HTCAPTION;
859 /* Check client area */
861 ScreenToClient16( wndPtr->hwndSelf, &pt );
862 GetClientRect16( wndPtr->hwndSelf, &rect );
863 if (PtInRect16( &rect, pt )) return HTCLIENT;
865 /* Check vertical scroll bar */
867 if (wndPtr->dwStyle & WS_VSCROLL)
869 rect.right += SYSMETRICS_CXVSCROLL;
870 if (PtInRect16( &rect, pt )) return HTVSCROLL;
873 /* Check horizontal scroll bar */
875 if (wndPtr->dwStyle & WS_HSCROLL)
877 rect.bottom += SYSMETRICS_CYHSCROLL;
878 if (PtInRect16( &rect, pt ))
880 /* Check size box */
881 if ((wndPtr->dwStyle & WS_VSCROLL) &&
882 (pt.x >= rect.right - SYSMETRICS_CXVSCROLL))
883 return HTSIZE;
884 return HTHSCROLL;
888 /* Check menu bar */
890 if (HAS_MENU(wndPtr))
892 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
893 return HTMENU;
896 /* Should never get here */
897 return HTERROR;
901 /***********************************************************************
902 * NC_HandleNCHitTest
904 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
906 LONG
907 NC_HandleNCHitTest (HWND32 hwnd , POINT16 pt)
909 WND *wndPtr = WIN_FindWndPtr (hwnd);
911 if (!wndPtr)
912 return HTERROR;
914 if (TWEAK_WineLook == WIN31_LOOK)
915 return NC_DoNCHitTest (wndPtr, pt);
916 else
917 return NC_DoNCHitTest95 (wndPtr, pt);
921 /***********************************************************************
922 * NC_DrawSysButton
924 void NC_DrawSysButton( HWND32 hwnd, HDC32 hdc, BOOL32 down )
926 RECT32 rect;
927 HDC32 hdcMem;
928 HBITMAP32 hbitmap;
929 WND *wndPtr = WIN_FindWndPtr( hwnd );
931 if( !(wndPtr->flags & WIN_MANAGED) )
933 NC_GetInsideRect( hwnd, &rect );
934 hdcMem = CreateCompatibleDC32( hdc );
935 hbitmap = SelectObject32( hdcMem, hbitmapClose );
936 BitBlt32(hdc, rect.left, rect.top, SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE,
937 hdcMem, (wndPtr->dwStyle & WS_CHILD) ? SYSMETRICS_CXSIZE : 0, 0,
938 down ? NOTSRCCOPY : SRCCOPY );
939 SelectObject32( hdcMem, hbitmap );
940 DeleteDC32( hdcMem );
945 /***********************************************************************
946 * NC_DrawMaxButton
948 static void NC_DrawMaxButton( HWND32 hwnd, HDC16 hdc, BOOL32 down )
950 RECT32 rect;
951 WND *wndPtr = WIN_FindWndPtr( hwnd );
952 HDC32 hdcMem;
954 if( !(wndPtr->flags & WIN_MANAGED) )
956 NC_GetInsideRect( hwnd, &rect );
957 hdcMem = CreateCompatibleDC32( hdc );
958 SelectObject32( hdcMem, (IsZoomed32(hwnd)
959 ? (down ? hbitmapRestoreD : hbitmapRestore)
960 : (down ? hbitmapMaximizeD : hbitmapMaximize)) );
961 BitBlt32( hdc, rect.right - SYSMETRICS_CXSIZE - 1, rect.top,
962 SYSMETRICS_CXSIZE + 1, SYSMETRICS_CYSIZE, hdcMem, 0, 0,
963 SRCCOPY );
964 DeleteDC32( hdcMem );
969 /***********************************************************************
970 * NC_DrawMinButton
972 static void NC_DrawMinButton( HWND32 hwnd, HDC16 hdc, BOOL32 down )
974 RECT32 rect;
975 WND *wndPtr = WIN_FindWndPtr( hwnd );
976 HDC32 hdcMem;
978 if( !(wndPtr->flags & WIN_MANAGED) )
980 NC_GetInsideRect( hwnd, &rect );
981 hdcMem = CreateCompatibleDC32( hdc );
982 SelectObject32( hdcMem, (down ? hbitmapMinimizeD : hbitmapMinimize) );
983 if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= SYSMETRICS_CXSIZE+1;
984 BitBlt32( hdc, rect.right - SYSMETRICS_CXSIZE - 1, rect.top,
985 SYSMETRICS_CXSIZE + 1, SYSMETRICS_CYSIZE, hdcMem, 0, 0,
986 SRCCOPY );
987 DeleteDC32( hdcMem );
992 /******************************************************************************
994 * void NC_DrawSysButton95(
995 * HWND32 hwnd,
996 * HDC32 hdc,
997 * BOOL32 down )
999 * Draws the Win95 system icon.
1001 * Revision history
1002 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1003 * Original implementation from NC_DrawSysButton source.
1004 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1005 * Fixed most bugs.
1007 *****************************************************************************/
1009 BOOL32
1010 NC_DrawSysButton95 (HWND32 hwnd, HDC32 hdc, BOOL32 down)
1012 WND *wndPtr = WIN_FindWndPtr( hwnd );
1014 if( !(wndPtr->flags & WIN_MANAGED) )
1016 HICON32 hIcon = 0;
1017 RECT32 rect;
1019 NC_GetInsideRect95( hwnd, &rect );
1021 if (wndPtr->class->hIconSm)
1022 hIcon = wndPtr->class->hIconSm;
1023 else if (wndPtr->class->hIcon)
1024 hIcon = wndPtr->class->hIcon;
1026 if (hIcon)
1027 DrawIconEx32 (hdc, rect.left + 2, rect.top + 2, hIcon,
1028 sysMetrics[SM_CXSMICON],
1029 sysMetrics[SM_CYSMICON],
1030 0, 0, DI_NORMAL);
1032 return (hIcon != 0);
1034 return FALSE;
1038 /******************************************************************************
1040 * void NC_DrawCloseButton95(
1041 * HWND32 hwnd,
1042 * HDC32 hdc,
1043 * BOOL32 down )
1045 * Draws the Win95 close button.
1047 * Revision history
1048 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1049 * Original implementation from NC_DrawSysButton95 source.
1051 *****************************************************************************/
1053 void
1054 NC_DrawCloseButton95 (HWND32 hwnd, HDC32 hdc, BOOL32 down)
1056 RECT32 rect;
1057 HDC32 hdcMem;
1058 WND *wndPtr = WIN_FindWndPtr( hwnd );
1060 if( !(wndPtr->flags & WIN_MANAGED) )
1062 BITMAP32 bmp;
1063 HBITMAP32 hBmp, hOldBmp;
1065 NC_GetInsideRect95( hwnd, &rect );
1067 hdcMem = CreateCompatibleDC32( hdc );
1068 hBmp = /*down ? hbitmapCloseD :*/ hbitmapClose;
1069 hOldBmp = SelectObject32 (hdcMem, hBmp);
1070 GetObject32A (hBmp, sizeof(BITMAP32), &bmp);
1071 BitBlt32 (hdc, rect.right - (sysMetrics[SM_CYCAPTION] + 1 + bmp.bmWidth) / 2,
1072 rect.top + (sysMetrics[SM_CYCAPTION] - 1 - bmp.bmHeight) / 2,
1073 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, down ? NOTSRCCOPY : SRCCOPY);
1075 SelectObject32 (hdcMem, hOldBmp);
1076 DeleteDC32 (hdcMem);
1081 /******************************************************************************
1083 * NC_DrawMaxButton95(
1084 * HWND32 hwnd,
1085 * HDC16 hdc,
1086 * BOOL32 down )
1088 * Draws the maximize button for Win95 style windows.
1090 * Bugs
1091 * Many. Spacing might still be incorrect. Need to fit a close
1092 * button between the max button and the edge.
1093 * Should scale the image with the title bar. And more...
1095 * Revision history
1096 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1097 * Original implementation.
1099 *****************************************************************************/
1101 static void NC_DrawMaxButton95(
1102 HWND32 hwnd,
1103 HDC16 hdc,
1104 BOOL32 down )
1106 RECT32 rect;
1107 WND *wndPtr = WIN_FindWndPtr( hwnd );
1108 SIZE32 bmsz;
1109 HBITMAP32 bm;
1110 HDC32 hdcMem;
1112 if( !(wndPtr->flags & WIN_MANAGED) &&
1113 GetBitmapDimensionEx32((bm = IsZoomed32(hwnd) ?
1114 (down ? hbitmapRestoreD : hbitmapRestore ) :
1115 (down ? hbitmapMaximizeD : hbitmapMaximize)),
1116 &bmsz)) {
1118 NC_GetInsideRect95( hwnd, &rect );
1120 if (wndPtr->dwStyle & WS_SYSMENU)
1121 rect.right -= sysMetrics[SM_CYCAPTION] + 1;
1123 hdcMem = CreateCompatibleDC32( hdc );
1124 SelectObject32( hdc, bm );
1125 BitBlt32( hdc, rect.right - (sysMetrics[SM_CXSIZE] + bmsz.cx) / 2,
1126 rect.top + (sysMetrics[SM_CYCAPTION] - 1 - bmsz.cy) / 2,
1127 bmsz.cx, bmsz.cy, hdcMem, 0, 0, SRCCOPY );
1128 DeleteDC32( hdcMem );
1131 return;
1135 /******************************************************************************
1137 * NC_DrawMinButton95(
1138 * HWND32 hwnd,
1139 * HDC16 hdc,
1140 * BOOL32 down )
1142 * Draws the minimize button for Win95 style windows.
1144 * Bugs
1145 * Many. Spacing is still incorrect. Should scale the image with the
1146 * title bar. And more...
1148 * Revision history
1149 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1150 * Original implementation.
1152 *****************************************************************************/
1154 static void NC_DrawMinButton95(
1155 HWND32 hwnd,
1156 HDC16 hdc,
1157 BOOL32 down )
1159 RECT32 rect;
1160 WND *wndPtr = WIN_FindWndPtr( hwnd );
1161 SIZE32 bmsz;
1162 HBITMAP32 bm;
1163 HDC32 hdcMem;
1165 if( !(wndPtr->flags & WIN_MANAGED) &&
1166 GetBitmapDimensionEx32((bm = down ? hbitmapMinimizeD :
1167 hbitmapMinimize), &bmsz)) {
1169 NC_GetInsideRect95( hwnd, &rect );
1171 if (wndPtr->dwStyle & WS_SYSMENU)
1172 rect.right -= sysMetrics[SM_CYCAPTION] + 1;
1174 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
1175 rect.right += -1 -
1176 (sysMetrics[SM_CXSIZE] + bmsz.cx) / 2;
1178 hdcMem = CreateCompatibleDC32( hdc );
1179 SelectObject32( hdc, bm );
1180 BitBlt32( hdc, rect.right - (sysMetrics[SM_CXSIZE] + bmsz.cx) / 2,
1181 rect.top + (sysMetrics[SM_CYCAPTION] - 1 - bmsz.cy) / 2,
1182 bmsz.cx, bmsz.cy, hdcMem, 0, 0, SRCCOPY );
1183 DeleteDC32( hdcMem );
1186 return;
1190 /***********************************************************************
1191 * NC_DrawFrame
1193 * Draw a window frame inside the given rectangle, and update the rectangle.
1194 * The correct pen for the frame must be selected in the DC.
1196 static void NC_DrawFrame( HDC32 hdc, RECT32 *rect, BOOL32 dlgFrame,
1197 BOOL32 active )
1199 INT32 width, height;
1201 if (TWEAK_WineLook != WIN31_LOOK)
1202 ERR (nonclient, "Called in Win95 mode. Aiee! Please report this.\n" );
1204 if (dlgFrame)
1206 width = SYSMETRICS_CXDLGFRAME - 1;
1207 height = SYSMETRICS_CYDLGFRAME - 1;
1208 SelectObject32( hdc, GetSysColorBrush32(active ? COLOR_ACTIVECAPTION :
1209 COLOR_INACTIVECAPTION) );
1211 else
1213 width = SYSMETRICS_CXFRAME - 1;
1214 height = SYSMETRICS_CYFRAME - 1;
1215 SelectObject32( hdc, GetSysColorBrush32(active ? COLOR_ACTIVEBORDER :
1216 COLOR_INACTIVEBORDER) );
1219 /* Draw frame */
1220 PatBlt32( hdc, rect->left, rect->top,
1221 rect->right - rect->left, height, PATCOPY );
1222 PatBlt32( hdc, rect->left, rect->top,
1223 width, rect->bottom - rect->top, PATCOPY );
1224 PatBlt32( hdc, rect->left, rect->bottom,
1225 rect->right - rect->left, -height, PATCOPY );
1226 PatBlt32( hdc, rect->right, rect->top,
1227 -width, rect->bottom - rect->top, PATCOPY );
1229 if (dlgFrame)
1231 InflateRect32( rect, -width, -height );
1233 else
1235 INT32 decYOff = SYSMETRICS_CXFRAME + SYSMETRICS_CXSIZE;
1236 INT32 decXOff = SYSMETRICS_CYFRAME + SYSMETRICS_CYSIZE;
1238 /* Draw inner rectangle */
1240 SelectObject32( hdc, GetStockObject32(NULL_BRUSH) );
1241 Rectangle32( hdc, rect->left + width, rect->top + height,
1242 rect->right - width , rect->bottom - height );
1244 /* Draw the decorations */
1246 MoveToEx32( hdc, rect->left, rect->top + decYOff, NULL );
1247 LineTo32( hdc, rect->left + width, rect->top + decYOff );
1248 MoveToEx32( hdc, rect->right - 1, rect->top + decYOff, NULL );
1249 LineTo32( hdc, rect->right - width - 1, rect->top + decYOff );
1250 MoveToEx32( hdc, rect->left, rect->bottom - decYOff, NULL );
1251 LineTo32( hdc, rect->left + width, rect->bottom - decYOff );
1252 MoveToEx32( hdc, rect->right - 1, rect->bottom - decYOff, NULL );
1253 LineTo32( hdc, rect->right - width - 1, rect->bottom - decYOff );
1255 MoveToEx32( hdc, rect->left + decXOff, rect->top, NULL );
1256 LineTo32( hdc, rect->left + decXOff, rect->top + height);
1257 MoveToEx32( hdc, rect->left + decXOff, rect->bottom - 1, NULL );
1258 LineTo32( hdc, rect->left + decXOff, rect->bottom - height - 1 );
1259 MoveToEx32( hdc, rect->right - decXOff, rect->top, NULL );
1260 LineTo32( hdc, rect->right - decXOff, rect->top + height );
1261 MoveToEx32( hdc, rect->right - decXOff, rect->bottom - 1, NULL );
1262 LineTo32( hdc, rect->right - decXOff, rect->bottom - height - 1 );
1264 InflateRect32( rect, -width - 1, -height - 1 );
1269 /******************************************************************************
1271 * void NC_DrawFrame95(
1272 * HDC32 hdc,
1273 * RECT32 *rect,
1274 * BOOL32 dlgFrame,
1275 * BOOL32 active )
1277 * Draw a window frame inside the given rectangle, and update the rectangle.
1278 * The correct pen for the frame must be selected in the DC.
1280 * Bugs
1281 * Many. First, just what IS a frame in Win95? Note that the 3D look
1282 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1283 * edge. The inner rectangle just inside the frame is handled by the
1284 * Caption code.
1286 * In short, for most people, this function should be a nop (unless
1287 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1288 * them lately, but just to get this code right). Even so, it doesn't
1289 * appear to be so. It's being worked on...
1291 * Revision history
1292 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1293 * Original implementation (based on NC_DrawFrame)
1294 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1295 * Some minor fixes.
1297 *****************************************************************************/
1299 static void NC_DrawFrame95(
1300 HDC32 hdc,
1301 RECT32 *rect,
1302 BOOL32 dlgFrame,
1303 BOOL32 active )
1305 INT32 width, height;
1307 if (dlgFrame)
1309 width = sysMetrics[SM_CXDLGFRAME] - sysMetrics[SM_CXEDGE];
1310 height = sysMetrics[SM_CYDLGFRAME] - sysMetrics[SM_CYEDGE];
1312 else
1314 width = sysMetrics[SM_CXFRAME] - sysMetrics[SM_CXEDGE];
1315 height = sysMetrics[SM_CYFRAME] - sysMetrics[SM_CYEDGE];
1318 SelectObject32( hdc, GetSysColorBrush32(active ? COLOR_ACTIVEBORDER :
1319 COLOR_INACTIVEBORDER) );
1321 /* Draw frame */
1322 PatBlt32( hdc, rect->left, rect->top,
1323 rect->right - rect->left, height, PATCOPY );
1324 PatBlt32( hdc, rect->left, rect->top,
1325 width, rect->bottom - rect->top, PATCOPY );
1326 PatBlt32( hdc, rect->left, rect->bottom,
1327 rect->right - rect->left, -height, PATCOPY );
1328 PatBlt32( hdc, rect->right, rect->top,
1329 -width, rect->bottom - rect->top, PATCOPY );
1331 InflateRect32( rect, -width, -height );
1336 /***********************************************************************
1337 * NC_DrawMovingFrame
1339 * Draw the frame used when moving or resizing window.
1341 * FIXME: This causes problems in Win95 mode. (why?)
1343 static void NC_DrawMovingFrame( HDC32 hdc, RECT32 *rect, BOOL32 thickframe )
1345 if (thickframe)
1347 RECT16 r16;
1348 CONV_RECT32TO16( rect, &r16 );
1349 FastWindowFrame( hdc, &r16, SYSMETRICS_CXFRAME,
1350 SYSMETRICS_CYFRAME, PATINVERT );
1352 else DrawFocusRect32( hdc, rect );
1356 /***********************************************************************
1357 * NC_DrawCaption
1359 * Draw the window caption.
1360 * The correct pen for the window frame must be selected in the DC.
1362 static void NC_DrawCaption( HDC32 hdc, RECT32 *rect, HWND32 hwnd,
1363 DWORD style, BOOL32 active )
1365 RECT32 r = *rect;
1366 WND * wndPtr = WIN_FindWndPtr( hwnd );
1367 char buffer[256];
1369 if (wndPtr->flags & WIN_MANAGED) return;
1371 if (!hbitmapClose)
1373 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1374 return;
1375 hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) );
1376 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1377 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1378 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1379 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1380 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1381 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1384 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
1386 HBRUSH32 hbrushOld = SelectObject32(hdc, GetSysColorBrush32(COLOR_WINDOW) );
1387 PatBlt32( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
1388 PatBlt32( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
1389 PatBlt32( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
1390 r.left++;
1391 r.right--;
1392 SelectObject32( hdc, hbrushOld );
1395 MoveTo( hdc, r.left, r.bottom );
1396 LineTo32( hdc, r.right, r.bottom );
1398 if (style & WS_SYSMENU)
1400 NC_DrawSysButton( hwnd, hdc, FALSE );
1401 r.left += SYSMETRICS_CXSIZE + 1;
1402 MoveTo( hdc, r.left - 1, r.top );
1403 LineTo32( hdc, r.left - 1, r.bottom );
1405 if (style & WS_MAXIMIZEBOX)
1407 NC_DrawMaxButton( hwnd, hdc, FALSE );
1408 r.right -= SYSMETRICS_CXSIZE + 1;
1410 if (style & WS_MINIMIZEBOX)
1412 NC_DrawMinButton( hwnd, hdc, FALSE );
1413 r.right -= SYSMETRICS_CXSIZE + 1;
1416 FillRect32( hdc, &r, GetSysColorBrush32(active ? COLOR_ACTIVECAPTION :
1417 COLOR_INACTIVECAPTION) );
1419 if (GetWindowText32A( hwnd, buffer, sizeof(buffer) ))
1421 if (active) SetTextColor32( hdc, GetSysColor32( COLOR_CAPTIONTEXT ) );
1422 else SetTextColor32( hdc, GetSysColor32( COLOR_INACTIVECAPTIONTEXT ) );
1423 SetBkMode32( hdc, TRANSPARENT );
1424 DrawText32A( hdc, buffer, -1, &r,
1425 DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );
1430 /******************************************************************************
1432 * NC_DrawCaption95(
1433 * HDC32 hdc,
1434 * RECT32 *rect,
1435 * HWND32 hwnd,
1436 * DWORD style,
1437 * BOOL32 active )
1439 * Draw the window caption for Win95 style windows.
1440 * The correct pen for the window frame must be selected in the DC.
1442 * Bugs
1443 * Hey, a function that finally works! Well, almost.
1444 * It's being worked on.
1446 * Revision history
1447 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1448 * Original implementation.
1449 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1450 * Some minor fixes.
1452 *****************************************************************************/
1454 static void NC_DrawCaption95(
1455 HDC32 hdc,
1456 RECT32 *rect,
1457 HWND32 hwnd,
1458 DWORD style,
1459 DWORD exStyle,
1460 BOOL32 active )
1462 RECT32 r = *rect;
1463 WND *wndPtr = WIN_FindWndPtr( hwnd );
1464 char buffer[256];
1465 HPEN32 hPrevPen;
1467 if (wndPtr->flags & WIN_MANAGED) return;
1469 hPrevPen = SelectObject32( hdc, GetSysColorPen32(COLOR_3DFACE) );
1470 MoveToEx32( hdc, r.left, r.bottom - 1, NULL );
1471 LineTo32( hdc, r.right, r.bottom - 1 );
1472 SelectObject32( hdc, hPrevPen );
1473 r.bottom--;
1475 FillRect32( hdc, &r, GetSysColorBrush32(active ? COLOR_ACTIVECAPTION :
1476 COLOR_INACTIVECAPTION) );
1478 if (!hbitmapClose) {
1479 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1480 return;
1481 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1482 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1483 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1484 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1485 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1486 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1489 if ((style & WS_SYSMENU) && !(exStyle & WS_EX_TOOLWINDOW)) {
1490 if (NC_DrawSysButton95 (hwnd, hdc, FALSE))
1491 r.left += sysMetrics[SM_CYCAPTION] - 1;
1493 if (style & WS_SYSMENU) {
1494 NC_DrawCloseButton95 (hwnd, hdc, FALSE);
1495 r.right -= sysMetrics[SM_CYCAPTION] - 1;
1497 if (style & WS_MAXIMIZEBOX) {
1498 NC_DrawMaxButton95( hwnd, hdc, FALSE );
1499 r.right -= SYSMETRICS_CXSIZE + 1;
1501 if (style & WS_MINIMIZEBOX) {
1502 NC_DrawMinButton95( hwnd, hdc, FALSE );
1503 r.right -= SYSMETRICS_CXSIZE + 1;
1506 if (GetWindowText32A( hwnd, buffer, sizeof(buffer) )) {
1507 NONCLIENTMETRICS32A nclm;
1508 HFONT32 hFont, hOldFont;
1509 nclm.cbSize = sizeof(NONCLIENTMETRICS32A);
1510 SystemParametersInfo32A (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1511 if (exStyle & WS_EX_TOOLWINDOW)
1512 hFont = CreateFontIndirect32A (&nclm.lfSmCaptionFont);
1513 else
1514 hFont = CreateFontIndirect32A (&nclm.lfCaptionFont);
1515 hOldFont = SelectObject32 (hdc, hFont);
1516 if (active) SetTextColor32( hdc, GetSysColor32( COLOR_CAPTIONTEXT ) );
1517 else SetTextColor32( hdc, GetSysColor32( COLOR_INACTIVECAPTIONTEXT ) );
1518 SetBkMode32( hdc, TRANSPARENT );
1519 r.left += 2;
1520 DrawText32A( hdc, buffer, -1, &r,
1521 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
1522 DeleteObject32 (SelectObject32 (hdc, hOldFont));
1528 /***********************************************************************
1529 * NC_DoNCPaint
1531 * Paint the non-client area. clip is currently unused.
1533 void NC_DoNCPaint( WND* wndPtr, HRGN32 clip, BOOL32 suppress_menupaint )
1535 HDC32 hdc;
1536 RECT32 rect;
1537 BOOL32 active;
1538 HWND32 hwnd = wndPtr->hwndSelf;
1540 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1541 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1543 active = wndPtr->flags & WIN_NCACTIVATED;
1545 TRACE(nonclient, "%04x %d\n", hwnd, active );
1547 if (!(hdc = GetDCEx32( hwnd, 0, DCX_USESTYLE | DCX_WINDOW ))) return;
1549 if (ExcludeVisRect( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1550 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1551 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1552 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1553 == NULLREGION)
1555 ReleaseDC32( hwnd, hdc );
1556 return;
1559 rect.top = rect.left = 0;
1560 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1561 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1563 SelectObject32( hdc, GetSysColorPen32(COLOR_WINDOWFRAME) );
1565 if (!(wndPtr->flags & WIN_MANAGED))
1567 if ((wndPtr->dwStyle & WS_BORDER) || (wndPtr->dwStyle & WS_DLGFRAME) ||
1568 (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME))
1570 SelectObject32( hdc, GetStockObject32(NULL_BRUSH) );
1571 Rectangle32( hdc, 0, 0, rect.right, rect.bottom );
1572 InflateRect32( &rect, -1, -1 );
1575 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1576 NC_DrawFrame( hdc, &rect, TRUE, active );
1577 else if (wndPtr->dwStyle & WS_THICKFRAME)
1578 NC_DrawFrame(hdc, &rect, FALSE, active );
1580 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1582 RECT32 r = rect;
1583 r.bottom = rect.top + SYSMETRICS_CYSIZE;
1584 rect.top += SYSMETRICS_CYSIZE + SYSMETRICS_CYBORDER;
1585 NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active );
1589 if (HAS_MENU(wndPtr))
1591 RECT32 r = rect;
1592 r.bottom = rect.top + SYSMETRICS_CYMENU; /* default height */
1593 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint );
1596 /* Draw the scroll-bars */
1598 if (wndPtr->dwStyle & WS_VSCROLL)
1599 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1600 if (wndPtr->dwStyle & WS_HSCROLL)
1601 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1603 /* Draw the "size-box" */
1605 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1607 RECT32 r = rect;
1608 r.left = r.right - SYSMETRICS_CXVSCROLL + 1;
1609 r.top = r.bottom - SYSMETRICS_CYHSCROLL + 1;
1610 if(wndPtr->dwStyle & WS_BORDER) {
1611 r.left++;
1612 r.top++;
1614 FillRect32( hdc, &r, GetSysColorBrush32(COLOR_SCROLLBAR) );
1617 ReleaseDC32( hwnd, hdc );
1621 /******************************************************************************
1623 * void NC_DoNCPaint95(
1624 * WND *wndPtr,
1625 * HRGN32 clip,
1626 * BOOL32 suppress_menupaint )
1628 * Paint the non-client area for Win95 windows. The clip region is
1629 * currently ignored.
1631 * Bugs
1632 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1633 * misc/tweak.c controls/menu.c # :-)
1635 * Revision history
1636 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1637 * Original implementation
1638 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1639 * Fixed some bugs.
1641 *****************************************************************************/
1643 void NC_DoNCPaint95(
1644 WND *wndPtr,
1645 HRGN32 clip,
1646 BOOL32 suppress_menupaint )
1648 HDC32 hdc;
1649 RECT32 rect;
1650 BOOL32 active;
1651 HWND32 hwnd = wndPtr->hwndSelf;
1653 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1654 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1656 active = wndPtr->flags & WIN_NCACTIVATED;
1658 TRACE(nonclient, "%04x %d\n", hwnd, active );
1660 if (!(hdc = GetDCEx32( hwnd, 0, DCX_USESTYLE | DCX_WINDOW ))) return;
1662 if (ExcludeVisRect( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1663 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1664 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1665 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1666 == NULLREGION)
1668 ReleaseDC32( hwnd, hdc );
1669 return;
1672 rect.top = rect.left = 0;
1673 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1674 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1676 SelectObject32( hdc, GetSysColorPen32(COLOR_WINDOWFRAME) );
1678 if(!(wndPtr->flags & WIN_MANAGED)) {
1679 if ((wndPtr->dwStyle & WS_BORDER) && ((wndPtr->dwStyle & WS_DLGFRAME) ||
1680 (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME) || (wndPtr->dwStyle & WS_THICKFRAME))) {
1681 DrawEdge32 (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1684 if (HAS_FIXEDFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1685 NC_DrawFrame95( hdc, &rect, TRUE, active );
1686 else if (wndPtr->dwStyle & WS_THICKFRAME)
1687 NC_DrawFrame95(hdc, &rect, FALSE, active );
1689 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1691 RECT32 r = rect;
1692 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW) {
1693 r.bottom = rect.top + sysMetrics[SM_CYSMCAPTION];
1694 rect.top += sysMetrics[SM_CYSMCAPTION];
1696 else {
1697 r.bottom = rect.top + sysMetrics[SM_CYCAPTION];
1698 rect.top += sysMetrics[SM_CYCAPTION];
1700 NC_DrawCaption95 (hdc, &r, hwnd, wndPtr->dwStyle,
1701 wndPtr->dwExStyle, active);
1705 if (HAS_MENU(wndPtr))
1707 RECT32 r = rect;
1708 r.bottom = rect.top + sysMetrics[SM_CYMENU];
1710 TRACE(nonclient, "Calling DrawMenuBar with "
1711 "rect (%d, %d)-(%d, %d)\n", r.left, r.top,
1712 r.right, r.bottom);
1714 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ) + 1;
1717 TRACE(nonclient, "After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1718 rect.left, rect.top, rect.right, rect.bottom );
1720 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
1721 DrawEdge32 (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1723 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
1724 DrawEdge32 (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1726 /* Draw the scroll-bars */
1728 if (wndPtr->dwStyle & WS_VSCROLL)
1729 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1730 if (wndPtr->dwStyle & WS_HSCROLL)
1731 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1733 /* Draw the "size-box" */
1734 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1736 RECT32 r = rect;
1737 r.left = r.right - SYSMETRICS_CXVSCROLL + 1;
1738 r.top = r.bottom - SYSMETRICS_CYHSCROLL + 1;
1739 FillRect32( hdc, &r, GetSysColorBrush32(COLOR_SCROLLBAR) );
1742 ReleaseDC32( hwnd, hdc );
1748 /***********************************************************************
1749 * NC_HandleNCPaint
1751 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1753 LONG NC_HandleNCPaint( HWND32 hwnd , HRGN32 clip)
1755 WND* wndPtr = WIN_FindWndPtr( hwnd );
1757 if( wndPtr && wndPtr->dwStyle & WS_VISIBLE )
1759 if( wndPtr->dwStyle & WS_MINIMIZE )
1760 WINPOS_RedrawIconTitle( hwnd );
1761 else if (TWEAK_WineLook == WIN31_LOOK)
1762 NC_DoNCPaint( wndPtr, clip, FALSE );
1763 else
1764 NC_DoNCPaint95( wndPtr, clip, FALSE );
1766 return 0;
1770 /***********************************************************************
1771 * NC_HandleNCActivate
1773 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1775 LONG NC_HandleNCActivate( WND *wndPtr, WPARAM16 wParam )
1777 WORD wStateChange;
1779 if( wParam ) wStateChange = !(wndPtr->flags & WIN_NCACTIVATED);
1780 else wStateChange = wndPtr->flags & WIN_NCACTIVATED;
1782 if( wStateChange )
1784 if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
1785 else wndPtr->flags &= ~WIN_NCACTIVATED;
1787 if( wndPtr->dwStyle & WS_MINIMIZE )
1788 WINPOS_RedrawIconTitle( wndPtr->hwndSelf );
1789 else if (TWEAK_WineLook == WIN31_LOOK)
1790 NC_DoNCPaint( wndPtr, (HRGN32)1, FALSE );
1791 else
1792 NC_DoNCPaint95( wndPtr, (HRGN32)1, FALSE );
1794 return TRUE;
1798 /***********************************************************************
1799 * NC_HandleSetCursor
1801 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1803 LONG NC_HandleSetCursor( HWND32 hwnd, WPARAM16 wParam, LPARAM lParam )
1805 if (hwnd != (HWND32)wParam) return 0; /* Don't set the cursor for child windows */
1807 switch(LOWORD(lParam))
1809 case HTERROR:
1811 WORD msg = HIWORD( lParam );
1812 if ((msg == WM_LBUTTONDOWN) || (msg == WM_MBUTTONDOWN) ||
1813 (msg == WM_RBUTTONDOWN))
1814 MessageBeep32(0);
1816 break;
1818 case HTCLIENT:
1820 WND *wndPtr;
1821 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) break;
1822 if (wndPtr->class->hCursor)
1824 SetCursor16( wndPtr->class->hCursor );
1825 return TRUE;
1827 else return FALSE;
1830 case HTLEFT:
1831 case HTRIGHT:
1832 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZEWE16 ) );
1834 case HTTOP:
1835 case HTBOTTOM:
1836 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENS16 ) );
1838 case HTTOPLEFT:
1839 case HTBOTTOMRIGHT:
1840 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENWSE16 ) );
1842 case HTTOPRIGHT:
1843 case HTBOTTOMLEFT:
1844 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENESW16 ) );
1847 /* Default cursor: arrow */
1848 return (LONG)SetCursor16( LoadCursor16( 0, IDC_ARROW16 ) );
1851 /***********************************************************************
1852 * NC_GetSysPopupPos
1854 BOOL32 NC_GetSysPopupPos( WND* wndPtr, RECT32* rect )
1856 if( wndPtr->hSysMenu )
1858 if( wndPtr->dwStyle & WS_MINIMIZE )
1859 GetWindowRect32( wndPtr->hwndSelf, rect );
1860 else
1862 if (TWEAK_WineLook == WIN31_LOOK)
1863 NC_GetInsideRect( wndPtr->hwndSelf, rect );
1864 else
1865 NC_GetInsideRect95( wndPtr->hwndSelf, rect );
1866 OffsetRect32( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
1867 if (wndPtr->dwStyle & WS_CHILD)
1868 ClientToScreen32( wndPtr->parent->hwndSelf, (POINT32 *)rect );
1869 if (TWEAK_WineLook == WIN31_LOOK) {
1870 rect->right = rect->left + SYSMETRICS_CXSIZE;
1871 rect->bottom = rect->top + SYSMETRICS_CYSIZE;
1873 else {
1874 rect->right = rect->left + sysMetrics[SM_CYCAPTION] - 1;
1875 rect->bottom = rect->top + sysMetrics[SM_CYCAPTION] - 1;
1878 return TRUE;
1880 return FALSE;
1883 /***********************************************************************
1884 * NC_StartSizeMove
1886 * Initialisation of a move or resize, when initiatied from a menu choice.
1887 * Return hit test code for caption or sizing border.
1889 static LONG NC_StartSizeMove( WND* wndPtr, WPARAM16 wParam,
1890 POINT16 *capturePoint )
1892 LONG hittest = 0;
1893 POINT16 pt;
1894 MSG16 msg;
1896 if ((wParam & 0xfff0) == SC_MOVE)
1898 /* Move pointer at the center of the caption */
1899 RECT32 rect;
1900 if (TWEAK_WineLook == WIN31_LOOK)
1901 NC_GetInsideRect( wndPtr->hwndSelf, &rect );
1902 else
1903 NC_GetInsideRect95( wndPtr->hwndSelf, &rect );
1904 if (wndPtr->dwStyle & WS_SYSMENU)
1905 rect.left += SYSMETRICS_CXSIZE + 1;
1906 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
1907 rect.right -= SYSMETRICS_CXSIZE + 1;
1908 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
1909 rect.right -= SYSMETRICS_CXSIZE + 1;
1910 pt.x = wndPtr->rectWindow.left + (rect.right - rect.left) / 2;
1911 pt.y = wndPtr->rectWindow.top + rect.top + SYSMETRICS_CYSIZE/2;
1912 hittest = HTCAPTION;
1913 *capturePoint = pt;
1915 else /* SC_SIZE */
1917 while(!hittest)
1919 MSG_InternalGetMessage( &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE );
1920 switch(msg.message)
1922 case WM_MOUSEMOVE:
1923 hittest = NC_HandleNCHitTest( wndPtr->hwndSelf, msg.pt );
1924 pt = msg.pt;
1925 if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
1926 hittest = 0;
1927 break;
1929 case WM_LBUTTONUP:
1930 return 0;
1932 case WM_KEYDOWN:
1933 switch(msg.wParam)
1935 case VK_UP:
1936 hittest = HTTOP;
1937 pt.x =(wndPtr->rectWindow.left+wndPtr->rectWindow.right)/2;
1938 pt.y = wndPtr->rectWindow.top + SYSMETRICS_CYFRAME / 2;
1939 break;
1940 case VK_DOWN:
1941 hittest = HTBOTTOM;
1942 pt.x =(wndPtr->rectWindow.left+wndPtr->rectWindow.right)/2;
1943 pt.y = wndPtr->rectWindow.bottom - SYSMETRICS_CYFRAME / 2;
1944 break;
1945 case VK_LEFT:
1946 hittest = HTLEFT;
1947 pt.x = wndPtr->rectWindow.left + SYSMETRICS_CXFRAME / 2;
1948 pt.y =(wndPtr->rectWindow.top+wndPtr->rectWindow.bottom)/2;
1949 break;
1950 case VK_RIGHT:
1951 hittest = HTRIGHT;
1952 pt.x = wndPtr->rectWindow.right - SYSMETRICS_CXFRAME / 2;
1953 pt.y =(wndPtr->rectWindow.top+wndPtr->rectWindow.bottom)/2;
1954 break;
1955 case VK_RETURN:
1956 case VK_ESCAPE: return 0;
1960 *capturePoint = pt;
1962 SetCursorPos32( pt.x, pt.y );
1963 NC_HandleSetCursor( wndPtr->hwndSelf,
1964 wndPtr->hwndSelf, MAKELONG( hittest, WM_MOUSEMOVE ));
1965 return hittest;
1969 /***********************************************************************
1970 * NC_DoSizeMove
1972 * Perform SC_MOVE and SC_SIZE commands.
1974 static void NC_DoSizeMove( HWND32 hwnd, WORD wParam )
1976 MSG16 msg;
1977 RECT32 sizingRect, mouseRect;
1978 HDC32 hdc;
1979 LONG hittest = (LONG)(wParam & 0x0f);
1980 HCURSOR16 hDragCursor = 0, hOldCursor = 0;
1981 POINT32 minTrack, maxTrack;
1982 POINT16 capturePoint, pt;
1983 WND * wndPtr = WIN_FindWndPtr( hwnd );
1984 BOOL32 thickframe = HAS_THICKFRAME( wndPtr->dwStyle );
1985 BOOL32 iconic = wndPtr->dwStyle & WS_MINIMIZE;
1986 BOOL32 moved = FALSE;
1987 DWORD dwPoint = GetMessagePos ();
1989 capturePoint = pt = *(POINT16*)&dwPoint;
1991 if (IsZoomed32(hwnd) || !IsWindowVisible32(hwnd) ||
1992 (wndPtr->flags & WIN_MANAGED)) return;
1994 if ((wParam & 0xfff0) == SC_MOVE)
1996 if (!(wndPtr->dwStyle & WS_CAPTION)) return;
1997 if (!hittest)
1998 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
1999 if (!hittest) return;
2001 else /* SC_SIZE */
2003 if (!thickframe) return;
2004 if ( hittest && hittest != HTSYSMENU ) hittest += 2;
2005 else
2007 SetCapture32(hwnd);
2008 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2009 if (!hittest)
2011 ReleaseCapture();
2012 return;
2017 /* Get min/max info */
2019 WINPOS_GetMinMaxInfo( wndPtr, NULL, NULL, &minTrack, &maxTrack );
2020 sizingRect = wndPtr->rectWindow;
2021 if (wndPtr->dwStyle & WS_CHILD)
2022 GetClientRect32( wndPtr->parent->hwndSelf, &mouseRect );
2023 else
2024 SetRect32(&mouseRect, 0, 0, SYSMETRICS_CXSCREEN, SYSMETRICS_CYSCREEN);
2025 if (ON_LEFT_BORDER(hittest))
2027 mouseRect.left = MAX( mouseRect.left, sizingRect.right-maxTrack.x );
2028 mouseRect.right = MIN( mouseRect.right, sizingRect.right-minTrack.x );
2030 else if (ON_RIGHT_BORDER(hittest))
2032 mouseRect.left = MAX( mouseRect.left, sizingRect.left+minTrack.x );
2033 mouseRect.right = MIN( mouseRect.right, sizingRect.left+maxTrack.x );
2035 if (ON_TOP_BORDER(hittest))
2037 mouseRect.top = MAX( mouseRect.top, sizingRect.bottom-maxTrack.y );
2038 mouseRect.bottom = MIN( mouseRect.bottom,sizingRect.bottom-minTrack.y);
2040 else if (ON_BOTTOM_BORDER(hittest))
2042 mouseRect.top = MAX( mouseRect.top, sizingRect.top+minTrack.y );
2043 mouseRect.bottom = MIN( mouseRect.bottom, sizingRect.top+maxTrack.y );
2045 if (wndPtr->dwStyle & WS_CHILD)
2047 MapWindowPoints32( wndPtr->parent->hwndSelf, 0,
2048 (LPPOINT32)&mouseRect, 2 );
2050 SendMessage16( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
2052 if (GetCapture32() != hwnd) SetCapture32( hwnd );
2054 if (wndPtr->dwStyle & WS_CHILD)
2056 /* Retrieve a default cache DC (without using the window style) */
2057 hdc = GetDCEx32( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
2059 else
2060 { /* Grab the server only when moving top-level windows without desktop */
2061 hdc = GetDC32( 0 );
2064 wndPtr->pDriver->pPreSizeMove(wndPtr);
2066 if( iconic ) /* create a cursor for dragging */
2068 HICON16 hIcon = (wndPtr->class->hIcon) ? wndPtr->class->hIcon
2069 : (HICON16)SendMessage16( hwnd, WM_QUERYDRAGICON, 0, 0L);
2070 if( hIcon ) hDragCursor = CURSORICON_IconToCursor( hIcon, TRUE );
2071 if( !hDragCursor ) iconic = FALSE;
2074 if( !iconic ) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2076 while(1)
2078 int dx = 0, dy = 0;
2080 MSG_InternalGetMessage( &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE );
2082 /* Exit on button-up, Return, or Esc */
2083 if ((msg.message == WM_LBUTTONUP) ||
2084 ((msg.message == WM_KEYDOWN) &&
2085 ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
2087 if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
2088 continue; /* We are not interested in other messages */
2090 dwPoint = GetMessagePos ();
2091 pt = *(POINT16*)&dwPoint;
2093 if (msg.message == WM_KEYDOWN) switch(msg.wParam)
2095 case VK_UP: pt.y -= 8; break;
2096 case VK_DOWN: pt.y += 8; break;
2097 case VK_LEFT: pt.x -= 8; break;
2098 case VK_RIGHT: pt.x += 8; break;
2101 pt.x = MAX( pt.x, mouseRect.left );
2102 pt.x = MIN( pt.x, mouseRect.right );
2103 pt.y = MAX( pt.y, mouseRect.top );
2104 pt.y = MIN( pt.y, mouseRect.bottom );
2106 dx = pt.x - capturePoint.x;
2107 dy = pt.y - capturePoint.y;
2109 if (dx || dy)
2111 if( !moved )
2113 moved = TRUE;
2114 if( iconic ) /* ok, no system popup tracking */
2116 hOldCursor = SetCursor32(hDragCursor);
2117 ShowCursor32( TRUE );
2118 WINPOS_ShowIconTitle( wndPtr, FALSE );
2122 if (msg.message == WM_KEYDOWN) SetCursorPos32( pt.x, pt.y );
2123 else
2125 RECT32 newRect = sizingRect;
2127 if (hittest == HTCAPTION) OffsetRect32( &newRect, dx, dy );
2128 if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
2129 else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
2130 if (ON_TOP_BORDER(hittest)) newRect.top += dy;
2131 else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
2132 if( !iconic )
2134 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2135 NC_DrawMovingFrame( hdc, &newRect, thickframe );
2137 capturePoint = pt;
2138 sizingRect = newRect;
2143 ReleaseCapture();
2144 if( iconic )
2146 if( moved ) /* restore cursors, show icon title later on */
2148 ShowCursor32( FALSE );
2149 SetCursor32( hOldCursor );
2151 DestroyCursor32( hDragCursor );
2153 else
2154 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2156 if (wndPtr->dwStyle & WS_CHILD)
2157 ReleaseDC32( wndPtr->parent->hwndSelf, hdc );
2158 else
2160 ReleaseDC32( 0, hdc );
2163 wndPtr->pDriver->pPostSizeMove(wndPtr);
2165 if (HOOK_IsHooked( WH_CBT ))
2167 RECT16* pr = SEGPTR_NEW(RECT16);
2168 if( pr )
2170 CONV_RECT32TO16( &sizingRect, pr );
2171 if( HOOK_CallHooks16( WH_CBT, HCBT_MOVESIZE, hwnd,
2172 (LPARAM)SEGPTR_GET(pr)) )
2173 sizingRect = wndPtr->rectWindow;
2174 else
2175 CONV_RECT16TO32( pr, &sizingRect );
2176 SEGPTR_FREE(pr);
2179 SendMessage16( hwnd, WM_EXITSIZEMOVE, 0, 0 );
2180 SendMessage16( hwnd, WM_SETVISIBLE, !IsIconic16(hwnd), 0L);
2182 if( moved && !((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
2184 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
2185 SetWindowPos32( hwnd, 0, sizingRect.left, sizingRect.top,
2186 sizingRect.right - sizingRect.left,
2187 sizingRect.bottom - sizingRect.top,
2188 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
2191 if( IsWindow32(hwnd) )
2192 if( wndPtr->dwStyle & WS_MINIMIZE )
2194 /* Single click brings up the system menu when iconized */
2196 if( !moved )
2198 if( wndPtr->dwStyle & WS_SYSMENU )
2199 SendMessage16( hwnd, WM_SYSCOMMAND,
2200 SC_MOUSEMENU + HTSYSMENU, *((LPARAM*)&pt));
2202 else WINPOS_ShowIconTitle( wndPtr, TRUE );
2207 /***********************************************************************
2208 * NC_TrackMinMaxBox
2210 * Track a mouse button press on the minimize or maximize box.
2212 static void NC_TrackMinMaxBox( HWND32 hwnd, WORD wParam )
2214 MSG16 msg;
2215 HDC32 hdc = GetWindowDC32( hwnd );
2216 BOOL32 pressed = TRUE;
2217 void (*paintButton)(HWND32, HDC16, BOOL32);
2219 SetCapture32( hwnd );
2220 if (wParam == HTMINBUTTON)
2221 paintButton =
2222 (TWEAK_WineLook == WIN31_LOOK) ? &NC_DrawMinButton : &NC_DrawMinButton95;
2223 else
2224 paintButton =
2225 (TWEAK_WineLook == WIN31_LOOK) ? &NC_DrawMaxButton : &NC_DrawMaxButton95;
2227 (*paintButton)( hwnd, hdc, TRUE );
2231 BOOL32 oldstate = pressed;
2232 MSG_InternalGetMessage( &msg, 0, 0, 0, PM_REMOVE, FALSE );
2234 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
2235 if (pressed != oldstate)
2236 (*paintButton)( hwnd, hdc, pressed );
2237 } while (msg.message != WM_LBUTTONUP);
2239 (*paintButton)( hwnd, hdc, FALSE );
2241 ReleaseCapture();
2242 ReleaseDC32( hwnd, hdc );
2243 if (!pressed) return;
2245 if (wParam == HTMINBUTTON)
2246 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&msg.pt );
2247 else
2248 SendMessage16( hwnd, WM_SYSCOMMAND,
2249 IsZoomed32(hwnd) ? SC_RESTORE:SC_MAXIMIZE, *(LONG*)&msg.pt );
2253 /***********************************************************************
2254 * NC_TrackCloseButton95
2256 * Track a mouse button press on the Win95 close button.
2258 static void
2259 NC_TrackCloseButton95 (HWND32 hwnd, WORD wParam)
2261 MSG16 msg;
2262 HDC32 hdc = GetWindowDC32( hwnd );
2263 BOOL32 pressed = TRUE;
2265 SetCapture32( hwnd );
2267 NC_DrawCloseButton95 (hwnd, hdc, TRUE);
2271 BOOL32 oldstate = pressed;
2272 MSG_InternalGetMessage( &msg, 0, 0, 0, PM_REMOVE, FALSE );
2274 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
2275 if (pressed != oldstate)
2276 NC_DrawCloseButton95 (hwnd, hdc, pressed);
2277 } while (msg.message != WM_LBUTTONUP);
2279 NC_DrawCloseButton95 (hwnd, hdc, FALSE);
2281 ReleaseCapture();
2282 ReleaseDC32( hwnd, hdc );
2283 if (!pressed) return;
2285 SendMessage16( hwnd, WM_SYSCOMMAND, SC_CLOSE, *(LONG*)&msg.pt );
2289 /***********************************************************************
2290 * NC_TrackScrollBar
2292 * Track a mouse button press on the horizontal or vertical scroll-bar.
2294 static void NC_TrackScrollBar( HWND32 hwnd, WPARAM32 wParam, POINT32 pt )
2296 MSG16 *msg;
2297 INT32 scrollbar;
2298 WND *wndPtr = WIN_FindWndPtr( hwnd );
2300 if ((wParam & 0xfff0) == SC_HSCROLL)
2302 if ((wParam & 0x0f) != HTHSCROLL) return;
2303 scrollbar = SB_HORZ;
2305 else /* SC_VSCROLL */
2307 if ((wParam & 0x0f) != HTVSCROLL) return;
2308 scrollbar = SB_VERT;
2311 if (!(msg = SEGPTR_NEW(MSG16))) return;
2312 pt.x -= wndPtr->rectWindow.left;
2313 pt.y -= wndPtr->rectWindow.top;
2314 SetCapture32( hwnd );
2315 SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt );
2319 GetMessage16( SEGPTR_GET(msg), 0, 0, 0 );
2320 switch(msg->message)
2322 case WM_LBUTTONUP:
2323 case WM_MOUSEMOVE:
2324 case WM_SYSTIMER:
2325 pt.x = LOWORD(msg->lParam) + wndPtr->rectClient.left -
2326 wndPtr->rectWindow.left;
2327 pt.y = HIWORD(msg->lParam) + wndPtr->rectClient.top -
2328 wndPtr->rectWindow.top;
2329 SCROLL_HandleScrollEvent( hwnd, scrollbar, msg->message, pt );
2330 break;
2331 default:
2332 TranslateMessage16( msg );
2333 DispatchMessage16( msg );
2334 break;
2336 if (!IsWindow32( hwnd ))
2338 ReleaseCapture();
2339 break;
2341 } while (msg->message != WM_LBUTTONUP);
2342 SEGPTR_FREE(msg);
2345 /***********************************************************************
2346 * NC_HandleNCLButtonDown
2348 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2350 LONG NC_HandleNCLButtonDown( WND* pWnd, WPARAM16 wParam, LPARAM lParam )
2352 HWND32 hwnd = pWnd->hwndSelf;
2354 switch(wParam) /* Hit test */
2356 case HTCAPTION:
2357 hwnd = WIN_GetTopParent(hwnd);
2359 if( WINPOS_SetActiveWindow(hwnd, TRUE, TRUE) || (GetActiveWindow32() == hwnd) )
2360 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
2361 break;
2363 case HTSYSMENU:
2364 if( pWnd->dwStyle & WS_SYSMENU )
2366 if( !(pWnd->dwStyle & WS_MINIMIZE) )
2368 HDC32 hDC = GetWindowDC32(hwnd);
2369 if (TWEAK_WineLook == WIN31_LOOK)
2370 NC_DrawSysButton( hwnd, hDC, TRUE );
2371 else
2372 NC_DrawSysButton95( hwnd, hDC, TRUE );
2373 ReleaseDC32( hwnd, hDC );
2375 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
2377 break;
2379 case HTMENU:
2380 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam );
2381 break;
2383 case HTHSCROLL:
2384 SendMessage16( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
2385 break;
2387 case HTVSCROLL:
2388 SendMessage16( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
2389 break;
2391 case HTMINBUTTON:
2392 case HTMAXBUTTON:
2393 NC_TrackMinMaxBox( hwnd, wParam );
2394 break;
2396 case HTCLOSE:
2397 if (TWEAK_WineLook >= WIN95_LOOK)
2398 NC_TrackCloseButton95 (hwnd, wParam);
2399 break;
2401 case HTLEFT:
2402 case HTRIGHT:
2403 case HTTOP:
2404 case HTTOPLEFT:
2405 case HTTOPRIGHT:
2406 case HTBOTTOM:
2407 case HTBOTTOMLEFT:
2408 case HTBOTTOMRIGHT:
2409 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2410 SendMessage16( hwnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam);
2411 break;
2413 case HTBORDER:
2414 break;
2416 return 0;
2420 /***********************************************************************
2421 * NC_HandleNCLButtonDblClk
2423 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2425 LONG NC_HandleNCLButtonDblClk( WND *pWnd, WPARAM16 wParam, LPARAM lParam )
2428 * if this is an icon, send a restore since we are handling
2429 * a double click
2431 if (pWnd->dwStyle & WS_MINIMIZE)
2433 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_RESTORE, lParam );
2434 return 0;
2437 switch(wParam) /* Hit test */
2439 case HTCAPTION:
2440 /* stop processing if WS_MAXIMIZEBOX is missing */
2441 if (pWnd->dwStyle & WS_MAXIMIZEBOX)
2442 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND,
2443 (pWnd->dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
2444 lParam );
2445 break;
2447 case HTSYSMENU:
2448 if (!(pWnd->class->style & CS_NOCLOSE))
2449 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, lParam );
2450 break;
2452 case HTHSCROLL:
2453 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL,
2454 lParam );
2455 break;
2457 case HTVSCROLL:
2458 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL,
2459 lParam );
2460 break;
2462 return 0;
2466 /***********************************************************************
2467 * NC_HandleSysCommand
2469 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2471 LONG NC_HandleSysCommand( HWND32 hwnd, WPARAM16 wParam, POINT16 pt )
2473 WND *wndPtr = WIN_FindWndPtr( hwnd );
2474 POINT32 pt32;
2475 UINT16 uCommand = wParam & 0xFFF0;
2477 TRACE(nonclient, "Handling WM_SYSCOMMAND %x %d,%d\n",
2478 wParam, pt.x, pt.y );
2480 if (wndPtr->dwStyle & WS_CHILD && uCommand != SC_KEYMENU )
2481 ScreenToClient16( wndPtr->parent->hwndSelf, &pt );
2483 switch (uCommand)
2485 case SC_SIZE:
2486 case SC_MOVE:
2487 NC_DoSizeMove( hwnd, wParam );
2488 break;
2490 case SC_MINIMIZE:
2491 ShowWindow32( hwnd, SW_MINIMIZE );
2492 break;
2494 case SC_MAXIMIZE:
2495 ShowWindow32( hwnd, SW_MAXIMIZE );
2496 break;
2498 case SC_RESTORE:
2499 ShowWindow32( hwnd, SW_RESTORE );
2500 break;
2502 case SC_CLOSE:
2503 return SendMessage16( hwnd, WM_CLOSE, 0, 0 );
2505 case SC_VSCROLL:
2506 case SC_HSCROLL:
2507 CONV_POINT16TO32( &pt, &pt32 );
2508 NC_TrackScrollBar( hwnd, wParam, pt32 );
2509 break;
2511 case SC_MOUSEMENU:
2512 CONV_POINT16TO32( &pt, &pt32 );
2513 MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt32 );
2514 break;
2516 case SC_KEYMENU:
2517 MENU_TrackKbdMenuBar( wndPtr , wParam , pt.x );
2518 break;
2520 case SC_TASKLIST:
2521 WinExec32( "taskman.exe", SW_SHOWNORMAL );
2522 break;
2524 case SC_SCREENSAVE:
2525 if (wParam == SC_ABOUTWINE)
2526 ShellAbout32A(hwnd,"Wine", WINE_RELEASE_INFO, 0);
2527 else
2528 if (wParam == SC_PUTMARK)
2529 TRACE(shell,"Mark requested by user\n");
2530 break;
2532 case SC_HOTKEY:
2533 case SC_ARRANGE:
2534 case SC_NEXTWINDOW:
2535 case SC_PREVWINDOW:
2536 FIXME (nonclient, "unimplemented!\n");
2537 break;
2539 return 0;