Handle system color background brushes
[reactos.git] / reactos / lib / user32 / windows / defwnd.c
1 /* $Id: defwnd.c,v 1.73 2003/08/20 21:42:27 gvg Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS user32.dll
5 * FILE: lib/user32/windows/window.c
6 * PURPOSE: Window management
7 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * UPDATE HISTORY:
9 * 06-06-2001 CSH Created
10 */
11
12 /* INCLUDES ******************************************************************/
13
14 #include <windows.h>
15 #include <user32.h>
16 #include <window.h>
17 #include <user32/wininternal.h>
18 #include <string.h>
19 #include <menu.h>
20 #include <cursor.h>
21 #include <winpos.h>
22
23 #define NDEBUG
24 #include <debug.h>
25
26 /* GLOBALS *******************************************************************/
27
28 static HBITMAP hbSysMenu;
29 /* TODO: widgets will be cached here.
30 static HBITMAP hbClose;
31 static HBITMAP hbCloseD;
32 static HBITMAP hbMinimize;
33 static HBITMAP hbMinimizeD;
34 static HBITMAP hbRestore;
35 static HBITMAP hbRestoreD;
36 static HBITMAP hbMaximize;
37 static HBITMAP hbScrUp;
38 static HBITMAP hbScrDwn;
39 static HBITMAP hbScrLeft;
40 static HBITMAP hbScrRight;
41 */
42
43
44 static COLORREF SysColours[29] =
45 {
46 RGB(224, 224, 224) /* COLOR_SCROLLBAR */,
47 RGB(58, 110, 165) /* COLOR_BACKGROUND */,
48 RGB(0, 0, 128) /* COLOR_ACTIVECAPTION */,
49 RGB(128, 128, 128) /* COLOR_INACTIVECAPTION */,
50 RGB(192, 192, 192) /* COLOR_MENU */,
51 RGB(192, 192, 192) /* COLOR_WINDOW */,
52 RGB(192, 192, 192) /* COLOR_WINDOWFRAME */,
53 RGB(0, 0, 0) /* COLOR_MENUTEXT */,
54 RGB(0, 0, 0) /* COLOR_WINDOWTEXT */,
55 RGB(255, 255, 255) /* COLOR_CAPTIONTEXT */,
56 RGB(128, 128, 128) /* COLOR_ACTIVEBORDER */,
57 RGB(255, 255, 255) /* COLOR_INACTIVEBORDER */,
58 RGB(255, 255, 232) /* COLOR_APPWORKSPACE */,
59 RGB(224, 224, 224) /* COLOR_HILIGHT */,
60 RGB(0, 0, 128) /* COLOR_HILIGHTTEXT */,
61 RGB(192, 192, 192) /* COLOR_BTNFACE */,
62 RGB(128, 128, 128) /* COLOR_BTNSHADOW */,
63 RGB(192, 192, 192) /* COLOR_GRAYTEXT */,
64 RGB(0, 0, 0) /* COLOR_BTNTEXT */,
65 RGB(192, 192, 192) /* COLOR_INACTIVECAPTIONTEXT */,
66 RGB(255, 255, 255) /* COLOR_BTNHILIGHT */,
67 RGB(32, 32, 32) /* COLOR_3DDKSHADOW */,
68 RGB(192, 192, 192) /* COLOR_3DLIGHT */,
69 RGB(0, 0, 0) /* COLOR_INFOTEXT */,
70 RGB(255, 255, 192) /* COLOR_INFOBK */,
71 RGB(184, 180, 184) /* COLOR_ALTERNATEBTNFACE */,
72 RGB(0, 0, 255) /* COLOR_HOTLIGHT */,
73 RGB(16, 132, 208) /* COLOR_GRADIENTACTIVECAPTION */,
74 RGB(181, 181, 181) /* COLOR_GRADIENTINACTIVECAPTION */,
75 };
76
77 static ATOM AtomInternalPos;
78
79 /* Bits in the dwKeyData */
80 #define KEYDATA_ALT 0x2000
81
82 /* FUNCTIONS *****************************************************************/
83
84 BOOL
85 IsMaxBoxActive(HWND hWnd)
86 {
87 ULONG uStyle = GetWindowLongW( hWnd, GWL_STYLE );
88 return (uStyle & WS_MAXIMIZEBOX);
89 }
90
91 BOOL
92 IsCloseBoxActive( HWND hWnd )
93 {
94 ULONG uStyle = GetWindowLongW(hWnd, GWL_STYLE );
95 return ( uStyle & WS_SYSMENU );
96 }
97
98 BOOL
99 IsMinBoxActive( HWND hWnd )
100 {
101 ULONG uStyle = GetWindowLongW( hWnd, GWL_STYLE );
102 return (uStyle & WS_MINIMIZEBOX);
103 }
104
105 INT
106 UIGetFrameSizeX( HWND hWnd )
107 {
108 ULONG uStyle = GetWindowLongW( hWnd, GWL_STYLE );
109
110 if ( uStyle & WS_THICKFRAME )
111 return GetSystemMetrics( SM_CXSIZEFRAME );
112 else
113 return GetSystemMetrics( SM_CXFRAME );
114 }
115
116 INT
117 UIGetFrameSizeY( HWND hWnd )
118 {
119 ULONG uStyle = GetWindowLongW( hWnd, GWL_STYLE );
120
121 if ( uStyle & WS_THICKFRAME )
122 return GetSystemMetrics( SM_CYSIZEFRAME );
123 else
124 return GetSystemMetrics( SM_CYFRAME );
125 }
126
127 VOID
128 UserSetupInternalPos( VOID )
129 {
130 LPSTR Str = "SysIP";
131 AtomInternalPos = GlobalAddAtomA(Str);
132 }
133
134
135 /*
136 * @implemented
137 */
138 DWORD STDCALL
139 GetSysColor(int nIndex)
140 {
141 return SysColours[nIndex];
142 }
143
144
145 HPEN STDCALL
146 GetSysColorPen( int nIndex )
147 {
148 return(CreatePen(PS_SOLID, 1, SysColours[nIndex]));
149 }
150
151
152 /*
153 * @implemented
154 */
155 HBRUSH STDCALL
156 GetSysColorBrush( int nIndex )
157 {
158 return(CreateSolidBrush(SysColours[nIndex]));
159 }
160
161
162 /*
163 * @unimplemented
164 */
165 LRESULT STDCALL
166 DefFrameProcA( HWND hWnd,
167 HWND hWndMDIClient,
168 UINT uMsg,
169 WPARAM wParam,
170 LPARAM lParam )
171 {
172 UNIMPLEMENTED;
173 return((LRESULT)0);
174 }
175
176 /*
177 * @unimplemented
178 */
179 LRESULT STDCALL
180 DefFrameProcW(HWND hWnd,
181 HWND hWndMDIClient,
182 UINT uMsg,
183 WPARAM wParam,
184 LPARAM lParam)
185 {
186 UNIMPLEMENTED;
187 return((LRESULT)0);
188 }
189
190 PINTERNALPOS
191 UserGetInternalPos(HWND hWnd)
192 {
193 PINTERNALPOS lpPos;
194 lpPos = (PINTERNALPOS)GetPropA(hWnd, (LPSTR)(DWORD)AtomInternalPos);
195 return(lpPos);
196 }
197
198 BOOL
199 DefWndRedrawIconTitle(HWND hWnd)
200 {
201 PINTERNALPOS lpPos = (PINTERNALPOS)GetPropA(hWnd,
202 (LPSTR)(DWORD)AtomInternalPos);
203 if (lpPos != NULL)
204 {
205 if (lpPos->IconTitle != NULL)
206 {
207 SendMessageA(lpPos->IconTitle, WM_SHOWWINDOW, TRUE, 0);
208 InvalidateRect(lpPos->IconTitle, NULL, TRUE);
209 return(TRUE);
210 }
211 }
212 return(FALSE);
213 }
214
215
216 BOOL
217 UserHasMenu(HWND hWnd, ULONG Style)
218 {
219 return(!(Style & WS_CHILD) && GetMenu(hWnd) != 0);
220 }
221
222
223 ULONG
224 UserHasAnyFrameStyle(ULONG Style, ULONG ExStyle)
225 {
226 return((Style & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) ||
227 (ExStyle & WS_EX_DLGMODALFRAME) ||
228 (!(Style & (WS_CHILD | WS_POPUP))));
229 }
230
231
232 ULONG
233 UserHasDlgFrameStyle(ULONG Style, ULONG ExStyle)
234 {
235 return((ExStyle & WS_EX_DLGMODALFRAME) ||
236 ((Style & WS_DLGFRAME) && (!(Style & WS_THICKFRAME))));
237 }
238
239
240 ULONG
241 UserHasThickFrameStyle(ULONG Style, ULONG ExStyle)
242 {
243 return((Style & WS_THICKFRAME) &&
244 (!((Style & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)));
245 }
246
247
248 ULONG
249 UserHasThinFrameStyle(ULONG Style, ULONG ExStyle)
250 {
251 return((Style & WS_BORDER) ||
252 (!(Style & (WS_CHILD | WS_POPUP))));
253 }
254
255
256 ULONG
257 UserHasBigFrameStyle(ULONG Style, ULONG ExStyle)
258 {
259 return((Style & (WS_THICKFRAME | WS_DLGFRAME)) ||
260 (ExStyle & WS_EX_DLGMODALFRAME));
261 }
262
263 void
264 UserGetInsideRectNC( HWND hWnd, RECT *rect )
265 {
266 RECT WindowRect;
267 ULONG Style;
268 ULONG ExStyle;
269
270 Style = GetWindowLongW(hWnd, GWL_STYLE);
271 ExStyle = GetWindowLongW(hWnd, GWL_EXSTYLE);
272 GetWindowRect(hWnd, &WindowRect);
273 rect->top = rect->left = 0;
274 rect->right = WindowRect.right - WindowRect.left;
275 rect->bottom = WindowRect.bottom - WindowRect.top;
276
277 if (Style & WS_ICONIC)
278 {
279 return;
280 }
281
282 /* Remove frame from rectangle */
283 if (UserHasThickFrameStyle(Style, ExStyle ))
284 {
285 InflateRect( rect, -GetSystemMetrics(SM_CXFRAME),
286 -GetSystemMetrics(SM_CYFRAME) );
287 }
288 else
289 {
290 if (UserHasDlgFrameStyle(Style, ExStyle ))
291 {
292 InflateRect( rect, -GetSystemMetrics(SM_CXDLGFRAME),
293 -GetSystemMetrics(SM_CYDLGFRAME));
294 /* FIXME: this isn't in NC_AdjustRect? why not? */
295 if (ExStyle & WS_EX_DLGMODALFRAME)
296 InflateRect( rect, -1, 0 );
297 }
298 else
299 {
300 if (UserHasThinFrameStyle(Style, ExStyle))
301 {
302 InflateRect(rect, -GetSystemMetrics(SM_CXBORDER),
303 -GetSystemMetrics(SM_CYBORDER));
304 }
305 }
306 }
307 }
308
309 WINBOOL
310 UserDrawSysMenuButton( HWND hWnd, HDC hDC, LPRECT Rect, BOOL down )
311 {
312 HDC hDcMem;
313 HBITMAP hSavedBitmap;
314 WINBOOL result = FALSE;
315
316 hbSysMenu = (HBITMAP)LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CLOSE));
317 hDcMem = CreateCompatibleDC(hDC);
318 if (! hDcMem) goto cleanup;
319 hSavedBitmap = SelectObject(hDcMem, hbSysMenu);
320 if (! hSavedBitmap) goto cleanup;
321
322 BitBlt(hDC, Rect->left + 2, Rect->top +
323 2, 16, 16, hDcMem,
324 (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD) ?
325 GetSystemMetrics(SM_CXSIZE): 0, 0, SRCCOPY);
326
327 result = TRUE;
328
329 cleanup:
330 if (hDcMem)
331 {
332 if(hSavedBitmap) SelectObject(hDcMem, hSavedBitmap);
333 DeleteDC(hDcMem);
334 }
335 return result;
336 }
337
338 /* FIXME: Cache bitmaps, then just bitblt instead of calling DFC() (and
339 wasting precious CPU cycles) every time */
340
341 static void
342 UserDrawCaptionButton( HWND hWnd, HDC hDC, BOOL bDown, ULONG Type )
343 {
344 RECT rect;
345 INT iBmpWidth = GetSystemMetrics(SM_CXSIZE) - 2;
346 INT iBmpHeight = GetSystemMetrics(SM_CYSIZE) - 4;
347
348 INT OffsetX = UIGetFrameSizeX( hWnd );
349 INT OffsetY = UIGetFrameSizeY( hWnd );
350
351 if(!(GetWindowLongW( hWnd, GWL_STYLE ) & WS_SYSMENU))
352 {
353 return;
354 }
355
356 GetWindowRect( hWnd, &rect );
357
358 rect.right = rect.right - rect.left;
359 rect.bottom = rect.bottom - rect.top;
360 rect.left = rect.top = 0;
361
362 switch(Type)
363 {
364 case DFCS_CAPTIONMIN:
365 {
366 if ((GetWindowLongW( hWnd, GWL_EXSTYLE ) & WS_EX_TOOLWINDOW) == TRUE)
367 return; /* ToolWindows don't have min/max buttons */
368
369 SetRect(&rect,
370 rect.right - OffsetX - (iBmpWidth*3) - 5,
371 OffsetY + 2,
372 rect.right - (iBmpWidth * 2) - OffsetX - 5,
373 rect.top + iBmpHeight + OffsetY + 2 );
374 DrawFrameControl( hDC, &rect, DFC_CAPTION,
375 DFCS_CAPTIONMIN | (bDown ? DFCS_PUSHED : 0) |
376 (IsMinBoxActive(hWnd) ? 0 : DFCS_INACTIVE) );
377 break;
378 }
379 case DFCS_CAPTIONMAX:
380 {
381 if ((GetWindowLongW( hWnd, GWL_EXSTYLE ) & WS_EX_TOOLWINDOW) == TRUE)
382 return; /* ToolWindows don't have min/max buttons */
383 SetRect(&rect,
384 rect.right - OffsetX - (iBmpWidth*2) - 5,
385 OffsetY + 2,
386 rect.right - iBmpWidth - OffsetX - 5,
387 rect.top + iBmpHeight + OffsetY + 2 );
388
389 DrawFrameControl( hDC, &rect, DFC_CAPTION,
390 (IsZoomed(hWnd) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMAX) |
391 (bDown ? DFCS_PUSHED : 0) |
392 (IsMaxBoxActive(hWnd) ? 0 : DFCS_INACTIVE) );
393 break;
394 }
395 case DFCS_CAPTIONCLOSE:
396 {
397 SetRect(&rect,
398 rect.right - OffsetX - iBmpWidth - 3,
399 OffsetY + 2,
400 rect.right - OffsetX - 3,
401 rect.top + iBmpHeight + OffsetY + 2 );
402
403 DrawFrameControl( hDC, &rect, DFC_CAPTION,
404 (DFCS_CAPTIONCLOSE |
405 (bDown ? DFCS_PUSHED : 0) |
406 (IsCloseBoxActive(hWnd) ? 0 : DFCS_INACTIVE)) );
407 }
408 }
409 }
410
411
412 // Enabling this will cause captions to draw smoother, but slower:
413 // #define DOUBLE_BUFFER_CAPTION
414 // NOTE: Double buffering appears to be broken for this at the moment
415
416 /*
417 * @implemented
418 */
419 WINBOOL
420 STDCALL
421 DrawCaption(
422 HWND hWnd,
423 HDC hDC,
424 LPRECT lprc,
425 UINT uFlags)
426 {
427 NONCLIENTMETRICSW nclm;
428 BOOL result = FALSE;
429 RECT r = *lprc;
430 UINT VCenter = 0, Padding = 0;
431 WCHAR buffer[256];
432 HFONT hFont = NULL,
433 hOldFont = NULL;
434 HBRUSH OldBrush = NULL;
435 HDC MemDC = NULL;
436
437 #ifdef DOUBLE_BUFFER_CAPTION
438 HBITMAP MemBMP = NULL,
439 OldBMP = NULL;
440
441 MemDC = CreateCompatibleDC(hDC);
442 if (! MemDC) goto cleanup;
443 MemBMP = CreateCompatibleBitmap(hDC, lprc->right - lprc->left, lprc->bottom - lprc->top);
444 if (! MemBMP) goto cleanup;
445 OldBMP = SelectObject(MemDC, MemBMP);
446 if (! OldBMP) goto cleanup;
447 #else
448 MemDC = hDC;
449
450 OffsetViewportOrgEx(MemDC, lprc->left, lprc->top, NULL);
451 #endif
452
453 // If DC_GRADIENT is specified, a Win 98/2000 style caption gradient should
454 // be painted. For now, that flag is ignored:
455 // Windows 98/Me, Windows 2000/XP: When this flag is set, the function uses
456 // COLOR_GRADIENTACTIVECAPTION (if the DC_ACTIVE flag was set) or
457 // COLOR_GRADIENTINACTIVECAPTION for the title-bar color.
458
459 // Draw the caption background
460 if (uFlags & DC_INBUTTON)
461 {
462 OldBrush = SelectObject(MemDC, GetSysColorBrush(uFlags & DC_ACTIVE ? COLOR_BTNFACE : COLOR_BTNSHADOW) );
463 if (! OldBrush) goto cleanup;
464 if (! PatBlt(MemDC, 0, 0, lprc->right - lprc->left, lprc->bottom - lprc->top, PATCOPY )) goto cleanup;
465 }
466 else
467 {
468 // DC_GRADIENT check should go here somewhere
469 OldBrush = SelectObject(MemDC, GetSysColorBrush(uFlags & DC_ACTIVE ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION) );
470 if (! OldBrush) goto cleanup;
471 if (! PatBlt(MemDC, 0, 0, lprc->right - lprc->left, lprc->bottom - lprc->top, PATCOPY )) goto cleanup;
472 }
473
474 VCenter = (lprc->bottom - lprc->top) / 2;
475 Padding = VCenter - (GetSystemMetrics(SM_CYCAPTION) / 2);
476
477 r.left = Padding;
478 r.right = r.left + (lprc->right - lprc->left);
479 r.top = Padding;
480 r.bottom = r.top + (GetSystemMetrics(SM_CYCAPTION) / 2);
481
482 if (uFlags & DC_ICON)
483 {
484 // For some reason the icon isn't centered correctly...
485 r.top --;
486 UserDrawSysMenuButton(hWnd, MemDC, &r, FALSE);
487 r.top ++;
488 }
489
490 r.top ++;
491 r.left += 2;
492
493 if ((uFlags & DC_TEXT) && (GetWindowTextW( hWnd, buffer, sizeof(buffer)/sizeof(buffer[0]) )))
494 {
495 // Duplicate odd behaviour from Windows:
496 if ((! uFlags & DC_SMALLCAP) || (uFlags & DC_ICON) || (uFlags & DC_INBUTTON) ||
497 (! uFlags & DC_ACTIVE))
498 r.left += GetSystemMetrics(SM_CXSIZE) + Padding;
499
500 r.right = (lprc->right - lprc->left);
501
502 nclm.cbSize = sizeof(nclm);
503 if (! SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, 0, &nclm, 0)) goto cleanup;
504
505 if (uFlags & DC_INBUTTON)
506 SetTextColor(MemDC, SysColours[ uFlags & DC_ACTIVE ? COLOR_BTNTEXT : COLOR_GRAYTEXT]);
507 else
508 SetTextColor(MemDC, SysColours[ uFlags & DC_ACTIVE ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT]);
509
510 SetBkMode( MemDC, TRANSPARENT );
511 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_EX_TOOLWINDOW)
512 // if (uFlags & DC_SMALLCAP) // incorrect
513 hFont = CreateFontIndirectW(&nclm.lfSmCaptionFont);
514 else
515 hFont = CreateFontIndirectW(&nclm.lfCaptionFont);
516
517 if (! hFont) goto cleanup;
518
519 hOldFont = SelectObject(MemDC, hFont);
520 if (! hOldFont) goto cleanup;
521
522 DrawTextW(MemDC, buffer, wcslen(buffer), &r, DT_VCENTER | DT_END_ELLIPSIS);
523 // Old method:
524 // TextOutW(hDC, r.left + (GetSystemMetrics(SM_CXDLGFRAME) * 2), lprc->top + (nclm.lfCaptionFont.lfHeight / 2), buffer, wcslen(buffer));
525 }
526
527 if (uFlags & DC_BUTTONS)
528 {
529 // Windows XP draws the caption buttons with DC_BUTTONS
530 // r.left += GetSystemMetrics(SM_CXSIZE) + 1;
531 // UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONCLOSE);
532 // r.right -= GetSystemMetrics(SM_CXSMSIZE) + 1;
533 // UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMIN);
534 // UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMAX);
535 }
536
537 #ifdef DOUBLE_BUFFER_CAPTION
538 if (! BitBlt(hDC, lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top,
539 MemDC, 0, 0, SRCCOPY)) goto cleanup;
540 #endif
541
542 result = TRUE;
543
544 cleanup :
545 if (MemDC)
546 {
547 if (OldBrush) SelectObject(MemDC, OldBrush);
548 if (hOldFont) SelectObject(MemDC, hOldFont);
549 if (hFont) DeleteObject(hFont);
550 #ifdef DOUBLE_BUFFER_CAPTION
551 if (OldBMP) SelectObject(MemDC, OldBMP);
552 if (MemBMP) DeleteObject(MemBMP);
553 DeleteDC(MemDC);
554 #else
555 OffsetViewportOrgEx(MemDC, -lprc->left, -lprc->top, NULL);
556 #endif
557 }
558
559 return result;
560 }
561
562
563
564 static void
565 UserDrawCaptionNC (
566 HDC hDC,
567 RECT *rect,
568 HWND hWnd,
569 DWORD style,
570 BOOL active )
571 {
572 RECT r = *rect;
573 UINT capflags = 0;
574
575 capflags = DC_ICON | DC_TEXT;
576 capflags |= (active & DC_ACTIVE);
577
578 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_EX_TOOLWINDOW)
579 capflags |= DC_SMALLCAP;
580
581 // Old code:
582 // PatBlt(hDC,rect->left + GetSystemMetrics(SM_CXFRAME), rect->top +
583 // GetSystemMetrics(SM_CYFRAME), rect->right - (GetSystemMetrics(SM_CXFRAME) * 2), (rect->top +
584 // GetSystemMetrics(SM_CYCAPTION)) - 1, PATCOPY );
585
586 r.left += GetSystemMetrics(SM_CXFRAME);
587 r.top += GetSystemMetrics(SM_CYFRAME);
588 r.right -= GetSystemMetrics(SM_CXFRAME);
589 r.bottom = r.top + GetSystemMetrics(SM_CYCAPTION);
590 // GetSystemMetrics(SM_CYCAPTION)) - 1, PATCOPY );
591
592 DrawCaption(hWnd, hDC, &r, capflags);
593
594 if (style & WS_SYSMENU)
595 {
596 // UserDrawSysMenuButton( hWnd, hDC, FALSE);
597 r.left += GetSystemMetrics(SM_CXSIZE) + 1;
598 UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONCLOSE);
599 r.right -= GetSystemMetrics(SM_CXSMSIZE) + 1;
600 UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMIN);
601 UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMAX);
602 }
603 }
604
605
606 VOID
607 UserDrawFrameNC(HWND hWnd, RECT* rect, BOOL dlgFrame, BOOL active)
608 {
609 HDC hDC = GetWindowDC(hWnd);
610 SelectObject( hDC, GetSysColorBrush(COLOR_WINDOW) );
611 DrawEdge(hDC, rect,EDGE_RAISED, BF_RECT | BF_MIDDLE);
612 }
613
614
615 void
616 SCROLL_DrawScrollBar (HWND hWnd, HDC hDC, INT nBar, BOOL arrows, BOOL interior);
617
618 VOID
619 DefWndDoPaintNC(HWND hWnd, HRGN clip)
620 {
621 BOOL Active = FALSE;
622 HDC hDC;
623 RECT rect;
624 ULONG Style;
625 ULONG ExStyle;
626 int wFrame = 0;
627
628 // This won't work because it conflicts with BS_BITMAP :
629 if (GetActiveWindow() == hWnd) Active = TRUE;
630 Style = GetWindowLongW(hWnd, GWL_STYLE);
631 ExStyle = GetWindowLongW(hWnd, GWL_EXSTYLE);
632
633 hDC = GetDCEx(hWnd, (clip > (HRGN)1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
634 ((clip > (HRGN)1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0));
635 if (hDC == 0)
636 {
637 return;
638 }
639
640 /* FIXME: Test whether we need to draw anything at all. */
641
642 GetWindowRect(hWnd, &rect);
643 rect.right = rect.right - rect.left;
644 rect.bottom = rect.bottom - rect.top;
645 rect.top = rect.left = 0;
646 SelectObject(hDC, GetSysColorPen(COLOR_WINDOWFRAME));
647 if (UserHasThickFrameStyle(Style, ExStyle))
648 {
649 UserDrawFrameNC(hWnd, &rect, FALSE, Active);
650 wFrame = GetSystemMetrics(SM_CXSIZEFRAME);
651 }
652 else if (UserHasDlgFrameStyle(Style, ExStyle))
653 {
654 UserDrawFrameNC(hWnd, &rect, TRUE, Active);
655 wFrame = GetSystemMetrics(SM_CXDLGFRAME);
656 }
657 if (Style & WS_CAPTION)
658 {
659 RECT r = rect;
660 r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
661 rect.top += GetSystemMetrics(SM_CYSIZE) +
662 GetSystemMetrics(SM_CYBORDER);
663 UserDrawCaptionNC(hDC, &r, hWnd, Style, Active);
664 }
665
666 /* Draw menu bar. */
667 if (UserHasMenu(hWnd, Style))
668 {
669 RECT r = rect;
670 r.bottom = rect.top + GetSystemMetrics(SM_CYMENU);
671 r.left += wFrame;
672 r.right -= wFrame;
673 rect.top += MenuDrawMenuBar(hDC, &r, hWnd, FALSE);
674 }
675
676 /* Draw scrollbars */
677 if (Style & WS_VSCROLL)
678 SCROLL_DrawScrollBar(hWnd, hDC, SB_VERT, TRUE, TRUE);
679 if (Style & WS_HSCROLL)
680 SCROLL_DrawScrollBar(hWnd, hDC, SB_HORZ, TRUE, TRUE);
681
682 /* FIXME: Draw size box.*/
683
684 ReleaseDC(hWnd, hDC);
685 }
686
687
688 LRESULT
689 DefWndPaintNC(HWND hWnd, HRGN clip)
690 {
691 if (IsWindowVisible(hWnd))
692 {
693 if (IsIconic(hWnd))
694 {
695 DefWndRedrawIconTitle(hWnd);
696 }
697 else
698 {
699 DefWndDoPaintNC(hWnd, clip);
700 }
701 }
702 return(0);
703 }
704
705
706 LRESULT
707 DefWndHitTestNC(HWND hWnd, POINT Point)
708 {
709 RECT WindowRect;
710 ULONG Style = GetWindowLongW(hWnd, GWL_STYLE);
711 ULONG ExStyle = GetWindowLongW(hWnd, GWL_EXSTYLE);
712
713 GetWindowRect(hWnd, &WindowRect);
714 if (!PtInRect(&WindowRect, Point))
715 {
716 return(HTNOWHERE);
717 }
718 if (Style & WS_MINIMIZE)
719 {
720 return(HTCAPTION);
721 }
722 if (UserHasThickFrameStyle(Style, ExStyle))
723 {
724 InflateRect(&WindowRect, -GetSystemMetrics(SM_CXFRAME),
725 -GetSystemMetrics(SM_CYFRAME));
726 if (!PtInRect(&WindowRect, Point))
727 {
728 if (Point.y < WindowRect.top)
729 {
730 if (Point.x < (WindowRect.left + GetSystemMetrics(SM_CXSIZE)))
731 {
732 return(HTTOPLEFT);
733 }
734 if (Point.x >= (WindowRect.right - GetSystemMetrics(SM_CXSIZE)))
735 {
736 return(HTTOPRIGHT);
737 }
738 return(HTTOP);
739 }
740 if (Point.y >= WindowRect.bottom)
741 {
742 if (Point.x < (WindowRect.left + GetSystemMetrics(SM_CXSIZE)))
743 {
744 return(HTBOTTOMLEFT);
745 }
746 if (Point.x >= (WindowRect.right - GetSystemMetrics(SM_CXSIZE)))
747 {
748 return(HTBOTTOMRIGHT);
749 }
750 return(HTBOTTOM);
751 }
752 if (Point.x < WindowRect.left)
753 {
754 if (Point.y < (WindowRect.top + GetSystemMetrics(SM_CYSIZE)))
755 {
756 return(HTTOPLEFT);
757 }
758 if (Point.y >= (WindowRect.bottom - GetSystemMetrics(SM_CYSIZE)))
759 {
760 return(HTBOTTOMLEFT);
761 }
762 return(HTLEFT);
763 }
764 if (Point.x >= WindowRect.right)
765 {
766 if (Point.y < (WindowRect.top + GetSystemMetrics(SM_CYSIZE)))
767 {
768 return(HTTOPRIGHT);
769 }
770 if (Point.y >= (WindowRect.bottom - GetSystemMetrics(SM_CYSIZE)))
771 {
772 return(HTBOTTOMRIGHT);
773 }
774 return(HTRIGHT);
775 }
776 }
777 }
778 else
779 {
780 if (UserHasDlgFrameStyle(Style, ExStyle))
781 {
782 InflateRect(&WindowRect, -GetSystemMetrics(SM_CXDLGFRAME),
783 -GetSystemMetrics(SM_CYDLGFRAME));
784 }
785 else if (UserHasThinFrameStyle(Style, ExStyle))
786 {
787 InflateRect(&WindowRect, -GetSystemMetrics(SM_CXBORDER),
788 -GetSystemMetrics(SM_CYBORDER));
789 }
790 if (!PtInRect(&WindowRect, Point))
791 {
792 return(HTBORDER);
793 }
794 }
795
796 if ((Style & WS_CAPTION) == WS_CAPTION)
797 {
798 WindowRect.top += (GetSystemMetrics(SM_CYCAPTION) -
799 GetSystemMetrics(SM_CYBORDER));
800 if (!PtInRect(&WindowRect, Point))
801 {
802 if ((Style & WS_SYSMENU) && !(ExStyle & WS_EX_TOOLWINDOW))
803 {
804 WindowRect.left += GetSystemMetrics(SM_CXSIZE);
805 WindowRect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
806 }
807 if (Point.x <= WindowRect.left)
808 {
809 return(HTSYSMENU);
810 }
811 if (WindowRect.right <= Point.x)
812 {
813 return(HTCLOSE);
814 }
815
816 if (Style & WS_MAXIMIZEBOX || Style & WS_MINIMIZEBOX)
817 {
818 WindowRect.right -= GetSystemMetrics(SM_CXSIZE) - 2;
819 }
820 if (Point.x >= WindowRect.right)
821 {
822 return(HTMAXBUTTON);
823 }
824
825 if (Style & WS_MINIMIZEBOX)
826 {
827 WindowRect.right -= GetSystemMetrics(SM_CXSIZE) - 2;
828 }
829 if (Point.x >= WindowRect.right)
830 {
831 return(HTMINBUTTON);
832 }
833 return(HTCAPTION);
834 }
835 }
836
837 ScreenToClient(hWnd, &Point);
838 GetClientRect(hWnd, &WindowRect);
839
840 if (PtInRect(&WindowRect, Point))
841 {
842 return(HTCLIENT);
843 }
844
845 if (Style & WS_VSCROLL)
846 {
847 WindowRect.right += GetSystemMetrics(SM_CXVSCROLL);
848 if (PtInRect(&WindowRect, Point))
849 {
850 return(HTVSCROLL);
851 }
852 }
853
854 if (Style & WS_HSCROLL)
855 {
856 WindowRect.bottom += GetSystemMetrics(SM_CYHSCROLL);
857 if (PtInRect(&WindowRect, Point))
858 {
859 if ((Style & WS_VSCROLL) &&
860 (Point.x >= (WindowRect.right - GetSystemMetrics(SM_CXVSCROLL))))
861 {
862 return(HTSIZE);
863 }
864 return(HTHSCROLL);
865 }
866 }
867
868 if (UserHasMenu(hWnd, Style))
869 {
870 if (Point.y < 0 && Point.x >= 0 && Point.x <= WindowRect.right)
871 {
872 return(HTMENU);
873 }
874 }
875
876 return(HTNOWHERE);
877 }
878
879 LRESULT
880 DefWndHandleLButtonDownNC(HWND hWnd, WPARAM wParam, LPARAM lParam)
881 {
882 switch (wParam)
883 {
884 case HTCAPTION:
885 {
886 HWND hTopWnd = GetAncestor(hWnd, GA_ROOT);
887 if (SetActiveWindow(hTopWnd) || GetActiveWindow() == hTopWnd)
888 {
889 SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam);
890 }
891 break;
892 }
893 case HTSYSMENU:
894 {
895 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_SYSMENU)
896 {
897 if (!(GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE))
898 {
899 HDC hDC = GetWindowDC(hWnd);
900 // UserDrawSysMenuButton(hWnd, hDC, TRUE);
901 ReleaseDC(hWnd, hDC);
902 }
903 SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU,
904 lParam);
905 }
906 break;
907 }
908 case HTMENU:
909 {
910 SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam);
911 break;
912 }
913 case HTHSCROLL:
914 {
915 SendMessageA(hWnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam);
916 break;
917 }
918 case HTVSCROLL:
919 {
920 SendMessageA(hWnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam);
921 break;
922 }
923 case HTMINBUTTON:
924 {
925 UserDrawCaptionButton( hWnd, GetWindowDC(hWnd), IsMinBoxActive(hWnd), DFCS_CAPTIONMIN);
926 break;
927 }
928 case HTMAXBUTTON:
929 {
930 UserDrawCaptionButton( hWnd, GetWindowDC(hWnd), IsMaxBoxActive(hWnd), DFCS_CAPTIONMAX);
931 break;
932 }
933 case HTCLOSE:
934 {
935 UserDrawCaptionButton( hWnd, GetWindowDC(hWnd), TRUE, DFCS_CAPTIONCLOSE);
936 break;
937 }
938 case HTLEFT:
939 case HTRIGHT:
940 case HTTOP:
941 case HTBOTTOM:
942 case HTTOPLEFT:
943 case HTTOPRIGHT:
944 case HTBOTTOMLEFT:
945 case HTBOTTOMRIGHT:
946 {
947 SendMessageA(hWnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam);
948 break;
949 }
950 }
951 return(0);
952 }
953
954
955 LRESULT
956 DefWndHandleLButtonDblClkNC(HWND hWnd, WPARAM wParam, LPARAM lParam)
957 {
958 UNIMPLEMENTED;
959 return(0);
960 }
961
962
963 LRESULT
964 DefWndHandleLButtonUpNC(HWND hWnd, WPARAM wParam, LPARAM lParam)
965 {
966 UserDrawCaptionButton( hWnd, GetWindowDC(hWnd), FALSE, DFCS_CAPTIONMIN);
967 UserDrawCaptionButton( hWnd, GetWindowDC(hWnd), FALSE, DFCS_CAPTIONMAX);
968 UserDrawCaptionButton( hWnd, GetWindowDC(hWnd), FALSE, DFCS_CAPTIONCLOSE);
969 switch (wParam)
970 {
971 case HTMINBUTTON:
972 {
973 SendMessageA(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
974 break;
975 }
976 case HTMAXBUTTON:
977 {
978 SendMessageA(hWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
979 break;
980 }
981 case HTCLOSE:
982 {
983 SendMessageA(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
984 break;
985 }
986 }
987 return(0);
988 }
989
990
991 LRESULT
992 DefWndHandleActiveNC(HWND hWnd, WPARAM wParam)
993 {
994 UNIMPLEMENTED;
995 return(0);
996 }
997
998
999 VOID
1000 DefWndSetRedraw(HWND hWnd, WPARAM wParam)
1001 {
1002 UNIMPLEMENTED;
1003 }
1004
1005
1006 LRESULT
1007 DefWndHandleSetCursor(HWND hWnd, WPARAM wParam, LPARAM lParam)
1008 {
1009 /* Not for child windows. */
1010 if (hWnd != (HWND)wParam)
1011 {
1012 return(0);
1013 }
1014
1015 switch(LOWORD(lParam))
1016 {
1017 case HTERROR:
1018 {
1019 WORD Msg = HIWORD(lParam);
1020 if (Msg == WM_LBUTTONDOWN || Msg == WM_MBUTTONDOWN ||
1021 Msg == WM_RBUTTONDOWN)
1022 {
1023 MessageBeep(0);
1024 }
1025 break;
1026 }
1027
1028 case HTCLIENT:
1029 {
1030 HICON hCursor = (HICON)GetClassLongW(hWnd, GCL_HCURSOR);
1031 if (hCursor)
1032 {
1033 SetCursor(hCursor);
1034 return(TRUE);
1035 }
1036 return(FALSE);
1037 }
1038
1039 case HTLEFT:
1040 case HTRIGHT:
1041 {
1042 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZEWE)));
1043 }
1044
1045 case HTTOP:
1046 case HTBOTTOM:
1047 {
1048 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENS)));
1049 }
1050
1051 case HTTOPLEFT:
1052 case HTBOTTOMRIGHT:
1053 {
1054 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENWSE)));
1055 }
1056
1057 case HTBOTTOMLEFT:
1058 case HTTOPRIGHT:
1059 {
1060 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENESW)));
1061 }
1062 }
1063 return((LRESULT)SetCursor(LoadCursorW(0, IDC_ARROW)));
1064 }
1065
1066 static LONG
1067 DefWndStartSizeMove(HWND hWnd, WPARAM wParam, POINT *capturePoint)
1068 {
1069 LONG hittest = 0;
1070 POINT pt;
1071 MSG msg;
1072 RECT rectWindow;
1073 ULONG Style = GetWindowLongW(hWnd, GWL_STYLE);
1074
1075 GetWindowRect(hWnd, &rectWindow);
1076
1077 if ((wParam & 0xfff0) == SC_MOVE)
1078 {
1079 /* Move pointer at the center of the caption */
1080 RECT rect;
1081 UserGetInsideRectNC(hWnd, &rect);
1082 if (Style & WS_SYSMENU)
1083 rect.left += GetSystemMetrics(SM_CXSIZE) + 1;
1084 if (Style & WS_MINIMIZEBOX)
1085 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1086 if (Style & WS_MAXIMIZEBOX)
1087 rect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
1088 pt.x = rectWindow.left + (rect.right - rect.left) / 2;
1089 pt.y = rectWindow.top + rect.top + GetSystemMetrics(SM_CYSIZE)/2;
1090 hittest = HTCAPTION;
1091 *capturePoint = pt;
1092 }
1093 else /* SC_SIZE */
1094 {
1095 while(!hittest)
1096 {
1097 GetMessageW(&msg, NULL, 0, 0);
1098 switch(msg.message)
1099 {
1100 case WM_MOUSEMOVE:
1101 hittest = DefWndHitTestNC(hWnd, msg.pt);
1102 if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT))
1103 hittest = 0;
1104 break;
1105
1106 case WM_LBUTTONUP:
1107 return 0;
1108
1109 case WM_KEYDOWN:
1110 switch(msg.wParam)
1111 {
1112 case VK_UP:
1113 hittest = HTTOP;
1114 pt.x =(rectWindow.left+rectWindow.right)/2;
1115 pt.y = rectWindow.top + GetSystemMetrics(SM_CYFRAME) / 2;
1116 break;
1117 case VK_DOWN:
1118 hittest = HTBOTTOM;
1119 pt.x =(rectWindow.left+rectWindow.right)/2;
1120 pt.y = rectWindow.bottom - GetSystemMetrics(SM_CYFRAME) / 2;
1121 break;
1122 case VK_LEFT:
1123 hittest = HTLEFT;
1124 pt.x = rectWindow.left + GetSystemMetrics(SM_CXFRAME) / 2;
1125 pt.y =(rectWindow.top+rectWindow.bottom)/2;
1126 break;
1127 case VK_RIGHT:
1128 hittest = HTRIGHT;
1129 pt.x = rectWindow.right - GetSystemMetrics(SM_CXFRAME) / 2;
1130 pt.y =(rectWindow.top+rectWindow.bottom)/2;
1131 break;
1132 case VK_RETURN:
1133 case VK_ESCAPE: return 0;
1134 }
1135 }
1136 }
1137 *capturePoint = pt;
1138 }
1139 SetCursorPos( pt.x, pt.y );
1140 DefWndHandleSetCursor(hWnd, (WPARAM)hWnd, MAKELONG(hittest, WM_MOUSEMOVE));
1141 return hittest;
1142 }
1143
1144 #define ON_LEFT_BORDER(hit) \
1145 (((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
1146 #define ON_RIGHT_BORDER(hit) \
1147 (((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
1148 #define ON_TOP_BORDER(hit) \
1149 (((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
1150 #define ON_BOTTOM_BORDER(hit) \
1151 (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
1152
1153 VOID STATIC
1154 UserDrawWindowFrame(HDC hdc, const RECT *rect,
1155 ULONG width, ULONG height, DWORD rop )
1156 {
1157 HBRUSH hbrush = SelectObject( hdc, GetStockObject( GRAY_BRUSH ) );
1158 PatBlt( hdc, rect->left, rect->top,
1159 rect->right - rect->left - width, height, rop );
1160 PatBlt( hdc, rect->left, rect->top + height, width,
1161 rect->bottom - rect->top - height, rop );
1162 PatBlt( hdc, rect->left + width, rect->bottom - 1,
1163 rect->right - rect->left - width, -height, rop );
1164 PatBlt( hdc, rect->right - 1, rect->top, -width,
1165 rect->bottom - rect->top - height, rop );
1166 SelectObject( hdc, hbrush );
1167 }
1168
1169 VOID STATIC
1170 UserDrawMovingFrame(HDC hdc, RECT *rect, BOOL thickframe)
1171 {
1172 if (thickframe)
1173 {
1174 UserDrawWindowFrame(hdc, rect, GetSystemMetrics(SM_CXFRAME),
1175 GetSystemMetrics(SM_CYFRAME), PATINVERT );
1176 }
1177 else DrawFocusRect( hdc, rect );
1178 }
1179
1180 VOID STATIC
1181 DefWndDoSizeMove(HWND hwnd, WORD wParam)
1182 {
1183 MSG msg;
1184 RECT sizingRect, mouseRect, origRect;
1185 HDC hdc;
1186 LONG hittest = (LONG)(wParam & 0x0f);
1187 HCURSOR hDragCursor = 0, hOldCursor = 0;
1188 POINT minTrack, maxTrack;
1189 POINT capturePoint, pt;
1190 ULONG Style = GetWindowLongW(hwnd, GWL_STYLE);
1191 ULONG ExStyle = GetWindowLongW(hwnd, GWL_EXSTYLE);
1192 BOOL thickframe = UserHasThickFrameStyle(Style, ExStyle);
1193 BOOL iconic = Style & WS_MINIMIZE;
1194 BOOL moved = FALSE;
1195 DWORD dwPoint = GetMessagePos();
1196 BOOL DragFullWindows = FALSE;
1197 HWND hWndParent;
1198
1199 SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS, 0, &DragFullWindows, 0);
1200
1201 pt.x = SLOWORD(dwPoint);
1202 pt.y = SHIWORD(dwPoint);
1203 capturePoint = pt;
1204
1205 if (IsZoomed(hwnd) || !IsWindowVisible(hwnd))
1206 {
1207 return;
1208 }
1209
1210 if ((wParam & 0xfff0) == SC_MOVE)
1211 {
1212 if (!hittest)
1213 {
1214 hittest = DefWndStartSizeMove(hwnd, wParam, &capturePoint);
1215 }
1216 if (!hittest)
1217 {
1218 return;
1219 }
1220 }
1221 else /* SC_SIZE */
1222 {
1223 if (!thickframe)
1224 {
1225 return;
1226 }
1227 if (hittest && hittest != HTSYSMENU)
1228 {
1229 hittest += 2;
1230 }
1231 else
1232 {
1233 SetCapture(hwnd);
1234 hittest = DefWndStartSizeMove(hwnd, wParam, &capturePoint);
1235 if (!hittest)
1236 {
1237 ReleaseCapture();
1238 return;
1239 }
1240 }
1241 }
1242
1243 if (Style & WS_CHILD)
1244 {
1245 hWndParent = GetParent(hwnd);
1246 }
1247
1248 /* Get min/max info */
1249
1250 WinPosGetMinMaxInfo(hwnd, NULL, NULL, &minTrack, &maxTrack);
1251 GetWindowRect(hwnd, &sizingRect);
1252 origRect = sizingRect;
1253 if (Style & WS_CHILD)
1254 {
1255 GetClientRect(hWndParent, &mouseRect );
1256 }
1257 else
1258 {
1259 SetRect(&mouseRect, 0, 0, GetSystemMetrics(SM_CXSCREEN),
1260 GetSystemMetrics(SM_CYSCREEN));
1261 }
1262 if (ON_LEFT_BORDER(hittest))
1263 {
1264 mouseRect.left = max( mouseRect.left, sizingRect.right-maxTrack.x );
1265 mouseRect.right = min( mouseRect.right, sizingRect.right-minTrack.x );
1266 }
1267 else if (ON_RIGHT_BORDER(hittest))
1268 {
1269 mouseRect.left = max( mouseRect.left, sizingRect.left+minTrack.x );
1270 mouseRect.right = min( mouseRect.right, sizingRect.left+maxTrack.x );
1271 }
1272 if (ON_TOP_BORDER(hittest))
1273 {
1274 mouseRect.top = max( mouseRect.top, sizingRect.bottom-maxTrack.y );
1275 mouseRect.bottom = min( mouseRect.bottom,sizingRect.bottom-minTrack.y);
1276 }
1277 else if (ON_BOTTOM_BORDER(hittest))
1278 {
1279 mouseRect.top = max( mouseRect.top, sizingRect.top+minTrack.y );
1280 mouseRect.bottom = min( mouseRect.bottom, sizingRect.top+maxTrack.y );
1281 }
1282 if (Style & WS_CHILD)
1283 {
1284 MapWindowPoints( hWndParent, 0, (LPPOINT)&mouseRect, 2 );
1285 }
1286 SendMessageA( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
1287
1288 if (GetCapture() != hwnd) SetCapture( hwnd );
1289
1290 if (Style & WS_CHILD)
1291 {
1292 /* Retrieve a default cache DC (without using the window style) */
1293 hdc = GetDCEx(hWndParent, 0, DCX_CACHE);
1294 }
1295 else
1296 {
1297 hdc = GetDC( 0 );
1298 }
1299
1300 if( iconic ) /* create a cursor for dragging */
1301 {
1302 HICON hIcon = (HICON)GetClassLongW(hwnd, GCL_HICON);
1303 if(!hIcon) hIcon = (HICON)SendMessageW( hwnd, WM_QUERYDRAGICON, 0, 0L);
1304 if( hIcon ) hDragCursor = CursorIconToCursor( hIcon, TRUE );
1305 if( !hDragCursor ) iconic = FALSE;
1306 }
1307
1308 /* invert frame if WIN31_LOOK to indicate mouse click on caption */
1309 if( !iconic && !DragFullWindows)
1310 {
1311 UserDrawMovingFrame( hdc, &sizingRect, thickframe );
1312 }
1313
1314 while(1)
1315 {
1316 int dx = 0, dy = 0;
1317
1318 GetMessageW(&msg, 0, 0, 0);
1319
1320 /* Exit on button-up, Return, or Esc */
1321 if ((msg.message == WM_LBUTTONUP) ||
1322 ((msg.message == WM_KEYDOWN) &&
1323 ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
1324
1325 if (msg.message == WM_PAINT)
1326 {
1327 if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
1328 UpdateWindow( msg.hwnd );
1329 if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
1330 continue;
1331 }
1332
1333 if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
1334 continue; /* We are not interested in other messages */
1335
1336 pt = msg.pt;
1337
1338 if (msg.message == WM_KEYDOWN) switch(msg.wParam)
1339 {
1340 case VK_UP: pt.y -= 8; break;
1341 case VK_DOWN: pt.y += 8; break;
1342 case VK_LEFT: pt.x -= 8; break;
1343 case VK_RIGHT: pt.x += 8; break;
1344 }
1345
1346 pt.x = max( pt.x, mouseRect.left );
1347 pt.x = min( pt.x, mouseRect.right );
1348 pt.y = max( pt.y, mouseRect.top );
1349 pt.y = min( pt.y, mouseRect.bottom );
1350
1351 dx = pt.x - capturePoint.x;
1352 dy = pt.y - capturePoint.y;
1353
1354 if (dx || dy)
1355 {
1356 if( !moved )
1357 {
1358 moved = TRUE;
1359
1360 if( iconic ) /* ok, no system popup tracking */
1361 {
1362 hOldCursor = SetCursor(hDragCursor);
1363 ShowCursor( TRUE );
1364 WinPosShowIconTitle( hwnd, FALSE );
1365 }
1366 }
1367
1368 if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
1369 else
1370 {
1371 RECT newRect = sizingRect;
1372 WPARAM wpSizingHit = 0;
1373
1374 if (hittest == HTCAPTION) OffsetRect( &newRect, dx, dy );
1375 if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
1376 else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
1377 if (ON_TOP_BORDER(hittest)) newRect.top += dy;
1378 else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
1379 if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
1380 capturePoint = pt;
1381
1382 /* determine the hit location */
1383 if (hittest >= HTLEFT && hittest <= HTBOTTOMRIGHT)
1384 wpSizingHit = WMSZ_LEFT + (hittest - HTLEFT);
1385 SendMessageA( hwnd, WM_SIZING, wpSizingHit, (LPARAM)&newRect );
1386
1387 if (!iconic)
1388 {
1389 if(!DragFullWindows)
1390 UserDrawMovingFrame( hdc, &newRect, thickframe );
1391 else {
1392 /* To avoid any deadlocks, all the locks on the windows
1393 structures must be suspended before the SetWindowPos */
1394 SetWindowPos( hwnd, 0, newRect.left, newRect.top,
1395 newRect.right - newRect.left,
1396 newRect.bottom - newRect.top,
1397 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
1398 }
1399 }
1400 sizingRect = newRect;
1401 }
1402 }
1403 }
1404
1405 ReleaseCapture();
1406 if( iconic )
1407 {
1408 if( moved ) /* restore cursors, show icon title later on */
1409 {
1410 ShowCursor( FALSE );
1411 SetCursor( hOldCursor );
1412 }
1413 DestroyCursor( hDragCursor );
1414 }
1415 else if(!DragFullWindows)
1416 UserDrawMovingFrame( hdc, &sizingRect, thickframe );
1417
1418 if (Style & WS_CHILD)
1419 ReleaseDC( hWndParent, hdc );
1420 else
1421 ReleaseDC( 0, hdc );
1422
1423 SendMessageA( hwnd, WM_EXITSIZEMOVE, 0, 0 );
1424 SendMessageA( hwnd, WM_SETVISIBLE, !IsIconic(hwnd), 0L);
1425
1426 /* window moved or resized */
1427 if (moved)
1428 {
1429 /* if the moving/resizing isn't canceled call SetWindowPos
1430 * with the new position or the new size of the window
1431 */
1432 if (!((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
1433 {
1434 /* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
1435 if(!DragFullWindows)
1436 SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top,
1437 sizingRect.right - sizingRect.left,
1438 sizingRect.bottom - sizingRect.top,
1439 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
1440 }
1441 else { /* restore previous size/position */
1442 if(DragFullWindows)
1443 SetWindowPos( hwnd, 0, origRect.left, origRect.top,
1444 origRect.right - origRect.left,
1445 origRect.bottom - origRect.top,
1446 ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
1447 }
1448 }
1449
1450 if( IsWindow(hwnd) )
1451 if( Style & WS_MINIMIZE )
1452 {
1453 /* Single click brings up the system menu when iconized */
1454
1455 if( !moved )
1456 {
1457 if( Style & WS_SYSMENU )
1458 SendMessageA( hwnd, WM_SYSCOMMAND,
1459 SC_MOUSEMENU + HTSYSMENU, MAKELONG(pt.x,pt.y));
1460 }
1461 else WinPosShowIconTitle( hwnd, TRUE );
1462 }
1463 }
1464
1465
1466 LRESULT
1467 DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, POINT Pt)
1468 {
1469 switch (wParam & 0xfff0)
1470 {
1471 case SC_MOVE:
1472 case SC_SIZE:
1473 DefWndDoSizeMove(hWnd, wParam);
1474 break;
1475 case SC_CLOSE:
1476 SendMessageA(hWnd, WM_CLOSE, 0, 0);
1477 break;
1478 case SC_MOUSEMENU:
1479 MenuTrackMouseMenuBar(hWnd, wParam, Pt);
1480 break;
1481 case SC_KEYMENU:
1482 MenuTrackKbdMenuBar(hWnd, wParam, Pt.x);
1483 break;
1484 default:
1485 /* FIXME: Implement */
1486 UNIMPLEMENTED;
1487 break;
1488 }
1489
1490 return(0);
1491 }
1492
1493
1494 VOID
1495 DefWndAdjustRect(RECT* Rect, ULONG Style, BOOL Menu, ULONG ExStyle)
1496 {
1497 if (Style & WS_ICONIC)
1498 {
1499 return;
1500 }
1501
1502 if (UserHasThickFrameStyle(Style, ExStyle))
1503 {
1504 InflateRect(Rect, GetSystemMetrics(SM_CXFRAME),
1505 GetSystemMetrics(SM_CYFRAME));
1506 }
1507 else if (UserHasDlgFrameStyle(Style, ExStyle))
1508 {
1509 InflateRect(Rect, GetSystemMetrics(SM_CXDLGFRAME),
1510 GetSystemMetrics(SM_CYDLGFRAME));
1511 }
1512 else if (UserHasThinFrameStyle(Style, ExStyle))
1513 {
1514 InflateRect(Rect, GetSystemMetrics(SM_CXBORDER),
1515 GetSystemMetrics(SM_CYBORDER));
1516 }
1517 if (Style & WS_CAPTION)
1518 {
1519 Rect->top -= (GetSystemMetrics(SM_CYCAPTION) -
1520 GetSystemMetrics(SM_CYBORDER)) + 1;
1521 }
1522 if (Menu)
1523 {
1524 Rect->top -= GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYBORDER);
1525 }
1526 if (Style & WS_VSCROLL)
1527 {
1528 Rect->right += GetSystemMetrics(SM_CXVSCROLL) - 1;
1529 if (UserHasAnyFrameStyle(Style, ExStyle))
1530 {
1531 Rect->right++;
1532 }
1533 }
1534 if (Style & WS_HSCROLL)
1535 {
1536 Rect->bottom += GetSystemMetrics(SM_CYHSCROLL) - 1;
1537 if (UserHasAnyFrameStyle(Style, ExStyle))
1538 {
1539 Rect->bottom++;
1540 }
1541 }
1542 }
1543
1544
1545 LRESULT STDCALL
1546 DefWndNCCalcSize(HWND hWnd, RECT* Rect)
1547 {
1548 LRESULT Result = 0;
1549 LONG Style = GetClassLongW(hWnd, GCL_STYLE);
1550 RECT TmpRect = {0, 0, 0, 0};
1551
1552 if (Style & CS_VREDRAW)
1553 {
1554 Result |= WVR_VREDRAW;
1555 }
1556 if (Style & CS_HREDRAW)
1557 {
1558 Result |= WVR_HREDRAW;
1559 }
1560
1561 if (!(GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE))
1562 {
1563 DefWndAdjustRect(&TmpRect, GetWindowLongW(hWnd, GWL_STYLE),
1564 FALSE, GetWindowLongW(hWnd, GWL_EXSTYLE));
1565 Rect->left -= TmpRect.left;
1566 Rect->top -= TmpRect.top;
1567 Rect->right -= TmpRect.right;
1568 Rect->bottom -= TmpRect.bottom;
1569 if (UserHasMenu(hWnd, GetWindowLongW(hWnd, GWL_EXSTYLE)))
1570 {
1571 Rect->top += MenuGetMenuBarHeight(hWnd,
1572 Rect->right - Rect->left,
1573 -TmpRect.left,
1574 -TmpRect.top) + 1;
1575 }
1576 Rect->bottom = max(Rect->top, Rect->bottom);
1577 Rect->right = max(Rect->left, Rect->right);
1578 }
1579 return(Result);
1580 }
1581
1582
1583 LRESULT
1584 DefWndHandleWindowPosChanging(HWND hWnd, WINDOWPOS* Pos)
1585 {
1586 UNIMPLEMENTED;
1587 return 0;
1588 }
1589
1590
1591 LRESULT STDCALL
1592 User32DefWindowProc(HWND hWnd,
1593 UINT Msg,
1594 WPARAM wParam,
1595 LPARAM lParam,
1596 BOOL bUnicode)
1597 {
1598 switch (Msg)
1599 {
1600 case WM_NCPAINT:
1601 {
1602 return(DefWndPaintNC(hWnd, (HRGN)wParam));
1603 }
1604 case WM_WINDOWPOSCHANGING:
1605 {
1606 break;
1607 }
1608 case WM_NCHITTEST:
1609 {
1610 POINT Point;
1611 Point.x = SLOWORD(lParam);
1612 Point.y = SHIWORD(lParam);
1613 return(DefWndHitTestNC(hWnd, Point));
1614 }
1615
1616 case WM_NCLBUTTONDOWN:
1617 {
1618 return(DefWndHandleLButtonDownNC(hWnd, wParam, lParam));
1619 }
1620
1621 case WM_NCLBUTTONUP:
1622 {
1623 return(DefWndHandleLButtonUpNC(hWnd, wParam, lParam));
1624 }
1625
1626 case WM_LBUTTONDBLCLK:
1627 case WM_NCLBUTTONDBLCLK:
1628 {
1629 return(DefWndHandleLButtonDblClkNC(hWnd, wParam, lParam));
1630 }
1631
1632 case WM_NCRBUTTONDOWN:
1633 {
1634 if (wParam == HTCAPTION)
1635 {
1636 SetCapture(hWnd);
1637 }
1638 break;
1639 }
1640 case WM_LBUTTONUP:
1641 {
1642 break;
1643 }
1644 case WM_RBUTTONUP:
1645 {
1646 POINT Pt;
1647 if (hWnd == GetCapture())
1648 {
1649 ReleaseCapture();
1650 }
1651 Pt.x = SLOWORD(lParam);
1652 Pt.y = SHIWORD(lParam);
1653 ClientToScreen(hWnd, &Pt);
1654 lParam = MAKELPARAM(Pt.x, Pt.y);
1655 if (bUnicode)
1656 {
1657 SendMessageW(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
1658 }
1659 else
1660 {
1661 SendMessageA (hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
1662 }
1663 break;
1664 }
1665
1666 case WM_NCRBUTTONUP:
1667 {
1668 /* Wine does nothing here. */
1669 break;
1670 }
1671
1672 case WM_CONTEXTMENU:
1673 {
1674 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD)
1675 {
1676 if (bUnicode)
1677 {
1678 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
1679 }
1680 else
1681 {
1682 SendMessageA(hWnd, WM_CONTEXTMENU, wParam, lParam);
1683 }
1684 }
1685 else
1686 {
1687 LONG HitCode;
1688 POINT Pt;
1689
1690 Pt.x = SLOWORD(lParam);
1691 Pt.y = SHIWORD(lParam);
1692
1693 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD)
1694 {
1695 ScreenToClient(GetParent(hWnd), &Pt);
1696 }
1697
1698 HitCode = DefWndHitTestNC(hWnd, Pt);
1699
1700 if (HitCode == HTCAPTION || HitCode == HTSYSMENU)
1701 {
1702 TrackPopupMenu(GetSystemMenu(hWnd, FALSE),
1703 TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
1704 Pt.x, Pt.y, 0, hWnd, NULL);
1705 }
1706 }
1707 break;
1708 }
1709
1710 case WM_NCACTIVATE:
1711 {
1712 return(DefWndHandleActiveNC(hWnd, wParam));
1713 }
1714
1715 case WM_NCDESTROY:
1716 {
1717 return(0);
1718 }
1719
1720 case WM_PRINT:
1721 {
1722 return(0);
1723 }
1724
1725 case WM_PAINTICON:
1726 case WM_PAINT:
1727 {
1728 PAINTSTRUCT Ps;
1729 HDC hDC = BeginPaint(hWnd, &Ps);
1730 if (hDC)
1731 {
1732 HICON hIcon;
1733 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE &&
1734 (hIcon = (HICON)GetClassLongW(hWnd, GCL_HICON)) != NULL)
1735 {
1736 RECT WindowRect;
1737 INT x, y;
1738 GetWindowRect(hWnd, &WindowRect);
1739 x = (WindowRect.right - WindowRect.left -
1740 GetSystemMetrics(SM_CXICON)) / 2;
1741 y = (WindowRect.bottom - WindowRect.top -
1742 GetSystemMetrics(SM_CYICON)) / 2;
1743 DrawIcon(hDC, x, y, hIcon);
1744 }
1745 if (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_CLIENTEDGE)
1746 {
1747 RECT WindowRect;
1748 GetClientRect(hWnd, &WindowRect);
1749 DrawEdge(hDC, &WindowRect, EDGE_SUNKEN, BF_RECT);
1750 }
1751 EndPaint(hWnd, &Ps);
1752 }
1753 return(0);
1754 }
1755
1756 case WM_SYNCPAINT:
1757 {
1758 HRGN hRgn;
1759 hRgn = CreateRectRgn(0, 0, 0, 0);
1760 if (GetUpdateRgn(hWnd, hRgn, FALSE) != NULLREGION)
1761 {
1762 RedrawWindow(hWnd, NULL, hRgn,
1763 RDW_ERASENOW | RDW_ERASE | RDW_FRAME |
1764 RDW_ALLCHILDREN);
1765 }
1766 DeleteObject(hRgn);
1767 return(0);
1768 }
1769
1770 case WM_SETREDRAW:
1771 {
1772 DefWndSetRedraw(hWnd, wParam);
1773 return(0);
1774 }
1775
1776 case WM_CLOSE:
1777 {
1778 DestroyWindow(hWnd);
1779 return(0);
1780 }
1781
1782 case WM_MOUSEACTIVATE:
1783 {
1784 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD)
1785 {
1786 LONG Ret;
1787 if (bUnicode)
1788 {
1789 Ret = SendMessageW(GetParent(hWnd), WM_MOUSEACTIVATE,
1790 wParam, lParam);
1791 }
1792 else
1793 {
1794 Ret = SendMessageA(GetParent(hWnd), WM_MOUSEACTIVATE,
1795 wParam, lParam);
1796 }
1797 if (Ret)
1798 {
1799 return(Ret);
1800 }
1801 }
1802 return((LOWORD(lParam) >= HTCLIENT) ? MA_ACTIVATE : MA_NOACTIVATE);
1803 }
1804
1805 case WM_ACTIVATE:
1806 {
1807 /* Check if the window is minimized. */
1808 if (LOWORD(lParam) != WA_INACTIVE &&
1809 !(GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE))
1810 {
1811 SetFocus(hWnd);
1812 }
1813 break;
1814 }
1815
1816 case WM_MOUSEWHEEL:
1817 {
1818 if (GetWindowLongW(hWnd, GWL_STYLE & WS_CHILD))
1819 {
1820 if (bUnicode)
1821 {
1822 return(SendMessageW(GetParent(hWnd), WM_MOUSEWHEEL,
1823 wParam, lParam));
1824 }
1825 else
1826 {
1827 return(SendMessageA(GetParent(hWnd), WM_MOUSEWHEEL,
1828 wParam, lParam));
1829 }
1830 }
1831 break;
1832 }
1833
1834 case WM_ERASEBKGND:
1835 case WM_ICONERASEBKGND:
1836 {
1837
1838 RECT Rect;
1839 HBRUSH hBrush = (HBRUSH)GetClassLongW(hWnd, GCL_HBRBACKGROUND);
1840 if (NULL == hBrush)
1841 {
1842 return 0;
1843 }
1844 if (0 == (((DWORD) hBrush) & 0xffff0000))
1845 {
1846 hBrush = GetSysColorBrush((DWORD) hBrush - 1);
1847 }
1848 GetClipBox((HDC)wParam, &Rect);
1849 FillRect((HDC)wParam, &Rect, hBrush);
1850 return(1);
1851 }
1852
1853 case WM_GETDLGCODE:
1854 {
1855 return(0);
1856 }
1857
1858 /* FIXME: Implement colour controls. */
1859
1860 case WM_SETCURSOR:
1861 {
1862 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_CHILD)
1863 {
1864 if (LOWORD(lParam) < HTLEFT || LOWORD(lParam) > HTBOTTOMRIGHT)
1865 {
1866 BOOL bResult;
1867 if (bUnicode)
1868 {
1869 bResult = SendMessageW(GetParent(hWnd), WM_SETCURSOR,
1870 wParam, lParam);
1871 }
1872 else
1873 {
1874 bResult = SendMessageA(GetParent(hWnd), WM_SETCURSOR,
1875 wParam, lParam);
1876 }
1877 if (bResult)
1878 {
1879 return(TRUE);
1880 }
1881 }
1882 }
1883 return(DefWndHandleSetCursor(hWnd, wParam, lParam));
1884 }
1885
1886 case WM_SYSCOMMAND:
1887 {
1888 POINT Pt;
1889 Pt.x = SLOWORD(lParam);
1890 Pt.y = SHIWORD(lParam);
1891 return(DefWndHandleSysCommand(hWnd, wParam, Pt));
1892 }
1893
1894 /* FIXME: Handle key messages. */
1895
1896 case WM_SHOWWINDOW:
1897 {
1898 if (lParam)
1899 {
1900 return(0);
1901 }
1902 /* FIXME: Not done correctly */
1903 if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_VISIBLE && !wParam) ||
1904 (!(GetWindowLongW(hWnd, GWL_STYLE) & WS_VISIBLE) && wParam))
1905 {
1906 return(0);
1907 }
1908 ShowWindow(hWnd, wParam ? SW_SHOWNA : SW_HIDE);
1909 break;
1910 }
1911
1912 case WM_CANCELMODE:
1913 {
1914 /* FIXME: Check for a desktop. */
1915 if (GetCapture() == hWnd)
1916 {
1917 ReleaseCapture();
1918 }
1919 break;
1920 }
1921
1922 case WM_VKEYTOITEM:
1923 case WM_CHARTOITEM:
1924 return(-1);
1925
1926 case WM_DROPOBJECT:
1927 /* FIXME: Implement this. */
1928 break;
1929
1930 case WM_QUERYDROPOBJECT:
1931 {
1932 if (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_ACCEPTFILES)
1933 {
1934 return(1);
1935 }
1936 break;
1937 }
1938
1939 case WM_QUERYDRAGICON:
1940 {
1941 UINT Len;
1942 HICON hIcon;
1943
1944 hIcon = (HICON)GetClassLongW(hWnd, GCL_HICON);
1945 if (hIcon)
1946 {
1947 return((LRESULT)hIcon);
1948 }
1949 for (Len = 1; Len < 64; Len++)
1950 {
1951 if ((hIcon = LoadIconW(NULL, MAKEINTRESOURCEW(Len))) != NULL)
1952 {
1953 return((LRESULT)hIcon);
1954 }
1955 }
1956 return((LRESULT)LoadIconW(0, IDI_APPLICATION));
1957 }
1958
1959 /* FIXME: WM_ISACTIVEICON */
1960
1961 case WM_NOTIFYFORMAT:
1962 {
1963 if (IsWindowUnicode(hWnd))
1964 {
1965 return(NFR_UNICODE);
1966 }
1967 else
1968 {
1969 return(NFR_ANSI);
1970 }
1971 }
1972
1973 case WM_SETICON:
1974 {
1975 INT Index = (wParam != 0) ? GCL_HICON : GCL_HICONSM;
1976 HICON hOldIcon = (HICON)GetClassLongW(hWnd, Index);
1977 SetClassLongW(hWnd, Index, lParam);
1978 SetWindowPos(hWnd, 0, 0, 0, 0, 0,
1979 SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
1980 SWP_NOACTIVATE | SWP_NOZORDER);
1981 return((LRESULT)hOldIcon);
1982 }
1983
1984 case WM_GETICON:
1985 {
1986 INT Index = (wParam != 0) ? GCL_HICON : GCL_HICONSM;
1987 return(GetClassLongW(hWnd, Index));
1988 }
1989
1990 case WM_HELP:
1991 {
1992 if (bUnicode)
1993 {
1994 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
1995 }
1996 else
1997 {
1998 SendMessageA(GetParent(hWnd), Msg, wParam, lParam);
1999 }
2000 break;
2001 }
2002
2003 case WM_SYSKEYDOWN:
2004 if (HIWORD(lParam) & KEYDATA_ALT)
2005 {
2006 if (wParam == VK_F4) /* Try to close the window */
2007 {
2008 //HWND hTopWnd = GetAncestor(hWnd, GA_ROOT);
2009 HWND hTopWnd = hWnd;
2010 if (!(GetClassLongW(hTopWnd, GCL_STYLE) & CS_NOCLOSE))
2011 {
2012 if (bUnicode)
2013 {
2014 PostMessageW(hTopWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
2015 }
2016 else
2017 {
2018 PostMessageA(hTopWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
2019 }
2020 }
2021 }
2022 }
2023 break;
2024 }
2025 return 0;
2026 }
2027
2028
2029 LRESULT STDCALL
2030 DefWindowProcA(HWND hWnd,
2031 UINT Msg,
2032 WPARAM wParam,
2033 LPARAM lParam)
2034 {
2035 LRESULT Result;
2036 static LPSTR WindowTextAtom = 0;
2037 PSTR WindowText;
2038
2039 switch (Msg)
2040 {
2041 case WM_NCCREATE:
2042 {
2043 CREATESTRUCTA* Cs = (CREATESTRUCTA*)lParam;
2044 if (HIWORD(Cs->lpszName))
2045 {
2046 if (0 == WindowTextAtom)
2047 {
2048 WindowTextAtom =
2049 (LPSTR)(ULONG)GlobalAddAtomA("USER32!WindowTextAtomA");
2050 }
2051 WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
2052 strlen(Cs->lpszName) * sizeof(CHAR));
2053 strcpy(WindowText, Cs->lpszName);
2054 SetPropA(hWnd, WindowTextAtom, WindowText);
2055 }
2056 return(1);
2057 }
2058
2059 case WM_NCCALCSIZE:
2060 {
2061 return(DefWndNCCalcSize(hWnd, (RECT*)lParam));
2062 }
2063
2064 case WM_WINDOWPOSCHANGING:
2065 {
2066 return(DefWndHandleWindowPosChanging(hWnd, (WINDOWPOS*)lParam));
2067 }
2068
2069 case WM_GETTEXTLENGTH:
2070 {
2071 if (WindowTextAtom == 0 ||
2072 (WindowText = GetPropA(hWnd, WindowTextAtom)) == NULL)
2073 {
2074 return(0);
2075 }
2076 return(strlen(WindowText));
2077 }
2078
2079 case WM_GETTEXT:
2080 {
2081 if (WindowTextAtom == 0 ||
2082 (WindowText = GetPropA(hWnd, WindowTextAtom)) == NULL)
2083 {
2084 if (wParam > 1)
2085 {
2086 *((PSTR)lParam) = '\0';
2087 }
2088 return(0);
2089 }
2090 strncpy((LPSTR)lParam, WindowText, wParam);
2091 return(min(wParam, strlen(WindowText)));
2092 }
2093
2094 case WM_SETTEXT:
2095 {
2096 if (0 == WindowTextAtom)
2097 {
2098 WindowTextAtom =
2099 (LPSTR)(DWORD)GlobalAddAtomA("USER32!WindowTextAtomA");
2100 }
2101 if (WindowTextAtom != 0 &&
2102 (WindowText = GetPropA(hWnd, WindowTextAtom)) == NULL)
2103 {
2104 RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText);
2105 }
2106 WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
2107 strlen((PSTR)lParam) * sizeof(CHAR));
2108 strcpy(WindowText, (PSTR)lParam);
2109 SetPropA(hWnd, WindowTextAtom, WindowText);
2110 if (0 != (GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION))
2111 {
2112 DefWndPaintNC(hWnd, (HRGN) 1);
2113 }
2114 Result = (LPARAM) TRUE;
2115 break;
2116 }
2117
2118 case WM_NCDESTROY:
2119 {
2120 if (WindowTextAtom != 0 &&
2121 (WindowText = RemovePropA(hWnd, WindowTextAtom)) == NULL)
2122 {
2123 RtlFreeHeap(GetProcessHeap(), 0, WindowText);
2124 }
2125 return(0);
2126 }
2127
2128 default:
2129 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, FALSE);
2130 break;
2131 }
2132
2133 return(Result);
2134 }
2135
2136
2137 LRESULT STDCALL
2138 DefWindowProcW(HWND hWnd,
2139 UINT Msg,
2140 WPARAM wParam,
2141 LPARAM lParam)
2142 {
2143 LRESULT Result;
2144 static LPWSTR WindowTextAtom = 0;
2145 PWSTR WindowText;
2146
2147 switch (Msg)
2148 {
2149 case WM_NCCREATE:
2150 {
2151 CREATESTRUCTW* Cs = (CREATESTRUCTW*)lParam;
2152 if (HIWORD(Cs->lpszName))
2153 {
2154 if (0 == WindowTextAtom)
2155 {
2156 WindowTextAtom =
2157 (LPWSTR)(DWORD)GlobalAddAtomW(L"USER32!WindowTextAtomW");
2158 }
2159 WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
2160 wcslen(Cs->lpszName) * sizeof(WCHAR));
2161 wcscpy(WindowText, Cs->lpszName);
2162 SetPropW(hWnd, WindowTextAtom, WindowText);
2163 }
2164 return(1);
2165 }
2166
2167 case WM_NCCALCSIZE:
2168 {
2169 return(DefWndNCCalcSize(hWnd, (RECT*)lParam));
2170 }
2171
2172 case WM_WINDOWPOSCHANGING:
2173 {
2174 return(DefWndHandleWindowPosChanging(hWnd, (WINDOWPOS*)lParam));
2175 }
2176
2177 case WM_GETTEXTLENGTH:
2178 {
2179 if (WindowTextAtom == 0 ||
2180 (WindowText = GetPropW(hWnd, WindowTextAtom)) == NULL)
2181 {
2182 return(0);
2183 }
2184 return(wcslen(WindowText));
2185 }
2186
2187 case WM_GETTEXT:
2188 {
2189 if (WindowTextAtom == 0 ||
2190 (WindowText = GetPropW(hWnd, WindowTextAtom)) == NULL)
2191 {
2192 if (wParam > 1)
2193 {
2194 ((PWSTR)lParam) = '\0';
2195 }
2196 return(0);
2197 }
2198 wcsncpy((PWSTR)lParam, WindowText, wParam);
2199 return(min(wParam, wcslen(WindowText)));
2200 }
2201
2202 case WM_SETTEXT:
2203 {
2204 if (WindowTextAtom == 0)
2205 {
2206 WindowTextAtom =
2207 (LPWSTR)(DWORD)GlobalAddAtomW(L"USER32!WindowTextAtomW");
2208 }
2209 if (WindowTextAtom != 0 &&
2210 (WindowText = GetPropW(hWnd, WindowTextAtom)) == NULL)
2211 {
2212 RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText);
2213 }
2214 WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
2215 wcslen((PWSTR)lParam) * sizeof(WCHAR));
2216 wcscpy(WindowText, (PWSTR)lParam);
2217 SetPropW(hWnd, WindowTextAtom, WindowText);
2218 if (0 != (GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION))
2219 {
2220 DefWndPaintNC(hWnd, (HRGN) 1);
2221 }
2222 Result = (LPARAM) TRUE;
2223 break;
2224 }
2225
2226 case WM_NCDESTROY:
2227 {
2228 if (WindowTextAtom != 0 &&
2229 (WindowText = RemovePropW(hWnd, WindowTextAtom)) == NULL)
2230 {
2231 RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText);
2232 }
2233 return(0);
2234 }
2235
2236 default:
2237 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, TRUE);
2238 break;
2239 }
2240
2241 return(Result);
2242 }