The new filedialog stuff does not handle template. So do not call if
[wine/gsoc_dplay.git] / windows / nonclient.c
blobbecbf06fdfc5ff4f46cc048df777fe06da1b968a
1 /*
2 * Non-client area window functions
4 * Copyright 1994 Alexandre Julliard
6 */
8 #include "wine/winuser16.h"
9 #include "version.h"
10 #include "win.h"
11 #include "message.h"
12 #include "user.h"
13 #include "heap.h"
14 #include "dce.h"
15 #include "cursoricon.h"
16 #include "dialog.h"
17 #include "menu.h"
18 #include "winpos.h"
19 #include "hook.h"
20 #include "scroll.h"
21 #include "nonclient.h"
22 #include "queue.h"
23 #include "selectors.h"
24 #include "tweak.h"
25 #include "debugtools.h"
26 #include "options.h"
27 #include "shellapi.h"
28 #include "cache.h"
29 #include "bitmap.h"
31 DEFAULT_DEBUG_CHANNEL(nonclient)
32 DECLARE_DEBUG_CHANNEL(shell)
34 BOOL NC_DrawGrayButton(HDC hdc, int x, int y);
36 static HBITMAP16 hbitmapClose = 0;
37 static HBITMAP16 hbitmapCloseD = 0;
38 static HBITMAP16 hbitmapMinimize = 0;
39 static HBITMAP16 hbitmapMinimizeD = 0;
40 static HBITMAP16 hbitmapMaximize = 0;
41 static HBITMAP16 hbitmapMaximizeD = 0;
42 static HBITMAP16 hbitmapRestore = 0;
43 static HBITMAP16 hbitmapRestoreD = 0;
45 BYTE lpGrayMask[] = { 0xAA, 0xA0,
46 0x55, 0x50,
47 0xAA, 0xA0,
48 0x55, 0x50,
49 0xAA, 0xA0,
50 0x55, 0x50,
51 0xAA, 0xA0,
52 0x55, 0x50,
53 0xAA, 0xA0,
54 0x55, 0x50};
56 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
57 #define SC_PUTMARK (SC_SCREENSAVE+2)
59 /* Some useful macros */
60 #define HAS_DLGFRAME(style,exStyle) \
61 (((exStyle) & WS_EX_DLGMODALFRAME) || \
62 (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
64 #define HAS_THICKFRAME(style,exStyle) \
65 (((style) & WS_THICKFRAME) && \
66 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
68 #define HAS_THINFRAME(style) \
69 (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
71 #define HAS_BIGFRAME(style,exStyle) \
72 (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
73 ((exStyle) & WS_EX_DLGMODALFRAME))
75 #define HAS_ANYFRAME(style,exStyle) \
76 (((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
77 ((exStyle) & WS_EX_DLGMODALFRAME) || \
78 !((style) & (WS_CHILD | WS_POPUP)))
80 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
82 #define ON_LEFT_BORDER(hit) \
83 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
84 #define ON_RIGHT_BORDER(hit) \
85 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
86 #define ON_TOP_BORDER(hit) \
87 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
88 #define ON_BOTTOM_BORDER(hit) \
89 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
91 /***********************************************************************
92 * WIN_WindowNeedsWMBorder
94 * This method defines the rules for a window to have a WM border,
95 * caption... It is used for consitency purposes.
97 BOOL WIN_WindowNeedsWMBorder( DWORD style, DWORD exStyle )
99 if (!(style & WS_CHILD) &&
100 Options.managed &&
101 !(exStyle & WS_EX_TOOLWINDOW) &&
102 ( ((style & WS_CAPTION) == WS_CAPTION) ||
103 (style & WS_THICKFRAME)))
104 return TRUE;
105 if (exStyle & WS_EX_TRAYWINDOW)
106 return TRUE;
107 return FALSE;
110 /***********************************************************************
111 * NC_AdjustRect
113 * Compute the size of the window rectangle from the size of the
114 * client rectangle.
116 static void NC_AdjustRect( LPRECT16 rect, DWORD style, BOOL menu,
117 DWORD exStyle )
119 if (TWEAK_WineLook > WIN31_LOOK)
120 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
122 if(style & WS_ICONIC) return;
123 /* Decide if the window will be managed (see CreateWindowEx) */
124 if (!WIN_WindowNeedsWMBorder(style, exStyle))
126 if (HAS_THICKFRAME( style, exStyle ))
127 InflateRect16( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
128 else
129 if (HAS_DLGFRAME( style, exStyle ))
130 InflateRect16( rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
131 else
132 if (HAS_THINFRAME( style ))
133 InflateRect16( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
135 if ((style & WS_CAPTION) == WS_CAPTION)
136 rect->top -= GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
138 if (menu) rect->top -= GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYBORDER);
140 if (style & WS_VSCROLL) {
141 rect->right += GetSystemMetrics(SM_CXVSCROLL) - 1;
142 if(!HAS_ANYFRAME( style, exStyle ))
143 rect->right++;
146 if (style & WS_HSCROLL) {
147 rect->bottom += GetSystemMetrics(SM_CYHSCROLL) - 1;
148 if(!HAS_ANYFRAME( style, exStyle ))
149 rect->bottom++;
154 /******************************************************************************
155 * NC_AdjustRectOuter95
157 * Computes the size of the "outside" parts of the window based on the
158 * parameters of the client area.
160 + PARAMS
161 * LPRECT16 rect
162 * DWORD style
163 * BOOL32 menu
164 * DWORD exStyle
166 * NOTES
167 * "Outer" parts of a window means the whole window frame, caption and
168 * menu bar. It does not include "inner" parts of the frame like client
169 * edge, static edge or scroll bars.
171 * Revision history
172 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
173 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
175 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
176 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
177 * NC_AdjustRectInner95 and added handling of Win95 styles.
179 * 28-Jul-1999 Ove Kåven (ovek@arcticnet.no)
180 * Streamlined window style checks.
182 *****************************************************************************/
184 static void
185 NC_AdjustRectOuter95 (LPRECT16 rect, DWORD style, BOOL menu, DWORD exStyle)
187 if(style & WS_ICONIC) return;
189 /* Decide if the window will be managed (see CreateWindowEx) */
190 if (!WIN_WindowNeedsWMBorder(style, exStyle))
192 if (HAS_THICKFRAME( style, exStyle ))
193 InflateRect16( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
194 else
195 if (HAS_DLGFRAME( style, exStyle ))
196 InflateRect16(rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
197 else
198 if (HAS_THINFRAME( style ))
199 InflateRect16( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
201 if ((style & WS_CAPTION) == WS_CAPTION)
203 if (exStyle & WS_EX_TOOLWINDOW)
204 rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
205 else
206 rect->top -= GetSystemMetrics(SM_CYCAPTION);
210 if (menu)
211 rect->top -= GetSystemMetrics(SM_CYMENU);
215 /******************************************************************************
216 * NC_AdjustRectInner95
218 * Computes the size of the "inside" part of the window based on the
219 * parameters of the client area.
221 + PARAMS
222 * LPRECT16 rect
223 * DWORD style
224 * DWORD exStyle
226 * NOTES
227 * "Inner" part of a window means the window frame inside of the flat
228 * window frame. It includes the client edge, the static edge and the
229 * scroll bars.
231 * Revision history
232 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
233 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
235 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
236 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
237 * NC_AdjustRectInner95 and added handling of Win95 styles.
239 *****************************************************************************/
241 static void
242 NC_AdjustRectInner95 (LPRECT16 rect, DWORD style, DWORD exStyle)
244 if(style & WS_ICONIC) return;
246 if (exStyle & WS_EX_CLIENTEDGE)
247 InflateRect16 (rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
249 if (exStyle & WS_EX_STATICEDGE)
250 InflateRect16 (rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
252 if (style & WS_VSCROLL) rect->right += GetSystemMetrics(SM_CXVSCROLL);
253 if (style & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
257 /***********************************************************************
258 * DrawCaption16 [USER.660] Draws a caption bar
260 * PARAMS
261 * hwnd [I]
262 * hdc [I]
263 * lpRect [I]
264 * uFlags [I]
266 * RETURNS
267 * Success:
268 * Failure:
271 BOOL16 WINAPI
272 DrawCaption16 (HWND16 hwnd, HDC16 hdc, const RECT16 *rect, UINT16 uFlags)
274 RECT rect32;
276 if (rect)
277 CONV_RECT16TO32 (rect, &rect32);
279 return (BOOL16)DrawCaptionTempA (hwnd, hdc, rect ? &rect32 : NULL,
280 0, 0, NULL, uFlags & 0x1F);
284 /***********************************************************************
285 * DrawCaption32 [USER32.154] Draws a caption bar
287 * PARAMS
288 * hwnd [I]
289 * hdc [I]
290 * lpRect [I]
291 * uFlags [I]
293 * RETURNS
294 * Success:
295 * Failure:
298 BOOL WINAPI
299 DrawCaption (HWND hwnd, HDC hdc, const RECT *lpRect, UINT uFlags)
301 return DrawCaptionTempA (hwnd, hdc, lpRect, 0, 0, NULL, uFlags & 0x1F);
305 /***********************************************************************
306 * DrawCaptionTemp16 [USER.657]
308 * PARAMS
310 * RETURNS
311 * Success:
312 * Failure:
315 BOOL16 WINAPI
316 DrawCaptionTemp16 (HWND16 hwnd, HDC16 hdc, const RECT16 *rect, HFONT16 hFont,
317 HICON16 hIcon, LPCSTR str, UINT16 uFlags)
319 RECT rect32;
321 if (rect)
322 CONV_RECT16TO32(rect,&rect32);
324 return (BOOL16)DrawCaptionTempA (hwnd, hdc, rect?&rect32:NULL, hFont,
325 hIcon, str, uFlags & 0x1F);
329 /***********************************************************************
330 * DrawCaptionTemp32A [USER32.599]
332 * PARAMS
334 * RETURNS
335 * Success:
336 * Failure:
339 BOOL WINAPI
340 DrawCaptionTempA (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
341 HICON hIcon, LPCSTR str, UINT uFlags)
343 RECT rc = *rect;
345 TRACE("(%08x,%08x,%p,%08x,%08x,\"%s\",%08x)\n",
346 hwnd, hdc, rect, hFont, hIcon, str, uFlags);
348 /* drawing background */
349 if (uFlags & DC_INBUTTON) {
350 FillRect (hdc, &rc, GetSysColorBrush (COLOR_3DFACE));
352 if (uFlags & DC_ACTIVE) {
353 HBRUSH hbr = SelectObject (hdc, CACHE_GetPattern55AABrush ());
354 PatBlt (hdc, rc.left, rc.top,
355 rc.right-rc.left, rc.bottom-rc.top, 0xFA0089);
356 SelectObject (hdc, hbr);
359 else {
360 FillRect (hdc, &rc, GetSysColorBrush ((uFlags & DC_ACTIVE) ?
361 COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
365 /* drawing icon */
366 if ((uFlags & DC_ICON) && !(uFlags & DC_SMALLCAP)) {
367 POINT pt;
369 pt.x = rc.left + 2;
370 pt.y = (rc.bottom + rc.top - GetSystemMetrics(SM_CYSMICON)) / 2;
372 if (hIcon) {
373 DrawIconEx (hdc, pt.x, pt.y, hIcon, GetSystemMetrics(SM_CXSMICON),
374 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
376 else {
377 HICON hAppIcon = (HICON) GetClassLongA(hwnd, GCL_HICONSM);
378 if(!hAppIcon) hAppIcon = (HICON) GetClassLongA(hwnd, GCL_HICON);
380 DrawIconEx (hdc, pt.x, pt.y, hAppIcon, GetSystemMetrics(SM_CXSMICON),
381 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
384 rc.left += (rc.bottom - rc.top);
387 /* drawing text */
388 if (uFlags & DC_TEXT) {
389 HFONT hOldFont;
391 if (uFlags & DC_INBUTTON)
392 SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
393 else if (uFlags & DC_ACTIVE)
394 SetTextColor (hdc, GetSysColor (COLOR_CAPTIONTEXT));
395 else
396 SetTextColor (hdc, GetSysColor (COLOR_INACTIVECAPTIONTEXT));
398 SetBkMode (hdc, TRANSPARENT);
400 if (hFont)
401 hOldFont = SelectObject (hdc, hFont);
402 else {
403 NONCLIENTMETRICSA nclm;
404 HFONT hNewFont;
405 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
406 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
407 hNewFont = CreateFontIndirectA ((uFlags & DC_SMALLCAP) ?
408 &nclm.lfSmCaptionFont : &nclm.lfCaptionFont);
409 hOldFont = SelectObject (hdc, hNewFont);
412 if (str)
413 DrawTextA (hdc, str, -1, &rc,
414 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
415 else {
416 CHAR szText[128];
417 INT nLen;
418 nLen = GetWindowTextA (hwnd, szText, 128);
419 DrawTextA (hdc, szText, nLen, &rc,
420 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
423 if (hFont)
424 SelectObject (hdc, hOldFont);
425 else
426 DeleteObject (SelectObject (hdc, hOldFont));
429 /* drawing focus ??? */
430 if (uFlags & 0x2000)
431 FIXME("undocumented flag (0x2000)!\n");
433 return 0;
437 /***********************************************************************
438 * DrawCaptionTemp32W [USER32.602]
440 * PARAMS
442 * RETURNS
443 * Success:
444 * Failure:
447 BOOL WINAPI
448 DrawCaptionTempW (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
449 HICON hIcon, LPCWSTR str, UINT uFlags)
451 LPSTR p = HEAP_strdupWtoA (GetProcessHeap (), 0, str);
452 BOOL res = DrawCaptionTempA (hwnd, hdc, rect, hFont, hIcon, p, uFlags);
453 HeapFree (GetProcessHeap (), 0, p);
454 return res;
458 /***********************************************************************
459 * AdjustWindowRect16 (USER.102)
461 BOOL16 WINAPI AdjustWindowRect16( LPRECT16 rect, DWORD style, BOOL16 menu )
463 return AdjustWindowRectEx16( rect, style, menu, 0 );
467 /***********************************************************************
468 * AdjustWindowRect32 (USER32.2)
470 BOOL WINAPI AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu )
472 return AdjustWindowRectEx( rect, style, menu, 0 );
476 /***********************************************************************
477 * AdjustWindowRectEx16 (USER.454)
479 BOOL16 WINAPI AdjustWindowRectEx16( LPRECT16 rect, DWORD style,
480 BOOL16 menu, DWORD exStyle )
482 /* Correct the window style */
484 if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
485 style |= WS_CAPTION;
486 style &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD);
487 exStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE |
488 WS_EX_STATICEDGE | WS_EX_TOOLWINDOW);
489 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
491 TRACE("(%d,%d)-(%d,%d) %08lx %d %08lx\n",
492 rect->left, rect->top, rect->right, rect->bottom,
493 style, menu, exStyle );
495 if (TWEAK_WineLook == WIN31_LOOK)
496 NC_AdjustRect( rect, style, menu, exStyle );
497 else {
498 NC_AdjustRectOuter95( rect, style, menu, exStyle );
499 NC_AdjustRectInner95( rect, style, exStyle );
502 return TRUE;
506 /***********************************************************************
507 * AdjustWindowRectEx32 (USER32.3)
509 BOOL WINAPI AdjustWindowRectEx( LPRECT rect, DWORD style,
510 BOOL menu, DWORD exStyle )
512 RECT16 rect16;
513 BOOL ret;
515 CONV_RECT32TO16( rect, &rect16 );
516 ret = AdjustWindowRectEx16( &rect16, style, (BOOL16)menu, exStyle );
517 CONV_RECT16TO32( &rect16, rect );
518 return ret;
522 /***********************************************************************
523 * NC_HandleNCCalcSize
525 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
527 LONG NC_HandleNCCalcSize( WND *pWnd, RECT *winRect )
529 RECT16 tmpRect = { 0, 0, 0, 0 };
530 LONG result = 0;
531 UINT style = (UINT) GetClassLongA(pWnd->hwndSelf, GCL_STYLE);
533 if (style & CS_VREDRAW) result |= WVR_VREDRAW;
534 if (style & CS_HREDRAW) result |= WVR_HREDRAW;
536 if( !( pWnd->dwStyle & WS_MINIMIZE ) ) {
537 if (TWEAK_WineLook == WIN31_LOOK)
538 NC_AdjustRect( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
539 else
540 NC_AdjustRectOuter95( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
542 winRect->left -= tmpRect.left;
543 winRect->top -= tmpRect.top;
544 winRect->right -= tmpRect.right;
545 winRect->bottom -= tmpRect.bottom;
547 if (HAS_MENU(pWnd)) {
548 TRACE("Calling GetMenuBarHeight with HWND 0x%x, width %d, "
549 "at (%d, %d).\n", pWnd->hwndSelf,
550 winRect->right - winRect->left,
551 -tmpRect.left, -tmpRect.top );
553 winRect->top +=
554 MENU_GetMenuBarHeight( pWnd->hwndSelf,
555 winRect->right - winRect->left,
556 -tmpRect.left, -tmpRect.top ) + 1;
559 if (TWEAK_WineLook > WIN31_LOOK) {
560 SetRect16 (&tmpRect, 0, 0, 0, 0);
561 NC_AdjustRectInner95 (&tmpRect, pWnd->dwStyle, pWnd->dwExStyle);
562 winRect->left -= tmpRect.left;
563 winRect->top -= tmpRect.top;
564 winRect->right -= tmpRect.right;
565 winRect->bottom -= tmpRect.bottom;
568 return result;
572 /***********************************************************************
573 * NC_GetInsideRect
575 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
576 * but without the borders (if any).
577 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
579 static void NC_GetInsideRect( HWND hwnd, RECT *rect )
581 WND * wndPtr = WIN_FindWndPtr( hwnd );
583 rect->top = rect->left = 0;
584 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
585 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
587 if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) goto END;
589 /* Remove frame from rectangle */
590 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
591 InflateRect( rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
592 else
593 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
595 InflateRect( rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
596 /* FIXME: this isn't in NC_AdjustRect? why not? */
597 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
598 InflateRect( rect, -1, 0 );
600 else
601 if (HAS_THINFRAME( wndPtr->dwStyle ))
602 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
603 END:
604 WIN_ReleaseWndPtr(wndPtr);
605 return;
609 /***********************************************************************
610 * NC_GetInsideRect95
612 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
613 * but without the borders (if any).
614 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
617 static void
618 NC_GetInsideRect95 (HWND hwnd, RECT *rect)
620 WND * wndPtr = WIN_FindWndPtr( hwnd );
622 rect->top = rect->left = 0;
623 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
624 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
626 if ((wndPtr->dwStyle & WS_ICONIC) || (wndPtr->flags & WIN_MANAGED)) goto END;
628 /* Remove frame from rectangle */
629 if (HAS_THICKFRAME (wndPtr->dwStyle, wndPtr->dwExStyle))
631 InflateRect( rect, -GetSystemMetrics(SM_CXSIZEFRAME), -GetSystemMetrics(SM_CYSIZEFRAME) );
633 else if (HAS_DLGFRAME (wndPtr->dwStyle, wndPtr->dwExStyle ))
635 InflateRect( rect, -GetSystemMetrics(SM_CXFIXEDFRAME), -GetSystemMetrics(SM_CYFIXEDFRAME));
637 else if (HAS_THINFRAME (wndPtr->dwStyle))
639 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
642 /* We have additional border information if the window
643 * is a child (but not an MDI child) */
644 if ( (wndPtr->dwStyle & WS_CHILD) &&
645 ( (wndPtr->dwExStyle & WS_EX_MDICHILD) == 0 ) )
647 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
648 InflateRect (rect, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE));
650 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
651 InflateRect (rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
653 END:
654 WIN_ReleaseWndPtr(wndPtr);
655 return;
659 /***********************************************************************
660 * NC_DoNCHitTest
662 * Handle a WM_NCHITTEST message. Called from NC_HandleNcHitTest().
665 static LONG NC_DoNCHitTest (WND *wndPtr, POINT16 pt )
667 RECT16 rect;
669 TRACE("hwnd=%04x pt=%d,%d\n", wndPtr->hwndSelf, pt.x, pt.y );
671 GetWindowRect16 (wndPtr->hwndSelf, &rect );
672 if (!PtInRect16( &rect, pt )) return HTNOWHERE;
674 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
676 if (!(wndPtr->flags & WIN_MANAGED))
678 /* Check borders */
679 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
681 InflateRect16( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
682 if (!PtInRect16( &rect, pt ))
684 /* Check top sizing border */
685 if (pt.y < rect.top)
687 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
688 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
689 return HTTOP;
691 /* Check bottom sizing border */
692 if (pt.y >= rect.bottom)
694 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
695 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
696 return HTBOTTOM;
698 /* Check left sizing border */
699 if (pt.x < rect.left)
701 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
702 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
703 return HTLEFT;
705 /* Check right sizing border */
706 if (pt.x >= rect.right)
708 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
709 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
710 return HTRIGHT;
714 else /* No thick frame */
716 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
717 InflateRect16(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
718 else if (HAS_THINFRAME( wndPtr->dwStyle ))
719 InflateRect16(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
720 if (!PtInRect16( &rect, pt )) return HTBORDER;
723 /* Check caption */
725 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
727 rect.top += GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
728 if (!PtInRect16( &rect, pt ))
730 /* Check system menu */
731 if (wndPtr->dwStyle & WS_SYSMENU)
732 rect.left += GetSystemMetrics(SM_CXSIZE);
733 if (pt.x <= rect.left) return HTSYSMENU;
735 /* Check maximize box */
736 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
737 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
739 if (pt.x >= rect.right) return HTMAXBUTTON;
740 /* Check minimize box */
741 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
742 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
743 if (pt.x >= rect.right) return HTMINBUTTON;
744 return HTCAPTION;
749 /* Check client area */
751 ScreenToClient16( wndPtr->hwndSelf, &pt );
752 GetClientRect16( wndPtr->hwndSelf, &rect );
753 if (PtInRect16( &rect, pt )) return HTCLIENT;
755 /* Check vertical scroll bar */
757 if (wndPtr->dwStyle & WS_VSCROLL)
759 rect.right += GetSystemMetrics(SM_CXVSCROLL);
760 if (PtInRect16( &rect, pt )) return HTVSCROLL;
763 /* Check horizontal scroll bar */
765 if (wndPtr->dwStyle & WS_HSCROLL)
767 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
768 if (PtInRect16( &rect, pt ))
770 /* Check size box */
771 if ((wndPtr->dwStyle & WS_VSCROLL) &&
772 (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
773 return HTSIZE;
774 return HTHSCROLL;
778 /* Check menu bar */
780 if (HAS_MENU(wndPtr))
782 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
783 return HTMENU;
786 /* Should never get here */
787 return HTERROR;
791 /***********************************************************************
792 * NC_DoNCHitTest95
794 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
796 * FIXME: Just a modified copy of the Win 3.1 version.
799 static LONG
800 NC_DoNCHitTest95 (WND *wndPtr, POINT16 pt )
802 RECT16 rect;
804 TRACE("hwnd=%04x pt=%d,%d\n", wndPtr->hwndSelf, pt.x, pt.y );
806 GetWindowRect16 (wndPtr->hwndSelf, &rect );
807 if (!PtInRect16( &rect, pt )) return HTNOWHERE;
809 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
811 if (!(wndPtr->flags & WIN_MANAGED))
813 /* Check borders */
814 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
816 InflateRect16( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
817 if (!PtInRect16( &rect, pt ))
819 /* Check top sizing border */
820 if (pt.y < rect.top)
822 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
823 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
824 return HTTOP;
826 /* Check bottom sizing border */
827 if (pt.y >= rect.bottom)
829 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
830 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
831 return HTBOTTOM;
833 /* Check left sizing border */
834 if (pt.x < rect.left)
836 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
837 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
838 return HTLEFT;
840 /* Check right sizing border */
841 if (pt.x >= rect.right)
843 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
844 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
845 return HTRIGHT;
849 else /* No thick frame */
851 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
852 InflateRect16(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
853 else if (HAS_THINFRAME( wndPtr->dwStyle ))
854 InflateRect16(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
855 if (!PtInRect16( &rect, pt )) return HTBORDER;
858 /* Check caption */
860 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
862 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
863 rect.top += GetSystemMetrics(SM_CYSMCAPTION) - 1;
864 else
865 rect.top += GetSystemMetrics(SM_CYCAPTION) - 1;
866 if (!PtInRect16( &rect, pt ))
868 /* Check system menu */
869 if(wndPtr->dwStyle & WS_SYSMENU)
871 /* Check if there is an user icon */
872 HICON hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICONSM);
873 if(!hIcon) hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICON);
875 /* If there is an icon associated with the window OR */
876 /* If there is no hIcon specified and this is not a modal dialog, */
877 /* there is a system menu icon. */
878 if((hIcon != 0) || (!(wndPtr->dwStyle & DS_MODALFRAME)))
879 rect.left += GetSystemMetrics(SM_CYCAPTION) - 1;
881 if (pt.x < rect.left) return HTSYSMENU;
883 /* Check close button */
884 if (wndPtr->dwStyle & WS_SYSMENU)
885 rect.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
886 if (pt.x > rect.right) return HTCLOSE;
888 /* Check maximize box */
889 /* In win95 there is automatically a Maximize button when there is a minimize one*/
890 if ((wndPtr->dwStyle & WS_MAXIMIZEBOX)|| (wndPtr->dwStyle & WS_MINIMIZEBOX))
891 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
892 if (pt.x > rect.right) return HTMAXBUTTON;
894 /* Check minimize box */
895 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
896 if ((wndPtr->dwStyle & WS_MINIMIZEBOX)||(wndPtr->dwStyle & WS_MAXIMIZEBOX))
897 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
899 if (pt.x > rect.right) return HTMINBUTTON;
900 return HTCAPTION;
905 /* Check client area */
907 ScreenToClient16( wndPtr->hwndSelf, &pt );
908 GetClientRect16( wndPtr->hwndSelf, &rect );
909 if (PtInRect16( &rect, pt )) return HTCLIENT;
911 /* Check vertical scroll bar */
913 if (wndPtr->dwStyle & WS_VSCROLL)
915 rect.right += GetSystemMetrics(SM_CXVSCROLL);
916 if (PtInRect16( &rect, pt )) return HTVSCROLL;
919 /* Check horizontal scroll bar */
921 if (wndPtr->dwStyle & WS_HSCROLL)
923 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
924 if (PtInRect16( &rect, pt ))
926 /* Check size box */
927 if ((wndPtr->dwStyle & WS_VSCROLL) &&
928 (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))
929 return HTSIZE;
930 return HTHSCROLL;
934 /* Check menu bar */
936 if (HAS_MENU(wndPtr))
938 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
939 return HTMENU;
942 /* Should never get here */
943 return HTERROR;
947 /***********************************************************************
948 * NC_HandleNCHitTest
950 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
952 LONG
953 NC_HandleNCHitTest (HWND hwnd , POINT16 pt)
955 LONG retvalue;
956 WND *wndPtr = WIN_FindWndPtr (hwnd);
958 if (!wndPtr)
959 return HTERROR;
961 if (TWEAK_WineLook == WIN31_LOOK)
962 retvalue = NC_DoNCHitTest (wndPtr, pt);
963 else
964 retvalue = NC_DoNCHitTest95 (wndPtr, pt);
965 WIN_ReleaseWndPtr(wndPtr);
966 return retvalue;
970 /***********************************************************************
971 * NC_DrawSysButton
973 void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down )
975 RECT rect;
976 HDC hdcMem;
977 HBITMAP hbitmap;
978 WND *wndPtr = WIN_FindWndPtr( hwnd );
980 if( !(wndPtr->flags & WIN_MANAGED) )
982 NC_GetInsideRect( hwnd, &rect );
983 hdcMem = CreateCompatibleDC( hdc );
984 hbitmap = SelectObject( hdcMem, hbitmapClose );
985 BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE), GetSystemMetrics(SM_CYSIZE),
986 hdcMem, (wndPtr->dwStyle & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE) : 0, 0,
987 down ? NOTSRCCOPY : SRCCOPY );
988 SelectObject( hdcMem, hbitmap );
989 DeleteDC( hdcMem );
991 WIN_ReleaseWndPtr(wndPtr);
995 /***********************************************************************
996 * NC_DrawMaxButton
998 static void NC_DrawMaxButton( HWND hwnd, HDC16 hdc, BOOL down )
1000 RECT rect;
1001 WND *wndPtr = WIN_FindWndPtr( hwnd );
1002 HDC hdcMem;
1004 if( !(wndPtr->flags & WIN_MANAGED) )
1006 NC_GetInsideRect( hwnd, &rect );
1007 hdcMem = CreateCompatibleDC( hdc );
1008 SelectObject( hdcMem, (IsZoomed(hwnd)
1009 ? (down ? hbitmapRestoreD : hbitmapRestore)
1010 : (down ? hbitmapMaximizeD : hbitmapMaximize)) );
1011 BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
1012 GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
1013 SRCCOPY );
1014 DeleteDC( hdcMem );
1016 WIN_ReleaseWndPtr(wndPtr);
1021 /***********************************************************************
1022 * NC_DrawMinButton
1024 static void NC_DrawMinButton( HWND hwnd, HDC16 hdc, BOOL down )
1026 RECT rect;
1027 WND *wndPtr = WIN_FindWndPtr( hwnd );
1028 HDC hdcMem;
1030 if( !(wndPtr->flags & WIN_MANAGED) )
1032 NC_GetInsideRect( hwnd, &rect );
1033 hdcMem = CreateCompatibleDC( hdc );
1034 SelectObject( hdcMem, (down ? hbitmapMinimizeD : hbitmapMinimize) );
1035 if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= GetSystemMetrics(SM_CXSIZE)+1;
1036 BitBlt( hdc, rect.right - GetSystemMetrics(SM_CXSIZE) - 1, rect.top,
1037 GetSystemMetrics(SM_CXSIZE) + 1, GetSystemMetrics(SM_CYSIZE), hdcMem, 0, 0,
1038 SRCCOPY );
1039 DeleteDC( hdcMem );
1041 WIN_ReleaseWndPtr(wndPtr);
1045 /******************************************************************************
1047 * void NC_DrawSysButton95(
1048 * HWND32 hwnd,
1049 * HDC32 hdc,
1050 * BOOL32 down )
1052 * Draws the Win95 system icon.
1054 * Revision history
1055 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1056 * Original implementation from NC_DrawSysButton source.
1057 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1058 * Fixed most bugs.
1060 *****************************************************************************/
1062 BOOL
1063 NC_DrawSysButton95 (HWND hwnd, HDC hdc, BOOL down)
1065 WND *wndPtr = WIN_FindWndPtr( hwnd );
1067 if( !(wndPtr->flags & WIN_MANAGED) )
1069 HICON hIcon;
1070 RECT rect;
1072 NC_GetInsideRect95( hwnd, &rect );
1074 hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICONSM);
1075 if(!hIcon) hIcon = (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICON);
1077 /* If there is no hIcon specified or this is not a modal dialog, */
1078 /* get the default one. */
1079 if(hIcon == 0)
1080 if (!(wndPtr->dwStyle & DS_MODALFRAME))
1081 hIcon = LoadImageA(0, MAKEINTRESOURCEA(OIC_WINEICON), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
1083 if (hIcon)
1084 DrawIconEx (hdc, rect.left + 2, rect.top + 2, hIcon,
1085 GetSystemMetrics(SM_CXSMICON),
1086 GetSystemMetrics(SM_CYSMICON),
1087 0, 0, DI_NORMAL);
1089 WIN_ReleaseWndPtr(wndPtr);
1090 return (hIcon != 0);
1092 WIN_ReleaseWndPtr(wndPtr);
1093 return FALSE;
1097 /******************************************************************************
1099 * void NC_DrawCloseButton95(
1100 * HWND32 hwnd,
1101 * HDC32 hdc,
1102 * BOOL32 down,
1103 * BOOL bGrayed )
1105 * Draws the Win95 close button.
1107 * If bGrayed is true, then draw a disabled Close button
1109 * Revision history
1110 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1111 * Original implementation from NC_DrawSysButton95 source.
1113 *****************************************************************************/
1115 static void NC_DrawCloseButton95 (HWND hwnd, HDC hdc, BOOL down, BOOL bGrayed)
1117 RECT rect;
1118 HDC hdcMem;
1119 WND *wndPtr = WIN_FindWndPtr( hwnd );
1121 if( !(wndPtr->flags & WIN_MANAGED) )
1123 BITMAP bmp;
1124 HBITMAP hBmp, hOldBmp;
1126 NC_GetInsideRect95( hwnd, &rect );
1128 hdcMem = CreateCompatibleDC( hdc );
1129 hBmp = down ? hbitmapCloseD : hbitmapClose;
1130 hOldBmp = SelectObject (hdcMem, hBmp);
1131 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1133 BitBlt (hdc, rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2,
1134 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1135 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY);
1137 if(bGrayed)
1138 NC_DrawGrayButton(hdc,rect.right - (GetSystemMetrics(SM_CYCAPTION) + 1 + bmp.bmWidth) / 2 + 2,
1139 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1141 SelectObject (hdcMem, hOldBmp);
1142 DeleteDC (hdcMem);
1144 WIN_ReleaseWndPtr(wndPtr);
1147 /******************************************************************************
1149 * NC_DrawMaxButton95(
1150 * HWND32 hwnd,
1151 * HDC16 hdc,
1152 * BOOL32 down
1153 * BOOL bGrayed )
1155 * Draws the maximize button for Win95 style windows.
1157 * If bGrayed is true, then draw a disabled Maximize button
1159 * Bugs
1160 * Many. Spacing might still be incorrect. Need to fit a close
1161 * button between the max button and the edge.
1162 * Should scale the image with the title bar. And more...
1164 * Revision history
1165 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1166 * Original implementation.
1168 *****************************************************************************/
1170 static void NC_DrawMaxButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
1172 RECT rect;
1173 HDC hdcMem;
1174 WND *wndPtr = WIN_FindWndPtr( hwnd );
1176 if( !(wndPtr->flags & WIN_MANAGED))
1178 BITMAP bmp;
1179 HBITMAP hBmp,hOldBmp;
1181 NC_GetInsideRect95( hwnd, &rect );
1182 hdcMem = CreateCompatibleDC( hdc );
1183 hBmp = IsZoomed(hwnd) ?
1184 (down ? hbitmapRestoreD : hbitmapRestore ) :
1185 (down ? hbitmapMaximizeD: hbitmapMaximize);
1186 hOldBmp=SelectObject( hdcMem, hBmp );
1187 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1189 if (wndPtr->dwStyle & WS_SYSMENU)
1190 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1192 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1193 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1194 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1196 if(bGrayed)
1197 NC_DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
1198 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1201 SelectObject (hdcMem, hOldBmp);
1202 DeleteDC( hdcMem );
1204 WIN_ReleaseWndPtr(wndPtr);
1207 /******************************************************************************
1209 * NC_DrawMinButton95(
1210 * HWND32 hwnd,
1211 * HDC16 hdc,
1212 * BOOL32 down,
1213 * BOOL bGrayed )
1215 * Draws the minimize button for Win95 style windows.
1217 * If bGrayed is true, then draw a disabled Minimize button
1219 * Bugs
1220 * Many. Spacing is still incorrect. Should scale the image with the
1221 * title bar. And more...
1223 * Revision history
1224 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1225 * Original implementation.
1227 *****************************************************************************/
1229 static void NC_DrawMinButton95(HWND hwnd,HDC16 hdc,BOOL down, BOOL bGrayed)
1231 RECT rect;
1232 HDC hdcMem;
1233 WND *wndPtr = WIN_FindWndPtr( hwnd );
1235 if( !(wndPtr->flags & WIN_MANAGED))
1238 BITMAP bmp;
1239 HBITMAP hBmp,hOldBmp;
1241 NC_GetInsideRect95( hwnd, &rect );
1243 hdcMem = CreateCompatibleDC( hdc );
1244 hBmp = down ? hbitmapMinimizeD : hbitmapMinimize;
1245 hOldBmp= SelectObject( hdcMem, hBmp );
1246 GetObjectA (hBmp, sizeof(BITMAP), &bmp);
1248 if (wndPtr->dwStyle & WS_SYSMENU)
1249 rect.right -= GetSystemMetrics(SM_CYCAPTION) + 1;
1251 /* In win 95 there is always a Maximize box when there is a Minimize one */
1252 if ((wndPtr->dwStyle & WS_MAXIMIZEBOX) || (wndPtr->dwStyle & WS_MINIMIZEBOX))
1253 rect.right += -1 - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2;
1255 BitBlt( hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2,
1256 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2,
1257 bmp.bmWidth, bmp.bmHeight, hdcMem, 0, 0, SRCCOPY );
1259 if(bGrayed)
1260 NC_DrawGrayButton(hdc, rect.right - (GetSystemMetrics(SM_CXSIZE) + bmp.bmWidth) / 2 + 2,
1261 rect.top + (GetSystemMetrics(SM_CYCAPTION) - 1 - bmp.bmHeight) / 2 + 2);
1264 SelectObject (hdcMem, hOldBmp);
1265 DeleteDC( hdcMem );
1267 WIN_ReleaseWndPtr(wndPtr);
1270 /***********************************************************************
1271 * NC_DrawFrame
1273 * Draw a window frame inside the given rectangle, and update the rectangle.
1274 * The correct pen for the frame must be selected in the DC.
1276 static void NC_DrawFrame( HDC hdc, RECT *rect, BOOL dlgFrame,
1277 BOOL active )
1279 INT width, height;
1281 if (TWEAK_WineLook != WIN31_LOOK)
1282 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
1284 if (dlgFrame)
1286 width = GetSystemMetrics(SM_CXDLGFRAME) - 1;
1287 height = GetSystemMetrics(SM_CYDLGFRAME) - 1;
1288 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1289 COLOR_INACTIVECAPTION) );
1291 else
1293 width = GetSystemMetrics(SM_CXFRAME) - 2;
1294 height = GetSystemMetrics(SM_CYFRAME) - 2;
1295 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1296 COLOR_INACTIVEBORDER) );
1299 /* Draw frame */
1300 PatBlt( hdc, rect->left, rect->top,
1301 rect->right - rect->left, height, PATCOPY );
1302 PatBlt( hdc, rect->left, rect->top,
1303 width, rect->bottom - rect->top, PATCOPY );
1304 PatBlt( hdc, rect->left, rect->bottom - 1,
1305 rect->right - rect->left, -height, PATCOPY );
1306 PatBlt( hdc, rect->right - 1, rect->top,
1307 -width, rect->bottom - rect->top, PATCOPY );
1309 if (dlgFrame)
1311 InflateRect( rect, -width, -height );
1313 else
1315 INT decYOff = GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXSIZE) - 1;
1316 INT decXOff = GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYSIZE) - 1;
1318 /* Draw inner rectangle */
1320 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1321 Rectangle( hdc, rect->left + width, rect->top + height,
1322 rect->right - width , rect->bottom - height );
1324 /* Draw the decorations */
1326 MoveToEx( hdc, rect->left, rect->top + decYOff, NULL );
1327 LineTo( hdc, rect->left + width, rect->top + decYOff );
1328 MoveToEx( hdc, rect->right - 1, rect->top + decYOff, NULL );
1329 LineTo( hdc, rect->right - width - 1, rect->top + decYOff );
1330 MoveToEx( hdc, rect->left, rect->bottom - decYOff, NULL );
1331 LineTo( hdc, rect->left + width, rect->bottom - decYOff );
1332 MoveToEx( hdc, rect->right - 1, rect->bottom - decYOff, NULL );
1333 LineTo( hdc, rect->right - width - 1, rect->bottom - decYOff );
1335 MoveToEx( hdc, rect->left + decXOff, rect->top, NULL );
1336 LineTo( hdc, rect->left + decXOff, rect->top + height);
1337 MoveToEx( hdc, rect->left + decXOff, rect->bottom - 1, NULL );
1338 LineTo( hdc, rect->left + decXOff, rect->bottom - height - 1 );
1339 MoveToEx( hdc, rect->right - decXOff, rect->top, NULL );
1340 LineTo( hdc, rect->right - decXOff, rect->top + height );
1341 MoveToEx( hdc, rect->right - decXOff, rect->bottom - 1, NULL );
1342 LineTo( hdc, rect->right - decXOff, rect->bottom - height - 1 );
1344 InflateRect( rect, -width - 1, -height - 1 );
1349 /******************************************************************************
1351 * void NC_DrawFrame95(
1352 * HDC32 hdc,
1353 * RECT32 *rect,
1354 * BOOL32 dlgFrame,
1355 * BOOL32 active )
1357 * Draw a window frame inside the given rectangle, and update the rectangle.
1358 * The correct pen for the frame must be selected in the DC.
1360 * Bugs
1361 * Many. First, just what IS a frame in Win95? Note that the 3D look
1362 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1363 * edge. The inner rectangle just inside the frame is handled by the
1364 * Caption code.
1366 * In short, for most people, this function should be a nop (unless
1367 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1368 * them lately, but just to get this code right). Even so, it doesn't
1369 * appear to be so. It's being worked on...
1371 * Revision history
1372 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1373 * Original implementation (based on NC_DrawFrame)
1374 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1375 * Some minor fixes.
1376 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1377 * Fixed a fix or something.
1379 *****************************************************************************/
1381 static void NC_DrawFrame95(
1382 HDC hdc,
1383 RECT *rect,
1384 BOOL dlgFrame,
1385 BOOL active )
1387 INT width, height;
1389 if (dlgFrame)
1391 width = GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
1392 height = GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
1394 else
1396 width = GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXEDGE);
1397 height = GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYEDGE);
1400 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1401 COLOR_INACTIVEBORDER) );
1403 /* Draw frame */
1404 PatBlt( hdc, rect->left, rect->top,
1405 rect->right - rect->left, height, PATCOPY );
1406 PatBlt( hdc, rect->left, rect->top,
1407 width, rect->bottom - rect->top, PATCOPY );
1408 PatBlt( hdc, rect->left, rect->bottom - 1,
1409 rect->right - rect->left, -height, PATCOPY );
1410 PatBlt( hdc, rect->right - 1, rect->top,
1411 -width, rect->bottom - rect->top, PATCOPY );
1413 InflateRect( rect, -width, -height );
1416 /***********************************************************************
1417 * NC_DrawMovingFrame
1419 * Draw the frame used when moving or resizing window.
1421 * FIXME: This causes problems in Win95 mode. (why?)
1423 static void NC_DrawMovingFrame( HDC hdc, RECT *rect, BOOL thickframe )
1425 if (thickframe)
1427 RECT16 r16;
1428 CONV_RECT32TO16( rect, &r16 );
1429 FastWindowFrame16( hdc, &r16, GetSystemMetrics(SM_CXFRAME),
1430 GetSystemMetrics(SM_CYFRAME), PATINVERT );
1432 else DrawFocusRect( hdc, rect );
1436 /***********************************************************************
1437 * NC_DrawCaption
1439 * Draw the window caption.
1440 * The correct pen for the window frame must be selected in the DC.
1442 static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd,
1443 DWORD style, BOOL active )
1445 RECT r = *rect;
1446 WND * wndPtr = WIN_FindWndPtr( hwnd );
1447 char buffer[256];
1449 if (wndPtr->flags & WIN_MANAGED)
1451 WIN_ReleaseWndPtr(wndPtr);
1452 return;
1455 if (!hbitmapClose)
1457 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1459 WIN_ReleaseWndPtr(wndPtr);
1460 return;
1462 hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED) );
1463 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1464 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1465 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1466 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1467 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1468 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1471 if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
1473 HBRUSH hbrushOld = SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW) );
1474 PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
1475 PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
1476 PatBlt( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
1477 r.left++;
1478 r.right--;
1479 SelectObject( hdc, hbrushOld );
1481 WIN_ReleaseWndPtr(wndPtr);
1482 MoveTo16( hdc, r.left, r.bottom );
1483 LineTo( hdc, r.right, r.bottom );
1485 if (style & WS_SYSMENU)
1487 NC_DrawSysButton( hwnd, hdc, FALSE );
1488 r.left += GetSystemMetrics(SM_CXSIZE) + 1;
1489 MoveTo16( hdc, r.left - 1, r.top );
1490 LineTo( hdc, r.left - 1, r.bottom );
1492 if (style & WS_MAXIMIZEBOX)
1494 NC_DrawMaxButton( hwnd, hdc, FALSE );
1495 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1497 if (style & WS_MINIMIZEBOX)
1499 NC_DrawMinButton( hwnd, hdc, FALSE );
1500 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1503 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1504 COLOR_INACTIVECAPTION) );
1506 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) ))
1508 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1509 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1510 SetBkMode( hdc, TRANSPARENT );
1511 DrawTextA( hdc, buffer, -1, &r,
1512 DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );
1517 /******************************************************************************
1519 * NC_DrawCaption95(
1520 * HDC32 hdc,
1521 * RECT32 *rect,
1522 * HWND32 hwnd,
1523 * DWORD style,
1524 * BOOL32 active )
1526 * Draw the window caption for Win95 style windows.
1527 * The correct pen for the window frame must be selected in the DC.
1529 * Bugs
1530 * Hey, a function that finally works! Well, almost.
1531 * It's being worked on.
1533 * Revision history
1534 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1535 * Original implementation.
1536 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1537 * Some minor fixes.
1539 *****************************************************************************/
1541 static void NC_DrawCaption95(
1542 HDC hdc,
1543 RECT *rect,
1544 HWND hwnd,
1545 DWORD style,
1546 DWORD exStyle,
1547 BOOL active )
1549 RECT r = *rect;
1550 WND *wndPtr = WIN_FindWndPtr( hwnd );
1551 char buffer[256];
1552 HPEN hPrevPen;
1553 HMENU hSysMenu;
1555 if (wndPtr->flags & WIN_MANAGED)
1557 WIN_ReleaseWndPtr(wndPtr);
1558 return;
1560 WIN_ReleaseWndPtr(wndPtr);
1562 hPrevPen = SelectObject( hdc, GetSysColorPen(COLOR_3DFACE) );
1563 MoveToEx( hdc, r.left, r.bottom - 1, NULL );
1564 LineTo( hdc, r.right, r.bottom - 1 );
1565 SelectObject( hdc, hPrevPen );
1566 r.bottom--;
1568 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1569 COLOR_INACTIVECAPTION) );
1571 if (!hbitmapClose) {
1572 if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSE) )))
1573 return;
1574 hbitmapCloseD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_CLOSED));
1575 hbitmapMinimize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCE) );
1576 hbitmapMinimizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_REDUCED) );
1577 hbitmapMaximize = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOM) );
1578 hbitmapMaximizeD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_ZOOMD) );
1579 hbitmapRestore = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORE) );
1580 hbitmapRestoreD = LoadBitmap16( 0, MAKEINTRESOURCE16(OBM_RESTORED) );
1583 if ((style & WS_SYSMENU) && !(exStyle & WS_EX_TOOLWINDOW)) {
1584 if (NC_DrawSysButton95 (hwnd, hdc, FALSE))
1585 r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
1588 if (style & WS_SYSMENU)
1590 UINT state;
1592 /* Go get the sysmenu */
1593 hSysMenu = GetSystemMenu(hwnd, FALSE);
1594 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
1596 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1597 NC_DrawCloseButton95 (hwnd, hdc, FALSE,
1598 ((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
1599 r.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
1601 if ((style & WS_MAXIMIZEBOX) || (style & WS_MINIMIZEBOX))
1603 /* In win95 the two buttons are always there */
1604 /* But if the menu item is not in the menu they're disabled*/
1606 NC_DrawMaxButton95( hwnd, hdc, FALSE, (!(style & WS_MAXIMIZEBOX)));
1607 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1609 NC_DrawMinButton95( hwnd, hdc, FALSE, (!(style & WS_MINIMIZEBOX)));
1610 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1614 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) )) {
1615 NONCLIENTMETRICSA nclm;
1616 HFONT hFont, hOldFont;
1617 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1618 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1619 if (exStyle & WS_EX_TOOLWINDOW)
1620 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
1621 else
1622 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
1623 hOldFont = SelectObject (hdc, hFont);
1624 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1625 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1626 SetBkMode( hdc, TRANSPARENT );
1627 r.left += 2;
1628 DrawTextA( hdc, buffer, -1, &r,
1629 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
1630 DeleteObject (SelectObject (hdc, hOldFont));
1636 /***********************************************************************
1637 * NC_DoNCPaint
1639 * Paint the non-client area. clip is currently unused.
1641 static void NC_DoNCPaint( WND* wndPtr, HRGN clip, BOOL suppress_menupaint )
1643 HDC hdc;
1644 RECT rect;
1645 BOOL active;
1646 HWND hwnd = wndPtr->hwndSelf;
1648 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1649 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1651 active = wndPtr->flags & WIN_NCACTIVATED;
1653 TRACE("%04x %d\n", hwnd, active );
1655 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1656 ((clip > 1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN): 0) ))) return;
1658 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1659 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1660 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1661 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1662 == NULLREGION)
1664 ReleaseDC( hwnd, hdc );
1665 return;
1668 rect.top = rect.left = 0;
1669 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1670 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1672 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1674 if (!(wndPtr->flags & WIN_MANAGED))
1676 if (HAS_ANYFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1678 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1679 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1680 InflateRect( &rect, -1, -1 );
1683 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1684 NC_DrawFrame(hdc, &rect, FALSE, active );
1685 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1686 NC_DrawFrame( hdc, &rect, TRUE, active );
1688 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1690 RECT r = rect;
1691 r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
1692 rect.top += GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYBORDER);
1693 NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active );
1697 if (HAS_MENU(wndPtr))
1699 RECT r = rect;
1700 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU); /* default height */
1701 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint );
1704 /* Draw the scroll-bars */
1706 if (wndPtr->dwStyle & WS_VSCROLL)
1707 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1708 if (wndPtr->dwStyle & WS_HSCROLL)
1709 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1711 /* Draw the "size-box" */
1713 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1715 RECT r = rect;
1716 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1717 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1718 if(wndPtr->dwStyle & WS_BORDER) {
1719 r.left++;
1720 r.top++;
1722 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1725 ReleaseDC( hwnd, hdc );
1729 /******************************************************************************
1731 * void NC_DoNCPaint95(
1732 * WND *wndPtr,
1733 * HRGN32 clip,
1734 * BOOL32 suppress_menupaint )
1736 * Paint the non-client area for Win95 windows. The clip region is
1737 * currently ignored.
1739 * Bugs
1740 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1741 * misc/tweak.c controls/menu.c # :-)
1743 * Revision history
1744 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1745 * Original implementation
1746 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1747 * Fixed some bugs.
1748 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1749 * Streamlined window style checks.
1751 *****************************************************************************/
1753 static void NC_DoNCPaint95(
1754 WND *wndPtr,
1755 HRGN clip,
1756 BOOL suppress_menupaint )
1758 HDC hdc;
1759 RECT rfuzz, rect, rectClip;
1760 BOOL active;
1761 HWND hwnd = wndPtr->hwndSelf;
1763 if ( wndPtr->dwStyle & WS_MINIMIZE ||
1764 !WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
1766 active = wndPtr->flags & WIN_NCACTIVATED;
1768 TRACE("%04x %d\n", hwnd, active );
1770 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1771 the call to GetDCEx implying that it is allowed not to use it either.
1772 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1773 will cause clipRgn to be deleted after ReleaseDC().
1774 Now, how is the "system" supposed to tell what happened?
1777 if (!(hdc = GetDCEx( hwnd, (clip > 1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1778 ((clip > 1) ?(DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0) ))) return;
1781 if (ExcludeVisRect16( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
1782 wndPtr->rectClient.top-wndPtr->rectWindow.top,
1783 wndPtr->rectClient.right-wndPtr->rectWindow.left,
1784 wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
1785 == NULLREGION)
1787 ReleaseDC( hwnd, hdc );
1788 return;
1791 rect.top = rect.left = 0;
1792 rect.right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
1793 rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
1795 if( clip > 1 )
1796 GetRgnBox( clip, &rectClip );
1797 else
1799 clip = 0;
1800 rectClip = rect;
1803 SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
1805 if(!(wndPtr->flags & WIN_MANAGED)) {
1806 if (HAS_BIGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle)) {
1807 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1809 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1810 NC_DrawFrame95(hdc, &rect, FALSE, active );
1811 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
1812 NC_DrawFrame95( hdc, &rect, TRUE, active );
1813 else if (HAS_THINFRAME( wndPtr->dwStyle )) {
1814 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1815 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1818 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
1820 RECT r = rect;
1821 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW) {
1822 r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
1823 rect.top += GetSystemMetrics(SM_CYSMCAPTION);
1825 else {
1826 r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
1827 rect.top += GetSystemMetrics(SM_CYCAPTION);
1829 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
1830 NC_DrawCaption95 (hdc, &r, hwnd, wndPtr->dwStyle,
1831 wndPtr->dwExStyle, active);
1835 if (HAS_MENU(wndPtr))
1837 RECT r = rect;
1838 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
1840 TRACE("Calling DrawMenuBar with rect (%d, %d)-(%d, %d)\n",
1841 r.left, r.top, r.right, r.bottom);
1843 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ) + 1;
1846 TRACE("After MenuBar, rect is (%d, %d)-(%d, %d).\n",
1847 rect.left, rect.top, rect.right, rect.bottom );
1849 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
1850 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1852 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
1853 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1855 /* Draw the scroll-bars */
1857 if (wndPtr->dwStyle & WS_VSCROLL)
1858 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1859 if (wndPtr->dwStyle & WS_HSCROLL)
1860 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1862 /* Draw the "size-box" */
1863 if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->dwStyle & WS_HSCROLL))
1865 RECT r = rect;
1866 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1867 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1868 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1871 ReleaseDC( hwnd, hdc );
1877 /***********************************************************************
1878 * NC_HandleNCPaint
1880 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1882 LONG NC_HandleNCPaint( HWND hwnd , HRGN clip)
1884 WND* wndPtr = WIN_FindWndPtr( hwnd );
1886 if( wndPtr && wndPtr->dwStyle & WS_VISIBLE )
1888 if( wndPtr->dwStyle & WS_MINIMIZE )
1889 WINPOS_RedrawIconTitle( hwnd );
1890 else if (TWEAK_WineLook == WIN31_LOOK)
1891 NC_DoNCPaint( wndPtr, clip, FALSE );
1892 else
1893 NC_DoNCPaint95( wndPtr, clip, FALSE );
1895 WIN_ReleaseWndPtr(wndPtr);
1896 return 0;
1900 /***********************************************************************
1901 * NC_HandleNCActivate
1903 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1905 LONG NC_HandleNCActivate( WND *wndPtr, WPARAM16 wParam )
1907 WORD wStateChange;
1909 if( wParam ) wStateChange = !(wndPtr->flags & WIN_NCACTIVATED);
1910 else wStateChange = wndPtr->flags & WIN_NCACTIVATED;
1912 if( wStateChange )
1914 if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
1915 else wndPtr->flags &= ~WIN_NCACTIVATED;
1917 if( wndPtr->dwStyle & WS_MINIMIZE )
1918 WINPOS_RedrawIconTitle( wndPtr->hwndSelf );
1919 else if (TWEAK_WineLook == WIN31_LOOK)
1920 NC_DoNCPaint( wndPtr, (HRGN)1, FALSE );
1921 else
1922 NC_DoNCPaint95( wndPtr, (HRGN)1, FALSE );
1924 return TRUE;
1928 /***********************************************************************
1929 * NC_HandleSetCursor
1931 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1933 LONG NC_HandleSetCursor( HWND hwnd, WPARAM16 wParam, LPARAM lParam )
1935 if (hwnd != (HWND)wParam) return 0; /* Don't set the cursor for child windows */
1937 switch(LOWORD(lParam))
1939 case HTERROR:
1941 WORD msg = HIWORD( lParam );
1942 if ((msg == WM_LBUTTONDOWN) || (msg == WM_MBUTTONDOWN) ||
1943 (msg == WM_RBUTTONDOWN))
1944 MessageBeep(0);
1946 break;
1948 case HTCLIENT:
1950 HICON16 hCursor = (HICON16) GetClassWord(hwnd, GCW_HCURSOR);
1951 if(hCursor) {
1952 SetCursor16(hCursor);
1953 return TRUE;
1955 return FALSE;
1958 case HTLEFT:
1959 case HTRIGHT:
1960 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZEWE16 ) );
1962 case HTTOP:
1963 case HTBOTTOM:
1964 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENS16 ) );
1966 case HTTOPLEFT:
1967 case HTBOTTOMRIGHT:
1968 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENWSE16 ) );
1970 case HTTOPRIGHT:
1971 case HTBOTTOMLEFT:
1972 return (LONG)SetCursor16( LoadCursor16( 0, IDC_SIZENESW16 ) );
1975 /* Default cursor: arrow */
1976 return (LONG)SetCursor16( LoadCursor16( 0, IDC_ARROW16 ) );
1979 /***********************************************************************
1980 * NC_GetSysPopupPos
1982 BOOL NC_GetSysPopupPos( WND* wndPtr, RECT* rect )
1984 if( wndPtr->hSysMenu )
1986 if( wndPtr->dwStyle & WS_MINIMIZE )
1987 GetWindowRect( wndPtr->hwndSelf, rect );
1988 else
1990 if (TWEAK_WineLook == WIN31_LOOK)
1991 NC_GetInsideRect( wndPtr->hwndSelf, rect );
1992 else
1993 NC_GetInsideRect95( wndPtr->hwndSelf, rect );
1994 OffsetRect( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
1995 if (wndPtr->dwStyle & WS_CHILD)
1996 ClientToScreen( wndPtr->parent->hwndSelf, (POINT *)rect );
1997 if (TWEAK_WineLook == WIN31_LOOK) {
1998 rect->right = rect->left + GetSystemMetrics(SM_CXSIZE);
1999 rect->bottom = rect->top + GetSystemMetrics(SM_CYSIZE);
2001 else {
2002 rect->right = rect->left + GetSystemMetrics(SM_CYCAPTION) - 1;
2003 rect->bottom = rect->top + GetSystemMetrics(SM_CYCAPTION) - 1;
2006 return TRUE;
2008 return FALSE;
2011 /***********************************************************************
2012 * NC_StartSizeMove
2014 * Initialisation of a move or resize, when initiatied from a menu choice.
2015 * Return hit test code for caption or sizing border.
2017 static LONG NC_StartSizeMove( WND* wndPtr, WPARAM16 wParam,
2018 POINT16 *capturePoint )
2020 LONG hittest = 0;
2021 POINT16 pt;
2022 MSG msg;
2023 RECT rectWindow;
2025 GetWindowRect(wndPtr->hwndSelf,&rectWindow);
2027 if ((wParam & 0xfff0) == SC_MOVE)
2029 /* Move pointer at the center of the caption */
2030 RECT rect;
2031 if (TWEAK_WineLook == WIN31_LOOK)
2032 NC_GetInsideRect( wndPtr->hwndSelf, &rect );
2033 else
2034 NC_GetInsideRect95( wndPtr->hwndSelf, &rect );
2035 if (wndPtr->dwStyle & WS_SYSMENU)
2036 rect.left += GetSystemMetrics(SM_CXSIZE) + 1;
2037 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
2038 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
2039 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
2040 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
2041 pt.x = rectWindow.left + (rect.right - rect.left) / 2;
2042 pt.y = rectWindow.top + rect.top + GetSystemMetrics(SM_CYSIZE)/2;
2043 hittest = HTCAPTION;
2044 *capturePoint = pt;
2046 else /* SC_SIZE */
2048 while(!hittest)
2050 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE, NULL );
2051 switch(msg.message)
2053 case WM_MOUSEMOVE:
2054 CONV_POINT32TO16(&msg.pt, &pt);
2055 hittest = NC_HandleNCHitTest( wndPtr->hwndSelf, pt );
2056 if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
2057 hittest = 0;
2058 break;
2060 case WM_LBUTTONUP:
2061 return 0;
2063 case WM_KEYDOWN:
2064 switch(msg.wParam)
2066 case VK_UP:
2067 hittest = HTTOP;
2068 pt.x =(rectWindow.left+rectWindow.right)/2;
2069 pt.y = rectWindow.top + GetSystemMetrics(SM_CYFRAME) / 2;
2070 break;
2071 case VK_DOWN:
2072 hittest = HTBOTTOM;
2073 pt.x =(rectWindow.left+rectWindow.right)/2;
2074 pt.y = rectWindow.bottom - GetSystemMetrics(SM_CYFRAME) / 2;
2075 break;
2076 case VK_LEFT:
2077 hittest = HTLEFT;
2078 pt.x = rectWindow.left + GetSystemMetrics(SM_CXFRAME) / 2;
2079 pt.y =(rectWindow.top+rectWindow.bottom)/2;
2080 break;
2081 case VK_RIGHT:
2082 hittest = HTRIGHT;
2083 pt.x = rectWindow.right - GetSystemMetrics(SM_CXFRAME) / 2;
2084 pt.y =(rectWindow.top+rectWindow.bottom)/2;
2085 break;
2086 case VK_RETURN:
2087 case VK_ESCAPE: return 0;
2091 *capturePoint = pt;
2093 SetCursorPos( pt.x, pt.y );
2094 NC_HandleSetCursor( wndPtr->hwndSelf,
2095 wndPtr->hwndSelf, MAKELONG( hittest, WM_MOUSEMOVE ));
2096 return hittest;
2100 /***********************************************************************
2101 * NC_DoSizeMove
2103 * Perform SC_MOVE and SC_SIZE commands. `
2105 static void NC_DoSizeMove( HWND hwnd, WORD wParam )
2107 MSG msg;
2108 RECT sizingRect, mouseRect;
2109 HDC hdc;
2110 LONG hittest = (LONG)(wParam & 0x0f);
2111 HCURSOR16 hDragCursor = 0, hOldCursor = 0;
2112 POINT minTrack, maxTrack;
2113 POINT16 capturePoint, pt;
2114 WND * wndPtr = WIN_FindWndPtr( hwnd );
2115 BOOL thickframe = HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle );
2116 BOOL iconic = wndPtr->dwStyle & WS_MINIMIZE;
2117 BOOL moved = FALSE;
2118 DWORD dwPoint = GetMessagePos ();
2120 capturePoint = pt = *(POINT16*)&dwPoint;
2122 if (IsZoomed(hwnd) || !IsWindowVisible(hwnd) ||
2123 (wndPtr->flags & WIN_MANAGED)) goto END;
2125 if ((wParam & 0xfff0) == SC_MOVE)
2127 if (!(wndPtr->dwStyle & WS_CAPTION)) goto END;
2128 if (!hittest)
2129 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2130 if (!hittest) goto END;
2132 else /* SC_SIZE */
2134 if (!thickframe) goto END;
2135 if ( hittest && hittest != HTSYSMENU ) hittest += 2;
2136 else
2138 SetCapture(hwnd);
2139 hittest = NC_StartSizeMove( wndPtr, wParam, &capturePoint );
2140 if (!hittest)
2142 ReleaseCapture();
2143 goto END;
2148 /* Get min/max info */
2150 WINPOS_GetMinMaxInfo( wndPtr, NULL, NULL, &minTrack, &maxTrack );
2151 sizingRect = wndPtr->rectWindow;
2152 if (wndPtr->dwStyle & WS_CHILD)
2153 GetClientRect( wndPtr->parent->hwndSelf, &mouseRect );
2154 else
2155 SetRect(&mouseRect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
2156 if (ON_LEFT_BORDER(hittest))
2158 mouseRect.left = MAX( mouseRect.left, sizingRect.right-maxTrack.x );
2159 mouseRect.right = MIN( mouseRect.right, sizingRect.right-minTrack.x );
2161 else if (ON_RIGHT_BORDER(hittest))
2163 mouseRect.left = MAX( mouseRect.left, sizingRect.left+minTrack.x );
2164 mouseRect.right = MIN( mouseRect.right, sizingRect.left+maxTrack.x );
2166 if (ON_TOP_BORDER(hittest))
2168 mouseRect.top = MAX( mouseRect.top, sizingRect.bottom-maxTrack.y );
2169 mouseRect.bottom = MIN( mouseRect.bottom,sizingRect.bottom-minTrack.y);
2171 else if (ON_BOTTOM_BORDER(hittest))
2173 mouseRect.top = MAX( mouseRect.top, sizingRect.top+minTrack.y );
2174 mouseRect.bottom = MIN( mouseRect.bottom, sizingRect.top+maxTrack.y );
2176 if (wndPtr->dwStyle & WS_CHILD)
2178 MapWindowPoints( wndPtr->parent->hwndSelf, 0,
2179 (LPPOINT)&mouseRect, 2 );
2181 SendMessage16( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
2183 if (GetCapture() != hwnd) SetCapture( hwnd );
2185 if (wndPtr->dwStyle & WS_CHILD)
2187 /* Retrieve a default cache DC (without using the window style) */
2188 hdc = GetDCEx( wndPtr->parent->hwndSelf, 0, DCX_CACHE );
2190 else
2191 { /* Grab the server only when moving top-level windows without desktop */
2192 hdc = GetDC( 0 );
2195 wndPtr->pDriver->pPreSizeMove(wndPtr);
2197 if( iconic ) /* create a cursor for dragging */
2199 HICON16 hIcon = GetClassWord(wndPtr->hwndSelf, GCW_HICON);
2200 if(!hIcon) hIcon = (HICON16) SendMessage16( hwnd, WM_QUERYDRAGICON, 0, 0L);
2201 if( hIcon ) hDragCursor = CURSORICON_IconToCursor( hIcon, TRUE );
2202 if( !hDragCursor ) iconic = FALSE;
2205 if( !iconic ) NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2207 while(1)
2209 int dx = 0, dy = 0;
2211 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE, NULL );
2213 /* Exit on button-up, Return, or Esc */
2214 if ((msg.message == WM_LBUTTONUP) ||
2215 ((msg.message == WM_KEYDOWN) &&
2216 ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
2218 if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
2219 continue; /* We are not interested in other messages */
2221 dwPoint = GetMessagePos ();
2222 pt = *(POINT16*)&dwPoint;
2224 if (msg.message == WM_KEYDOWN) switch(msg.wParam)
2226 case VK_UP: pt.y -= 8; break;
2227 case VK_DOWN: pt.y += 8; break;
2228 case VK_LEFT: pt.x -= 8; break;
2229 case VK_RIGHT: pt.x += 8; break;
2232 pt.x = MAX( pt.x, mouseRect.left );
2233 pt.x = MIN( pt.x, mouseRect.right );
2234 pt.y = MAX( pt.y, mouseRect.top );
2235 pt.y = MIN( pt.y, mouseRect.bottom );
2237 dx = pt.x - capturePoint.x;
2238 dy = pt.y - capturePoint.y;
2240 if (dx || dy)
2242 if( !moved )
2244 moved = TRUE;
2245 if( iconic ) /* ok, no system popup tracking */
2247 hOldCursor = SetCursor(hDragCursor);
2248 ShowCursor( TRUE );
2249 WINPOS_ShowIconTitle( wndPtr, FALSE );
2253 if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
2254 else
2256 RECT newRect = sizingRect;
2258 if (hittest == HTCAPTION) OffsetRect( &newRect, dx, dy );
2259 if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
2260 else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
2261 if (ON_TOP_BORDER(hittest)) newRect.top += dy;
2262 else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
2263 if( !iconic )
2265 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2266 NC_DrawMovingFrame( hdc, &newRect, thickframe );
2268 capturePoint = pt;
2269 sizingRect = newRect;
2274 ReleaseCapture();
2275 if( iconic )
2277 if( moved ) /* restore cursors, show icon title later on */
2279 ShowCursor( FALSE );
2280 SetCursor( hOldCursor );
2282 DestroyCursor( hDragCursor );
2284 else
2285 NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
2287 if (wndPtr->dwStyle & WS_CHILD)
2288 ReleaseDC( wndPtr->parent->hwndSelf, hdc );
2289 else
2291 ReleaseDC( 0, hdc );
2294 wndPtr->pDriver->pPostSizeMove(wndPtr);
2296 if (HOOK_IsHooked( WH_CBT ))
2298 RECT16* pr = SEGPTR_NEW(RECT16);
2299 if( pr )
2301 CONV_RECT32TO16( &sizingRect, pr );
2302 if( HOOK_CallHooks16( WH_CBT, HCBT_MOVESIZE, hwnd,
2303 (LPARAM)SEGPTR_GET(pr)) )
2304 sizingRect = wndPtr->rectWindow;
2305 else
2306 CONV_RECT16TO32( pr, &sizingRect );
2307 SEGPTR_FREE(pr);
2310 SendMessage16( hwnd, WM_EXITSIZEMOVE, 0, 0 );
2311 SendMessage16( hwnd, WM_SETVISIBLE, !IsIconic16(hwnd), 0L);
2313 /* window moved or resized */
2314 if (moved)
2316 /* if the moving/resizing isn't canceled call SetWindowPos
2317 * with the new position or the new size of the window
2319 if (!((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
2321 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
2322 SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top,
2323 sizingRect.right - sizingRect.left,
2324 sizingRect.bottom - sizingRect.top,
2325 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
2329 if( IsWindow(hwnd) )
2330 if( wndPtr->dwStyle & WS_MINIMIZE )
2332 /* Single click brings up the system menu when iconized */
2334 if( !moved )
2336 if( wndPtr->dwStyle & WS_SYSMENU )
2337 SendMessage16( hwnd, WM_SYSCOMMAND,
2338 SC_MOUSEMENU + HTSYSMENU, *((LPARAM*)&pt));
2340 else WINPOS_ShowIconTitle( wndPtr, TRUE );
2343 END:
2344 WIN_ReleaseWndPtr(wndPtr);
2348 /***********************************************************************
2349 * NC_TrackMinMaxBox95
2351 * Track a mouse button press on the minimize or maximize box.
2353 * The big difference between 3.1 and 95 is the disabled button state.
2354 * In win95 the system button can be disabled, so it can ignore the mouse
2355 * event.
2358 static void NC_TrackMinMaxBox95( HWND hwnd, WORD wParam )
2360 MSG msg;
2361 POINT16 pt16;
2362 HDC hdc = GetWindowDC( hwnd );
2363 BOOL pressed = TRUE;
2364 UINT state;
2365 DWORD wndStyle = GetWindowLongA( hwnd, GWL_STYLE);
2366 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
2368 void (*paintButton)(HWND, HDC16, BOOL, BOOL);
2370 if (wParam == HTMINBUTTON)
2372 /* If the style is not present, do nothing */
2373 if (!(wndStyle & WS_MINIMIZEBOX))
2374 return;
2376 /* Check if the sysmenu item for minimize is there */
2377 state = GetMenuState(hSysMenu, SC_MINIMIZE, MF_BYCOMMAND);
2379 paintButton = &NC_DrawMinButton95;
2381 else
2383 /* If the style is not present, do nothing */
2384 if (!(wndStyle & WS_MAXIMIZEBOX))
2385 return;
2387 /* Check if the sysmenu item for maximize is there */
2388 state = GetMenuState(hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
2390 paintButton = &NC_DrawMaxButton95;
2393 SetCapture( hwnd );
2395 (*paintButton)( hwnd, hdc, TRUE, FALSE);
2399 BOOL oldstate = pressed;
2400 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2401 CONV_POINT32TO16( &msg.pt, &pt16 );
2403 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2404 if (pressed != oldstate)
2405 (*paintButton)( hwnd, hdc, pressed, FALSE);
2406 } while (msg.message != WM_LBUTTONUP);
2408 (*paintButton)( hwnd, hdc, FALSE, FALSE);
2410 ReleaseCapture();
2411 ReleaseDC( hwnd, hdc );
2413 /* If the item minimize or maximize of the sysmenu are not there */
2414 /* or if the style is not present, do nothing */
2415 if ((!pressed) || (state == 0xFFFFFFFF))
2416 return;
2418 if (wParam == HTMINBUTTON)
2419 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&pt16 );
2420 else
2421 SendMessage16( hwnd, WM_SYSCOMMAND,
2422 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, *(LONG*)&pt16 );
2425 /***********************************************************************
2426 * NC_TrackMinMaxBox
2428 * Track a mouse button press on the minimize or maximize box.
2430 static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
2432 MSG msg;
2433 POINT16 pt16;
2434 HDC hdc = GetWindowDC( hwnd );
2435 BOOL pressed = TRUE;
2436 void (*paintButton)(HWND, HDC16, BOOL);
2438 SetCapture( hwnd );
2440 if (wParam == HTMINBUTTON)
2441 paintButton = &NC_DrawMinButton;
2442 else
2443 paintButton = &NC_DrawMaxButton;
2445 (*paintButton)( hwnd, hdc, TRUE);
2449 BOOL oldstate = pressed;
2450 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2451 CONV_POINT32TO16( &msg.pt, &pt16 );
2453 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2454 if (pressed != oldstate)
2455 (*paintButton)( hwnd, hdc, pressed);
2456 } while (msg.message != WM_LBUTTONUP);
2458 (*paintButton)( hwnd, hdc, FALSE);
2460 ReleaseCapture();
2461 ReleaseDC( hwnd, hdc );
2463 if (!pressed) return;
2465 if (wParam == HTMINBUTTON)
2466 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&pt16 );
2467 else
2468 SendMessage16( hwnd, WM_SYSCOMMAND,
2469 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, *(LONG*)&pt16 );
2473 /***********************************************************************
2474 * NC_TrackCloseButton95
2476 * Track a mouse button press on the Win95 close button.
2478 static void
2479 NC_TrackCloseButton95 (HWND hwnd, WORD wParam)
2481 MSG msg;
2482 POINT16 pt16;
2483 HDC hdc;
2484 BOOL pressed = TRUE;
2485 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
2486 UINT state;
2488 if(hSysMenu == 0)
2489 return;
2491 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
2493 /* If the item close of the sysmenu is disabled or not there do nothing */
2494 if((state & MF_DISABLED) || (state & MF_GRAYED) || (state == 0xFFFFFFFF))
2495 return;
2497 hdc = GetWindowDC( hwnd );
2499 SetCapture( hwnd );
2501 NC_DrawCloseButton95 (hwnd, hdc, TRUE, FALSE);
2505 BOOL oldstate = pressed;
2506 MSG_InternalGetMessage( QMSG_WIN32A, &msg, 0, 0, 0, PM_REMOVE, FALSE, NULL );
2507 CONV_POINT32TO16( &msg.pt, &pt16 );
2509 pressed = (NC_HandleNCHitTest( hwnd, pt16 ) == wParam);
2510 if (pressed != oldstate)
2511 NC_DrawCloseButton95 (hwnd, hdc, pressed, FALSE);
2512 } while (msg.message != WM_LBUTTONUP);
2514 NC_DrawCloseButton95 (hwnd, hdc, FALSE, FALSE);
2516 ReleaseCapture();
2517 ReleaseDC( hwnd, hdc );
2518 if (!pressed) return;
2520 SendMessage16( hwnd, WM_SYSCOMMAND, SC_CLOSE, *(LONG*)&pt16 );
2524 /***********************************************************************
2525 * NC_TrackScrollBar
2527 * Track a mouse button press on the horizontal or vertical scroll-bar.
2529 static void NC_TrackScrollBar( HWND hwnd, WPARAM wParam, POINT pt )
2531 MSG16 *msg;
2532 INT scrollbar;
2533 WND *wndPtr = WIN_FindWndPtr( hwnd );
2535 if ((wParam & 0xfff0) == SC_HSCROLL)
2537 if ((wParam & 0x0f) != HTHSCROLL) goto END;
2538 scrollbar = SB_HORZ;
2540 else /* SC_VSCROLL */
2542 if ((wParam & 0x0f) != HTVSCROLL) goto END;
2543 scrollbar = SB_VERT;
2546 if (!(msg = SEGPTR_NEW(MSG16))) goto END;
2547 pt.x -= wndPtr->rectWindow.left;
2548 pt.y -= wndPtr->rectWindow.top;
2549 SetCapture( hwnd );
2550 SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt );
2554 GetMessage16( SEGPTR_GET(msg), 0, 0, 0 );
2555 switch(msg->message)
2557 case WM_LBUTTONUP:
2558 case WM_MOUSEMOVE:
2559 case WM_SYSTIMER:
2560 pt.x = LOWORD(msg->lParam) + wndPtr->rectClient.left -
2561 wndPtr->rectWindow.left;
2562 pt.y = HIWORD(msg->lParam) + wndPtr->rectClient.top -
2563 wndPtr->rectWindow.top;
2564 SCROLL_HandleScrollEvent( hwnd, scrollbar, msg->message, pt );
2565 break;
2566 default:
2567 TranslateMessage16( msg );
2568 DispatchMessage16( msg );
2569 break;
2571 if (!IsWindow( hwnd ))
2573 ReleaseCapture();
2574 break;
2576 } while (msg->message != WM_LBUTTONUP);
2577 SEGPTR_FREE(msg);
2578 END:
2579 WIN_ReleaseWndPtr(wndPtr);
2582 /***********************************************************************
2583 * NC_HandleNCLButtonDown
2585 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2587 LONG NC_HandleNCLButtonDown( WND* pWnd, WPARAM16 wParam, LPARAM lParam )
2589 HWND hwnd = pWnd->hwndSelf;
2591 switch(wParam) /* Hit test */
2593 case HTCAPTION:
2594 hwnd = WIN_GetTopParent(hwnd);
2596 if( WINPOS_SetActiveWindow(hwnd, TRUE, TRUE) || (GetActiveWindow() == hwnd) )
2597 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
2598 break;
2600 case HTSYSMENU:
2601 if( pWnd->dwStyle & WS_SYSMENU )
2603 if( !(pWnd->dwStyle & WS_MINIMIZE) )
2605 HDC hDC = GetWindowDC(hwnd);
2606 if (TWEAK_WineLook == WIN31_LOOK)
2607 NC_DrawSysButton( hwnd, hDC, TRUE );
2608 else
2609 NC_DrawSysButton95( hwnd, hDC, TRUE );
2610 ReleaseDC( hwnd, hDC );
2612 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
2614 break;
2616 case HTMENU:
2617 SendMessage16( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam );
2618 break;
2620 case HTHSCROLL:
2621 SendMessage16( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
2622 break;
2624 case HTVSCROLL:
2625 SendMessage16( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
2626 break;
2628 case HTMINBUTTON:
2629 case HTMAXBUTTON:
2630 if (TWEAK_WineLook == WIN31_LOOK)
2631 NC_TrackMinMaxBox( hwnd, wParam );
2632 else
2633 NC_TrackMinMaxBox95( hwnd, wParam );
2634 break;
2636 case HTCLOSE:
2637 if (TWEAK_WineLook >= WIN95_LOOK)
2638 NC_TrackCloseButton95 (hwnd, wParam);
2639 break;
2641 case HTLEFT:
2642 case HTRIGHT:
2643 case HTTOP:
2644 case HTTOPLEFT:
2645 case HTTOPRIGHT:
2646 case HTBOTTOM:
2647 case HTBOTTOMLEFT:
2648 case HTBOTTOMRIGHT:
2649 /* make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU */
2650 SendMessage16( hwnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam);
2651 break;
2653 case HTBORDER:
2654 break;
2656 return 0;
2660 /***********************************************************************
2661 * NC_HandleNCLButtonDblClk
2663 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2665 LONG NC_HandleNCLButtonDblClk( WND *pWnd, WPARAM16 wParam, LPARAM lParam )
2668 * if this is an icon, send a restore since we are handling
2669 * a double click
2671 if (pWnd->dwStyle & WS_MINIMIZE)
2673 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_RESTORE, lParam );
2674 return 0;
2677 switch(wParam) /* Hit test */
2679 case HTCAPTION:
2680 /* stop processing if WS_MAXIMIZEBOX is missing */
2681 if (pWnd->dwStyle & WS_MAXIMIZEBOX)
2682 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND,
2683 (pWnd->dwStyle & WS_MAXIMIZE) ? SC_RESTORE : SC_MAXIMIZE,
2684 lParam );
2685 break;
2687 case HTSYSMENU:
2688 if (!(GetClassWord(pWnd->hwndSelf, GCW_STYLE) & CS_NOCLOSE))
2689 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, lParam );
2690 break;
2692 case HTHSCROLL:
2693 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL,
2694 lParam );
2695 break;
2697 case HTVSCROLL:
2698 SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL,
2699 lParam );
2700 break;
2702 return 0;
2706 /***********************************************************************
2707 * NC_HandleSysCommand
2709 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2711 LONG NC_HandleSysCommand( HWND hwnd, WPARAM16 wParam, POINT16 pt )
2713 WND *wndPtr = WIN_FindWndPtr( hwnd );
2714 POINT pt32;
2715 UINT16 uCommand = wParam & 0xFFF0;
2717 TRACE("Handling WM_SYSCOMMAND %x %d,%d\n", wParam, pt.x, pt.y );
2719 if (wndPtr->dwStyle & WS_CHILD && uCommand != SC_KEYMENU )
2720 ScreenToClient16( wndPtr->parent->hwndSelf, &pt );
2722 switch (uCommand)
2724 case SC_SIZE:
2725 case SC_MOVE:
2726 NC_DoSizeMove( hwnd, wParam );
2727 break;
2729 case SC_MINIMIZE:
2730 if (hwnd == GetForegroundWindow())
2731 ShowOwnedPopups(hwnd,FALSE);
2732 ShowWindow( hwnd, SW_MINIMIZE );
2733 break;
2735 case SC_MAXIMIZE:
2736 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2737 ShowOwnedPopups(hwnd,TRUE);
2738 ShowWindow( hwnd, SW_MAXIMIZE );
2739 break;
2741 case SC_RESTORE:
2742 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2743 ShowOwnedPopups(hwnd,TRUE);
2744 ShowWindow( hwnd, SW_RESTORE );
2745 break;
2747 case SC_CLOSE:
2748 WIN_ReleaseWndPtr(wndPtr);
2749 return SendMessage16( hwnd, WM_CLOSE, 0, 0 );
2751 case SC_VSCROLL:
2752 case SC_HSCROLL:
2753 CONV_POINT16TO32( &pt, &pt32 );
2754 NC_TrackScrollBar( hwnd, wParam, pt32 );
2755 break;
2757 case SC_MOUSEMENU:
2758 CONV_POINT16TO32( &pt, &pt32 );
2759 MENU_TrackMouseMenuBar( wndPtr, wParam & 0x000F, pt32 );
2760 break;
2762 case SC_KEYMENU:
2763 MENU_TrackKbdMenuBar( wndPtr , wParam , pt.x );
2764 break;
2766 case SC_TASKLIST:
2767 WinExec( "taskman.exe", SW_SHOWNORMAL );
2768 break;
2770 case SC_SCREENSAVE:
2771 if (wParam == SC_ABOUTWINE)
2772 ShellAboutA(hwnd,"Wine", WINE_RELEASE_INFO, 0);
2773 else
2774 if (wParam == SC_PUTMARK)
2775 TRACE_(shell)("Mark requested by user\n");
2776 break;
2778 case SC_HOTKEY:
2779 case SC_ARRANGE:
2780 case SC_NEXTWINDOW:
2781 case SC_PREVWINDOW:
2782 FIXME("unimplemented!\n");
2783 break;
2785 WIN_ReleaseWndPtr(wndPtr);
2786 return 0;
2789 /*************************************************************
2790 * NC_DrawGrayButton
2792 * Stub for the grayed button of the caption
2794 *************************************************************/
2796 BOOL NC_DrawGrayButton(HDC hdc, int x, int y)
2798 HBITMAP hMaskBmp;
2799 HDC hdcMask = CreateCompatibleDC (0);
2800 HBRUSH hOldBrush;
2802 hMaskBmp = CreateBitmap (12, 10, 1, 1, lpGrayMask);
2804 if(hMaskBmp == 0)
2805 return FALSE;
2807 SelectObject (hdcMask, hMaskBmp);
2809 /* Draw the grayed bitmap using the mask */
2810 hOldBrush = SelectObject (hdc, RGB(128, 128, 128));
2811 BitBlt (hdc, x, y, 12, 10,
2812 hdcMask, 0, 0, 0xB8074A);
2814 /* Clean up */
2815 SelectObject (hdc, hOldBrush);
2816 DeleteObject(hMaskBmp);
2817 DeleteDC (hdcMask);
2819 return TRUE;