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