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