Allocate a memory view for builtin dlls so that VirtualQuery returns
[wine/multimedia.git] / windows / nonclient.c
blobff491c26e0f523e2ede4f30140cb2c91e27a1ac4
1 /*
2 * Non-client area window functions
4 * Copyright 1994 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "config.h"
23 #include <stdarg.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wingdi.h"
28 #include "wine/winuser16.h"
29 #include "wownt32.h"
30 #include "win.h"
31 #include "user.h"
32 #include "dce.h"
33 #include "controls.h"
34 #include "cursoricon.h"
35 #include "winpos.h"
36 #include "nonclient.h"
37 #include "shellapi.h"
38 #include "bitmap.h"
39 #include "wine/debug.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(nonclient);
42 WINE_DECLARE_DEBUG_CHANNEL(shell);
44 BOOL NC_DrawGrayButton(HDC hdc, int x, int y);
46 static HBITMAP hbitmapClose;
48 static const BYTE lpGrayMask[] = { 0xAA, 0xA0,
49 0x55, 0x50,
50 0xAA, 0xA0,
51 0x55, 0x50,
52 0xAA, 0xA0,
53 0x55, 0x50,
54 0xAA, 0xA0,
55 0x55, 0x50,
56 0xAA, 0xA0,
57 0x55, 0x50};
59 #define SC_ABOUTWINE (SC_SCREENSAVE+1)
60 #define SC_PUTMARK (SC_SCREENSAVE+2)
62 /* Some useful macros */
63 #define HAS_DLGFRAME(style,exStyle) \
64 (((exStyle) & WS_EX_DLGMODALFRAME) || \
65 (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
67 #define HAS_THICKFRAME(style,exStyle) \
68 (((style) & WS_THICKFRAME) && \
69 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
71 #define HAS_THINFRAME(style) \
72 (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
74 #define HAS_BIGFRAME(style,exStyle) \
75 (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
76 ((exStyle) & WS_EX_DLGMODALFRAME))
78 #define HAS_STATICOUTERFRAME(style,exStyle) \
79 (((exStyle) & (WS_EX_STATICEDGE|WS_EX_DLGMODALFRAME)) == \
80 WS_EX_STATICEDGE)
82 #define HAS_ANYFRAME(style,exStyle) \
83 (((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
84 ((exStyle) & WS_EX_DLGMODALFRAME) || \
85 !((style) & (WS_CHILD | WS_POPUP)))
87 #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
90 /***********************************************************************
91 * NC_AdjustRect
93 * Compute the size of the window rectangle from the size of the
94 * client rectangle.
96 static void NC_AdjustRect( LPRECT rect, DWORD style, BOOL menu, DWORD exStyle )
98 if (TWEAK_WineLook > WIN31_LOOK)
99 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
101 if(style & WS_ICONIC) return;
103 if (HAS_THICKFRAME( style, exStyle ))
104 InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
105 else if (HAS_DLGFRAME( style, exStyle ))
106 InflateRect( rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
107 else if (HAS_THINFRAME( style ))
108 InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
110 if ((style & WS_CAPTION) == WS_CAPTION)
111 rect->top -= GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
113 if (menu) rect->top -= GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYBORDER);
115 if (style & WS_VSCROLL) {
116 rect->right += GetSystemMetrics(SM_CXVSCROLL) - 1;
117 if(!HAS_ANYFRAME( style, exStyle ))
118 rect->right++;
121 if (style & WS_HSCROLL) {
122 rect->bottom += GetSystemMetrics(SM_CYHSCROLL) - 1;
123 if(!HAS_ANYFRAME( style, exStyle ))
124 rect->bottom++;
129 /******************************************************************************
130 * NC_AdjustRectOuter95
132 * Computes the size of the "outside" parts of the window based on the
133 * parameters of the client area.
135 + PARAMS
136 * LPRECT16 rect
137 * DWORD style
138 * BOOL menu
139 * DWORD exStyle
141 * NOTES
142 * "Outer" parts of a window means the whole window frame, caption and
143 * menu bar. It does not include "inner" parts of the frame like client
144 * edge, static edge or scroll bars.
146 * Revision history
147 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
148 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
150 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
151 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
152 * NC_AdjustRectInner95 and added handling of Win95 styles.
154 * 28-Jul-1999 Ove Kåven (ovek@arcticnet.no)
155 * Streamlined window style checks.
157 *****************************************************************************/
159 static void
160 NC_AdjustRectOuter95 (LPRECT rect, DWORD style, BOOL menu, DWORD exStyle)
162 int adjust;
163 if(style & WS_ICONIC) return;
165 if ((exStyle & (WS_EX_STATICEDGE|WS_EX_DLGMODALFRAME)) ==
166 WS_EX_STATICEDGE)
168 adjust = 1; /* for the outer frame always present */
170 else
172 adjust = 0;
173 if ((exStyle & WS_EX_DLGMODALFRAME) ||
174 (style & (WS_THICKFRAME|WS_DLGFRAME))) adjust = 2; /* outer */
176 if (style & WS_THICKFRAME)
177 adjust += ( GetSystemMetrics (SM_CXFRAME)
178 - GetSystemMetrics (SM_CXDLGFRAME)); /* The resize border */
179 if ((style & (WS_BORDER|WS_DLGFRAME)) ||
180 (exStyle & WS_EX_DLGMODALFRAME))
181 adjust++; /* The other border */
183 InflateRect (rect, adjust, adjust);
185 if ((style & WS_CAPTION) == WS_CAPTION)
187 if (exStyle & WS_EX_TOOLWINDOW)
188 rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
189 else
190 rect->top -= GetSystemMetrics(SM_CYCAPTION);
192 if (menu) rect->top -= GetSystemMetrics(SM_CYMENU);
196 /******************************************************************************
197 * NC_AdjustRectInner95
199 * Computes the size of the "inside" part of the window based on the
200 * parameters of the client area.
202 + PARAMS
203 * LPRECT16 rect
204 * DWORD style
205 * DWORD exStyle
207 * NOTES
208 * "Inner" part of a window means the window frame inside of the flat
209 * window frame. It includes the client edge, the static edge and the
210 * scroll bars.
212 * Revision history
213 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
214 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
216 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
217 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
218 * NC_AdjustRectInner95 and added handling of Win95 styles.
220 *****************************************************************************/
222 static void
223 NC_AdjustRectInner95 (LPRECT rect, DWORD style, DWORD exStyle)
225 if(style & WS_ICONIC) return;
227 if (exStyle & WS_EX_CLIENTEDGE)
228 InflateRect(rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
230 if (style & WS_VSCROLL)
232 if((exStyle & WS_EX_LEFTSCROLLBAR) != 0)
233 rect->left -= GetSystemMetrics(SM_CXVSCROLL);
234 else
235 rect->right += GetSystemMetrics(SM_CXVSCROLL);
237 if (style & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
242 static HICON NC_IconForWindow( HWND hwnd )
244 HICON hIcon = (HICON) GetClassLongA( hwnd, GCL_HICONSM );
245 if (!hIcon) hIcon = (HICON) GetClassLongA( hwnd, GCL_HICON );
247 /* If there is no hIcon specified and this is a modal dialog,
248 * get the default one.
250 if (!hIcon && (GetWindowLongA( hwnd, GWL_STYLE ) & DS_MODALFRAME))
251 hIcon = LoadImageA(0, (LPSTR)IDI_WINLOGO, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
252 return hIcon;
255 /***********************************************************************
256 * DrawCaption (USER32.@) Draws a caption bar
258 * PARAMS
259 * hwnd [I]
260 * hdc [I]
261 * lpRect [I]
262 * uFlags [I]
264 * RETURNS
265 * Success:
266 * Failure:
269 BOOL WINAPI
270 DrawCaption (HWND hwnd, HDC hdc, const RECT *lpRect, UINT uFlags)
272 return DrawCaptionTempA (hwnd, hdc, lpRect, 0, 0, NULL, uFlags & 0x1F);
276 /***********************************************************************
277 * DrawCaptionTempA (USER32.@)
279 BOOL WINAPI DrawCaptionTempA (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
280 HICON hIcon, LPCSTR str, UINT uFlags)
282 LPWSTR strW;
283 INT len;
284 BOOL ret = FALSE;
286 if (!(uFlags & DC_TEXT) || !str)
287 return DrawCaptionTempW( hwnd, hdc, rect, hFont, hIcon, NULL, uFlags );
289 len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
290 if ((strW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
292 MultiByteToWideChar( CP_ACP, 0, str, -1, strW, len );
293 ret = DrawCaptionTempW (hwnd, hdc, rect, hFont, hIcon, strW, uFlags);
294 HeapFree( GetProcessHeap (), 0, strW );
296 return ret;
300 /***********************************************************************
301 * DrawCaptionTempW (USER32.@)
303 BOOL WINAPI DrawCaptionTempW (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
304 HICON hIcon, LPCWSTR str, UINT uFlags)
306 RECT rc = *rect;
308 TRACE("(%p,%p,%p,%p,%p,%s,%08x)\n",
309 hwnd, hdc, rect, hFont, hIcon, debugstr_w(str), uFlags);
311 /* drawing background */
312 if (uFlags & DC_INBUTTON) {
313 FillRect (hdc, &rc, GetSysColorBrush (COLOR_3DFACE));
315 if (uFlags & DC_ACTIVE) {
316 HBRUSH hbr = SelectObject (hdc, CACHE_GetPattern55AABrush ());
317 PatBlt (hdc, rc.left, rc.top,
318 rc.right-rc.left, rc.bottom-rc.top, 0xFA0089);
319 SelectObject (hdc, hbr);
322 else {
323 FillRect (hdc, &rc, GetSysColorBrush ((uFlags & DC_ACTIVE) ?
324 COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
328 /* drawing icon */
329 if ((uFlags & DC_ICON) && !(uFlags & DC_SMALLCAP)) {
330 POINT pt;
332 pt.x = rc.left + 2;
333 pt.y = (rc.bottom + rc.top - GetSystemMetrics(SM_CYSMICON)) / 2;
335 if (!hIcon) hIcon = NC_IconForWindow(hwnd);
336 DrawIconEx (hdc, pt.x, pt.y, hIcon, GetSystemMetrics(SM_CXSMICON),
337 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
338 rc.left += (rc.bottom - rc.top);
341 /* drawing text */
342 if (uFlags & DC_TEXT) {
343 HFONT hOldFont;
345 if (uFlags & DC_INBUTTON)
346 SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
347 else if (uFlags & DC_ACTIVE)
348 SetTextColor (hdc, GetSysColor (COLOR_CAPTIONTEXT));
349 else
350 SetTextColor (hdc, GetSysColor (COLOR_INACTIVECAPTIONTEXT));
352 SetBkMode (hdc, TRANSPARENT);
354 if (hFont)
355 hOldFont = SelectObject (hdc, hFont);
356 else {
357 NONCLIENTMETRICSW nclm;
358 HFONT hNewFont;
359 nclm.cbSize = sizeof(NONCLIENTMETRICSW);
360 SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
361 hNewFont = CreateFontIndirectW ((uFlags & DC_SMALLCAP) ?
362 &nclm.lfSmCaptionFont : &nclm.lfCaptionFont);
363 hOldFont = SelectObject (hdc, hNewFont);
366 if (str)
367 DrawTextW (hdc, str, -1, &rc,
368 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
369 else {
370 WCHAR szText[128];
371 INT nLen;
372 nLen = GetWindowTextW (hwnd, szText, 128);
373 DrawTextW (hdc, szText, nLen, &rc,
374 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
377 if (hFont)
378 SelectObject (hdc, hOldFont);
379 else
380 DeleteObject (SelectObject (hdc, hOldFont));
383 /* drawing focus ??? */
384 if (uFlags & 0x2000)
385 FIXME("undocumented flag (0x2000)!\n");
387 return 0;
391 /***********************************************************************
392 * AdjustWindowRect (USER.102)
394 BOOL16 WINAPI AdjustWindowRect16( LPRECT16 rect, DWORD style, BOOL16 menu )
396 return AdjustWindowRectEx16( rect, style, menu, 0 );
400 /***********************************************************************
401 * AdjustWindowRect (USER32.@)
403 BOOL WINAPI AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu )
405 return AdjustWindowRectEx( rect, style, menu, 0 );
409 /***********************************************************************
410 * AdjustWindowRectEx (USER.454)
412 BOOL16 WINAPI AdjustWindowRectEx16( LPRECT16 rect, DWORD style,
413 BOOL16 menu, DWORD exStyle )
415 RECT rect32;
416 BOOL ret;
418 CONV_RECT16TO32( rect, &rect32 );
419 ret = AdjustWindowRectEx( &rect32, style, menu, exStyle );
420 CONV_RECT32TO16( &rect32, rect );
421 return ret;
425 /***********************************************************************
426 * AdjustWindowRectEx (USER32.@)
428 BOOL WINAPI AdjustWindowRectEx( LPRECT rect, DWORD style, BOOL menu, DWORD exStyle )
430 /* Correct the window style */
431 style &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD);
432 exStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE |
433 WS_EX_STATICEDGE | WS_EX_TOOLWINDOW);
434 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
436 TRACE("(%ld,%ld)-(%ld,%ld) %08lx %d %08lx\n",
437 rect->left, rect->top, rect->right, rect->bottom,
438 style, menu, exStyle );
440 if (TWEAK_WineLook == WIN31_LOOK)
441 NC_AdjustRect( rect, style, menu, exStyle );
442 else
444 NC_AdjustRectOuter95( rect, style, menu, exStyle );
445 NC_AdjustRectInner95( rect, style, exStyle );
447 return TRUE;
451 /***********************************************************************
452 * NC_HandleNCCalcSize
454 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
456 LONG NC_HandleNCCalcSize( HWND hwnd, RECT *winRect )
458 RECT tmpRect = { 0, 0, 0, 0 };
459 LONG result = 0;
460 LONG cls_style = GetClassLongA(hwnd, GCL_STYLE);
461 LONG style = GetWindowLongA( hwnd, GWL_STYLE );
462 LONG exStyle = GetWindowLongA( hwnd, GWL_EXSTYLE );
464 if (cls_style & CS_VREDRAW) result |= WVR_VREDRAW;
465 if (cls_style & CS_HREDRAW) result |= WVR_HREDRAW;
467 if (!IsIconic(hwnd))
469 if (TWEAK_WineLook == WIN31_LOOK)
470 NC_AdjustRect( &tmpRect, style, FALSE, exStyle );
471 else
472 NC_AdjustRectOuter95( &tmpRect, style, FALSE, exStyle );
474 winRect->left -= tmpRect.left;
475 winRect->top -= tmpRect.top;
476 winRect->right -= tmpRect.right;
477 winRect->bottom -= tmpRect.bottom;
479 if (!(style & WS_CHILD) && GetMenu(hwnd))
481 TRACE("Calling GetMenuBarHeight with hwnd %p, width %ld, at (%ld, %ld).\n",
482 hwnd, winRect->right - winRect->left, -tmpRect.left, -tmpRect.top );
484 winRect->top +=
485 MENU_GetMenuBarHeight( hwnd,
486 winRect->right - winRect->left,
487 -tmpRect.left, -tmpRect.top ) + 1;
490 if (TWEAK_WineLook > WIN31_LOOK) {
491 SetRect(&tmpRect, 0, 0, 0, 0);
492 NC_AdjustRectInner95 (&tmpRect, style, exStyle);
493 winRect->left -= tmpRect.left;
494 winRect->top -= tmpRect.top;
495 winRect->right -= tmpRect.right;
496 winRect->bottom -= tmpRect.bottom;
499 if (winRect->top > winRect->bottom)
500 winRect->bottom = winRect->top;
502 if (winRect->left > winRect->right)
503 winRect->right = winRect->left;
505 return result;
509 /***********************************************************************
510 * NC_GetInsideRect
512 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
513 * but without the borders (if any).
514 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
516 void NC_GetInsideRect( HWND hwnd, RECT *rect )
518 WND * wndPtr = WIN_FindWndPtr( hwnd );
520 rect->top = rect->left = 0;
521 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
522 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
524 if (wndPtr->dwStyle & WS_ICONIC) goto END;
526 /* Remove frame from rectangle */
527 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
529 InflateRect( rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
531 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
533 InflateRect( rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
534 /* FIXME: this isn't in NC_AdjustRect? why not? */
535 if ((TWEAK_WineLook == WIN31_LOOK) && (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME))
536 InflateRect( rect, -1, 0 );
538 else if (HAS_THINFRAME( wndPtr->dwStyle ))
540 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
543 /* We have additional border information if the window
544 * is a child (but not an MDI child) */
545 if (TWEAK_WineLook != WIN31_LOOK)
547 if ( (wndPtr->dwStyle & WS_CHILD) &&
548 ( (wndPtr->dwExStyle & WS_EX_MDICHILD) == 0 ) )
550 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
551 InflateRect (rect, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE));
552 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
553 InflateRect (rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
557 END:
558 WIN_ReleaseWndPtr(wndPtr);
559 return;
563 /***********************************************************************
564 * NC_DoNCHitTest
566 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
569 static LONG NC_DoNCHitTest (WND *wndPtr, POINT pt )
571 RECT rect;
573 TRACE("hwnd=%p pt=%ld,%ld\n", wndPtr->hwndSelf, pt.x, pt.y );
575 GetWindowRect(wndPtr->hwndSelf, &rect );
576 if (!PtInRect( &rect, pt )) return HTNOWHERE;
578 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
580 /* Check borders */
581 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
583 InflateRect( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
584 if (!PtInRect( &rect, pt ))
586 /* Check top sizing border */
587 if (pt.y < rect.top)
589 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
590 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
591 return HTTOP;
593 /* Check bottom sizing border */
594 if (pt.y >= rect.bottom)
596 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
597 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
598 return HTBOTTOM;
600 /* Check left sizing border */
601 if (pt.x < rect.left)
603 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
604 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
605 return HTLEFT;
607 /* Check right sizing border */
608 if (pt.x >= rect.right)
610 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
611 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
612 return HTRIGHT;
616 else /* No thick frame */
618 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
619 InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
620 else if (HAS_THINFRAME( wndPtr->dwStyle ))
621 InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
622 if (!PtInRect( &rect, pt )) return HTBORDER;
625 /* Check caption */
627 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
629 rect.top += GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
630 if (!PtInRect( &rect, pt ))
632 /* Check system menu */
633 if ((wndPtr->dwStyle & WS_SYSMENU) && !(wndPtr->dwExStyle & WS_EX_TOOLWINDOW))
634 rect.left += GetSystemMetrics(SM_CXSIZE);
635 if (pt.x <= rect.left) return HTSYSMENU;
637 /* Check maximize box */
638 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
639 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
641 if (pt.x >= rect.right) return HTMAXBUTTON;
642 /* Check minimize box */
643 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
644 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
645 if (pt.x >= rect.right) return HTMINBUTTON;
646 return HTCAPTION;
650 /* Check client area */
652 ScreenToClient( wndPtr->hwndSelf, &pt );
653 GetClientRect( wndPtr->hwndSelf, &rect );
654 if (PtInRect( &rect, pt )) return HTCLIENT;
656 /* Check vertical scroll bar */
658 if (wndPtr->dwStyle & WS_VSCROLL)
660 if((wndPtr->dwExStyle & WS_EX_LEFTSCROLLBAR) != 0)
661 rect.left -= GetSystemMetrics(SM_CXVSCROLL);
662 else
663 rect.right += GetSystemMetrics(SM_CXVSCROLL);
664 if (PtInRect( &rect, pt )) return HTVSCROLL;
667 /* Check horizontal scroll bar */
669 if (wndPtr->dwStyle & WS_HSCROLL)
671 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
672 if (PtInRect( &rect, pt ))
674 /* Check size box */
675 if ((wndPtr->dwStyle & WS_VSCROLL) &&
676 ((((wndPtr->dwExStyle & WS_EX_LEFTSCROLLBAR) != 0) && (pt.x <= rect.left + GetSystemMetrics(SM_CXVSCROLL))) ||
677 (((wndPtr->dwExStyle & WS_EX_LEFTSCROLLBAR) == 0) && (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))))
678 return HTSIZE;
679 return HTHSCROLL;
683 /* Check menu bar */
685 if (HAS_MENU(wndPtr))
687 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
688 return HTMENU;
691 /* Has to return HTNOWHERE if nothing was found
692 Could happen when a window has a customized non client area */
693 return HTNOWHERE;
697 /***********************************************************************
698 * NC_DoNCHitTest95
700 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
702 * FIXME: Just a modified copy of the Win 3.1 version.
705 static LONG NC_DoNCHitTest95 (WND *wndPtr, POINT pt )
707 RECT rect;
709 TRACE("hwnd=%p pt=%ld,%ld\n", wndPtr->hwndSelf, pt.x, pt.y );
711 GetWindowRect(wndPtr->hwndSelf, &rect );
712 if (!PtInRect( &rect, pt )) return HTNOWHERE;
714 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
716 /* Check borders */
717 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
719 InflateRect( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
720 if (!PtInRect( &rect, pt ))
722 /* Check top sizing border */
723 if (pt.y < rect.top)
725 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
726 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
727 return HTTOP;
729 /* Check bottom sizing border */
730 if (pt.y >= rect.bottom)
732 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
733 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
734 return HTBOTTOM;
736 /* Check left sizing border */
737 if (pt.x < rect.left)
739 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
740 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
741 return HTLEFT;
743 /* Check right sizing border */
744 if (pt.x >= rect.right)
746 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
747 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
748 return HTRIGHT;
752 else /* No thick frame */
754 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
755 InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
756 else if (HAS_THINFRAME( wndPtr->dwStyle ))
757 InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
758 if (!PtInRect( &rect, pt )) return HTBORDER;
761 /* Check caption */
763 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
765 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
766 rect.top += GetSystemMetrics(SM_CYSMCAPTION) - 1;
767 else
768 rect.top += GetSystemMetrics(SM_CYCAPTION) - 1;
769 if (!PtInRect( &rect, pt ))
771 /* Check system menu */
772 if ((wndPtr->dwStyle & WS_SYSMENU) && !(wndPtr->dwExStyle & WS_EX_TOOLWINDOW))
774 if (NC_IconForWindow(wndPtr->hwndSelf))
775 rect.left += GetSystemMetrics(SM_CYCAPTION) - 1;
777 if (pt.x < rect.left) return HTSYSMENU;
779 /* Check close button */
780 if (wndPtr->dwStyle & WS_SYSMENU)
781 rect.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
782 if (pt.x > rect.right) return HTCLOSE;
784 /* Check maximize box */
785 /* In win95 there is automatically a Maximize button when there is a minimize one*/
786 if ((wndPtr->dwStyle & WS_MAXIMIZEBOX)|| (wndPtr->dwStyle & WS_MINIMIZEBOX))
787 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
788 if (pt.x > rect.right) return HTMAXBUTTON;
790 /* Check minimize box */
791 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
792 if ((wndPtr->dwStyle & WS_MINIMIZEBOX)||(wndPtr->dwStyle & WS_MAXIMIZEBOX))
793 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
795 if (pt.x > rect.right) return HTMINBUTTON;
796 return HTCAPTION;
800 /* Check client area */
802 ScreenToClient( wndPtr->hwndSelf, &pt );
803 GetClientRect( wndPtr->hwndSelf, &rect );
804 if (PtInRect( &rect, pt )) return HTCLIENT;
806 /* Check vertical scroll bar */
808 if (wndPtr->dwStyle & WS_VSCROLL)
810 if((wndPtr->dwExStyle & WS_EX_LEFTSCROLLBAR) != 0)
811 rect.left -= GetSystemMetrics(SM_CXVSCROLL);
812 else
813 rect.right += GetSystemMetrics(SM_CXVSCROLL);
814 if (PtInRect( &rect, pt )) return HTVSCROLL;
817 /* Check horizontal scroll bar */
819 if (wndPtr->dwStyle & WS_HSCROLL)
821 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
822 if (PtInRect( &rect, pt ))
824 /* Check size box */
825 if ((wndPtr->dwStyle & WS_VSCROLL) &&
826 ((((wndPtr->dwExStyle & WS_EX_LEFTSCROLLBAR) != 0) && (pt.x <= rect.left + GetSystemMetrics(SM_CXVSCROLL))) ||
827 (((wndPtr->dwExStyle & WS_EX_LEFTSCROLLBAR) == 0) && (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))))
828 return HTSIZE;
829 return HTHSCROLL;
833 /* Check menu bar */
835 if (HAS_MENU(wndPtr))
837 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
838 return HTMENU;
841 /* Has to return HTNOWHERE if nothing was found
842 Could happen when a window has a customized non client area */
843 return HTNOWHERE;
847 /***********************************************************************
848 * NC_HandleNCHitTest
850 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
852 LONG NC_HandleNCHitTest (HWND hwnd , POINT pt)
854 LONG retvalue;
855 WND *wndPtr = WIN_FindWndPtr (hwnd);
857 if (!wndPtr)
858 return HTERROR;
860 if (TWEAK_WineLook == WIN31_LOOK)
861 retvalue = NC_DoNCHitTest (wndPtr, pt);
862 else
863 retvalue = NC_DoNCHitTest95 (wndPtr, pt);
864 WIN_ReleaseWndPtr(wndPtr);
865 return retvalue;
869 /***********************************************************************
870 * NC_DrawSysButton
872 void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down )
874 RECT rect;
875 HDC hdcMem;
876 HBITMAP hbitmap;
878 NC_GetInsideRect( hwnd, &rect );
879 hdcMem = CreateCompatibleDC( hdc );
880 hbitmap = SelectObject( hdcMem, hbitmapClose );
881 BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE), GetSystemMetrics(SM_CYSIZE),
882 hdcMem, (GetWindowLongA(hwnd,GWL_STYLE) & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE) : 0, 0,
883 down ? NOTSRCCOPY : SRCCOPY );
884 SelectObject( hdcMem, hbitmap );
885 DeleteDC( hdcMem );
889 /***********************************************************************
890 * NC_DrawMaxButton
892 static void NC_DrawMaxButton( HWND hwnd, HDC hdc, BOOL down )
894 RECT rect;
895 UINT flags = IsZoomed(hwnd) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMAX;
897 NC_GetInsideRect( hwnd, &rect );
898 rect.left = rect.right - GetSystemMetrics(SM_CXSIZE) + 1;
899 rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
900 rect.top += 1;
901 rect.right -= 1;
902 if (down) flags |= DFCS_PUSHED;
903 DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
907 /***********************************************************************
908 * NC_DrawMinButton
910 static void NC_DrawMinButton( HWND hwnd, HDC hdc, BOOL down )
912 RECT rect;
913 UINT flags = DFCS_CAPTIONMIN;
914 DWORD style = GetWindowLongA( hwnd, GWL_STYLE );
916 NC_GetInsideRect( hwnd, &rect );
917 if (style & (WS_MAXIMIZEBOX|WS_MINIMIZEBOX))
918 rect.right -= GetSystemMetrics(SM_CXSIZE) - 2;
919 rect.left = rect.right - GetSystemMetrics(SM_CXSIZE) + 1;
920 rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
921 rect.top += 1;
922 rect.right -= 1;
923 if (down) flags |= DFCS_PUSHED;
924 DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
928 /******************************************************************************
930 * void NC_DrawSysButton95(
931 * HWND hwnd,
932 * HDC hdc,
933 * BOOL down )
935 * Draws the Win95 system icon.
937 * Revision history
938 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
939 * Original implementation from NC_DrawSysButton source.
940 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
941 * Fixed most bugs.
943 *****************************************************************************/
945 BOOL
946 NC_DrawSysButton95 (HWND hwnd, HDC hdc, BOOL down)
948 HICON hIcon = NC_IconForWindow( hwnd );
950 if (hIcon)
952 RECT rect;
953 NC_GetInsideRect( hwnd, &rect );
954 DrawIconEx (hdc, rect.left + 1, rect.top + 1, hIcon,
955 GetSystemMetrics(SM_CXSIZE) - 1,
956 GetSystemMetrics(SM_CYSIZE) - 1, 0, 0, DI_NORMAL);
958 return (hIcon != 0);
962 /******************************************************************************
964 * void NC_DrawCloseButton95(
965 * HWND hwnd,
966 * HDC hdc,
967 * BOOL down,
968 * BOOL bGrayed )
970 * Draws the Win95 close button.
972 * If bGrayed is true, then draw a disabled Close button
974 * Revision history
975 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
976 * Original implementation from NC_DrawSysButton95 source.
978 *****************************************************************************/
980 static void NC_DrawCloseButton95 (HWND hwnd, HDC hdc, BOOL down, BOOL bGrayed)
982 RECT rect;
984 NC_GetInsideRect( hwnd, &rect );
986 /* A tool window has a smaller Close button */
987 if (GetWindowLongA( hwnd, GWL_EXSTYLE ) & WS_EX_TOOLWINDOW)
989 INT iBmpHeight = 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
990 INT iBmpWidth = 11; /* it uses 11x11 for the close button in tool window */
991 INT iCaptionHeight = GetSystemMetrics(SM_CYSMCAPTION);
993 rect.top = rect.top + (iCaptionHeight - 1 - iBmpHeight) / 2;
994 rect.left = rect.right - (iCaptionHeight + 1 + iBmpWidth) / 2;
995 rect.bottom = rect.top + iBmpHeight;
996 rect.right = rect.left + iBmpWidth;
998 else
1000 rect.left = rect.right - GetSystemMetrics(SM_CXSIZE) - 1;
1001 rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
1002 rect.top += 2;
1003 rect.right -= 2;
1005 DrawFrameControl( hdc, &rect, DFC_CAPTION,
1006 (DFCS_CAPTIONCLOSE |
1007 (down ? DFCS_PUSHED : 0) |
1008 (bGrayed ? DFCS_INACTIVE : 0)) );
1011 /******************************************************************************
1012 * NC_DrawMaxButton95
1014 * Draws the maximize button for Win95 style windows.
1015 * If bGrayed is true, then draw a disabled Maximize button
1017 static void NC_DrawMaxButton95(HWND hwnd,HDC hdc,BOOL down, BOOL bGrayed)
1019 RECT rect;
1020 UINT flags = IsZoomed(hwnd) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMAX;
1022 NC_GetInsideRect( hwnd, &rect );
1023 if (GetWindowLongA( hwnd, GWL_STYLE) & WS_SYSMENU)
1024 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1025 rect.left = rect.right - GetSystemMetrics(SM_CXSIZE);
1026 rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
1027 rect.top += 2;
1028 rect.right -= 2;
1029 if (down) flags |= DFCS_PUSHED;
1030 if (bGrayed) flags |= DFCS_INACTIVE;
1031 DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
1034 /******************************************************************************
1035 * NC_DrawMinButton95
1037 * Draws the minimize button for Win95 style windows.
1038 * If bGrayed is true, then draw a disabled Minimize button
1040 static void NC_DrawMinButton95(HWND hwnd,HDC hdc,BOOL down, BOOL bGrayed)
1042 RECT rect;
1043 UINT flags = DFCS_CAPTIONMIN;
1044 DWORD style = GetWindowLongA( hwnd, GWL_STYLE );
1046 NC_GetInsideRect( hwnd, &rect );
1047 if (style & WS_SYSMENU)
1048 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1049 if (style & (WS_MAXIMIZEBOX|WS_MINIMIZEBOX))
1050 rect.right -= GetSystemMetrics(SM_CXSIZE) - 2;
1051 rect.left = rect.right - GetSystemMetrics(SM_CXSIZE);
1052 rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
1053 rect.top += 2;
1054 rect.right -= 2;
1055 if (down) flags |= DFCS_PUSHED;
1056 if (bGrayed) flags |= DFCS_INACTIVE;
1057 DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
1060 /***********************************************************************
1061 * NC_DrawFrame
1063 * Draw a window frame inside the given rectangle, and update the rectangle.
1064 * The correct pen for the frame must be selected in the DC.
1066 static void NC_DrawFrame( HDC hdc, RECT *rect, BOOL dlgFrame,
1067 BOOL active )
1069 INT width, height;
1071 if (TWEAK_WineLook != WIN31_LOOK)
1072 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
1074 if (dlgFrame)
1076 width = GetSystemMetrics(SM_CXDLGFRAME) - 1;
1077 height = GetSystemMetrics(SM_CYDLGFRAME) - 1;
1078 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1079 COLOR_INACTIVECAPTION) );
1081 else
1083 width = GetSystemMetrics(SM_CXFRAME) - 2;
1084 height = GetSystemMetrics(SM_CYFRAME) - 2;
1085 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1086 COLOR_INACTIVEBORDER) );
1089 /* Draw frame */
1090 PatBlt( hdc, rect->left, rect->top,
1091 rect->right - rect->left, height, PATCOPY );
1092 PatBlt( hdc, rect->left, rect->top,
1093 width, rect->bottom - rect->top, PATCOPY );
1094 PatBlt( hdc, rect->left, rect->bottom - 1,
1095 rect->right - rect->left, -height, PATCOPY );
1096 PatBlt( hdc, rect->right - 1, rect->top,
1097 -width, rect->bottom - rect->top, PATCOPY );
1099 if (dlgFrame)
1101 InflateRect( rect, -width, -height );
1103 else
1105 INT decYOff = GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXSIZE) - 1;
1106 INT decXOff = GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYSIZE) - 1;
1108 /* Draw inner rectangle */
1110 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1111 Rectangle( hdc, rect->left + width, rect->top + height,
1112 rect->right - width , rect->bottom - height );
1114 /* Draw the decorations */
1116 MoveToEx( hdc, rect->left, rect->top + decYOff, NULL );
1117 LineTo( hdc, rect->left + width, rect->top + decYOff );
1118 MoveToEx( hdc, rect->right - 1, rect->top + decYOff, NULL );
1119 LineTo( hdc, rect->right - width - 1, rect->top + decYOff );
1120 MoveToEx( hdc, rect->left, rect->bottom - decYOff, NULL );
1121 LineTo( hdc, rect->left + width, rect->bottom - decYOff );
1122 MoveToEx( hdc, rect->right - 1, rect->bottom - decYOff, NULL );
1123 LineTo( hdc, rect->right - width - 1, rect->bottom - decYOff );
1125 MoveToEx( hdc, rect->left + decXOff, rect->top, NULL );
1126 LineTo( hdc, rect->left + decXOff, rect->top + height);
1127 MoveToEx( hdc, rect->left + decXOff, rect->bottom - 1, NULL );
1128 LineTo( hdc, rect->left + decXOff, rect->bottom - height - 1 );
1129 MoveToEx( hdc, rect->right - decXOff, rect->top, NULL );
1130 LineTo( hdc, rect->right - decXOff, rect->top + height );
1131 MoveToEx( hdc, rect->right - decXOff, rect->bottom - 1, NULL );
1132 LineTo( hdc, rect->right - decXOff, rect->bottom - height - 1 );
1134 InflateRect( rect, -width - 1, -height - 1 );
1139 /******************************************************************************
1141 * void NC_DrawFrame95(
1142 * HDC hdc,
1143 * RECT *rect,
1144 * BOOL active,
1145 * DWORD style,
1146 * DWORD exStyle )
1148 * Draw a window frame inside the given rectangle, and update the rectangle.
1150 * Bugs
1151 * Many. First, just what IS a frame in Win95? Note that the 3D look
1152 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1153 * edge. The inner rectangle just inside the frame is handled by the
1154 * Caption code.
1156 * In short, for most people, this function should be a nop (unless
1157 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1158 * them lately, but just to get this code right). Even so, it doesn't
1159 * appear to be so. It's being worked on...
1161 * Revision history
1162 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1163 * Original implementation (based on NC_DrawFrame)
1164 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1165 * Some minor fixes.
1166 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1167 * Fixed a fix or something.
1169 *****************************************************************************/
1171 static void NC_DrawFrame95(
1172 HDC hdc,
1173 RECT *rect,
1174 BOOL active,
1175 DWORD style,
1176 DWORD exStyle)
1178 INT width, height;
1180 /* Firstly the "thick" frame */
1181 if (style & WS_THICKFRAME)
1183 width = GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXDLGFRAME);
1184 height = GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYDLGFRAME);
1186 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1187 COLOR_INACTIVEBORDER) );
1188 /* Draw frame */
1189 PatBlt( hdc, rect->left, rect->top,
1190 rect->right - rect->left, height, PATCOPY );
1191 PatBlt( hdc, rect->left, rect->top,
1192 width, rect->bottom - rect->top, PATCOPY );
1193 PatBlt( hdc, rect->left, rect->bottom - 1,
1194 rect->right - rect->left, -height, PATCOPY );
1195 PatBlt( hdc, rect->right - 1, rect->top,
1196 -width, rect->bottom - rect->top, PATCOPY );
1198 InflateRect( rect, -width, -height );
1201 /* Now the other bit of the frame */
1202 if ((style & (WS_BORDER|WS_DLGFRAME)) ||
1203 (exStyle & WS_EX_DLGMODALFRAME))
1205 width = GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
1206 height = GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
1207 /* This should give a value of 1 that should also work for a border */
1209 SelectObject( hdc, GetSysColorBrush(
1210 (exStyle & (WS_EX_DLGMODALFRAME|WS_EX_CLIENTEDGE)) ?
1211 COLOR_3DFACE :
1212 (exStyle & WS_EX_STATICEDGE) ?
1213 COLOR_WINDOWFRAME :
1214 (style & (WS_DLGFRAME|WS_THICKFRAME)) ?
1215 COLOR_3DFACE :
1216 /* else */
1217 COLOR_WINDOWFRAME));
1219 /* Draw frame */
1220 PatBlt( hdc, rect->left, rect->top,
1221 rect->right - rect->left, height, PATCOPY );
1222 PatBlt( hdc, rect->left, rect->top,
1223 width, rect->bottom - rect->top, PATCOPY );
1224 PatBlt( hdc, rect->left, rect->bottom - 1,
1225 rect->right - rect->left, -height, PATCOPY );
1226 PatBlt( hdc, rect->right - 1, rect->top,
1227 -width, rect->bottom - rect->top, PATCOPY );
1229 InflateRect( rect, -width, -height );
1234 /***********************************************************************
1235 * NC_DrawCaption
1237 * Draw the window caption.
1238 * The correct pen for the window frame must be selected in the DC.
1240 static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd,
1241 DWORD style, BOOL active )
1243 RECT r = *rect;
1244 char buffer[256];
1246 if (!hbitmapClose)
1248 if (!(hbitmapClose = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_OLD_CLOSE) ))) return;
1251 if (GetWindowLongA( hwnd, GWL_EXSTYLE) & WS_EX_DLGMODALFRAME)
1253 HBRUSH hbrushOld = SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW) );
1254 PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
1255 PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
1256 PatBlt( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
1257 r.left++;
1258 r.right--;
1259 SelectObject( hdc, hbrushOld );
1261 MoveToEx( hdc, r.left, r.bottom, NULL );
1262 LineTo( hdc, r.right, r.bottom );
1264 if (style & WS_SYSMENU)
1266 NC_DrawSysButton( hwnd, hdc, FALSE );
1267 r.left += GetSystemMetrics(SM_CXSIZE) + 1;
1268 MoveToEx( hdc, r.left - 1, r.top, NULL );
1269 LineTo( hdc, r.left - 1, r.bottom );
1271 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION) );
1272 if (style & WS_MAXIMIZEBOX)
1274 NC_DrawMaxButton( hwnd, hdc, FALSE );
1275 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1277 if (style & WS_MINIMIZEBOX)
1279 NC_DrawMinButton( hwnd, hdc, FALSE );
1280 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1283 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) ))
1285 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1286 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1287 SetBkMode( hdc, TRANSPARENT );
1288 DrawTextA( hdc, buffer, -1, &r,
1289 DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );
1294 /******************************************************************************
1296 * NC_DrawCaption95(
1297 * HDC hdc,
1298 * RECT *rect,
1299 * HWND hwnd,
1300 * DWORD style,
1301 * BOOL active )
1303 * Draw the window caption for Win95 style windows.
1304 * The correct pen for the window frame must be selected in the DC.
1306 * Bugs
1307 * Hey, a function that finally works! Well, almost.
1308 * It's being worked on.
1310 * Revision history
1311 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1312 * Original implementation.
1313 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1314 * Some minor fixes.
1316 *****************************************************************************/
1318 static void NC_DrawCaption95(
1319 HDC hdc,
1320 RECT *rect,
1321 HWND hwnd,
1322 DWORD style,
1323 DWORD exStyle,
1324 BOOL active )
1326 RECT r = *rect;
1327 char buffer[256];
1328 HPEN hPrevPen;
1329 HMENU hSysMenu;
1331 hPrevPen = SelectObject( hdc, SYSCOLOR_GetPen(
1332 ((exStyle & (WS_EX_STATICEDGE|WS_EX_CLIENTEDGE|
1333 WS_EX_DLGMODALFRAME)) == WS_EX_STATICEDGE) ?
1334 COLOR_WINDOWFRAME : COLOR_3DFACE) );
1335 MoveToEx( hdc, r.left, r.bottom - 1, NULL );
1336 LineTo( hdc, r.right, r.bottom - 1 );
1337 SelectObject( hdc, hPrevPen );
1338 r.bottom--;
1340 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
1341 COLOR_INACTIVECAPTION) );
1343 if ((style & WS_SYSMENU) && !(exStyle & WS_EX_TOOLWINDOW)) {
1344 if (NC_DrawSysButton95 (hwnd, hdc, FALSE))
1345 r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
1348 if (style & WS_SYSMENU)
1350 UINT state;
1352 /* Go get the sysmenu */
1353 hSysMenu = GetSystemMenu(hwnd, FALSE);
1354 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
1356 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
1357 NC_DrawCloseButton95 (hwnd, hdc, FALSE,
1358 ((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
1359 r.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
1361 if ((style & WS_MAXIMIZEBOX) || (style & WS_MINIMIZEBOX))
1363 /* In win95 the two buttons are always there */
1364 /* But if the menu item is not in the menu they're disabled*/
1366 NC_DrawMaxButton95( hwnd, hdc, FALSE, (!(style & WS_MAXIMIZEBOX)));
1367 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1369 NC_DrawMinButton95( hwnd, hdc, FALSE, (!(style & WS_MINIMIZEBOX)));
1370 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1374 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) )) {
1375 NONCLIENTMETRICSA nclm;
1376 HFONT hFont, hOldFont;
1377 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1378 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
1379 if (exStyle & WS_EX_TOOLWINDOW)
1380 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
1381 else
1382 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
1383 hOldFont = SelectObject (hdc, hFont);
1384 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1385 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1386 SetBkMode( hdc, TRANSPARENT );
1387 r.left += 2;
1388 DrawTextA( hdc, buffer, -1, &r,
1389 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
1390 DeleteObject (SelectObject (hdc, hOldFont));
1396 /***********************************************************************
1397 * NC_DoNCPaint
1399 * Paint the non-client area. clip is currently unused.
1401 static void NC_DoNCPaint( HWND hwnd, HRGN clip, BOOL suppress_menupaint )
1403 HDC hdc;
1404 RECT rect;
1405 BOOL active;
1406 WND *wndPtr;
1407 DWORD dwStyle, dwExStyle;
1408 WORD flags;
1409 RECT rectClient, rectWindow;
1410 int has_menu;
1412 if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return;
1413 has_menu = HAS_MENU(wndPtr);
1414 dwStyle = wndPtr->dwStyle;
1415 dwExStyle = wndPtr->dwExStyle;
1416 flags = wndPtr->flags;
1417 rectClient = wndPtr->rectClient;
1418 rectWindow = wndPtr->rectWindow;
1419 WIN_ReleasePtr( wndPtr );
1421 if ( dwStyle & WS_MINIMIZE ||
1422 !WIN_IsWindowDrawable( hwnd, 0 )) return; /* Nothing to do */
1424 active = flags & WIN_NCACTIVATED;
1426 TRACE("%p %d\n", hwnd, active );
1428 if (!(hdc = GetDCEx( hwnd, (clip > (HRGN)1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1429 ((clip > (HRGN)1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN): 0) ))) return;
1431 if (ExcludeVisRect16( HDC_16(hdc), rectClient.left-rectWindow.left,
1432 rectClient.top-rectWindow.top,
1433 rectClient.right-rectWindow.left,
1434 rectClient.bottom-rectWindow.top )
1435 == NULLREGION)
1437 ReleaseDC( hwnd, hdc );
1438 return;
1441 rect.top = rect.left = 0;
1442 rect.right = rectWindow.right - rectWindow.left;
1443 rect.bottom = rectWindow.bottom - rectWindow.top;
1445 SelectObject( hdc, SYSCOLOR_GetPen(COLOR_WINDOWFRAME) );
1447 if (HAS_ANYFRAME( dwStyle, dwExStyle ))
1449 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1450 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1451 InflateRect( &rect, -1, -1 );
1454 if (HAS_THICKFRAME( dwStyle, dwExStyle ))
1455 NC_DrawFrame(hdc, &rect, FALSE, active );
1456 else if (HAS_DLGFRAME( dwStyle, dwExStyle ))
1457 NC_DrawFrame( hdc, &rect, TRUE, active );
1459 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
1461 RECT r = rect;
1462 r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
1463 rect.top += GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYBORDER);
1464 NC_DrawCaption( hdc, &r, hwnd, dwStyle, active );
1467 if (has_menu)
1469 RECT r = rect;
1470 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU); /* default height */
1471 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint );
1474 /* Draw the scroll-bars */
1476 if (dwStyle & WS_VSCROLL)
1477 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1478 if (dwStyle & WS_HSCROLL)
1479 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1481 /* Draw the "size-box" */
1483 if ((dwStyle & WS_VSCROLL) && (dwStyle & WS_HSCROLL))
1485 RECT r = rect;
1486 if((dwExStyle & WS_EX_LEFTSCROLLBAR) != 0)
1487 r.right = r.left + GetSystemMetrics(SM_CXVSCROLL) + 1;
1488 else
1489 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1490 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1491 if(wndPtr->dwStyle & WS_BORDER) {
1492 r.left++;
1493 r.top++;
1495 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1498 ReleaseDC( hwnd, hdc );
1502 /******************************************************************************
1504 * void NC_DoNCPaint95(
1505 * HWND hwnd,
1506 * HRGN clip,
1507 * BOOL suppress_menupaint )
1509 * Paint the non-client area for Win95 windows. The clip region is
1510 * currently ignored.
1512 * Bugs
1513 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1514 * misc/tweak.c controls/menu.c # :-)
1516 * Revision history
1517 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1518 * Original implementation
1519 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1520 * Fixed some bugs.
1521 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1522 * Streamlined window style checks.
1524 *****************************************************************************/
1526 static void NC_DoNCPaint95(
1527 HWND hwnd,
1528 HRGN clip,
1529 BOOL suppress_menupaint )
1531 HDC hdc;
1532 RECT rfuzz, rect, rectClip;
1533 BOOL active;
1534 WND *wndPtr;
1535 DWORD dwStyle, dwExStyle;
1536 WORD flags;
1537 RECT rectClient, rectWindow;
1538 int has_menu;
1540 if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return;
1541 has_menu = HAS_MENU(wndPtr);
1542 dwStyle = wndPtr->dwStyle;
1543 dwExStyle = wndPtr->dwExStyle;
1544 flags = wndPtr->flags;
1545 rectClient = wndPtr->rectClient;
1546 rectWindow = wndPtr->rectWindow;
1547 WIN_ReleasePtr( wndPtr );
1549 if ( dwStyle & WS_MINIMIZE ||
1550 !WIN_IsWindowDrawable( hwnd, 0 )) return; /* Nothing to do */
1552 active = flags & WIN_NCACTIVATED;
1554 TRACE("%p %d\n", hwnd, active );
1556 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1557 the call to GetDCEx implying that it is allowed not to use it either.
1558 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1559 will cause clipRgn to be deleted after ReleaseDC().
1560 Now, how is the "system" supposed to tell what happened?
1563 if (!(hdc = GetDCEx( hwnd, (clip > (HRGN)1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1564 ((clip > (HRGN)1) ?(DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0) ))) return;
1567 if (ExcludeVisRect16( HDC_16(hdc), rectClient.left-rectWindow.left,
1568 rectClient.top-rectWindow.top,
1569 rectClient.right-rectWindow.left,
1570 rectClient.bottom-rectWindow.top )
1571 == NULLREGION)
1573 ReleaseDC( hwnd, hdc );
1574 return;
1577 rect.top = rect.left = 0;
1578 rect.right = rectWindow.right - rectWindow.left;
1579 rect.bottom = rectWindow.bottom - rectWindow.top;
1581 if( clip > (HRGN)1 )
1582 GetRgnBox( clip, &rectClip );
1583 else
1585 clip = 0;
1586 rectClip = rect;
1589 SelectObject( hdc, SYSCOLOR_GetPen(COLOR_WINDOWFRAME) );
1591 if (HAS_STATICOUTERFRAME(dwStyle, dwExStyle)) {
1592 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1594 else if (HAS_BIGFRAME( dwStyle, dwExStyle)) {
1595 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1598 NC_DrawFrame95(hdc, &rect, active, dwStyle, dwExStyle );
1600 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
1602 RECT r = rect;
1603 if (dwExStyle & WS_EX_TOOLWINDOW) {
1604 r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
1605 rect.top += GetSystemMetrics(SM_CYSMCAPTION);
1607 else {
1608 r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
1609 rect.top += GetSystemMetrics(SM_CYCAPTION);
1611 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
1612 NC_DrawCaption95 (hdc, &r, hwnd, dwStyle,
1613 dwExStyle, active);
1616 if (has_menu)
1618 RECT r = rect;
1619 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
1621 TRACE("Calling DrawMenuBar with rect (%ld, %ld)-(%ld, %ld)\n",
1622 r.left, r.top, r.right, r.bottom);
1624 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ) + 1;
1627 TRACE("After MenuBar, rect is (%ld, %ld)-(%ld, %ld).\n",
1628 rect.left, rect.top, rect.right, rect.bottom );
1630 if (dwExStyle & WS_EX_CLIENTEDGE)
1631 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1633 /* Draw the scroll-bars */
1635 if (dwStyle & WS_VSCROLL)
1636 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
1637 if (dwStyle & WS_HSCROLL)
1638 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
1640 /* Draw the "size-box" */
1641 if ((dwStyle & WS_VSCROLL) && (dwStyle & WS_HSCROLL))
1643 RECT r = rect;
1644 if((dwExStyle & WS_EX_LEFTSCROLLBAR) != 0)
1645 r.right = r.left + GetSystemMetrics(SM_CXVSCROLL) + 1;
1646 else
1647 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
1648 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
1649 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
1652 ReleaseDC( hwnd, hdc );
1658 /***********************************************************************
1659 * NC_HandleNCPaint
1661 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1663 LONG NC_HandleNCPaint( HWND hwnd , HRGN clip)
1665 DWORD dwStyle = GetWindowLongW( hwnd, GWL_STYLE );
1667 if( dwStyle & WS_VISIBLE )
1669 if( dwStyle & WS_MINIMIZE )
1670 WINPOS_RedrawIconTitle( hwnd );
1671 else if (TWEAK_WineLook == WIN31_LOOK)
1672 NC_DoNCPaint( hwnd, clip, FALSE );
1673 else
1674 NC_DoNCPaint95( hwnd, clip, FALSE );
1676 return 0;
1680 /***********************************************************************
1681 * NC_HandleNCActivate
1683 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1685 LONG NC_HandleNCActivate( HWND hwnd, WPARAM wParam )
1687 WND* wndPtr = WIN_FindWndPtr( hwnd );
1689 /* Lotus Notes draws menu descriptions in the caption of its main
1690 * window. When it wants to restore original "system" view, it just
1691 * sends WM_NCACTIVATE message to itself. Any optimizations here in
1692 * attempt to minimize redrawings lead to a not restored caption.
1694 if (wndPtr)
1696 if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
1697 else wndPtr->flags &= ~WIN_NCACTIVATED;
1698 WIN_ReleaseWndPtr(wndPtr);
1700 if (IsIconic(hwnd)) WINPOS_RedrawIconTitle( hwnd );
1701 else if (TWEAK_WineLook == WIN31_LOOK)
1702 NC_DoNCPaint( hwnd, (HRGN)1, FALSE );
1703 else
1704 NC_DoNCPaint95( hwnd, (HRGN)1, FALSE );
1706 return TRUE;
1710 /***********************************************************************
1711 * NC_HandleSetCursor
1713 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1715 LONG NC_HandleSetCursor( HWND hwnd, WPARAM wParam, LPARAM lParam )
1717 hwnd = WIN_GetFullHandle( (HWND)wParam );
1719 switch(LOWORD(lParam))
1721 case HTERROR:
1723 WORD msg = HIWORD( lParam );
1724 if ((msg == WM_LBUTTONDOWN) || (msg == WM_MBUTTONDOWN) ||
1725 (msg == WM_RBUTTONDOWN))
1726 MessageBeep(0);
1728 break;
1730 case HTCLIENT:
1732 HCURSOR hCursor = (HCURSOR)GetClassLongA(hwnd, GCL_HCURSOR);
1733 if(hCursor) {
1734 SetCursor(hCursor);
1735 return TRUE;
1737 return FALSE;
1740 case HTLEFT:
1741 case HTRIGHT:
1742 return (LONG)SetCursor( LoadCursorA( 0, (LPSTR)IDC_SIZEWE ) );
1744 case HTTOP:
1745 case HTBOTTOM:
1746 return (LONG)SetCursor( LoadCursorA( 0, (LPSTR)IDC_SIZENS ) );
1748 case HTTOPLEFT:
1749 case HTBOTTOMRIGHT:
1750 return (LONG)SetCursor( LoadCursorA( 0, (LPSTR)IDC_SIZENWSE ) );
1752 case HTTOPRIGHT:
1753 case HTBOTTOMLEFT:
1754 return (LONG)SetCursor( LoadCursorA( 0, (LPSTR)IDC_SIZENESW ) );
1757 /* Default cursor: arrow */
1758 return (LONG)SetCursor( LoadCursorA( 0, (LPSTR)IDC_ARROW ) );
1761 /***********************************************************************
1762 * NC_GetSysPopupPos
1764 void NC_GetSysPopupPos( HWND hwnd, RECT* rect )
1766 if (IsIconic(hwnd)) GetWindowRect( hwnd, rect );
1767 else
1769 WND *wndPtr = WIN_FindWndPtr( hwnd );
1770 if (!wndPtr) return;
1772 NC_GetInsideRect( hwnd, rect );
1773 OffsetRect( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
1774 if (wndPtr->dwStyle & WS_CHILD)
1775 ClientToScreen( GetParent(hwnd), (POINT *)rect );
1776 if (TWEAK_WineLook == WIN31_LOOK) {
1777 rect->right = rect->left + GetSystemMetrics(SM_CXSIZE);
1778 rect->bottom = rect->top + GetSystemMetrics(SM_CYSIZE);
1780 else {
1781 rect->right = rect->left + GetSystemMetrics(SM_CYCAPTION) - 1;
1782 rect->bottom = rect->top + GetSystemMetrics(SM_CYCAPTION) - 1;
1784 WIN_ReleaseWndPtr( wndPtr );
1788 /***********************************************************************
1789 * NC_TrackMinMaxBox95
1791 * Track a mouse button press on the minimize or maximize box.
1793 * The big difference between 3.1 and 95 is the disabled button state.
1794 * In win95 the system button can be disabled, so it can ignore the mouse
1795 * event.
1798 static void NC_TrackMinMaxBox95( HWND hwnd, WORD wParam )
1800 MSG msg;
1801 HDC hdc = GetWindowDC( hwnd );
1802 BOOL pressed = TRUE;
1803 UINT state;
1804 DWORD wndStyle = GetWindowLongA( hwnd, GWL_STYLE);
1805 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
1807 void (*paintButton)(HWND, HDC, BOOL, BOOL);
1809 if (wParam == HTMINBUTTON)
1811 /* If the style is not present, do nothing */
1812 if (!(wndStyle & WS_MINIMIZEBOX))
1813 return;
1815 /* Check if the sysmenu item for minimize is there */
1816 state = GetMenuState(hSysMenu, SC_MINIMIZE, MF_BYCOMMAND);
1818 paintButton = &NC_DrawMinButton95;
1820 else
1822 /* If the style is not present, do nothing */
1823 if (!(wndStyle & WS_MAXIMIZEBOX))
1824 return;
1826 /* Check if the sysmenu item for maximize is there */
1827 state = GetMenuState(hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
1829 paintButton = &NC_DrawMaxButton95;
1832 SetCapture( hwnd );
1834 (*paintButton)( hwnd, hdc, TRUE, FALSE);
1836 while(1)
1838 BOOL oldstate = pressed;
1840 if (!GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST )) break;
1841 if (CallMsgFilterW( &msg, MSGF_MAX )) continue;
1843 if(msg.message == WM_LBUTTONUP)
1844 break;
1846 if(msg.message != WM_MOUSEMOVE)
1847 continue;
1849 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
1850 if (pressed != oldstate)
1851 (*paintButton)( hwnd, hdc, pressed, FALSE);
1854 if(pressed)
1855 (*paintButton)(hwnd, hdc, FALSE, FALSE);
1857 ReleaseCapture();
1858 ReleaseDC( hwnd, hdc );
1860 /* If the item minimize or maximize of the sysmenu are not there */
1861 /* or if the style is not present, do nothing */
1862 if ((!pressed) || (state == 0xFFFFFFFF))
1863 return;
1865 if (wParam == HTMINBUTTON)
1866 SendMessageA( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
1867 else
1868 SendMessageA( hwnd, WM_SYSCOMMAND,
1869 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
1872 /***********************************************************************
1873 * NC_TrackMinMaxBox
1875 * Track a mouse button press on the minimize or maximize box.
1877 static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
1879 MSG msg;
1880 HDC hdc = GetWindowDC( hwnd );
1881 BOOL pressed = TRUE;
1882 void (*paintButton)(HWND, HDC, BOOL);
1884 SetCapture( hwnd );
1886 if (wParam == HTMINBUTTON)
1887 paintButton = &NC_DrawMinButton;
1888 else
1889 paintButton = &NC_DrawMaxButton;
1891 (*paintButton)( hwnd, hdc, TRUE);
1893 while(1)
1895 BOOL oldstate = pressed;
1897 if (!GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST )) break;
1898 if (CallMsgFilterW( &msg, MSGF_MAX )) continue;
1900 if(msg.message == WM_LBUTTONUP)
1901 break;
1903 if(msg.message != WM_MOUSEMOVE)
1904 continue;
1906 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
1907 if (pressed != oldstate)
1908 (*paintButton)( hwnd, hdc, pressed);
1911 if(pressed)
1912 (*paintButton)( hwnd, hdc, FALSE);
1914 ReleaseCapture();
1915 ReleaseDC( hwnd, hdc );
1917 if (!pressed) return;
1919 if (wParam == HTMINBUTTON)
1920 SendMessageA( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
1921 else
1922 SendMessageA( hwnd, WM_SYSCOMMAND,
1923 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
1927 /***********************************************************************
1928 * NC_TrackCloseButton95
1930 * Track a mouse button press on the Win95 close button.
1932 static void
1933 NC_TrackCloseButton95 (HWND hwnd, WORD wParam)
1935 MSG msg;
1936 HDC hdc;
1937 BOOL pressed = TRUE;
1938 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
1939 UINT state;
1941 if(hSysMenu == 0)
1942 return;
1944 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
1946 /* If the item close of the sysmenu is disabled or not there do nothing */
1947 if((state & MF_DISABLED) || (state & MF_GRAYED) || (state == 0xFFFFFFFF))
1948 return;
1950 hdc = GetWindowDC( hwnd );
1952 SetCapture( hwnd );
1954 NC_DrawCloseButton95 (hwnd, hdc, TRUE, FALSE);
1956 while(1)
1958 BOOL oldstate = pressed;
1960 if (!GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST )) break;
1961 if (CallMsgFilterW( &msg, MSGF_MAX )) continue;
1963 if(msg.message == WM_LBUTTONUP)
1964 break;
1966 if(msg.message != WM_MOUSEMOVE)
1967 continue;
1969 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
1970 if (pressed != oldstate)
1971 NC_DrawCloseButton95 (hwnd, hdc, pressed, FALSE);
1974 if(pressed)
1975 NC_DrawCloseButton95 (hwnd, hdc, FALSE, FALSE);
1977 ReleaseCapture();
1978 ReleaseDC( hwnd, hdc );
1979 if (!pressed) return;
1981 SendMessageA( hwnd, WM_SYSCOMMAND, SC_CLOSE, MAKELONG(msg.pt.x,msg.pt.y) );
1985 /***********************************************************************
1986 * NC_TrackScrollBar
1988 * Track a mouse button press on the horizontal or vertical scroll-bar.
1990 static void NC_TrackScrollBar( HWND hwnd, WPARAM wParam, POINT pt )
1992 INT scrollbar;
1994 if ((wParam & 0xfff0) == SC_HSCROLL)
1996 if ((wParam & 0x0f) != HTHSCROLL) return;
1997 scrollbar = SB_HORZ;
1999 else /* SC_VSCROLL */
2001 if ((wParam & 0x0f) != HTVSCROLL) return;
2002 scrollbar = SB_VERT;
2004 SCROLL_TrackScrollBar( hwnd, scrollbar, pt );
2008 /***********************************************************************
2009 * NC_HandleNCLButtonDown
2011 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
2013 LONG NC_HandleNCLButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam )
2015 LONG style = GetWindowLongA( hwnd, GWL_STYLE );
2017 switch(wParam) /* Hit test */
2019 case HTCAPTION:
2021 HWND top = GetAncestor( hwnd, GA_ROOT );
2023 if (FOCUS_MouseActivate( top ) || (GetActiveWindow() == top))
2024 SendMessageW( hwnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
2025 break;
2028 case HTSYSMENU:
2029 if( style & WS_SYSMENU )
2031 if( !(style & WS_MINIMIZE) )
2033 HDC hDC = GetWindowDC(hwnd);
2034 if (TWEAK_WineLook == WIN31_LOOK)
2035 NC_DrawSysButton( hwnd, hDC, TRUE );
2036 else
2037 NC_DrawSysButton95( hwnd, hDC, TRUE );
2038 ReleaseDC( hwnd, hDC );
2040 SendMessageW( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
2042 break;
2044 case HTMENU:
2045 SendMessageW( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam );
2046 break;
2048 case HTHSCROLL:
2049 SendMessageW( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
2050 break;
2052 case HTVSCROLL:
2053 SendMessageW( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
2054 break;
2056 case HTMINBUTTON:
2057 case HTMAXBUTTON:
2058 if (TWEAK_WineLook == WIN31_LOOK)
2059 NC_TrackMinMaxBox( hwnd, wParam );
2060 else
2061 NC_TrackMinMaxBox95( hwnd, wParam );
2062 break;
2064 case HTCLOSE:
2065 if (TWEAK_WineLook >= WIN95_LOOK)
2066 NC_TrackCloseButton95 (hwnd, wParam);
2067 break;
2069 case HTLEFT:
2070 case HTRIGHT:
2071 case HTTOP:
2072 case HTTOPLEFT:
2073 case HTTOPRIGHT:
2074 case HTBOTTOM:
2075 case HTBOTTOMLEFT:
2076 case HTBOTTOMRIGHT:
2077 /* Old comment:
2078 * "make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU"
2079 * This was previously done by setting wParam=SC_SIZE + wParam - 2
2081 /* But that is not what WinNT does. Instead it sends this. This
2082 * is easy to differentiate from HTSYSMENU, because HTSYSMENU adds
2083 * SC_MOUSEMENU into wParam.
2085 SendMessageW( hwnd, WM_SYSCOMMAND, SC_SIZE + wParam - (HTLEFT-WMSZ_LEFT), lParam);
2086 break;
2088 case HTBORDER:
2089 break;
2091 return 0;
2095 /***********************************************************************
2096 * NC_HandleNCLButtonDblClk
2098 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2100 LONG NC_HandleNCLButtonDblClk( HWND hwnd, WPARAM wParam, LPARAM lParam )
2103 * if this is an icon, send a restore since we are handling
2104 * a double click
2106 if (IsIconic(hwnd))
2108 SendMessageW( hwnd, WM_SYSCOMMAND, SC_RESTORE, lParam );
2109 return 0;
2112 switch(wParam) /* Hit test */
2114 case HTCAPTION:
2115 /* stop processing if WS_MAXIMIZEBOX is missing */
2116 if (GetWindowLongA( hwnd, GWL_STYLE ) & WS_MAXIMIZEBOX)
2117 SendMessageW( hwnd, WM_SYSCOMMAND,
2118 IsZoomed(hwnd) ? SC_RESTORE : SC_MAXIMIZE, lParam );
2119 break;
2121 case HTSYSMENU:
2122 if (!(GetClassLongW(hwnd, GCL_STYLE) & CS_NOCLOSE))
2123 SendMessageW( hwnd, WM_SYSCOMMAND, SC_CLOSE, lParam );
2124 break;
2126 case HTHSCROLL:
2127 SendMessageW( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
2128 break;
2130 case HTVSCROLL:
2131 SendMessageW( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
2132 break;
2134 return 0;
2138 /***********************************************************************
2139 * NC_HandleSysCommand
2141 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2143 LONG NC_HandleSysCommand( HWND hwnd, WPARAM wParam, LPARAM lParam )
2145 TRACE("Handling WM_SYSCOMMAND %x %lx\n", wParam, lParam );
2147 switch (wParam & 0xfff0)
2149 case SC_SIZE:
2150 case SC_MOVE:
2151 if (USER_Driver.pSysCommandSizeMove)
2152 USER_Driver.pSysCommandSizeMove( hwnd, wParam );
2153 break;
2155 case SC_MINIMIZE:
2156 if (hwnd == GetForegroundWindow())
2157 ShowOwnedPopups(hwnd,FALSE);
2158 ShowWindow( hwnd, SW_MINIMIZE );
2159 break;
2161 case SC_MAXIMIZE:
2162 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2163 ShowOwnedPopups(hwnd,TRUE);
2164 ShowWindow( hwnd, SW_MAXIMIZE );
2165 break;
2167 case SC_RESTORE:
2168 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2169 ShowOwnedPopups(hwnd,TRUE);
2170 ShowWindow( hwnd, SW_RESTORE );
2171 break;
2173 case SC_CLOSE:
2174 return SendMessageA( hwnd, WM_CLOSE, 0, 0 );
2176 case SC_VSCROLL:
2177 case SC_HSCROLL:
2179 POINT pt;
2180 pt.x = (short)LOWORD(lParam);
2181 pt.y = (short)HIWORD(lParam);
2182 NC_TrackScrollBar( hwnd, wParam, pt );
2184 break;
2186 case SC_MOUSEMENU:
2188 POINT pt;
2189 pt.x = (short)LOWORD(lParam);
2190 pt.y = (short)HIWORD(lParam);
2191 MENU_TrackMouseMenuBar( hwnd, wParam & 0x000F, pt );
2193 break;
2195 case SC_KEYMENU:
2196 MENU_TrackKbdMenuBar( hwnd, wParam, LOWORD(lParam) );
2197 break;
2199 case SC_TASKLIST:
2200 WinExec( "taskman.exe", SW_SHOWNORMAL );
2201 break;
2203 case SC_SCREENSAVE:
2204 if (wParam == SC_ABOUTWINE)
2206 HMODULE hmodule = LoadLibraryA( "shell32.dll" );
2207 if (hmodule)
2209 FARPROC aboutproc = GetProcAddress( hmodule, "ShellAboutA" );
2210 if (aboutproc) aboutproc( hwnd, PACKAGE_NAME, PACKAGE_STRING, 0 );
2211 FreeLibrary( hmodule );
2214 else
2215 if (wParam == SC_PUTMARK)
2216 TRACE_(shell)("Mark requested by user\n");
2217 break;
2219 case SC_HOTKEY:
2220 case SC_ARRANGE:
2221 case SC_NEXTWINDOW:
2222 case SC_PREVWINDOW:
2223 FIXME("unimplemented!\n");
2224 break;
2226 return 0;
2229 /*************************************************************
2230 * NC_DrawGrayButton
2232 * Stub for the grayed button of the caption
2234 *************************************************************/
2236 BOOL NC_DrawGrayButton(HDC hdc, int x, int y)
2238 HBITMAP hMaskBmp;
2239 HDC hdcMask;
2240 HBRUSH hOldBrush;
2242 hMaskBmp = CreateBitmap (12, 10, 1, 1, lpGrayMask);
2244 if(hMaskBmp == 0)
2245 return FALSE;
2247 hdcMask = CreateCompatibleDC (0);
2248 SelectObject (hdcMask, hMaskBmp);
2250 /* Draw the grayed bitmap using the mask */
2251 hOldBrush = SelectObject (hdc, (HGDIOBJ)RGB(128, 128, 128));
2252 BitBlt (hdc, x, y, 12, 10,
2253 hdcMask, 0, 0, 0xB8074A);
2255 /* Clean up */
2256 SelectObject (hdc, hOldBrush);
2257 DeleteObject(hMaskBmp);
2258 DeleteDC (hdcMask);
2260 return TRUE;