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