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