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