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