Release 980712
[wine/multimedia.git] / windows / nonclient.c
blobf9917eecd9492b66c01f7886c24f7cf646474a59
1 /*
2 * Non-client area window functions
4 * Copyright 1994 Alexandre Julliard
6 */
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"
29 int NC_CaptionLeftNudge;
30 int NC_CaptionTopNudge;
31 int NC_SysControlNudge;
32 int NC_MaxControlNudge;
33 int NC_MinControlNudge;
34 UINT32 NC_CaptionTextFlags;
35 HBRUSH32 NC_WinHighlight95;
36 HBRUSH32 NC_WinShadow95;
38 static HBITMAP16 hbitmapClose = 0;
39 static HBITMAP16 hbitmapCloseD = 0;
40 static HBITMAP16 hbitmapMinimize = 0;
41 static HBITMAP16 hbitmapMinimizeD = 0;
42 static HBITMAP16 hbitmapMaximize = 0;
43 static HBITMAP16 hbitmapMaximizeD = 0;
44 static HBITMAP16 hbitmapRestore = 0;
45 static HBITMAP16 hbitmapRestoreD = 0;
47 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
49 /* Some useful macros */
50 #define HAS_DLGFRAME(style,exStyle) \
51 (((exStyle) & WS_EX_DLGMODALFRAME) || \
52 (((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
54 #define HAS_THICKFRAME(style) \
55 (((style) & WS_THICKFRAME) && \
56 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
58 #define HAS_FIXEDFRAME(style,exStyle) \
59 (((((exStyle) & WS_EX_DLGMODALFRAME) || \
60 ((style) & WS_DLGFRAME)) && ((style) & WS_BORDER)) && \
61 !((style) & WS_THICKFRAME))
63 #define HAS_SIZEFRAME(style) \
64 (((style) & WS_THICKFRAME) && \
65 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
67 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
69 #define ON_LEFT_BORDER(hit) \
70 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
71 #define ON_RIGHT_BORDER(hit) \
72 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
73 #define ON_TOP_BORDER(hit) \
74 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
75 #define ON_BOTTOM_BORDER(hit) \
76 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
78 /***********************************************************************
79 * NC_AdjustRect
81 * Compute the size of the window rectangle from the size of the
82 * client rectangle.
84 static void NC_AdjustRect( LPRECT16 rect, DWORD style, BOOL32 menu,
85 DWORD exStyle )
87 if(TWEAK_Win95Look)
88 ERR(nonclient, "Called in Win95 mode. Aiee! Please report this.\n" );
90 if(style & WS_ICONIC) return;
91 /* Decide if the window will be managed (see CreateWindowEx) */
92 if (!(Options.managed && !(style & WS_CHILD) &&
93 ((style & (WS_DLGFRAME | WS_THICKFRAME)) ||
94 (exStyle & WS_EX_DLGMODALFRAME))))
96 if (HAS_DLGFRAME( style, exStyle ))
97 InflateRect16(rect, SYSMETRICS_CXDLGFRAME, SYSMETRICS_CYDLGFRAME );
98 else
100 if (HAS_THICKFRAME(style))
101 InflateRect16( rect, SYSMETRICS_CXFRAME, SYSMETRICS_CYFRAME );
102 if (style & WS_BORDER)
103 InflateRect16( rect, SYSMETRICS_CXBORDER, SYSMETRICS_CYBORDER);
106 if ((style & WS_CAPTION) == WS_CAPTION)
107 rect->top -= SYSMETRICS_CYCAPTION - SYSMETRICS_CYBORDER;
109 if (menu) rect->top -= SYSMETRICS_CYMENU + SYSMETRICS_CYBORDER;
111 if (style & WS_VSCROLL) {
112 rect->right += SYSMETRICS_CXVSCROLL - 1;
113 if(!(style & WS_BORDER))
114 rect->right++;
117 if (style & WS_HSCROLL) {
118 rect->bottom += SYSMETRICS_CYHSCROLL - 1;
119 if(!(style & WS_BORDER))
120 rect->bottom++;
125 /******************************************************************************
126 * NC_AdjustRectOuter95
128 * Computes the size of the "outside" parts of the window based on the
129 * parameters of the client area.
131 + PARAMS
132 * LPRECT16 rect
133 * DWORD style
134 * BOOL32 menu
135 * DWORD exStyle
137 * NOTES
138 * "Outer" parts of a window means the whole window frame, caption and
139 * menu bar. It does not include "inner" parts of the frame like client
140 * edge, static edge or scroll bars.
142 * Revision history
143 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
144 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
146 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
147 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
148 * NC_AdjustRectInner95 and added handling of Win95 styles.
150 *****************************************************************************/
152 static void
153 NC_AdjustRectOuter95 (LPRECT16 rect, DWORD style, BOOL32 menu, DWORD exStyle)
155 if(style & WS_ICONIC) return;
157 /* Decide if the window will be managed (see CreateWindowEx) */
158 if (!(Options.managed && !(style & WS_CHILD) &&
159 ((style & (WS_DLGFRAME | WS_THICKFRAME)) ||
160 (exStyle & WS_EX_DLGMODALFRAME))))
162 if (HAS_FIXEDFRAME( style, exStyle ))
163 InflateRect16(rect, SYSMETRICS_CXDLGFRAME, SYSMETRICS_CYDLGFRAME );
164 else
166 if (HAS_SIZEFRAME(style))
167 InflateRect16( rect, SYSMETRICS_CXFRAME, SYSMETRICS_CYFRAME );
168 #if 0
169 if (style & WS_BORDER)
170 InflateRect16( rect, SYSMETRICS_CXBORDER, SYSMETRICS_CYBORDER);
171 #endif
174 if ((style & WS_CAPTION) == WS_CAPTION)
175 if (exStyle & WS_EX_TOOLWINDOW)
176 rect->top -= SYSMETRICS_CYSMCAPTION;
177 else
178 rect->top -= SYSMETRICS_CYCAPTION;
179 // rect->top -= sysMetrics[SM_CYCAPTION];
182 if (menu)
183 rect->top -= sysMetrics[SM_CYMENU];
187 /******************************************************************************
188 * NC_AdjustRectInner95
190 * Computes the size of the "inside" part of the window based on the
191 * parameters of the client area.
193 + PARAMS
194 * LPRECT16 rect
195 * DWORD style
196 * DWORD exStyle
198 * NOTES
199 * "Inner" part of a window means the window frame inside of the flat
200 * window frame. It includes the client edge, the static edge and the
201 * scroll bars.
203 * Revision history
204 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
205 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
207 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
208 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
209 * NC_AdjustRectInner95 and added handling of Win95 styles.
211 *****************************************************************************/
213 static void
214 NC_AdjustRectInner95 (LPRECT16 rect, DWORD style, DWORD exStyle)
216 if(style & WS_ICONIC) return;
218 if (exStyle & WS_EX_CLIENTEDGE)
219 InflateRect16 (rect, sysMetrics[SM_CXEDGE], sysMetrics[SM_CYEDGE]);
221 if (exStyle & WS_EX_STATICEDGE)
222 InflateRect16 (rect, sysMetrics[SM_CXBORDER], sysMetrics[SM_CYBORDER]);
224 if (style & WS_VSCROLL) rect->right += SYSMETRICS_CXVSCROLL;
225 if (style & WS_HSCROLL) rect->bottom += SYSMETRICS_CYHSCROLL;
229 /***********************************************************************
230 * DrawCaptionTempA (USER32.599)
232 DWORD WINAPI DrawCaptionTemp32A(HWND32 hwnd,HDC32 hdc,LPRECT32 rect,
233 HFONT32 hfont,DWORD x1,LPCSTR str,DWORD x2)
235 FIXME(nonclient,"(%08x,%08x,%p,%08x,%08lx,\"%s\",%08lx): stub\n",
236 hwnd,hdc,rect,hfont,x1,str,x2);
237 return 0;
241 /***********************************************************************
242 * AdjustWindowRect16 (USER.102)
244 BOOL16 WINAPI AdjustWindowRect16( LPRECT16 rect, DWORD style, BOOL16 menu )
246 return AdjustWindowRectEx16( rect, style, menu, 0 );
250 /***********************************************************************
251 * AdjustWindowRect32 (USER32.2)
253 BOOL32 WINAPI AdjustWindowRect32( LPRECT32 rect, DWORD style, BOOL32 menu )
255 return AdjustWindowRectEx32( rect, style, menu, 0 );
259 /***********************************************************************
260 * AdjustWindowRectEx16 (USER.454)
262 BOOL16 WINAPI AdjustWindowRectEx16( LPRECT16 rect, DWORD style,
263 BOOL16 menu, DWORD exStyle )
265 /* Correct the window style */
267 if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
268 style |= WS_CAPTION;
269 style &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD);
270 exStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE |
271 WS_EX_STATICEDGE | WS_EX_TOOLWINDOW);
272 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
274 TRACE(nonclient, "(%d,%d)-(%d,%d) %08lx %d %08lx\n",
275 rect->left, rect->top, rect->right, rect->bottom,
276 style, menu, exStyle );
278 if(TWEAK_Win95Look) {
279 NC_AdjustRectOuter95( rect, style, menu, exStyle );
280 NC_AdjustRectInner95( rect, style, exStyle );
282 else
283 NC_AdjustRect( rect, style, menu, exStyle );
285 return TRUE;
289 /***********************************************************************
290 * AdjustWindowRectEx32 (USER32.3)
292 BOOL32 WINAPI AdjustWindowRectEx32( LPRECT32 rect, DWORD style,
293 BOOL32 menu, DWORD exStyle )
295 RECT16 rect16;
296 BOOL32 ret;
298 CONV_RECT32TO16( rect, &rect16 );
299 ret = AdjustWindowRectEx16( &rect16, style, (BOOL16)menu, exStyle );
300 CONV_RECT16TO32( &rect16, rect );
301 return ret;
305 /***********************************************************************
306 * NC_HandleNCCalcSize
308 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
310 LONG NC_HandleNCCalcSize( WND *pWnd, RECT32 *winRect )
312 RECT16 tmpRect = { 0, 0, 0, 0 };
313 LONG result = 0;
315 if (pWnd->class->style & CS_VREDRAW) result |= WVR_VREDRAW;
316 if (pWnd->class->style & CS_HREDRAW) result |= WVR_HREDRAW;
318 if( !( pWnd->dwStyle & WS_MINIMIZE ) ) {
319 if(TWEAK_Win95Look)
320 NC_AdjustRectOuter95( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
321 else
322 NC_AdjustRect( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
324 winRect->left -= tmpRect.left;
325 winRect->top -= tmpRect.top;
326 winRect->right -= tmpRect.right;
327 winRect->bottom -= tmpRect.bottom;
329 if (HAS_MENU(pWnd)) {
330 TRACE(nonclient, "Calling "
331 "GetMenuBarHeight with HWND 0x%x, width %d, "
332 "at (%d, %d).\n", pWnd->hwndSelf,
333 winRect->right - winRect->left,
334 -tmpRect.left, -tmpRect.top );
336 winRect->top +=
337 MENU_GetMenuBarHeight( pWnd->hwndSelf,
338 winRect->right - winRect->left,
339 -tmpRect.left, -tmpRect.top ) + 1;
342 if (TWEAK_Win95Look) {
343 SetRect16 (&tmpRect, 0, 0, 0, 0);
344 NC_AdjustRectInner95 (&tmpRect, pWnd->dwStyle, pWnd->dwExStyle);
345 winRect->left -= tmpRect.left;
346 winRect->top -= tmpRect.top;
347 winRect->right -= tmpRect.right;
348 winRect->bottom -= tmpRect.bottom;
351 return result;
355 /***********************************************************************
356 * NC_GetInsideRect
358 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
359 * but without the borders (if any).
360 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
362 static void NC_GetInsideRect( HWND32 hwnd, RECT32 *rect )
364 WND * wndPtr = WIN_FindWndPtr( hwnd );
366 rect->top = rect->left = 0;
367 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
368 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
370 if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) return;
372 /* Remove frame from rectangle */
373 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
375 InflateRect32( rect, -SYSMETRICS_CXDLGFRAME, -SYSMETRICS_CYDLGFRAME);
376 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
377 InflateRect32( rect, -1, 0 );
379 else
381 if (HAS_THICKFRAME( wndPtr->dwStyle ))
382 InflateRect32( rect, -SYSMETRICS_CXFRAME, -SYSMETRICS_CYFRAME );
383 if (wndPtr->dwStyle & WS_BORDER)
384 InflateRect32( rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER );
387 return;
391 /***********************************************************************
392 * NC_GetInsideRect95
394 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
395 * but without the borders (if any).
396 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
399 static void
400 NC_GetInsideRect95 (HWND32 hwnd, RECT32 *rect)
402 WND * wndPtr = WIN_FindWndPtr( hwnd );
404 rect->top = rect->left = 0;
405 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
406 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
408 if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) return;
410 /* Remove frame from rectangle */
411 if (HAS_FIXEDFRAME (wndPtr->dwStyle, wndPtr->dwExStyle ))
413 InflateRect32( rect, -SYSMETRICS_CXFIXEDFRAME, -SYSMETRICS_CYFIXEDFRAME);
415 else if (HAS_SIZEFRAME (wndPtr->dwStyle))
417 InflateRect32( rect, -SYSMETRICS_CXSIZEFRAME, -SYSMETRICS_CYSIZEFRAME );
419 /* if (wndPtr->dwStyle & WS_BORDER)
420 InflateRect32( rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER );*/
423 if (wndPtr->dwStyle & WS_CHILD) {
424 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
425 InflateRect32 (rect, -SYSMETRICS_CXEDGE, -SYSMETRICS_CYEDGE);
427 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
428 InflateRect32 (rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER);
431 return;
435 /***********************************************************************
436 * NC_DoNCHitTest
438 * Handle a WM_NCHITTEST message. Called from NC_HandleNcHitTest().
441 LONG NC_DoNCHitTest (WND *wndPtr, POINT16 pt )
443 RECT16 rect;
445 TRACE(nonclient, "hwnd=%04x pt=%d,%d\n",
446 wndPtr->hwndSelf, pt.x, pt.y );
448 GetWindowRect16 (wndPtr->hwndSelf, &rect );
449 if (!PtInRect16( &rect, pt )) return HTNOWHERE;
451 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
453 if (!(wndPtr->flags & WIN_MANAGED))
455 /* Check borders */
456 if (HAS_THICKFRAME( wndPtr->dwStyle ))
458 InflateRect16( &rect, -SYSMETRICS_CXFRAME, -SYSMETRICS_CYFRAME );
459 if (wndPtr->dwStyle & WS_BORDER)
460 InflateRect16(&rect,-SYSMETRICS_CXBORDER,-SYSMETRICS_CYBORDER);
461 if (!PtInRect16( &rect, pt ))
463 /* Check top sizing border */
464 if (pt.y < rect.top)
466 if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTTOPLEFT;
467 if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTTOPRIGHT;
468 return HTTOP;
470 /* Check bottom sizing border */
471 if (pt.y >= rect.bottom)
473 if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTBOTTOMLEFT;
474 if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTBOTTOMRIGHT;
475 return HTBOTTOM;
477 /* Check left sizing border */
478 if (pt.x < rect.left)
480 if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPLEFT;
481 if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMLEFT;
482 return HTLEFT;
484 /* Check right sizing border */
485 if (pt.x >= rect.right)
487 if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPRIGHT;
488 if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMRIGHT;
489 return HTRIGHT;
493 else /* No thick frame */
495 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
496 InflateRect16(&rect, -SYSMETRICS_CXDLGFRAME, -SYSMETRICS_CYDLGFRAME);
497 else if (wndPtr->dwStyle & WS_BORDER)
498 InflateRect16(&rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER);
499 if (!PtInRect16( &rect, pt )) return HTBORDER;
502 /* Check caption */
504 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
506 rect.top += sysMetrics[SM_CYCAPTION] - 1;
507 if (!PtInRect16( &rect, pt ))
509 /* Check system menu */
510 if (wndPtr->dwStyle & WS_SYSMENU)
511 rect.left += SYSMETRICS_CXSIZE;
512 if (pt.x <= rect.left) return HTSYSMENU;
513 /* Check maximize box */
514 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
515 rect.right -= SYSMETRICS_CXSIZE + 1;
516 if (pt.x >= rect.right) return HTMAXBUTTON;
517 /* Check minimize box */
518 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
519 rect.right -= SYSMETRICS_CXSIZE + 1;
520 if (pt.x >= rect.right) return HTMINBUTTON;
521 return HTCAPTION;
526 /* Check client area */
528 ScreenToClient16( wndPtr->hwndSelf, &pt );
529 GetClientRect16( wndPtr->hwndSelf, &rect );
530 if (PtInRect16( &rect, pt )) return HTCLIENT;
532 /* Check vertical scroll bar */
534 if (wndPtr->dwStyle & WS_VSCROLL)
536 rect.right += SYSMETRICS_CXVSCROLL;
537 if (PtInRect16( &rect, pt )) return HTVSCROLL;
540 /* Check horizontal scroll bar */
542 if (wndPtr->dwStyle & WS_HSCROLL)
544 rect.bottom += SYSMETRICS_CYHSCROLL;
545 if (PtInRect16( &rect, pt ))
547 /* Check size box */
548 if ((wndPtr->dwStyle & WS_VSCROLL) &&
549 (pt.x >= rect.right - SYSMETRICS_CXVSCROLL))
550 return HTSIZE;
551 return HTHSCROLL;
555 /* Check menu bar */
557 if (HAS_MENU(wndPtr))
559 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
560 return HTMENU;
563 /* Should never get here */
564 return HTERROR;
568 /***********************************************************************
569 * NC_DoNCHitTest95
571 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
573 * FIXME: Just a copy of the Win 3.1 version.
576 LONG
577 NC_DoNCHitTest95 (WND *wndPtr, POINT16 pt )
579 RECT16 rect;
581 TRACE(nonclient, "hwnd=%04x pt=%d,%d\n",
582 wndPtr->hwndSelf, pt.x, pt.y );
584 GetWindowRect16 (wndPtr->hwndSelf, &rect );
585 if (!PtInRect16( &rect, pt )) return HTNOWHERE;
587 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
589 if (!(wndPtr->flags & WIN_MANAGED))
591 /* Check borders */
592 if (HAS_SIZEFRAME( wndPtr->dwStyle ))
594 InflateRect16( &rect, -SYSMETRICS_CXFRAME, -SYSMETRICS_CYFRAME );
595 // if (wndPtr->dwStyle & WS_BORDER)
596 // InflateRect16(&rect,-SYSMETRICS_CXBORDER,-SYSMETRICS_CYBORDER);
597 if (!PtInRect16( &rect, pt ))
599 /* Check top sizing border */
600 if (pt.y < rect.top)
602 if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTTOPLEFT;
603 if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTTOPRIGHT;
604 return HTTOP;
606 /* Check bottom sizing border */
607 if (pt.y >= rect.bottom)
609 if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTBOTTOMLEFT;
610 if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTBOTTOMRIGHT;
611 return HTBOTTOM;
613 /* Check left sizing border */
614 if (pt.x < rect.left)
616 if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPLEFT;
617 if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMLEFT;
618 return HTLEFT;
620 /* Check right sizing border */
621 if (pt.x >= rect.right)
623 if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPRIGHT;
624 if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMRIGHT;
625 return HTRIGHT;
629 else /* No thick frame */
631 if (HAS_FIXEDFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
632 InflateRect16(&rect, -SYSMETRICS_CXDLGFRAME, -SYSMETRICS_CYDLGFRAME);
633 // else if (wndPtr->dwStyle & WS_BORDER)
634 // InflateRect16(&rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER);
635 if (!PtInRect16( &rect, pt )) return HTBORDER;
638 /* Check caption */
640 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
642 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
643 rect.top += sysMetrics[SM_CYSMCAPTION] - 1;
644 else
645 rect.top += sysMetrics[SM_CYCAPTION] - 1;
646 if (!PtInRect16( &rect, pt ))
648 /* Check system menu */
649 if ((wndPtr->dwStyle & WS_SYSMENU) &&
650 ((wndPtr->class->hIconSm) || (wndPtr->class->hIcon)))
651 rect.left += sysMetrics[SM_CYCAPTION] - 1;
652 if (pt.x < rect.left) return HTSYSMENU;
654 /* Check close button */
655 if (wndPtr->dwStyle & WS_SYSMENU)
656 rect.right -= sysMetrics[SM_CYCAPTION] - 1;
657 if (pt.x > rect.right) return HTCLOSE;
659 /* Check maximize box */
660 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
661 rect.right -= SYSMETRICS_CXSIZE + 1;
662 if (pt.x > rect.right) return HTMAXBUTTON;
664 /* Check minimize box */
665 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
666 rect.right -= SYSMETRICS_CXSIZE + 1;
667 if (pt.x > rect.right) return HTMINBUTTON;
668 return HTCAPTION;
673 /* Check client area */
675 ScreenToClient16( wndPtr->hwndSelf, &pt );
676 GetClientRect16( wndPtr->hwndSelf, &rect );
677 if (PtInRect16( &rect, pt )) return HTCLIENT;
679 /* Check vertical scroll bar */
681 if (wndPtr->dwStyle & WS_VSCROLL)
683 rect.right += SYSMETRICS_CXVSCROLL;
684 if (PtInRect16( &rect, pt )) return HTVSCROLL;
687 /* Check horizontal scroll bar */
689 if (wndPtr->dwStyle & WS_HSCROLL)
691 rect.bottom += SYSMETRICS_CYHSCROLL;
692 if (PtInRect16( &rect, pt ))
694 /* Check size box */
695 if ((wndPtr->dwStyle & WS_VSCROLL) &&
696 (pt.x >= rect.right - SYSMETRICS_CXVSCROLL))
697 return HTSIZE;
698 return HTHSCROLL;
702 /* Check menu bar */
704 if (HAS_MENU(wndPtr))
706 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
707 return HTMENU;
710 /* Should never get here */
711 return HTERROR;
715 /***********************************************************************
716 * NC_HandleNCHitTest
718 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
720 LONG
721 NC_HandleNCHitTest( HWND32 hwnd , POINT16 pt)
723 WND* wndPtr = WIN_FindWndPtr( hwnd );
725 if (!wndPtr)
726 return HTERROR;
728 if(TWEAK_Win95Look)
729 return NC_DoNCHitTest95 (wndPtr, pt);
730 else
731 return NC_DoNCHitTest (wndPtr, pt);
735 /***********************************************************************
736 * NC_DrawSysButton
738 void NC_DrawSysButton( HWND32 hwnd, HDC32 hdc, BOOL32 down )
740 RECT32 rect;
741 HDC32 hdcMem;
742 HBITMAP32 hbitmap;
743 WND *wndPtr = WIN_FindWndPtr( hwnd );
745 if( !(wndPtr->flags & WIN_MANAGED) )
747 NC_GetInsideRect( hwnd, &rect );
748 hdcMem = CreateCompatibleDC32( hdc );
749 hbitmap = SelectObject32( hdcMem, hbitmapClose );
750 BitBlt32(hdc, rect.left, rect.top, SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE,
751 hdcMem, (wndPtr->dwStyle & WS_CHILD) ? SYSMETRICS_CXSIZE : 0, 0,
752 down ? NOTSRCCOPY : SRCCOPY );
753 SelectObject32( hdcMem, hbitmap );
754 DeleteDC32( hdcMem );
759 /***********************************************************************
760 * NC_DrawMaxButton
762 static void NC_DrawMaxButton( HWND32 hwnd, HDC16 hdc, BOOL32 down )
764 RECT32 rect;
765 WND *wndPtr = WIN_FindWndPtr( hwnd );
767 if( !(wndPtr->flags & WIN_MANAGED) )
769 NC_GetInsideRect( hwnd, &rect );
770 GRAPH_DrawBitmap( hdc, (IsZoomed32(hwnd)
771 ? (down ? hbitmapRestoreD : hbitmapRestore)
772 : (down ? hbitmapMaximizeD : hbitmapMaximize)),
773 rect.right - SYSMETRICS_CXSIZE - 1, rect.top,
774 0, 0, SYSMETRICS_CXSIZE+1, SYSMETRICS_CYSIZE, FALSE );
779 /***********************************************************************
780 * NC_DrawMinButton
782 static void NC_DrawMinButton( HWND32 hwnd, HDC16 hdc, BOOL32 down )
784 RECT32 rect;
785 WND *wndPtr = WIN_FindWndPtr( hwnd );
787 if( !(wndPtr->flags & WIN_MANAGED) )
789 NC_GetInsideRect( hwnd, &rect );
790 if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= SYSMETRICS_CXSIZE+1;
791 GRAPH_DrawBitmap( hdc, (down ? hbitmapMinimizeD : hbitmapMinimize),
792 rect.right - SYSMETRICS_CXSIZE - 1, rect.top,
793 0, 0, SYSMETRICS_CXSIZE+1, SYSMETRICS_CYSIZE, FALSE );
798 /******************************************************************************
800 * void NC_DrawSysButton95(
801 * HWND32 hwnd,
802 * HDC32 hdc,
803 * BOOL32 down )
805 * Draws the Win95 system icon.
807 * Revision history
808 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
809 * Original implementation from NC_DrawSysButton source.
810 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
811 * Fixed most bugs.
813 *****************************************************************************/
815 BOOL32
816 NC_DrawSysButton95 (HWND32 hwnd, HDC32 hdc, BOOL32 down)
818 WND *wndPtr = WIN_FindWndPtr( hwnd );
820 if( !(wndPtr->flags & WIN_MANAGED) )
822 HICON32 hIcon = 0;
823 RECT32 rect;
825 NC_GetInsideRect95( hwnd, &rect );
827 if (wndPtr->class->hIconSm)
828 hIcon = wndPtr->class->hIconSm;
829 else if (wndPtr->class->hIcon)
830 hIcon = wndPtr->class->hIcon;
832 if (hIcon)
833 DrawIconEx32 (hdc, rect.left + 2, rect.top + 1, hIcon,
834 sysMetrics[SM_CYCAPTION] - 3,
835 sysMetrics[SM_CYCAPTION] - 3, 0, 0, DI_NORMAL);
836 return (hIcon != 0);
838 return FALSE;
842 /******************************************************************************
844 * void NC_DrawCloseButton95(
845 * HWND32 hwnd,
846 * HDC32 hdc,
847 * BOOL32 down )
849 * Draws the Win95 close button.
851 * Revision history
852 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
853 * Original implementation from NC_DrawSysButton95 source.
855 *****************************************************************************/
857 void
858 NC_DrawCloseButton95 (HWND32 hwnd, HDC32 hdc, BOOL32 down)
860 RECT32 rect;
861 HDC32 hdcMem;
862 WND *wndPtr = WIN_FindWndPtr( hwnd );
864 if( !(wndPtr->flags & WIN_MANAGED) )
866 BITMAP32 bmp;
867 HBITMAP32 hBmp, hOldBmp;
869 NC_GetInsideRect95( hwnd, &rect );
871 hdcMem = CreateCompatibleDC32( hdc );
872 hBmp = /*down ? hbitmapCloseD :*/ hbitmapClose;
873 hOldBmp = SelectObject32 (hdcMem, hBmp);
874 GetObject32A (hBmp, sizeof(BITMAP32), &bmp);
875 BitBlt32 (hdc, rect.right - (sysMetrics[SM_CYCAPTION] + 1 + bmp.bmWidth) / 2,
876 rect.top + (sysMetrics[SM_CYCAPTION] - 1 - bmp.bmHeight) / 2,
877 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, down ? NOTSRCCOPY : SRCCOPY);
879 SelectObject32 (hdcMem, hOldBmp);
880 DeleteDC32 (hdcMem);
885 /******************************************************************************
887 * NC_DrawMaxButton95(
888 * HWND32 hwnd,
889 * HDC16 hdc,
890 * BOOL32 down )
892 * Draws the maximize button for Win95 style windows.
894 * Bugs
895 * Many. Spacing might still be incorrect. Need to fit a close
896 * button between the max button and the edge.
897 * Should scale the image with the title bar. And more...
899 * Revision history
900 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
901 * Original implementation.
903 *****************************************************************************/
905 static void NC_DrawMaxButton95(
906 HWND32 hwnd,
907 HDC16 hdc,
908 BOOL32 down )
910 RECT32 rect;
911 WND *wndPtr = WIN_FindWndPtr( hwnd );
912 SIZE32 bmsz;
913 HBITMAP32 bm;
915 if( !(wndPtr->flags & WIN_MANAGED) &&
916 GetBitmapDimensionEx32((bm = IsZoomed32(hwnd) ?
917 (down ? hbitmapRestoreD : hbitmapRestore ) :
918 (down ? hbitmapMaximizeD : hbitmapMaximize)),
919 &bmsz)) {
921 NC_GetInsideRect95( hwnd, &rect );
923 if (wndPtr->dwStyle & WS_SYSMENU)
924 rect.right -= sysMetrics[SM_CYCAPTION] + 1;
926 GRAPH_DrawBitmap( hdc, bm, rect.right + NC_MinControlNudge -
927 (sysMetrics[SM_CXSIZE] + bmsz.cx) / 2,
928 rect.top + (sysMetrics[SM_CYCAPTION] - 1 - bmsz.cy) / 2,
929 0, 0, bmsz.cx, bmsz.cy, FALSE );
932 return;
936 /******************************************************************************
938 * NC_DrawMinButton95(
939 * HWND32 hwnd,
940 * HDC16 hdc,
941 * BOOL32 down )
943 * Draws the minimize button for Win95 style windows.
945 * Bugs
946 * Many. Spacing is still incorrect. Should scale the image with the
947 * title bar. And more...
949 * Revision history
950 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
951 * Original implementation.
953 *****************************************************************************/
955 static void NC_DrawMinButton95(
956 HWND32 hwnd,
957 HDC16 hdc,
958 BOOL32 down )
960 RECT32 rect;
961 WND *wndPtr = WIN_FindWndPtr( hwnd );
962 SIZE32 bmsz;
963 HBITMAP32 bm;
965 if( !(wndPtr->flags & WIN_MANAGED) &&
966 GetBitmapDimensionEx32((bm = down ? hbitmapMinimizeD :
967 hbitmapMinimize), &bmsz)) {
969 NC_GetInsideRect95( hwnd, &rect );
971 if (wndPtr->dwStyle & WS_SYSMENU)
972 rect.right -= sysMetrics[SM_CYCAPTION] + 1;
974 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
975 rect.right += -1 + NC_MaxControlNudge -
976 (sysMetrics[SM_CXSIZE] + bmsz.cx) / 2;
978 GRAPH_DrawBitmap( hdc, bm, rect.right + NC_MinControlNudge -
979 (sysMetrics[SM_CXSIZE] + bmsz.cx) / 2,
980 rect.top + (sysMetrics[SM_CYCAPTION] - 1 - bmsz.cy) / 2,
981 0, 0, bmsz.cx, bmsz.cy, FALSE );
984 return;
988 /***********************************************************************
989 * NC_DrawFrame
991 * Draw a window frame inside the given rectangle, and update the rectangle.
992 * The correct pen for the frame must be selected in the DC.
994 static void NC_DrawFrame( HDC32 hdc, RECT32 *rect, BOOL32 dlgFrame,
995 BOOL32 active )
997 INT32 width, height;
999 if(TWEAK_Win95Look)
1000 ERR(nonclient, "Called in Win95 mode. Aiee! Please report this.\n" );
1002 if (dlgFrame)
1004 width = SYSMETRICS_CXDLGFRAME - 1;
1005 height = SYSMETRICS_CYDLGFRAME - 1;
1006 SelectObject32( hdc, GetSysColorBrush32(active ? COLOR_ACTIVECAPTION :
1007 COLOR_INACTIVECAPTION) );
1009 else
1011 width = SYSMETRICS_CXFRAME - 1;
1012 height = SYSMETRICS_CYFRAME - 1;
1013 SelectObject32( hdc, GetSysColorBrush32(active ? COLOR_ACTIVEBORDER :
1014 COLOR_INACTIVEBORDER) );
1017 /* Draw frame */
1018 PatBlt32( hdc, rect->left, rect->top,
1019 rect->right - rect->left, height, PATCOPY );
1020 PatBlt32( hdc, rect->left, rect->top,
1021 width, rect->bottom - rect->top, PATCOPY );
1022 PatBlt32( hdc, rect->left, rect->bottom,
1023 rect->right - rect->left, -height, PATCOPY );
1024 PatBlt32( hdc, rect->right, rect->top,
1025 -width, rect->bottom - rect->top, PATCOPY );
1027 if (dlgFrame)
1029 InflateRect32( rect, -width, -height );
1031 else
1033 POINT32 lpt[16];
1035 /* Draw inner rectangle */
1037 GRAPH_DrawRectangle( hdc, rect->left + width,
1038 rect->top + height,
1039 rect->right - rect->left - 2*width ,
1040 rect->bottom - rect->top - 2*height,
1041 (HPEN32)0 );
1043 /* Draw the decorations */
1045 lpt[4].x = lpt[0].x = rect->left;
1046 lpt[5].x = lpt[1].x = rect->left + width;
1047 lpt[6].x = lpt[2].x = rect->right - 1;
1048 lpt[7].x = lpt[3].x = rect->right - width - 1;
1050 lpt[0].y = lpt[1].y = lpt[2].y = lpt[3].y =
1051 rect->top + SYSMETRICS_CYFRAME + SYSMETRICS_CYSIZE;
1052 lpt[4].y = lpt[5].y = lpt[6].y = lpt[7].y =
1053 rect->bottom - SYSMETRICS_CYFRAME - SYSMETRICS_CYSIZE;
1055 lpt[8].x = lpt[9].x = lpt[10].x = lpt[11].x =
1056 rect->left + SYSMETRICS_CXFRAME + SYSMETRICS_CXSIZE;
1057 lpt[12].x = lpt[13].x = lpt[14].x = lpt[15].x =
1058 rect->right - SYSMETRICS_CXFRAME - SYSMETRICS_CYSIZE;
1060 lpt[12].y = lpt[8].y = rect->top;
1061 lpt[13].y = lpt[9].y = rect->top + height;
1062 lpt[14].y = lpt[10].y = rect->bottom - 1;
1063 lpt[15].y = lpt[11].y = rect->bottom - height - 1;
1065 GRAPH_DrawLines( hdc, lpt, 8, (HPEN32)0 ); /* 8 is the maximum */
1066 InflateRect32( rect, -width - 1, -height - 1 );
1071 /******************************************************************************
1073 * void NC_DrawFrame95(
1074 * HDC32 hdc,
1075 * RECT32 *rect,
1076 * BOOL32 dlgFrame,
1077 * BOOL32 active )
1079 * Draw a window frame inside the given rectangle, and update the rectangle.
1080 * The correct pen for the frame must be selected in the DC.
1082 * Bugs
1083 * Many. First, just what IS a frame in Win95? Note that the 3D look
1084 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1085 * edge. The inner rectangle just inside the frame is handled by the
1086 * Caption code.
1088 * In short, for most people, this function should be a nop (unless
1089 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1090 * them lately, but just to get this code right). Even so, it doesn't
1091 * appear to be so. It's being worked on...
1093 * Revision history
1094 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1095 * Original implementation (based on NC_DrawFrame)
1096 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1097 * Some minor fixes.
1099 *****************************************************************************/
1101 static void NC_DrawFrame95(
1102 HDC32 hdc,
1103 RECT32 *rect,
1104 BOOL32 dlgFrame,
1105 BOOL32 active )
1107 INT32 width, height;
1109 if (dlgFrame)
1111 width = sysMetrics[SM_CXDLGFRAME] - sysMetrics[SM_CXEDGE];
1112 height = sysMetrics[SM_CYDLGFRAME] - sysMetrics[SM_CYEDGE];
1114 else
1116 width = sysMetrics[SM_CXFRAME] - sysMetrics[SM_CXEDGE];
1117 height = sysMetrics[SM_CYFRAME] - sysMetrics[SM_CYEDGE];
1120 SelectObject32( hdc, GetSysColorBrush32(active ? COLOR_ACTIVEBORDER :
1121 COLOR_INACTIVEBORDER) );
1123 /* Draw frame */
1124 PatBlt32( hdc, rect->left, rect->top,
1125 rect->right - rect->left, height, PATCOPY );
1126 PatBlt32( hdc, rect->left, rect->top,
1127 width, rect->bottom - rect->top, PATCOPY );
1128 PatBlt32( hdc, rect->left, rect->bottom,
1129 rect->right - rect->left, -height, PATCOPY );
1130 PatBlt32( hdc, rect->right, rect->top,
1131 -width, rect->bottom - rect->top, PATCOPY );
1133 InflateRect32( rect, -width, -height );
1138 /***********************************************************************
1139 * NC_DrawMovingFrame
1141 * Draw the frame used when moving or resizing window.
1143 * FIXME: This causes problems in Win95 mode. (why?)
1145 static void NC_DrawMovingFrame( HDC32 hdc, RECT32 *rect, BOOL32 thickframe )
1147 if (thickframe)
1149 RECT16 r16;
1150 CONV_RECT32TO16( rect, &r16 );
1151 FastWindowFrame( hdc, &r16, SYSMETRICS_CXFRAME,
1152 SYSMETRICS_CYFRAME, PATINVERT );
1154 else DrawFocusRect32( hdc, rect );
1158 /***********************************************************************
1159 * NC_DrawCaption
1161 * Draw the window caption.
1162 * The correct pen for the window frame must be selected in the DC.
1164 static void NC_DrawCaption( HDC32 hdc, RECT32 *rect, HWND32 hwnd,
1165 DWORD style, BOOL32 active )
1167 RECT32 r = *rect;
1168 WND * wndPtr = WIN_FindWndPtr( hwnd );
1169 char buffer[256];
1171 if (wndPtr->flags & WIN_MANAGED) return;
1173 if (!hbitmapClose)
1175 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1176 return;
1177 hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) );
1178 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1179 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1180 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1181 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1182 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1183 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1186 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
1188 HBRUSH32 hbrushOld = SelectObject32(hdc, GetSysColorBrush32(COLOR_WINDOW) );
1189 PatBlt32( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
1190 PatBlt32( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
1191 PatBlt32( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
1192 r.left++;
1193 r.right--;
1194 SelectObject32( hdc, hbrushOld );
1197 MoveTo( hdc, r.left, r.bottom );
1198 LineTo32( hdc, r.right, r.bottom );
1200 if (style & WS_SYSMENU)
1202 NC_DrawSysButton( hwnd, hdc, FALSE );
1203 r.left += SYSMETRICS_CXSIZE + 1;
1204 MoveTo( hdc, r.left - 1, r.top );
1205 LineTo32( hdc, r.left - 1, r.bottom );
1207 if (style & WS_MAXIMIZEBOX)
1209 NC_DrawMaxButton( hwnd, hdc, FALSE );
1210 r.right -= SYSMETRICS_CXSIZE + 1;
1212 if (style & WS_MINIMIZEBOX)
1214 NC_DrawMinButton( hwnd, hdc, FALSE );
1215 r.right -= SYSMETRICS_CXSIZE + 1;
1218 FillRect32( hdc, &r, GetSysColorBrush32(active ? COLOR_ACTIVECAPTION :
1219 COLOR_INACTIVECAPTION) );
1221 if (GetWindowText32A( hwnd, buffer, sizeof(buffer) ))
1223 if (active) SetTextColor32( hdc, GetSysColor32( COLOR_CAPTIONTEXT ) );
1224 else SetTextColor32( hdc, GetSysColor32( COLOR_INACTIVECAPTIONTEXT ) );
1225 SetBkMode32( hdc, TRANSPARENT );
1226 DrawText32A( hdc, buffer, -1, &r,
1227 DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );
1232 /******************************************************************************
1234 * NC_DrawCaption95(
1235 * HDC32 hdc,
1236 * RECT32 *rect,
1237 * HWND32 hwnd,
1238 * DWORD style,
1239 * BOOL32 active )
1241 * Draw the window caption for Win95 style windows.
1242 * The correct pen for the window frame must be selected in the DC.
1244 * Bugs
1245 * Hey, a function that finally works! Well, almost.
1246 * It's being worked on.
1248 * Revision history
1249 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1250 * Original implementation.
1251 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1252 * Some minor fixes.
1254 *****************************************************************************/
1256 static void NC_DrawCaption95(
1257 HDC32 hdc,
1258 RECT32 *rect,
1259 HWND32 hwnd,
1260 DWORD style,
1261 BOOL32 active )
1263 RECT32 r = *rect;
1264 WND *wndPtr = WIN_FindWndPtr( hwnd );
1265 char buffer[256];
1266 POINT32 sep[2] = { { r.left, r.bottom - 1 },
1267 { r.right, r.bottom - 1 } };
1269 if (wndPtr->flags & WIN_MANAGED) return;
1271 GRAPH_DrawLines( hdc, sep, 1, TWEAK_PenC095 );
1272 r.bottom--;
1274 FillRect32( hdc, &r, GetSysColorBrush32(active ? COLOR_ACTIVECAPTION :
1275 COLOR_INACTIVECAPTION) );
1277 if (!hbitmapClose) {
1278 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1279 return;
1280 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1281 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1282 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1283 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1284 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1285 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1288 if (style & WS_SYSMENU) {
1289 if (NC_DrawSysButton95 (hwnd, hdc, FALSE))
1290 r.left += sysMetrics[SM_CYCAPTION] - 1;
1291 NC_DrawCloseButton95 (hwnd, hdc, FALSE);
1292 r.right -= sysMetrics[SM_CYCAPTION] - 1;
1294 if (style & WS_MAXIMIZEBOX) {
1295 NC_DrawMaxButton95( hwnd, hdc, FALSE );
1296 r.right -= SYSMETRICS_CXSIZE + 1;
1298 if (style & WS_MINIMIZEBOX) {
1299 NC_DrawMinButton95( hwnd, hdc, FALSE );
1300 r.right -= SYSMETRICS_CXSIZE + 1;
1303 if (GetWindowText32A( hwnd, buffer, sizeof(buffer) )) {
1304 NONCLIENTMETRICS32A nclm;
1305 HFONT32 hFont, hOldFont;
1306 nclm.cbSize = sizeof(NONCLIENTMETRICS32A);
1307 SystemParametersInfo32A (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1308 hFont = CreateFontIndirect32A (&nclm.lfCaptionFont);
1309 hOldFont = SelectObject32 (hdc, hFont);
1310 if (active) SetTextColor32( hdc, GetSysColor32( COLOR_CAPTIONTEXT ) );
1311 else SetTextColor32( hdc, GetSysColor32( COLOR_INACTIVECAPTIONTEXT ) );
1312 SetBkMode32( hdc, TRANSPARENT );
1313 r.left += 2;
1314 DrawText32A( hdc, buffer, -1, &r, NC_CaptionTextFlags );
1315 DeleteObject32 (SelectObject32 (hdc, hOldFont));
1321 /***********************************************************************
1322 * NC_DoNCPaint
1324 * Paint the non-client area. clip is currently unused.
1326 void NC_DoNCPaint( WND* wndPtr, HRGN32 clip, BOOL32 suppress_menupaint )
1328 HDC32 hdc;
1329 RECT32 rect;
1330 BOOL32 active;
1331 HWND32 hwnd = wndPtr->hwndSelf;
1333 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1334 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1336 active = wndPtr->flags & WIN_NCACTIVATED;
1338 TRACE(nonclient, "%04x %d\n", hwnd, active );
1340 if (!(hdc = GetDCEx32( hwnd, 0, DCX_USESTYLE | DCX_WINDOW ))) return;
1342 if (ExcludeVisRect( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1343 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1344 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1345 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1346 == NULLREGION)
1348 ReleaseDC32( hwnd, hdc );
1349 return;
1352 rect.top = rect.left = 0;
1353 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1354 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1356 SelectObject32( hdc, GetSysColorPen32(COLOR_WINDOWFRAME) );
1358 if (!(wndPtr->flags & WIN_MANAGED))
1360 if ((wndPtr->dwStyle & WS_BORDER) || (wndPtr->dwStyle & WS_DLGFRAME) ||
1361 (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME))
1363 GRAPH_DrawRectangle( hdc, 0, 0,
1364 rect.right, rect.bottom, (HPEN32)0 );
1365 InflateRect32( &rect, -1, -1 );
1368 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1369 NC_DrawFrame( hdc, &rect, TRUE, active );
1370 else if (wndPtr->dwStyle & WS_THICKFRAME)
1371 NC_DrawFrame(hdc, &rect, FALSE, active );
1373 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1375 RECT32 r = rect;
1376 r.bottom = rect.top + SYSMETRICS_CYSIZE;
1377 rect.top += SYSMETRICS_CYSIZE + SYSMETRICS_CYBORDER;
1378 NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active );
1382 if (HAS_MENU(wndPtr))
1384 RECT32 r = rect;
1385 r.bottom = rect.top + SYSMETRICS_CYMENU; /* default height */
1386 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint );
1389 /* Draw the scroll-bars */
1391 if (wndPtr->dwStyle & WS_VSCROLL)
1392 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE );
1393 if (wndPtr->dwStyle & WS_HSCROLL)
1394 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE );
1396 /* Draw the "size-box" */
1398 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1400 RECT32 r = rect;
1401 r.left = r.right - SYSMETRICS_CXVSCROLL + 1;
1402 r.top = r.bottom - SYSMETRICS_CYHSCROLL + 1;
1403 if(wndPtr->dwStyle & WS_BORDER) {
1404 r.left++;
1405 r.top++;
1407 FillRect32( hdc, &r, GetSysColorBrush32(COLOR_SCROLLBAR) );
1410 ReleaseDC32( hwnd, hdc );
1414 /******************************************************************************
1416 * void NC_DoNCPaint95(
1417 * WND *wndPtr,
1418 * HRGN32 clip,
1419 * BOOL32 suppress_menupaint )
1421 * Paint the non-client area for Win95 windows. The clip region is
1422 * currently ignored.
1424 * Bugs
1425 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1426 * misc/tweak.c controls/menu.c # :-)
1428 * Revision history
1429 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1430 * Original implementation
1431 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1432 * Fixed some bugs.
1434 *****************************************************************************/
1436 void NC_DoNCPaint95(
1437 WND *wndPtr,
1438 HRGN32 clip,
1439 BOOL32 suppress_menupaint )
1441 HDC32 hdc;
1442 RECT32 rect;
1443 BOOL32 active;
1444 HWND32 hwnd = wndPtr->hwndSelf;
1446 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1447 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1449 active = wndPtr->flags & WIN_NCACTIVATED;
1451 TRACE(nonclient, "%04x %d\n", hwnd, active );
1453 if (!(hdc = GetDCEx32( hwnd, 0, DCX_USESTYLE | DCX_WINDOW ))) return;
1455 if (ExcludeVisRect( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1456 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1457 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1458 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1459 == NULLREGION)
1461 ReleaseDC32( hwnd, hdc );
1462 return;
1465 rect.top = rect.left = 0;
1466 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1467 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1469 SelectObject32( hdc, GetSysColorPen32(COLOR_WINDOWFRAME) );
1471 if(!(wndPtr->flags & WIN_MANAGED)) {
1472 if ((wndPtr->dwStyle & WS_BORDER) && ((wndPtr->dwStyle & WS_DLGFRAME) ||
1473 (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME) || (wndPtr->dwStyle & WS_THICKFRAME))) {
1474 DrawEdge32 (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1477 if (HAS_FIXEDFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1478 NC_DrawFrame95( hdc, &rect, TRUE, active );
1479 else if (wndPtr->dwStyle & WS_THICKFRAME)
1480 NC_DrawFrame95(hdc, &rect, FALSE, active );
1482 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1484 RECT32 r = rect;
1485 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW) {
1486 r.bottom = rect.top + sysMetrics[SM_CYSMCAPTION];
1487 rect.top += sysMetrics[SM_CYSMCAPTION];
1489 else {
1490 r.bottom = rect.top + sysMetrics[SM_CYCAPTION];
1491 rect.top += sysMetrics[SM_CYCAPTION];
1493 NC_DrawCaption95( hdc, &r, hwnd, wndPtr->dwStyle, active );
1497 if (HAS_MENU(wndPtr))
1499 RECT32 r = rect;
1500 r.bottom = rect.top + sysMetrics[SM_CYMENU];
1502 TRACE(nonclient, "Calling DrawMenuBar with "
1503 "rect (%d, %d)-(%d, %d)\n", r.left, r.top,
1504 r.right, r.bottom);
1506 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ) + 1;
1509 TRACE(nonclient, "After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1510 rect.left, rect.top, rect.right, rect.bottom );
1512 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
1513 DrawEdge32 (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1515 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
1516 DrawEdge32 (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1518 /* Draw the scroll-bars */
1520 if (wndPtr->dwStyle & WS_VSCROLL)
1521 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE );
1522 if (wndPtr->dwStyle & WS_HSCROLL)
1523 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE );
1525 /* Draw the "size-box" */
1526 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1528 RECT32 r = rect;
1529 r.left = r.right - SYSMETRICS_CXVSCROLL + 1;
1530 r.top = r.bottom - SYSMETRICS_CYHSCROLL + 1;
1531 FillRect32( hdc, &r, GetSysColorBrush32(COLOR_SCROLLBAR) );
1534 ReleaseDC32( hwnd, hdc );
1540 /***********************************************************************
1541 * NC_HandleNCPaint
1543 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1545 LONG NC_HandleNCPaint( HWND32 hwnd , HRGN32 clip)
1547 WND* wndPtr = WIN_FindWndPtr( hwnd );
1549 if( wndPtr && wndPtr->dwStyle & WS_VISIBLE )
1551 if( wndPtr->dwStyle & WS_MINIMIZE )
1552 WINPOS_RedrawIconTitle( hwnd );
1553 else if(TWEAK_Win95Look)
1554 NC_DoNCPaint95( wndPtr, clip, FALSE );
1555 else
1556 NC_DoNCPaint( wndPtr, clip, FALSE );
1558 return 0;
1562 /***********************************************************************
1563 * NC_HandleNCActivate
1565 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1567 LONG NC_HandleNCActivate( WND *wndPtr, WPARAM16 wParam )
1569 WORD wStateChange;
1571 if( wParam ) wStateChange = !(wndPtr->flags & WIN_NCACTIVATED);
1572 else wStateChange = wndPtr->flags & WIN_NCACTIVATED;
1574 if( wStateChange )
1576 if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
1577 else wndPtr->flags &= ~WIN_NCACTIVATED;
1579 if( wndPtr->dwStyle & WS_MINIMIZE )
1580 WINPOS_RedrawIconTitle( wndPtr->hwndSelf );
1581 else if( TWEAK_Win95Look )
1582 NC_DoNCPaint95( wndPtr, (HRGN32)1, FALSE );
1583 else
1584 NC_DoNCPaint( wndPtr, (HRGN32)1, FALSE );
1586 return TRUE;
1590 /***********************************************************************
1591 * NC_HandleSetCursor
1593 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1595 LONG NC_HandleSetCursor( HWND32 hwnd, WPARAM16 wParam, LPARAM lParam )
1597 if (hwnd != (HWND32)wParam) return 0; /* Don't set the cursor for child windows */
1599 switch(LOWORD(lParam))
1601 case HTERROR:
1603 WORD msg = HIWORD( lParam );
1604 if ((msg == WM_LBUTTONDOWN) || (msg == WM_MBUTTONDOWN) ||
1605 (msg == WM_RBUTTONDOWN))
1606 MessageBeep32(0);
1608 break;
1610 case HTCLIENT:
1612 WND *wndPtr;
1613 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) break;
1614 if (wndPtr->class->hCursor)
1616 SetCursor16( wndPtr->class->hCursor );
1617 return TRUE;
1619 else return FALSE;
1622 case HTLEFT:
1623 case HTRIGHT:
1624 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZEWE16 ) );
1626 case HTTOP:
1627 case HTBOTTOM:
1628 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENS16 ) );
1630 case HTTOPLEFT:
1631 case HTBOTTOMRIGHT:
1632 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENWSE16 ) );
1634 case HTTOPRIGHT:
1635 case HTBOTTOMLEFT:
1636 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENESW16 ) );
1639 /* Default cursor: arrow */
1640 return (LONG)SetCursor16( LoadCursor16( 0, IDC_ARROW16 ) );
1643 /***********************************************************************
1644 * NC_GetSysPopupPos
1646 BOOL32 NC_GetSysPopupPos( WND* wndPtr, RECT32* rect )
1648 if( wndPtr->hSysMenu )
1650 if( wndPtr->dwStyle & WS_MINIMIZE )
1651 GetWindowRect32( wndPtr->hwndSelf, rect );
1652 else
1654 if(TWEAK_Win95Look)
1655 NC_GetInsideRect95( wndPtr->hwndSelf, rect );
1656 else
1657 NC_GetInsideRect( wndPtr->hwndSelf, rect );
1658 OffsetRect32( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
1659 if (wndPtr->dwStyle & WS_CHILD)
1660 ClientToScreen32( wndPtr->parent->hwndSelf, (POINT32 *)rect );
1661 if(TWEAK_Win95Look) {
1662 rect->right = rect->left + sysMetrics[SM_CYCAPTION] - 1;
1663 rect->bottom = rect->top + sysMetrics[SM_CYCAPTION] - 1;
1665 else {
1666 rect->right = rect->left + SYSMETRICS_CXSIZE;
1667 rect->bottom = rect->top + SYSMETRICS_CYSIZE;
1670 return TRUE;
1672 return FALSE;
1675 /***********************************************************************
1676 * NC_StartSizeMove
1678 * Initialisation of a move or resize, when initiatied from a menu choice.
1679 * Return hit test code for caption or sizing border.
1681 static LONG NC_StartSizeMove( WND* wndPtr, WPARAM16 wParam,
1682 POINT16 *capturePoint )
1684 LONG hittest = 0;
1685 POINT16 pt;
1686 MSG16 msg;
1688 if ((wParam & 0xfff0) == SC_MOVE)
1690 /* Move pointer at the center of the caption */
1691 RECT32 rect;
1692 if(TWEAK_Win95Look)
1693 NC_GetInsideRect95( wndPtr->hwndSelf, &rect );
1694 else
1695 NC_GetInsideRect( wndPtr->hwndSelf, &rect );
1696 if (wndPtr->dwStyle & WS_SYSMENU)
1697 rect.left += SYSMETRICS_CXSIZE + 1;
1698 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
1699 rect.right -= SYSMETRICS_CXSIZE + 1;
1700 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
1701 rect.right -= SYSMETRICS_CXSIZE + 1;
1702 pt.x = wndPtr->rectWindow.left + (rect.right - rect.left) / 2;
1703 pt.y = wndPtr->rectWindow.top + rect.top + SYSMETRICS_CYSIZE/2;
1704 hittest = HTCAPTION;
1705 *capturePoint = pt;
1707 if (wndPtr->dwStyle & WS_CHILD)
1708 ClientToScreen16( wndPtr->parent->hwndSelf, &pt );
1710 else /* SC_SIZE */
1712 while(!hittest)
1714 MSG_InternalGetMessage( &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE );
1715 switch(msg.message)
1717 case WM_MOUSEMOVE:
1718 hittest = NC_HandleNCHitTest( wndPtr->hwndSelf, msg.pt );
1719 pt = msg.pt;
1720 if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
1721 hittest = 0;
1722 break;
1724 case WM_LBUTTONUP:
1725 return 0;
1727 case WM_KEYDOWN:
1728 switch(msg.wParam)
1730 case VK_UP:
1731 hittest = HTTOP;
1732 pt.x =(wndPtr->rectWindow.left+wndPtr->rectWindow.right)/2;
1733 pt.y = wndPtr->rectWindow.top + SYSMETRICS_CYFRAME / 2;
1734 break;
1735 case VK_DOWN:
1736 hittest = HTBOTTOM;
1737 pt.x =(wndPtr->rectWindow.left+wndPtr->rectWindow.right)/2;
1738 pt.y = wndPtr->rectWindow.bottom - SYSMETRICS_CYFRAME / 2;
1739 break;
1740 case VK_LEFT:
1741 hittest = HTLEFT;
1742 pt.x = wndPtr->rectWindow.left + SYSMETRICS_CXFRAME / 2;
1743 pt.y =(wndPtr->rectWindow.top+wndPtr->rectWindow.bottom)/2;
1744 break;
1745 case VK_RIGHT:
1746 hittest = HTRIGHT;
1747 pt.x = wndPtr->rectWindow.right - SYSMETRICS_CXFRAME / 2;
1748 pt.y =(wndPtr->rectWindow.top+wndPtr->rectWindow.bottom)/2;
1749 break;
1750 case VK_RETURN:
1751 case VK_ESCAPE: return 0;
1755 *capturePoint = pt;
1757 SetCursorPos32( pt.x, pt.y );
1758 NC_HandleSetCursor( wndPtr->hwndSelf,
1759 wndPtr->hwndSelf, MAKELONG( hittest, WM_MOUSEMOVE ));
1760 return hittest;
1764 /***********************************************************************
1765 * NC_DoSizeMove
1767 * Perform SC_MOVE and SC_SIZE commands.
1769 static void NC_DoSizeMove( HWND32 hwnd, WORD wParam, POINT16 pt )
1771 MSG16 msg;
1772 RECT32 sizingRect, mouseRect;
1773 HDC32 hdc;
1774 LONG hittest = (LONG)(wParam & 0x0f);
1775 HCURSOR16 hDragCursor = 0, hOldCursor = 0;
1776 POINT32 minTrack, maxTrack;
1777 POINT16 capturePoint = pt;
1778 WND * wndPtr = WIN_FindWndPtr( hwnd );
1779 BOOL32 thickframe = HAS_THICKFRAME( wndPtr->dwStyle );
1780 BOOL32 iconic = wndPtr->dwStyle & WS_MINIMIZE;
1781 BOOL32 moved = FALSE;
1783 if (IsZoomed32(hwnd) || !IsWindowVisible32(hwnd) ||
1784 (wndPtr->flags & WIN_MANAGED)) return;
1786 if ((wParam & 0xfff0) == SC_MOVE)
1788 if (!(wndPtr->dwStyle & WS_CAPTION)) return;
1789 if (!hittest)
1790 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
1791 if (!hittest) return;
1793 else /* SC_SIZE */
1795 if (!thickframe) return;
1796 if ( hittest && hittest != HTSYSMENU ) hittest += 2;
1797 else
1799 SetCapture32(hwnd);
1800 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
1801 if (!hittest)
1803 ReleaseCapture();
1804 return;
1809 /* Get min/max info */
1811 WINPOS_GetMinMaxInfo( wndPtr, NULL, NULL, &minTrack, &maxTrack );
1812 sizingRect = wndPtr->rectWindow;
1813 if (wndPtr->dwStyle & WS_CHILD)
1814 GetClientRect32( wndPtr->parent->hwndSelf, &mouseRect );
1815 else
1816 SetRect32(&mouseRect, 0, 0, SYSMETRICS_CXSCREEN, SYSMETRICS_CYSCREEN);
1817 if (ON_LEFT_BORDER(hittest))
1819 mouseRect.left = MAX( mouseRect.left, sizingRect.right-maxTrack.x );
1820 mouseRect.right = MIN( mouseRect.right, sizingRect.right-minTrack.x );
1822 else if (ON_RIGHT_BORDER(hittest))
1824 mouseRect.left = MAX( mouseRect.left, sizingRect.left+minTrack.x );
1825 mouseRect.right = MIN( mouseRect.right, sizingRect.left+maxTrack.x );
1827 if (ON_TOP_BORDER(hittest))
1829 mouseRect.top = MAX( mouseRect.top, sizingRect.bottom-maxTrack.y );
1830 mouseRect.bottom = MIN( mouseRect.bottom,sizingRect.bottom-minTrack.y);
1832 else if (ON_BOTTOM_BORDER(hittest))
1834 mouseRect.top = MAX( mouseRect.top, sizingRect.top+minTrack.y );
1835 mouseRect.bottom = MIN( mouseRect.bottom, sizingRect.top+maxTrack.y );
1837 SendMessage16( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
1839 if (GetCapture32() != hwnd) SetCapture32( hwnd );
1841 if (wndPtr->dwStyle & WS_CHILD)
1843 /* Retrieve a default cache DC (without using the window style) */
1844 hdc = GetDCEx32( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
1846 else
1847 { /* Grab the server only when moving top-level windows without desktop */
1848 hdc = GetDC32( 0 );
1849 if (rootWindow == DefaultRootWindow(display)) TSXGrabServer( display );
1852 if( iconic ) /* create a cursor for dragging */
1854 HICON16 hIcon = (wndPtr->class->hIcon) ? wndPtr->class->hIcon
1855 : (HICON16)SendMessage16( hwnd, WM_QUERYDRAGICON, 0, 0L);
1856 if( hIcon ) hDragCursor = CURSORICON_IconToCursor( hIcon, TRUE );
1857 if( !hDragCursor ) iconic = FALSE;
1860 if( !iconic ) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
1862 while(1)
1864 int dx = 0, dy = 0;
1866 MSG_InternalGetMessage( &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE );
1868 /* Exit on button-up, Return, or Esc */
1869 if ((msg.message == WM_LBUTTONUP) ||
1870 ((msg.message == WM_KEYDOWN) &&
1871 ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
1873 if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
1874 continue; /* We are not interested in other messages */
1876 pt = msg.pt;
1877 if (wndPtr->dwStyle & WS_CHILD)
1878 ScreenToClient16( wndPtr->parent->hwndSelf, &pt );
1880 if (msg.message == WM_KEYDOWN) switch(msg.wParam)
1882 case VK_UP: pt.y -= 8; break;
1883 case VK_DOWN: pt.y += 8; break;
1884 case VK_LEFT: pt.x -= 8; break;
1885 case VK_RIGHT: pt.x += 8; break;
1888 pt.x = MAX( pt.x, mouseRect.left );
1889 pt.x = MIN( pt.x, mouseRect.right );
1890 pt.y = MAX( pt.y, mouseRect.top );
1891 pt.y = MIN( pt.y, mouseRect.bottom );
1893 dx = pt.x - capturePoint.x;
1894 dy = pt.y - capturePoint.y;
1896 if (dx || dy)
1898 if( !moved )
1900 moved = TRUE;
1901 if( iconic ) /* ok, no system popup tracking */
1903 hOldCursor = SetCursor32(hDragCursor);
1904 ShowCursor32( TRUE );
1905 WINPOS_ShowIconTitle( wndPtr, FALSE );
1909 if (msg.message == WM_KEYDOWN) SetCursorPos32( pt.x, pt.y );
1910 else
1912 RECT32 newRect = sizingRect;
1914 if (hittest == HTCAPTION) OffsetRect32( &newRect, dx, dy );
1915 if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
1916 else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
1917 if (ON_TOP_BORDER(hittest)) newRect.top += dy;
1918 else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
1919 if( !iconic )
1921 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
1922 NC_DrawMovingFrame( hdc, &newRect, thickframe );
1924 capturePoint = pt;
1925 sizingRect = newRect;
1930 ReleaseCapture();
1931 if( iconic )
1933 if( moved ) /* restore cursors, show icon title later on */
1935 ShowCursor32( FALSE );
1936 SetCursor32( hOldCursor );
1938 DestroyCursor32( hDragCursor );
1940 else
1941 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
1943 if (wndPtr->dwStyle & WS_CHILD)
1944 ReleaseDC32( wndPtr->parent->hwndSelf, hdc );
1945 else
1947 ReleaseDC32( 0, hdc );
1948 if (rootWindow == DefaultRootWindow(display)) TSXUngrabServer( display );
1951 if (HOOK_IsHooked( WH_CBT ))
1953 RECT16* pr = SEGPTR_NEW(RECT16);
1954 if( pr )
1956 CONV_RECT32TO16( &sizingRect, pr );
1957 if( HOOK_CallHooks16( WH_CBT, HCBT_MOVESIZE, hwnd,
1958 (LPARAM)SEGPTR_GET(pr)) )
1959 sizingRect = wndPtr->rectWindow;
1960 else
1961 CONV_RECT16TO32( pr, &sizingRect );
1962 SEGPTR_FREE(pr);
1965 SendMessage16( hwnd, WM_EXITSIZEMOVE, 0, 0 );
1966 SendMessage16( hwnd, WM_SETVISIBLE, !IsIconic16(hwnd), 0L);
1968 if( moved && !((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
1970 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
1971 SetWindowPos32( hwnd, 0, sizingRect.left, sizingRect.top,
1972 sizingRect.right - sizingRect.left,
1973 sizingRect.bottom - sizingRect.top,
1974 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
1977 if( IsWindow32(hwnd) )
1978 if( wndPtr->dwStyle & WS_MINIMIZE )
1980 /* Single click brings up the system menu when iconized */
1982 if( !moved )
1984 if( wndPtr->dwStyle & WS_SYSMENU )
1985 SendMessage16( hwnd, WM_SYSCOMMAND,
1986 SC_MOUSEMENU + HTSYSMENU, *((LPARAM*)&pt));
1988 else WINPOS_ShowIconTitle( wndPtr, TRUE );
1993 /***********************************************************************
1994 * NC_TrackMinMaxBox
1996 * Track a mouse button press on the minimize or maximize box.
1998 static void NC_TrackMinMaxBox( HWND32 hwnd, WORD wParam )
2000 MSG16 msg;
2001 HDC32 hdc = GetWindowDC32( hwnd );
2002 BOOL32 pressed = TRUE;
2003 void (*paintButton)(HWND32, HDC16, BOOL32);
2005 SetCapture32( hwnd );
2006 if (wParam == HTMINBUTTON)
2007 paintButton = (TWEAK_Win95Look) ? &NC_DrawMinButton95 : &NC_DrawMinButton;
2008 else
2009 paintButton = (TWEAK_Win95Look) ? &NC_DrawMaxButton95 : &NC_DrawMaxButton;
2011 (*paintButton)( hwnd, hdc, TRUE );
2015 BOOL32 oldstate = pressed;
2016 MSG_InternalGetMessage( &msg, 0, 0, 0, PM_REMOVE, FALSE );
2018 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
2019 if (pressed != oldstate)
2020 (*paintButton)( hwnd, hdc, pressed );
2021 } while (msg.message != WM_LBUTTONUP);
2023 (*paintButton)( hwnd, hdc, FALSE );
2025 ReleaseCapture();
2026 ReleaseDC32( hwnd, hdc );
2027 if (!pressed) return;
2029 if (wParam == HTMINBUTTON)
2030 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&msg.pt );
2031 else
2032 SendMessage16( hwnd, WM_SYSCOMMAND,
2033 IsZoomed32(hwnd) ? SC_RESTORE:SC_MAXIMIZE, *(LONG*)&msg.pt );
2037 /***********************************************************************
2038 * NC_TrackCloseButton95
2040 * Track a mouse button press on the Win95 close button.
2042 static void
2043 NC_TrackCloseButton95 (HWND32 hwnd, WORD wParam)
2045 MSG16 msg;
2046 HDC32 hdc = GetWindowDC32( hwnd );
2047 BOOL32 pressed = TRUE;
2049 SetCapture32( hwnd );
2051 NC_DrawCloseButton95 (hwnd, hdc, TRUE);
2055 BOOL32 oldstate = pressed;
2056 MSG_InternalGetMessage( &msg, 0, 0, 0, PM_REMOVE, FALSE );
2058 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
2059 if (pressed != oldstate)
2060 NC_DrawCloseButton95 (hwnd, hdc, pressed);
2061 } while (msg.message != WM_LBUTTONUP);
2063 NC_DrawCloseButton95 (hwnd, hdc, FALSE);
2065 ReleaseCapture();
2066 ReleaseDC32( hwnd, hdc );
2067 if (!pressed) return;
2069 SendMessage16( hwnd, WM_SYSCOMMAND, SC_CLOSE, *(LONG*)&msg.pt );
2073 /***********************************************************************
2074 * NC_TrackScrollBar
2076 * Track a mouse button press on the horizontal or vertical scroll-bar.
2078 static void NC_TrackScrollBar( HWND32 hwnd, WPARAM32 wParam, POINT32 pt )
2080 MSG16 *msg;
2081 INT32 scrollbar;
2082 WND *wndPtr = WIN_FindWndPtr( hwnd );
2084 if ((wParam & 0xfff0) == SC_HSCROLL)
2086 if ((wParam & 0x0f) != HTHSCROLL) return;
2087 scrollbar = SB_HORZ;
2089 else /* SC_VSCROLL */
2091 if ((wParam & 0x0f) != HTVSCROLL) return;
2092 scrollbar = SB_VERT;
2095 if (!(msg = SEGPTR_NEW(MSG16))) return;
2096 pt.x -= wndPtr->rectWindow.left;
2097 pt.y -= wndPtr->rectWindow.top;
2098 SetCapture32( hwnd );
2099 SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt );
2103 GetMessage16( SEGPTR_GET(msg), 0, 0, 0 );
2104 switch(msg->message)
2106 case WM_LBUTTONUP:
2107 case WM_MOUSEMOVE:
2108 case WM_SYSTIMER:
2109 pt.x = LOWORD(msg->lParam) + wndPtr->rectClient.left -
2110 wndPtr->rectWindow.left;
2111 pt.y = HIWORD(msg->lParam) + wndPtr->rectClient.top -
2112 wndPtr->rectWindow.top;
2113 SCROLL_HandleScrollEvent( hwnd, scrollbar, msg->message, pt );
2114 break;
2115 default:
2116 TranslateMessage16( msg );
2117 DispatchMessage16( msg );
2118 break;
2120 if (!IsWindow32( hwnd ))
2122 ReleaseCapture();
2123 break;
2125 } while (msg->message != WM_LBUTTONUP);
2126 SEGPTR_FREE(msg);
2129 /***********************************************************************
2130 * NC_HandleNCLButtonDown
2132 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2134 LONG NC_HandleNCLButtonDown( WND* pWnd, WPARAM16 wParam, LPARAM lParam )
2136 HWND32 hwnd = pWnd->hwndSelf;
2138 switch(wParam) /* Hit test */
2140 case HTCAPTION:
2141 hwnd = WIN_GetTopParent(hwnd);
2143 if( WINPOS_SetActiveWindow(hwnd, TRUE, TRUE) || (GetActiveWindow32() == hwnd) )
2144 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
2145 break;
2147 case HTSYSMENU:
2148 if( pWnd->dwStyle & WS_SYSMENU )
2150 if( !(pWnd->dwStyle & WS_MINIMIZE) )
2152 HDC32 hDC = GetWindowDC32(hwnd);
2153 if( TWEAK_Win95Look)
2154 NC_DrawSysButton95( hwnd, hDC, TRUE );
2155 else
2156 NC_DrawSysButton( hwnd, hDC, TRUE );
2157 ReleaseDC32( hwnd, hDC );
2159 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
2161 break;
2163 case HTMENU:
2164 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam );
2165 break;
2167 case HTHSCROLL:
2168 SendMessage16( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
2169 break;
2171 case HTVSCROLL:
2172 SendMessage16( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
2173 break;
2175 case HTMINBUTTON:
2176 case HTMAXBUTTON:
2177 NC_TrackMinMaxBox( hwnd, wParam );
2178 break;
2180 case HTCLOSE:
2181 if (TWEAK_Win95Look)
2182 NC_TrackCloseButton95 (hwnd, wParam);
2183 break;
2185 case HTLEFT:
2186 case HTRIGHT:
2187 case HTTOP:
2188 case HTTOPLEFT:
2189 case HTTOPRIGHT:
2190 case HTBOTTOM:
2191 case HTBOTTOMLEFT:
2192 case HTBOTTOMRIGHT:
2193 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2194 SendMessage16( hwnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam);
2195 break;
2197 case HTBORDER:
2198 break;
2200 return 0;
2204 /***********************************************************************
2205 * NC_HandleNCLButtonDblClk
2207 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2209 LONG NC_HandleNCLButtonDblClk( WND *pWnd, WPARAM16 wParam, LPARAM lParam )
2212 * if this is an icon, send a restore since we are handling
2213 * a double click
2215 if (pWnd->dwStyle & WS_MINIMIZE)
2217 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_RESTORE, lParam );
2218 return 0;
2221 switch(wParam) /* Hit test */
2223 case HTCAPTION:
2224 /* stop processing if WS_MAXIMIZEBOX is missing */
2225 if (pWnd->dwStyle & WS_MAXIMIZEBOX)
2226 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND,
2227 (pWnd->dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
2228 lParam );
2229 break;
2231 case HTSYSMENU:
2232 if (!(pWnd->class->style & CS_NOCLOSE))
2233 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, lParam );
2234 break;
2236 case HTHSCROLL:
2237 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL,
2238 lParam );
2239 break;
2241 case HTVSCROLL:
2242 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL,
2243 lParam );
2244 break;
2246 return 0;
2250 /***********************************************************************
2251 * NC_HandleSysCommand
2253 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2255 LONG NC_HandleSysCommand( HWND32 hwnd, WPARAM16 wParam, POINT16 pt )
2257 WND *wndPtr = WIN_FindWndPtr( hwnd );
2258 POINT32 pt32;
2259 UINT16 uCommand = wParam & 0xFFF0;
2261 TRACE(nonclient, "Handling WM_SYSCOMMAND %x %d,%d\n",
2262 wParam, pt.x, pt.y );
2264 if (wndPtr->dwStyle & WS_CHILD && uCommand != SC_KEYMENU )
2265 ScreenToClient16( wndPtr->parent->hwndSelf, &pt );
2267 switch (uCommand)
2269 case SC_SIZE:
2270 case SC_MOVE:
2271 NC_DoSizeMove( hwnd, wParam, pt );
2272 break;
2274 case SC_MINIMIZE:
2275 ShowWindow32( hwnd, SW_MINIMIZE );
2276 break;
2278 case SC_MAXIMIZE:
2279 ShowWindow32( hwnd, SW_MAXIMIZE );
2280 break;
2282 case SC_RESTORE:
2283 ShowWindow32( hwnd, SW_RESTORE );
2284 break;
2286 case SC_CLOSE:
2287 return SendMessage16( hwnd, WM_CLOSE, 0, 0 );
2289 case SC_VSCROLL:
2290 case SC_HSCROLL:
2291 CONV_POINT16TO32( &pt, &pt32 );
2292 NC_TrackScrollBar( hwnd, wParam, pt32 );
2293 break;
2295 case SC_MOUSEMENU:
2296 CONV_POINT16TO32( &pt, &pt32 );
2297 MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt32 );
2298 break;
2300 case SC_KEYMENU:
2301 MENU_TrackKbdMenuBar( wndPtr , wParam , pt.x );
2302 break;
2304 case SC_TASKLIST:
2305 WinExec32( "taskman.exe", SW_SHOWNORMAL );
2306 break;
2308 case SC_SCREENSAVE:
2309 if (wParam == SC_ABOUTWINE)
2310 ShellAbout32A(hwnd,"Wine", WINE_RELEASE_INFO, 0);
2311 break;
2313 case SC_HOTKEY:
2314 case SC_ARRANGE:
2315 case SC_NEXTWINDOW:
2316 case SC_PREVWINDOW:
2317 /* FIXME: unimplemented */
2318 break;
2320 return 0;