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