Initial revision
[wine/multimedia.git] / windows / nonclient.c
blobb5dbbcf85da4b75d05ed72ab5789534e09d01baa
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 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;
38 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
40 /* Some useful macros */
41 #define HAS_DLGFRAME(style,exStyle) \
42 (((exStyle) & WS_EX_DLGMODALFRAME) || \
43 (((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
45 #define HAS_THICKFRAME(style) \
46 (((style) & WS_THICKFRAME) && \
47 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
49 #define HAS_FIXEDFRAME(style,exStyle) \
50 (((((exStyle) & WS_EX_DLGMODALFRAME) || \
51 ((style) & WS_DLGFRAME)) && ((style) & WS_BORDER)) && \
52 !((style) & WS_THICKFRAME))
54 #define HAS_SIZEFRAME(style) \
55 (((style) & WS_THICKFRAME) && \
56 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
58 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
60 #define ON_LEFT_BORDER(hit) \
61 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
62 #define ON_RIGHT_BORDER(hit) \
63 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
64 #define ON_TOP_BORDER(hit) \
65 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
66 #define ON_BOTTOM_BORDER(hit) \
67 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
69 /***********************************************************************
70 * NC_AdjustRect
72 * Compute the size of the window rectangle from the size of the
73 * client rectangle.
75 static void NC_AdjustRect( LPRECT16 rect, DWORD style, BOOL32 menu,
76 DWORD exStyle )
78 if (TWEAK_WineLook > WIN31_LOOK)
79 ERR(nonclient, "Called in Win95 mode. Aiee! Please report this.\n" );
81 if(style & WS_ICONIC) return;
82 /* Decide if the window will be managed (see CreateWindowEx) */
83 if (!(Options.managed && !(style & WS_CHILD) &&
84 ((style & (WS_DLGFRAME | WS_THICKFRAME)) ||
85 (exStyle & WS_EX_DLGMODALFRAME))))
87 if (HAS_DLGFRAME( style, exStyle ))
88 InflateRect16(rect, SYSMETRICS_CXDLGFRAME, SYSMETRICS_CYDLGFRAME );
89 else
91 if (HAS_THICKFRAME(style))
92 InflateRect16( rect, SYSMETRICS_CXFRAME, SYSMETRICS_CYFRAME );
93 if (style & WS_BORDER)
94 InflateRect16( rect, SYSMETRICS_CXBORDER, SYSMETRICS_CYBORDER);
97 if ((style & WS_CAPTION) == WS_CAPTION)
98 rect->top -= SYSMETRICS_CYCAPTION - SYSMETRICS_CYBORDER;
100 if (menu) rect->top -= SYSMETRICS_CYMENU + SYSMETRICS_CYBORDER;
102 if (style & WS_VSCROLL) {
103 rect->right += SYSMETRICS_CXVSCROLL - 1;
104 if(!(style & WS_BORDER))
105 rect->right++;
108 if (style & WS_HSCROLL) {
109 rect->bottom += SYSMETRICS_CYHSCROLL - 1;
110 if(!(style & WS_BORDER))
111 rect->bottom++;
116 /******************************************************************************
117 * NC_AdjustRectOuter95
119 * Computes the size of the "outside" parts of the window based on the
120 * parameters of the client area.
122 + PARAMS
123 * LPRECT16 rect
124 * DWORD style
125 * BOOL32 menu
126 * DWORD exStyle
128 * NOTES
129 * "Outer" parts of a window means the whole window frame, caption and
130 * menu bar. It does not include "inner" parts of the frame like client
131 * edge, static edge or scroll bars.
133 * Revision history
134 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
135 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
137 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
138 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
139 * NC_AdjustRectInner95 and added handling of Win95 styles.
141 *****************************************************************************/
143 static void
144 NC_AdjustRectOuter95 (LPRECT16 rect, DWORD style, BOOL32 menu, DWORD exStyle)
146 if(style & WS_ICONIC) return;
148 /* Decide if the window will be managed (see CreateWindowEx) */
149 if (!(Options.managed && !(style & WS_CHILD) &&
150 ((style & (WS_DLGFRAME | WS_THICKFRAME)) ||
151 (exStyle & WS_EX_DLGMODALFRAME))))
153 if (HAS_FIXEDFRAME( style, exStyle ))
154 InflateRect16(rect, SYSMETRICS_CXDLGFRAME, SYSMETRICS_CYDLGFRAME );
155 else
157 if (HAS_SIZEFRAME(style))
158 InflateRect16( rect, SYSMETRICS_CXFRAME, SYSMETRICS_CYFRAME );
159 #if 0
160 if (style & WS_BORDER)
161 InflateRect16( rect, SYSMETRICS_CXBORDER, SYSMETRICS_CYBORDER);
162 #endif
165 if ((style & WS_CAPTION) == WS_CAPTION)
166 if (exStyle & WS_EX_TOOLWINDOW)
167 rect->top -= SYSMETRICS_CYSMCAPTION;
168 else
169 rect->top -= SYSMETRICS_CYCAPTION;
172 if (menu)
173 rect->top -= sysMetrics[SM_CYMENU];
177 /******************************************************************************
178 * NC_AdjustRectInner95
180 * Computes the size of the "inside" part of the window based on the
181 * parameters of the client area.
183 + PARAMS
184 * LPRECT16 rect
185 * DWORD style
186 * DWORD exStyle
188 * NOTES
189 * "Inner" part of a window means the window frame inside of the flat
190 * window frame. It includes the client edge, the static edge and the
191 * scroll bars.
193 * Revision history
194 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
195 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
197 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
198 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
199 * NC_AdjustRectInner95 and added handling of Win95 styles.
201 *****************************************************************************/
203 static void
204 NC_AdjustRectInner95 (LPRECT16 rect, DWORD style, DWORD exStyle)
206 if(style & WS_ICONIC) return;
208 if (exStyle & WS_EX_CLIENTEDGE)
209 InflateRect16 (rect, sysMetrics[SM_CXEDGE], sysMetrics[SM_CYEDGE]);
211 if (exStyle & WS_EX_STATICEDGE)
212 InflateRect16 (rect, sysMetrics[SM_CXBORDER], sysMetrics[SM_CYBORDER]);
214 if (style & WS_VSCROLL) rect->right += SYSMETRICS_CXVSCROLL;
215 if (style & WS_HSCROLL) rect->bottom += SYSMETRICS_CYHSCROLL;
219 /***********************************************************************
220 * DrawCaptionTempA [USER32.599]
223 DWORD WINAPI
224 DrawCaptionTemp32A (HWND32 hwnd, HDC32 hdc, LPRECT32 rect,
225 HFONT32 hfont,DWORD x1,LPCSTR str,DWORD x2)
227 FIXME (nonclient, "(%08x,%08x,%p,%08x,%08x,\"%s\",%08x): stub\n",
228 hwnd, hdc, rect, hfont, x1, str, x2);
230 return 0;
234 /***********************************************************************
235 * AdjustWindowRect16 (USER.102)
237 BOOL16 WINAPI AdjustWindowRect16( LPRECT16 rect, DWORD style, BOOL16 menu )
239 return AdjustWindowRectEx16( rect, style, menu, 0 );
243 /***********************************************************************
244 * AdjustWindowRect32 (USER32.2)
246 BOOL32 WINAPI AdjustWindowRect32( LPRECT32 rect, DWORD style, BOOL32 menu )
248 return AdjustWindowRectEx32( rect, style, menu, 0 );
252 /***********************************************************************
253 * AdjustWindowRectEx16 (USER.454)
255 BOOL16 WINAPI AdjustWindowRectEx16( LPRECT16 rect, DWORD style,
256 BOOL16 menu, DWORD exStyle )
258 /* Correct the window style */
260 if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
261 style |= WS_CAPTION;
262 style &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD);
263 exStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE |
264 WS_EX_STATICEDGE | WS_EX_TOOLWINDOW);
265 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
267 TRACE(nonclient, "(%d,%d)-(%d,%d) %08lx %d %08lx\n",
268 rect->left, rect->top, rect->right, rect->bottom,
269 style, menu, exStyle );
271 if (TWEAK_WineLook == WIN31_LOOK)
272 NC_AdjustRect( rect, style, menu, exStyle );
273 else {
274 NC_AdjustRectOuter95( rect, style, menu, exStyle );
275 NC_AdjustRectInner95( rect, style, exStyle );
278 return TRUE;
282 /***********************************************************************
283 * AdjustWindowRectEx32 (USER32.3)
285 BOOL32 WINAPI AdjustWindowRectEx32( LPRECT32 rect, DWORD style,
286 BOOL32 menu, DWORD exStyle )
288 RECT16 rect16;
289 BOOL32 ret;
291 CONV_RECT32TO16( rect, &rect16 );
292 ret = AdjustWindowRectEx16( &rect16, style, (BOOL16)menu, exStyle );
293 CONV_RECT16TO32( &rect16, rect );
294 return ret;
298 /***********************************************************************
299 * NC_HandleNCCalcSize
301 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
303 LONG NC_HandleNCCalcSize( WND *pWnd, RECT32 *winRect )
305 RECT16 tmpRect = { 0, 0, 0, 0 };
306 LONG result = 0;
308 if (pWnd->class->style & CS_VREDRAW) result |= WVR_VREDRAW;
309 if (pWnd->class->style & CS_HREDRAW) result |= WVR_HREDRAW;
311 if( !( pWnd->dwStyle & WS_MINIMIZE ) ) {
312 if (TWEAK_WineLook == WIN31_LOOK)
313 NC_AdjustRect( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
314 else
315 NC_AdjustRectOuter95( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
317 winRect->left -= tmpRect.left;
318 winRect->top -= tmpRect.top;
319 winRect->right -= tmpRect.right;
320 winRect->bottom -= tmpRect.bottom;
322 if (HAS_MENU(pWnd)) {
323 TRACE(nonclient, "Calling "
324 "GetMenuBarHeight with HWND 0x%x, width %d, "
325 "at (%d, %d).\n", pWnd->hwndSelf,
326 winRect->right - winRect->left,
327 -tmpRect.left, -tmpRect.top );
329 winRect->top +=
330 MENU_GetMenuBarHeight( pWnd->hwndSelf,
331 winRect->right - winRect->left,
332 -tmpRect.left, -tmpRect.top ) + 1;
335 if (TWEAK_WineLook > WIN31_LOOK) {
336 SetRect16 (&tmpRect, 0, 0, 0, 0);
337 NC_AdjustRectInner95 (&tmpRect, pWnd->dwStyle, pWnd->dwExStyle);
338 winRect->left -= tmpRect.left;
339 winRect->top -= tmpRect.top;
340 winRect->right -= tmpRect.right;
341 winRect->bottom -= tmpRect.bottom;
344 return result;
348 /***********************************************************************
349 * NC_GetInsideRect
351 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
352 * but without the borders (if any).
353 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
355 static void NC_GetInsideRect( HWND32 hwnd, RECT32 *rect )
357 WND * wndPtr = WIN_FindWndPtr( hwnd );
359 rect->top = rect->left = 0;
360 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
361 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
363 if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) return;
365 /* Remove frame from rectangle */
366 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
368 InflateRect32( rect, -SYSMETRICS_CXDLGFRAME, -SYSMETRICS_CYDLGFRAME);
369 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
370 InflateRect32( rect, -1, 0 );
372 else
374 if (HAS_THICKFRAME( wndPtr->dwStyle ))
375 InflateRect32( rect, -SYSMETRICS_CXFRAME, -SYSMETRICS_CYFRAME );
376 if (wndPtr->dwStyle & WS_BORDER)
377 InflateRect32( rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER );
380 return;
384 /***********************************************************************
385 * NC_GetInsideRect95
387 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
388 * but without the borders (if any).
389 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
392 static void
393 NC_GetInsideRect95 (HWND32 hwnd, RECT32 *rect)
395 WND * wndPtr = WIN_FindWndPtr( hwnd );
397 rect->top = rect->left = 0;
398 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
399 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
401 if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) return;
403 /* Remove frame from rectangle */
404 if (HAS_FIXEDFRAME (wndPtr->dwStyle, wndPtr->dwExStyle ))
406 InflateRect32( rect, -SYSMETRICS_CXFIXEDFRAME, -SYSMETRICS_CYFIXEDFRAME);
408 else if (HAS_SIZEFRAME (wndPtr->dwStyle))
410 InflateRect32( rect, -SYSMETRICS_CXSIZEFRAME, -SYSMETRICS_CYSIZEFRAME );
412 /* if (wndPtr->dwStyle & WS_BORDER)
413 InflateRect32( rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER );*/
416 if (wndPtr->dwStyle & WS_CHILD) {
417 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
418 InflateRect32 (rect, -SYSMETRICS_CXEDGE, -SYSMETRICS_CYEDGE);
420 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
421 InflateRect32 (rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER);
424 return;
428 /***********************************************************************
429 * NC_DoNCHitTest
431 * Handle a WM_NCHITTEST message. Called from NC_HandleNcHitTest().
434 LONG NC_DoNCHitTest (WND *wndPtr, POINT16 pt )
436 RECT16 rect;
438 TRACE(nonclient, "hwnd=%04x pt=%d,%d\n",
439 wndPtr->hwndSelf, pt.x, pt.y );
441 GetWindowRect16 (wndPtr->hwndSelf, &rect );
442 if (!PtInRect16( &rect, pt )) return HTNOWHERE;
444 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
446 if (!(wndPtr->flags & WIN_MANAGED))
448 /* Check borders */
449 if (HAS_THICKFRAME( wndPtr->dwStyle ))
451 InflateRect16( &rect, -SYSMETRICS_CXFRAME, -SYSMETRICS_CYFRAME );
452 if (wndPtr->dwStyle & WS_BORDER)
453 InflateRect16(&rect,-SYSMETRICS_CXBORDER,-SYSMETRICS_CYBORDER);
454 if (!PtInRect16( &rect, pt ))
456 /* Check top sizing border */
457 if (pt.y < rect.top)
459 if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTTOPLEFT;
460 if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTTOPRIGHT;
461 return HTTOP;
463 /* Check bottom sizing border */
464 if (pt.y >= rect.bottom)
466 if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTBOTTOMLEFT;
467 if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTBOTTOMRIGHT;
468 return HTBOTTOM;
470 /* Check left sizing border */
471 if (pt.x < rect.left)
473 if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPLEFT;
474 if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMLEFT;
475 return HTLEFT;
477 /* Check right sizing border */
478 if (pt.x >= rect.right)
480 if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPRIGHT;
481 if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMRIGHT;
482 return HTRIGHT;
486 else /* No thick frame */
488 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
489 InflateRect16(&rect, -SYSMETRICS_CXDLGFRAME, -SYSMETRICS_CYDLGFRAME);
490 else if (wndPtr->dwStyle & WS_BORDER)
491 InflateRect16(&rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER);
492 if (!PtInRect16( &rect, pt )) return HTBORDER;
495 /* Check caption */
497 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
499 rect.top += sysMetrics[SM_CYCAPTION] - 1;
500 if (!PtInRect16( &rect, pt ))
502 /* Check system menu */
503 if (wndPtr->dwStyle & WS_SYSMENU)
504 rect.left += SYSMETRICS_CXSIZE;
505 if (pt.x <= rect.left) return HTSYSMENU;
506 /* Check maximize box */
507 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
508 rect.right -= SYSMETRICS_CXSIZE + 1;
509 if (pt.x >= rect.right) return HTMAXBUTTON;
510 /* Check minimize box */
511 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
512 rect.right -= SYSMETRICS_CXSIZE + 1;
513 if (pt.x >= rect.right) return HTMINBUTTON;
514 return HTCAPTION;
519 /* Check client area */
521 ScreenToClient16( wndPtr->hwndSelf, &pt );
522 GetClientRect16( wndPtr->hwndSelf, &rect );
523 if (PtInRect16( &rect, pt )) return HTCLIENT;
525 /* Check vertical scroll bar */
527 if (wndPtr->dwStyle & WS_VSCROLL)
529 rect.right += SYSMETRICS_CXVSCROLL;
530 if (PtInRect16( &rect, pt )) return HTVSCROLL;
533 /* Check horizontal scroll bar */
535 if (wndPtr->dwStyle & WS_HSCROLL)
537 rect.bottom += SYSMETRICS_CYHSCROLL;
538 if (PtInRect16( &rect, pt ))
540 /* Check size box */
541 if ((wndPtr->dwStyle & WS_VSCROLL) &&
542 (pt.x >= rect.right - SYSMETRICS_CXVSCROLL))
543 return HTSIZE;
544 return HTHSCROLL;
548 /* Check menu bar */
550 if (HAS_MENU(wndPtr))
552 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
553 return HTMENU;
556 /* Should never get here */
557 return HTERROR;
561 /***********************************************************************
562 * NC_DoNCHitTest95
564 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
566 * FIXME: Just a modified copy of the Win 3.1 version.
569 LONG
570 NC_DoNCHitTest95 (WND *wndPtr, POINT16 pt )
572 RECT16 rect;
574 TRACE(nonclient, "hwnd=%04x pt=%d,%d\n",
575 wndPtr->hwndSelf, pt.x, pt.y );
577 GetWindowRect16 (wndPtr->hwndSelf, &rect );
578 if (!PtInRect16( &rect, pt )) return HTNOWHERE;
580 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
582 if (!(wndPtr->flags & WIN_MANAGED))
584 /* Check borders */
585 if (HAS_SIZEFRAME( wndPtr->dwStyle ))
587 InflateRect16( &rect, -SYSMETRICS_CXFRAME, -SYSMETRICS_CYFRAME );
588 // if (wndPtr->dwStyle & WS_BORDER)
589 // InflateRect16(&rect,-SYSMETRICS_CXBORDER,-SYSMETRICS_CYBORDER);
590 if (!PtInRect16( &rect, pt ))
592 /* Check top sizing border */
593 if (pt.y < rect.top)
595 if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTTOPLEFT;
596 if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTTOPRIGHT;
597 return HTTOP;
599 /* Check bottom sizing border */
600 if (pt.y >= rect.bottom)
602 if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTBOTTOMLEFT;
603 if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTBOTTOMRIGHT;
604 return HTBOTTOM;
606 /* Check left sizing border */
607 if (pt.x < rect.left)
609 if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPLEFT;
610 if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMLEFT;
611 return HTLEFT;
613 /* Check right sizing border */
614 if (pt.x >= rect.right)
616 if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPRIGHT;
617 if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMRIGHT;
618 return HTRIGHT;
622 else /* No thick frame */
624 if (HAS_FIXEDFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
625 InflateRect16(&rect, -SYSMETRICS_CXDLGFRAME, -SYSMETRICS_CYDLGFRAME);
626 // else if (wndPtr->dwStyle & WS_BORDER)
627 // InflateRect16(&rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER);
628 if (!PtInRect16( &rect, pt )) return HTBORDER;
631 /* Check caption */
633 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
635 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
636 rect.top += sysMetrics[SM_CYSMCAPTION] - 1;
637 else
638 rect.top += sysMetrics[SM_CYCAPTION] - 1;
639 if (!PtInRect16( &rect, pt ))
641 /* Check system menu */
642 if ((wndPtr->dwStyle & WS_SYSMENU) &&
643 ((wndPtr->class->hIconSm) || (wndPtr->class->hIcon)))
644 rect.left += sysMetrics[SM_CYCAPTION] - 1;
645 if (pt.x < rect.left) return HTSYSMENU;
647 /* Check close button */
648 if (wndPtr->dwStyle & WS_SYSMENU)
649 rect.right -= sysMetrics[SM_CYCAPTION] - 1;
650 if (pt.x > rect.right) return HTCLOSE;
652 /* Check maximize box */
653 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
654 rect.right -= SYSMETRICS_CXSIZE + 1;
655 if (pt.x > rect.right) return HTMAXBUTTON;
657 /* Check minimize box */
658 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
659 rect.right -= SYSMETRICS_CXSIZE + 1;
660 if (pt.x > rect.right) return HTMINBUTTON;
661 return HTCAPTION;
666 /* Check client area */
668 ScreenToClient16( wndPtr->hwndSelf, &pt );
669 GetClientRect16( wndPtr->hwndSelf, &rect );
670 if (PtInRect16( &rect, pt )) return HTCLIENT;
672 /* Check vertical scroll bar */
674 if (wndPtr->dwStyle & WS_VSCROLL)
676 rect.right += SYSMETRICS_CXVSCROLL;
677 if (PtInRect16( &rect, pt )) return HTVSCROLL;
680 /* Check horizontal scroll bar */
682 if (wndPtr->dwStyle & WS_HSCROLL)
684 rect.bottom += SYSMETRICS_CYHSCROLL;
685 if (PtInRect16( &rect, pt ))
687 /* Check size box */
688 if ((wndPtr->dwStyle & WS_VSCROLL) &&
689 (pt.x >= rect.right - SYSMETRICS_CXVSCROLL))
690 return HTSIZE;
691 return HTHSCROLL;
695 /* Check menu bar */
697 if (HAS_MENU(wndPtr))
699 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
700 return HTMENU;
703 /* Should never get here */
704 return HTERROR;
708 /***********************************************************************
709 * NC_HandleNCHitTest
711 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
713 LONG
714 NC_HandleNCHitTest (HWND32 hwnd , POINT16 pt)
716 WND *wndPtr = WIN_FindWndPtr (hwnd);
718 if (!wndPtr)
719 return HTERROR;
721 if (TWEAK_WineLook == WIN31_LOOK)
722 return NC_DoNCHitTest (wndPtr, pt);
723 else
724 return NC_DoNCHitTest95 (wndPtr, pt);
728 /***********************************************************************
729 * NC_DrawSysButton
731 void NC_DrawSysButton( HWND32 hwnd, HDC32 hdc, BOOL32 down )
733 RECT32 rect;
734 HDC32 hdcMem;
735 HBITMAP32 hbitmap;
736 WND *wndPtr = WIN_FindWndPtr( hwnd );
738 if( !(wndPtr->flags & WIN_MANAGED) )
740 NC_GetInsideRect( hwnd, &rect );
741 hdcMem = CreateCompatibleDC32( hdc );
742 hbitmap = SelectObject32( hdcMem, hbitmapClose );
743 BitBlt32(hdc, rect.left, rect.top, SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE,
744 hdcMem, (wndPtr->dwStyle & WS_CHILD) ? SYSMETRICS_CXSIZE : 0, 0,
745 down ? NOTSRCCOPY : SRCCOPY );
746 SelectObject32( hdcMem, hbitmap );
747 DeleteDC32( hdcMem );
752 /***********************************************************************
753 * NC_DrawMaxButton
755 static void NC_DrawMaxButton( HWND32 hwnd, HDC16 hdc, BOOL32 down )
757 RECT32 rect;
758 WND *wndPtr = WIN_FindWndPtr( hwnd );
760 if( !(wndPtr->flags & WIN_MANAGED) )
762 NC_GetInsideRect( hwnd, &rect );
763 GRAPH_DrawBitmap( hdc, (IsZoomed32(hwnd)
764 ? (down ? hbitmapRestoreD : hbitmapRestore)
765 : (down ? hbitmapMaximizeD : hbitmapMaximize)),
766 rect.right - SYSMETRICS_CXSIZE - 1, rect.top,
767 0, 0, SYSMETRICS_CXSIZE+1, SYSMETRICS_CYSIZE, FALSE );
772 /***********************************************************************
773 * NC_DrawMinButton
775 static void NC_DrawMinButton( HWND32 hwnd, HDC16 hdc, BOOL32 down )
777 RECT32 rect;
778 WND *wndPtr = WIN_FindWndPtr( hwnd );
780 if( !(wndPtr->flags & WIN_MANAGED) )
782 NC_GetInsideRect( hwnd, &rect );
783 if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= SYSMETRICS_CXSIZE+1;
784 GRAPH_DrawBitmap( hdc, (down ? hbitmapMinimizeD : hbitmapMinimize),
785 rect.right - SYSMETRICS_CXSIZE - 1, rect.top,
786 0, 0, SYSMETRICS_CXSIZE+1, SYSMETRICS_CYSIZE, FALSE );
791 /******************************************************************************
793 * void NC_DrawSysButton95(
794 * HWND32 hwnd,
795 * HDC32 hdc,
796 * BOOL32 down )
798 * Draws the Win95 system icon.
800 * Revision history
801 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
802 * Original implementation from NC_DrawSysButton source.
803 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
804 * Fixed most bugs.
806 *****************************************************************************/
808 BOOL32
809 NC_DrawSysButton95 (HWND32 hwnd, HDC32 hdc, BOOL32 down)
811 WND *wndPtr = WIN_FindWndPtr( hwnd );
813 if( !(wndPtr->flags & WIN_MANAGED) )
815 HICON32 hIcon = 0;
816 RECT32 rect;
818 NC_GetInsideRect95( hwnd, &rect );
820 if (wndPtr->class->hIconSm)
821 hIcon = wndPtr->class->hIconSm;
822 else if (wndPtr->class->hIcon)
823 hIcon = wndPtr->class->hIcon;
824 // else
825 // hIcon = LoadIcon32A (0, IDI_APPLICATION);
827 if (hIcon)
828 DrawIconEx32 (hdc, rect.left + 2, rect.top + 1, hIcon,
829 sysMetrics[SM_CXSMICON],
830 sysMetrics[SM_CYSMICON],
831 0, 0, DI_NORMAL);
833 return (hIcon != 0);
835 return FALSE;
839 /******************************************************************************
841 * void NC_DrawCloseButton95(
842 * HWND32 hwnd,
843 * HDC32 hdc,
844 * BOOL32 down )
846 * Draws the Win95 close button.
848 * Revision history
849 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
850 * Original implementation from NC_DrawSysButton95 source.
852 *****************************************************************************/
854 void
855 NC_DrawCloseButton95 (HWND32 hwnd, HDC32 hdc, BOOL32 down)
857 RECT32 rect;
858 HDC32 hdcMem;
859 WND *wndPtr = WIN_FindWndPtr( hwnd );
861 if( !(wndPtr->flags & WIN_MANAGED) )
863 BITMAP32 bmp;
864 HBITMAP32 hBmp, hOldBmp;
866 NC_GetInsideRect95( hwnd, &rect );
868 hdcMem = CreateCompatibleDC32( hdc );
869 hBmp = /*down ? hbitmapCloseD :*/ hbitmapClose;
870 hOldBmp = SelectObject32 (hdcMem, hBmp);
871 GetObject32A (hBmp, sizeof(BITMAP32), &bmp);
872 BitBlt32 (hdc, rect.right - (sysMetrics[SM_CYCAPTION] + 1 + bmp.bmWidth) / 2,
873 rect.top + (sysMetrics[SM_CYCAPTION] - 1 - bmp.bmHeight) / 2,
874 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, down ? NOTSRCCOPY : SRCCOPY);
876 SelectObject32 (hdcMem, hOldBmp);
877 DeleteDC32 (hdcMem);
882 /******************************************************************************
884 * NC_DrawMaxButton95(
885 * HWND32 hwnd,
886 * HDC16 hdc,
887 * BOOL32 down )
889 * Draws the maximize button for Win95 style windows.
891 * Bugs
892 * Many. Spacing might still be incorrect. Need to fit a close
893 * button between the max button and the edge.
894 * Should scale the image with the title bar. And more...
896 * Revision history
897 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
898 * Original implementation.
900 *****************************************************************************/
902 static void NC_DrawMaxButton95(
903 HWND32 hwnd,
904 HDC16 hdc,
905 BOOL32 down )
907 RECT32 rect;
908 WND *wndPtr = WIN_FindWndPtr( hwnd );
909 SIZE32 bmsz;
910 HBITMAP32 bm;
912 if( !(wndPtr->flags & WIN_MANAGED) &&
913 GetBitmapDimensionEx32((bm = IsZoomed32(hwnd) ?
914 (down ? hbitmapRestoreD : hbitmapRestore ) :
915 (down ? hbitmapMaximizeD : hbitmapMaximize)),
916 &bmsz)) {
918 NC_GetInsideRect95( hwnd, &rect );
920 if (wndPtr->dwStyle & WS_SYSMENU)
921 rect.right -= sysMetrics[SM_CYCAPTION] + 1;
923 GRAPH_DrawBitmap( hdc, bm, rect.right -
924 (sysMetrics[SM_CXSIZE] + bmsz.cx) / 2,
925 rect.top + (sysMetrics[SM_CYCAPTION] - 1 - bmsz.cy) / 2,
926 0, 0, bmsz.cx, bmsz.cy, FALSE );
929 return;
933 /******************************************************************************
935 * NC_DrawMinButton95(
936 * HWND32 hwnd,
937 * HDC16 hdc,
938 * BOOL32 down )
940 * Draws the minimize button for Win95 style windows.
942 * Bugs
943 * Many. Spacing is still incorrect. Should scale the image with the
944 * title bar. And more...
946 * Revision history
947 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
948 * Original implementation.
950 *****************************************************************************/
952 static void NC_DrawMinButton95(
953 HWND32 hwnd,
954 HDC16 hdc,
955 BOOL32 down )
957 RECT32 rect;
958 WND *wndPtr = WIN_FindWndPtr( hwnd );
959 SIZE32 bmsz;
960 HBITMAP32 bm;
962 if( !(wndPtr->flags & WIN_MANAGED) &&
963 GetBitmapDimensionEx32((bm = down ? hbitmapMinimizeD :
964 hbitmapMinimize), &bmsz)) {
966 NC_GetInsideRect95( hwnd, &rect );
968 if (wndPtr->dwStyle & WS_SYSMENU)
969 rect.right -= sysMetrics[SM_CYCAPTION] + 1;
971 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
972 rect.right += -1 -
973 (sysMetrics[SM_CXSIZE] + bmsz.cx) / 2;
975 GRAPH_DrawBitmap( hdc, bm, rect.right -
976 (sysMetrics[SM_CXSIZE] + bmsz.cx) / 2,
977 rect.top + (sysMetrics[SM_CYCAPTION] - 1 - bmsz.cy) / 2,
978 0, 0, bmsz.cx, bmsz.cy, FALSE );
981 return;
985 /***********************************************************************
986 * NC_DrawFrame
988 * Draw a window frame inside the given rectangle, and update the rectangle.
989 * The correct pen for the frame must be selected in the DC.
991 static void NC_DrawFrame( HDC32 hdc, RECT32 *rect, BOOL32 dlgFrame,
992 BOOL32 active )
994 INT32 width, height;
996 if (TWEAK_WineLook != WIN31_LOOK)
997 ERR (nonclient, "Called in Win95 mode. Aiee! Please report this.\n" );
999 if (dlgFrame)
1001 width = SYSMETRICS_CXDLGFRAME - 1;
1002 height = SYSMETRICS_CYDLGFRAME - 1;
1003 SelectObject32( hdc, GetSysColorBrush32(active ? COLOR_ACTIVECAPTION :
1004 COLOR_INACTIVECAPTION) );
1006 else
1008 width = SYSMETRICS_CXFRAME - 1;
1009 height = SYSMETRICS_CYFRAME - 1;
1010 SelectObject32( hdc, GetSysColorBrush32(active ? COLOR_ACTIVEBORDER :
1011 COLOR_INACTIVEBORDER) );
1014 /* Draw frame */
1015 PatBlt32( hdc, rect->left, rect->top,
1016 rect->right - rect->left, height, PATCOPY );
1017 PatBlt32( hdc, rect->left, rect->top,
1018 width, rect->bottom - rect->top, PATCOPY );
1019 PatBlt32( hdc, rect->left, rect->bottom,
1020 rect->right - rect->left, -height, PATCOPY );
1021 PatBlt32( hdc, rect->right, rect->top,
1022 -width, rect->bottom - rect->top, PATCOPY );
1024 if (dlgFrame)
1026 InflateRect32( rect, -width, -height );
1028 else
1030 POINT32 lpt[16];
1032 /* Draw inner rectangle */
1034 GRAPH_DrawRectangle( hdc, rect->left + width,
1035 rect->top + height,
1036 rect->right - rect->left - 2*width ,
1037 rect->bottom - rect->top - 2*height,
1038 (HPEN32)0 );
1040 /* Draw the decorations */
1042 lpt[4].x = lpt[0].x = rect->left;
1043 lpt[5].x = lpt[1].x = rect->left + width;
1044 lpt[6].x = lpt[2].x = rect->right - 1;
1045 lpt[7].x = lpt[3].x = rect->right - width - 1;
1047 lpt[0].y = lpt[1].y = lpt[2].y = lpt[3].y =
1048 rect->top + SYSMETRICS_CYFRAME + SYSMETRICS_CYSIZE;
1049 lpt[4].y = lpt[5].y = lpt[6].y = lpt[7].y =
1050 rect->bottom - SYSMETRICS_CYFRAME - SYSMETRICS_CYSIZE;
1052 lpt[8].x = lpt[9].x = lpt[10].x = lpt[11].x =
1053 rect->left + SYSMETRICS_CXFRAME + SYSMETRICS_CXSIZE;
1054 lpt[12].x = lpt[13].x = lpt[14].x = lpt[15].x =
1055 rect->right - SYSMETRICS_CXFRAME - SYSMETRICS_CYSIZE;
1057 lpt[12].y = lpt[8].y = rect->top;
1058 lpt[13].y = lpt[9].y = rect->top + height;
1059 lpt[14].y = lpt[10].y = rect->bottom - 1;
1060 lpt[15].y = lpt[11].y = rect->bottom - height - 1;
1062 GRAPH_DrawLines( hdc, lpt, 8, (HPEN32)0 ); /* 8 is the maximum */
1063 InflateRect32( rect, -width - 1, -height - 1 );
1068 /******************************************************************************
1070 * void NC_DrawFrame95(
1071 * HDC32 hdc,
1072 * RECT32 *rect,
1073 * BOOL32 dlgFrame,
1074 * BOOL32 active )
1076 * Draw a window frame inside the given rectangle, and update the rectangle.
1077 * The correct pen for the frame must be selected in the DC.
1079 * Bugs
1080 * Many. First, just what IS a frame in Win95? Note that the 3D look
1081 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1082 * edge. The inner rectangle just inside the frame is handled by the
1083 * Caption code.
1085 * In short, for most people, this function should be a nop (unless
1086 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1087 * them lately, but just to get this code right). Even so, it doesn't
1088 * appear to be so. It's being worked on...
1090 * Revision history
1091 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1092 * Original implementation (based on NC_DrawFrame)
1093 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1094 * Some minor fixes.
1096 *****************************************************************************/
1098 static void NC_DrawFrame95(
1099 HDC32 hdc,
1100 RECT32 *rect,
1101 BOOL32 dlgFrame,
1102 BOOL32 active )
1104 INT32 width, height;
1106 if (dlgFrame)
1108 width = sysMetrics[SM_CXDLGFRAME] - sysMetrics[SM_CXEDGE];
1109 height = sysMetrics[SM_CYDLGFRAME] - sysMetrics[SM_CYEDGE];
1111 else
1113 width = sysMetrics[SM_CXFRAME] - sysMetrics[SM_CXEDGE];
1114 height = sysMetrics[SM_CYFRAME] - sysMetrics[SM_CYEDGE];
1117 SelectObject32( hdc, GetSysColorBrush32(active ? COLOR_ACTIVEBORDER :
1118 COLOR_INACTIVEBORDER) );
1120 /* Draw frame */
1121 PatBlt32( hdc, rect->left, rect->top,
1122 rect->right - rect->left, height, PATCOPY );
1123 PatBlt32( hdc, rect->left, rect->top,
1124 width, rect->bottom - rect->top, PATCOPY );
1125 PatBlt32( hdc, rect->left, rect->bottom,
1126 rect->right - rect->left, -height, PATCOPY );
1127 PatBlt32( hdc, rect->right, rect->top,
1128 -width, rect->bottom - rect->top, PATCOPY );
1130 InflateRect32( rect, -width, -height );
1135 /***********************************************************************
1136 * NC_DrawMovingFrame
1138 * Draw the frame used when moving or resizing window.
1140 * FIXME: This causes problems in Win95 mode. (why?)
1142 static void NC_DrawMovingFrame( HDC32 hdc, RECT32 *rect, BOOL32 thickframe )
1144 if (thickframe)
1146 RECT16 r16;
1147 CONV_RECT32TO16( rect, &r16 );
1148 FastWindowFrame( hdc, &r16, SYSMETRICS_CXFRAME,
1149 SYSMETRICS_CYFRAME, PATINVERT );
1151 else DrawFocusRect32( hdc, rect );
1155 /***********************************************************************
1156 * NC_DrawCaption
1158 * Draw the window caption.
1159 * The correct pen for the window frame must be selected in the DC.
1161 static void NC_DrawCaption( HDC32 hdc, RECT32 *rect, HWND32 hwnd,
1162 DWORD style, BOOL32 active )
1164 RECT32 r = *rect;
1165 WND * wndPtr = WIN_FindWndPtr( hwnd );
1166 char buffer[256];
1168 if (wndPtr->flags & WIN_MANAGED) return;
1170 if (!hbitmapClose)
1172 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1173 return;
1174 hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) );
1175 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1176 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1177 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1178 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1179 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1180 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1183 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
1185 HBRUSH32 hbrushOld = SelectObject32(hdc, GetSysColorBrush32(COLOR_WINDOW) );
1186 PatBlt32( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
1187 PatBlt32( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
1188 PatBlt32( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
1189 r.left++;
1190 r.right--;
1191 SelectObject32( hdc, hbrushOld );
1194 MoveTo( hdc, r.left, r.bottom );
1195 LineTo32( hdc, r.right, r.bottom );
1197 if (style & WS_SYSMENU)
1199 NC_DrawSysButton( hwnd, hdc, FALSE );
1200 r.left += SYSMETRICS_CXSIZE + 1;
1201 MoveTo( hdc, r.left - 1, r.top );
1202 LineTo32( hdc, r.left - 1, r.bottom );
1204 if (style & WS_MAXIMIZEBOX)
1206 NC_DrawMaxButton( hwnd, hdc, FALSE );
1207 r.right -= SYSMETRICS_CXSIZE + 1;
1209 if (style & WS_MINIMIZEBOX)
1211 NC_DrawMinButton( hwnd, hdc, FALSE );
1212 r.right -= SYSMETRICS_CXSIZE + 1;
1215 FillRect32( hdc, &r, GetSysColorBrush32(active ? COLOR_ACTIVECAPTION :
1216 COLOR_INACTIVECAPTION) );
1218 if (GetWindowText32A( hwnd, buffer, sizeof(buffer) ))
1220 if (active) SetTextColor32( hdc, GetSysColor32( COLOR_CAPTIONTEXT ) );
1221 else SetTextColor32( hdc, GetSysColor32( COLOR_INACTIVECAPTIONTEXT ) );
1222 SetBkMode32( hdc, TRANSPARENT );
1223 DrawText32A( hdc, buffer, -1, &r,
1224 DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );
1229 /******************************************************************************
1231 * NC_DrawCaption95(
1232 * HDC32 hdc,
1233 * RECT32 *rect,
1234 * HWND32 hwnd,
1235 * DWORD style,
1236 * BOOL32 active )
1238 * Draw the window caption for Win95 style windows.
1239 * The correct pen for the window frame must be selected in the DC.
1241 * Bugs
1242 * Hey, a function that finally works! Well, almost.
1243 * It's being worked on.
1245 * Revision history
1246 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1247 * Original implementation.
1248 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1249 * Some minor fixes.
1251 *****************************************************************************/
1253 static void NC_DrawCaption95(
1254 HDC32 hdc,
1255 RECT32 *rect,
1256 HWND32 hwnd,
1257 DWORD style,
1258 BOOL32 active )
1260 RECT32 r = *rect;
1261 WND *wndPtr = WIN_FindWndPtr( hwnd );
1262 char buffer[256];
1263 POINT32 sep[2] = { { r.left, r.bottom - 1 },
1264 { r.right, r.bottom - 1 } };
1266 if (wndPtr->flags & WIN_MANAGED) return;
1268 GRAPH_DrawLines( hdc, sep, 1, GetSysColorPen32(COLOR_3DFACE) );
1269 r.bottom--;
1271 FillRect32( hdc, &r, GetSysColorBrush32(active ? COLOR_ACTIVECAPTION :
1272 COLOR_INACTIVECAPTION) );
1274 if (!hbitmapClose) {
1275 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1276 return;
1277 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1278 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1279 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1280 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1281 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1282 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1285 if (style & WS_SYSMENU) {
1286 if (NC_DrawSysButton95 (hwnd, hdc, FALSE))
1287 r.left += sysMetrics[SM_CYCAPTION] - 1;
1288 NC_DrawCloseButton95 (hwnd, hdc, FALSE);
1289 r.right -= sysMetrics[SM_CYCAPTION] - 1;
1291 if (style & WS_MAXIMIZEBOX) {
1292 NC_DrawMaxButton95( hwnd, hdc, FALSE );
1293 r.right -= SYSMETRICS_CXSIZE + 1;
1295 if (style & WS_MINIMIZEBOX) {
1296 NC_DrawMinButton95( hwnd, hdc, FALSE );
1297 r.right -= SYSMETRICS_CXSIZE + 1;
1300 if (GetWindowText32A( hwnd, buffer, sizeof(buffer) )) {
1301 NONCLIENTMETRICS32A nclm;
1302 HFONT32 hFont, hOldFont;
1303 nclm.cbSize = sizeof(NONCLIENTMETRICS32A);
1304 SystemParametersInfo32A (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1305 hFont = CreateFontIndirect32A (&nclm.lfCaptionFont);
1306 hOldFont = SelectObject32 (hdc, hFont);
1307 if (active) SetTextColor32( hdc, GetSysColor32( COLOR_CAPTIONTEXT ) );
1308 else SetTextColor32( hdc, GetSysColor32( COLOR_INACTIVECAPTIONTEXT ) );
1309 SetBkMode32( hdc, TRANSPARENT );
1310 r.left += 2;
1311 DrawText32A( hdc, buffer, -1, &r,
1312 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
1313 DeleteObject32 (SelectObject32 (hdc, hOldFont));
1319 /***********************************************************************
1320 * NC_DoNCPaint
1322 * Paint the non-client area. clip is currently unused.
1324 void NC_DoNCPaint( WND* wndPtr, HRGN32 clip, BOOL32 suppress_menupaint )
1326 HDC32 hdc;
1327 RECT32 rect;
1328 BOOL32 active;
1329 HWND32 hwnd = wndPtr->hwndSelf;
1331 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1332 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1334 active = wndPtr->flags & WIN_NCACTIVATED;
1336 TRACE(nonclient, "%04x %d\n", hwnd, active );
1338 if (!(hdc = GetDCEx32( hwnd, 0, DCX_USESTYLE | DCX_WINDOW ))) return;
1340 if (ExcludeVisRect( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1341 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1342 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1343 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1344 == NULLREGION)
1346 ReleaseDC32( hwnd, hdc );
1347 return;
1350 rect.top = rect.left = 0;
1351 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1352 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1354 SelectObject32( hdc, GetSysColorPen32(COLOR_WINDOWFRAME) );
1356 if (!(wndPtr->flags & WIN_MANAGED))
1358 if ((wndPtr->dwStyle & WS_BORDER) || (wndPtr->dwStyle & WS_DLGFRAME) ||
1359 (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME))
1361 GRAPH_DrawRectangle( hdc, 0, 0,
1362 rect.right, rect.bottom, (HPEN32)0 );
1363 InflateRect32( &rect, -1, -1 );
1366 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1367 NC_DrawFrame( hdc, &rect, TRUE, active );
1368 else if (wndPtr->dwStyle & WS_THICKFRAME)
1369 NC_DrawFrame(hdc, &rect, FALSE, active );
1371 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1373 RECT32 r = rect;
1374 r.bottom = rect.top + SYSMETRICS_CYSIZE;
1375 rect.top += SYSMETRICS_CYSIZE + SYSMETRICS_CYBORDER;
1376 NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active );
1380 if (HAS_MENU(wndPtr))
1382 RECT32 r = rect;
1383 r.bottom = rect.top + SYSMETRICS_CYMENU; /* default height */
1384 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint );
1387 /* Draw the scroll-bars */
1389 if (wndPtr->dwStyle & WS_VSCROLL)
1390 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE );
1391 if (wndPtr->dwStyle & WS_HSCROLL)
1392 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE );
1394 /* Draw the "size-box" */
1396 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1398 RECT32 r = rect;
1399 r.left = r.right - SYSMETRICS_CXVSCROLL + 1;
1400 r.top = r.bottom - SYSMETRICS_CYHSCROLL + 1;
1401 if(wndPtr->dwStyle & WS_BORDER) {
1402 r.left++;
1403 r.top++;
1405 FillRect32( hdc, &r, GetSysColorBrush32(COLOR_SCROLLBAR) );
1408 ReleaseDC32( hwnd, hdc );
1412 /******************************************************************************
1414 * void NC_DoNCPaint95(
1415 * WND *wndPtr,
1416 * HRGN32 clip,
1417 * BOOL32 suppress_menupaint )
1419 * Paint the non-client area for Win95 windows. The clip region is
1420 * currently ignored.
1422 * Bugs
1423 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1424 * misc/tweak.c controls/menu.c # :-)
1426 * Revision history
1427 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1428 * Original implementation
1429 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1430 * Fixed some bugs.
1432 *****************************************************************************/
1434 void NC_DoNCPaint95(
1435 WND *wndPtr,
1436 HRGN32 clip,
1437 BOOL32 suppress_menupaint )
1439 HDC32 hdc;
1440 RECT32 rect;
1441 BOOL32 active;
1442 HWND32 hwnd = wndPtr->hwndSelf;
1444 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1445 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1447 active = wndPtr->flags & WIN_NCACTIVATED;
1449 TRACE(nonclient, "%04x %d\n", hwnd, active );
1451 if (!(hdc = GetDCEx32( hwnd, 0, DCX_USESTYLE | DCX_WINDOW ))) return;
1453 if (ExcludeVisRect( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1454 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1455 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1456 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1457 == NULLREGION)
1459 ReleaseDC32( hwnd, hdc );
1460 return;
1463 rect.top = rect.left = 0;
1464 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1465 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1467 SelectObject32( hdc, GetSysColorPen32(COLOR_WINDOWFRAME) );
1469 if(!(wndPtr->flags & WIN_MANAGED)) {
1470 if ((wndPtr->dwStyle & WS_BORDER) && ((wndPtr->dwStyle & WS_DLGFRAME) ||
1471 (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME) || (wndPtr->dwStyle & WS_THICKFRAME))) {
1472 DrawEdge32 (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1475 if (HAS_FIXEDFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1476 NC_DrawFrame95( hdc, &rect, TRUE, active );
1477 else if (wndPtr->dwStyle & WS_THICKFRAME)
1478 NC_DrawFrame95(hdc, &rect, FALSE, active );
1480 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1482 RECT32 r = rect;
1483 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW) {
1484 r.bottom = rect.top + sysMetrics[SM_CYSMCAPTION];
1485 rect.top += sysMetrics[SM_CYSMCAPTION];
1487 else {
1488 r.bottom = rect.top + sysMetrics[SM_CYCAPTION];
1489 rect.top += sysMetrics[SM_CYCAPTION];
1491 NC_DrawCaption95( hdc, &r, hwnd, wndPtr->dwStyle, active );
1495 if (HAS_MENU(wndPtr))
1497 RECT32 r = rect;
1498 r.bottom = rect.top + sysMetrics[SM_CYMENU];
1500 TRACE(nonclient, "Calling DrawMenuBar with "
1501 "rect (%d, %d)-(%d, %d)\n", r.left, r.top,
1502 r.right, r.bottom);
1504 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ) + 1;
1507 TRACE(nonclient, "After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1508 rect.left, rect.top, rect.right, rect.bottom );
1510 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
1511 DrawEdge32 (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1513 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
1514 DrawEdge32 (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1516 /* Draw the scroll-bars */
1518 if (wndPtr->dwStyle & WS_VSCROLL)
1519 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE );
1520 if (wndPtr->dwStyle & WS_HSCROLL)
1521 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE );
1523 /* Draw the "size-box" */
1524 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1526 RECT32 r = rect;
1527 r.left = r.right - SYSMETRICS_CXVSCROLL + 1;
1528 r.top = r.bottom - SYSMETRICS_CYHSCROLL + 1;
1529 FillRect32( hdc, &r, GetSysColorBrush32(COLOR_SCROLLBAR) );
1532 ReleaseDC32( hwnd, hdc );
1538 /***********************************************************************
1539 * NC_HandleNCPaint
1541 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1543 LONG NC_HandleNCPaint( HWND32 hwnd , HRGN32 clip)
1545 WND* wndPtr = WIN_FindWndPtr( hwnd );
1547 if( wndPtr && wndPtr->dwStyle & WS_VISIBLE )
1549 if( wndPtr->dwStyle & WS_MINIMIZE )
1550 WINPOS_RedrawIconTitle( hwnd );
1551 else if (TWEAK_WineLook == WIN31_LOOK)
1552 NC_DoNCPaint( wndPtr, clip, FALSE );
1553 else
1554 NC_DoNCPaint95( wndPtr, clip, FALSE );
1556 return 0;
1560 /***********************************************************************
1561 * NC_HandleNCActivate
1563 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1565 LONG NC_HandleNCActivate( WND *wndPtr, WPARAM16 wParam )
1567 WORD wStateChange;
1569 if( wParam ) wStateChange = !(wndPtr->flags & WIN_NCACTIVATED);
1570 else wStateChange = wndPtr->flags & WIN_NCACTIVATED;
1572 if( wStateChange )
1574 if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
1575 else wndPtr->flags &= ~WIN_NCACTIVATED;
1577 if( wndPtr->dwStyle & WS_MINIMIZE )
1578 WINPOS_RedrawIconTitle( wndPtr->hwndSelf );
1579 else if (TWEAK_WineLook == WIN31_LOOK)
1580 NC_DoNCPaint( wndPtr, (HRGN32)1, FALSE );
1581 else
1582 NC_DoNCPaint95( wndPtr, (HRGN32)1, FALSE );
1584 return TRUE;
1588 /***********************************************************************
1589 * NC_HandleSetCursor
1591 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1593 LONG NC_HandleSetCursor( HWND32 hwnd, WPARAM16 wParam, LPARAM lParam )
1595 if (hwnd != (HWND32)wParam) return 0; /* Don't set the cursor for child windows */
1597 switch(LOWORD(lParam))
1599 case HTERROR:
1601 WORD msg = HIWORD( lParam );
1602 if ((msg == WM_LBUTTONDOWN) || (msg == WM_MBUTTONDOWN) ||
1603 (msg == WM_RBUTTONDOWN))
1604 MessageBeep32(0);
1606 break;
1608 case HTCLIENT:
1610 WND *wndPtr;
1611 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) break;
1612 if (wndPtr->class->hCursor)
1614 SetCursor16( wndPtr->class->hCursor );
1615 return TRUE;
1617 else return FALSE;
1620 case HTLEFT:
1621 case HTRIGHT:
1622 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZEWE16 ) );
1624 case HTTOP:
1625 case HTBOTTOM:
1626 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENS16 ) );
1628 case HTTOPLEFT:
1629 case HTBOTTOMRIGHT:
1630 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENWSE16 ) );
1632 case HTTOPRIGHT:
1633 case HTBOTTOMLEFT:
1634 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENESW16 ) );
1637 /* Default cursor: arrow */
1638 return (LONG)SetCursor16( LoadCursor16( 0, IDC_ARROW16 ) );
1641 /***********************************************************************
1642 * NC_GetSysPopupPos
1644 BOOL32 NC_GetSysPopupPos( WND* wndPtr, RECT32* rect )
1646 if( wndPtr->hSysMenu )
1648 if( wndPtr->dwStyle & WS_MINIMIZE )
1649 GetWindowRect32( wndPtr->hwndSelf, rect );
1650 else
1652 if (TWEAK_WineLook == WIN31_LOOK)
1653 NC_GetInsideRect( wndPtr->hwndSelf, rect );
1654 else
1655 NC_GetInsideRect95( wndPtr->hwndSelf, rect );
1656 OffsetRect32( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
1657 if (wndPtr->dwStyle & WS_CHILD)
1658 ClientToScreen32( wndPtr->parent->hwndSelf, (POINT32 *)rect );
1659 if (TWEAK_WineLook == WIN31_LOOK) {
1660 rect->right = rect->left + SYSMETRICS_CXSIZE;
1661 rect->bottom = rect->top + SYSMETRICS_CYSIZE;
1663 else {
1664 rect->right = rect->left + sysMetrics[SM_CYCAPTION] - 1;
1665 rect->bottom = rect->top + sysMetrics[SM_CYCAPTION] - 1;
1668 return TRUE;
1670 return FALSE;
1673 /***********************************************************************
1674 * NC_StartSizeMove
1676 * Initialisation of a move or resize, when initiatied from a menu choice.
1677 * Return hit test code for caption or sizing border.
1679 static LONG NC_StartSizeMove( WND* wndPtr, WPARAM16 wParam,
1680 POINT16 *capturePoint )
1682 LONG hittest = 0;
1683 POINT16 pt;
1684 MSG16 msg;
1686 if ((wParam & 0xfff0) == SC_MOVE)
1688 /* Move pointer at the center of the caption */
1689 RECT32 rect;
1690 if (TWEAK_WineLook == WIN31_LOOK)
1691 NC_GetInsideRect( wndPtr->hwndSelf, &rect );
1692 else
1693 NC_GetInsideRect95( wndPtr->hwndSelf, &rect );
1694 if (wndPtr->dwStyle & WS_SYSMENU)
1695 rect.left += SYSMETRICS_CXSIZE + 1;
1696 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
1697 rect.right -= SYSMETRICS_CXSIZE + 1;
1698 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
1699 rect.right -= SYSMETRICS_CXSIZE + 1;
1700 pt.x = wndPtr->rectWindow.left + (rect.right - rect.left) / 2;
1701 pt.y = wndPtr->rectWindow.top + rect.top + SYSMETRICS_CYSIZE/2;
1702 hittest = HTCAPTION;
1703 *capturePoint = pt;
1705 if (wndPtr->dwStyle & WS_CHILD)
1706 ClientToScreen16( wndPtr->parent->hwndSelf, &pt );
1708 else /* SC_SIZE */
1710 while(!hittest)
1712 MSG_InternalGetMessage( &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE );
1713 switch(msg.message)
1715 case WM_MOUSEMOVE:
1716 hittest = NC_HandleNCHitTest( wndPtr->hwndSelf, msg.pt );
1717 pt = msg.pt;
1718 if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
1719 hittest = 0;
1720 break;
1722 case WM_LBUTTONUP:
1723 return 0;
1725 case WM_KEYDOWN:
1726 switch(msg.wParam)
1728 case VK_UP:
1729 hittest = HTTOP;
1730 pt.x =(wndPtr->rectWindow.left+wndPtr->rectWindow.right)/2;
1731 pt.y = wndPtr->rectWindow.top + SYSMETRICS_CYFRAME / 2;
1732 break;
1733 case VK_DOWN:
1734 hittest = HTBOTTOM;
1735 pt.x =(wndPtr->rectWindow.left+wndPtr->rectWindow.right)/2;
1736 pt.y = wndPtr->rectWindow.bottom - SYSMETRICS_CYFRAME / 2;
1737 break;
1738 case VK_LEFT:
1739 hittest = HTLEFT;
1740 pt.x = wndPtr->rectWindow.left + SYSMETRICS_CXFRAME / 2;
1741 pt.y =(wndPtr->rectWindow.top+wndPtr->rectWindow.bottom)/2;
1742 break;
1743 case VK_RIGHT:
1744 hittest = HTRIGHT;
1745 pt.x = wndPtr->rectWindow.right - SYSMETRICS_CXFRAME / 2;
1746 pt.y =(wndPtr->rectWindow.top+wndPtr->rectWindow.bottom)/2;
1747 break;
1748 case VK_RETURN:
1749 case VK_ESCAPE: return 0;
1753 *capturePoint = pt;
1755 SetCursorPos32( pt.x, pt.y );
1756 NC_HandleSetCursor( wndPtr->hwndSelf,
1757 wndPtr->hwndSelf, MAKELONG( hittest, WM_MOUSEMOVE ));
1758 return hittest;
1762 /***********************************************************************
1763 * NC_DoSizeMove
1765 * Perform SC_MOVE and SC_SIZE commands.
1767 static void NC_DoSizeMove( HWND32 hwnd, WORD wParam )
1769 MSG16 msg;
1770 RECT32 sizingRect, mouseRect;
1771 HDC32 hdc;
1772 LONG hittest = (LONG)(wParam & 0x0f);
1773 HCURSOR16 hDragCursor = 0, hOldCursor = 0;
1774 POINT32 minTrack, maxTrack;
1775 POINT16 capturePoint, pt;
1776 WND * wndPtr = WIN_FindWndPtr( hwnd );
1777 BOOL32 thickframe = HAS_THICKFRAME( wndPtr->dwStyle );
1778 BOOL32 iconic = wndPtr->dwStyle & WS_MINIMIZE;
1779 BOOL32 moved = FALSE;
1781 GetCursorPos16 (&pt);
1782 capturePoint = pt;
1784 if (IsZoomed32(hwnd) || !IsWindowVisible32(hwnd) ||
1785 (wndPtr->flags & WIN_MANAGED)) return;
1787 if ((wParam & 0xfff0) == SC_MOVE)
1789 if (!(wndPtr->dwStyle & WS_CAPTION)) return;
1790 if (!hittest)
1791 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
1792 if (!hittest) return;
1794 else /* SC_SIZE */
1796 if (!thickframe) return;
1797 if ( hittest && hittest != HTSYSMENU ) hittest += 2;
1798 else
1800 SetCapture32(hwnd);
1801 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
1802 if (!hittest)
1804 ReleaseCapture();
1805 return;
1810 /* Get min/max info */
1812 WINPOS_GetMinMaxInfo( wndPtr, NULL, NULL, &minTrack, &maxTrack );
1813 sizingRect = wndPtr->rectWindow;
1814 if (wndPtr->dwStyle & WS_CHILD)
1815 GetClientRect32( wndPtr->parent->hwndSelf, &mouseRect );
1816 else
1817 SetRect32(&mouseRect, 0, 0, SYSMETRICS_CXSCREEN, SYSMETRICS_CYSCREEN);
1818 if (ON_LEFT_BORDER(hittest))
1820 mouseRect.left = MAX( mouseRect.left, sizingRect.right-maxTrack.x );
1821 mouseRect.right = MIN( mouseRect.right, sizingRect.right-minTrack.x );
1823 else if (ON_RIGHT_BORDER(hittest))
1825 mouseRect.left = MAX( mouseRect.left, sizingRect.left+minTrack.x );
1826 mouseRect.right = MIN( mouseRect.right, sizingRect.left+maxTrack.x );
1828 if (ON_TOP_BORDER(hittest))
1830 mouseRect.top = MAX( mouseRect.top, sizingRect.bottom-maxTrack.y );
1831 mouseRect.bottom = MIN( mouseRect.bottom,sizingRect.bottom-minTrack.y);
1833 else if (ON_BOTTOM_BORDER(hittest))
1835 mouseRect.top = MAX( mouseRect.top, sizingRect.top+minTrack.y );
1836 mouseRect.bottom = MIN( mouseRect.bottom, sizingRect.top+maxTrack.y );
1838 SendMessage16( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
1840 if (GetCapture32() != hwnd) SetCapture32( hwnd );
1842 if (wndPtr->dwStyle & WS_CHILD)
1844 /* Retrieve a default cache DC (without using the window style) */
1845 hdc = GetDCEx32( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
1847 else
1848 { /* Grab the server only when moving top-level windows without desktop */
1849 hdc = GetDC32( 0 );
1850 if (rootWindow == DefaultRootWindow(display)) TSXGrabServer( display );
1853 if( iconic ) /* create a cursor for dragging */
1855 HICON16 hIcon = (wndPtr->class->hIcon) ? wndPtr->class->hIcon
1856 : (HICON16)SendMessage16( hwnd, WM_QUERYDRAGICON, 0, 0L);
1857 if( hIcon ) hDragCursor = CURSORICON_IconToCursor( hIcon, TRUE );
1858 if( !hDragCursor ) iconic = FALSE;
1861 if( !iconic ) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
1863 while(1)
1865 int dx = 0, dy = 0;
1867 MSG_InternalGetMessage( &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE );
1869 /* Exit on button-up, Return, or Esc */
1870 if ((msg.message == WM_LBUTTONUP) ||
1871 ((msg.message == WM_KEYDOWN) &&
1872 ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
1874 if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
1875 continue; /* We are not interested in other messages */
1877 pt = msg.pt;
1878 if (wndPtr->dwStyle & WS_CHILD)
1879 ScreenToClient16( wndPtr->parent->hwndSelf, &pt );
1881 if (msg.message == WM_KEYDOWN) switch(msg.wParam)
1883 case VK_UP: pt.y -= 8; break;
1884 case VK_DOWN: pt.y += 8; break;
1885 case VK_LEFT: pt.x -= 8; break;
1886 case VK_RIGHT: pt.x += 8; break;
1889 pt.x = MAX( pt.x, mouseRect.left );
1890 pt.x = MIN( pt.x, mouseRect.right );
1891 pt.y = MAX( pt.y, mouseRect.top );
1892 pt.y = MIN( pt.y, mouseRect.bottom );
1894 dx = pt.x - capturePoint.x;
1895 dy = pt.y - capturePoint.y;
1897 if (dx || dy)
1899 if( !moved )
1901 moved = TRUE;
1902 if( iconic ) /* ok, no system popup tracking */
1904 hOldCursor = SetCursor32(hDragCursor);
1905 ShowCursor32( TRUE );
1906 WINPOS_ShowIconTitle( wndPtr, FALSE );
1910 if (msg.message == WM_KEYDOWN) SetCursorPos32( pt.x, pt.y );
1911 else
1913 RECT32 newRect = sizingRect;
1915 if (hittest == HTCAPTION) OffsetRect32( &newRect, dx, dy );
1916 if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
1917 else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
1918 if (ON_TOP_BORDER(hittest)) newRect.top += dy;
1919 else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
1920 if( !iconic )
1922 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
1923 NC_DrawMovingFrame( hdc, &newRect, thickframe );
1925 capturePoint = pt;
1926 sizingRect = newRect;
1931 ReleaseCapture();
1932 if( iconic )
1934 if( moved ) /* restore cursors, show icon title later on */
1936 ShowCursor32( FALSE );
1937 SetCursor32( hOldCursor );
1939 DestroyCursor32( hDragCursor );
1941 else
1942 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
1944 if (wndPtr->dwStyle & WS_CHILD)
1945 ReleaseDC32( wndPtr->parent->hwndSelf, hdc );
1946 else
1948 ReleaseDC32( 0, hdc );
1949 if (rootWindow == DefaultRootWindow(display)) TSXUngrabServer( display );
1952 if (HOOK_IsHooked( WH_CBT ))
1954 RECT16* pr = SEGPTR_NEW(RECT16);
1955 if( pr )
1957 CONV_RECT32TO16( &sizingRect, pr );
1958 if( HOOK_CallHooks16( WH_CBT, HCBT_MOVESIZE, hwnd,
1959 (LPARAM)SEGPTR_GET(pr)) )
1960 sizingRect = wndPtr->rectWindow;
1961 else
1962 CONV_RECT16TO32( pr, &sizingRect );
1963 SEGPTR_FREE(pr);
1966 SendMessage16( hwnd, WM_EXITSIZEMOVE, 0, 0 );
1967 SendMessage16( hwnd, WM_SETVISIBLE, !IsIconic16(hwnd), 0L);
1969 if( moved && !((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
1971 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
1972 SetWindowPos32( hwnd, 0, sizingRect.left, sizingRect.top,
1973 sizingRect.right - sizingRect.left,
1974 sizingRect.bottom - sizingRect.top,
1975 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
1978 if( IsWindow32(hwnd) )
1979 if( wndPtr->dwStyle & WS_MINIMIZE )
1981 /* Single click brings up the system menu when iconized */
1983 if( !moved )
1985 if( wndPtr->dwStyle & WS_SYSMENU )
1986 SendMessage16( hwnd, WM_SYSCOMMAND,
1987 SC_MOUSEMENU + HTSYSMENU, *((LPARAM*)&pt));
1989 else WINPOS_ShowIconTitle( wndPtr, TRUE );
1994 /***********************************************************************
1995 * NC_TrackMinMaxBox
1997 * Track a mouse button press on the minimize or maximize box.
1999 static void NC_TrackMinMaxBox( HWND32 hwnd, WORD wParam )
2001 MSG16 msg;
2002 HDC32 hdc = GetWindowDC32( hwnd );
2003 BOOL32 pressed = TRUE;
2004 void (*paintButton)(HWND32, HDC16, BOOL32);
2006 SetCapture32( hwnd );
2007 if (wParam == HTMINBUTTON)
2008 paintButton =
2009 (TWEAK_WineLook == WIN31_LOOK) ? &NC_DrawMinButton : &NC_DrawMinButton95;
2010 else
2011 paintButton =
2012 (TWEAK_WineLook == WIN31_LOOK) ? &NC_DrawMaxButton : &NC_DrawMaxButton95;
2014 (*paintButton)( hwnd, hdc, TRUE );
2018 BOOL32 oldstate = pressed;
2019 MSG_InternalGetMessage( &msg, 0, 0, 0, PM_REMOVE, FALSE );
2021 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
2022 if (pressed != oldstate)
2023 (*paintButton)( hwnd, hdc, pressed );
2024 } while (msg.message != WM_LBUTTONUP);
2026 (*paintButton)( hwnd, hdc, FALSE );
2028 ReleaseCapture();
2029 ReleaseDC32( hwnd, hdc );
2030 if (!pressed) return;
2032 if (wParam == HTMINBUTTON)
2033 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&msg.pt );
2034 else
2035 SendMessage16( hwnd, WM_SYSCOMMAND,
2036 IsZoomed32(hwnd) ? SC_RESTORE:SC_MAXIMIZE, *(LONG*)&msg.pt );
2040 /***********************************************************************
2041 * NC_TrackCloseButton95
2043 * Track a mouse button press on the Win95 close button.
2045 static void
2046 NC_TrackCloseButton95 (HWND32 hwnd, WORD wParam)
2048 MSG16 msg;
2049 HDC32 hdc = GetWindowDC32( hwnd );
2050 BOOL32 pressed = TRUE;
2052 SetCapture32( hwnd );
2054 NC_DrawCloseButton95 (hwnd, hdc, TRUE);
2058 BOOL32 oldstate = pressed;
2059 MSG_InternalGetMessage( &msg, 0, 0, 0, PM_REMOVE, FALSE );
2061 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
2062 if (pressed != oldstate)
2063 NC_DrawCloseButton95 (hwnd, hdc, pressed);
2064 } while (msg.message != WM_LBUTTONUP);
2066 NC_DrawCloseButton95 (hwnd, hdc, FALSE);
2068 ReleaseCapture();
2069 ReleaseDC32( hwnd, hdc );
2070 if (!pressed) return;
2072 SendMessage16( hwnd, WM_SYSCOMMAND, SC_CLOSE, *(LONG*)&msg.pt );
2076 /***********************************************************************
2077 * NC_TrackScrollBar
2079 * Track a mouse button press on the horizontal or vertical scroll-bar.
2081 static void NC_TrackScrollBar( HWND32 hwnd, WPARAM32 wParam, POINT32 pt )
2083 MSG16 *msg;
2084 INT32 scrollbar;
2085 WND *wndPtr = WIN_FindWndPtr( hwnd );
2087 if ((wParam & 0xfff0) == SC_HSCROLL)
2089 if ((wParam & 0x0f) != HTHSCROLL) return;
2090 scrollbar = SB_HORZ;
2092 else /* SC_VSCROLL */
2094 if ((wParam & 0x0f) != HTVSCROLL) return;
2095 scrollbar = SB_VERT;
2098 if (!(msg = SEGPTR_NEW(MSG16))) return;
2099 pt.x -= wndPtr->rectWindow.left;
2100 pt.y -= wndPtr->rectWindow.top;
2101 SetCapture32( hwnd );
2102 SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt );
2106 GetMessage16( SEGPTR_GET(msg), 0, 0, 0 );
2107 switch(msg->message)
2109 case WM_LBUTTONUP:
2110 case WM_MOUSEMOVE:
2111 case WM_SYSTIMER:
2112 pt.x = LOWORD(msg->lParam) + wndPtr->rectClient.left -
2113 wndPtr->rectWindow.left;
2114 pt.y = HIWORD(msg->lParam) + wndPtr->rectClient.top -
2115 wndPtr->rectWindow.top;
2116 SCROLL_HandleScrollEvent( hwnd, scrollbar, msg->message, pt );
2117 break;
2118 default:
2119 TranslateMessage16( msg );
2120 DispatchMessage16( msg );
2121 break;
2123 if (!IsWindow32( hwnd ))
2125 ReleaseCapture();
2126 break;
2128 } while (msg->message != WM_LBUTTONUP);
2129 SEGPTR_FREE(msg);
2132 /***********************************************************************
2133 * NC_HandleNCLButtonDown
2135 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2137 LONG NC_HandleNCLButtonDown( WND* pWnd, WPARAM16 wParam, LPARAM lParam )
2139 HWND32 hwnd = pWnd->hwndSelf;
2141 switch(wParam) /* Hit test */
2143 case HTCAPTION:
2144 hwnd = WIN_GetTopParent(hwnd);
2146 if( WINPOS_SetActiveWindow(hwnd, TRUE, TRUE) || (GetActiveWindow32() == hwnd) )
2147 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
2148 break;
2150 case HTSYSMENU:
2151 if( pWnd->dwStyle & WS_SYSMENU )
2153 if( !(pWnd->dwStyle & WS_MINIMIZE) )
2155 HDC32 hDC = GetWindowDC32(hwnd);
2156 if (TWEAK_WineLook == WIN31_LOOK)
2157 NC_DrawSysButton( hwnd, hDC, TRUE );
2158 else
2159 NC_DrawSysButton95( hwnd, hDC, TRUE );
2160 ReleaseDC32( hwnd, hDC );
2162 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
2164 break;
2166 case HTMENU:
2167 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam );
2168 break;
2170 case HTHSCROLL:
2171 SendMessage16( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
2172 break;
2174 case HTVSCROLL:
2175 SendMessage16( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
2176 break;
2178 case HTMINBUTTON:
2179 case HTMAXBUTTON:
2180 NC_TrackMinMaxBox( hwnd, wParam );
2181 break;
2183 case HTCLOSE:
2184 if (TWEAK_WineLook >= WIN95_LOOK)
2185 NC_TrackCloseButton95 (hwnd, wParam);
2186 break;
2188 case HTLEFT:
2189 case HTRIGHT:
2190 case HTTOP:
2191 case HTTOPLEFT:
2192 case HTTOPRIGHT:
2193 case HTBOTTOM:
2194 case HTBOTTOMLEFT:
2195 case HTBOTTOMRIGHT:
2196 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2197 SendMessage16( hwnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam);
2198 break;
2200 case HTBORDER:
2201 break;
2203 return 0;
2207 /***********************************************************************
2208 * NC_HandleNCLButtonDblClk
2210 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2212 LONG NC_HandleNCLButtonDblClk( WND *pWnd, WPARAM16 wParam, LPARAM lParam )
2215 * if this is an icon, send a restore since we are handling
2216 * a double click
2218 if (pWnd->dwStyle & WS_MINIMIZE)
2220 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_RESTORE, lParam );
2221 return 0;
2224 switch(wParam) /* Hit test */
2226 case HTCAPTION:
2227 /* stop processing if WS_MAXIMIZEBOX is missing */
2228 if (pWnd->dwStyle & WS_MAXIMIZEBOX)
2229 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND,
2230 (pWnd->dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
2231 lParam );
2232 break;
2234 case HTSYSMENU:
2235 if (!(pWnd->class->style & CS_NOCLOSE))
2236 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, lParam );
2237 break;
2239 case HTHSCROLL:
2240 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL,
2241 lParam );
2242 break;
2244 case HTVSCROLL:
2245 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL,
2246 lParam );
2247 break;
2249 return 0;
2253 /***********************************************************************
2254 * NC_HandleSysCommand
2256 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2258 LONG NC_HandleSysCommand( HWND32 hwnd, WPARAM16 wParam, POINT16 pt )
2260 WND *wndPtr = WIN_FindWndPtr( hwnd );
2261 POINT32 pt32;
2262 UINT16 uCommand = wParam & 0xFFF0;
2264 TRACE(nonclient, "Handling WM_SYSCOMMAND %x %d,%d\n",
2265 wParam, pt.x, pt.y );
2267 if (wndPtr->dwStyle & WS_CHILD && uCommand != SC_KEYMENU )
2268 ScreenToClient16( wndPtr->parent->hwndSelf, &pt );
2270 switch (uCommand)
2272 case SC_SIZE:
2273 case SC_MOVE:
2274 NC_DoSizeMove( hwnd, wParam );
2275 break;
2277 case SC_MINIMIZE:
2278 ShowWindow32( hwnd, SW_MINIMIZE );
2279 break;
2281 case SC_MAXIMIZE:
2282 ShowWindow32( hwnd, SW_MAXIMIZE );
2283 break;
2285 case SC_RESTORE:
2286 ShowWindow32( hwnd, SW_RESTORE );
2287 break;
2289 case SC_CLOSE:
2290 return SendMessage16( hwnd, WM_CLOSE, 0, 0 );
2292 case SC_VSCROLL:
2293 case SC_HSCROLL:
2294 CONV_POINT16TO32( &pt, &pt32 );
2295 NC_TrackScrollBar( hwnd, wParam, pt32 );
2296 break;
2298 case SC_MOUSEMENU:
2299 CONV_POINT16TO32( &pt, &pt32 );
2300 MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt32 );
2301 break;
2303 case SC_KEYMENU:
2304 MENU_TrackKbdMenuBar( wndPtr , wParam , pt.x );
2305 break;
2307 case SC_TASKLIST:
2308 WinExec32( "taskman.exe", SW_SHOWNORMAL );
2309 break;
2311 case SC_SCREENSAVE:
2312 if (wParam == SC_ABOUTWINE)
2313 ShellAbout32A(hwnd,"Wine", WINE_RELEASE_INFO, 0);
2314 break;
2316 case SC_HOTKEY:
2317 case SC_ARRANGE:
2318 case SC_NEXTWINDOW:
2319 case SC_PREVWINDOW:
2320 FIXME (nonclient, "unimplemented!\n");
2321 break;
2323 return 0;