Added autoconf check for "inline". You can now use it, it will be
[wine/dcerpc.git] / windows / nonclient.c
blobfa8a0d753517bf8d4def7fe032426e5711de6780
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 "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 "debug.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_BORDER)))
50 #define HAS_THICKFRAME(style) \
51 (((style) & WS_THICKFRAME) && \
52 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
54 #define HAS_FIXEDFRAME(style,exStyle) \
55 (((((exStyle) & WS_EX_DLGMODALFRAME) || \
56 ((style) & WS_DLGFRAME)) && ((style) & WS_BORDER)) && \
57 !((style) & WS_THICKFRAME))
59 #define HAS_SIZEFRAME(style) \
60 (((style) & WS_THICKFRAME) && \
61 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
63 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
65 #define ON_LEFT_BORDER(hit) \
66 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
67 #define ON_RIGHT_BORDER(hit) \
68 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
69 #define ON_TOP_BORDER(hit) \
70 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
71 #define ON_BOTTOM_BORDER(hit) \
72 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
74 /***********************************************************************
75 * NC_AdjustRect
77 * Compute the size of the window rectangle from the size of the
78 * client rectangle.
80 static void NC_AdjustRect( LPRECT16 rect, DWORD style, BOOL menu,
81 DWORD exStyle )
83 if (TWEAK_WineLook > WIN31_LOOK)
84 ERR(nonclient, "Called in Win95 mode. Aiee! Please report this.\n" );
86 if(style & WS_ICONIC) return;
87 /* Decide if the window will be managed (see CreateWindowEx) */
88 if (!(Options.managed && !(style & WS_CHILD) &&
89 ((style & (WS_DLGFRAME | WS_THICKFRAME)) ||
90 (exStyle & WS_EX_DLGMODALFRAME))))
92 if (HAS_DLGFRAME( style, exStyle ))
93 InflateRect16(rect, SYSMETRICS_CXDLGFRAME, SYSMETRICS_CYDLGFRAME );
94 else
96 if (HAS_THICKFRAME(style))
97 InflateRect16( rect, SYSMETRICS_CXFRAME, SYSMETRICS_CYFRAME );
98 if (style & WS_BORDER)
99 InflateRect16( rect, SYSMETRICS_CXBORDER, SYSMETRICS_CYBORDER);
102 if ((style & WS_CAPTION) == WS_CAPTION)
103 rect->top -= SYSMETRICS_CYCAPTION - SYSMETRICS_CYBORDER;
105 if (menu) rect->top -= SYSMETRICS_CYMENU + SYSMETRICS_CYBORDER;
107 if (style & WS_VSCROLL) {
108 rect->right += SYSMETRICS_CXVSCROLL - 1;
109 if(!(style & WS_BORDER))
110 rect->right++;
113 if (style & WS_HSCROLL) {
114 rect->bottom += SYSMETRICS_CYHSCROLL - 1;
115 if(!(style & WS_BORDER))
116 rect->bottom++;
121 /******************************************************************************
122 * NC_AdjustRectOuter95
124 * Computes the size of the "outside" parts of the window based on the
125 * parameters of the client area.
127 + PARAMS
128 * LPRECT16 rect
129 * DWORD style
130 * BOOL32 menu
131 * DWORD exStyle
133 * NOTES
134 * "Outer" parts of a window means the whole window frame, caption and
135 * menu bar. It does not include "inner" parts of the frame like client
136 * edge, static edge or scroll bars.
138 * Revision history
139 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
140 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
142 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
143 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
144 * NC_AdjustRectInner95 and added handling of Win95 styles.
146 *****************************************************************************/
148 static void
149 NC_AdjustRectOuter95 (LPRECT16 rect, DWORD style, BOOL menu, DWORD exStyle)
151 if(style & WS_ICONIC) return;
153 /* Decide if the window will be managed (see CreateWindowEx) */
154 if (!(Options.managed && !(style & WS_CHILD) &&
155 ((style & (WS_DLGFRAME | WS_THICKFRAME)) ||
156 (exStyle & WS_EX_DLGMODALFRAME))))
158 if (HAS_FIXEDFRAME( style, exStyle ))
159 InflateRect16(rect, SYSMETRICS_CXDLGFRAME, SYSMETRICS_CYDLGFRAME );
160 else
162 if (HAS_SIZEFRAME(style))
163 InflateRect16( rect, SYSMETRICS_CXFRAME, SYSMETRICS_CYFRAME );
164 #if 0
165 if (style & WS_BORDER)
166 InflateRect16( rect, SYSMETRICS_CXBORDER, SYSMETRICS_CYBORDER);
167 #endif
170 if ((style & WS_CAPTION) == WS_CAPTION)
172 if (exStyle & WS_EX_TOOLWINDOW)
173 rect->top -= SYSMETRICS_CYSMCAPTION;
174 else
175 rect->top -= SYSMETRICS_CYCAPTION;
179 if (menu)
180 rect->top -= sysMetrics[SM_CYMENU];
184 /******************************************************************************
185 * NC_AdjustRectInner95
187 * Computes the size of the "inside" part of the window based on the
188 * parameters of the client area.
190 + PARAMS
191 * LPRECT16 rect
192 * DWORD style
193 * DWORD exStyle
195 * NOTES
196 * "Inner" part of a window means the window frame inside of the flat
197 * window frame. It includes the client edge, the static edge and the
198 * scroll bars.
200 * Revision history
201 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
202 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
204 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
205 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
206 * NC_AdjustRectInner95 and added handling of Win95 styles.
208 *****************************************************************************/
210 static void
211 NC_AdjustRectInner95 (LPRECT16 rect, DWORD style, DWORD exStyle)
213 if(style & WS_ICONIC) return;
215 if (exStyle & WS_EX_CLIENTEDGE)
216 InflateRect16 (rect, sysMetrics[SM_CXEDGE], sysMetrics[SM_CYEDGE]);
218 if (exStyle & WS_EX_STATICEDGE)
219 InflateRect16 (rect, sysMetrics[SM_CXBORDER], sysMetrics[SM_CYBORDER]);
221 if (style & WS_VSCROLL) rect->right += SYSMETRICS_CXVSCROLL;
222 if (style & WS_HSCROLL) rect->bottom += SYSMETRICS_CYHSCROLL;
226 /***********************************************************************
227 * DrawCaption16 [USER.660] Draws a caption bar
229 * PARAMS
230 * hwnd [I]
231 * hdc [I]
232 * lpRect [I]
233 * uFlags [I]
235 * RETURNS
236 * Success:
237 * Failure:
240 BOOL16 WINAPI
241 DrawCaption16 (HWND16 hwnd, HDC16 hdc, const RECT16 *rect, UINT16 uFlags)
243 RECT rect32;
245 if (rect)
246 CONV_RECT16TO32 (rect, &rect32);
248 return (BOOL16)DrawCaptionTempA (hwnd, hdc, rect ? &rect32 : NULL,
249 0, 0, NULL, uFlags & 0x1F);
253 /***********************************************************************
254 * DrawCaption32 [USER32.154] Draws a caption bar
256 * PARAMS
257 * hwnd [I]
258 * hdc [I]
259 * lpRect [I]
260 * uFlags [I]
262 * RETURNS
263 * Success:
264 * Failure:
267 BOOL WINAPI
268 DrawCaption (HWND hwnd, HDC hdc, const RECT *lpRect, UINT uFlags)
270 return DrawCaptionTempA (hwnd, hdc, lpRect, 0, 0, NULL, uFlags & 0x1F);
274 /***********************************************************************
275 * DrawCaptionTemp16 [USER.657]
277 * PARAMS
279 * RETURNS
280 * Success:
281 * Failure:
284 BOOL16 WINAPI
285 DrawCaptionTemp16 (HWND16 hwnd, HDC16 hdc, const RECT16 *rect, HFONT16 hFont,
286 HICON16 hIcon, LPCSTR str, UINT16 uFlags)
288 RECT rect32;
290 if (rect)
291 CONV_RECT16TO32(rect,&rect32);
293 return (BOOL16)DrawCaptionTempA (hwnd, hdc, rect?&rect32:NULL, hFont,
294 hIcon, str, uFlags & 0x1F);
298 /***********************************************************************
299 * DrawCaptionTemp32A [USER32.599]
301 * PARAMS
303 * RETURNS
304 * Success:
305 * Failure:
308 BOOL WINAPI
309 DrawCaptionTempA (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
310 HICON hIcon, LPCSTR str, UINT uFlags)
312 RECT rc = *rect;
314 TRACE (nonclient, "(%08x,%08x,%p,%08x,%08x,\"%s\",%08x)\n",
315 hwnd, hdc, rect, hFont, hIcon, str, uFlags);
317 /* drawing background */
318 if (uFlags & DC_INBUTTON) {
319 FillRect (hdc, &rc, GetSysColorBrush (COLOR_3DFACE));
321 if (uFlags & DC_ACTIVE) {
322 HBRUSH hbr = SelectObject (hdc, CACHE_GetPattern55AABrush ());
323 PatBlt (hdc, rc.left, rc.top,
324 rc.right-rc.left, rc.bottom-rc.top, 0xFA0089);
325 SelectObject (hdc, hbr);
328 else {
329 FillRect (hdc, &rc, GetSysColorBrush ((uFlags & DC_ACTIVE) ?
330 COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
334 /* drawing icon */
335 if ((uFlags & DC_ICON) && !(uFlags & DC_SMALLCAP)) {
336 POINT pt;
338 pt.x = rc.left + 2;
339 pt.y = (rc.bottom + rc.top - sysMetrics[SM_CYSMICON]) / 2;
341 if (hIcon) {
342 DrawIconEx (hdc, pt.x, pt.y, hIcon, sysMetrics[SM_CXSMICON],
343 sysMetrics[SM_CYSMICON], 0, 0, DI_NORMAL);
345 else {
346 WND *wndPtr = WIN_FindWndPtr(hwnd);
347 HICON hAppIcon = 0;
349 if (wndPtr->class->hIconSm)
350 hAppIcon = wndPtr->class->hIconSm;
351 else if (wndPtr->class->hIcon)
352 hAppIcon = wndPtr->class->hIcon;
354 DrawIconEx (hdc, pt.x, pt.y, hAppIcon, sysMetrics[SM_CXSMICON],
355 sysMetrics[SM_CYSMICON], 0, 0, DI_NORMAL);
356 WIN_ReleaseWndPtr(wndPtr);
359 rc.left += (rc.bottom - rc.top);
362 /* drawing text */
363 if (uFlags & DC_TEXT) {
364 HFONT hOldFont;
366 if (uFlags & DC_INBUTTON)
367 SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
368 else if (uFlags & DC_ACTIVE)
369 SetTextColor (hdc, GetSysColor (COLOR_CAPTIONTEXT));
370 else
371 SetTextColor (hdc, GetSysColor (COLOR_INACTIVECAPTIONTEXT));
373 SetBkMode (hdc, TRANSPARENT);
375 if (hFont)
376 hOldFont = SelectObject (hdc, hFont);
377 else {
378 NONCLIENTMETRICSA nclm;
379 HFONT hNewFont;
380 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
381 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
382 hNewFont = CreateFontIndirectA ((uFlags & DC_SMALLCAP) ?
383 &nclm.lfSmCaptionFont : &nclm.lfCaptionFont);
384 hOldFont = SelectObject (hdc, hNewFont);
387 if (str)
388 DrawTextA (hdc, str, -1, &rc,
389 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
390 else {
391 CHAR szText[128];
392 INT nLen;
393 nLen = GetWindowTextA (hwnd, szText, 128);
394 DrawTextA (hdc, szText, nLen, &rc,
395 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
398 if (hFont)
399 SelectObject (hdc, hOldFont);
400 else
401 DeleteObject (SelectObject (hdc, hOldFont));
404 /* drawing focus ??? */
405 if (uFlags & 0x2000)
406 FIXME (nonclient, "undocumented flag (0x2000)!\n");
408 return 0;
412 /***********************************************************************
413 * DrawCaptionTemp32W [USER32.602]
415 * PARAMS
417 * RETURNS
418 * Success:
419 * Failure:
422 BOOL WINAPI
423 DrawCaptionTempW (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
424 HICON hIcon, LPCWSTR str, UINT uFlags)
426 LPSTR p = HEAP_strdupWtoA (GetProcessHeap (), 0, str);
427 BOOL res = DrawCaptionTempA (hwnd, hdc, rect, hFont, hIcon, p, uFlags);
428 HeapFree (GetProcessHeap (), 0, p);
429 return res;
433 /***********************************************************************
434 * AdjustWindowRect16 (USER.102)
436 BOOL16 WINAPI AdjustWindowRect16( LPRECT16 rect, DWORD style, BOOL16 menu )
438 return AdjustWindowRectEx16( rect, style, menu, 0 );
442 /***********************************************************************
443 * AdjustWindowRect32 (USER32.2)
445 BOOL WINAPI AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu )
447 return AdjustWindowRectEx( rect, style, menu, 0 );
451 /***********************************************************************
452 * AdjustWindowRectEx16 (USER.454)
454 BOOL16 WINAPI AdjustWindowRectEx16( LPRECT16 rect, DWORD style,
455 BOOL16 menu, DWORD exStyle )
457 /* Correct the window style */
459 if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
460 style |= WS_CAPTION;
461 style &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD);
462 exStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE |
463 WS_EX_STATICEDGE | WS_EX_TOOLWINDOW);
464 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
466 TRACE(nonclient, "(%d,%d)-(%d,%d) %08lx %d %08lx\n",
467 rect->left, rect->top, rect->right, rect->bottom,
468 style, menu, exStyle );
470 if (TWEAK_WineLook == WIN31_LOOK)
471 NC_AdjustRect( rect, style, menu, exStyle );
472 else {
473 NC_AdjustRectOuter95( rect, style, menu, exStyle );
474 NC_AdjustRectInner95( rect, style, exStyle );
477 return TRUE;
481 /***********************************************************************
482 * AdjustWindowRectEx32 (USER32.3)
484 BOOL WINAPI AdjustWindowRectEx( LPRECT rect, DWORD style,
485 BOOL menu, DWORD exStyle )
487 RECT16 rect16;
488 BOOL ret;
490 CONV_RECT32TO16( rect, &rect16 );
491 ret = AdjustWindowRectEx16( &rect16, style, (BOOL16)menu, exStyle );
492 CONV_RECT16TO32( &rect16, rect );
493 return ret;
497 /***********************************************************************
498 * NC_HandleNCCalcSize
500 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
502 LONG NC_HandleNCCalcSize( WND *pWnd, RECT *winRect )
504 RECT16 tmpRect = { 0, 0, 0, 0 };
505 LONG result = 0;
507 if (pWnd->class->style & CS_VREDRAW) result |= WVR_VREDRAW;
508 if (pWnd->class->style & CS_HREDRAW) result |= WVR_HREDRAW;
510 if( !( pWnd->dwStyle & WS_MINIMIZE ) ) {
511 if (TWEAK_WineLook == WIN31_LOOK)
512 NC_AdjustRect( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
513 else
514 NC_AdjustRectOuter95( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
516 winRect->left -= tmpRect.left;
517 winRect->top -= tmpRect.top;
518 winRect->right -= tmpRect.right;
519 winRect->bottom -= tmpRect.bottom;
521 if (HAS_MENU(pWnd)) {
522 TRACE(nonclient, "Calling "
523 "GetMenuBarHeight with HWND 0x%x, width %d, "
524 "at (%d, %d).\n", pWnd->hwndSelf,
525 winRect->right - winRect->left,
526 -tmpRect.left, -tmpRect.top );
528 winRect->top +=
529 MENU_GetMenuBarHeight( pWnd->hwndSelf,
530 winRect->right - winRect->left,
531 -tmpRect.left, -tmpRect.top ) + 1;
534 if (TWEAK_WineLook > WIN31_LOOK) {
535 SetRect16 (&tmpRect, 0, 0, 0, 0);
536 NC_AdjustRectInner95 (&tmpRect, pWnd->dwStyle, pWnd->dwExStyle);
537 winRect->left -= tmpRect.left;
538 winRect->top -= tmpRect.top;
539 winRect->right -= tmpRect.right;
540 winRect->bottom -= tmpRect.bottom;
543 return result;
547 /***********************************************************************
548 * NC_GetInsideRect
550 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
551 * but without the borders (if any).
552 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
554 static void NC_GetInsideRect( HWND hwnd, RECT *rect )
556 WND * wndPtr = WIN_FindWndPtr( hwnd );
558 rect->top = rect->left = 0;
559 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
560 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
562 if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) goto END;
564 /* Remove frame from rectangle */
565 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
567 InflateRect( rect, -SYSMETRICS_CXDLGFRAME, -SYSMETRICS_CYDLGFRAME);
568 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
569 InflateRect( rect, -1, 0 );
571 else
573 if (HAS_THICKFRAME( wndPtr->dwStyle ))
574 InflateRect( rect, -SYSMETRICS_CXFRAME, -SYSMETRICS_CYFRAME );
575 if (wndPtr->dwStyle & WS_BORDER)
576 InflateRect( rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER );
578 END:
579 WIN_ReleaseWndPtr(wndPtr);
580 return;
584 /***********************************************************************
585 * NC_GetInsideRect95
587 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
588 * but without the borders (if any).
589 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
592 static void
593 NC_GetInsideRect95 (HWND hwnd, RECT *rect)
595 WND * wndPtr = WIN_FindWndPtr( hwnd );
597 rect->top = rect->left = 0;
598 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
599 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
601 if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) goto END;
603 /* Remove frame from rectangle */
604 if (HAS_FIXEDFRAME (wndPtr->dwStyle, wndPtr->dwExStyle ))
606 InflateRect( rect, -SYSMETRICS_CXFIXEDFRAME, -SYSMETRICS_CYFIXEDFRAME);
608 else if (HAS_SIZEFRAME (wndPtr->dwStyle))
610 InflateRect( rect, -SYSMETRICS_CXSIZEFRAME, -SYSMETRICS_CYSIZEFRAME );
612 /* if (wndPtr->dwStyle & WS_BORDER)
613 InflateRect32( rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER );*/
616 if (wndPtr->dwStyle & WS_CHILD) {
617 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
618 InflateRect (rect, -SYSMETRICS_CXEDGE, -SYSMETRICS_CYEDGE);
620 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
621 InflateRect (rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER);
623 END:
624 WIN_ReleaseWndPtr(wndPtr);
625 return;
629 /***********************************************************************
630 * NC_DoNCHitTest
632 * Handle a WM_NCHITTEST message. Called from NC_HandleNcHitTest().
635 LONG NC_DoNCHitTest (WND *wndPtr, POINT16 pt )
637 RECT16 rect;
639 TRACE(nonclient, "hwnd=%04x pt=%d,%d\n",
640 wndPtr->hwndSelf, pt.x, pt.y );
642 GetWindowRect16 (wndPtr->hwndSelf, &rect );
643 if (!PtInRect16( &rect, pt )) return HTNOWHERE;
645 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
647 if (!(wndPtr->flags & WIN_MANAGED))
649 /* Check borders */
650 if (HAS_THICKFRAME( wndPtr->dwStyle ))
652 InflateRect16( &rect, -SYSMETRICS_CXFRAME, -SYSMETRICS_CYFRAME );
653 if (wndPtr->dwStyle & WS_BORDER)
654 InflateRect16(&rect,-SYSMETRICS_CXBORDER,-SYSMETRICS_CYBORDER);
655 if (!PtInRect16( &rect, pt ))
657 /* Check top sizing border */
658 if (pt.y < rect.top)
660 if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTTOPLEFT;
661 if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTTOPRIGHT;
662 return HTTOP;
664 /* Check bottom sizing border */
665 if (pt.y >= rect.bottom)
667 if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTBOTTOMLEFT;
668 if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTBOTTOMRIGHT;
669 return HTBOTTOM;
671 /* Check left sizing border */
672 if (pt.x < rect.left)
674 if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPLEFT;
675 if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMLEFT;
676 return HTLEFT;
678 /* Check right sizing border */
679 if (pt.x >= rect.right)
681 if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPRIGHT;
682 if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMRIGHT;
683 return HTRIGHT;
687 else /* No thick frame */
689 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
690 InflateRect16(&rect, -SYSMETRICS_CXDLGFRAME, -SYSMETRICS_CYDLGFRAME);
691 else if (wndPtr->dwStyle & WS_BORDER)
692 InflateRect16(&rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER);
693 if (!PtInRect16( &rect, pt )) return HTBORDER;
696 /* Check caption */
698 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
700 rect.top += sysMetrics[SM_CYCAPTION] - 1;
701 if (!PtInRect16( &rect, pt ))
703 /* Check system menu */
704 if (wndPtr->dwStyle & WS_SYSMENU)
705 rect.left += SYSMETRICS_CXSIZE;
706 if (pt.x <= rect.left) return HTSYSMENU;
707 /* Check maximize box */
708 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
709 rect.right -= SYSMETRICS_CXSIZE + 1;
710 if (pt.x >= rect.right) return HTMAXBUTTON;
711 /* Check minimize box */
712 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
713 rect.right -= SYSMETRICS_CXSIZE + 1;
714 if (pt.x >= rect.right) return HTMINBUTTON;
715 return HTCAPTION;
720 /* Check client area */
722 ScreenToClient16( wndPtr->hwndSelf, &pt );
723 GetClientRect16( wndPtr->hwndSelf, &rect );
724 if (PtInRect16( &rect, pt )) return HTCLIENT;
726 /* Check vertical scroll bar */
728 if (wndPtr->dwStyle & WS_VSCROLL)
730 rect.right += SYSMETRICS_CXVSCROLL;
731 if (PtInRect16( &rect, pt )) return HTVSCROLL;
734 /* Check horizontal scroll bar */
736 if (wndPtr->dwStyle & WS_HSCROLL)
738 rect.bottom += SYSMETRICS_CYHSCROLL;
739 if (PtInRect16( &rect, pt ))
741 /* Check size box */
742 if ((wndPtr->dwStyle & WS_VSCROLL) &&
743 (pt.x >= rect.right - SYSMETRICS_CXVSCROLL))
744 return HTSIZE;
745 return HTHSCROLL;
749 /* Check menu bar */
751 if (HAS_MENU(wndPtr))
753 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
754 return HTMENU;
757 /* Should never get here */
758 return HTERROR;
762 /***********************************************************************
763 * NC_DoNCHitTest95
765 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
767 * FIXME: Just a modified copy of the Win 3.1 version.
770 LONG
771 NC_DoNCHitTest95 (WND *wndPtr, POINT16 pt )
773 RECT16 rect;
775 TRACE(nonclient, "hwnd=%04x pt=%d,%d\n",
776 wndPtr->hwndSelf, pt.x, pt.y );
778 GetWindowRect16 (wndPtr->hwndSelf, &rect );
779 if (!PtInRect16( &rect, pt )) return HTNOWHERE;
781 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
783 if (!(wndPtr->flags & WIN_MANAGED))
785 /* Check borders */
786 if (HAS_SIZEFRAME( wndPtr->dwStyle ))
788 InflateRect16( &rect, -SYSMETRICS_CXFRAME, -SYSMETRICS_CYFRAME );
789 /* if (wndPtr->dwStyle & WS_BORDER) */
790 /* InflateRect16(&rect,-SYSMETRICS_CXBORDER,-SYSMETRICS_CYBORDER); */
791 if (!PtInRect16( &rect, pt ))
793 /* Check top sizing border */
794 if (pt.y < rect.top)
796 if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTTOPLEFT;
797 if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTTOPRIGHT;
798 return HTTOP;
800 /* Check bottom sizing border */
801 if (pt.y >= rect.bottom)
803 if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTBOTTOMLEFT;
804 if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTBOTTOMRIGHT;
805 return HTBOTTOM;
807 /* Check left sizing border */
808 if (pt.x < rect.left)
810 if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPLEFT;
811 if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMLEFT;
812 return HTLEFT;
814 /* Check right sizing border */
815 if (pt.x >= rect.right)
817 if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPRIGHT;
818 if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMRIGHT;
819 return HTRIGHT;
823 else /* No thick frame */
825 if (HAS_FIXEDFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
826 InflateRect16(&rect, -SYSMETRICS_CXDLGFRAME, -SYSMETRICS_CYDLGFRAME);
827 /* else if (wndPtr->dwStyle & WS_BORDER) */
828 /* InflateRect16(&rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER); */
829 if (!PtInRect16( &rect, pt )) return HTBORDER;
832 /* Check caption */
834 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
836 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
837 rect.top += sysMetrics[SM_CYSMCAPTION] - 1;
838 else
839 rect.top += sysMetrics[SM_CYCAPTION] - 1;
840 if (!PtInRect16( &rect, pt ))
842 /* Check system menu */
843 if ((wndPtr->dwStyle & WS_SYSMENU) &&
844 ((wndPtr->class->hIconSm) || (wndPtr->class->hIcon)))
845 rect.left += sysMetrics[SM_CYCAPTION] - 1;
846 if (pt.x < rect.left) return HTSYSMENU;
848 /* Check close button */
849 if (wndPtr->dwStyle & WS_SYSMENU)
850 rect.right -= sysMetrics[SM_CYCAPTION] - 1;
851 if (pt.x > rect.right) return HTCLOSE;
853 /* Check maximize box */
854 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
855 rect.right -= SYSMETRICS_CXSIZE + 1;
856 if (pt.x > rect.right) return HTMAXBUTTON;
858 /* Check minimize box */
859 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
860 rect.right -= SYSMETRICS_CXSIZE + 1;
861 if (pt.x > rect.right) return HTMINBUTTON;
862 return HTCAPTION;
867 /* Check client area */
869 ScreenToClient16( wndPtr->hwndSelf, &pt );
870 GetClientRect16( wndPtr->hwndSelf, &rect );
871 if (PtInRect16( &rect, pt )) return HTCLIENT;
873 /* Check vertical scroll bar */
875 if (wndPtr->dwStyle & WS_VSCROLL)
877 rect.right += SYSMETRICS_CXVSCROLL;
878 if (PtInRect16( &rect, pt )) return HTVSCROLL;
881 /* Check horizontal scroll bar */
883 if (wndPtr->dwStyle & WS_HSCROLL)
885 rect.bottom += SYSMETRICS_CYHSCROLL;
886 if (PtInRect16( &rect, pt ))
888 /* Check size box */
889 if ((wndPtr->dwStyle & WS_VSCROLL) &&
890 (pt.x >= rect.right - SYSMETRICS_CXVSCROLL))
891 return HTSIZE;
892 return HTHSCROLL;
896 /* Check menu bar */
898 if (HAS_MENU(wndPtr))
900 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
901 return HTMENU;
904 /* Should never get here */
905 return HTERROR;
909 /***********************************************************************
910 * NC_HandleNCHitTest
912 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
914 LONG
915 NC_HandleNCHitTest (HWND hwnd , POINT16 pt)
917 LONG retvalue;
918 WND *wndPtr = WIN_FindWndPtr (hwnd);
920 if (!wndPtr)
921 return HTERROR;
923 if (TWEAK_WineLook == WIN31_LOOK)
924 retvalue = NC_DoNCHitTest (wndPtr, pt);
925 else
926 retvalue = NC_DoNCHitTest95 (wndPtr, pt);
927 WIN_ReleaseWndPtr(wndPtr);
928 return retvalue;
932 /***********************************************************************
933 * NC_DrawSysButton
935 void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down )
937 RECT rect;
938 HDC hdcMem;
939 HBITMAP hbitmap;
940 WND *wndPtr = WIN_FindWndPtr( hwnd );
942 if( !(wndPtr->flags & WIN_MANAGED) )
944 NC_GetInsideRect( hwnd, &rect );
945 hdcMem = CreateCompatibleDC( hdc );
946 hbitmap = SelectObject( hdcMem, hbitmapClose );
947 BitBlt(hdc, rect.left, rect.top, SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE,
948 hdcMem, (wndPtr->dwStyle & WS_CHILD) ? SYSMETRICS_CXSIZE : 0, 0,
949 down ? NOTSRCCOPY : SRCCOPY );
950 SelectObject( hdcMem, hbitmap );
951 DeleteDC( hdcMem );
953 WIN_ReleaseWndPtr(wndPtr);
957 /***********************************************************************
958 * NC_DrawMaxButton
960 static void NC_DrawMaxButton( HWND hwnd, HDC16 hdc, BOOL down )
962 RECT rect;
963 WND *wndPtr = WIN_FindWndPtr( hwnd );
964 HDC hdcMem;
966 if( !(wndPtr->flags & WIN_MANAGED) )
968 NC_GetInsideRect( hwnd, &rect );
969 hdcMem = CreateCompatibleDC( hdc );
970 SelectObject( hdcMem, (IsZoomed(hwnd)
971 ? (down ? hbitmapRestoreD : hbitmapRestore)
972 : (down ? hbitmapMaximizeD : hbitmapMaximize)) );
973 BitBlt( hdc, rect.right - SYSMETRICS_CXSIZE - 1, rect.top,
974 SYSMETRICS_CXSIZE + 1, SYSMETRICS_CYSIZE, hdcMem, 0, 0,
975 SRCCOPY );
976 DeleteDC( hdcMem );
978 WIN_ReleaseWndPtr(wndPtr);
983 /***********************************************************************
984 * NC_DrawMinButton
986 static void NC_DrawMinButton( HWND hwnd, HDC16 hdc, BOOL down )
988 RECT rect;
989 WND *wndPtr = WIN_FindWndPtr( hwnd );
990 HDC hdcMem;
992 if( !(wndPtr->flags & WIN_MANAGED) )
994 NC_GetInsideRect( hwnd, &rect );
995 hdcMem = CreateCompatibleDC( hdc );
996 SelectObject( hdcMem, (down ? hbitmapMinimizeD : hbitmapMinimize) );
997 if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= SYSMETRICS_CXSIZE+1;
998 BitBlt( hdc, rect.right - SYSMETRICS_CXSIZE - 1, rect.top,
999 SYSMETRICS_CXSIZE + 1, SYSMETRICS_CYSIZE, hdcMem, 0, 0,
1000 SRCCOPY );
1001 DeleteDC( hdcMem );
1003 WIN_ReleaseWndPtr(wndPtr);
1007 /******************************************************************************
1009 * void NC_DrawSysButton95(
1010 * HWND32 hwnd,
1011 * HDC32 hdc,
1012 * BOOL32 down )
1014 * Draws the Win95 system icon.
1016 * Revision history
1017 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1018 * Original implementation from NC_DrawSysButton source.
1019 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1020 * Fixed most bugs.
1022 *****************************************************************************/
1024 BOOL
1025 NC_DrawSysButton95 (HWND hwnd, HDC hdc, BOOL down)
1027 WND *wndPtr = WIN_FindWndPtr( hwnd );
1029 if( !(wndPtr->flags & WIN_MANAGED) )
1031 HICON hIcon = 0;
1032 RECT rect;
1034 NC_GetInsideRect95( hwnd, &rect );
1036 if (wndPtr->class->hIconSm)
1037 hIcon = wndPtr->class->hIconSm;
1038 else if (wndPtr->class->hIcon)
1039 hIcon = wndPtr->class->hIcon;
1041 if (hIcon)
1042 DrawIconEx (hdc, rect.left + 2, rect.top + 2, hIcon,
1043 sysMetrics[SM_CXSMICON],
1044 sysMetrics[SM_CYSMICON],
1045 0, 0, DI_NORMAL);
1047 WIN_ReleaseWndPtr(wndPtr);
1048 return (hIcon != 0);
1050 WIN_ReleaseWndPtr(wndPtr);
1051 return FALSE;
1055 /******************************************************************************
1057 * void NC_DrawCloseButton95(
1058 * HWND32 hwnd,
1059 * HDC32 hdc,
1060 * BOOL32 down )
1062 * Draws the Win95 close button.
1064 * Revision history
1065 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1066 * Original implementation from NC_DrawSysButton95 source.
1068 *****************************************************************************/
1070 void NC_DrawCloseButton95 (HWND hwnd, HDC hdc, BOOL down)
1072 RECT rect;
1073 HDC hdcMem;
1074 WND *wndPtr = WIN_FindWndPtr( hwnd );
1076 if( !(wndPtr->flags & WIN_MANAGED) )
1078 BITMAP bmp;
1079 HBITMAP hBmp, hOldBmp;
1081 NC_GetInsideRect95( hwnd, &rect );
1083 hdcMem = CreateCompatibleDC( hdc );
1084 hBmp = down ? hbitmapCloseD : hbitmapClose;
1085 hOldBmp = SelectObject (hdcMem, hBmp);
1086 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1087 BitBlt (hdc, rect.right - (sysMetrics[SM_CYCAPTION] + 1 + bmp.bmWidth) / 2,
1088 rect.top + (sysMetrics[SM_CYCAPTION] - 1 - bmp.bmHeight) / 2,
1089 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);
1091 SelectObject (hdcMem, hOldBmp);
1092 DeleteDC (hdcMem);
1094 WIN_ReleaseWndPtr(wndPtr);
1097 /******************************************************************************
1099 * NC_DrawMaxButton95(
1100 * HWND32 hwnd,
1101 * HDC16 hdc,
1102 * BOOL32 down )
1104 * Draws the maximize button for Win95 style windows.
1106 * Bugs
1107 * Many. Spacing might still be incorrect. Need to fit a close
1108 * button between the max button and the edge.
1109 * Should scale the image with the title bar. And more...
1111 * Revision history
1112 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1113 * Original implementation.
1115 *****************************************************************************/
1117 static void NC_DrawMaxButton95(HWND hwnd,HDC16 hdc,BOOL down )
1119 RECT rect;
1120 HDC hdcMem;
1121 WND *wndPtr = WIN_FindWndPtr( hwnd );
1123 if( !(wndPtr->flags & WIN_MANAGED))
1125 BITMAP bmp;
1126 HBITMAP hBmp,hOldBmp;
1128 NC_GetInsideRect95( hwnd, &rect );
1129 hdcMem = CreateCompatibleDC( hdc );
1130 hBmp = IsZoomed(hwnd) ?
1131 (down ? hbitmapRestoreD : hbitmapRestore ) :
1132 (down ? hbitmapMaximizeD: hbitmapMaximize);
1133 hOldBmp=SelectObject( hdcMem, hBmp );
1134 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1136 if (wndPtr->dwStyle & WS_SYSMENU)
1137 rect.right -= sysMetrics[SM_CYCAPTION] + 1;
1139 BitBlt( hdc, rect.right - (sysMetrics[SM_CXSIZE] + bmp.bmWidth) / 2,
1140 rect.top + (sysMetrics[SM_CYCAPTION] - 1 - bmp.bmHeight) / 2,
1141 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1142 SelectObject (hdcMem, hOldBmp);
1143 DeleteDC( hdcMem );
1145 WIN_ReleaseWndPtr(wndPtr);
1148 /******************************************************************************
1150 * NC_DrawMinButton95(
1151 * HWND32 hwnd,
1152 * HDC16 hdc,
1153 * BOOL32 down )
1155 * Draws the minimize button for Win95 style windows.
1157 * Bugs
1158 * Many. Spacing is still incorrect. Should scale the image with the
1159 * title bar. And more...
1161 * Revision history
1162 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1163 * Original implementation.
1165 *****************************************************************************/
1167 static void NC_DrawMinButton95(HWND hwnd,HDC16 hdc,BOOL down )
1169 RECT rect;
1170 HDC hdcMem;
1171 WND *wndPtr = WIN_FindWndPtr( hwnd );
1173 if( !(wndPtr->flags & WIN_MANAGED))
1176 BITMAP bmp;
1177 HBITMAP hBmp,hOldBmp;
1179 NC_GetInsideRect95( hwnd, &rect );
1181 hdcMem = CreateCompatibleDC( hdc );
1182 hBmp = down ? hbitmapMinimizeD : hbitmapMinimize;
1183 hOldBmp= SelectObject( hdcMem, hBmp );
1184 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1186 if (wndPtr->dwStyle & WS_SYSMENU)
1187 rect.right -= sysMetrics[SM_CYCAPTION] + 1;
1189 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
1190 rect.right += -1 - (sysMetrics[SM_CXSIZE] + bmp.bmWidth) / 2;
1192 BitBlt( hdc, rect.right - (sysMetrics[SM_CXSIZE] + bmp.bmWidth) / 2,
1193 rect.top + (sysMetrics[SM_CYCAPTION] - 1 - bmp.bmHeight) / 2,
1194 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1196 SelectObject (hdcMem, hOldBmp);
1197 DeleteDC( hdcMem );
1199 WIN_ReleaseWndPtr(wndPtr);
1202 /***********************************************************************
1203 * NC_DrawFrame
1205 * Draw a window frame inside the given rectangle, and update the rectangle.
1206 * The correct pen for the frame must be selected in the DC.
1208 static void NC_DrawFrame( HDC hdc, RECT *rect, BOOL dlgFrame,
1209 BOOL active )
1211 INT width, height;
1213 if (TWEAK_WineLook != WIN31_LOOK)
1214 ERR (nonclient, "Called in Win95 mode. Aiee! Please report this.\n" );
1216 if (dlgFrame)
1218 width = SYSMETRICS_CXDLGFRAME - 1;
1219 height = SYSMETRICS_CYDLGFRAME - 1;
1220 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1221 COLOR_INACTIVECAPTION) );
1223 else
1225 width = SYSMETRICS_CXFRAME - 1;
1226 height = SYSMETRICS_CYFRAME - 1;
1227 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1228 COLOR_INACTIVEBORDER) );
1231 /* Draw frame */
1232 PatBlt( hdc, rect->left, rect->top,
1233 rect->right - rect->left, height, PATCOPY );
1234 PatBlt( hdc, rect->left, rect->top,
1235 width, rect->bottom - rect->top, PATCOPY );
1236 PatBlt( hdc, rect->left, rect->bottom - 1,
1237 rect->right - rect->left, -height, PATCOPY );
1238 PatBlt( hdc, rect->right - 1, rect->top,
1239 -width, rect->bottom - rect->top, PATCOPY );
1241 if (dlgFrame)
1243 InflateRect( rect, -width, -height );
1245 else
1247 INT decYOff = SYSMETRICS_CXFRAME + SYSMETRICS_CXSIZE;
1248 INT decXOff = SYSMETRICS_CYFRAME + SYSMETRICS_CYSIZE;
1250 /* Draw inner rectangle */
1252 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1253 Rectangle( hdc, rect->left + width, rect->top + height,
1254 rect->right - width , rect->bottom - height );
1256 /* Draw the decorations */
1258 MoveToEx( hdc, rect->left, rect->top + decYOff, NULL );
1259 LineTo( hdc, rect->left + width, rect->top + decYOff );
1260 MoveToEx( hdc, rect->right - 1, rect->top + decYOff, NULL );
1261 LineTo( hdc, rect->right - width - 1, rect->top + decYOff );
1262 MoveToEx( hdc, rect->left, rect->bottom - decYOff, NULL );
1263 LineTo( hdc, rect->left + width, rect->bottom - decYOff );
1264 MoveToEx( hdc, rect->right - 1, rect->bottom - decYOff, NULL );
1265 LineTo( hdc, rect->right - width - 1, rect->bottom - decYOff );
1267 MoveToEx( hdc, rect->left + decXOff, rect->top, NULL );
1268 LineTo( hdc, rect->left + decXOff, rect->top + height);
1269 MoveToEx( hdc, rect->left + decXOff, rect->bottom - 1, NULL );
1270 LineTo( hdc, rect->left + decXOff, rect->bottom - height - 1 );
1271 MoveToEx( hdc, rect->right - decXOff, rect->top, NULL );
1272 LineTo( hdc, rect->right - decXOff, rect->top + height );
1273 MoveToEx( hdc, rect->right - decXOff, rect->bottom - 1, NULL );
1274 LineTo( hdc, rect->right - decXOff, rect->bottom - height - 1 );
1276 InflateRect( rect, -width - 1, -height - 1 );
1281 /******************************************************************************
1283 * void NC_DrawFrame95(
1284 * HDC32 hdc,
1285 * RECT32 *rect,
1286 * BOOL32 dlgFrame,
1287 * BOOL32 active )
1289 * Draw a window frame inside the given rectangle, and update the rectangle.
1290 * The correct pen for the frame must be selected in the DC.
1292 * Bugs
1293 * Many. First, just what IS a frame in Win95? Note that the 3D look
1294 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1295 * edge. The inner rectangle just inside the frame is handled by the
1296 * Caption code.
1298 * In short, for most people, this function should be a nop (unless
1299 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1300 * them lately, but just to get this code right). Even so, it doesn't
1301 * appear to be so. It's being worked on...
1303 * Revision history
1304 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1305 * Original implementation (based on NC_DrawFrame)
1306 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1307 * Some minor fixes.
1309 *****************************************************************************/
1311 static void NC_DrawFrame95(
1312 HDC hdc,
1313 RECT *rect,
1314 BOOL dlgFrame,
1315 BOOL active )
1317 INT width, height;
1319 if (dlgFrame)
1321 width = sysMetrics[SM_CXDLGFRAME] - sysMetrics[SM_CXEDGE];
1322 height = sysMetrics[SM_CYDLGFRAME] - sysMetrics[SM_CYEDGE];
1324 else
1326 width = sysMetrics[SM_CXFRAME] - sysMetrics[SM_CXEDGE];
1327 height = sysMetrics[SM_CYFRAME] - sysMetrics[SM_CYEDGE];
1330 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1331 COLOR_INACTIVEBORDER) );
1333 /* Draw frame */
1334 PatBlt( hdc, rect->left, rect->top,
1335 rect->right - rect->left, height, PATCOPY );
1336 PatBlt( hdc, rect->left, rect->top,
1337 width, rect->bottom - rect->top, PATCOPY );
1338 PatBlt( hdc, rect->left, rect->bottom - 1,
1339 rect->right - rect->left, -height, PATCOPY );
1340 PatBlt( hdc, rect->right - 1, rect->top - 1,
1341 -width, rect->bottom - rect->top, PATCOPY );
1343 InflateRect( rect, -width, -height );
1346 /***********************************************************************
1347 * NC_DrawMovingFrame
1349 * Draw the frame used when moving or resizing window.
1351 * FIXME: This causes problems in Win95 mode. (why?)
1353 static void NC_DrawMovingFrame( HDC hdc, RECT *rect, BOOL thickframe )
1355 if (thickframe)
1357 RECT16 r16;
1358 CONV_RECT32TO16( rect, &r16 );
1359 FastWindowFrame16( hdc, &r16, SYSMETRICS_CXFRAME,
1360 SYSMETRICS_CYFRAME, PATINVERT );
1362 else DrawFocusRect( hdc, rect );
1366 /***********************************************************************
1367 * NC_DrawCaption
1369 * Draw the window caption.
1370 * The correct pen for the window frame must be selected in the DC.
1372 static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd,
1373 DWORD style, BOOL active )
1375 RECT r = *rect;
1376 WND * wndPtr = WIN_FindWndPtr( hwnd );
1377 char buffer[256];
1379 if (wndPtr->flags & WIN_MANAGED)
1381 WIN_ReleaseWndPtr(wndPtr);
1382 return;
1385 if (!hbitmapClose)
1387 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1389 WIN_ReleaseWndPtr(wndPtr);
1390 return;
1392 hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED) );
1393 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1394 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1395 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1396 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1397 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1398 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1401 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
1403 HBRUSH hbrushOld = SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW) );
1404 PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
1405 PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
1406 PatBlt( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
1407 r.left++;
1408 r.right--;
1409 SelectObject( hdc, hbrushOld );
1411 WIN_ReleaseWndPtr(wndPtr);
1412 MoveTo16( hdc, r.left, r.bottom );
1413 LineTo( hdc, r.right, r.bottom );
1415 if (style & WS_SYSMENU)
1417 NC_DrawSysButton( hwnd, hdc, FALSE );
1418 r.left += SYSMETRICS_CXSIZE + 1;
1419 MoveTo16( hdc, r.left - 1, r.top );
1420 LineTo( hdc, r.left - 1, r.bottom );
1422 if (style & WS_MAXIMIZEBOX)
1424 NC_DrawMaxButton( hwnd, hdc, FALSE );
1425 r.right -= SYSMETRICS_CXSIZE + 1;
1427 if (style & WS_MINIMIZEBOX)
1429 NC_DrawMinButton( hwnd, hdc, FALSE );
1430 r.right -= SYSMETRICS_CXSIZE + 1;
1433 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1434 COLOR_INACTIVECAPTION) );
1436 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) ))
1438 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1439 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1440 SetBkMode( hdc, TRANSPARENT );
1441 DrawTextA( hdc, buffer, -1, &r,
1442 DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );
1447 /******************************************************************************
1449 * NC_DrawCaption95(
1450 * HDC32 hdc,
1451 * RECT32 *rect,
1452 * HWND32 hwnd,
1453 * DWORD style,
1454 * BOOL32 active )
1456 * Draw the window caption for Win95 style windows.
1457 * The correct pen for the window frame must be selected in the DC.
1459 * Bugs
1460 * Hey, a function that finally works! Well, almost.
1461 * It's being worked on.
1463 * Revision history
1464 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1465 * Original implementation.
1466 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1467 * Some minor fixes.
1469 *****************************************************************************/
1471 static void NC_DrawCaption95(
1472 HDC hdc,
1473 RECT *rect,
1474 HWND hwnd,
1475 DWORD style,
1476 DWORD exStyle,
1477 BOOL active )
1479 RECT r = *rect;
1480 WND *wndPtr = WIN_FindWndPtr( hwnd );
1481 char buffer[256];
1482 HPEN hPrevPen;
1484 if (wndPtr->flags & WIN_MANAGED)
1486 WIN_ReleaseWndPtr(wndPtr);
1487 return;
1489 WIN_ReleaseWndPtr(wndPtr);
1491 hPrevPen = SelectObject( hdc, GetSysColorPen(COLOR_3DFACE) );
1492 MoveToEx( hdc, r.left, r.bottom - 1, NULL );
1493 LineTo( hdc, r.right, r.bottom - 1 );
1494 SelectObject( hdc, hPrevPen );
1495 r.bottom--;
1497 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1498 COLOR_INACTIVECAPTION) );
1500 if (!hbitmapClose) {
1501 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1502 return;
1503 hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED));
1504 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1505 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1506 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1507 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1508 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1509 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1512 if ((style & WS_SYSMENU) && !(exStyle & WS_EX_TOOLWINDOW)) {
1513 if (NC_DrawSysButton95 (hwnd, hdc, FALSE))
1514 r.left += sysMetrics[SM_CYCAPTION] - 1;
1516 if (style & WS_SYSMENU) {
1517 NC_DrawCloseButton95 (hwnd, hdc, FALSE);
1518 r.right -= sysMetrics[SM_CYCAPTION] - 1;
1520 if (style & WS_MAXIMIZEBOX) {
1521 NC_DrawMaxButton95( hwnd, hdc, FALSE );
1522 r.right -= SYSMETRICS_CXSIZE + 1;
1524 if (style & WS_MINIMIZEBOX) {
1525 NC_DrawMinButton95( hwnd, hdc, FALSE );
1526 r.right -= SYSMETRICS_CXSIZE + 1;
1529 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) )) {
1530 NONCLIENTMETRICSA nclm;
1531 HFONT hFont, hOldFont;
1532 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1533 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1534 if (exStyle & WS_EX_TOOLWINDOW)
1535 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
1536 else
1537 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
1538 hOldFont = SelectObject (hdc, hFont);
1539 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1540 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1541 SetBkMode( hdc, TRANSPARENT );
1542 r.left += 2;
1543 DrawTextA( hdc, buffer, -1, &r,
1544 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
1545 DeleteObject (SelectObject (hdc, hOldFont));
1551 /***********************************************************************
1552 * NC_DoNCPaint
1554 * Paint the non-client area. clip is currently unused.
1556 void NC_DoNCPaint( WND* wndPtr, HRGN clip, BOOL suppress_menupaint )
1558 HDC hdc;
1559 RECT rect;
1560 BOOL active;
1561 HWND hwnd = wndPtr->hwndSelf;
1563 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1564 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1566 active = wndPtr->flags & WIN_NCACTIVATED;
1568 TRACE(nonclient, "%04x %d\n", hwnd, active );
1570 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1571 ((clip > 1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN): 0) ))) return;
1573 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1574 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1575 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1576 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1577 == NULLREGION)
1579 ReleaseDC( hwnd, hdc );
1580 return;
1583 rect.top = rect.left = 0;
1584 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1585 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1587 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1589 if (!(wndPtr->flags & WIN_MANAGED))
1591 if ((wndPtr->dwStyle & WS_BORDER) || (wndPtr->dwStyle & WS_DLGFRAME) ||
1592 (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME))
1594 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1595 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1596 InflateRect( &rect, -1, -1 );
1599 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1600 NC_DrawFrame( hdc, &rect, TRUE, active );
1601 else if (wndPtr->dwStyle & WS_THICKFRAME)
1602 NC_DrawFrame(hdc, &rect, FALSE, active );
1604 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1606 RECT r = rect;
1607 r.bottom = rect.top + SYSMETRICS_CYSIZE;
1608 rect.top += SYSMETRICS_CYSIZE + SYSMETRICS_CYBORDER;
1609 NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active );
1613 if (HAS_MENU(wndPtr))
1615 RECT r = rect;
1616 r.bottom = rect.top + SYSMETRICS_CYMENU; /* default height */
1617 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint );
1620 /* Draw the scroll-bars */
1622 if (wndPtr->dwStyle & WS_VSCROLL)
1623 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1624 if (wndPtr->dwStyle & WS_HSCROLL)
1625 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1627 /* Draw the "size-box" */
1629 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1631 RECT r = rect;
1632 r.left = r.right - SYSMETRICS_CXVSCROLL + 1;
1633 r.top = r.bottom - SYSMETRICS_CYHSCROLL + 1;
1634 if(wndPtr->dwStyle & WS_BORDER) {
1635 r.left++;
1636 r.top++;
1638 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1641 ReleaseDC( hwnd, hdc );
1645 /******************************************************************************
1647 * void NC_DoNCPaint95(
1648 * WND *wndPtr,
1649 * HRGN32 clip,
1650 * BOOL32 suppress_menupaint )
1652 * Paint the non-client area for Win95 windows. The clip region is
1653 * currently ignored.
1655 * Bugs
1656 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1657 * misc/tweak.c controls/menu.c # :-)
1659 * Revision history
1660 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1661 * Original implementation
1662 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1663 * Fixed some bugs.
1665 *****************************************************************************/
1667 void NC_DoNCPaint95(
1668 WND *wndPtr,
1669 HRGN clip,
1670 BOOL suppress_menupaint )
1672 HDC hdc;
1673 RECT rfuzz, rect, rectClip;
1674 BOOL active;
1675 HWND hwnd = wndPtr->hwndSelf;
1677 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1678 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1680 active = wndPtr->flags & WIN_NCACTIVATED;
1682 TRACE(nonclient, "%04x %d\n", hwnd, active );
1684 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in the call to
1685 * GetDCEx implying that it is allowed not to use it either. However, the suggested
1686 * GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN) will cause clipRgn to be deleted
1687 * after ReleaseDC(). Now, how is the "system" supposed to tell what happened?
1690 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1691 ((clip > 1) ?(DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0) ))) return;
1694 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1695 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1696 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1697 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1698 == NULLREGION)
1700 ReleaseDC( hwnd, hdc );
1701 return;
1704 rect.top = rect.left = 0;
1705 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1706 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1708 if( clip > 1 )
1709 GetRgnBox( clip, &rectClip );
1710 else
1712 clip = 0;
1713 rectClip = rect;
1716 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1718 if(!(wndPtr->flags & WIN_MANAGED)) {
1719 if ((wndPtr->dwStyle & WS_BORDER) && ((wndPtr->dwStyle & WS_DLGFRAME) ||
1720 (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME) || (wndPtr->dwStyle & WS_THICKFRAME))) {
1721 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1724 if (HAS_FIXEDFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1725 NC_DrawFrame95( hdc, &rect, TRUE, active );
1726 else if (wndPtr->dwStyle & WS_THICKFRAME)
1727 NC_DrawFrame95(hdc, &rect, FALSE, active );
1729 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1731 RECT r = rect;
1732 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW) {
1733 r.bottom = rect.top + sysMetrics[SM_CYSMCAPTION];
1734 rect.top += sysMetrics[SM_CYSMCAPTION];
1736 else {
1737 r.bottom = rect.top + sysMetrics[SM_CYCAPTION];
1738 rect.top += sysMetrics[SM_CYCAPTION];
1740 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
1741 NC_DrawCaption95 (hdc, &r, hwnd, wndPtr->dwStyle,
1742 wndPtr->dwExStyle, active);
1746 if (HAS_MENU(wndPtr))
1748 RECT r = rect;
1749 r.bottom = rect.top + sysMetrics[SM_CYMENU];
1751 TRACE(nonclient, "Calling DrawMenuBar with "
1752 "rect (%d, %d)-(%d, %d)\n", r.left, r.top,
1753 r.right, r.bottom);
1755 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ) + 1;
1758 TRACE(nonclient, "After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1759 rect.left, rect.top, rect.right, rect.bottom );
1761 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
1762 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1764 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
1765 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1767 /* Draw the scroll-bars */
1769 if (wndPtr->dwStyle & WS_VSCROLL)
1770 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1771 if (wndPtr->dwStyle & WS_HSCROLL)
1772 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1774 /* Draw the "size-box" */
1775 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1777 RECT r = rect;
1778 r.left = r.right - SYSMETRICS_CXVSCROLL + 1;
1779 r.top = r.bottom - SYSMETRICS_CYHSCROLL + 1;
1780 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1783 ReleaseDC( hwnd, hdc );
1789 /***********************************************************************
1790 * NC_HandleNCPaint
1792 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1794 LONG NC_HandleNCPaint( HWND hwnd , HRGN clip)
1796 WND* wndPtr = WIN_FindWndPtr( hwnd );
1798 if( wndPtr && wndPtr->dwStyle & WS_VISIBLE )
1800 if( wndPtr->dwStyle & WS_MINIMIZE )
1801 WINPOS_RedrawIconTitle( hwnd );
1802 else if (TWEAK_WineLook == WIN31_LOOK)
1803 NC_DoNCPaint( wndPtr, clip, FALSE );
1804 else
1805 NC_DoNCPaint95( wndPtr, clip, FALSE );
1807 WIN_ReleaseWndPtr(wndPtr);
1808 return 0;
1812 /***********************************************************************
1813 * NC_HandleNCActivate
1815 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1817 LONG NC_HandleNCActivate( WND *wndPtr, WPARAM16 wParam )
1819 WORD wStateChange;
1821 if( wParam ) wStateChange = !(wndPtr->flags & WIN_NCACTIVATED);
1822 else wStateChange = wndPtr->flags & WIN_NCACTIVATED;
1824 if( wStateChange )
1826 if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
1827 else wndPtr->flags &= ~WIN_NCACTIVATED;
1829 if( wndPtr->dwStyle & WS_MINIMIZE )
1830 WINPOS_RedrawIconTitle( wndPtr->hwndSelf );
1831 else if (TWEAK_WineLook == WIN31_LOOK)
1832 NC_DoNCPaint( wndPtr, (HRGN)1, FALSE );
1833 else
1834 NC_DoNCPaint95( wndPtr, (HRGN)1, FALSE );
1836 return TRUE;
1840 /***********************************************************************
1841 * NC_HandleSetCursor
1843 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1845 LONG NC_HandleSetCursor( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
1847 if (hwnd != (HWND)wParam) return 0; /* Don't set the cursor for child windows */
1849 switch(LOWORD(lParam))
1851 case HTERROR:
1853 WORD msg = HIWORD( lParam );
1854 if ((msg == WM_LBUTTONDOWN) || (msg == WM_MBUTTONDOWN) ||
1855 (msg == WM_RBUTTONDOWN))
1856 MessageBeep(0);
1858 break;
1860 case HTCLIENT:
1862 WND *wndPtr;
1863 BOOL retvalue;
1865 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) break;
1866 if (wndPtr->class->hCursor)
1868 SetCursor16( wndPtr->class->hCursor );
1869 retvalue = TRUE;
1871 else retvalue = FALSE;
1872 WIN_ReleaseWndPtr(wndPtr);
1873 return retvalue;
1876 case HTLEFT:
1877 case HTRIGHT:
1878 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZEWE16 ) );
1880 case HTTOP:
1881 case HTBOTTOM:
1882 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENS16 ) );
1884 case HTTOPLEFT:
1885 case HTBOTTOMRIGHT:
1886 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENWSE16 ) );
1888 case HTTOPRIGHT:
1889 case HTBOTTOMLEFT:
1890 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENESW16 ) );
1893 /* Default cursor: arrow */
1894 return (LONG)SetCursor16( LoadCursor16( 0, IDC_ARROW16 ) );
1897 /***********************************************************************
1898 * NC_GetSysPopupPos
1900 BOOL NC_GetSysPopupPos( WND* wndPtr, RECT* rect )
1902 if( wndPtr->hSysMenu )
1904 if( wndPtr->dwStyle & WS_MINIMIZE )
1905 GetWindowRect( wndPtr->hwndSelf, rect );
1906 else
1908 if (TWEAK_WineLook == WIN31_LOOK)
1909 NC_GetInsideRect( wndPtr->hwndSelf, rect );
1910 else
1911 NC_GetInsideRect95( wndPtr->hwndSelf, rect );
1912 OffsetRect( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
1913 if (wndPtr->dwStyle & WS_CHILD)
1914 ClientToScreen( wndPtr->parent->hwndSelf, (POINT *)rect );
1915 if (TWEAK_WineLook == WIN31_LOOK) {
1916 rect->right = rect->left + SYSMETRICS_CXSIZE;
1917 rect->bottom = rect->top + SYSMETRICS_CYSIZE;
1919 else {
1920 rect->right = rect->left + sysMetrics[SM_CYCAPTION] - 1;
1921 rect->bottom = rect->top + sysMetrics[SM_CYCAPTION] - 1;
1924 return TRUE;
1926 return FALSE;
1929 /***********************************************************************
1930 * NC_StartSizeMove
1932 * Initialisation of a move or resize, when initiatied from a menu choice.
1933 * Return hit test code for caption or sizing border.
1935 static LONG NC_StartSizeMove( WND* wndPtr, WPARAM16 wParam,
1936 POINT16 *capturePoint )
1938 LONG hittest = 0;
1939 POINT16 pt;
1940 MSG msg;
1942 if ((wParam & 0xfff0) == SC_MOVE)
1944 /* Move pointer at the center of the caption */
1945 RECT rect;
1946 if (TWEAK_WineLook == WIN31_LOOK)
1947 NC_GetInsideRect( wndPtr->hwndSelf, &rect );
1948 else
1949 NC_GetInsideRect95( wndPtr->hwndSelf, &rect );
1950 if (wndPtr->dwStyle & WS_SYSMENU)
1951 rect.left += SYSMETRICS_CXSIZE + 1;
1952 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
1953 rect.right -= SYSMETRICS_CXSIZE + 1;
1954 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
1955 rect.right -= SYSMETRICS_CXSIZE + 1;
1956 pt.x = wndPtr->rectWindow.left + (rect.right - rect.left) / 2;
1957 pt.y = wndPtr->rectWindow.top + rect.top + SYSMETRICS_CYSIZE/2;
1958 hittest = HTCAPTION;
1959 *capturePoint = pt;
1961 else /* SC_SIZE */
1963 while(!hittest)
1965 MSG_InternalGetMessage( &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE );
1966 switch(msg.message)
1968 case WM_MOUSEMOVE:
1969 CONV_POINT32TO16(&msg.pt, &pt);
1970 hittest = NC_HandleNCHitTest( wndPtr->hwndSelf, pt );
1971 if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
1972 hittest = 0;
1973 break;
1975 case WM_LBUTTONUP:
1976 return 0;
1978 case WM_KEYDOWN:
1979 switch(msg.wParam)
1981 case VK_UP:
1982 hittest = HTTOP;
1983 pt.x =(wndPtr->rectWindow.left+wndPtr->rectWindow.right)/2;
1984 pt.y = wndPtr->rectWindow.top + SYSMETRICS_CYFRAME / 2;
1985 break;
1986 case VK_DOWN:
1987 hittest = HTBOTTOM;
1988 pt.x =(wndPtr->rectWindow.left+wndPtr->rectWindow.right)/2;
1989 pt.y = wndPtr->rectWindow.bottom - SYSMETRICS_CYFRAME / 2;
1990 break;
1991 case VK_LEFT:
1992 hittest = HTLEFT;
1993 pt.x = wndPtr->rectWindow.left + SYSMETRICS_CXFRAME / 2;
1994 pt.y =(wndPtr->rectWindow.top+wndPtr->rectWindow.bottom)/2;
1995 break;
1996 case VK_RIGHT:
1997 hittest = HTRIGHT;
1998 pt.x = wndPtr->rectWindow.right - SYSMETRICS_CXFRAME / 2;
1999 pt.y =(wndPtr->rectWindow.top+wndPtr->rectWindow.bottom)/2;
2000 break;
2001 case VK_RETURN:
2002 case VK_ESCAPE: return 0;
2006 *capturePoint = pt;
2008 SetCursorPos( pt.x, pt.y );
2009 NC_HandleSetCursor( wndPtr->hwndSelf,
2010 wndPtr->hwndSelf, MAKELONG( hittest, WM_MOUSEMOVE ));
2011 return hittest;
2015 /***********************************************************************
2016 * NC_DoSizeMove
2018 * Perform SC_MOVE and SC_SIZE commands. `
2020 static void NC_DoSizeMove( HWND hwnd, WORD wParam )
2022 MSG msg;
2023 RECT sizingRect, mouseRect;
2024 HDC hdc;
2025 LONG hittest = (LONG)(wParam & 0x0f);
2026 HCURSOR16 hDragCursor = 0, hOldCursor = 0;
2027 POINT minTrack, maxTrack;
2028 POINT16 capturePoint, pt;
2029 WND * wndPtr = WIN_FindWndPtr( hwnd );
2030 BOOL thickframe = HAS_THICKFRAME( wndPtr->dwStyle );
2031 BOOL iconic = wndPtr->dwStyle & WS_MINIMIZE;
2032 BOOL moved = FALSE;
2033 DWORD dwPoint = GetMessagePos ();
2035 capturePoint = pt = *(POINT16*)&dwPoint;
2037 if (IsZoomed(hwnd) || !IsWindowVisible(hwnd) ||
2038 (wndPtr->flags & WIN_MANAGED)) goto END;
2040 if ((wParam & 0xfff0) == SC_MOVE)
2042 if (!(wndPtr->dwStyle & WS_CAPTION)) goto END;
2043 if (!hittest)
2044 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2045 if (!hittest) goto END;
2047 else /* SC_SIZE */
2049 if (!thickframe) goto END;
2050 if ( hittest && hittest != HTSYSMENU ) hittest += 2;
2051 else
2053 SetCapture(hwnd);
2054 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2055 if (!hittest)
2057 ReleaseCapture();
2058 goto END;
2063 /* Get min/max info */
2065 WINPOS_GetMinMaxInfo( wndPtr, NULL, NULL, &minTrack, &maxTrack );
2066 sizingRect = wndPtr->rectWindow;
2067 if (wndPtr->dwStyle & WS_CHILD)
2068 GetClientRect( wndPtr->parent->hwndSelf, &mouseRect );
2069 else
2070 SetRect(&mouseRect, 0, 0, SYSMETRICS_CXSCREEN, SYSMETRICS_CYSCREEN);
2071 if (ON_LEFT_BORDER(hittest))
2073 mouseRect.left = MAX( mouseRect.left, sizingRect.right-maxTrack.x );
2074 mouseRect.right = MIN( mouseRect.right, sizingRect.right-minTrack.x );
2076 else if (ON_RIGHT_BORDER(hittest))
2078 mouseRect.left = MAX( mouseRect.left, sizingRect.left+minTrack.x );
2079 mouseRect.right = MIN( mouseRect.right, sizingRect.left+maxTrack.x );
2081 if (ON_TOP_BORDER(hittest))
2083 mouseRect.top = MAX( mouseRect.top, sizingRect.bottom-maxTrack.y );
2084 mouseRect.bottom = MIN( mouseRect.bottom,sizingRect.bottom-minTrack.y);
2086 else if (ON_BOTTOM_BORDER(hittest))
2088 mouseRect.top = MAX( mouseRect.top, sizingRect.top+minTrack.y );
2089 mouseRect.bottom = MIN( mouseRect.bottom, sizingRect.top+maxTrack.y );
2091 if (wndPtr->dwStyle & WS_CHILD)
2093 MapWindowPoints( wndPtr->parent->hwndSelf, 0,
2094 (LPPOINT)&mouseRect, 2 );
2096 SendMessage16( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
2098 if (GetCapture() != hwnd) SetCapture( hwnd );
2100 if (wndPtr->dwStyle & WS_CHILD)
2102 /* Retrieve a default cache DC (without using the window style) */
2103 hdc = GetDCEx( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
2105 else
2106 { /* Grab the server only when moving top-level windows without desktop */
2107 hdc = GetDC( 0 );
2110 wndPtr->pDriver->pPreSizeMove(wndPtr);
2112 if( iconic ) /* create a cursor for dragging */
2114 HICON16 hIcon = (wndPtr->class->hIcon) ? wndPtr->class->hIcon
2115 : (HICON16)SendMessage16( hwnd, WM_QUERYDRAGICON, 0, 0L);
2116 if( hIcon ) hDragCursor = CURSORICON_IconToCursor( hIcon, TRUE );
2117 if( !hDragCursor ) iconic = FALSE;
2120 if( !iconic ) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2122 while(1)
2124 int dx = 0, dy = 0;
2126 MSG_InternalGetMessage( &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE );
2128 /* Exit on button-up, Return, or Esc */
2129 if ((msg.message == WM_LBUTTONUP) ||
2130 ((msg.message == WM_KEYDOWN) &&
2131 ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
2133 if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
2134 continue; /* We are not interested in other messages */
2136 dwPoint = GetMessagePos ();
2137 pt = *(POINT16*)&dwPoint;
2139 if (msg.message == WM_KEYDOWN) switch(msg.wParam)
2141 case VK_UP: pt.y -= 8; break;
2142 case VK_DOWN: pt.y += 8; break;
2143 case VK_LEFT: pt.x -= 8; break;
2144 case VK_RIGHT: pt.x += 8; break;
2147 pt.x = MAX( pt.x, mouseRect.left );
2148 pt.x = MIN( pt.x, mouseRect.right );
2149 pt.y = MAX( pt.y, mouseRect.top );
2150 pt.y = MIN( pt.y, mouseRect.bottom );
2152 dx = pt.x - capturePoint.x;
2153 dy = pt.y - capturePoint.y;
2155 if (dx || dy)
2157 if( !moved )
2159 moved = TRUE;
2160 if( iconic ) /* ok, no system popup tracking */
2162 hOldCursor = SetCursor(hDragCursor);
2163 ShowCursor( TRUE );
2164 WINPOS_ShowIconTitle( wndPtr, FALSE );
2168 if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
2169 else
2171 RECT newRect = sizingRect;
2173 if (hittest == HTCAPTION) OffsetRect( &newRect, dx, dy );
2174 if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
2175 else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
2176 if (ON_TOP_BORDER(hittest)) newRect.top += dy;
2177 else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
2178 if( !iconic )
2180 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2181 NC_DrawMovingFrame( hdc, &newRect, thickframe );
2183 capturePoint = pt;
2184 sizingRect = newRect;
2189 ReleaseCapture();
2190 if( iconic )
2192 if( moved ) /* restore cursors, show icon title later on */
2194 ShowCursor( FALSE );
2195 SetCursor( hOldCursor );
2197 DestroyCursor( hDragCursor );
2199 else
2200 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2202 if (wndPtr->dwStyle & WS_CHILD)
2203 ReleaseDC( wndPtr->parent->hwndSelf, hdc );
2204 else
2206 ReleaseDC( 0, hdc );
2209 wndPtr->pDriver->pPostSizeMove(wndPtr);
2211 if (HOOK_IsHooked( WH_CBT ))
2213 RECT16* pr = SEGPTR_NEW(RECT16);
2214 if( pr )
2216 CONV_RECT32TO16( &sizingRect, pr );
2217 if( HOOK_CallHooks16( WH_CBT, HCBT_MOVESIZE, hwnd,
2218 (LPARAM)SEGPTR_GET(pr)) )
2219 sizingRect = wndPtr->rectWindow;
2220 else
2221 CONV_RECT16TO32( pr, &sizingRect );
2222 SEGPTR_FREE(pr);
2225 SendMessage16( hwnd, WM_EXITSIZEMOVE, 0, 0 );
2226 SendMessage16( hwnd, WM_SETVISIBLE, !IsIconic16(hwnd), 0L);
2228 if( moved && !((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
2230 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
2231 SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top,
2232 sizingRect.right - sizingRect.left,
2233 sizingRect.bottom - sizingRect.top,
2234 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
2237 if( IsWindow(hwnd) )
2238 if( wndPtr->dwStyle & WS_MINIMIZE )
2240 /* Single click brings up the system menu when iconized */
2242 if( !moved )
2244 if( wndPtr->dwStyle & WS_SYSMENU )
2245 SendMessage16( hwnd, WM_SYSCOMMAND,
2246 SC_MOUSEMENU + HTSYSMENU, *((LPARAM*)&pt));
2248 else WINPOS_ShowIconTitle( wndPtr, TRUE );
2251 END:
2252 WIN_ReleaseWndPtr(wndPtr);
2256 /***********************************************************************
2257 * NC_TrackMinMaxBox
2259 * Track a mouse button press on the minimize or maximize box.
2261 static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
2263 MSG msg;
2264 POINT16 pt16;
2265 HDC hdc = GetWindowDC( hwnd );
2266 BOOL pressed = TRUE;
2267 void (*paintButton)(HWND, HDC16, BOOL);
2269 SetCapture( hwnd );
2270 if (wParam == HTMINBUTTON)
2271 paintButton =
2272 (TWEAK_WineLook == WIN31_LOOK) ? &NC_DrawMinButton : &NC_DrawMinButton95;
2273 else
2274 paintButton =
2275 (TWEAK_WineLook == WIN31_LOOK) ? &NC_DrawMaxButton : &NC_DrawMaxButton95;
2277 (*paintButton)( hwnd, hdc, TRUE );
2281 BOOL oldstate = pressed;
2282 MSG_InternalGetMessage( &msg, 0, 0, 0, PM_REMOVE, FALSE );
2283 CONV_POINT32TO16( &msg.pt, &pt16 );
2285 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2286 if (pressed != oldstate)
2287 (*paintButton)( hwnd, hdc, pressed );
2288 } while (msg.message != WM_LBUTTONUP);
2290 (*paintButton)( hwnd, hdc, FALSE );
2292 ReleaseCapture();
2293 ReleaseDC( hwnd, hdc );
2294 if (!pressed) return;
2296 if (wParam == HTMINBUTTON)
2297 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&pt16 );
2298 else
2299 SendMessage16( hwnd, WM_SYSCOMMAND,
2300 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, *(LONG*)&pt16 );
2304 /***********************************************************************
2305 * NC_TrackCloseButton95
2307 * Track a mouse button press on the Win95 close button.
2309 static void
2310 NC_TrackCloseButton95 (HWND hwnd, WORD wParam)
2312 MSG msg;
2313 POINT16 pt16;
2314 HDC hdc = GetWindowDC( hwnd );
2315 BOOL pressed = TRUE;
2317 SetCapture( hwnd );
2319 NC_DrawCloseButton95 (hwnd, hdc, TRUE);
2323 BOOL oldstate = pressed;
2324 MSG_InternalGetMessage( &msg, 0, 0, 0, PM_REMOVE, FALSE );
2325 CONV_POINT32TO16( &msg.pt, &pt16 );
2327 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2328 if (pressed != oldstate)
2329 NC_DrawCloseButton95 (hwnd, hdc, pressed);
2330 } while (msg.message != WM_LBUTTONUP);
2332 NC_DrawCloseButton95 (hwnd, hdc, FALSE);
2334 ReleaseCapture();
2335 ReleaseDC( hwnd, hdc );
2336 if (!pressed) return;
2338 SendMessage16( hwnd, WM_SYSCOMMAND, SC_CLOSE, *(LONG*)&pt16 );
2342 /***********************************************************************
2343 * NC_TrackScrollBar
2345 * Track a mouse button press on the horizontal or vertical scroll-bar.
2347 static void NC_TrackScrollBar( HWND hwnd, WPARAM wParam, POINT pt )
2349 MSG16 *msg;
2350 INT scrollbar;
2351 WND *wndPtr = WIN_FindWndPtr( hwnd );
2353 if ((wParam & 0xfff0) == SC_HSCROLL)
2355 if ((wParam & 0x0f) != HTHSCROLL) goto END;
2356 scrollbar = SB_HORZ;
2358 else /* SC_VSCROLL */
2360 if ((wParam & 0x0f) != HTVSCROLL) goto END;
2361 scrollbar = SB_VERT;
2364 if (!(msg = SEGPTR_NEW(MSG16))) goto END;
2365 pt.x -= wndPtr->rectWindow.left;
2366 pt.y -= wndPtr->rectWindow.top;
2367 SetCapture( hwnd );
2368 SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt );
2372 GetMessage16( SEGPTR_GET(msg), 0, 0, 0 );
2373 switch(msg->message)
2375 case WM_LBUTTONUP:
2376 case WM_MOUSEMOVE:
2377 case WM_SYSTIMER:
2378 pt.x = LOWORD(msg->lParam) + wndPtr->rectClient.left -
2379 wndPtr->rectWindow.left;
2380 pt.y = HIWORD(msg->lParam) + wndPtr->rectClient.top -
2381 wndPtr->rectWindow.top;
2382 SCROLL_HandleScrollEvent( hwnd, scrollbar, msg->message, pt );
2383 break;
2384 default:
2385 TranslateMessage16( msg );
2386 DispatchMessage16( msg );
2387 break;
2389 if (!IsWindow( hwnd ))
2391 ReleaseCapture();
2392 break;
2394 } while (msg->message != WM_LBUTTONUP);
2395 SEGPTR_FREE(msg);
2396 END:
2397 WIN_ReleaseWndPtr(wndPtr);
2400 /***********************************************************************
2401 * NC_HandleNCLButtonDown
2403 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2405 LONG NC_HandleNCLButtonDown( WND* pWnd, WPARAM16 wParam, LPARAM lParam )
2407 HWND hwnd = pWnd->hwndSelf;
2409 switch(wParam) /* Hit test */
2411 case HTCAPTION:
2412 hwnd = WIN_GetTopParent(hwnd);
2414 if( WINPOS_SetActiveWindow(hwnd, TRUE, TRUE) || (GetActiveWindow() == hwnd) )
2415 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
2416 break;
2418 case HTSYSMENU:
2419 if( pWnd->dwStyle & WS_SYSMENU )
2421 if( !(pWnd->dwStyle & WS_MINIMIZE) )
2423 HDC hDC = GetWindowDC(hwnd);
2424 if (TWEAK_WineLook == WIN31_LOOK)
2425 NC_DrawSysButton( hwnd, hDC, TRUE );
2426 else
2427 NC_DrawSysButton95( hwnd, hDC, TRUE );
2428 ReleaseDC( hwnd, hDC );
2430 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
2432 break;
2434 case HTMENU:
2435 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam );
2436 break;
2438 case HTHSCROLL:
2439 SendMessage16( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
2440 break;
2442 case HTVSCROLL:
2443 SendMessage16( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
2444 break;
2446 case HTMINBUTTON:
2447 case HTMAXBUTTON:
2448 NC_TrackMinMaxBox( hwnd, wParam );
2449 break;
2451 case HTCLOSE:
2452 if (TWEAK_WineLook >= WIN95_LOOK)
2453 NC_TrackCloseButton95 (hwnd, wParam);
2454 break;
2456 case HTLEFT:
2457 case HTRIGHT:
2458 case HTTOP:
2459 case HTTOPLEFT:
2460 case HTTOPRIGHT:
2461 case HTBOTTOM:
2462 case HTBOTTOMLEFT:
2463 case HTBOTTOMRIGHT:
2464 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2465 SendMessage16( hwnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam);
2466 break;
2468 case HTBORDER:
2469 break;
2471 return 0;
2475 /***********************************************************************
2476 * NC_HandleNCLButtonDblClk
2478 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2480 LONG NC_HandleNCLButtonDblClk( WND *pWnd, WPARAM16 wParam, LPARAM lParam )
2483 * if this is an icon, send a restore since we are handling
2484 * a double click
2486 if (pWnd->dwStyle & WS_MINIMIZE)
2488 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_RESTORE, lParam );
2489 return 0;
2492 switch(wParam) /* Hit test */
2494 case HTCAPTION:
2495 /* stop processing if WS_MAXIMIZEBOX is missing */
2496 if (pWnd->dwStyle & WS_MAXIMIZEBOX)
2497 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND,
2498 (pWnd->dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
2499 lParam );
2500 break;
2502 case HTSYSMENU:
2503 if (!(pWnd->class->style & CS_NOCLOSE))
2504 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, lParam );
2505 break;
2507 case HTHSCROLL:
2508 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL,
2509 lParam );
2510 break;
2512 case HTVSCROLL:
2513 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL,
2514 lParam );
2515 break;
2517 return 0;
2521 /***********************************************************************
2522 * NC_HandleSysCommand
2524 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2526 LONG NC_HandleSysCommand( HWND hwnd, WPARAM16 wParam, POINT16 pt )
2528 WND *wndPtr = WIN_FindWndPtr( hwnd );
2529 POINT pt32;
2530 UINT16 uCommand = wParam & 0xFFF0;
2532 TRACE(nonclient, "Handling WM_SYSCOMMAND %x %d,%d\n",
2533 wParam, pt.x, pt.y );
2535 if (wndPtr->dwStyle & WS_CHILD && uCommand != SC_KEYMENU )
2536 ScreenToClient16( wndPtr->parent->hwndSelf, &pt );
2538 switch (uCommand)
2540 case SC_SIZE:
2541 case SC_MOVE:
2542 NC_DoSizeMove( hwnd, wParam );
2543 break;
2545 case SC_MINIMIZE:
2546 ShowWindow( hwnd, SW_MINIMIZE );
2547 break;
2549 case SC_MAXIMIZE:
2550 ShowWindow( hwnd, SW_MAXIMIZE );
2551 break;
2553 case SC_RESTORE:
2554 ShowWindow( hwnd, SW_RESTORE );
2555 break;
2557 case SC_CLOSE:
2558 WIN_ReleaseWndPtr(wndPtr);
2559 return SendMessage16( hwnd, WM_CLOSE, 0, 0 );
2561 case SC_VSCROLL:
2562 case SC_HSCROLL:
2563 CONV_POINT16TO32( &pt, &pt32 );
2564 NC_TrackScrollBar( hwnd, wParam, pt32 );
2565 break;
2567 case SC_MOUSEMENU:
2568 CONV_POINT16TO32( &pt, &pt32 );
2569 MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt32 );
2570 break;
2572 case SC_KEYMENU:
2573 MENU_TrackKbdMenuBar( wndPtr , wParam , pt.x );
2574 break;
2576 case SC_TASKLIST:
2577 WinExec( "taskman.exe", SW_SHOWNORMAL );
2578 break;
2580 case SC_SCREENSAVE:
2581 if (wParam == SC_ABOUTWINE)
2582 ShellAboutA(hwnd,"Wine", WINE_RELEASE_INFO, 0);
2583 else
2584 if (wParam == SC_PUTMARK)
2585 TRACE(shell,"Mark requested by user\n");
2586 break;
2588 case SC_HOTKEY:
2589 case SC_ARRANGE:
2590 case SC_NEXTWINDOW:
2591 case SC_PREVWINDOW:
2592 FIXME (nonclient, "unimplemented!\n");
2593 break;
2595 WIN_ReleaseWndPtr(wndPtr);
2596 return 0;