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