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