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