blob: 354e0eb30fbc19f2e74b3b86b071dd454d791efe [file] [log] [blame]
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001/*
2 * Non-client area window functions
3 *
4 * Copyright 1994 Alexandre Julliard
Alexandre Julliard234bc241994-12-10 13:02:28 +00005 *
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00006 * 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.
10 *
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.
15 *
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
Alexandre Julliard7cbe6571995-01-09 18:21:16 +000019 */
Alexandre Julliardcdd09231994-01-12 11:12:51 +000020
Alexandre Julliarddaa28862002-04-11 21:54:01 +000021#include "config.h"
22
Jeremy Whited3e22d92000-02-10 19:03:02 +000023#include "windef.h"
24#include "wingdi.h"
Michael Veksler9d14a001999-05-08 12:40:24 +000025#include "wine/winuser16.h"
Michael Stefaniucec5612e2002-10-30 23:45:38 +000026#include "wownt32.h"
Alexandre Julliardcdd09231994-01-12 11:12:51 +000027#include "win.h"
Alexandre Julliarddba420a1994-02-02 06:48:31 +000028#include "user.h"
Alex Korobka4f1ac051999-03-28 09:37:57 +000029#include "dce.h"
Alexandre Julliard91222da2000-12-10 23:01:33 +000030#include "controls.h"
Alexandre Julliard44ed71f1997-12-21 19:17:50 +000031#include "cursoricon.h"
Alexandre Julliard234bc241994-12-10 13:02:28 +000032#include "winpos.h"
Alexandre Julliard234bc241994-12-10 13:02:28 +000033#include "nonclient.h"
Marcus Meissner317af321999-02-17 13:51:06 +000034#include "shellapi.h"
Pascal Lessardd814bb61999-07-31 13:02:02 +000035#include "bitmap.h"
Michael Stefaniucec5612e2002-10-30 23:45:38 +000036#include "wine/debug.h"
Alexandre Julliardcdd09231994-01-12 11:12:51 +000037
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000038WINE_DEFAULT_DEBUG_CHANNEL(nonclient);
39WINE_DECLARE_DEBUG_CHANNEL(shell);
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000040
Pascal Lessardd814bb61999-07-31 13:02:02 +000041BOOL NC_DrawGrayButton(HDC hdc, int x, int y);
42
Alexandre Julliardc1d35cc2001-01-24 19:47:57 +000043static HBITMAP hbitmapClose;
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +000044
Alexandre Julliardc1d35cc2001-01-24 19:47:57 +000045static const BYTE lpGrayMask[] = { 0xAA, 0xA0,
Vincent Béron9a624912002-05-31 23:06:46 +000046 0x55, 0x50,
Pascal Lessardd814bb61999-07-31 13:02:02 +000047 0xAA, 0xA0,
Vincent Béron9a624912002-05-31 23:06:46 +000048 0x55, 0x50,
Pascal Lessardd814bb61999-07-31 13:02:02 +000049 0xAA, 0xA0,
Vincent Béron9a624912002-05-31 23:06:46 +000050 0x55, 0x50,
Pascal Lessardd814bb61999-07-31 13:02:02 +000051 0xAA, 0xA0,
Vincent Béron9a624912002-05-31 23:06:46 +000052 0x55, 0x50,
Pascal Lessardd814bb61999-07-31 13:02:02 +000053 0xAA, 0xA0,
54 0x55, 0x50};
55
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +000056#define SC_ABOUTWINE (SC_SCREENSAVE+1)
Uwe Bonnes37007771998-11-01 15:07:24 +000057#define SC_PUTMARK (SC_SCREENSAVE+2)
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +000058
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +000059 /* Some useful macros */
60#define HAS_DLGFRAME(style,exStyle) \
Alexandre Julliard0c126c71996-02-18 18:44:41 +000061 (((exStyle) & WS_EX_DLGMODALFRAME) || \
Ove Kaaven60c78f11999-07-03 15:40:29 +000062 (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +000063
Ove Kaaven60c78f11999-07-03 15:40:29 +000064#define HAS_THICKFRAME(style,exStyle) \
Alexandre Julliard0c126c71996-02-18 18:44:41 +000065 (((style) & WS_THICKFRAME) && \
Abey George48c6eb51999-09-03 12:33:40 +000066 !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +000067
Ove Kaaven60c78f11999-07-03 15:40:29 +000068#define HAS_THINFRAME(style) \
69 (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +000070
Ove Kaaven60c78f11999-07-03 15:40:29 +000071#define HAS_BIGFRAME(style,exStyle) \
72 (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
73 ((exStyle) & WS_EX_DLGMODALFRAME))
Gerard Patel5773dad1999-06-12 14:45:56 +000074
Bill Medlandcbfbf2a2001-07-20 18:36:49 +000075#define HAS_STATICOUTERFRAME(style,exStyle) \
76 (((exStyle) & (WS_EX_STATICEDGE|WS_EX_DLGMODALFRAME)) == \
77 WS_EX_STATICEDGE)
78
Ove Kaaven60c78f11999-07-03 15:40:29 +000079#define HAS_ANYFRAME(style,exStyle) \
80 (((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
81 ((exStyle) & WS_EX_DLGMODALFRAME) || \
82 !((style) & (WS_CHILD | WS_POPUP)))
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +000083
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +000084#define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0))
85
Sylvain St-Germain00bf3811999-07-24 12:11:22 +000086
87/***********************************************************************
Alexandre Julliardcdd09231994-01-12 11:12:51 +000088 * NC_AdjustRect
89 *
90 * Compute the size of the window rectangle from the size of the
91 * client rectangle.
92 */
Alexandre Julliard3abeae82001-05-09 17:21:04 +000093static void NC_AdjustRect( LPRECT rect, DWORD style, BOOL menu, DWORD exStyle )
Alexandre Julliardcdd09231994-01-12 11:12:51 +000094{
Alexandre Julliardd30dfd21998-09-27 18:28:36 +000095 if (TWEAK_WineLook > WIN31_LOOK)
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +000096 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
Alexandre Julliardd37eb361997-07-20 16:23:21 +000097
Alexandre Julliardbf9130a1996-10-13 17:45:47 +000098 if(style & WS_ICONIC) return;
Alexandre Julliard0c126c71996-02-18 18:44:41 +000099
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000100 if (HAS_THICKFRAME( style, exStyle ))
101 InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
102 else if (HAS_DLGFRAME( style, exStyle ))
103 InflateRect( rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
104 else if (HAS_THINFRAME( style ))
105 InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
106
107 if ((style & WS_CAPTION) == WS_CAPTION)
108 rect->top -= GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
109
Marcus Meissnerddca3151999-05-22 11:33:23 +0000110 if (menu) rect->top -= GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYBORDER);
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000111
Alexandre Julliardf90efa91998-06-14 15:24:15 +0000112 if (style & WS_VSCROLL) {
Marcus Meissnerddca3151999-05-22 11:33:23 +0000113 rect->right += GetSystemMetrics(SM_CXVSCROLL) - 1;
Ove Kaaven60c78f11999-07-03 15:40:29 +0000114 if(!HAS_ANYFRAME( style, exStyle ))
Alexandre Julliardf90efa91998-06-14 15:24:15 +0000115 rect->right++;
116 }
117
118 if (style & WS_HSCROLL) {
Marcus Meissnerddca3151999-05-22 11:33:23 +0000119 rect->bottom += GetSystemMetrics(SM_CYHSCROLL) - 1;
Ove Kaaven60c78f11999-07-03 15:40:29 +0000120 if(!HAS_ANYFRAME( style, exStyle ))
Alexandre Julliardf90efa91998-06-14 15:24:15 +0000121 rect->bottom++;
122 }
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000123}
124
125
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000126/******************************************************************************
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000127 * NC_AdjustRectOuter95
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000128 *
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000129 * Computes the size of the "outside" parts of the window based on the
130 * parameters of the client area.
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000131 *
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000132 + PARAMS
133 * LPRECT16 rect
134 * DWORD style
Patrik Stridvall2d6457c2000-03-28 20:22:59 +0000135 * BOOL menu
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000136 * DWORD exStyle
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000137 *
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000138 * NOTES
139 * "Outer" parts of a window means the whole window frame, caption and
140 * menu bar. It does not include "inner" parts of the frame like client
141 * edge, static edge or scroll bars.
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000142 *
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000143 * Revision history
144 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
145 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
146 *
147 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
148 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
149 * NC_AdjustRectInner95 and added handling of Win95 styles.
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000150 *
Ove Kaaven60c78f11999-07-03 15:40:29 +0000151 * 28-Jul-1999 Ove Kåven (ovek@arcticnet.no)
152 * Streamlined window style checks.
153 *
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000154 *****************************************************************************/
155
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000156static void
Alexandre Julliard3abeae82001-05-09 17:21:04 +0000157NC_AdjustRectOuter95 (LPRECT rect, DWORD style, BOOL menu, DWORD exStyle)
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000158{
Bill Medlandcbfbf2a2001-07-20 18:36:49 +0000159 int adjust;
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000160 if(style & WS_ICONIC) return;
161
Vincent Béron9a624912002-05-31 23:06:46 +0000162 if ((exStyle & (WS_EX_STATICEDGE|WS_EX_DLGMODALFRAME)) ==
Bill Medlandcbfbf2a2001-07-20 18:36:49 +0000163 WS_EX_STATICEDGE)
164 {
165 adjust = 1; /* for the outer frame always present */
166 }
167 else
168 {
169 adjust = 0;
170 if ((exStyle & WS_EX_DLGMODALFRAME) ||
171 (style & (WS_THICKFRAME|WS_DLGFRAME))) adjust = 2; /* outer */
172 }
173 if (style & WS_THICKFRAME)
174 adjust += ( GetSystemMetrics (SM_CXFRAME)
175 - GetSystemMetrics (SM_CXDLGFRAME)); /* The resize border */
Vincent Béron9a624912002-05-31 23:06:46 +0000176 if ((style & (WS_BORDER|WS_DLGFRAME)) ||
Bill Medlandcbfbf2a2001-07-20 18:36:49 +0000177 (exStyle & WS_EX_DLGMODALFRAME))
178 adjust++; /* The other border */
179
180 InflateRect (rect, adjust, adjust);
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000181
182 if ((style & WS_CAPTION) == WS_CAPTION)
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000183 {
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000184 if (exStyle & WS_EX_TOOLWINDOW)
185 rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
Ove Kaaven60c78f11999-07-03 15:40:29 +0000186 else
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000187 rect->top -= GetSystemMetrics(SM_CYCAPTION);
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000188 }
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000189 if (menu) rect->top -= GetSystemMetrics(SM_CYMENU);
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000190}
191
192
193/******************************************************************************
194 * NC_AdjustRectInner95
195 *
196 * Computes the size of the "inside" part of the window based on the
197 * parameters of the client area.
198 *
199 + PARAMS
200 * LPRECT16 rect
201 * DWORD style
202 * DWORD exStyle
203 *
204 * NOTES
205 * "Inner" part of a window means the window frame inside of the flat
206 * window frame. It includes the client edge, the static edge and the
207 * scroll bars.
208 *
209 * Revision history
210 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
211 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
212 *
213 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
214 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
215 * NC_AdjustRectInner95 and added handling of Win95 styles.
216 *
217 *****************************************************************************/
218
219static void
Alexandre Julliard3abeae82001-05-09 17:21:04 +0000220NC_AdjustRectInner95 (LPRECT rect, DWORD style, DWORD exStyle)
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000221{
222 if(style & WS_ICONIC) return;
223
224 if (exStyle & WS_EX_CLIENTEDGE)
Alexandre Julliard3abeae82001-05-09 17:21:04 +0000225 InflateRect(rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000226
Alberto Massaribf9390e2003-01-14 23:41:01 +0000227 if (style & WS_VSCROLL)
228 {
229 if((exStyle & WS_EX_LEFTSCROLLBAR) != 0)
230 rect->left -= GetSystemMetrics(SM_CXVSCROLL);
231 else
232 rect->right += GetSystemMetrics(SM_CXVSCROLL);
233 }
Marcus Meissnerddca3151999-05-22 11:33:23 +0000234 if (style & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000235}
236
237
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000238
239static HICON NC_IconForWindow( HWND hwnd )
240{
241 HICON hIcon = (HICON) GetClassLongA( hwnd, GCL_HICONSM );
242 if (!hIcon) hIcon = (HICON) GetClassLongA( hwnd, GCL_HICON );
243
244 /* If there is no hIcon specified and this is a modal dialog,
245 * get the default one.
246 */
247 if (!hIcon && (GetWindowLongA( hwnd, GWL_STYLE ) & DS_MODALFRAME))
248 hIcon = LoadImageA(0, IDI_WINLOGOA, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
249 return hIcon;
250}
251
Alexandre Julliarde658d821997-11-30 17:45:40 +0000252/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +0000253 * DrawCaption (USER32.@) Draws a caption bar
Eric Kohl8e517b51998-10-11 13:06:35 +0000254 *
255 * PARAMS
256 * hwnd [I]
257 * hdc [I]
258 * lpRect [I]
259 * uFlags [I]
260 *
Eric Kohld0b79c01998-10-24 10:45:42 +0000261 * RETURNS
262 * Success:
263 * Failure:
Eric Kohl8e517b51998-10-11 13:06:35 +0000264 */
265
Alexandre Julliarda3960291999-02-26 11:11:13 +0000266BOOL WINAPI
267DrawCaption (HWND hwnd, HDC hdc, const RECT *lpRect, UINT uFlags)
Eric Kohl8e517b51998-10-11 13:06:35 +0000268{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000269 return DrawCaptionTempA (hwnd, hdc, lpRect, 0, 0, NULL, uFlags & 0x1F);
Eric Kohl8e517b51998-10-11 13:06:35 +0000270}
271
272
273/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +0000274 * DrawCaptionTempA (USER32.@)
Eric Kohl8e517b51998-10-11 13:06:35 +0000275 */
Alexandre Julliard193cf502002-01-01 00:24:30 +0000276BOOL WINAPI DrawCaptionTempA (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
277 HICON hIcon, LPCSTR str, UINT uFlags)
278{
279 LPWSTR strW;
280 INT len;
281 BOOL ret = FALSE;
Eric Kohl8e517b51998-10-11 13:06:35 +0000282
Alexandre Julliard193cf502002-01-01 00:24:30 +0000283 if (!(uFlags & DC_TEXT) || !str)
284 return DrawCaptionTempW( hwnd, hdc, rect, hFont, hIcon, NULL, uFlags );
285
286 len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
287 if ((strW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
288 {
289 MultiByteToWideChar( CP_ACP, 0, str, -1, strW, len );
290 ret = DrawCaptionTempW (hwnd, hdc, rect, hFont, hIcon, strW, uFlags);
291 HeapFree( GetProcessHeap (), 0, strW );
292 }
293 return ret;
294}
295
296
297/***********************************************************************
298 * DrawCaptionTempW (USER32.@)
299 */
300BOOL WINAPI DrawCaptionTempW (HWND hwnd, HDC hdc, const RECT *rect, HFONT hFont,
301 HICON hIcon, LPCWSTR str, UINT uFlags)
Eric Kohl8e517b51998-10-11 13:06:35 +0000302{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000303 RECT rc = *rect;
Eric Kohl8e517b51998-10-11 13:06:35 +0000304
Alexandre Julliardaff7dda2002-11-22 21:22:14 +0000305 TRACE("(%p,%p,%p,%p,%p,%s,%08x)\n",
Alexandre Julliard193cf502002-01-01 00:24:30 +0000306 hwnd, hdc, rect, hFont, hIcon, debugstr_w(str), uFlags);
Eric Kohl8e517b51998-10-11 13:06:35 +0000307
308 /* drawing background */
309 if (uFlags & DC_INBUTTON) {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000310 FillRect (hdc, &rc, GetSysColorBrush (COLOR_3DFACE));
Eric Kohl8e517b51998-10-11 13:06:35 +0000311
312 if (uFlags & DC_ACTIVE) {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000313 HBRUSH hbr = SelectObject (hdc, CACHE_GetPattern55AABrush ());
314 PatBlt (hdc, rc.left, rc.top,
Eric Kohl8e517b51998-10-11 13:06:35 +0000315 rc.right-rc.left, rc.bottom-rc.top, 0xFA0089);
Alexandre Julliarda3960291999-02-26 11:11:13 +0000316 SelectObject (hdc, hbr);
Eric Kohl8e517b51998-10-11 13:06:35 +0000317 }
318 }
319 else {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000320 FillRect (hdc, &rc, GetSysColorBrush ((uFlags & DC_ACTIVE) ?
Eric Kohl8e517b51998-10-11 13:06:35 +0000321 COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
322 }
323
324
325 /* drawing icon */
326 if ((uFlags & DC_ICON) && !(uFlags & DC_SMALLCAP)) {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000327 POINT pt;
Eric Kohl8e517b51998-10-11 13:06:35 +0000328
329 pt.x = rc.left + 2;
Marcus Meissnerddca3151999-05-22 11:33:23 +0000330 pt.y = (rc.bottom + rc.top - GetSystemMetrics(SM_CYSMICON)) / 2;
Eric Kohl8e517b51998-10-11 13:06:35 +0000331
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000332 if (!hIcon) hIcon = NC_IconForWindow(hwnd);
333 DrawIconEx (hdc, pt.x, pt.y, hIcon, GetSystemMetrics(SM_CXSMICON),
334 GetSystemMetrics(SM_CYSMICON), 0, 0, DI_NORMAL);
Eric Kohl8e517b51998-10-11 13:06:35 +0000335 rc.left += (rc.bottom - rc.top);
336 }
337
338 /* drawing text */
339 if (uFlags & DC_TEXT) {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000340 HFONT hOldFont;
Eric Kohl8e517b51998-10-11 13:06:35 +0000341
342 if (uFlags & DC_INBUTTON)
Alexandre Julliarda3960291999-02-26 11:11:13 +0000343 SetTextColor (hdc, GetSysColor (COLOR_BTNTEXT));
Eric Kohl8e517b51998-10-11 13:06:35 +0000344 else if (uFlags & DC_ACTIVE)
Alexandre Julliarda3960291999-02-26 11:11:13 +0000345 SetTextColor (hdc, GetSysColor (COLOR_CAPTIONTEXT));
Eric Kohl8e517b51998-10-11 13:06:35 +0000346 else
Alexandre Julliarda3960291999-02-26 11:11:13 +0000347 SetTextColor (hdc, GetSysColor (COLOR_INACTIVECAPTIONTEXT));
Eric Kohl8e517b51998-10-11 13:06:35 +0000348
Alexandre Julliarda3960291999-02-26 11:11:13 +0000349 SetBkMode (hdc, TRANSPARENT);
Eric Kohl8e517b51998-10-11 13:06:35 +0000350
351 if (hFont)
Alexandre Julliarda3960291999-02-26 11:11:13 +0000352 hOldFont = SelectObject (hdc, hFont);
Eric Kohl8e517b51998-10-11 13:06:35 +0000353 else {
Matthew Davison3f174162002-11-24 22:13:26 +0000354 NONCLIENTMETRICSW nclm;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000355 HFONT hNewFont;
Rein Klazes6f9b6862002-12-16 22:12:11 +0000356 nclm.cbSize = sizeof(NONCLIENTMETRICSW);
Matthew Davison3f174162002-11-24 22:13:26 +0000357 SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
358 hNewFont = CreateFontIndirectW ((uFlags & DC_SMALLCAP) ?
Eric Kohl8e517b51998-10-11 13:06:35 +0000359 &nclm.lfSmCaptionFont : &nclm.lfCaptionFont);
Alexandre Julliarda3960291999-02-26 11:11:13 +0000360 hOldFont = SelectObject (hdc, hNewFont);
Eric Kohl8e517b51998-10-11 13:06:35 +0000361 }
362
363 if (str)
Alexandre Julliard193cf502002-01-01 00:24:30 +0000364 DrawTextW (hdc, str, -1, &rc,
Eric Kohl8e517b51998-10-11 13:06:35 +0000365 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
366 else {
Alexandre Julliard193cf502002-01-01 00:24:30 +0000367 WCHAR szText[128];
Alexandre Julliarda3960291999-02-26 11:11:13 +0000368 INT nLen;
Alexandre Julliard193cf502002-01-01 00:24:30 +0000369 nLen = GetWindowTextW (hwnd, szText, 128);
370 DrawTextW (hdc, szText, nLen, &rc,
Eric Kohl8e517b51998-10-11 13:06:35 +0000371 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT);
372 }
373
374 if (hFont)
Alexandre Julliarda3960291999-02-26 11:11:13 +0000375 SelectObject (hdc, hOldFont);
Eric Kohl8e517b51998-10-11 13:06:35 +0000376 else
Alexandre Julliarda3960291999-02-26 11:11:13 +0000377 DeleteObject (SelectObject (hdc, hOldFont));
Eric Kohl8e517b51998-10-11 13:06:35 +0000378 }
379
380 /* drawing focus ??? */
381 if (uFlags & 0x2000)
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000382 FIXME("undocumented flag (0x2000)!\n");
Eric Kohl8e517b51998-10-11 13:06:35 +0000383
384 return 0;
385}
386
387
388/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +0000389 * AdjustWindowRect (USER.102)
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000390 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000391BOOL16 WINAPI AdjustWindowRect16( LPRECT16 rect, DWORD style, BOOL16 menu )
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000392{
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000393 return AdjustWindowRectEx16( rect, style, menu, 0 );
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000394}
395
396
397/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +0000398 * AdjustWindowRect (USER32.@)
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000399 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000400BOOL WINAPI AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000401{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000402 return AdjustWindowRectEx( rect, style, menu, 0 );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000403}
404
405
406/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +0000407 * AdjustWindowRectEx (USER.454)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000408 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000409BOOL16 WINAPI AdjustWindowRectEx16( LPRECT16 rect, DWORD style,
410 BOOL16 menu, DWORD exStyle )
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000411{
Alexandre Julliard3abeae82001-05-09 17:21:04 +0000412 RECT rect32;
413 BOOL ret;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000414
Alexandre Julliard3abeae82001-05-09 17:21:04 +0000415 CONV_RECT16TO32( rect, &rect32 );
416 ret = AdjustWindowRectEx( &rect32, style, menu, exStyle );
417 CONV_RECT32TO16( &rect32, rect );
418 return ret;
419}
420
421
422/***********************************************************************
423 * AdjustWindowRectEx (USER32.@)
424 */
425BOOL WINAPI AdjustWindowRectEx( LPRECT rect, DWORD style, BOOL menu, DWORD exStyle )
426{
427 /* Correct the window style */
Alexandre Julliard84c70f51997-05-09 08:40:27 +0000428 style &= (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME | WS_CHILD);
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000429 exStyle &= (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE |
Alexandre Julliard3abeae82001-05-09 17:21:04 +0000430 WS_EX_STATICEDGE | WS_EX_TOOLWINDOW);
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000431 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
432
Dan Kegel0fd521f2003-01-08 21:09:25 +0000433 TRACE("(%ld,%ld)-(%ld,%ld) %08lx %d %08lx\n",
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000434 rect->left, rect->top, rect->right, rect->bottom,
435 style, menu, exStyle );
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000436
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000437 if (TWEAK_WineLook == WIN31_LOOK)
Alexandre Julliard3abeae82001-05-09 17:21:04 +0000438 NC_AdjustRect( rect, style, menu, exStyle );
439 else
440 {
441 NC_AdjustRectOuter95( rect, style, menu, exStyle );
442 NC_AdjustRectInner95( rect, style, exStyle );
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000443 }
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000444 return TRUE;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000445}
446
447
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000448/***********************************************************************
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000449 * NC_HandleNCCalcSize
450 *
451 * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
452 */
Alexandre Julliardde424282001-08-10 22:51:42 +0000453LONG NC_HandleNCCalcSize( HWND hwnd, RECT *winRect )
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000454{
Alexandre Julliard3abeae82001-05-09 17:21:04 +0000455 RECT tmpRect = { 0, 0, 0, 0 };
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000456 LONG result = 0;
Alexandre Julliardde424282001-08-10 22:51:42 +0000457 LONG cls_style = GetClassLongA(hwnd, GCL_STYLE);
458 LONG style = GetWindowLongA( hwnd, GWL_STYLE );
459 LONG exStyle = GetWindowLongA( hwnd, GWL_EXSTYLE );
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000460
Alexandre Julliardde424282001-08-10 22:51:42 +0000461 if (cls_style & CS_VREDRAW) result |= WVR_VREDRAW;
462 if (cls_style & CS_HREDRAW) result |= WVR_HREDRAW;
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000463
Alexandre Julliardde424282001-08-10 22:51:42 +0000464 if (!IsIconic(hwnd))
465 {
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000466 if (TWEAK_WineLook == WIN31_LOOK)
Alexandre Julliardde424282001-08-10 22:51:42 +0000467 NC_AdjustRect( &tmpRect, style, FALSE, exStyle );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000468 else
Alexandre Julliardde424282001-08-10 22:51:42 +0000469 NC_AdjustRectOuter95( &tmpRect, style, FALSE, exStyle );
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000470
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000471 winRect->left -= tmpRect.left;
472 winRect->top -= tmpRect.top;
473 winRect->right -= tmpRect.right;
474 winRect->bottom -= tmpRect.bottom;
475
Alexandre Julliardde424282001-08-10 22:51:42 +0000476 if (!(style & WS_CHILD) && GetMenu(hwnd))
477 {
Dan Kegel0fd521f2003-01-08 21:09:25 +0000478 TRACE("Calling GetMenuBarHeight with hwnd %p, width %ld, at (%ld, %ld).\n",
Alexandre Julliardaff7dda2002-11-22 21:22:14 +0000479 hwnd, winRect->right - winRect->left, -tmpRect.left, -tmpRect.top );
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000480
481 winRect->top +=
Alexandre Julliardde424282001-08-10 22:51:42 +0000482 MENU_GetMenuBarHeight( hwnd,
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000483 winRect->right - winRect->left,
484 -tmpRect.left, -tmpRect.top ) + 1;
485 }
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000486
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000487 if (TWEAK_WineLook > WIN31_LOOK) {
Alexandre Julliard3abeae82001-05-09 17:21:04 +0000488 SetRect(&tmpRect, 0, 0, 0, 0);
Alexandre Julliardde424282001-08-10 22:51:42 +0000489 NC_AdjustRectInner95 (&tmpRect, style, exStyle);
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000490 winRect->left -= tmpRect.left;
491 winRect->top -= tmpRect.top;
492 winRect->right -= tmpRect.right;
493 winRect->bottom -= tmpRect.bottom;
494 }
Mike McCormacka2bdade2000-09-12 23:37:57 +0000495
496 if (winRect->top > winRect->bottom)
497 winRect->bottom = winRect->top;
498
499 if (winRect->left > winRect->right)
500 winRect->right = winRect->left;
Alexandre Julliard2d159fb1994-07-15 16:04:31 +0000501 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000502 return result;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000503}
504
505
506/***********************************************************************
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000507 * NC_GetInsideRect
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000508 *
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000509 * Get the 'inside' rectangle of a window, i.e. the whole window rectangle
510 * but without the borders (if any).
511 * The rectangle is in window coordinates (for drawing with GetWindowDC()).
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000512 */
Alexandre Julliard3abeae82001-05-09 17:21:04 +0000513void NC_GetInsideRect( HWND hwnd, RECT *rect )
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000514{
515 WND * wndPtr = WIN_FindWndPtr( hwnd );
516
517 rect->top = rect->left = 0;
518 rect->right = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
519 rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
520
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000521 if (wndPtr->dwStyle & WS_ICONIC) goto END;
Alexandre Julliard3ed37e01994-11-07 18:20:42 +0000522
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000523 /* Remove frame from rectangle */
Ove Kaaven60c78f11999-07-03 15:40:29 +0000524 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
Alexandre Julliarddba420a1994-02-02 06:48:31 +0000525 {
Alexandre Julliard3abeae82001-05-09 17:21:04 +0000526 InflateRect( rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
527 }
528 else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
529 {
530 InflateRect( rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
531 /* FIXME: this isn't in NC_AdjustRect? why not? */
532 if ((TWEAK_WineLook == WIN31_LOOK) && (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME))
Alexandre Julliarda3960291999-02-26 11:11:13 +0000533 InflateRect( rect, -1, 0 );
Alexandre Julliarddba420a1994-02-02 06:48:31 +0000534 }
Alexandre Julliard3abeae82001-05-09 17:21:04 +0000535 else if (HAS_THINFRAME( wndPtr->dwStyle ))
Alexandre Julliardf90efa91998-06-14 15:24:15 +0000536 {
Ove Kaaven60c78f11999-07-03 15:40:29 +0000537 InflateRect( rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER) );
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000538 }
539
Francis Beaudet1cc0a9a1999-09-03 15:00:45 +0000540 /* We have additional border information if the window
541 * is a child (but not an MDI child) */
Alexandre Julliard3abeae82001-05-09 17:21:04 +0000542 if (TWEAK_WineLook != WIN31_LOOK)
543 {
544 if ( (wndPtr->dwStyle & WS_CHILD) &&
545 ( (wndPtr->dwExStyle & WS_EX_MDICHILD) == 0 ) )
546 {
547 if (wndPtr->dwExStyle & WS_EX_CLIENTEDGE)
548 InflateRect (rect, -GetSystemMetrics(SM_CXEDGE), -GetSystemMetrics(SM_CYEDGE));
549 if (wndPtr->dwExStyle & WS_EX_STATICEDGE)
550 InflateRect (rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
551 }
Alexandre Julliardf90efa91998-06-14 15:24:15 +0000552 }
Alexandre Julliard3abeae82001-05-09 17:21:04 +0000553
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000554END:
555 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliardf90efa91998-06-14 15:24:15 +0000556 return;
557}
558
559
560/***********************************************************************
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000561 * NC_DoNCHitTest
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000562 *
Andreas Mohr260f1a12000-09-22 20:59:29 +0000563 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000564 */
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000565
Alexandre Julliard83f52d12000-09-26 22:20:14 +0000566static LONG NC_DoNCHitTest (WND *wndPtr, POINT pt )
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000567{
Alexandre Julliard83f52d12000-09-26 22:20:14 +0000568 RECT rect;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000569
Alexandre Julliardaff7dda2002-11-22 21:22:14 +0000570 TRACE("hwnd=%p pt=%ld,%ld\n", wndPtr->hwndSelf, pt.x, pt.y );
Alexandre Julliard940d58c1994-09-16 09:24:37 +0000571
Alexandre Julliard83f52d12000-09-26 22:20:14 +0000572 GetWindowRect(wndPtr->hwndSelf, &rect );
573 if (!PtInRect( &rect, pt )) return HTNOWHERE;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000574
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000575 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000576
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000577 /* Check borders */
578 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000579 {
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000580 InflateRect( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
581 if (!PtInRect( &rect, pt ))
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000582 {
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000583 /* Check top sizing border */
584 if (pt.y < rect.top)
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000585 {
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000586 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
587 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
588 return HTTOP;
589 }
590 /* Check bottom sizing border */
591 if (pt.y >= rect.bottom)
592 {
593 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
594 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
595 return HTBOTTOM;
596 }
597 /* Check left sizing border */
598 if (pt.x < rect.left)
599 {
600 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
601 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
602 return HTLEFT;
603 }
604 /* Check right sizing border */
605 if (pt.x >= rect.right)
606 {
607 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
608 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
609 return HTRIGHT;
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000610 }
611 }
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000612 }
613 else /* No thick frame */
614 {
615 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
616 InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
617 else if (HAS_THINFRAME( wndPtr->dwStyle ))
618 InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
619 if (!PtInRect( &rect, pt )) return HTBORDER;
620 }
621
622 /* Check caption */
623
624 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
625 {
626 rect.top += GetSystemMetrics(SM_CYCAPTION) - GetSystemMetrics(SM_CYBORDER);
627 if (!PtInRect( &rect, pt ))
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000628 {
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000629 /* Check system menu */
630 if ((wndPtr->dwStyle & WS_SYSMENU) && !(wndPtr->dwExStyle & WS_EX_TOOLWINDOW))
631 rect.left += GetSystemMetrics(SM_CXSIZE);
632 if (pt.x <= rect.left) return HTSYSMENU;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000633
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000634 /* Check maximize box */
635 if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
636 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
Alexandre Julliardf7207251994-07-23 07:57:48 +0000637
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000638 if (pt.x >= rect.right) return HTMAXBUTTON;
639 /* Check minimize box */
640 if (wndPtr->dwStyle & WS_MINIMIZEBOX)
641 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
642 if (pt.x >= rect.right) return HTMINBUTTON;
643 return HTCAPTION;
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000644 }
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000645 }
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000646
Alexandre Julliardf7207251994-07-23 07:57:48 +0000647 /* Check client area */
648
Alexandre Julliard83f52d12000-09-26 22:20:14 +0000649 ScreenToClient( wndPtr->hwndSelf, &pt );
650 GetClientRect( wndPtr->hwndSelf, &rect );
651 if (PtInRect( &rect, pt )) return HTCLIENT;
Alexandre Julliardf7207251994-07-23 07:57:48 +0000652
653 /* Check vertical scroll bar */
654
655 if (wndPtr->dwStyle & WS_VSCROLL)
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000656 {
Alberto Massaribf9390e2003-01-14 23:41:01 +0000657 if((wndPtr->dwExStyle & WS_EX_LEFTSCROLLBAR) != 0)
658 rect.left -= GetSystemMetrics(SM_CXVSCROLL);
659 else
660 rect.right += GetSystemMetrics(SM_CXVSCROLL);
661 if (PtInRect( &rect, pt )) return HTVSCROLL;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000662 }
663
Alexandre Julliardf7207251994-07-23 07:57:48 +0000664 /* Check horizontal scroll bar */
665
666 if (wndPtr->dwStyle & WS_HSCROLL)
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000667 {
Marcus Meissnerddca3151999-05-22 11:33:23 +0000668 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
Alexandre Julliard83f52d12000-09-26 22:20:14 +0000669 if (PtInRect( &rect, pt ))
Alexandre Julliardf7207251994-07-23 07:57:48 +0000670 {
671 /* Check size box */
672 if ((wndPtr->dwStyle & WS_VSCROLL) &&
Alberto Massaribf9390e2003-01-14 23:41:01 +0000673 ((((wndPtr->dwExStyle & WS_EX_LEFTSCROLLBAR) != 0) && (pt.x <= rect.left + GetSystemMetrics(SM_CXVSCROLL))) ||
674 (((wndPtr->dwExStyle & WS_EX_LEFTSCROLLBAR) == 0) && (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))))
Alexandre Julliardf7207251994-07-23 07:57:48 +0000675 return HTSIZE;
676 return HTHSCROLL;
677 }
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000678 }
679
Alexandre Julliardf7207251994-07-23 07:57:48 +0000680 /* Check menu bar */
681
682 if (HAS_MENU(wndPtr))
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000683 {
Alexandre Julliardf7207251994-07-23 07:57:48 +0000684 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
685 return HTMENU;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000686 }
687
Vincent Béron9a624912002-05-31 23:06:46 +0000688 /* Has to return HTNOWHERE if nothing was found
Francois Boisvert5538ec42000-07-29 00:00:29 +0000689 Could happen when a window has a customized non client area */
Vincent Béron9a624912002-05-31 23:06:46 +0000690 return HTNOWHERE;
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000691}
692
693
694/***********************************************************************
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000695 * NC_DoNCHitTest95
696 *
697 * Handle a WM_NCHITTEST message. Called from NC_HandleNCHitTest().
698 *
Alexandre Julliard829fe321998-07-26 14:27:39 +0000699 * FIXME: Just a modified copy of the Win 3.1 version.
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000700 */
701
Alexandre Julliard83f52d12000-09-26 22:20:14 +0000702static LONG NC_DoNCHitTest95 (WND *wndPtr, POINT pt )
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000703{
Alexandre Julliard83f52d12000-09-26 22:20:14 +0000704 RECT rect;
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000705
Alexandre Julliardaff7dda2002-11-22 21:22:14 +0000706 TRACE("hwnd=%p pt=%ld,%ld\n", wndPtr->hwndSelf, pt.x, pt.y );
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000707
Alexandre Julliard83f52d12000-09-26 22:20:14 +0000708 GetWindowRect(wndPtr->hwndSelf, &rect );
709 if (!PtInRect( &rect, pt )) return HTNOWHERE;
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000710
711 if (wndPtr->dwStyle & WS_MINIMIZE) return HTCAPTION;
712
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000713 /* Check borders */
714 if (HAS_THICKFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000715 {
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000716 InflateRect( &rect, -GetSystemMetrics(SM_CXFRAME), -GetSystemMetrics(SM_CYFRAME) );
717 if (!PtInRect( &rect, pt ))
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000718 {
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000719 /* Check top sizing border */
720 if (pt.y < rect.top)
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000721 {
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000722 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTTOPLEFT;
723 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTTOPRIGHT;
724 return HTTOP;
725 }
726 /* Check bottom sizing border */
727 if (pt.y >= rect.bottom)
728 {
729 if (pt.x < rect.left+GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMLEFT;
730 if (pt.x >= rect.right-GetSystemMetrics(SM_CXSIZE)) return HTBOTTOMRIGHT;
731 return HTBOTTOM;
732 }
733 /* Check left sizing border */
734 if (pt.x < rect.left)
735 {
736 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPLEFT;
737 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMLEFT;
738 return HTLEFT;
739 }
740 /* Check right sizing border */
741 if (pt.x >= rect.right)
742 {
743 if (pt.y < rect.top+GetSystemMetrics(SM_CYSIZE)) return HTTOPRIGHT;
744 if (pt.y >= rect.bottom-GetSystemMetrics(SM_CYSIZE)) return HTBOTTOMRIGHT;
745 return HTRIGHT;
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000746 }
747 }
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000748 }
749 else /* No thick frame */
750 {
751 if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
752 InflateRect(&rect, -GetSystemMetrics(SM_CXDLGFRAME), -GetSystemMetrics(SM_CYDLGFRAME));
753 else if (HAS_THINFRAME( wndPtr->dwStyle ))
754 InflateRect(&rect, -GetSystemMetrics(SM_CXBORDER), -GetSystemMetrics(SM_CYBORDER));
755 if (!PtInRect( &rect, pt )) return HTBORDER;
756 }
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000757
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000758 /* Check caption */
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000759
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000760 if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
761 {
762 if (wndPtr->dwExStyle & WS_EX_TOOLWINDOW)
763 rect.top += GetSystemMetrics(SM_CYSMCAPTION) - 1;
764 else
765 rect.top += GetSystemMetrics(SM_CYCAPTION) - 1;
766 if (!PtInRect( &rect, pt ))
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000767 {
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000768 /* Check system menu */
769 if ((wndPtr->dwStyle & WS_SYSMENU) && !(wndPtr->dwExStyle & WS_EX_TOOLWINDOW))
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000770 {
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000771 if (NC_IconForWindow(wndPtr->hwndSelf))
772 rect.left += GetSystemMetrics(SM_CYCAPTION) - 1;
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000773 }
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000774 if (pt.x < rect.left) return HTSYSMENU;
775
776 /* Check close button */
777 if (wndPtr->dwStyle & WS_SYSMENU)
778 rect.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
779 if (pt.x > rect.right) return HTCLOSE;
780
781 /* Check maximize box */
782 /* In win95 there is automatically a Maximize button when there is a minimize one*/
783 if ((wndPtr->dwStyle & WS_MAXIMIZEBOX)|| (wndPtr->dwStyle & WS_MINIMIZEBOX))
784 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
785 if (pt.x > rect.right) return HTMAXBUTTON;
786
787 /* Check minimize box */
788 /* In win95 there is automatically a Maximize button when there is a Maximize one*/
789 if ((wndPtr->dwStyle & WS_MINIMIZEBOX)||(wndPtr->dwStyle & WS_MAXIMIZEBOX))
790 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
791
792 if (pt.x > rect.right) return HTMINBUTTON;
793 return HTCAPTION;
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000794 }
795 }
796
797 /* Check client area */
798
Alexandre Julliard83f52d12000-09-26 22:20:14 +0000799 ScreenToClient( wndPtr->hwndSelf, &pt );
800 GetClientRect( wndPtr->hwndSelf, &rect );
801 if (PtInRect( &rect, pt )) return HTCLIENT;
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000802
803 /* Check vertical scroll bar */
804
805 if (wndPtr->dwStyle & WS_VSCROLL)
806 {
Alberto Massaribf9390e2003-01-14 23:41:01 +0000807 if((wndPtr->dwExStyle & WS_EX_LEFTSCROLLBAR) != 0)
808 rect.left -= GetSystemMetrics(SM_CXVSCROLL);
809 else
810 rect.right += GetSystemMetrics(SM_CXVSCROLL);
811 if (PtInRect( &rect, pt )) return HTVSCROLL;
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000812 }
813
814 /* Check horizontal scroll bar */
815
816 if (wndPtr->dwStyle & WS_HSCROLL)
817 {
Marcus Meissnerddca3151999-05-22 11:33:23 +0000818 rect.bottom += GetSystemMetrics(SM_CYHSCROLL);
Alexandre Julliard83f52d12000-09-26 22:20:14 +0000819 if (PtInRect( &rect, pt ))
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000820 {
821 /* Check size box */
822 if ((wndPtr->dwStyle & WS_VSCROLL) &&
Alberto Massaribf9390e2003-01-14 23:41:01 +0000823 ((((wndPtr->dwExStyle & WS_EX_LEFTSCROLLBAR) != 0) && (pt.x <= rect.left + GetSystemMetrics(SM_CXVSCROLL))) ||
824 (((wndPtr->dwExStyle & WS_EX_LEFTSCROLLBAR) == 0) && (pt.x >= rect.right - GetSystemMetrics(SM_CXVSCROLL)))))
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000825 return HTSIZE;
826 return HTHSCROLL;
827 }
828 }
829
830 /* Check menu bar */
831
832 if (HAS_MENU(wndPtr))
833 {
834 if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
835 return HTMENU;
836 }
837
Vincent Béron9a624912002-05-31 23:06:46 +0000838 /* Has to return HTNOWHERE if nothing was found
Francois Boisvert5538ec42000-07-29 00:00:29 +0000839 Could happen when a window has a customized non client area */
840 return HTNOWHERE;
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000841}
842
843
844/***********************************************************************
845 * NC_HandleNCHitTest
846 *
847 * Handle a WM_NCHITTEST message. Called from DefWindowProc().
848 */
Alexandre Julliard83f52d12000-09-26 22:20:14 +0000849LONG NC_HandleNCHitTest (HWND hwnd , POINT pt)
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000850{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000851 LONG retvalue;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000852 WND *wndPtr = WIN_FindWndPtr (hwnd);
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000853
854 if (!wndPtr)
855 return HTERROR;
856
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000857 if (TWEAK_WineLook == WIN31_LOOK)
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000858 retvalue = NC_DoNCHitTest (wndPtr, pt);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +0000859 else
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000860 retvalue = NC_DoNCHitTest95 (wndPtr, pt);
861 WIN_ReleaseWndPtr(wndPtr);
862 return retvalue;
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000863}
864
865
866/***********************************************************************
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000867 * NC_DrawSysButton
868 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000869void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down )
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000870{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000871 RECT rect;
872 HDC hdcMem;
873 HBITMAP hbitmap;
Alexandre Julliard7cbe6571995-01-09 18:21:16 +0000874
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000875 NC_GetInsideRect( hwnd, &rect );
876 hdcMem = CreateCompatibleDC( hdc );
877 hbitmap = SelectObject( hdcMem, hbitmapClose );
878 BitBlt(hdc, rect.left, rect.top, GetSystemMetrics(SM_CXSIZE), GetSystemMetrics(SM_CYSIZE),
879 hdcMem, (GetWindowLongA(hwnd,GWL_STYLE) & WS_CHILD) ? GetSystemMetrics(SM_CXSIZE) : 0, 0,
880 down ? NOTSRCCOPY : SRCCOPY );
881 SelectObject( hdcMem, hbitmap );
882 DeleteDC( hdcMem );
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000883}
884
885
886/***********************************************************************
887 * NC_DrawMaxButton
888 */
Michael Stefaniucec5612e2002-10-30 23:45:38 +0000889static void NC_DrawMaxButton( HWND hwnd, HDC hdc, BOOL down )
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000890{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000891 RECT rect;
Alexandre Julliardcc2d3822002-01-03 02:35:23 +0000892 UINT flags = IsZoomed(hwnd) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMAX;
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000893
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000894 NC_GetInsideRect( hwnd, &rect );
Alexandre Julliardcc2d3822002-01-03 02:35:23 +0000895 rect.left = rect.right - GetSystemMetrics(SM_CXSIZE) + 1;
896 rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
897 rect.top += 1;
898 rect.right -= 1;
899 if (down) flags |= DFCS_PUSHED;
900 DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000901}
902
903
904/***********************************************************************
905 * NC_DrawMinButton
906 */
Michael Stefaniucec5612e2002-10-30 23:45:38 +0000907static void NC_DrawMinButton( HWND hwnd, HDC hdc, BOOL down )
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000908{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000909 RECT rect;
Alexandre Julliardcc2d3822002-01-03 02:35:23 +0000910 UINT flags = DFCS_CAPTIONMIN;
911 DWORD style = GetWindowLongA( hwnd, GWL_STYLE );
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000912
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000913 NC_GetInsideRect( hwnd, &rect );
Alexandre Julliardcc2d3822002-01-03 02:35:23 +0000914 if (style & (WS_MAXIMIZEBOX|WS_MINIMIZEBOX))
915 rect.right -= GetSystemMetrics(SM_CXSIZE) - 2;
916 rect.left = rect.right - GetSystemMetrics(SM_CXSIZE) + 1;
917 rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
918 rect.top += 1;
919 rect.right -= 1;
920 if (down) flags |= DFCS_PUSHED;
921 DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +0000922}
923
924
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000925/******************************************************************************
926 *
927 * void NC_DrawSysButton95(
Patrik Stridvall2d6457c2000-03-28 20:22:59 +0000928 * HWND hwnd,
929 * HDC hdc,
930 * BOOL down )
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000931 *
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000932 * Draws the Win95 system icon.
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000933 *
934 * Revision history
935 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
936 * Original implementation from NC_DrawSysButton source.
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000937 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
938 * Fixed most bugs.
939 *
940 *****************************************************************************/
941
Alexandre Julliarda3960291999-02-26 11:11:13 +0000942BOOL
943NC_DrawSysButton95 (HWND hwnd, HDC hdc, BOOL down)
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000944{
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000945 HICON hIcon = NC_IconForWindow( hwnd );
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000946
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000947 if (hIcon)
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000948 {
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000949 RECT rect;
950 NC_GetInsideRect( hwnd, &rect );
Alexandre Julliardd4304f82002-08-28 22:25:12 +0000951 DrawIconEx (hdc, rect.left + 1, rect.top + 1, hIcon,
952 GetSystemMetrics(SM_CXSIZE) - 1,
953 GetSystemMetrics(SM_CYSIZE) - 1, 0, 0, DI_NORMAL);
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000954 }
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000955 return (hIcon != 0);
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000956}
957
958
959/******************************************************************************
960 *
961 * void NC_DrawCloseButton95(
Patrik Stridvall2d6457c2000-03-28 20:22:59 +0000962 * HWND hwnd,
963 * HDC hdc,
964 * BOOL down,
Pascal Lessardd814bb61999-07-31 13:02:02 +0000965 * BOOL bGrayed )
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000966 *
967 * Draws the Win95 close button.
968 *
Pascal Lessardd814bb61999-07-31 13:02:02 +0000969 * If bGrayed is true, then draw a disabled Close button
970 *
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +0000971 * Revision history
972 * 11-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
973 * Original implementation from NC_DrawSysButton95 source.
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000974 *
975 *****************************************************************************/
976
Pascal Lessardd814bb61999-07-31 13:02:02 +0000977static void NC_DrawCloseButton95 (HWND hwnd, HDC hdc, BOOL down, BOOL bGrayed)
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000978{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000979 RECT rect;
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000980
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000981 NC_GetInsideRect( hwnd, &rect );
982
983 /* A tool window has a smaller Close button */
984 if (GetWindowLongA( hwnd, GWL_EXSTYLE ) & WS_EX_TOOLWINDOW)
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000985 {
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000986 INT iBmpHeight = 11; /* Windows does not use SM_CXSMSIZE and SM_CYSMSIZE */
987 INT iBmpWidth = 11; /* it uses 11x11 for the close button in tool window */
988 INT iCaptionHeight = GetSystemMetrics(SM_CYSMCAPTION);
Alexandre Julliardf90efa91998-06-14 15:24:15 +0000989
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000990 rect.top = rect.top + (iCaptionHeight - 1 - iBmpHeight) / 2;
991 rect.left = rect.right - (iCaptionHeight + 1 + iBmpWidth) / 2;
992 rect.bottom = rect.top + iBmpHeight;
993 rect.right = rect.left + iBmpWidth;
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000994 }
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000995 else
996 {
997 rect.left = rect.right - GetSystemMetrics(SM_CXSIZE) - 1;
998 rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
999 rect.top += 2;
1000 rect.right -= 2;
1001 }
1002 DrawFrameControl( hdc, &rect, DFC_CAPTION,
1003 (DFCS_CAPTIONCLOSE |
1004 (down ? DFCS_PUSHED : 0) |
1005 (bGrayed ? DFCS_INACTIVE : 0)) );
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001006}
1007
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001008/******************************************************************************
Alexandre Julliardc1d35cc2001-01-24 19:47:57 +00001009 * NC_DrawMaxButton95
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001010 *
1011 * Draws the maximize button for Win95 style windows.
Pascal Lessardd814bb61999-07-31 13:02:02 +00001012 * If bGrayed is true, then draw a disabled Maximize button
Alexandre Julliardc1d35cc2001-01-24 19:47:57 +00001013 */
Michael Stefaniucec5612e2002-10-30 23:45:38 +00001014static void NC_DrawMaxButton95(HWND hwnd,HDC hdc,BOOL down, BOOL bGrayed)
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001015{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001016 RECT rect;
Alexandre Julliarddc4fe772001-06-04 21:55:17 +00001017 UINT flags = IsZoomed(hwnd) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMAX;
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001018
Alexandre Julliarddc4fe772001-06-04 21:55:17 +00001019 NC_GetInsideRect( hwnd, &rect );
1020 if (GetWindowLongA( hwnd, GWL_STYLE) & WS_SYSMENU)
1021 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1022 rect.left = rect.right - GetSystemMetrics(SM_CXSIZE);
1023 rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
1024 rect.top += 2;
1025 rect.right -= 2;
1026 if (down) flags |= DFCS_PUSHED;
1027 if (bGrayed) flags |= DFCS_INACTIVE;
1028 DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001029}
1030
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001031/******************************************************************************
Alexandre Julliardc1d35cc2001-01-24 19:47:57 +00001032 * NC_DrawMinButton95
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001033 *
1034 * Draws the minimize button for Win95 style windows.
Pascal Lessardd814bb61999-07-31 13:02:02 +00001035 * If bGrayed is true, then draw a disabled Minimize button
Alexandre Julliardc1d35cc2001-01-24 19:47:57 +00001036 */
Michael Stefaniucec5612e2002-10-30 23:45:38 +00001037static void NC_DrawMinButton95(HWND hwnd,HDC hdc,BOOL down, BOOL bGrayed)
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001038{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001039 RECT rect;
Alexandre Julliarddc4fe772001-06-04 21:55:17 +00001040 UINT flags = DFCS_CAPTIONMIN;
1041 DWORD style = GetWindowLongA( hwnd, GWL_STYLE );
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001042
Alexandre Julliarddc4fe772001-06-04 21:55:17 +00001043 NC_GetInsideRect( hwnd, &rect );
1044 if (style & WS_SYSMENU)
1045 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1046 if (style & (WS_MAXIMIZEBOX|WS_MINIMIZEBOX))
1047 rect.right -= GetSystemMetrics(SM_CXSIZE) - 2;
1048 rect.left = rect.right - GetSystemMetrics(SM_CXSIZE);
1049 rect.bottom = rect.top + GetSystemMetrics(SM_CYSIZE) - 1;
1050 rect.top += 2;
1051 rect.right -= 2;
1052 if (down) flags |= DFCS_PUSHED;
1053 if (bGrayed) flags |= DFCS_INACTIVE;
1054 DrawFrameControl( hdc, &rect, DFC_CAPTION, flags );
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001055}
1056
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00001057/***********************************************************************
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001058 * NC_DrawFrame
1059 *
1060 * Draw a window frame inside the given rectangle, and update the rectangle.
Alexandre Julliardaca05781994-10-17 18:12:41 +00001061 * The correct pen for the frame must be selected in the DC.
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001062 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001063static void NC_DrawFrame( HDC hdc, RECT *rect, BOOL dlgFrame,
1064 BOOL active )
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001065{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001066 INT width, height;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001067
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001068 if (TWEAK_WineLook != WIN31_LOOK)
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001069 ERR("Called in Win95 mode. Aiee! Please report this.\n" );
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001070
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001071 if (dlgFrame)
1072 {
Marcus Meissnerddca3151999-05-22 11:33:23 +00001073 width = GetSystemMetrics(SM_CXDLGFRAME) - 1;
1074 height = GetSystemMetrics(SM_CYDLGFRAME) - 1;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001075 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
Alexandre Julliard02e90081998-01-04 17:49:09 +00001076 COLOR_INACTIVECAPTION) );
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001077 }
1078 else
1079 {
Ove Kaaven60c78f11999-07-03 15:40:29 +00001080 width = GetSystemMetrics(SM_CXFRAME) - 2;
1081 height = GetSystemMetrics(SM_CYFRAME) - 2;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001082 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
Alexandre Julliard02e90081998-01-04 17:49:09 +00001083 COLOR_INACTIVEBORDER) );
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001084 }
1085
1086 /* Draw frame */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001087 PatBlt( hdc, rect->left, rect->top,
Alexandre Julliard75d86e11996-11-17 18:59:11 +00001088 rect->right - rect->left, height, PATCOPY );
Alexandre Julliarda3960291999-02-26 11:11:13 +00001089 PatBlt( hdc, rect->left, rect->top,
Alexandre Julliard75d86e11996-11-17 18:59:11 +00001090 width, rect->bottom - rect->top, PATCOPY );
Randy Weems0bc73c71999-03-25 15:49:11 +00001091 PatBlt( hdc, rect->left, rect->bottom - 1,
Alexandre Julliard75d86e11996-11-17 18:59:11 +00001092 rect->right - rect->left, -height, PATCOPY );
Randy Weems0bc73c71999-03-25 15:49:11 +00001093 PatBlt( hdc, rect->right - 1, rect->top,
Alexandre Julliard75d86e11996-11-17 18:59:11 +00001094 -width, rect->bottom - rect->top, PATCOPY );
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001095
1096 if (dlgFrame)
1097 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001098 InflateRect( rect, -width, -height );
Vincent Béron9a624912002-05-31 23:06:46 +00001099 }
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00001100 else
1101 {
Ove Kaaven60c78f11999-07-03 15:40:29 +00001102 INT decYOff = GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXSIZE) - 1;
1103 INT decXOff = GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYSIZE) - 1;
Huw D M Davies2d617be1998-12-08 09:14:09 +00001104
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001105 /* Draw inner rectangle */
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00001106
Alexandre Julliarda3960291999-02-26 11:11:13 +00001107 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1108 Rectangle( hdc, rect->left + width, rect->top + height,
Huw D M Davies2d617be1998-12-08 09:14:09 +00001109 rect->right - width , rect->bottom - height );
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001110
1111 /* Draw the decorations */
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001112
Alexandre Julliarda3960291999-02-26 11:11:13 +00001113 MoveToEx( hdc, rect->left, rect->top + decYOff, NULL );
1114 LineTo( hdc, rect->left + width, rect->top + decYOff );
1115 MoveToEx( hdc, rect->right - 1, rect->top + decYOff, NULL );
1116 LineTo( hdc, rect->right - width - 1, rect->top + decYOff );
1117 MoveToEx( hdc, rect->left, rect->bottom - decYOff, NULL );
1118 LineTo( hdc, rect->left + width, rect->bottom - decYOff );
1119 MoveToEx( hdc, rect->right - 1, rect->bottom - decYOff, NULL );
1120 LineTo( hdc, rect->right - width - 1, rect->bottom - decYOff );
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001121
Alexandre Julliarda3960291999-02-26 11:11:13 +00001122 MoveToEx( hdc, rect->left + decXOff, rect->top, NULL );
1123 LineTo( hdc, rect->left + decXOff, rect->top + height);
1124 MoveToEx( hdc, rect->left + decXOff, rect->bottom - 1, NULL );
1125 LineTo( hdc, rect->left + decXOff, rect->bottom - height - 1 );
1126 MoveToEx( hdc, rect->right - decXOff, rect->top, NULL );
1127 LineTo( hdc, rect->right - decXOff, rect->top + height );
1128 MoveToEx( hdc, rect->right - decXOff, rect->bottom - 1, NULL );
1129 LineTo( hdc, rect->right - decXOff, rect->bottom - height - 1 );
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001130
Alexandre Julliarda3960291999-02-26 11:11:13 +00001131 InflateRect( rect, -width - 1, -height - 1 );
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00001132 }
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001133}
1134
1135
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001136/******************************************************************************
1137 *
1138 * void NC_DrawFrame95(
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001139 * HDC hdc,
1140 * RECT *rect,
Bill Medlandcbfbf2a2001-07-20 18:36:49 +00001141 * BOOL active,
1142 * DWORD style,
1143 * DWORD exStyle )
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001144 *
1145 * Draw a window frame inside the given rectangle, and update the rectangle.
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001146 *
1147 * Bugs
1148 * Many. First, just what IS a frame in Win95? Note that the 3D look
1149 * on the outer edge is handled by NC_DoNCPaint95. As is the inner
1150 * edge. The inner rectangle just inside the frame is handled by the
1151 * Caption code.
1152 *
1153 * In short, for most people, this function should be a nop (unless
1154 * you LIKE thick borders in Win95/NT4.0 -- I've been working with
1155 * them lately, but just to get this code right). Even so, it doesn't
1156 * appear to be so. It's being worked on...
Vincent Béron9a624912002-05-31 23:06:46 +00001157 *
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001158 * Revision history
1159 * 06-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1160 * Original implementation (based on NC_DrawFrame)
Alexandre Julliardf90efa91998-06-14 15:24:15 +00001161 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1162 * Some minor fixes.
Ove Kaaven60c78f11999-07-03 15:40:29 +00001163 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1164 * Fixed a fix or something.
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001165 *
1166 *****************************************************************************/
1167
1168static void NC_DrawFrame95(
Alexandre Julliarda3960291999-02-26 11:11:13 +00001169 HDC hdc,
1170 RECT *rect,
Bill Medlandcbfbf2a2001-07-20 18:36:49 +00001171 BOOL active,
1172 DWORD style,
1173 DWORD exStyle)
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001174{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001175 INT width, height;
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001176
Bill Medlandcbfbf2a2001-07-20 18:36:49 +00001177 /* Firstly the "thick" frame */
1178 if (style & WS_THICKFRAME)
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001179 {
Bill Medlandcbfbf2a2001-07-20 18:36:49 +00001180 width = GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXDLGFRAME);
1181 height = GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYDLGFRAME);
1182
1183 SelectObject( hdc, GetSysColorBrush(active ? COLOR_ACTIVEBORDER :
1184 COLOR_INACTIVEBORDER) );
1185 /* Draw frame */
1186 PatBlt( hdc, rect->left, rect->top,
1187 rect->right - rect->left, height, PATCOPY );
1188 PatBlt( hdc, rect->left, rect->top,
1189 width, rect->bottom - rect->top, PATCOPY );
1190 PatBlt( hdc, rect->left, rect->bottom - 1,
1191 rect->right - rect->left, -height, PATCOPY );
1192 PatBlt( hdc, rect->right - 1, rect->top,
1193 -width, rect->bottom - rect->top, PATCOPY );
1194
1195 InflateRect( rect, -width, -height );
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001196 }
1197
Bill Medlandcbfbf2a2001-07-20 18:36:49 +00001198 /* Now the other bit of the frame */
1199 if ((style & (WS_BORDER|WS_DLGFRAME)) ||
1200 (exStyle & WS_EX_DLGMODALFRAME))
1201 {
1202 width = GetSystemMetrics(SM_CXDLGFRAME) - GetSystemMetrics(SM_CXEDGE);
1203 height = GetSystemMetrics(SM_CYDLGFRAME) - GetSystemMetrics(SM_CYEDGE);
1204 /* This should give a value of 1 that should also work for a border */
Alexandre Julliardf90efa91998-06-14 15:24:15 +00001205
Bill Medlandcbfbf2a2001-07-20 18:36:49 +00001206 SelectObject( hdc, GetSysColorBrush(
1207 (exStyle & (WS_EX_DLGMODALFRAME|WS_EX_CLIENTEDGE)) ?
1208 COLOR_3DFACE :
1209 (exStyle & WS_EX_STATICEDGE) ?
1210 COLOR_WINDOWFRAME :
1211 (style & (WS_DLGFRAME|WS_THICKFRAME)) ?
1212 COLOR_3DFACE :
1213 /* else */
1214 COLOR_WINDOWFRAME));
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001215
Bill Medlandcbfbf2a2001-07-20 18:36:49 +00001216 /* Draw frame */
1217 PatBlt( hdc, rect->left, rect->top,
1218 rect->right - rect->left, height, PATCOPY );
1219 PatBlt( hdc, rect->left, rect->top,
1220 width, rect->bottom - rect->top, PATCOPY );
1221 PatBlt( hdc, rect->left, rect->bottom - 1,
1222 rect->right - rect->left, -height, PATCOPY );
1223 PatBlt( hdc, rect->right - 1, rect->top,
1224 -width, rect->bottom - rect->top, PATCOPY );
1225
1226 InflateRect( rect, -width, -height );
1227 }
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001228}
1229
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00001230
1231/***********************************************************************
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001232 * NC_DrawCaption
1233 *
1234 * Draw the window caption.
1235 * The correct pen for the window frame must be selected in the DC.
1236 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001237static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd,
1238 DWORD style, BOOL active )
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001239{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001240 RECT r = *rect;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001241 char buffer[256];
1242
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00001243 if (!hbitmapClose)
1244 {
Alexandre Julliardcc2d3822002-01-03 02:35:23 +00001245 if (!(hbitmapClose = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_OLD_CLOSE) ))) return;
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00001246 }
Vincent Béron9a624912002-05-31 23:06:46 +00001247
Alexandre Julliarddc4fe772001-06-04 21:55:17 +00001248 if (GetWindowLongA( hwnd, GWL_EXSTYLE) & WS_EX_DLGMODALFRAME)
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001249 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001250 HBRUSH hbrushOld = SelectObject(hdc, GetSysColorBrush(COLOR_WINDOW) );
1251 PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY );
1252 PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
1253 PatBlt( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY );
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001254 r.left++;
1255 r.right--;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001256 SelectObject( hdc, hbrushOld );
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001257 }
Alexandre Julliardb0efe282000-08-04 04:18:04 +00001258 MoveToEx( hdc, r.left, r.bottom, NULL );
Alexandre Julliarda3960291999-02-26 11:11:13 +00001259 LineTo( hdc, r.right, r.bottom );
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001260
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001261 if (style & WS_SYSMENU)
1262 {
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001263 NC_DrawSysButton( hwnd, hdc, FALSE );
Marcus Meissnerddca3151999-05-22 11:33:23 +00001264 r.left += GetSystemMetrics(SM_CXSIZE) + 1;
Alexandre Julliardb0efe282000-08-04 04:18:04 +00001265 MoveToEx( hdc, r.left - 1, r.top, NULL );
Alexandre Julliarda3960291999-02-26 11:11:13 +00001266 LineTo( hdc, r.left - 1, r.bottom );
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001267 }
Alexandre Julliardcc2d3822002-01-03 02:35:23 +00001268 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION) );
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001269 if (style & WS_MAXIMIZEBOX)
1270 {
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001271 NC_DrawMaxButton( hwnd, hdc, FALSE );
Marcus Meissnerddca3151999-05-22 11:33:23 +00001272 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001273 }
1274 if (style & WS_MINIMIZEBOX)
1275 {
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001276 NC_DrawMinButton( hwnd, hdc, FALSE );
Marcus Meissnerddca3151999-05-22 11:33:23 +00001277 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001278 }
1279
Alexandre Julliarda3960291999-02-26 11:11:13 +00001280 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) ))
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001281 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001282 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1283 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1284 SetBkMode( hdc, TRANSPARENT );
1285 DrawTextA( hdc, buffer, -1, &r,
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00001286 DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX );
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001287 }
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001288}
1289
1290
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001291/******************************************************************************
1292 *
1293 * NC_DrawCaption95(
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001294 * HDC hdc,
1295 * RECT *rect,
1296 * HWND hwnd,
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001297 * DWORD style,
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001298 * BOOL active )
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001299 *
1300 * Draw the window caption for Win95 style windows.
1301 * The correct pen for the window frame must be selected in the DC.
1302 *
1303 * Bugs
Alexandre Julliardf90efa91998-06-14 15:24:15 +00001304 * Hey, a function that finally works! Well, almost.
1305 * It's being worked on.
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001306 *
1307 * Revision history
1308 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1309 * Original implementation.
Alexandre Julliardf90efa91998-06-14 15:24:15 +00001310 * 02-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1311 * Some minor fixes.
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001312 *
1313 *****************************************************************************/
1314
1315static void NC_DrawCaption95(
Alexandre Julliarda3960291999-02-26 11:11:13 +00001316 HDC hdc,
1317 RECT *rect,
1318 HWND hwnd,
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001319 DWORD style,
Eric Kohl8e517b51998-10-11 13:06:35 +00001320 DWORD exStyle,
Alexandre Julliarda3960291999-02-26 11:11:13 +00001321 BOOL active )
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001322{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001323 RECT r = *rect;
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001324 char buffer[256];
Alexandre Julliarda3960291999-02-26 11:11:13 +00001325 HPEN hPrevPen;
Pascal Lessardd814bb61999-07-31 13:02:02 +00001326 HMENU hSysMenu;
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001327
Alexandre Julliard4344c362002-05-20 18:15:28 +00001328 hPrevPen = SelectObject( hdc, SYSCOLOR_GetPen(
Bill Medlandcbfbf2a2001-07-20 18:36:49 +00001329 ((exStyle & (WS_EX_STATICEDGE|WS_EX_CLIENTEDGE|
1330 WS_EX_DLGMODALFRAME)) == WS_EX_STATICEDGE) ?
1331 COLOR_WINDOWFRAME : COLOR_3DFACE) );
Alexandre Julliarda3960291999-02-26 11:11:13 +00001332 MoveToEx( hdc, r.left, r.bottom - 1, NULL );
1333 LineTo( hdc, r.right, r.bottom - 1 );
1334 SelectObject( hdc, hPrevPen );
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001335 r.bottom--;
1336
Alexandre Julliarda3960291999-02-26 11:11:13 +00001337 FillRect( hdc, &r, GetSysColorBrush(active ? COLOR_ACTIVECAPTION :
Alexandre Julliard02e90081998-01-04 17:49:09 +00001338 COLOR_INACTIVECAPTION) );
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001339
Eric Kohl8e517b51998-10-11 13:06:35 +00001340 if ((style & WS_SYSMENU) && !(exStyle & WS_EX_TOOLWINDOW)) {
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001341 if (NC_DrawSysButton95 (hwnd, hdc, FALSE))
Marcus Meissnerddca3151999-05-22 11:33:23 +00001342 r.left += GetSystemMetrics(SM_CYCAPTION) - 1;
Eric Kohl8e517b51998-10-11 13:06:35 +00001343 }
Pascal Lessardd814bb61999-07-31 13:02:02 +00001344
Vincent Béron9a624912002-05-31 23:06:46 +00001345 if (style & WS_SYSMENU)
Pascal Lessardd814bb61999-07-31 13:02:02 +00001346 {
1347 UINT state;
1348
1349 /* Go get the sysmenu */
1350 hSysMenu = GetSystemMenu(hwnd, FALSE);
1351 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
1352
1353 /* Draw a grayed close button if disabled and a normal one if SC_CLOSE is not there */
Vincent Béron9a624912002-05-31 23:06:46 +00001354 NC_DrawCloseButton95 (hwnd, hdc, FALSE,
Pascal Lessardd814bb61999-07-31 13:02:02 +00001355 ((((state & MF_DISABLED) || (state & MF_GRAYED))) && (state != 0xFFFFFFFF)));
Marcus Meissnerddca3151999-05-22 11:33:23 +00001356 r.right -= GetSystemMetrics(SM_CYCAPTION) - 1;
Pascal Lessardd814bb61999-07-31 13:02:02 +00001357
1358 if ((style & WS_MAXIMIZEBOX) || (style & WS_MINIMIZEBOX))
1359 {
1360 /* In win95 the two buttons are always there */
1361 /* But if the menu item is not in the menu they're disabled*/
1362
1363 NC_DrawMaxButton95( hwnd, hdc, FALSE, (!(style & WS_MAXIMIZEBOX)));
1364 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
Vincent Béron9a624912002-05-31 23:06:46 +00001365
Pascal Lessardd814bb61999-07-31 13:02:02 +00001366 NC_DrawMinButton95( hwnd, hdc, FALSE, (!(style & WS_MINIMIZEBOX)));
1367 r.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1368 }
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001369 }
1370
Alexandre Julliarda3960291999-02-26 11:11:13 +00001371 if (GetWindowTextA( hwnd, buffer, sizeof(buffer) )) {
1372 NONCLIENTMETRICSA nclm;
1373 HFONT hFont, hOldFont;
1374 nclm.cbSize = sizeof(NONCLIENTMETRICSA);
1375 SystemParametersInfoA (SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
Eric Kohl8e517b51998-10-11 13:06:35 +00001376 if (exStyle & WS_EX_TOOLWINDOW)
Alexandre Julliarda3960291999-02-26 11:11:13 +00001377 hFont = CreateFontIndirectA (&nclm.lfSmCaptionFont);
Eric Kohl8e517b51998-10-11 13:06:35 +00001378 else
Alexandre Julliarda3960291999-02-26 11:11:13 +00001379 hFont = CreateFontIndirectA (&nclm.lfCaptionFont);
1380 hOldFont = SelectObject (hdc, hFont);
1381 if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
1382 else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) );
1383 SetBkMode( hdc, TRANSPARENT );
Alexandre Julliardf90efa91998-06-14 15:24:15 +00001384 r.left += 2;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001385 DrawTextA( hdc, buffer, -1, &r,
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001386 DT_SINGLELINE | DT_VCENTER | DT_NOPREFIX | DT_LEFT );
Alexandre Julliarda3960291999-02-26 11:11:13 +00001387 DeleteObject (SelectObject (hdc, hOldFont));
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001388 }
1389}
1390
1391
1392
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001393/***********************************************************************
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001394 * NC_DoNCPaint
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001395 *
Alexandre Julliardc981d0b1996-03-31 16:40:13 +00001396 * Paint the non-client area. clip is currently unused.
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001397 */
Gerard Patele9b4fd12001-11-30 23:13:22 +00001398static void NC_DoNCPaint( HWND hwnd, HRGN clip, BOOL suppress_menupaint )
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001399{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001400 HDC hdc;
1401 RECT rect;
1402 BOOL active;
Gerard Patele9b4fd12001-11-30 23:13:22 +00001403 WND *wndPtr;
1404 DWORD dwStyle, dwExStyle;
1405 WORD flags;
1406 RECT rectClient, rectWindow;
1407 int has_menu;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001408
Gerard Patele9b4fd12001-11-30 23:13:22 +00001409 if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return;
1410 has_menu = HAS_MENU(wndPtr);
1411 dwStyle = wndPtr->dwStyle;
Vincent Béron9a624912002-05-31 23:06:46 +00001412 dwExStyle = wndPtr->dwExStyle;
Gerard Patele9b4fd12001-11-30 23:13:22 +00001413 flags = wndPtr->flags;
1414 rectClient = wndPtr->rectClient;
1415 rectWindow = wndPtr->rectWindow;
1416 WIN_ReleasePtr( wndPtr );
1417
1418 if ( dwStyle & WS_MINIMIZE ||
Alexandre Julliard8fd26b92001-10-15 17:56:45 +00001419 !WIN_IsWindowDrawable( hwnd, 0 )) return; /* Nothing to do */
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001420
Gerard Patele9b4fd12001-11-30 23:13:22 +00001421 active = flags & WIN_NCACTIVATED;
Alexandre Julliardc981d0b1996-03-31 16:40:13 +00001422
Alexandre Julliardaff7dda2002-11-22 21:22:14 +00001423 TRACE("%p %d\n", hwnd, active );
Alexandre Julliardc981d0b1996-03-31 16:40:13 +00001424
Michael Stefaniucec5612e2002-10-30 23:45:38 +00001425 if (!(hdc = GetDCEx( hwnd, (clip > (HRGN)1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1426 ((clip > (HRGN)1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN): 0) ))) return;
Alexandre Julliard940d58c1994-09-16 09:24:37 +00001427
Michael Stefaniucec5612e2002-10-30 23:45:38 +00001428 if (ExcludeVisRect16( HDC_16(hdc), rectClient.left-rectWindow.left,
Gerard Patele9b4fd12001-11-30 23:13:22 +00001429 rectClient.top-rectWindow.top,
1430 rectClient.right-rectWindow.left,
1431 rectClient.bottom-rectWindow.top )
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001432 == NULLREGION)
1433 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001434 ReleaseDC( hwnd, hdc );
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001435 return;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001436 }
1437
1438 rect.top = rect.left = 0;
Gerard Patele9b4fd12001-11-30 23:13:22 +00001439 rect.right = rectWindow.right - rectWindow.left;
1440 rect.bottom = rectWindow.bottom - rectWindow.top;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001441
Alexandre Julliard4344c362002-05-20 18:15:28 +00001442 SelectObject( hdc, SYSCOLOR_GetPen(COLOR_WINDOWFRAME) );
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001443
Gerard Patele9b4fd12001-11-30 23:13:22 +00001444 if (HAS_ANYFRAME( dwStyle, dwExStyle ))
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001445 {
Alexandre Julliarddc4fe772001-06-04 21:55:17 +00001446 SelectObject( hdc, GetStockObject(NULL_BRUSH) );
1447 Rectangle( hdc, 0, 0, rect.right, rect.bottom );
1448 InflateRect( &rect, -1, -1 );
1449 }
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001450
Gerard Patele9b4fd12001-11-30 23:13:22 +00001451 if (HAS_THICKFRAME( dwStyle, dwExStyle ))
Alexandre Julliarddc4fe772001-06-04 21:55:17 +00001452 NC_DrawFrame(hdc, &rect, FALSE, active );
Gerard Patele9b4fd12001-11-30 23:13:22 +00001453 else if (HAS_DLGFRAME( dwStyle, dwExStyle ))
Alexandre Julliarddc4fe772001-06-04 21:55:17 +00001454 NC_DrawFrame( hdc, &rect, TRUE, active );
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001455
Gerard Patele9b4fd12001-11-30 23:13:22 +00001456 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
Alexandre Julliarddc4fe772001-06-04 21:55:17 +00001457 {
1458 RECT r = rect;
1459 r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
1460 rect.top += GetSystemMetrics(SM_CYSIZE) + GetSystemMetrics(SM_CYBORDER);
Gerard Patele9b4fd12001-11-30 23:13:22 +00001461 NC_DrawCaption( hdc, &r, hwnd, dwStyle, active );
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001462 }
1463
Gerard Patele9b4fd12001-11-30 23:13:22 +00001464 if (has_menu)
Alexandre Julliardf7207251994-07-23 07:57:48 +00001465 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001466 RECT r = rect;
Marcus Meissnerddca3151999-05-22 11:33:23 +00001467 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU); /* default height */
Alexandre Julliard940d58c1994-09-16 09:24:37 +00001468 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint );
Alexandre Julliardf7207251994-07-23 07:57:48 +00001469 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001470
Alexandre Julliardecc37121994-11-22 16:31:29 +00001471 /* Draw the scroll-bars */
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001472
Gerard Patele9b4fd12001-11-30 23:13:22 +00001473 if (dwStyle & WS_VSCROLL)
Alex Korobkad2085841998-10-18 10:37:46 +00001474 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
Gerard Patele9b4fd12001-11-30 23:13:22 +00001475 if (dwStyle & WS_HSCROLL)
Alex Korobkad2085841998-10-18 10:37:46 +00001476 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
Alexandre Julliardecc37121994-11-22 16:31:29 +00001477
1478 /* Draw the "size-box" */
1479
Gerard Patele9b4fd12001-11-30 23:13:22 +00001480 if ((dwStyle & WS_VSCROLL) && (dwStyle & WS_HSCROLL))
Alexandre Julliardecc37121994-11-22 16:31:29 +00001481 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001482 RECT r = rect;
Alberto Massaribf9390e2003-01-14 23:41:01 +00001483 if((dwExStyle & WS_EX_LEFTSCROLLBAR) != 0)
1484 r.right = r.left + GetSystemMetrics(SM_CXVSCROLL) + 1;
1485 else
1486 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
Marcus Meissnerddca3151999-05-22 11:33:23 +00001487 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
Alexandre Julliardf90efa91998-06-14 15:24:15 +00001488 if(wndPtr->dwStyle & WS_BORDER) {
1489 r.left++;
1490 r.top++;
1491 }
Alexandre Julliarda3960291999-02-26 11:11:13 +00001492 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
Vincent Béron9a624912002-05-31 23:06:46 +00001493 }
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001494
Alexandre Julliarda3960291999-02-26 11:11:13 +00001495 ReleaseDC( hwnd, hdc );
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001496}
1497
1498
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001499/******************************************************************************
1500 *
1501 * void NC_DoNCPaint95(
Gerard Patele9b4fd12001-11-30 23:13:22 +00001502 * HWND hwnd,
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001503 * HRGN clip,
1504 * BOOL suppress_menupaint )
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001505 *
1506 * Paint the non-client area for Win95 windows. The clip region is
1507 * currently ignored.
1508 *
1509 * Bugs
1510 * grep -E -A10 -B5 \(95\)\|\(Bugs\)\|\(FIXME\) windows/nonclient.c \
1511 * misc/tweak.c controls/menu.c # :-)
1512 *
1513 * Revision history
1514 * 03-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
1515 * Original implementation
Alexandre Julliardf90efa91998-06-14 15:24:15 +00001516 * 10-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
1517 * Fixed some bugs.
Ove Kaaven60c78f11999-07-03 15:40:29 +00001518 * 29-Jun-1999 Ove Kåven (ovek@arcticnet.no)
1519 * Streamlined window style checks.
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001520 *
1521 *****************************************************************************/
1522
Patrik Stridvall1ed4ecf1999-06-26 14:58:24 +00001523static void NC_DoNCPaint95(
Gerard Patele9b4fd12001-11-30 23:13:22 +00001524 HWND hwnd,
Alexandre Julliarda3960291999-02-26 11:11:13 +00001525 HRGN clip,
1526 BOOL suppress_menupaint )
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001527{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001528 HDC hdc;
Alex Korobka4f1ac051999-03-28 09:37:57 +00001529 RECT rfuzz, rect, rectClip;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001530 BOOL active;
Gerard Patele9b4fd12001-11-30 23:13:22 +00001531 WND *wndPtr;
1532 DWORD dwStyle, dwExStyle;
1533 WORD flags;
1534 RECT rectClient, rectWindow;
1535 int has_menu;
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001536
Gerard Patele9b4fd12001-11-30 23:13:22 +00001537 if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return;
1538 has_menu = HAS_MENU(wndPtr);
1539 dwStyle = wndPtr->dwStyle;
Vincent Béron9a624912002-05-31 23:06:46 +00001540 dwExStyle = wndPtr->dwExStyle;
Gerard Patele9b4fd12001-11-30 23:13:22 +00001541 flags = wndPtr->flags;
1542 rectClient = wndPtr->rectClient;
1543 rectWindow = wndPtr->rectWindow;
1544 WIN_ReleasePtr( wndPtr );
1545
1546 if ( dwStyle & WS_MINIMIZE ||
Alexandre Julliard8fd26b92001-10-15 17:56:45 +00001547 !WIN_IsWindowDrawable( hwnd, 0 )) return; /* Nothing to do */
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001548
Gerard Patele9b4fd12001-11-30 23:13:22 +00001549 active = flags & WIN_NCACTIVATED;
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001550
Alexandre Julliardaff7dda2002-11-22 21:22:14 +00001551 TRACE("%p %d\n", hwnd, active );
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001552
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001553 /* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
1554 the call to GetDCEx implying that it is allowed not to use it either.
1555 However, the suggested GetDCEx( , DCX_WINDOW | DCX_INTERSECTRGN)
1556 will cause clipRgn to be deleted after ReleaseDC().
1557 Now, how is the "system" supposed to tell what happened?
Alex Korobka4f1ac051999-03-28 09:37:57 +00001558 */
1559
Michael Stefaniucec5612e2002-10-30 23:45:38 +00001560 if (!(hdc = GetDCEx( hwnd, (clip > (HRGN)1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
1561 ((clip > (HRGN)1) ?(DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0) ))) return;
Alex Korobka4f1ac051999-03-28 09:37:57 +00001562
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001563
Michael Stefaniucec5612e2002-10-30 23:45:38 +00001564 if (ExcludeVisRect16( HDC_16(hdc), rectClient.left-rectWindow.left,
Gerard Patele9b4fd12001-11-30 23:13:22 +00001565 rectClient.top-rectWindow.top,
1566 rectClient.right-rectWindow.left,
1567 rectClient.bottom-rectWindow.top )
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001568 == NULLREGION)
1569 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001570 ReleaseDC( hwnd, hdc );
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001571 return;
1572 }
1573
1574 rect.top = rect.left = 0;
Gerard Patele9b4fd12001-11-30 23:13:22 +00001575 rect.right = rectWindow.right - rectWindow.left;
1576 rect.bottom = rectWindow.bottom - rectWindow.top;
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001577
Michael Stefaniucec5612e2002-10-30 23:45:38 +00001578 if( clip > (HRGN)1 )
Alex Korobka4f1ac051999-03-28 09:37:57 +00001579 GetRgnBox( clip, &rectClip );
1580 else
1581 {
1582 clip = 0;
1583 rectClip = rect;
1584 }
1585
Alexandre Julliard4344c362002-05-20 18:15:28 +00001586 SelectObject( hdc, SYSCOLOR_GetPen(COLOR_WINDOWFRAME) );
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001587
Gerard Patele9b4fd12001-11-30 23:13:22 +00001588 if (HAS_STATICOUTERFRAME(dwStyle, dwExStyle)) {
Bill Medlandcbfbf2a2001-07-20 18:36:49 +00001589 DrawEdge (hdc, &rect, BDR_SUNKENOUTER, BF_RECT | BF_ADJUST);
1590 }
Gerard Patele9b4fd12001-11-30 23:13:22 +00001591 else if (HAS_BIGFRAME( dwStyle, dwExStyle)) {
Alexandre Julliarddc4fe772001-06-04 21:55:17 +00001592 DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT | BF_ADJUST);
1593 }
Bill Medlandcbfbf2a2001-07-20 18:36:49 +00001594
Gerard Patele9b4fd12001-11-30 23:13:22 +00001595 NC_DrawFrame95(hdc, &rect, active, dwStyle, dwExStyle );
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001596
Gerard Patele9b4fd12001-11-30 23:13:22 +00001597 if ((dwStyle & WS_CAPTION) == WS_CAPTION)
Alexandre Julliarddc4fe772001-06-04 21:55:17 +00001598 {
1599 RECT r = rect;
Gerard Patele9b4fd12001-11-30 23:13:22 +00001600 if (dwExStyle & WS_EX_TOOLWINDOW) {
Alexandre Julliarddc4fe772001-06-04 21:55:17 +00001601 r.bottom = rect.top + GetSystemMetrics(SM_CYSMCAPTION);
1602 rect.top += GetSystemMetrics(SM_CYSMCAPTION);
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001603 }
Alexandre Julliarddc4fe772001-06-04 21:55:17 +00001604 else {
1605 r.bottom = rect.top + GetSystemMetrics(SM_CYCAPTION);
1606 rect.top += GetSystemMetrics(SM_CYCAPTION);
1607 }
1608 if( !clip || IntersectRect( &rfuzz, &r, &rectClip ) )
Gerard Patele9b4fd12001-11-30 23:13:22 +00001609 NC_DrawCaption95 (hdc, &r, hwnd, dwStyle,
1610 dwExStyle, active);
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001611 }
1612
Gerard Patele9b4fd12001-11-30 23:13:22 +00001613 if (has_menu)
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001614 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001615 RECT r = rect;
Marcus Meissnerddca3151999-05-22 11:33:23 +00001616 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
Vincent Béron9a624912002-05-31 23:06:46 +00001617
Dan Kegel0fd521f2003-01-08 21:09:25 +00001618 TRACE("Calling DrawMenuBar with rect (%ld, %ld)-(%ld, %ld)\n",
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001619 r.left, r.top, r.right, r.bottom);
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001620
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001621 rect.top += MENU_DrawMenuBar( hdc, &r, hwnd, suppress_menupaint ) + 1;
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001622 }
1623
Dan Kegel0fd521f2003-01-08 21:09:25 +00001624 TRACE("After MenuBar, rect is (%ld, %ld)-(%ld, %ld).\n",
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001625 rect.left, rect.top, rect.right, rect.bottom );
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001626
Gerard Patele9b4fd12001-11-30 23:13:22 +00001627 if (dwExStyle & WS_EX_CLIENTEDGE)
Alexandre Julliarda3960291999-02-26 11:11:13 +00001628 DrawEdge (hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001629
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001630 /* Draw the scroll-bars */
1631
Gerard Patele9b4fd12001-11-30 23:13:22 +00001632 if (dwStyle & WS_VSCROLL)
Alex Korobkad2085841998-10-18 10:37:46 +00001633 SCROLL_DrawScrollBar( hwnd, hdc, SB_VERT, TRUE, TRUE );
Gerard Patele9b4fd12001-11-30 23:13:22 +00001634 if (dwStyle & WS_HSCROLL)
Alex Korobkad2085841998-10-18 10:37:46 +00001635 SCROLL_DrawScrollBar( hwnd, hdc, SB_HORZ, TRUE, TRUE );
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001636
1637 /* Draw the "size-box" */
Gerard Patele9b4fd12001-11-30 23:13:22 +00001638 if ((dwStyle & WS_VSCROLL) && (dwStyle & WS_HSCROLL))
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001639 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001640 RECT r = rect;
Alberto Massaribf9390e2003-01-14 23:41:01 +00001641 if((dwExStyle & WS_EX_LEFTSCROLLBAR) != 0)
1642 r.right = r.left + GetSystemMetrics(SM_CXVSCROLL) + 1;
1643 else
1644 r.left = r.right - GetSystemMetrics(SM_CXVSCROLL) + 1;
Marcus Meissnerddca3151999-05-22 11:33:23 +00001645 r.top = r.bottom - GetSystemMetrics(SM_CYHSCROLL) + 1;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001646 FillRect( hdc, &r, GetSysColorBrush(COLOR_SCROLLBAR) );
Vincent Béron9a624912002-05-31 23:06:46 +00001647 }
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001648
Alexandre Julliarda3960291999-02-26 11:11:13 +00001649 ReleaseDC( hwnd, hdc );
Alexandre Julliardd37eb361997-07-20 16:23:21 +00001650}
1651
1652
1653
Alexandre Julliard988ca971994-06-21 16:15:21 +00001654
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001655/***********************************************************************
1656 * NC_HandleNCPaint
1657 *
1658 * Handle a WM_NCPAINT message. Called from DefWindowProc().
1659 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001660LONG NC_HandleNCPaint( HWND hwnd , HRGN clip)
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001661{
Gerard Patele9b4fd12001-11-30 23:13:22 +00001662 DWORD dwStyle = GetWindowLongW( hwnd, GWL_STYLE );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001663
Gerard Patele9b4fd12001-11-30 23:13:22 +00001664 if( dwStyle & WS_VISIBLE )
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001665 {
Gerard Patele9b4fd12001-11-30 23:13:22 +00001666 if( dwStyle & WS_MINIMIZE )
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001667 WINPOS_RedrawIconTitle( hwnd );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001668 else if (TWEAK_WineLook == WIN31_LOOK)
Gerard Patele9b4fd12001-11-30 23:13:22 +00001669 NC_DoNCPaint( hwnd, clip, FALSE );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001670 else
Gerard Patele9b4fd12001-11-30 23:13:22 +00001671 NC_DoNCPaint95( hwnd, clip, FALSE );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001672 }
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001673 return 0;
1674}
1675
1676
1677/***********************************************************************
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001678 * NC_HandleNCActivate
1679 *
1680 * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
1681 */
Alexandre Julliardde424282001-08-10 22:51:42 +00001682LONG NC_HandleNCActivate( HWND hwnd, WPARAM wParam )
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001683{
Alexandre Julliardde424282001-08-10 22:51:42 +00001684 WND* wndPtr = WIN_FindWndPtr( hwnd );
1685
Dmitry Timoshkovd1e648f2001-06-04 02:49:22 +00001686 /* Lotus Notes draws menu descriptions in the caption of its main
1687 * window. When it wants to restore original "system" view, it just
1688 * sends WM_NCACTIVATE message to itself. Any optimizations here in
1689 * attempt to minimize redrawings lead to a not restored caption.
1690 */
Alexandre Julliardde424282001-08-10 22:51:42 +00001691 if (wndPtr)
Alexandre Julliard1e37a181996-08-18 16:21:52 +00001692 {
Alexandre Julliard23946ad1997-06-16 17:43:53 +00001693 if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
1694 else wndPtr->flags &= ~WIN_NCACTIVATED;
Gerard Patele9b4fd12001-11-30 23:13:22 +00001695 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard1e37a181996-08-18 16:21:52 +00001696
Alexandre Julliardde424282001-08-10 22:51:42 +00001697 if (IsIconic(hwnd)) WINPOS_RedrawIconTitle( hwnd );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001698 else if (TWEAK_WineLook == WIN31_LOOK)
Gerard Patele9b4fd12001-11-30 23:13:22 +00001699 NC_DoNCPaint( hwnd, (HRGN)1, FALSE );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001700 else
Gerard Patele9b4fd12001-11-30 23:13:22 +00001701 NC_DoNCPaint95( hwnd, (HRGN)1, FALSE );
Alexandre Julliard1e37a181996-08-18 16:21:52 +00001702 }
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001703 return TRUE;
1704}
1705
1706
1707/***********************************************************************
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001708 * NC_HandleSetCursor
1709 *
1710 * Handle a WM_SETCURSOR message. Called from DefWindowProc().
1711 */
Alexandre Julliardcb25e252001-08-08 23:28:42 +00001712LONG NC_HandleSetCursor( HWND hwnd, WPARAM wParam, LPARAM lParam )
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001713{
Dmitry Timoshkov5474aa92002-04-09 01:37:06 +00001714 hwnd = WIN_GetFullHandle( (HWND)wParam );
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001715
1716 switch(LOWORD(lParam))
1717 {
1718 case HTERROR:
1719 {
1720 WORD msg = HIWORD( lParam );
1721 if ((msg == WM_LBUTTONDOWN) || (msg == WM_MBUTTONDOWN) ||
1722 (msg == WM_RBUTTONDOWN))
Alexandre Julliarda3960291999-02-26 11:11:13 +00001723 MessageBeep(0);
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001724 }
1725 break;
1726
1727 case HTCLIENT:
1728 {
Michael Stefaniucbc54d782002-10-10 21:22:09 +00001729 HCURSOR hCursor = (HCURSOR)GetClassLongA(hwnd, GCL_HCURSOR);
Gerard Patel5773dad1999-06-12 14:45:56 +00001730 if(hCursor) {
Alexandre Julliardd44e4952001-08-20 18:09:39 +00001731 SetCursor(hCursor);
Gerard Patel5773dad1999-06-12 14:45:56 +00001732 return TRUE;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001733 }
Gerard Patel5773dad1999-06-12 14:45:56 +00001734 return FALSE;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001735 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001736
1737 case HTLEFT:
1738 case HTRIGHT:
Alexandre Julliard2682bc22000-11-27 22:03:23 +00001739 return (LONG)SetCursor( LoadCursorA( 0, IDC_SIZEWEA ) );
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001740
1741 case HTTOP:
1742 case HTBOTTOM:
Alexandre Julliard2682bc22000-11-27 22:03:23 +00001743 return (LONG)SetCursor( LoadCursorA( 0, IDC_SIZENSA ) );
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001744
1745 case HTTOPLEFT:
Vincent Béron9a624912002-05-31 23:06:46 +00001746 case HTBOTTOMRIGHT:
Alexandre Julliard2682bc22000-11-27 22:03:23 +00001747 return (LONG)SetCursor( LoadCursorA( 0, IDC_SIZENWSEA ) );
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001748
1749 case HTTOPRIGHT:
1750 case HTBOTTOMLEFT:
Alexandre Julliard2682bc22000-11-27 22:03:23 +00001751 return (LONG)SetCursor( LoadCursorA( 0, IDC_SIZENESWA ) );
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001752 }
1753
1754 /* Default cursor: arrow */
Alexandre Julliard2682bc22000-11-27 22:03:23 +00001755 return (LONG)SetCursor( LoadCursorA( 0, IDC_ARROWA ) );
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001756}
1757
Alexandre Julliard1e37a181996-08-18 16:21:52 +00001758/***********************************************************************
1759 * NC_GetSysPopupPos
1760 */
Alexandre Julliardde424282001-08-10 22:51:42 +00001761void NC_GetSysPopupPos( HWND hwnd, RECT* rect )
Alexandre Julliard1e37a181996-08-18 16:21:52 +00001762{
Alexandre Julliardde424282001-08-10 22:51:42 +00001763 if (IsIconic(hwnd)) GetWindowRect( hwnd, rect );
1764 else
1765 {
1766 WND *wndPtr = WIN_FindWndPtr( hwnd );
1767 if (!wndPtr) return;
1768
1769 NC_GetInsideRect( hwnd, rect );
1770 OffsetRect( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top);
1771 if (wndPtr->dwStyle & WS_CHILD)
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00001772 ClientToScreen( GetParent(hwnd), (POINT *)rect );
Alexandre Julliardde424282001-08-10 22:51:42 +00001773 if (TWEAK_WineLook == WIN31_LOOK) {
Marcus Meissnerddca3151999-05-22 11:33:23 +00001774 rect->right = rect->left + GetSystemMetrics(SM_CXSIZE);
1775 rect->bottom = rect->top + GetSystemMetrics(SM_CYSIZE);
Alexandre Julliardde424282001-08-10 22:51:42 +00001776 }
1777 else {
Marcus Meissnerddca3151999-05-22 11:33:23 +00001778 rect->right = rect->left + GetSystemMetrics(SM_CYCAPTION) - 1;
1779 rect->bottom = rect->top + GetSystemMetrics(SM_CYCAPTION) - 1;
Alexandre Julliardde424282001-08-10 22:51:42 +00001780 }
1781 WIN_ReleaseWndPtr( wndPtr );
1782 }
Alexandre Julliard1e37a181996-08-18 16:21:52 +00001783}
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001784
1785/***********************************************************************
Pascal Lessardd814bb61999-07-31 13:02:02 +00001786 * NC_TrackMinMaxBox95
1787 *
1788 * Track a mouse button press on the minimize or maximize box.
1789 *
1790 * The big difference between 3.1 and 95 is the disabled button state.
1791 * In win95 the system button can be disabled, so it can ignore the mouse
1792 * event.
1793 *
1794 */
1795static void NC_TrackMinMaxBox95( HWND hwnd, WORD wParam )
1796{
1797 MSG msg;
Pascal Lessardd814bb61999-07-31 13:02:02 +00001798 HDC hdc = GetWindowDC( hwnd );
1799 BOOL pressed = TRUE;
1800 UINT state;
1801 DWORD wndStyle = GetWindowLongA( hwnd, GWL_STYLE);
1802 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
1803
Michael Stefaniucec5612e2002-10-30 23:45:38 +00001804 void (*paintButton)(HWND, HDC, BOOL, BOOL);
Pascal Lessardd814bb61999-07-31 13:02:02 +00001805
1806 if (wParam == HTMINBUTTON)
1807 {
1808 /* If the style is not present, do nothing */
1809 if (!(wndStyle & WS_MINIMIZEBOX))
1810 return;
1811
1812 /* Check if the sysmenu item for minimize is there */
1813 state = GetMenuState(hSysMenu, SC_MINIMIZE, MF_BYCOMMAND);
Vincent Béron9a624912002-05-31 23:06:46 +00001814
Pascal Lessardd814bb61999-07-31 13:02:02 +00001815 paintButton = &NC_DrawMinButton95;
1816 }
1817 else
1818 {
1819 /* If the style is not present, do nothing */
1820 if (!(wndStyle & WS_MAXIMIZEBOX))
1821 return;
1822
1823 /* Check if the sysmenu item for maximize is there */
1824 state = GetMenuState(hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND);
Vincent Béron9a624912002-05-31 23:06:46 +00001825
Pascal Lessardd814bb61999-07-31 13:02:02 +00001826 paintButton = &NC_DrawMaxButton95;
1827 }
1828
1829 SetCapture( hwnd );
1830
1831 (*paintButton)( hwnd, hdc, TRUE, FALSE);
1832
Dmitry Timoshkov63ba91d2000-10-15 00:22:29 +00001833 while(1)
Pascal Lessardd814bb61999-07-31 13:02:02 +00001834 {
1835 BOOL oldstate = pressed;
Alexandre Julliardbfb4a232001-08-06 18:05:47 +00001836
1837 if (!GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST )) break;
1838 if (CallMsgFilterW( &msg, MSGF_MAX )) continue;
Pascal Lessardd814bb61999-07-31 13:02:02 +00001839
Dmitry Timoshkov63ba91d2000-10-15 00:22:29 +00001840 if(msg.message == WM_LBUTTONUP)
1841 break;
1842
1843 if(msg.message != WM_MOUSEMOVE)
1844 continue;
1845
Alexandre Julliard83f52d12000-09-26 22:20:14 +00001846 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
Pascal Lessardd814bb61999-07-31 13:02:02 +00001847 if (pressed != oldstate)
1848 (*paintButton)( hwnd, hdc, pressed, FALSE);
Dmitry Timoshkov63ba91d2000-10-15 00:22:29 +00001849 }
Pascal Lessardd814bb61999-07-31 13:02:02 +00001850
Dmitry Timoshkov63ba91d2000-10-15 00:22:29 +00001851 if(pressed)
1852 (*paintButton)(hwnd, hdc, FALSE, FALSE);
Pascal Lessardd814bb61999-07-31 13:02:02 +00001853
1854 ReleaseCapture();
1855 ReleaseDC( hwnd, hdc );
1856
1857 /* If the item minimize or maximize of the sysmenu are not there */
1858 /* or if the style is not present, do nothing */
1859 if ((!pressed) || (state == 0xFFFFFFFF))
1860 return;
1861
Vincent Béron9a624912002-05-31 23:06:46 +00001862 if (wParam == HTMINBUTTON)
Alexandre Julliard83f52d12000-09-26 22:20:14 +00001863 SendMessageA( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
Pascal Lessardd814bb61999-07-31 13:02:02 +00001864 else
Alexandre Julliard83f52d12000-09-26 22:20:14 +00001865 SendMessageA( hwnd, WM_SYSCOMMAND,
1866 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
Pascal Lessardd814bb61999-07-31 13:02:02 +00001867}
1868
1869/***********************************************************************
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001870 * NC_TrackMinMaxBox
1871 *
1872 * Track a mouse button press on the minimize or maximize box.
1873 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001874static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001875{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001876 MSG msg;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001877 HDC hdc = GetWindowDC( hwnd );
1878 BOOL pressed = TRUE;
Michael Stefaniucec5612e2002-10-30 23:45:38 +00001879 void (*paintButton)(HWND, HDC, BOOL);
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001880
Alexandre Julliarda3960291999-02-26 11:11:13 +00001881 SetCapture( hwnd );
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00001882
Pascal Lessardd814bb61999-07-31 13:02:02 +00001883 if (wParam == HTMINBUTTON)
1884 paintButton = &NC_DrawMinButton;
1885 else
1886 paintButton = &NC_DrawMaxButton;
1887
1888 (*paintButton)( hwnd, hdc, TRUE);
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001889
Dmitry Timoshkov63ba91d2000-10-15 00:22:29 +00001890 while(1)
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001891 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001892 BOOL oldstate = pressed;
Alexandre Julliardbfb4a232001-08-06 18:05:47 +00001893
1894 if (!GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST )) break;
1895 if (CallMsgFilterW( &msg, MSGF_MAX )) continue;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001896
Dmitry Timoshkov63ba91d2000-10-15 00:22:29 +00001897 if(msg.message == WM_LBUTTONUP)
1898 break;
1899
1900 if(msg.message != WM_MOUSEMOVE)
1901 continue;
1902
Alexandre Julliard83f52d12000-09-26 22:20:14 +00001903 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001904 if (pressed != oldstate)
Pascal Lessardd814bb61999-07-31 13:02:02 +00001905 (*paintButton)( hwnd, hdc, pressed);
Dmitry Timoshkov63ba91d2000-10-15 00:22:29 +00001906 }
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001907
Dmitry Timoshkov63ba91d2000-10-15 00:22:29 +00001908 if(pressed)
1909 (*paintButton)( hwnd, hdc, FALSE);
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001910
1911 ReleaseCapture();
Alexandre Julliarda3960291999-02-26 11:11:13 +00001912 ReleaseDC( hwnd, hdc );
Pascal Lessardd814bb61999-07-31 13:02:02 +00001913
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001914 if (!pressed) return;
1915
Vincent Béron9a624912002-05-31 23:06:46 +00001916 if (wParam == HTMINBUTTON)
Alexandre Julliard83f52d12000-09-26 22:20:14 +00001917 SendMessageA( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001918 else
Alexandre Julliard83f52d12000-09-26 22:20:14 +00001919 SendMessageA( hwnd, WM_SYSCOMMAND,
1920 IsZoomed(hwnd) ? SC_RESTORE:SC_MAXIMIZE, MAKELONG(msg.pt.x,msg.pt.y) );
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001921}
1922
1923
1924/***********************************************************************
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001925 * NC_TrackCloseButton95
1926 *
1927 * Track a mouse button press on the Win95 close button.
1928 */
1929static void
Alexandre Julliarda3960291999-02-26 11:11:13 +00001930NC_TrackCloseButton95 (HWND hwnd, WORD wParam)
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001931{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001932 MSG msg;
Pascal Lessardd814bb61999-07-31 13:02:02 +00001933 HDC hdc;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001934 BOOL pressed = TRUE;
Pascal Lessardd814bb61999-07-31 13:02:02 +00001935 HMENU hSysMenu = GetSystemMenu(hwnd, FALSE);
1936 UINT state;
1937
1938 if(hSysMenu == 0)
1939 return;
1940
1941 state = GetMenuState(hSysMenu, SC_CLOSE, MF_BYCOMMAND);
Vincent Béron9a624912002-05-31 23:06:46 +00001942
Pascal Lessardd814bb61999-07-31 13:02:02 +00001943 /* If the item close of the sysmenu is disabled or not there do nothing */
1944 if((state & MF_DISABLED) || (state & MF_GRAYED) || (state == 0xFFFFFFFF))
1945 return;
1946
1947 hdc = GetWindowDC( hwnd );
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001948
Alexandre Julliarda3960291999-02-26 11:11:13 +00001949 SetCapture( hwnd );
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001950
Pascal Lessardd814bb61999-07-31 13:02:02 +00001951 NC_DrawCloseButton95 (hwnd, hdc, TRUE, FALSE);
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001952
Dmitry Timoshkov63ba91d2000-10-15 00:22:29 +00001953 while(1)
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001954 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001955 BOOL oldstate = pressed;
Alexandre Julliardbfb4a232001-08-06 18:05:47 +00001956
1957 if (!GetMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST )) break;
1958 if (CallMsgFilterW( &msg, MSGF_MAX )) continue;
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001959
Dmitry Timoshkov63ba91d2000-10-15 00:22:29 +00001960 if(msg.message == WM_LBUTTONUP)
1961 break;
1962
1963 if(msg.message != WM_MOUSEMOVE)
1964 continue;
1965
Alexandre Julliard83f52d12000-09-26 22:20:14 +00001966 pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001967 if (pressed != oldstate)
Pascal Lessardd814bb61999-07-31 13:02:02 +00001968 NC_DrawCloseButton95 (hwnd, hdc, pressed, FALSE);
Dmitry Timoshkov63ba91d2000-10-15 00:22:29 +00001969 }
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001970
Dmitry Timoshkov63ba91d2000-10-15 00:22:29 +00001971 if(pressed)
1972 NC_DrawCloseButton95 (hwnd, hdc, FALSE, FALSE);
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001973
1974 ReleaseCapture();
Alexandre Julliarda3960291999-02-26 11:11:13 +00001975 ReleaseDC( hwnd, hdc );
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001976 if (!pressed) return;
1977
Alexandre Julliard83f52d12000-09-26 22:20:14 +00001978 SendMessageA( hwnd, WM_SYSCOMMAND, SC_CLOSE, MAKELONG(msg.pt.x,msg.pt.y) );
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001979}
1980
1981
1982/***********************************************************************
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001983 * NC_TrackScrollBar
1984 *
1985 * Track a mouse button press on the horizontal or vertical scroll-bar.
1986 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001987static void NC_TrackScrollBar( HWND hwnd, WPARAM wParam, POINT pt )
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001988{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001989 INT scrollbar;
Alexandre Julliardecc37121994-11-22 16:31:29 +00001990
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001991 if ((wParam & 0xfff0) == SC_HSCROLL)
1992 {
Alexandre Julliardb662e112001-10-16 21:52:26 +00001993 if ((wParam & 0x0f) != HTHSCROLL) return;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001994 scrollbar = SB_HORZ;
1995 }
1996 else /* SC_VSCROLL */
1997 {
Alexandre Julliardb662e112001-10-16 21:52:26 +00001998 if ((wParam & 0x0f) != HTVSCROLL) return;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001999 scrollbar = SB_VERT;
2000 }
Alexandre Julliardb662e112001-10-16 21:52:26 +00002001 SCROLL_TrackScrollBar( hwnd, scrollbar, pt );
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00002002}
2003
Alexandre Julliardb662e112001-10-16 21:52:26 +00002004
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00002005/***********************************************************************
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002006 * NC_HandleNCLButtonDown
Alexandre Julliardcdd09231994-01-12 11:12:51 +00002007 *
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002008 * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
Alexandre Julliardcdd09231994-01-12 11:12:51 +00002009 */
Alexandre Julliardde424282001-08-10 22:51:42 +00002010LONG NC_HandleNCLButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam )
Alexandre Julliardcdd09231994-01-12 11:12:51 +00002011{
Alexandre Julliardde424282001-08-10 22:51:42 +00002012 LONG style = GetWindowLongA( hwnd, GWL_STYLE );
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00002013
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002014 switch(wParam) /* Hit test */
Alexandre Julliardcdd09231994-01-12 11:12:51 +00002015 {
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002016 case HTCAPTION:
Alexandre Julliardde424282001-08-10 22:51:42 +00002017 {
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00002018 HWND top = GetAncestor( hwnd, GA_ROOT );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002019
Alexandre Julliard5030bda2002-10-11 23:41:06 +00002020 if (FOCUS_MouseActivate( top ) || (GetActiveWindow() == top))
Alexandre Julliardde424282001-08-10 22:51:42 +00002021 SendMessageW( hwnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam );
2022 break;
2023 }
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002024
Alexandre Julliardcdd09231994-01-12 11:12:51 +00002025 case HTSYSMENU:
Alexandre Julliardde424282001-08-10 22:51:42 +00002026 if( style & WS_SYSMENU )
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00002027 {
Alexandre Julliardde424282001-08-10 22:51:42 +00002028 if( !(style & WS_MINIMIZE) )
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00002029 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00002030 HDC hDC = GetWindowDC(hwnd);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002031 if (TWEAK_WineLook == WIN31_LOOK)
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00002032 NC_DrawSysButton( hwnd, hDC, TRUE );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002033 else
2034 NC_DrawSysButton95( hwnd, hDC, TRUE );
Alexandre Julliarda3960291999-02-26 11:11:13 +00002035 ReleaseDC( hwnd, hDC );
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00002036 }
Alexandre Julliardcb25e252001-08-08 23:28:42 +00002037 SendMessageW( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, lParam );
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00002038 }
2039 break;
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002040
2041 case HTMENU:
Alexandre Julliardcb25e252001-08-08 23:28:42 +00002042 SendMessageW( hwnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam );
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002043 break;
2044
2045 case HTHSCROLL:
Alexandre Julliardcb25e252001-08-08 23:28:42 +00002046 SendMessageW( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002047 break;
2048
2049 case HTVSCROLL:
Alexandre Julliardcb25e252001-08-08 23:28:42 +00002050 SendMessageW( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002051 break;
2052
2053 case HTMINBUTTON:
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002054 case HTMAXBUTTON:
Pascal Lessardd814bb61999-07-31 13:02:02 +00002055 if (TWEAK_WineLook == WIN31_LOOK)
2056 NC_TrackMinMaxBox( hwnd, wParam );
2057 else
Vincent Béron9a624912002-05-31 23:06:46 +00002058 NC_TrackMinMaxBox95( hwnd, wParam );
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002059 break;
2060
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00002061 case HTCLOSE:
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002062 if (TWEAK_WineLook >= WIN95_LOOK)
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00002063 NC_TrackCloseButton95 (hwnd, wParam);
2064 break;
Vincent Béron9a624912002-05-31 23:06:46 +00002065
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002066 case HTLEFT:
2067 case HTRIGHT:
2068 case HTTOP:
2069 case HTTOPLEFT:
2070 case HTTOPRIGHT:
2071 case HTBOTTOM:
2072 case HTBOTTOMLEFT:
2073 case HTBOTTOMRIGHT:
Duane Clark5d35bc72003-02-18 23:24:57 +00002074 /* Old comment:
2075 * "make sure hittest fits into 0xf and doesn't overlap with HTSYSMENU"
2076 * This was previously done by setting wParam=SC_SIZE + wParam - 2
2077 */
2078 /* But that is not what WinNT does. Instead it sends this. This
2079 * is easy to differentiate from HTSYSMENU, because HTSYSMENU adds
2080 * SC_MOUSEMENU into wParam.
2081 */
2082 SendMessageW( hwnd, WM_SYSCOMMAND, SC_SIZE + wParam - (HTLEFT-WMSZ_LEFT), lParam);
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002083 break;
2084
2085 case HTBORDER:
2086 break;
2087 }
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002088 return 0;
2089}
2090
2091
2092/***********************************************************************
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002093 * NC_HandleNCLButtonDblClk
2094 *
2095 * Handle a WM_NCLBUTTONDBLCLK message. Called from DefWindowProc().
2096 */
Alexandre Julliardde424282001-08-10 22:51:42 +00002097LONG NC_HandleNCLButtonDblClk( HWND hwnd, WPARAM wParam, LPARAM lParam )
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002098{
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002099 /*
2100 * if this is an icon, send a restore since we are handling
2101 * a double click
2102 */
Alexandre Julliardde424282001-08-10 22:51:42 +00002103 if (IsIconic(hwnd))
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002104 {
Alexandre Julliardde424282001-08-10 22:51:42 +00002105 SendMessageW( hwnd, WM_SYSCOMMAND, SC_RESTORE, lParam );
Alexandre Julliard1285c2f1996-05-06 16:06:24 +00002106 return 0;
Vincent Béron9a624912002-05-31 23:06:46 +00002107 }
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002108
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002109 switch(wParam) /* Hit test */
2110 {
2111 case HTCAPTION:
Alexandre Julliard902da691995-11-05 14:39:02 +00002112 /* stop processing if WS_MAXIMIZEBOX is missing */
Alexandre Julliardde424282001-08-10 22:51:42 +00002113 if (GetWindowLongA( hwnd, GWL_STYLE ) & WS_MAXIMIZEBOX)
2114 SendMessageW( hwnd, WM_SYSCOMMAND,
2115 IsZoomed(hwnd) ? SC_RESTORE : SC_MAXIMIZE, lParam );
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002116 break;
2117
2118 case HTSYSMENU:
Alexandre Julliardd44e4952001-08-20 18:09:39 +00002119 if (!(GetClassLongW(hwnd, GCL_STYLE) & CS_NOCLOSE))
Alexandre Julliardde424282001-08-10 22:51:42 +00002120 SendMessageW( hwnd, WM_SYSCOMMAND, SC_CLOSE, lParam );
Alexandre Julliardcdd09231994-01-12 11:12:51 +00002121 break;
Alexandre Julliard491502b1997-11-01 19:08:16 +00002122
2123 case HTHSCROLL:
Alexandre Julliardde424282001-08-10 22:51:42 +00002124 SendMessageW( hwnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam );
Alexandre Julliard491502b1997-11-01 19:08:16 +00002125 break;
2126
2127 case HTVSCROLL:
Alexandre Julliardde424282001-08-10 22:51:42 +00002128 SendMessageW( hwnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam );
Alexandre Julliard491502b1997-11-01 19:08:16 +00002129 break;
Alexandre Julliardcdd09231994-01-12 11:12:51 +00002130 }
2131 return 0;
2132}
2133
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002134
2135/***********************************************************************
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002136 * NC_HandleSysCommand
2137 *
2138 * Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
2139 */
Alexandre Julliardb662e112001-10-16 21:52:26 +00002140LONG NC_HandleSysCommand( HWND hwnd, WPARAM wParam, LPARAM lParam )
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002141{
Alexandre Julliardb662e112001-10-16 21:52:26 +00002142 TRACE("Handling WM_SYSCOMMAND %x %lx\n", wParam, lParam );
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002143
Alexandre Julliardb662e112001-10-16 21:52:26 +00002144 switch (wParam & 0xfff0)
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002145 {
2146 case SC_SIZE:
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002147 case SC_MOVE:
Alexandre Julliard3abeae82001-05-09 17:21:04 +00002148 if (USER_Driver.pSysCommandSizeMove)
2149 USER_Driver.pSysCommandSizeMove( hwnd, wParam );
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002150 break;
2151
2152 case SC_MINIMIZE:
Noomen Hamzad1a1f7d1999-10-24 00:02:27 +00002153 if (hwnd == GetForegroundWindow())
2154 ShowOwnedPopups(hwnd,FALSE);
Vincent Béron9a624912002-05-31 23:06:46 +00002155 ShowWindow( hwnd, SW_MINIMIZE );
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002156 break;
2157
2158 case SC_MAXIMIZE:
Noomen Hamzad1a1f7d1999-10-24 00:02:27 +00002159 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2160 ShowOwnedPopups(hwnd,TRUE);
Alexandre Julliarda3960291999-02-26 11:11:13 +00002161 ShowWindow( hwnd, SW_MAXIMIZE );
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002162 break;
2163
2164 case SC_RESTORE:
Noomen Hamzad1a1f7d1999-10-24 00:02:27 +00002165 if (IsIconic(hwnd) && hwnd == GetForegroundWindow())
2166 ShowOwnedPopups(hwnd,TRUE);
Alexandre Julliarda3960291999-02-26 11:11:13 +00002167 ShowWindow( hwnd, SW_RESTORE );
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002168 break;
2169
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002170 case SC_CLOSE:
Alexandre Julliard83f52d12000-09-26 22:20:14 +00002171 return SendMessageA( hwnd, WM_CLOSE, 0, 0 );
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002172
2173 case SC_VSCROLL:
2174 case SC_HSCROLL:
Alexandre Julliardb662e112001-10-16 21:52:26 +00002175 {
2176 POINT pt;
2177 pt.x = SLOWORD(lParam);
2178 pt.y = SHIWORD(lParam);
2179 NC_TrackScrollBar( hwnd, wParam, pt );
2180 }
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002181 break;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00002182
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002183 case SC_MOUSEMENU:
Alexandre Julliardb662e112001-10-16 21:52:26 +00002184 {
2185 POINT pt;
2186 pt.x = SLOWORD(lParam);
2187 pt.y = SHIWORD(lParam);
2188 MENU_TrackMouseMenuBar( hwnd, wParam & 0x000F, pt );
2189 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00002190 break;
2191
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002192 case SC_KEYMENU:
Alexandre Julliardb662e112001-10-16 21:52:26 +00002193 MENU_TrackKbdMenuBar( hwnd, wParam, LOWORD(lParam) );
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00002194 break;
Alexandre Julliardb662e112001-10-16 21:52:26 +00002195
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002196 case SC_TASKLIST:
Vincent Béron9a624912002-05-31 23:06:46 +00002197 WinExec( "taskman.exe", SW_SHOWNORMAL );
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002198 break;
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +00002199
2200 case SC_SCREENSAVE:
2201 if (wParam == SC_ABOUTWINE)
Alexandre Julliard563561e2000-01-24 05:46:47 +00002202 {
2203 HMODULE hmodule = LoadLibraryA( "shell32.dll" );
2204 if (hmodule)
2205 {
2206 FARPROC aboutproc = GetProcAddress( hmodule, "ShellAboutA" );
Alexandre Julliarddaa28862002-04-11 21:54:01 +00002207 if (aboutproc) aboutproc( hwnd, PACKAGE_NAME, PACKAGE_STRING, 0 );
Alexandre Julliard563561e2000-01-24 05:46:47 +00002208 FreeLibrary( hmodule );
2209 }
2210 }
Vincent Béron9a624912002-05-31 23:06:46 +00002211 else
Uwe Bonnes37007771998-11-01 15:07:24 +00002212 if (wParam == SC_PUTMARK)
Alexandre Julliard06c275a1999-05-02 14:32:27 +00002213 TRACE_(shell)("Mark requested by user\n");
Alexandre Julliard3f2abfa1994-08-16 15:43:11 +00002214 break;
Vincent Béron9a624912002-05-31 23:06:46 +00002215
Alexandre Julliard9ea19e51997-01-01 17:29:55 +00002216 case SC_HOTKEY:
2217 case SC_ARRANGE:
2218 case SC_NEXTWINDOW:
2219 case SC_PREVWINDOW:
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00002220 FIXME("unimplemented!\n");
Alexandre Julliard9ea19e51997-01-01 17:29:55 +00002221 break;
Alexandre Julliard86a8d0f1994-01-18 23:04:40 +00002222 }
2223 return 0;
2224}
Pascal Lessardd814bb61999-07-31 13:02:02 +00002225
2226/*************************************************************
2227* NC_DrawGrayButton
2228*
2229* Stub for the grayed button of the caption
2230*
2231*************************************************************/
2232
2233BOOL NC_DrawGrayButton(HDC hdc, int x, int y)
2234{
2235 HBITMAP hMaskBmp;
Mike McCormack2d106a52002-11-13 19:43:53 +00002236 HDC hdcMask;
Pascal Lessardd814bb61999-07-31 13:02:02 +00002237 HBRUSH hOldBrush;
2238
2239 hMaskBmp = CreateBitmap (12, 10, 1, 1, lpGrayMask);
Vincent Béron9a624912002-05-31 23:06:46 +00002240
Pascal Lessardd814bb61999-07-31 13:02:02 +00002241 if(hMaskBmp == 0)
2242 return FALSE;
Vincent Béron9a624912002-05-31 23:06:46 +00002243
Mike McCormack2d106a52002-11-13 19:43:53 +00002244 hdcMask = CreateCompatibleDC (0);
Pascal Lessardd814bb61999-07-31 13:02:02 +00002245 SelectObject (hdcMask, hMaskBmp);
Vincent Béron9a624912002-05-31 23:06:46 +00002246
Pascal Lessardd814bb61999-07-31 13:02:02 +00002247 /* Draw the grayed bitmap using the mask */
Michael Stefaniucec5612e2002-10-30 23:45:38 +00002248 hOldBrush = SelectObject (hdc, (HGDIOBJ)RGB(128, 128, 128));
Pascal Lessardd814bb61999-07-31 13:02:02 +00002249 BitBlt (hdc, x, y, 12, 10,
2250 hdcMask, 0, 0, 0xB8074A);
Vincent Béron9a624912002-05-31 23:06:46 +00002251
Pascal Lessardd814bb61999-07-31 13:02:02 +00002252 /* Clean up */
2253 SelectObject (hdc, hOldBrush);
2254 DeleteObject(hMaskBmp);
2255 DeleteDC (hdcMask);
Vincent Béron9a624912002-05-31 23:06:46 +00002256
Pascal Lessardd814bb61999-07-31 13:02:02 +00002257 return TRUE;
2258}