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