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