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