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