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