- use fonts/fontsizes given by SystemParametersInfo
[wine] / windows / nonclient.c
1 /*
2  * Non-client area window functions
3  *
4  * Copyright 1994 Alexandre Julliard
5  *
6  */
7
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"
29
30 static HBITMAP16 hbitmapClose = 0;
31 static HBITMAP16 hbitmapCloseD = 0;
32 static HBITMAP16 hbitmapMinimize = 0;
33 static HBITMAP16 hbitmapMinimizeD = 0;
34 static HBITMAP16 hbitmapMaximize = 0;
35 static HBITMAP16 hbitmapMaximizeD = 0;
36 static HBITMAP16 hbitmapRestore = 0;
37 static HBITMAP16 hbitmapRestoreD = 0;
38
39 #define SC_ABOUTWINE            (SC_SCREENSAVE+1)
40 #define SC_PUTMARK              (SC_SCREENSAVE+2)
41
42   /* Some useful macros */
43 #define HAS_DLGFRAME(style,exStyle) \
44     (((exStyle) & WS_EX_DLGMODALFRAME) || \
45      (((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
46
47 #define HAS_THICKFRAME(style) \
48     (((style) & WS_THICKFRAME) && \
49      !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
50
51 #define HAS_FIXEDFRAME(style,exStyle) \
52    (((((exStyle) & WS_EX_DLGMODALFRAME) || \
53       ((style) & WS_DLGFRAME)) && ((style) & WS_BORDER)) && \
54      !((style) & WS_THICKFRAME))
55
56 #define HAS_SIZEFRAME(style) \
57     (((style) & WS_THICKFRAME) && \
58      !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
59
60 #define HAS_MENU(w)  (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
61
62 #define ON_LEFT_BORDER(hit) \
63  (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
64 #define ON_RIGHT_BORDER(hit) \
65  (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
66 #define ON_TOP_BORDER(hit) \
67  (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
68 #define ON_BOTTOM_BORDER(hit) \
69  (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
70
71 /***********************************************************************
72  *           NC_AdjustRect
73  *
74  * Compute the size of the window rectangle from the size of the
75  * client rectangle.
76  */
77 static void NC_AdjustRect( LPRECT16 rect, DWORD style, BOOL menu,
78                            DWORD exStyle )
79 {
80     if (TWEAK_WineLook > WIN31_LOOK)
81         ERR(nonclient, "Called in Win95 mode. Aiee! Please report this.\n" );
82
83     if(style & WS_ICONIC) return;
84     /* Decide if the window will be managed (see CreateWindowEx) */
85     if (!(Options.managed && !(style & WS_CHILD) &&
86           ((style & (WS_DLGFRAME | WS_THICKFRAME)) ||
87            (exStyle & WS_EX_DLGMODALFRAME))))
88     {
89         if (HAS_DLGFRAME( style, exStyle ))
90             InflateRect16(rect, SYSMETRICS_CXDLGFRAME, SYSMETRICS_CYDLGFRAME );
91         else
92         {
93             if (HAS_THICKFRAME(style))
94                 InflateRect16( rect, SYSMETRICS_CXFRAME, SYSMETRICS_CYFRAME );
95             if (style & WS_BORDER)
96                 InflateRect16( rect, SYSMETRICS_CXBORDER, SYSMETRICS_CYBORDER);
97         }
98
99         if ((style & WS_CAPTION) == WS_CAPTION)
100             rect->top -= SYSMETRICS_CYCAPTION - SYSMETRICS_CYBORDER;
101     }
102     if (menu) rect->top -= SYSMETRICS_CYMENU + SYSMETRICS_CYBORDER;
103
104     if (style & WS_VSCROLL) {
105       rect->right  += SYSMETRICS_CXVSCROLL - 1;
106       if(!(style & WS_BORDER))
107          rect->right++;
108     }
109
110     if (style & WS_HSCROLL) {
111       rect->bottom += SYSMETRICS_CYHSCROLL - 1;
112       if(!(style & WS_BORDER))
113          rect->bottom++;
114     }
115 }
116
117
118 /******************************************************************************
119  * NC_AdjustRectOuter95
120  *
121  * Computes the size of the "outside" parts of the window based on the
122  * parameters of the client area.
123  *
124  + PARAMS
125  *     LPRECT16  rect
126  *     DWORD  style
127  *     BOOL32  menu
128  *     DWORD  exStyle
129  *
130  * NOTES
131  *     "Outer" parts of a window means the whole window frame, caption and
132  *     menu bar. It does not include "inner" parts of the frame like client
133  *     edge, static edge or scroll bars.
134  *
135  * Revision history
136  *     05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
137  *        Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
138  *
139  *     20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
140  *        Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
141  *        NC_AdjustRectInner95 and added handling of Win95 styles.
142  *
143  *****************************************************************************/
144
145 static void
146 NC_AdjustRectOuter95 (LPRECT16 rect, DWORD style, BOOL menu, DWORD exStyle)
147 {
148     if(style & WS_ICONIC) return;
149
150     /* Decide if the window will be managed (see CreateWindowEx) */
151     if (!(Options.managed && !(style & WS_CHILD) &&
152           ((style & (WS_DLGFRAME | WS_THICKFRAME)) ||
153            (exStyle & WS_EX_DLGMODALFRAME))))
154     {
155         if (HAS_FIXEDFRAME( style, exStyle ))
156             InflateRect16(rect, SYSMETRICS_CXDLGFRAME, SYSMETRICS_CYDLGFRAME );
157         else
158         {
159             if (HAS_SIZEFRAME(style))
160                 InflateRect16( rect, SYSMETRICS_CXFRAME, SYSMETRICS_CYFRAME );
161 #if 0
162             if (style & WS_BORDER)
163                 InflateRect16( rect, SYSMETRICS_CXBORDER, SYSMETRICS_CYBORDER);
164 #endif
165         }
166
167         if ((style & WS_CAPTION) == WS_CAPTION)
168         {
169             if (exStyle & WS_EX_TOOLWINDOW)
170                 rect->top -= SYSMETRICS_CYSMCAPTION;
171             else
172                 rect->top -= SYSMETRICS_CYCAPTION;
173         }
174     }
175
176     if (menu)
177         rect->top -= sysMetrics[SM_CYMENU];
178 }
179
180
181 /******************************************************************************
182  * NC_AdjustRectInner95
183  *
184  * Computes the size of the "inside" part of the window based on the
185  * parameters of the client area.
186  *
187  + PARAMS
188  *     LPRECT16 rect
189  *     DWORD    style
190  *     DWORD    exStyle
191  *
192  * NOTES
193  *     "Inner" part of a window means the window frame inside of the flat
194  *     window frame. It includes the client edge, the static edge and the
195  *     scroll bars.
196  *
197  * Revision history
198  *     05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
199  *        Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
200  *
201  *     20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
202  *        Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
203  *        NC_AdjustRectInner95 and added handling of Win95 styles.
204  *
205  *****************************************************************************/
206
207 static void
208 NC_AdjustRectInner95 (LPRECT16 rect, DWORD style, DWORD exStyle)
209 {
210     if(style & WS_ICONIC) return;
211
212     if (exStyle & WS_EX_CLIENTEDGE)
213         InflateRect16 (rect, sysMetrics[SM_CXEDGE], sysMetrics[SM_CYEDGE]);
214
215     if (exStyle & WS_EX_STATICEDGE)
216         InflateRect16 (rect, sysMetrics[SM_CXBORDER], sysMetrics[SM_CYBORDER]);
217
218     if (style & WS_VSCROLL) rect->right  += SYSMETRICS_CXVSCROLL;
219     if (style & WS_HSCROLL) rect->bottom += SYSMETRICS_CYHSCROLL;
220 }
221
222
223 /***********************************************************************
224  * DrawCaption16 [USER.660] Draws a caption bar
225  *
226  * PARAMS
227  *     hwnd   [I]
228  *     hdc    [I]
229  *     lpRect [I]
230  *     uFlags [I]
231  *
232  * RETURNS
233  *     Success:
234  *     Failure:
235  */
236
237 BOOL16 WINAPI
238 DrawCaption16 (HWND16 hwnd, HDC16 hdc, const RECT16 *rect, UINT16 uFlags)
239 {
240     RECT rect32;
241
242     if (rect)
243         CONV_RECT16TO32 (rect, &rect32);
244
245     return (BOOL16)DrawCaptionTempA (hwnd, hdc, rect ? &rect32 : NULL,
246                                        0, 0, NULL, uFlags & 0x1F);
247 }
248
249
250 /***********************************************************************
251  * DrawCaption32 [USER32.154] Draws a caption bar
252  *
253  * PARAMS
254  *     hwnd   [I]
255  *     hdc    [I]
256  *     lpRect [I]
257  *     uFlags [I]
258  *
259  * RETURNS
260  *     Success:
261  *     Failure:
262  */
263
264 BOOL WINAPI
265 DrawCaption (HWND hwnd, HDC hdc, const RECT *lpRect, UINT uFlags)
266 {
267     return DrawCaptionTempA (hwnd, hdc, lpRect, 0, 0, NULL, uFlags & 0x1F);
268 }
269
270
271 /***********************************************************************
272  * DrawCaptionTemp16 [USER.657]
273  *
274  * PARAMS
275  *
276  * RETURNS
277  *     Success:
278  *     Failure:
279  */
280
281 BOOL16 WINAPI
282 DrawCaptionTemp16 (HWND16 hwnd, HDC16 hdc, const RECT16 *rect, HFONT16 hFont,
283                    HICON16 hIcon, LPCSTR str, UINT16 uFlags)
284 {
285     RECT rect32;
286
287     if (rect)
288         CONV_RECT16TO32(rect,&rect32);
289
290     return (BOOL16)DrawCaptionTempA (hwnd, hdc, rect?&rect32:NULL, hFont,
291                                        hIcon, str, uFlags & 0x1F);
292 }
293
294
295 /***********************************************************************
296  * DrawCaptionTemp32A [USER32.599]
297  *
298  * PARAMS
299  *
300  * RETURNS
301  *     Success:
302  *     Failure:
303  */
304
305 BOOL WINAPI
306 DrawCaptionTempA (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
307                     HICON hIcon, LPCSTR str, UINT uFlags)
308 {
309     RECT   rc = *rect;
310
311     TRACE (nonclient, "(%08x,%08x,%p,%08x,%08x,\"%s\",%08x)\n",
312            hwnd, hdc, rect, hFont, hIcon, str, uFlags);
313
314     /* drawing background */
315     if (uFlags & DC_INBUTTON) {
316         FillRect (hdc, &rc, GetSysColorBrush (COLOR_3DFACE));
317
318         if (uFlags & DC_ACTIVE) {
319             HBRUSH hbr = SelectObject (hdc, CACHE_GetPattern55AABrush ());
320             PatBlt (hdc, rc.left, rc.top,
321                       rc.right-rc.left, rc.bottom-rc.top, 0xFA0089);
322             SelectObject (hdc, hbr);
323         }
324     }
325     else {
326         FillRect (hdc, &rc, GetSysColorBrush ((uFlags & DC_ACTIVE) ?
327                     COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
328     }
329
330
331     /* drawing icon */
332     if ((uFlags & DC_ICON) && !(uFlags & DC_SMALLCAP)) {
333         POINT pt;
334
335         pt.x = rc.left + 2;
336         pt.y = (rc.bottom + rc.top - sysMetrics[SM_CYSMICON]) / 2;
337
338         if (hIcon) {
339             DrawIconEx (hdc, pt.x, pt.y, hIcon, sysMetrics[SM_CXSMICON],
340                           sysMetrics[SM_CYSMICON], 0, 0, DI_NORMAL);
341         }
342         else {
343             WND *wndPtr = WIN_FindWndPtr(hwnd);
344             HICON hAppIcon = 0;
345
346             if (wndPtr->class->hIconSm)
347                 hAppIcon = wndPtr->class->hIconSm;
348             else if (wndPtr->class->hIcon)
349                 hAppIcon = wndPtr->class->hIcon;
350
351             DrawIconEx (hdc, pt.x, pt.y, hAppIcon, sysMetrics[SM_CXSMICON],
352                           sysMetrics[SM_CYSMICON], 0, 0, DI_NORMAL);
353             WIN_ReleaseWndPtr(wndPtr);
354         }
355
356         rc.left += (rc.bottom - rc.top);
357     }
358
359     /* drawing text */
360     if (uFlags & DC_TEXT) {
361         HFONT hOldFont;
362
363         if (uFlags & DC_INBUTTON)
364             SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
365         else if (uFlags & DC_ACTIVE)
366             SetTextColor (hdc, GetSysColor (COLOR_CAPTIONTEXT));
367         else
368             SetTextColor (hdc, GetSysColor (COLOR_INACTIVECAPTIONTEXT));
369
370         SetBkMode (hdc, TRANSPARENT);
371
372         if (hFont)
373             hOldFont = SelectObject (hdc, hFont);
374         else {
375             NONCLIENTMETRICSA nclm;
376             HFONT hNewFont;
377             nclm.cbSize = sizeof(NONCLIENTMETRICSA);
378             SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
379             hNewFont = CreateFontIndirectA ((uFlags & DC_SMALLCAP) ?
380                 &nclm.lfSmCaptionFont : &nclm.lfCaptionFont);
381             hOldFont = SelectObject (hdc, hNewFont);
382         }
383
384         if (str)
385             DrawTextA (hdc, str, -1, &rc,
386                          DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
387         else {
388             CHAR szText[128];
389             INT nLen;
390             nLen = GetWindowTextA (hwnd, szText, 128);
391             DrawTextA (hdc, szText, nLen, &rc,
392                          DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
393         }
394
395         if (hFont)
396             SelectObject (hdc, hOldFont);
397         else
398             DeleteObject (SelectObject (hdc, hOldFont));
399     }
400
401     /* drawing focus ??? */
402     if (uFlags & 0x2000)
403         FIXME (nonclient, "undocumented flag (0x2000)!\n");
404
405     return 0;
406 }
407
408
409 /***********************************************************************
410  * DrawCaptionTemp32W [USER32.602]
411  *
412  * PARAMS
413  *
414  * RETURNS
415  *     Success:
416  *     Failure:
417  */
418
419 BOOL WINAPI
420 DrawCaptionTempW (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
421                     HICON hIcon, LPCWSTR str, UINT uFlags)
422 {
423     LPSTR p = HEAP_strdupWtoA (GetProcessHeap (), 0, str);
424     BOOL res = DrawCaptionTempA (hwnd, hdc, rect, hFont, hIcon, p, uFlags);
425     HeapFree (GetProcessHeap (), 0, p);
426     return res;
427 }
428
429
430 /***********************************************************************
431  *           AdjustWindowRect16    (USER.102)
432  */
433 BOOL16 WINAPI AdjustWindowRect16( LPRECT16 rect, DWORD style, BOOL16 menu )
434 {
435     return AdjustWindowRectEx16( rect, style, menu, 0 );
436 }
437
438
439 /***********************************************************************
440  *           AdjustWindowRect32    (USER32.2)
441  */
442 BOOL WINAPI AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu )
443 {
444     return AdjustWindowRectEx( rect, style, menu, 0 );
445 }
446
447
448 /***********************************************************************
449  *           AdjustWindowRectEx16    (USER.454)
450  */
451 BOOL16 WINAPI AdjustWindowRectEx16( LPRECT16 rect, DWORD style,
452                                     BOOL16 menu, DWORD exStyle )
453 {
454       /* Correct the window style */
455
456     if (!(style & (WS_POPUP | WS_CHILD)))  /* Overlapped window */
457         style |= WS_CAPTION;
458     style &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD);
459     exStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE |
460                 WS_EX_STATICEDGE | WS_EX_TOOLWINDOW);
461     if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
462
463     TRACE(nonclient, "(%d,%d)-(%d,%d) %08lx %d %08lx\n",
464                       rect->left, rect->top, rect->right, rect->bottom,
465                       style, menu, exStyle );
466
467     if (TWEAK_WineLook == WIN31_LOOK)
468         NC_AdjustRect( rect, style, menu, exStyle );
469     else {
470         NC_AdjustRectOuter95( rect, style, menu, exStyle );
471         NC_AdjustRectInner95( rect, style, exStyle );
472     }
473
474     return TRUE;
475 }
476
477
478 /***********************************************************************
479  *           AdjustWindowRectEx32    (USER32.3)
480  */
481 BOOL WINAPI AdjustWindowRectEx( LPRECT rect, DWORD style,
482                                     BOOL menu, DWORD exStyle )
483 {
484     RECT16 rect16;
485     BOOL ret;
486
487     CONV_RECT32TO16( rect, &rect16 );
488     ret = AdjustWindowRectEx16( &rect16, style, (BOOL16)menu, exStyle );
489     CONV_RECT16TO32( &rect16, rect );
490     return ret;
491 }
492
493
494 /***********************************************************************
495  *           NC_HandleNCCalcSize
496  *
497  * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
498  */
499 LONG NC_HandleNCCalcSize( WND *pWnd, RECT *winRect )
500 {
501     RECT16 tmpRect = { 0, 0, 0, 0 };
502     LONG result = 0;
503
504     if (pWnd->class->style & CS_VREDRAW) result |= WVR_VREDRAW;
505     if (pWnd->class->style & CS_HREDRAW) result |= WVR_HREDRAW;
506
507     if( !( pWnd->dwStyle & WS_MINIMIZE ) ) {
508         if (TWEAK_WineLook == WIN31_LOOK)
509             NC_AdjustRect( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
510         else
511             NC_AdjustRectOuter95( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
512
513         winRect->left   -= tmpRect.left;
514         winRect->top    -= tmpRect.top;
515         winRect->right  -= tmpRect.right;
516         winRect->bottom -= tmpRect.bottom;
517
518         if (HAS_MENU(pWnd)) {
519             TRACE(nonclient, "Calling "
520                                "GetMenuBarHeight with HWND 0x%x, width %d, "
521                                "at (%d, %d).\n", pWnd->hwndSelf,
522                                winRect->right - winRect->left,
523                                -tmpRect.left, -tmpRect.top );
524
525             winRect->top +=
526                 MENU_GetMenuBarHeight( pWnd->hwndSelf,
527                                        winRect->right - winRect->left,
528                                        -tmpRect.left, -tmpRect.top ) + 1;
529         }
530
531         if (TWEAK_WineLook > WIN31_LOOK) {
532             SetRect16 (&tmpRect, 0, 0, 0, 0);
533             NC_AdjustRectInner95 (&tmpRect, pWnd->dwStyle, pWnd->dwExStyle);
534             winRect->left   -= tmpRect.left;
535             winRect->top    -= tmpRect.top;
536             winRect->right  -= tmpRect.right;
537             winRect->bottom -= tmpRect.bottom;
538         }
539     }
540     return result;
541 }
542
543
544 /***********************************************************************
545  *           NC_GetInsideRect
546  *
547  * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
548  * but without the borders (if any).
549  * The rectangle is in window coordinates (for drawing with GetWindowDC()).
550  */
551 static void NC_GetInsideRect( HWND hwnd, RECT *rect )
552 {
553     WND * wndPtr = WIN_FindWndPtr( hwnd );
554
555     rect->top    = rect->left = 0;
556     rect->right  = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
557     rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
558
559     if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) goto END;
560
561     /* Remove frame from rectangle */
562     if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
563     {
564         InflateRect( rect, -SYSMETRICS_CXDLGFRAME, -SYSMETRICS_CYDLGFRAME);
565         if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
566             InflateRect( rect, -1, 0 );
567     }
568     else
569     {
570         if (HAS_THICKFRAME( wndPtr->dwStyle ))
571             InflateRect( rect, -SYSMETRICS_CXFRAME, -SYSMETRICS_CYFRAME );
572         if (wndPtr->dwStyle & WS_BORDER)
573             InflateRect( rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER );
574     }
575 END:
576     WIN_ReleaseWndPtr(wndPtr);
577     return;
578 }
579
580
581 /***********************************************************************
582  *           NC_GetInsideRect95
583  *
584  * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
585  * but without the borders (if any).
586  * The rectangle is in window coordinates (for drawing with GetWindowDC()).
587  */
588
589 static void
590 NC_GetInsideRect95 (HWND hwnd, RECT *rect)
591 {
592     WND * wndPtr = WIN_FindWndPtr( hwnd );
593
594     rect->top    = rect->left = 0;
595     rect->right  = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
596     rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
597
598     if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) goto END;
599
600     /* Remove frame from rectangle */
601     if (HAS_FIXEDFRAME (wndPtr->dwStyle, wndPtr->dwExStyle ))
602     {
603         InflateRect( rect, -SYSMETRICS_CXFIXEDFRAME, -SYSMETRICS_CYFIXEDFRAME);
604     }
605     else if (HAS_SIZEFRAME (wndPtr->dwStyle))
606     {
607         InflateRect( rect, -SYSMETRICS_CXSIZEFRAME, -SYSMETRICS_CYSIZEFRAME );
608
609 /*      if (wndPtr->dwStyle & WS_BORDER)
610           InflateRect32( rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER );*/
611     }
612
613     if (wndPtr->dwStyle & WS_CHILD) {
614         if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
615             InflateRect (rect, -SYSMETRICS_CXEDGE, -SYSMETRICS_CYEDGE);
616
617         if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
618             InflateRect (rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER);
619     }
620 END:
621     WIN_ReleaseWndPtr(wndPtr);
622     return;
623 }
624
625
626 /***********************************************************************
627  * NC_DoNCHitTest
628  *
629  * Handle a WM_NCHITTEST message. Called from NC_HandleNcHitTest().
630  */
631
632 LONG NC_DoNCHitTest (WND *wndPtr, POINT16 pt )
633 {
634     RECT16 rect;
635
636     TRACE(nonclient, "hwnd=%04x pt=%d,%d\n",
637                       wndPtr->hwndSelf, pt.x, pt.y );
638
639     GetWindowRect16 (wndPtr->hwndSelf, &rect );
640     if (!PtInRect16( &rect, pt )) return HTNOWHERE;
641
642     if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
643
644     if (!(wndPtr->flags & WIN_MANAGED))
645     {
646         /* Check borders */
647         if (HAS_THICKFRAME( wndPtr->dwStyle ))
648         {
649             InflateRect16( &rect, -SYSMETRICS_CXFRAME, -SYSMETRICS_CYFRAME );
650             if (wndPtr->dwStyle & WS_BORDER)
651                 InflateRect16(&rect,-SYSMETRICS_CXBORDER,-SYSMETRICS_CYBORDER);
652             if (!PtInRect16( &rect, pt ))
653             {
654                 /* Check top sizing border */
655                 if (pt.y < rect.top)
656                 {
657                     if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTTOPLEFT;
658                     if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTTOPRIGHT;
659                     return HTTOP;
660                 }
661                 /* Check bottom sizing border */
662                 if (pt.y >= rect.bottom)
663                 {
664                     if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTBOTTOMLEFT;
665                     if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTBOTTOMRIGHT;
666                     return HTBOTTOM;
667                 }
668                 /* Check left sizing border */
669                 if (pt.x < rect.left)
670                 {
671                     if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPLEFT;
672                     if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMLEFT;
673                     return HTLEFT;
674                 }
675                 /* Check right sizing border */
676                 if (pt.x >= rect.right)
677                 {
678                     if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPRIGHT;
679                     if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMRIGHT;
680                     return HTRIGHT;
681                 }
682             }
683         }
684         else  /* No thick frame */
685         {
686             if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
687                 InflateRect16(&rect, -SYSMETRICS_CXDLGFRAME, -SYSMETRICS_CYDLGFRAME);
688             else if (wndPtr->dwStyle & WS_BORDER)
689                 InflateRect16(&rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER);
690             if (!PtInRect16( &rect, pt )) return HTBORDER;
691         }
692
693         /* Check caption */
694
695         if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
696         {
697             rect.top += sysMetrics[SM_CYCAPTION] - 1;
698             if (!PtInRect16( &rect, pt ))
699             {
700                 /* Check system menu */
701                 if (wndPtr->dwStyle & WS_SYSMENU)
702                     rect.left += SYSMETRICS_CXSIZE;
703                 if (pt.x <= rect.left) return HTSYSMENU;
704                 /* Check maximize box */
705                 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
706                     rect.right -= SYSMETRICS_CXSIZE + 1;
707                 if (pt.x >= rect.right) return HTMAXBUTTON;
708                 /* Check minimize box */
709                 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
710                     rect.right -= SYSMETRICS_CXSIZE + 1;
711                 if (pt.x >= rect.right) return HTMINBUTTON;
712                 return HTCAPTION;
713             }
714         }
715     }
716
717       /* Check client area */
718
719     ScreenToClient16( wndPtr->hwndSelf, &pt );
720     GetClientRect16( wndPtr->hwndSelf, &rect );
721     if (PtInRect16( &rect, pt )) return HTCLIENT;
722
723       /* Check vertical scroll bar */
724
725     if (wndPtr->dwStyle & WS_VSCROLL)
726     {
727         rect.right += SYSMETRICS_CXVSCROLL;
728         if (PtInRect16( &rect, pt )) return HTVSCROLL;
729     }
730
731       /* Check horizontal scroll bar */
732
733     if (wndPtr->dwStyle & WS_HSCROLL)
734     {
735         rect.bottom += SYSMETRICS_CYHSCROLL;
736         if (PtInRect16( &rect, pt ))
737         {
738               /* Check size box */
739             if ((wndPtr->dwStyle & WS_VSCROLL) &&
740                 (pt.x >= rect.right - SYSMETRICS_CXVSCROLL))
741                 return HTSIZE;
742             return HTHSCROLL;
743         }
744     }
745
746       /* Check menu bar */
747
748     if (HAS_MENU(wndPtr))
749     {
750         if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
751             return HTMENU;
752     }
753
754       /* Should never get here */
755     return HTERROR;
756 }
757
758
759 /***********************************************************************
760  * NC_DoNCHitTest95
761  *
762  * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
763  *
764  * FIXME:  Just a modified copy of the Win 3.1 version.
765  */
766
767 LONG
768 NC_DoNCHitTest95 (WND *wndPtr, POINT16 pt )
769 {
770     RECT16 rect;
771
772     TRACE(nonclient, "hwnd=%04x pt=%d,%d\n",
773                       wndPtr->hwndSelf, pt.x, pt.y );
774
775     GetWindowRect16 (wndPtr->hwndSelf, &rect );
776     if (!PtInRect16( &rect, pt )) return HTNOWHERE;
777
778     if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
779
780     if (!(wndPtr->flags & WIN_MANAGED))
781     {
782         /* Check borders */
783         if (HAS_SIZEFRAME( wndPtr->dwStyle ))
784         {
785             InflateRect16( &rect, -SYSMETRICS_CXFRAME, -SYSMETRICS_CYFRAME );
786 /*            if (wndPtr->dwStyle & WS_BORDER) */
787 /*                InflateRect16(&rect,-SYSMETRICS_CXBORDER,-SYSMETRICS_CYBORDER); */
788             if (!PtInRect16( &rect, pt ))
789             {
790                 /* Check top sizing border */
791                 if (pt.y < rect.top)
792                 {
793                     if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTTOPLEFT;
794                     if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTTOPRIGHT;
795                     return HTTOP;
796                 }
797                 /* Check bottom sizing border */
798                 if (pt.y >= rect.bottom)
799                 {
800                     if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTBOTTOMLEFT;
801                     if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTBOTTOMRIGHT;
802                     return HTBOTTOM;
803                 }
804                 /* Check left sizing border */
805                 if (pt.x < rect.left)
806                 {
807                     if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPLEFT;
808                     if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMLEFT;
809                     return HTLEFT;
810                 }
811                 /* Check right sizing border */
812                 if (pt.x >= rect.right)
813                 {
814                     if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPRIGHT;
815                     if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMRIGHT;
816                     return HTRIGHT;
817                 }
818             }
819         }
820         else  /* No thick frame */
821         {
822             if (HAS_FIXEDFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
823                 InflateRect16(&rect, -SYSMETRICS_CXDLGFRAME, -SYSMETRICS_CYDLGFRAME);
824 /*            else if (wndPtr->dwStyle & WS_BORDER) */
825 /*                InflateRect16(&rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER); */
826             if (!PtInRect16( &rect, pt )) return HTBORDER;
827         }
828
829         /* Check caption */
830
831         if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
832         {
833             if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
834                 rect.top += sysMetrics[SM_CYSMCAPTION] - 1;
835             else
836                 rect.top += sysMetrics[SM_CYCAPTION] - 1;
837             if (!PtInRect16( &rect, pt ))
838             {
839                 /* Check system menu */
840                 if ((wndPtr->dwStyle & WS_SYSMENU) &&
841                     ((wndPtr->class->hIconSm) || (wndPtr->class->hIcon)))
842                     rect.left += sysMetrics[SM_CYCAPTION] - 1;
843                 if (pt.x < rect.left) return HTSYSMENU;
844
845                 /* Check close button */
846                 if (wndPtr->dwStyle & WS_SYSMENU)
847                     rect.right -= sysMetrics[SM_CYCAPTION] - 1;
848                 if (pt.x > rect.right) return HTCLOSE;
849
850                 /* Check maximize box */
851                 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
852                     rect.right -= SYSMETRICS_CXSIZE + 1;
853                 if (pt.x > rect.right) return HTMAXBUTTON;
854
855                 /* Check minimize box */
856                 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
857                     rect.right -= SYSMETRICS_CXSIZE + 1;
858                 if (pt.x > rect.right) return HTMINBUTTON;
859                 return HTCAPTION;
860             }
861         }
862     }
863
864       /* Check client area */
865
866     ScreenToClient16( wndPtr->hwndSelf, &pt );
867     GetClientRect16( wndPtr->hwndSelf, &rect );
868     if (PtInRect16( &rect, pt )) return HTCLIENT;
869
870       /* Check vertical scroll bar */
871
872     if (wndPtr->dwStyle & WS_VSCROLL)
873     {
874         rect.right += SYSMETRICS_CXVSCROLL;
875         if (PtInRect16( &rect, pt )) return HTVSCROLL;
876     }
877
878       /* Check horizontal scroll bar */
879
880     if (wndPtr->dwStyle & WS_HSCROLL)
881     {
882         rect.bottom += SYSMETRICS_CYHSCROLL;
883         if (PtInRect16( &rect, pt ))
884         {
885               /* Check size box */
886             if ((wndPtr->dwStyle & WS_VSCROLL) &&
887                 (pt.x >= rect.right - SYSMETRICS_CXVSCROLL))
888                 return HTSIZE;
889             return HTHSCROLL;
890         }
891     }
892
893       /* Check menu bar */
894
895     if (HAS_MENU(wndPtr))
896     {
897         if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
898             return HTMENU;
899     }
900
901       /* Should never get here */
902     return HTERROR;
903 }
904
905
906 /***********************************************************************
907  * NC_HandleNCHitTest
908  *
909  * Handle a WM_NCHITTEST message. Called from DefWindowProc().
910  */
911 LONG
912 NC_HandleNCHitTest (HWND hwnd , POINT16 pt)
913 {
914     LONG retvalue;
915     WND *wndPtr = WIN_FindWndPtr (hwnd);
916
917     if (!wndPtr)
918         return HTERROR;
919
920     if (TWEAK_WineLook == WIN31_LOOK)
921         retvalue = NC_DoNCHitTest (wndPtr, pt);
922     else
923         retvalue = NC_DoNCHitTest95 (wndPtr, pt);
924     WIN_ReleaseWndPtr(wndPtr);
925     return retvalue;
926 }
927
928
929 /***********************************************************************
930  *           NC_DrawSysButton
931  */
932 void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down )
933 {
934     RECT rect;
935     HDC hdcMem;
936     HBITMAP hbitmap;
937     WND *wndPtr = WIN_FindWndPtr( hwnd );
938
939     if( !(wndPtr->flags & WIN_MANAGED) )
940     {
941       NC_GetInsideRect( hwnd, &rect );
942       hdcMem = CreateCompatibleDC( hdc );
943       hbitmap = SelectObject( hdcMem, hbitmapClose );
944       BitBlt(hdc, rect.left, rect.top, SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE,
945                hdcMem, (wndPtr->dwStyle & WS_CHILD) ? SYSMETRICS_CXSIZE : 0, 0,
946                down ? NOTSRCCOPY : SRCCOPY );
947       SelectObject( hdcMem, hbitmap );
948       DeleteDC( hdcMem );
949     }
950     WIN_ReleaseWndPtr(wndPtr);
951 }
952
953
954 /***********************************************************************
955  *           NC_DrawMaxButton
956  */
957 static void NC_DrawMaxButton( HWND hwnd, HDC16 hdc, BOOL down )
958 {
959     RECT rect;
960     WND *wndPtr = WIN_FindWndPtr( hwnd );
961     HDC hdcMem;
962
963     if( !(wndPtr->flags & WIN_MANAGED) )
964     {
965       NC_GetInsideRect( hwnd, &rect );
966       hdcMem = CreateCompatibleDC( hdc );
967       SelectObject( hdcMem,  (IsZoomed(hwnd) 
968                              ? (down ? hbitmapRestoreD : hbitmapRestore)
969                              : (down ? hbitmapMaximizeD : hbitmapMaximize)) );
970       BitBlt( hdc, rect.right - SYSMETRICS_CXSIZE - 1, rect.top,
971                 SYSMETRICS_CXSIZE + 1, SYSMETRICS_CYSIZE, hdcMem, 0, 0,
972                 SRCCOPY );
973       DeleteDC( hdcMem );
974     }
975     WIN_ReleaseWndPtr(wndPtr);
976
977 }
978
979
980 /***********************************************************************
981  *           NC_DrawMinButton
982  */
983 static void NC_DrawMinButton( HWND hwnd, HDC16 hdc, BOOL down )
984 {
985     RECT rect;
986     WND *wndPtr = WIN_FindWndPtr( hwnd );
987     HDC hdcMem;
988
989     if( !(wndPtr->flags & WIN_MANAGED) )
990     {
991       NC_GetInsideRect( hwnd, &rect );
992       hdcMem = CreateCompatibleDC( hdc );
993       SelectObject( hdcMem, (down ? hbitmapMinimizeD : hbitmapMinimize) );
994       if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= SYSMETRICS_CXSIZE+1;
995       BitBlt( hdc, rect.right - SYSMETRICS_CXSIZE - 1, rect.top,
996                 SYSMETRICS_CXSIZE + 1, SYSMETRICS_CYSIZE, hdcMem, 0, 0,
997                 SRCCOPY );
998       DeleteDC( hdcMem );
999     }
1000     WIN_ReleaseWndPtr(wndPtr);
1001 }
1002
1003
1004 /******************************************************************************
1005  *
1006  *   void  NC_DrawSysButton95(
1007  *      HWND32  hwnd,
1008  *      HDC32  hdc,
1009  *      BOOL32  down )
1010  *
1011  *   Draws the Win95 system icon.
1012  *
1013  *   Revision history
1014  *        05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1015  *             Original implementation from NC_DrawSysButton source.
1016  *        11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1017  *             Fixed most bugs.
1018  *
1019  *****************************************************************************/
1020
1021 BOOL
1022 NC_DrawSysButton95 (HWND hwnd, HDC hdc, BOOL down)
1023 {
1024     WND *wndPtr = WIN_FindWndPtr( hwnd );
1025
1026     if( !(wndPtr->flags & WIN_MANAGED) )
1027     {
1028         HICON  hIcon = 0;
1029         RECT rect;
1030
1031         NC_GetInsideRect95( hwnd, &rect );
1032
1033         if (wndPtr->class->hIconSm)
1034             hIcon = wndPtr->class->hIconSm;
1035         else if (wndPtr->class->hIcon)
1036             hIcon = wndPtr->class->hIcon;
1037
1038         if (hIcon)
1039             DrawIconEx (hdc, rect.left + 2, rect.top + 2, hIcon,
1040                           sysMetrics[SM_CXSMICON],
1041                           sysMetrics[SM_CYSMICON],
1042                           0, 0, DI_NORMAL);
1043
1044         WIN_ReleaseWndPtr(wndPtr);
1045         return (hIcon != 0);
1046     }
1047     WIN_ReleaseWndPtr(wndPtr);
1048     return FALSE;
1049 }
1050
1051
1052 /******************************************************************************
1053  *
1054  *   void  NC_DrawCloseButton95(
1055  *      HWND32  hwnd,
1056  *      HDC32  hdc,
1057  *      BOOL32  down )
1058  *
1059  *   Draws the Win95 close button.
1060  *
1061  *   Revision history
1062  *        11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1063  *             Original implementation from NC_DrawSysButton95 source.
1064  *
1065  *****************************************************************************/
1066
1067 void NC_DrawCloseButton95 (HWND hwnd, HDC hdc, BOOL down)
1068 {
1069     RECT rect;
1070     HDC hdcMem;
1071     WND *wndPtr = WIN_FindWndPtr( hwnd );
1072
1073     if( !(wndPtr->flags & WIN_MANAGED) )
1074     {
1075         BITMAP bmp;
1076         HBITMAP hBmp, hOldBmp;
1077
1078         NC_GetInsideRect95( hwnd, &rect );
1079
1080         hdcMem = CreateCompatibleDC( hdc );
1081         hBmp = down ? hbitmapCloseD : hbitmapClose;
1082         hOldBmp = SelectObject (hdcMem, hBmp);
1083         GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1084         BitBlt (hdc, rect.right - (sysMetrics[SM_CYCAPTION] + 1 + bmp.bmWidth) / 2,
1085                   rect.top + (sysMetrics[SM_CYCAPTION] - 1 - bmp.bmHeight) / 2,
1086                   bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);
1087
1088         SelectObject (hdcMem, hOldBmp);
1089         DeleteDC (hdcMem);
1090     }
1091     WIN_ReleaseWndPtr(wndPtr);
1092 }
1093
1094 /******************************************************************************
1095  *
1096  *   NC_DrawMaxButton95(
1097  *      HWND32  hwnd,
1098  *      HDC16  hdc,
1099  *      BOOL32  down )
1100  *
1101  *   Draws the maximize button for Win95 style windows.
1102  *
1103  *   Bugs
1104  *        Many.  Spacing might still be incorrect.  Need to fit a close
1105  *        button between the max button and the edge.
1106  *        Should scale the image with the title bar.  And more...
1107  *
1108  *   Revision history
1109  *        05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1110  *             Original implementation.
1111  *
1112  *****************************************************************************/
1113
1114 static void  NC_DrawMaxButton95(HWND hwnd,HDC16 hdc,BOOL down )
1115 {
1116     RECT rect;
1117     HDC hdcMem;
1118     WND *wndPtr = WIN_FindWndPtr( hwnd );
1119
1120     if( !(wndPtr->flags & WIN_MANAGED))
1121     {
1122         BITMAP  bmp;
1123         HBITMAP  hBmp,hOldBmp;
1124
1125         NC_GetInsideRect95( hwnd, &rect );
1126         hdcMem = CreateCompatibleDC( hdc );
1127        hBmp = IsZoomed(hwnd) ?
1128                                 (down ? hbitmapRestoreD : hbitmapRestore ) :
1129                                (down ? hbitmapMaximizeD: hbitmapMaximize);
1130         hOldBmp=SelectObject( hdcMem, hBmp );
1131         GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1132
1133         if (wndPtr->dwStyle & WS_SYSMENU)
1134             rect.right -= sysMetrics[SM_CYCAPTION] + 1;
1135         
1136         BitBlt( hdc, rect.right - (sysMetrics[SM_CXSIZE] + bmp.bmWidth) / 2,
1137                   rect.top + (sysMetrics[SM_CYCAPTION] - 1 - bmp.bmHeight) / 2,
1138                   bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1139         SelectObject (hdcMem, hOldBmp);
1140         DeleteDC( hdcMem );
1141     }
1142     WIN_ReleaseWndPtr(wndPtr);
1143 }
1144
1145 /******************************************************************************
1146  *
1147  *   NC_DrawMinButton95(
1148  *      HWND32  hwnd,
1149  *      HDC16  hdc,
1150  *      BOOL32  down )
1151  *
1152  *   Draws the minimize button for Win95 style windows.
1153  *
1154  *   Bugs
1155  *        Many.  Spacing is still incorrect.  Should scale the image with the
1156  *        title bar.  And more...
1157  *
1158  *   Revision history
1159  *        05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1160  *             Original implementation.
1161  *
1162  *****************************************************************************/
1163
1164 static void  NC_DrawMinButton95(HWND hwnd,HDC16 hdc,BOOL down )
1165 {
1166     RECT rect;
1167     HDC hdcMem;
1168     WND *wndPtr = WIN_FindWndPtr( hwnd );
1169
1170     if( !(wndPtr->flags & WIN_MANAGED))
1171         
1172     {
1173        BITMAP  bmp;
1174        HBITMAP  hBmp,hOldBmp;
1175         
1176         NC_GetInsideRect95( hwnd, &rect );
1177
1178        hdcMem = CreateCompatibleDC( hdc );
1179        hBmp = down ? hbitmapMinimizeD : hbitmapMinimize;
1180        hOldBmp= SelectObject( hdcMem, hBmp );
1181         GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1182
1183         if (wndPtr->dwStyle & WS_SYSMENU)
1184             rect.right -= sysMetrics[SM_CYCAPTION] + 1;
1185
1186         if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
1187             rect.right += -1 - (sysMetrics[SM_CXSIZE] + bmp.bmWidth) / 2;
1188
1189         BitBlt( hdc, rect.right - (sysMetrics[SM_CXSIZE] + bmp.bmWidth) / 2,
1190                   rect.top + (sysMetrics[SM_CYCAPTION] - 1 - bmp.bmHeight) / 2,
1191                   bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1192
1193        SelectObject (hdcMem, hOldBmp);
1194         DeleteDC( hdcMem );
1195     }
1196     WIN_ReleaseWndPtr(wndPtr);
1197 }
1198
1199 /***********************************************************************
1200  *           NC_DrawFrame
1201  *
1202  * Draw a window frame inside the given rectangle, and update the rectangle.
1203  * The correct pen for the frame must be selected in the DC.
1204  */
1205 static void NC_DrawFrame( HDC hdc, RECT *rect, BOOL dlgFrame,
1206                           BOOL active )
1207 {
1208     INT width, height;
1209
1210     if (TWEAK_WineLook != WIN31_LOOK)
1211         ERR (nonclient, "Called in Win95 mode. Aiee! Please report this.\n" );
1212
1213     if (dlgFrame)
1214     {
1215         width = SYSMETRICS_CXDLGFRAME - 1;
1216         height = SYSMETRICS_CYDLGFRAME - 1;
1217         SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1218                                                 COLOR_INACTIVECAPTION) );
1219     }
1220     else
1221     {
1222         width = SYSMETRICS_CXFRAME - 1;
1223         height = SYSMETRICS_CYFRAME - 1;
1224         SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1225                                                 COLOR_INACTIVEBORDER) );
1226     }
1227
1228       /* Draw frame */
1229     PatBlt( hdc, rect->left, rect->top,
1230               rect->right - rect->left, height, PATCOPY );
1231     PatBlt( hdc, rect->left, rect->top,
1232               width, rect->bottom - rect->top, PATCOPY );
1233     PatBlt( hdc, rect->left, rect->bottom - 1,
1234               rect->right - rect->left, -height, PATCOPY );
1235     PatBlt( hdc, rect->right - 1, rect->top,
1236               -width, rect->bottom - rect->top, PATCOPY );
1237
1238     if (dlgFrame)
1239     {
1240         InflateRect( rect, -width, -height );
1241     } 
1242     else
1243     {
1244         INT decYOff = SYSMETRICS_CXFRAME + SYSMETRICS_CXSIZE;
1245         INT decXOff = SYSMETRICS_CYFRAME + SYSMETRICS_CYSIZE;
1246
1247       /* Draw inner rectangle */
1248
1249         SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1250         Rectangle( hdc, rect->left + width, rect->top + height,
1251                      rect->right - width , rect->bottom - height );
1252
1253       /* Draw the decorations */
1254
1255         MoveToEx( hdc, rect->left, rect->top + decYOff, NULL );
1256         LineTo( hdc, rect->left + width, rect->top + decYOff );
1257         MoveToEx( hdc, rect->right - 1, rect->top + decYOff, NULL );
1258         LineTo( hdc, rect->right - width - 1, rect->top + decYOff );
1259         MoveToEx( hdc, rect->left, rect->bottom - decYOff, NULL );
1260         LineTo( hdc, rect->left + width, rect->bottom - decYOff );
1261         MoveToEx( hdc, rect->right - 1, rect->bottom - decYOff, NULL );
1262         LineTo( hdc, rect->right - width - 1, rect->bottom - decYOff );
1263
1264         MoveToEx( hdc, rect->left + decXOff, rect->top, NULL );
1265         LineTo( hdc, rect->left + decXOff, rect->top + height);
1266         MoveToEx( hdc, rect->left + decXOff, rect->bottom - 1, NULL );
1267         LineTo( hdc, rect->left + decXOff, rect->bottom - height - 1 );
1268         MoveToEx( hdc, rect->right - decXOff, rect->top, NULL );
1269         LineTo( hdc, rect->right - decXOff, rect->top + height );
1270         MoveToEx( hdc, rect->right - decXOff, rect->bottom - 1, NULL );
1271         LineTo( hdc, rect->right - decXOff, rect->bottom - height - 1 );
1272
1273         InflateRect( rect, -width - 1, -height - 1 );
1274     }
1275 }
1276
1277
1278 /******************************************************************************
1279  *
1280  *   void  NC_DrawFrame95(
1281  *      HDC32  hdc,
1282  *      RECT32  *rect,
1283  *      BOOL32  dlgFrame,
1284  *      BOOL32  active )
1285  *
1286  *   Draw a window frame inside the given rectangle, and update the rectangle.
1287  *   The correct pen for the frame must be selected in the DC.
1288  *
1289  *   Bugs
1290  *        Many.  First, just what IS a frame in Win95?  Note that the 3D look
1291  *        on the outer edge is handled by NC_DoNCPaint95.  As is the inner
1292  *        edge.  The inner rectangle just inside the frame is handled by the
1293  *        Caption code.
1294  *
1295  *        In short, for most people, this function should be a nop (unless
1296  *        you LIKE thick borders in Win95/NT4.0 -- I've been working with
1297  *        them lately, but just to get this code right).  Even so, it doesn't
1298  *        appear to be so.  It's being worked on...
1299  * 
1300  *   Revision history
1301  *        06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1302  *             Original implementation (based on NC_DrawFrame)
1303  *        02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1304  *             Some minor fixes.
1305  *
1306  *****************************************************************************/
1307
1308 static void  NC_DrawFrame95(
1309     HDC  hdc,
1310     RECT  *rect,
1311     BOOL  dlgFrame,
1312     BOOL  active )
1313 {
1314     INT width, height;
1315
1316     if (dlgFrame)
1317     {
1318         width = sysMetrics[SM_CXDLGFRAME] - sysMetrics[SM_CXEDGE];
1319         height = sysMetrics[SM_CYDLGFRAME] - sysMetrics[SM_CYEDGE];
1320     }
1321     else
1322     {
1323         width = sysMetrics[SM_CXFRAME] - sysMetrics[SM_CXEDGE];
1324         height = sysMetrics[SM_CYFRAME] - sysMetrics[SM_CYEDGE];
1325     }
1326
1327     SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1328                 COLOR_INACTIVEBORDER) );
1329
1330     /* Draw frame */
1331     PatBlt( hdc, rect->left, rect->top,
1332               rect->right - rect->left, height, PATCOPY );
1333     PatBlt( hdc, rect->left, rect->top,
1334               width, rect->bottom - rect->top, PATCOPY );
1335     PatBlt( hdc, rect->left, rect->bottom - 1,
1336               rect->right - rect->left, -height, PATCOPY );
1337     PatBlt( hdc, rect->right - 1, rect->top - 1,
1338               -width, rect->bottom - rect->top, PATCOPY );
1339
1340     InflateRect( rect, -width, -height );
1341 }
1342
1343 /***********************************************************************
1344  *           NC_DrawMovingFrame
1345  *
1346  * Draw the frame used when moving or resizing window.
1347  *
1348  * FIXME:  This causes problems in Win95 mode.  (why?)
1349  */
1350 static void NC_DrawMovingFrame( HDC hdc, RECT *rect, BOOL thickframe )
1351 {
1352     if (thickframe)
1353     {
1354         RECT16 r16;
1355         CONV_RECT32TO16( rect, &r16 );
1356         FastWindowFrame16( hdc, &r16, SYSMETRICS_CXFRAME,
1357                          SYSMETRICS_CYFRAME, PATINVERT );
1358     }
1359     else DrawFocusRect( hdc, rect );
1360 }
1361
1362
1363 /***********************************************************************
1364  *           NC_DrawCaption
1365  *
1366  * Draw the window caption.
1367  * The correct pen for the window frame must be selected in the DC.
1368  */
1369 static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd,
1370                             DWORD style, BOOL active )
1371 {
1372     RECT r = *rect;
1373     WND * wndPtr = WIN_FindWndPtr( hwnd );
1374     char buffer[256];
1375
1376     if (wndPtr->flags & WIN_MANAGED)
1377     {
1378         WIN_ReleaseWndPtr(wndPtr);
1379         return;
1380     }
1381
1382     if (!hbitmapClose)
1383     {
1384         if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1385         {
1386             WIN_ReleaseWndPtr(wndPtr);
1387             return;
1388         }
1389         hbitmapCloseD    = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED) );
1390         hbitmapMinimize  = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1391         hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1392         hbitmapMaximize  = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1393         hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1394         hbitmapRestore   = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1395         hbitmapRestoreD  = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1396     }
1397     
1398     if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
1399     {
1400         HBRUSH hbrushOld = SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW) );
1401         PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
1402         PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
1403         PatBlt( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
1404         r.left++;
1405         r.right--;
1406         SelectObject( hdc, hbrushOld );
1407     }
1408     WIN_ReleaseWndPtr(wndPtr);
1409     MoveTo16( hdc, r.left, r.bottom );
1410     LineTo( hdc, r.right, r.bottom );
1411
1412     if (style & WS_SYSMENU)
1413     {
1414         NC_DrawSysButton( hwnd, hdc, FALSE );
1415         r.left += SYSMETRICS_CXSIZE + 1;
1416         MoveTo16( hdc, r.left - 1, r.top );
1417         LineTo( hdc, r.left - 1, r.bottom );
1418     }
1419     if (style & WS_MAXIMIZEBOX)
1420     {
1421         NC_DrawMaxButton( hwnd, hdc, FALSE );
1422         r.right -= SYSMETRICS_CXSIZE + 1;
1423     }
1424     if (style & WS_MINIMIZEBOX)
1425     {
1426         NC_DrawMinButton( hwnd, hdc, FALSE );
1427         r.right -= SYSMETRICS_CXSIZE + 1;
1428     }
1429
1430     FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1431                                             COLOR_INACTIVECAPTION) );
1432
1433     if (GetWindowTextA( hwnd, buffer, sizeof(buffer) ))
1434     {
1435         if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1436         else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1437         SetBkMode( hdc, TRANSPARENT );
1438         DrawTextA( hdc, buffer, -1, &r,
1439                      DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );
1440     }
1441 }
1442
1443
1444 /******************************************************************************
1445  *
1446  *   NC_DrawCaption95(
1447  *      HDC32  hdc,
1448  *      RECT32 *rect,
1449  *      HWND32 hwnd,
1450  *      DWORD  style,
1451  *      BOOL32 active )
1452  *
1453  *   Draw the window caption for Win95 style windows.
1454  *   The correct pen for the window frame must be selected in the DC.
1455  *
1456  *   Bugs
1457  *        Hey, a function that finally works!  Well, almost.
1458  *        It's being worked on.
1459  *
1460  *   Revision history
1461  *        05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1462  *             Original implementation.
1463  *        02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1464  *             Some minor fixes.
1465  *
1466  *****************************************************************************/
1467
1468 static void  NC_DrawCaption95(
1469     HDC  hdc,
1470     RECT *rect,
1471     HWND hwnd,
1472     DWORD  style,
1473     DWORD  exStyle,
1474     BOOL active )
1475 {
1476     RECT  r = *rect;
1477     WND     *wndPtr = WIN_FindWndPtr( hwnd );
1478     char    buffer[256];
1479     HPEN  hPrevPen;
1480
1481     if (wndPtr->flags & WIN_MANAGED)
1482     {
1483         WIN_ReleaseWndPtr(wndPtr);
1484         return;
1485     }
1486     WIN_ReleaseWndPtr(wndPtr);
1487
1488     hPrevPen = SelectObject( hdc, GetSysColorPen(COLOR_3DFACE) );
1489     MoveToEx( hdc, r.left, r.bottom - 1, NULL );
1490     LineTo( hdc, r.right, r.bottom - 1 );
1491     SelectObject( hdc, hPrevPen );
1492     r.bottom--;
1493
1494     FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1495                                             COLOR_INACTIVECAPTION) );
1496
1497     if (!hbitmapClose) {
1498         if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1499             return;
1500         hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED));
1501         hbitmapMinimize  = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1502         hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1503         hbitmapMaximize  = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1504         hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1505         hbitmapRestore   = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1506         hbitmapRestoreD  = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1507     }
1508
1509     if ((style & WS_SYSMENU) && !(exStyle & WS_EX_TOOLWINDOW)) {
1510         if (NC_DrawSysButton95 (hwnd, hdc, FALSE))
1511             r.left += sysMetrics[SM_CYCAPTION] - 1;
1512     }
1513     if (style & WS_SYSMENU) {
1514         NC_DrawCloseButton95 (hwnd, hdc, FALSE);
1515         r.right -= sysMetrics[SM_CYCAPTION] - 1;
1516     }
1517     if (style & WS_MAXIMIZEBOX) {
1518         NC_DrawMaxButton95( hwnd, hdc, FALSE );
1519         r.right -= SYSMETRICS_CXSIZE + 1;
1520     }
1521     if (style & WS_MINIMIZEBOX) {
1522         NC_DrawMinButton95( hwnd, hdc, FALSE );
1523         r.right -= SYSMETRICS_CXSIZE + 1;
1524     }
1525
1526     if (GetWindowTextA( hwnd, buffer, sizeof(buffer) )) {
1527         NONCLIENTMETRICSA nclm;
1528         HFONT hFont, hOldFont;
1529         nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1530         SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1531         if (exStyle & WS_EX_TOOLWINDOW)
1532             hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
1533         else
1534             hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
1535         hOldFont = SelectObject (hdc, hFont);
1536         if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1537         else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1538         SetBkMode( hdc, TRANSPARENT );
1539         r.left += 2;
1540         DrawTextA( hdc, buffer, -1, &r,
1541                      DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
1542         DeleteObject (SelectObject (hdc, hOldFont));
1543     }
1544 }
1545
1546
1547
1548 /***********************************************************************
1549  *           NC_DoNCPaint
1550  *
1551  * Paint the non-client area. clip is currently unused.
1552  */
1553 void NC_DoNCPaint( WND* wndPtr, HRGN clip, BOOL suppress_menupaint )
1554 {
1555     HDC hdc;
1556     RECT rect;
1557     BOOL active;
1558     HWND hwnd = wndPtr->hwndSelf;
1559
1560     if ( wndPtr->dwStyle & WS_MINIMIZE ||
1561         !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1562
1563     active  = wndPtr->flags & WIN_NCACTIVATED;
1564
1565     TRACE(nonclient, "%04x %d\n", hwnd, active );
1566
1567     if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1568                               ((clip > 1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN): 0) ))) return;
1569
1570     if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1571                         wndPtr->rectClient.top-wndPtr->rectWindow.top,
1572                         wndPtr->rectClient.right-wndPtr->rectWindow.left,
1573                         wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1574         == NULLREGION)
1575     {
1576         ReleaseDC( hwnd, hdc );
1577         return;
1578     }
1579
1580     rect.top = rect.left = 0;
1581     rect.right  = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1582     rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1583
1584     SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1585
1586     if (!(wndPtr->flags & WIN_MANAGED))
1587     {
1588         if ((wndPtr->dwStyle & WS_BORDER) || (wndPtr->dwStyle & WS_DLGFRAME) ||
1589             (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME))
1590         {
1591             SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1592             Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1593             InflateRect( &rect, -1, -1 );
1594         }
1595
1596         if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle )) 
1597             NC_DrawFrame( hdc, &rect, TRUE, active );
1598         else if (wndPtr->dwStyle & WS_THICKFRAME)
1599             NC_DrawFrame(hdc, &rect, FALSE, active );
1600
1601         if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1602         {
1603             RECT r = rect;
1604             r.bottom = rect.top + SYSMETRICS_CYSIZE;
1605             rect.top += SYSMETRICS_CYSIZE + SYSMETRICS_CYBORDER;
1606             NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active );
1607         }
1608     }
1609
1610     if (HAS_MENU(wndPtr))
1611     {
1612         RECT r = rect;
1613         r.bottom = rect.top + SYSMETRICS_CYMENU;  /* default height */
1614         rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint );
1615     }
1616
1617       /* Draw the scroll-bars */
1618
1619     if (wndPtr->dwStyle & WS_VSCROLL)
1620         SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1621     if (wndPtr->dwStyle & WS_HSCROLL)
1622         SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1623
1624       /* Draw the "size-box" */
1625
1626     if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1627     {
1628         RECT r = rect;
1629         r.left = r.right - SYSMETRICS_CXVSCROLL + 1;
1630         r.top  = r.bottom - SYSMETRICS_CYHSCROLL + 1;
1631         if(wndPtr->dwStyle & WS_BORDER) {
1632           r.left++;
1633           r.top++;
1634         }
1635         FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1636     }    
1637
1638     ReleaseDC( hwnd, hdc );
1639 }
1640
1641
1642 /******************************************************************************
1643  *
1644  *   void  NC_DoNCPaint95(
1645  *      WND  *wndPtr,
1646  *      HRGN32  clip,
1647  *      BOOL32  suppress_menupaint )
1648  *
1649  *   Paint the non-client area for Win95 windows.  The clip region is
1650  *   currently ignored.
1651  *
1652  *   Bugs
1653  *        grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1654  *           misc/tweak.c controls/menu.c  # :-)
1655  *
1656  *   Revision history
1657  *        03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1658  *             Original implementation
1659  *        10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1660  *             Fixed some bugs.
1661  *
1662  *****************************************************************************/
1663
1664 void  NC_DoNCPaint95(
1665     WND  *wndPtr,
1666     HRGN  clip,
1667     BOOL  suppress_menupaint )
1668 {
1669     HDC hdc;
1670     RECT rfuzz, rect, rectClip;
1671     BOOL active;
1672     HWND hwnd = wndPtr->hwndSelf;
1673
1674     if ( wndPtr->dwStyle & WS_MINIMIZE ||
1675         !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1676
1677     active  = wndPtr->flags & WIN_NCACTIVATED;
1678
1679     TRACE(nonclient, "%04x %d\n", hwnd, active );
1680
1681     /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in the call to
1682      * GetDCEx implying that it is allowed not to use it either. However, the suggested
1683      * GetDCEx(    , DCX_WINDOW | DCX_INTERSECTRGN) will cause clipRgn to be deleted
1684      * after ReleaseDC(). Now, how is the "system" supposed to tell what happened?
1685      */
1686
1687     if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1688                               ((clip > 1) ?(DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0) ))) return;
1689
1690
1691     if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1692                         wndPtr->rectClient.top-wndPtr->rectWindow.top,
1693                         wndPtr->rectClient.right-wndPtr->rectWindow.left,
1694                         wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1695         == NULLREGION)
1696     {
1697         ReleaseDC( hwnd, hdc );
1698         return;
1699     }
1700
1701     rect.top = rect.left = 0;
1702     rect.right  = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1703     rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1704
1705     if( clip > 1 )
1706         GetRgnBox( clip, &rectClip );
1707     else
1708     {
1709         clip = 0;
1710         rectClip = rect;
1711     }
1712
1713     SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1714
1715     if(!(wndPtr->flags & WIN_MANAGED)) {
1716         if ((wndPtr->dwStyle & WS_BORDER) && ((wndPtr->dwStyle & WS_DLGFRAME) ||
1717             (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME) || (wndPtr->dwStyle & WS_THICKFRAME))) {
1718             DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1719         }
1720
1721         if (HAS_FIXEDFRAME( wndPtr->dwStyle, wndPtr->dwExStyle )) 
1722             NC_DrawFrame95( hdc, &rect, TRUE, active );
1723         else if (wndPtr->dwStyle & WS_THICKFRAME)
1724             NC_DrawFrame95(hdc, &rect, FALSE, active );
1725
1726         if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1727         {
1728             RECT  r = rect;
1729             if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW) {
1730                 r.bottom = rect.top + sysMetrics[SM_CYSMCAPTION];
1731                 rect.top += sysMetrics[SM_CYSMCAPTION];
1732             }
1733             else {
1734                 r.bottom = rect.top + sysMetrics[SM_CYCAPTION];
1735                 rect.top += sysMetrics[SM_CYCAPTION];
1736             }
1737             if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
1738                 NC_DrawCaption95 (hdc, &r, hwnd, wndPtr->dwStyle,
1739                                   wndPtr->dwExStyle, active);
1740         }
1741     }
1742
1743     if (HAS_MENU(wndPtr))
1744     {
1745         RECT r = rect;
1746         r.bottom = rect.top + sysMetrics[SM_CYMENU];
1747         
1748         TRACE(nonclient, "Calling DrawMenuBar with "
1749                           "rect (%d, %d)-(%d, %d)\n", r.left, r.top,
1750                           r.right, r.bottom);
1751
1752         rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ) + 1;
1753     }
1754
1755     TRACE(nonclient, "After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1756                        rect.left, rect.top, rect.right, rect.bottom );
1757
1758     if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
1759         DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1760
1761     if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
1762         DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1763
1764     /* Draw the scroll-bars */
1765
1766     if (wndPtr->dwStyle & WS_VSCROLL)
1767         SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1768     if (wndPtr->dwStyle & WS_HSCROLL)
1769         SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1770
1771     /* Draw the "size-box" */
1772     if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1773     {
1774         RECT r = rect;
1775         r.left = r.right - SYSMETRICS_CXVSCROLL + 1;
1776         r.top  = r.bottom - SYSMETRICS_CYHSCROLL + 1;
1777         FillRect( hdc, &r,  GetSysColorBrush(COLOR_SCROLLBAR) );
1778     }    
1779
1780     ReleaseDC( hwnd, hdc );
1781 }
1782
1783
1784
1785
1786 /***********************************************************************
1787  *           NC_HandleNCPaint
1788  *
1789  * Handle a WM_NCPAINT message. Called from DefWindowProc().
1790  */
1791 LONG NC_HandleNCPaint( HWND hwnd , HRGN clip)
1792 {
1793     WND* wndPtr = WIN_FindWndPtr( hwnd );
1794
1795     if( wndPtr && wndPtr->dwStyle & WS_VISIBLE )
1796     {
1797         if( wndPtr->dwStyle & WS_MINIMIZE )
1798             WINPOS_RedrawIconTitle( hwnd );
1799         else if (TWEAK_WineLook == WIN31_LOOK)
1800             NC_DoNCPaint( wndPtr, clip, FALSE );
1801         else
1802             NC_DoNCPaint95( wndPtr, clip, FALSE );
1803     }
1804     WIN_ReleaseWndPtr(wndPtr);
1805     return 0;
1806 }
1807
1808
1809 /***********************************************************************
1810  *           NC_HandleNCActivate
1811  *
1812  * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1813  */
1814 LONG NC_HandleNCActivate( WND *wndPtr, WPARAM16 wParam )
1815 {
1816     WORD wStateChange;
1817
1818     if( wParam ) wStateChange = !(wndPtr->flags & WIN_NCACTIVATED);
1819     else wStateChange = wndPtr->flags & WIN_NCACTIVATED;
1820
1821     if( wStateChange )
1822     {
1823         if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
1824         else wndPtr->flags &= ~WIN_NCACTIVATED;
1825
1826         if( wndPtr->dwStyle & WS_MINIMIZE ) 
1827             WINPOS_RedrawIconTitle( wndPtr->hwndSelf );
1828         else if (TWEAK_WineLook == WIN31_LOOK)
1829             NC_DoNCPaint( wndPtr, (HRGN)1, FALSE );
1830         else
1831             NC_DoNCPaint95( wndPtr, (HRGN)1, FALSE );
1832     }
1833     return TRUE;
1834 }
1835
1836
1837 /***********************************************************************
1838  *           NC_HandleSetCursor
1839  *
1840  * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1841  */
1842 LONG NC_HandleSetCursor( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
1843 {
1844     if (hwnd != (HWND)wParam) return 0;  /* Don't set the cursor for child windows */
1845
1846     switch(LOWORD(lParam))
1847     {
1848     case HTERROR:
1849         {
1850             WORD msg = HIWORD( lParam );
1851             if ((msg == WM_LBUTTONDOWN) || (msg == WM_MBUTTONDOWN) ||
1852                 (msg == WM_RBUTTONDOWN))
1853                 MessageBeep(0);
1854         }
1855         break;
1856
1857     case HTCLIENT:
1858         {
1859             WND *wndPtr;
1860             BOOL retvalue;
1861             
1862             if (!(wndPtr = WIN_FindWndPtr( hwnd ))) break;
1863             if (wndPtr->class->hCursor)
1864             {
1865                 SetCursor16( wndPtr->class->hCursor );
1866                 retvalue = TRUE;
1867             }
1868             else retvalue = FALSE;
1869             WIN_ReleaseWndPtr(wndPtr);
1870             return retvalue;
1871         }
1872
1873     case HTLEFT:
1874     case HTRIGHT:
1875         return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZEWE16 ) );
1876
1877     case HTTOP:
1878     case HTBOTTOM:
1879         return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENS16 ) );
1880
1881     case HTTOPLEFT:
1882     case HTBOTTOMRIGHT: 
1883         return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENWSE16 ) );
1884
1885     case HTTOPRIGHT:
1886     case HTBOTTOMLEFT:
1887         return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENESW16 ) );
1888     }
1889
1890     /* Default cursor: arrow */
1891     return (LONG)SetCursor16( LoadCursor16( 0, IDC_ARROW16 ) );
1892 }
1893
1894 /***********************************************************************
1895  *           NC_GetSysPopupPos
1896  */
1897 BOOL NC_GetSysPopupPos( WND* wndPtr, RECT* rect )
1898 {
1899   if( wndPtr->hSysMenu )
1900   {
1901       if( wndPtr->dwStyle & WS_MINIMIZE )
1902           GetWindowRect( wndPtr->hwndSelf, rect );
1903       else
1904       {
1905           if (TWEAK_WineLook == WIN31_LOOK)
1906               NC_GetInsideRect( wndPtr->hwndSelf, rect );
1907           else
1908               NC_GetInsideRect95( wndPtr->hwndSelf, rect );
1909           OffsetRect( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
1910           if (wndPtr->dwStyle & WS_CHILD)
1911               ClientToScreen( wndPtr->parent->hwndSelf, (POINT *)rect );
1912           if (TWEAK_WineLook == WIN31_LOOK) {
1913             rect->right = rect->left + SYSMETRICS_CXSIZE;
1914             rect->bottom = rect->top + SYSMETRICS_CYSIZE;
1915           }
1916           else {
1917             rect->right = rect->left + sysMetrics[SM_CYCAPTION] - 1;
1918             rect->bottom = rect->top + sysMetrics[SM_CYCAPTION] - 1;
1919           }
1920       }
1921       return TRUE;
1922   }
1923   return FALSE;
1924 }
1925
1926 /***********************************************************************
1927  *           NC_StartSizeMove
1928  *
1929  * Initialisation of a move or resize, when initiatied from a menu choice.
1930  * Return hit test code for caption or sizing border.
1931  */
1932 static LONG NC_StartSizeMove( WND* wndPtr, WPARAM16 wParam,
1933                               POINT16 *capturePoint )
1934 {
1935     LONG hittest = 0;
1936     POINT16 pt;
1937     MSG msg;
1938
1939     if ((wParam & 0xfff0) == SC_MOVE)
1940     {
1941           /* Move pointer at the center of the caption */
1942         RECT rect;
1943         if (TWEAK_WineLook == WIN31_LOOK)
1944             NC_GetInsideRect( wndPtr->hwndSelf, &rect );
1945         else
1946             NC_GetInsideRect95( wndPtr->hwndSelf, &rect );
1947         if (wndPtr->dwStyle & WS_SYSMENU)
1948             rect.left += SYSMETRICS_CXSIZE + 1;
1949         if (wndPtr->dwStyle & WS_MINIMIZEBOX)
1950             rect.right -= SYSMETRICS_CXSIZE + 1;
1951         if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
1952             rect.right -= SYSMETRICS_CXSIZE + 1;
1953         pt.x = wndPtr->rectWindow.left + (rect.right - rect.left) / 2;
1954         pt.y = wndPtr->rectWindow.top + rect.top + SYSMETRICS_CYSIZE/2;
1955         hittest = HTCAPTION;
1956         *capturePoint = pt;
1957     }
1958     else  /* SC_SIZE */
1959     {
1960         while(!hittest)
1961         {
1962             MSG_InternalGetMessage( &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE );
1963             switch(msg.message)
1964             {
1965             case WM_MOUSEMOVE:
1966                 CONV_POINT32TO16(&msg.pt, &pt);
1967                 hittest = NC_HandleNCHitTest( wndPtr->hwndSelf, pt );
1968                 if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
1969                     hittest = 0;
1970                 break;
1971
1972             case WM_LBUTTONUP:
1973                 return 0;
1974
1975             case WM_KEYDOWN:
1976                 switch(msg.wParam)
1977                 {
1978                 case VK_UP:
1979                     hittest = HTTOP;
1980                     pt.x =(wndPtr->rectWindow.left+wndPtr->rectWindow.right)/2;
1981                     pt.y = wndPtr->rectWindow.top + SYSMETRICS_CYFRAME / 2;
1982                     break;
1983                 case VK_DOWN:
1984                     hittest = HTBOTTOM;
1985                     pt.x =(wndPtr->rectWindow.left+wndPtr->rectWindow.right)/2;
1986                     pt.y = wndPtr->rectWindow.bottom - SYSMETRICS_CYFRAME / 2;
1987                     break;
1988                 case VK_LEFT:
1989                     hittest = HTLEFT;
1990                     pt.x = wndPtr->rectWindow.left + SYSMETRICS_CXFRAME / 2;
1991                     pt.y =(wndPtr->rectWindow.top+wndPtr->rectWindow.bottom)/2;
1992                     break;
1993                 case VK_RIGHT:
1994                     hittest = HTRIGHT;
1995                     pt.x = wndPtr->rectWindow.right - SYSMETRICS_CXFRAME / 2;
1996                     pt.y =(wndPtr->rectWindow.top+wndPtr->rectWindow.bottom)/2;
1997                     break;
1998                 case VK_RETURN:
1999                 case VK_ESCAPE: return 0;
2000                 }
2001             }
2002         }
2003         *capturePoint = pt;
2004     }
2005     SetCursorPos( pt.x, pt.y );
2006     NC_HandleSetCursor( wndPtr->hwndSelf, 
2007                         wndPtr->hwndSelf, MAKELONG( hittest, WM_MOUSEMOVE ));
2008     return hittest;
2009 }
2010
2011
2012 /***********************************************************************
2013  *           NC_DoSizeMove
2014  *
2015  * Perform SC_MOVE and SC_SIZE commands.               `
2016  */
2017 static void NC_DoSizeMove( HWND hwnd, WORD wParam )
2018 {
2019     MSG msg;
2020     RECT sizingRect, mouseRect;
2021     HDC hdc;
2022     LONG hittest = (LONG)(wParam & 0x0f);
2023     HCURSOR16 hDragCursor = 0, hOldCursor = 0;
2024     POINT minTrack, maxTrack;
2025     POINT16 capturePoint, pt;
2026     WND *     wndPtr = WIN_FindWndPtr( hwnd );
2027     BOOL    thickframe = HAS_THICKFRAME( wndPtr->dwStyle );
2028     BOOL    iconic = wndPtr->dwStyle & WS_MINIMIZE;
2029     BOOL    moved = FALSE;
2030     DWORD     dwPoint = GetMessagePos ();
2031
2032     capturePoint = pt = *(POINT16*)&dwPoint;
2033
2034     if (IsZoomed(hwnd) || !IsWindowVisible(hwnd) ||
2035         (wndPtr->flags & WIN_MANAGED)) goto END;
2036
2037     if ((wParam & 0xfff0) == SC_MOVE)
2038     {
2039         if (!(wndPtr->dwStyle & WS_CAPTION)) goto END;
2040         if (!hittest) 
2041              hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2042         if (!hittest) goto END;
2043     }
2044     else  /* SC_SIZE */
2045     {
2046         if (!thickframe) goto END;
2047         if ( hittest && hittest != HTSYSMENU ) hittest += 2;
2048         else
2049         {
2050             SetCapture(hwnd);
2051             hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2052             if (!hittest)
2053             {
2054                 ReleaseCapture();
2055                 goto END;
2056             }
2057         }
2058     }
2059
2060       /* Get min/max info */
2061
2062     WINPOS_GetMinMaxInfo( wndPtr, NULL, NULL, &minTrack, &maxTrack );
2063     sizingRect = wndPtr->rectWindow;
2064     if (wndPtr->dwStyle & WS_CHILD)
2065         GetClientRect( wndPtr->parent->hwndSelf, &mouseRect );
2066     else 
2067         SetRect(&mouseRect, 0, 0, SYSMETRICS_CXSCREEN, SYSMETRICS_CYSCREEN);
2068     if (ON_LEFT_BORDER(hittest))
2069     {
2070         mouseRect.left  = MAX( mouseRect.left, sizingRect.right-maxTrack.x );
2071         mouseRect.right = MIN( mouseRect.right, sizingRect.right-minTrack.x );
2072     }
2073     else if (ON_RIGHT_BORDER(hittest))
2074     {
2075         mouseRect.left  = MAX( mouseRect.left, sizingRect.left+minTrack.x );
2076         mouseRect.right = MIN( mouseRect.right, sizingRect.left+maxTrack.x );
2077     }
2078     if (ON_TOP_BORDER(hittest))
2079     {
2080         mouseRect.top    = MAX( mouseRect.top, sizingRect.bottom-maxTrack.y );
2081         mouseRect.bottom = MIN( mouseRect.bottom,sizingRect.bottom-minTrack.y);
2082     }
2083     else if (ON_BOTTOM_BORDER(hittest))
2084     {
2085         mouseRect.top    = MAX( mouseRect.top, sizingRect.top+minTrack.y );
2086         mouseRect.bottom = MIN( mouseRect.bottom, sizingRect.top+maxTrack.y );
2087     }
2088     if (wndPtr->dwStyle & WS_CHILD)
2089     {
2090         MapWindowPoints( wndPtr->parent->hwndSelf, 0, 
2091                 (LPPOINT)&mouseRect, 2 );
2092     }
2093     SendMessage16( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
2094
2095     if (GetCapture() != hwnd) SetCapture( hwnd );    
2096
2097     if (wndPtr->dwStyle & WS_CHILD)
2098     {
2099           /* Retrieve a default cache DC (without using the window style) */
2100         hdc = GetDCEx( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
2101     }
2102     else
2103     {  /* Grab the server only when moving top-level windows without desktop */
2104         hdc = GetDC( 0 );
2105     }
2106
2107     wndPtr->pDriver->pPreSizeMove(wndPtr);
2108
2109     if( iconic ) /* create a cursor for dragging */
2110     {
2111         HICON16 hIcon = (wndPtr->class->hIcon) ? wndPtr->class->hIcon
2112                       : (HICON16)SendMessage16( hwnd, WM_QUERYDRAGICON, 0, 0L);
2113         if( hIcon ) hDragCursor =  CURSORICON_IconToCursor( hIcon, TRUE );
2114         if( !hDragCursor ) iconic = FALSE;
2115     }
2116
2117     if( !iconic ) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2118
2119     while(1)
2120     {
2121         int dx = 0, dy = 0;
2122
2123         MSG_InternalGetMessage( &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE );
2124
2125           /* Exit on button-up, Return, or Esc */
2126         if ((msg.message == WM_LBUTTONUP) ||
2127             ((msg.message == WM_KEYDOWN) && 
2128              ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
2129
2130         if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
2131             continue;  /* We are not interested in other messages */
2132
2133         dwPoint = GetMessagePos ();
2134         pt = *(POINT16*)&dwPoint;
2135         
2136         if (msg.message == WM_KEYDOWN) switch(msg.wParam)
2137         {
2138             case VK_UP:    pt.y -= 8; break;
2139             case VK_DOWN:  pt.y += 8; break;
2140             case VK_LEFT:  pt.x -= 8; break;
2141             case VK_RIGHT: pt.x += 8; break;            
2142         }
2143
2144         pt.x = MAX( pt.x, mouseRect.left );
2145         pt.x = MIN( pt.x, mouseRect.right );
2146         pt.y = MAX( pt.y, mouseRect.top );
2147         pt.y = MIN( pt.y, mouseRect.bottom );
2148
2149         dx = pt.x - capturePoint.x;
2150         dy = pt.y - capturePoint.y;
2151
2152         if (dx || dy)
2153         {
2154             if( !moved )
2155             {
2156                 moved = TRUE;
2157                 if( iconic ) /* ok, no system popup tracking */
2158                 {
2159                     hOldCursor = SetCursor(hDragCursor);
2160                     ShowCursor( TRUE );
2161                     WINPOS_ShowIconTitle( wndPtr, FALSE );
2162                 }
2163             }
2164
2165             if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
2166             else
2167             {
2168                 RECT newRect = sizingRect;
2169
2170                 if (hittest == HTCAPTION) OffsetRect( &newRect, dx, dy );
2171                 if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
2172                 else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
2173                 if (ON_TOP_BORDER(hittest)) newRect.top += dy;
2174                 else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
2175                 if( !iconic )
2176                 {
2177                     NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2178                     NC_DrawMovingFrame( hdc, &newRect, thickframe );
2179                 }
2180                 capturePoint = pt;
2181                 sizingRect = newRect;
2182             }
2183         }
2184     }
2185
2186     ReleaseCapture();
2187     if( iconic )
2188     {
2189         if( moved ) /* restore cursors, show icon title later on */
2190         {
2191             ShowCursor( FALSE );
2192             SetCursor( hOldCursor );
2193         }
2194         DestroyCursor( hDragCursor );
2195     }
2196     else
2197         NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2198
2199     if (wndPtr->dwStyle & WS_CHILD)
2200         ReleaseDC( wndPtr->parent->hwndSelf, hdc );
2201     else
2202     {
2203         ReleaseDC( 0, hdc );
2204     }
2205
2206     wndPtr->pDriver->pPostSizeMove(wndPtr);
2207
2208     if (HOOK_IsHooked( WH_CBT ))
2209     {
2210         RECT16* pr = SEGPTR_NEW(RECT16);
2211         if( pr )
2212         {
2213             CONV_RECT32TO16( &sizingRect, pr );
2214             if( HOOK_CallHooks16( WH_CBT, HCBT_MOVESIZE, hwnd,
2215                                 (LPARAM)SEGPTR_GET(pr)) )
2216                 sizingRect = wndPtr->rectWindow;
2217             else
2218                 CONV_RECT16TO32( pr, &sizingRect );
2219             SEGPTR_FREE(pr);
2220         }
2221     }
2222     SendMessage16( hwnd, WM_EXITSIZEMOVE, 0, 0 );
2223     SendMessage16( hwnd, WM_SETVISIBLE, !IsIconic16(hwnd), 0L);
2224
2225     if( moved && !((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
2226     {
2227         /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
2228         SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top,
2229                         sizingRect.right - sizingRect.left,
2230                         sizingRect.bottom - sizingRect.top,
2231                       ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
2232     }
2233
2234     if( IsWindow(hwnd) )
2235         if( wndPtr->dwStyle & WS_MINIMIZE )
2236         {
2237             /* Single click brings up the system menu when iconized */
2238
2239             if( !moved ) 
2240             {
2241                  if( wndPtr->dwStyle & WS_SYSMENU ) 
2242                      SendMessage16( hwnd, WM_SYSCOMMAND,
2243                                     SC_MOUSEMENU + HTSYSMENU, *((LPARAM*)&pt));
2244             }
2245             else WINPOS_ShowIconTitle( wndPtr, TRUE );
2246         }
2247
2248 END:
2249     WIN_ReleaseWndPtr(wndPtr);
2250 }
2251
2252
2253 /***********************************************************************
2254  *           NC_TrackMinMaxBox
2255  *
2256  * Track a mouse button press on the minimize or maximize box.
2257  */
2258 static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
2259 {
2260     MSG msg;
2261     POINT16 pt16;
2262     HDC hdc = GetWindowDC( hwnd );
2263     BOOL pressed = TRUE;
2264     void  (*paintButton)(HWND, HDC16, BOOL);
2265
2266     SetCapture( hwnd );
2267     if (wParam == HTMINBUTTON)
2268         paintButton =
2269             (TWEAK_WineLook == WIN31_LOOK) ? &NC_DrawMinButton : &NC_DrawMinButton95;
2270     else
2271         paintButton =
2272             (TWEAK_WineLook == WIN31_LOOK) ? &NC_DrawMaxButton : &NC_DrawMaxButton95;
2273
2274     (*paintButton)( hwnd, hdc, TRUE );
2275
2276     do
2277     {
2278         BOOL oldstate = pressed;
2279         MSG_InternalGetMessage( &msg, 0, 0, 0, PM_REMOVE, FALSE );
2280         CONV_POINT32TO16( &msg.pt, &pt16 );
2281
2282         pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2283         if (pressed != oldstate)
2284            (*paintButton)( hwnd, hdc, pressed );
2285     } while (msg.message != WM_LBUTTONUP);
2286
2287     (*paintButton)( hwnd, hdc, FALSE );
2288
2289     ReleaseCapture();
2290     ReleaseDC( hwnd, hdc );
2291     if (!pressed) return;
2292
2293     if (wParam == HTMINBUTTON) 
2294         SendMessage16( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&pt16 );
2295     else
2296         SendMessage16( hwnd, WM_SYSCOMMAND, 
2297                   IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, *(LONG*)&pt16 );
2298 }
2299
2300
2301 /***********************************************************************
2302  * NC_TrackCloseButton95
2303  *
2304  * Track a mouse button press on the Win95 close button.
2305  */
2306 static void
2307 NC_TrackCloseButton95 (HWND hwnd, WORD wParam)
2308 {
2309     MSG msg;
2310     POINT16 pt16;
2311     HDC hdc = GetWindowDC( hwnd );
2312     BOOL pressed = TRUE;
2313
2314     SetCapture( hwnd );
2315
2316     NC_DrawCloseButton95 (hwnd, hdc, TRUE);
2317
2318     do
2319     {
2320         BOOL oldstate = pressed;
2321         MSG_InternalGetMessage( &msg, 0, 0, 0, PM_REMOVE, FALSE );
2322         CONV_POINT32TO16( &msg.pt, &pt16 );
2323
2324         pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2325         if (pressed != oldstate)
2326            NC_DrawCloseButton95 (hwnd, hdc, pressed);
2327     } while (msg.message != WM_LBUTTONUP);
2328
2329     NC_DrawCloseButton95 (hwnd, hdc, FALSE);
2330
2331     ReleaseCapture();
2332     ReleaseDC( hwnd, hdc );
2333     if (!pressed) return;
2334
2335     SendMessage16( hwnd, WM_SYSCOMMAND, SC_CLOSE, *(LONG*)&pt16 );
2336 }
2337
2338
2339 /***********************************************************************
2340  *           NC_TrackScrollBar
2341  *
2342  * Track a mouse button press on the horizontal or vertical scroll-bar.
2343  */
2344 static void NC_TrackScrollBar( HWND hwnd, WPARAM wParam, POINT pt )
2345 {
2346     MSG16 *msg;
2347     INT scrollbar;
2348     WND *wndPtr = WIN_FindWndPtr( hwnd );
2349
2350     if ((wParam & 0xfff0) == SC_HSCROLL)
2351     {
2352         if ((wParam & 0x0f) != HTHSCROLL) goto END;
2353         scrollbar = SB_HORZ;
2354     }
2355     else  /* SC_VSCROLL */
2356     {
2357         if ((wParam & 0x0f) != HTVSCROLL) goto END;
2358         scrollbar = SB_VERT;
2359     }
2360
2361     if (!(msg = SEGPTR_NEW(MSG16))) goto END;
2362     pt.x -= wndPtr->rectWindow.left;
2363     pt.y -= wndPtr->rectWindow.top;
2364     SetCapture( hwnd );
2365     SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt );
2366
2367     do
2368     {
2369         GetMessage16( SEGPTR_GET(msg), 0, 0, 0 );
2370         switch(msg->message)
2371         {
2372         case WM_LBUTTONUP:
2373         case WM_MOUSEMOVE:
2374         case WM_SYSTIMER:
2375             pt.x = LOWORD(msg->lParam) + wndPtr->rectClient.left - 
2376               wndPtr->rectWindow.left;
2377             pt.y = HIWORD(msg->lParam) + wndPtr->rectClient.top - 
2378               wndPtr->rectWindow.top;
2379             SCROLL_HandleScrollEvent( hwnd, scrollbar, msg->message, pt );
2380             break;
2381         default:
2382             TranslateMessage16( msg );
2383             DispatchMessage16( msg );
2384             break;
2385         }
2386         if (!IsWindow( hwnd ))
2387         {
2388             ReleaseCapture();
2389             break;
2390         }
2391     } while (msg->message != WM_LBUTTONUP);
2392     SEGPTR_FREE(msg);
2393 END:
2394     WIN_ReleaseWndPtr(wndPtr);
2395 }
2396
2397 /***********************************************************************
2398  *           NC_HandleNCLButtonDown
2399  *
2400  * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2401  */
2402 LONG NC_HandleNCLButtonDown( WND* pWnd, WPARAM16 wParam, LPARAM lParam )
2403 {
2404     HWND hwnd = pWnd->hwndSelf;
2405
2406     switch(wParam)  /* Hit test */
2407     {
2408     case HTCAPTION:
2409          hwnd = WIN_GetTopParent(hwnd);
2410
2411          if( WINPOS_SetActiveWindow(hwnd, TRUE, TRUE) || (GetActiveWindow() == hwnd) )
2412                 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
2413          break;
2414
2415     case HTSYSMENU:
2416          if( pWnd->dwStyle & WS_SYSMENU )
2417          {
2418              if( !(pWnd->dwStyle & WS_MINIMIZE) )
2419              {
2420                 HDC hDC = GetWindowDC(hwnd);
2421                 if (TWEAK_WineLook == WIN31_LOOK)
2422                     NC_DrawSysButton( hwnd, hDC, TRUE );
2423                 else
2424                     NC_DrawSysButton95( hwnd, hDC, TRUE );
2425                 ReleaseDC( hwnd, hDC );
2426              }
2427              SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
2428          }
2429          break;
2430
2431     case HTMENU:
2432         SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam );
2433         break;
2434
2435     case HTHSCROLL:
2436         SendMessage16( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
2437         break;
2438
2439     case HTVSCROLL:
2440         SendMessage16( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
2441         break;
2442
2443     case HTMINBUTTON:
2444     case HTMAXBUTTON:
2445         NC_TrackMinMaxBox( hwnd, wParam );
2446         break;
2447
2448     case HTCLOSE:
2449         if (TWEAK_WineLook >= WIN95_LOOK)
2450             NC_TrackCloseButton95 (hwnd, wParam);
2451         break;
2452
2453     case HTLEFT:
2454     case HTRIGHT:
2455     case HTTOP:
2456     case HTTOPLEFT:
2457     case HTTOPRIGHT:
2458     case HTBOTTOM:
2459     case HTBOTTOMLEFT:
2460     case HTBOTTOMRIGHT:
2461         /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2462         SendMessage16( hwnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam);
2463         break;
2464
2465     case HTBORDER:
2466         break;
2467     }
2468     return 0;
2469 }
2470
2471
2472 /***********************************************************************
2473  *           NC_HandleNCLButtonDblClk
2474  *
2475  * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2476  */
2477 LONG NC_HandleNCLButtonDblClk( WND *pWnd, WPARAM16 wParam, LPARAM lParam )
2478 {
2479     /*
2480      * if this is an icon, send a restore since we are handling
2481      * a double click
2482      */
2483     if (pWnd->dwStyle & WS_MINIMIZE)
2484     {
2485         SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_RESTORE, lParam );
2486         return 0;
2487     } 
2488
2489     switch(wParam)  /* Hit test */
2490     {
2491     case HTCAPTION:
2492         /* stop processing if WS_MAXIMIZEBOX is missing */
2493         if (pWnd->dwStyle & WS_MAXIMIZEBOX)
2494             SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND,
2495                       (pWnd->dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
2496                       lParam );
2497         break;
2498
2499     case HTSYSMENU:
2500         if (!(pWnd->class->style & CS_NOCLOSE))
2501             SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, lParam );
2502         break;
2503
2504     case HTHSCROLL:
2505         SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL,
2506                        lParam );
2507         break;
2508
2509     case HTVSCROLL:
2510         SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL,
2511                        lParam );
2512         break;
2513     }
2514     return 0;
2515 }
2516
2517
2518 /***********************************************************************
2519  *           NC_HandleSysCommand
2520  *
2521  * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2522  */
2523 LONG NC_HandleSysCommand( HWND hwnd, WPARAM16 wParam, POINT16 pt )
2524 {
2525     WND *wndPtr = WIN_FindWndPtr( hwnd );
2526     POINT pt32;
2527     UINT16 uCommand = wParam & 0xFFF0;
2528
2529     TRACE(nonclient, "Handling WM_SYSCOMMAND %x %d,%d\n", 
2530                       wParam, pt.x, pt.y );
2531
2532     if (wndPtr->dwStyle & WS_CHILD && uCommand != SC_KEYMENU )
2533         ScreenToClient16( wndPtr->parent->hwndSelf, &pt );
2534
2535     switch (uCommand)
2536     {
2537     case SC_SIZE:
2538     case SC_MOVE:
2539         NC_DoSizeMove( hwnd, wParam );
2540         break;
2541
2542     case SC_MINIMIZE:
2543         ShowWindow( hwnd, SW_MINIMIZE ); 
2544         break;
2545
2546     case SC_MAXIMIZE:
2547         ShowWindow( hwnd, SW_MAXIMIZE );
2548         break;
2549
2550     case SC_RESTORE:
2551         ShowWindow( hwnd, SW_RESTORE );
2552         break;
2553
2554     case SC_CLOSE:
2555         WIN_ReleaseWndPtr(wndPtr);
2556         return SendMessage16( hwnd, WM_CLOSE, 0, 0 );
2557
2558     case SC_VSCROLL:
2559     case SC_HSCROLL:
2560         CONV_POINT16TO32( &pt, &pt32 );
2561         NC_TrackScrollBar( hwnd, wParam, pt32 );
2562         break;
2563
2564     case SC_MOUSEMENU:
2565         CONV_POINT16TO32( &pt, &pt32 );
2566         MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt32 );
2567         break;
2568
2569     case SC_KEYMENU:
2570         MENU_TrackKbdMenuBar( wndPtr , wParam , pt.x );
2571         break;
2572         
2573     case SC_TASKLIST:
2574         WinExec( "taskman.exe", SW_SHOWNORMAL ); 
2575         break;
2576
2577     case SC_SCREENSAVE:
2578         if (wParam == SC_ABOUTWINE)
2579             ShellAboutA(hwnd,"Wine", WINE_RELEASE_INFO, 0);
2580         else 
2581           if (wParam == SC_PUTMARK)
2582             TRACE(shell,"Mark requested by user\n");
2583         break;
2584   
2585     case SC_HOTKEY:
2586     case SC_ARRANGE:
2587     case SC_NEXTWINDOW:
2588     case SC_PREVWINDOW:
2589         FIXME (nonclient, "unimplemented!\n");
2590         break;
2591     }
2592     WIN_ReleaseWndPtr(wndPtr);
2593     return 0;
2594 }