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