2003-07-05 Casper S. Hornstrup <chorns@users.sourceforge.net>
[reactos.git] / reactos / lib / user32 / windows / defwnd.c
1 /* $Id: defwnd.c,v 1.54 2003/07/05 17:57:22 chorns 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
20 #define NDEBUG
21 #include <debug.h>
22
23 /* GLOBALS *******************************************************************/
24
25 static HBITMAP hbSysMenu;
26 /* TODO: widgets will be cached here.
27 static HBITMAP hbClose;
28 static HBITMAP hbCloseD;
29 static HBITMAP hbMinimize;
30 static HBITMAP hbMinimizeD;
31 static HBITMAP hbRestore;
32 static HBITMAP hbRestoreD;
33 static HBITMAP hbMaximize;
34 static HBITMAP hbScrUp;
35 static HBITMAP hbScrDwn;
36 static HBITMAP hbScrLeft;
37 static HBITMAP hbScrRight;
38 */
39 static COLORREF SysColours[] =
40 {
41 RGB(224, 224, 224) /* COLOR_SCROLLBAR */,
42 RGB(58, 110, 165) /* COLOR_BACKGROUND */,
43 RGB(0, 0, 128) /* COLOR_ACTIVECAPTION */,
44 RGB(128, 128, 128) /* COLOR_INACTIVECAPTION */,
45 RGB(192, 192, 192) /* COLOR_MENU */,
46 RGB(192, 192, 192) /* COLOR_WINDOW */,
47 RGB(192, 192, 192) /* COLOR_WINDOWFRAME */,
48 RGB(0, 0, 0) /* COLOR_MENUTEXT */,
49 RGB(0, 0, 0) /* COLOR_WINDOWTEXT */,
50 RGB(255, 255, 255) /* COLOR_CAPTIONTEXT */,
51 RGB(128, 128, 128) /* COLOR_ACTIVEBORDER */,
52 RGB(255, 255, 255) /* COLOR_INACTIVEBORDER */,
53 RGB(255, 255, 232) /* COLOR_APPWORKSPACE */,
54 RGB(224, 224, 224) /* COLOR_HILIGHT */,
55 RGB(0, 0, 128) /* COLOR_HILIGHTTEXT */,
56 RGB(192, 192, 192) /* COLOR_BTNFACE */,
57 RGB(128, 128, 128) /* COLOR_BTNSHADOW */,
58 RGB(192, 192, 192) /* COLOR_GRAYTEXT */,
59 RGB(0, 0, 0) /* COLOR_BTNTEXT */,
60 RGB(192, 192, 192) /* COLOR_INACTIVECAPTIONTEXT */,
61 RGB(255, 255, 255) /* COLOR_BTNHILIGHT */,
62 RGB(32, 32, 32) /* COLOR_3DDKSHADOW */,
63 RGB(192, 192, 192) /* COLOR_3DLIGHT */,
64 RGB(0, 0, 0) /* COLOR_INFOTEXT */,
65 RGB(255, 255, 192) /* COLOR_INFOBK */,
66 RGB(184, 180, 184) /* COLOR_ALTERNATEBTNFACE */,
67 RGB(0, 0, 255) /* COLOR_HOTLIGHT */,
68 RGB(16, 132, 208) /* COLOR_GRADIENTACTIVECAPTION */,
69 RGB(181, 181, 181) /* COLOR_GRADIENTINACTIVECAPTION */,
70 };
71
72 static ATOM AtomInternalPos;
73
74 /* Bits in the dwKeyData */
75 #define KEYDATA_ALT 0x2000
76
77 /* FUNCTIONS *****************************************************************/
78
79 BOOL IsMaxBoxActive(HWND hWnd)
80 {
81 ULONG uStyle = GetWindowLong( hWnd, GWL_STYLE );
82 return (uStyle & WS_MAXIMIZEBOX);
83 }
84
85 BOOL IsCloseBoxActive( HWND hWnd )
86 {
87 ULONG uStyle = GetWindowLong(hWnd, GWL_STYLE );
88 return ( uStyle & WS_SYSMENU );
89 }
90
91 BOOL IsMinBoxActive( HWND hWnd )
92 {
93 ULONG uStyle = GetWindowLong( hWnd, GWL_STYLE );
94 return (uStyle & WS_MINIMIZEBOX);
95 }
96
97 INT UIGetFrameSizeX( HWND hWnd )
98 {
99 ULONG uStyle = GetWindowLong( hWnd, GWL_STYLE );
100
101 if ( uStyle & WS_THICKFRAME )
102 return GetSystemMetrics( SM_CXSIZEFRAME );
103 else
104 return GetSystemMetrics( SM_CXFRAME );
105 }
106
107 INT UIGetFrameSizeY( HWND hWnd )
108 {
109 ULONG uStyle = GetWindowLong( hWnd, GWL_STYLE );
110
111 if ( uStyle & WS_THICKFRAME )
112 return GetSystemMetrics( SM_CYSIZEFRAME );
113 else
114 return GetSystemMetrics( SM_CYFRAME );
115 }
116
117 VOID
118 UserSetupInternalPos( VOID )
119 {
120 LPSTR Str = "SysIP";
121 AtomInternalPos = GlobalAddAtomA(Str);
122 }
123
124 DWORD STDCALL
125 GetSysColor(int nIndex)
126 {
127 return SysColours[nIndex];
128 }
129
130 HPEN STDCALL
131 GetSysColorPen( int nIndex )
132 {
133 return(CreatePen(PS_SOLID, 1, SysColours[nIndex]));
134 }
135
136 HBRUSH STDCALL
137 GetSysColorBrush( int nIndex )
138 {
139 return(CreateSolidBrush(SysColours[nIndex]));
140 }
141
142
143 LRESULT STDCALL
144 DefFrameProcA( HWND hWnd,
145 HWND hWndMDIClient,
146 UINT uMsg,
147 WPARAM wParam,
148 LPARAM lParam )
149 {
150 UNIMPLEMENTED;
151 return((LRESULT)0);
152 }
153
154 LRESULT STDCALL
155 DefFrameProcW(HWND hWnd,
156 HWND hWndMDIClient,
157 UINT uMsg,
158 WPARAM wParam,
159 LPARAM lParam)
160 {
161 UNIMPLEMENTED;
162 return((LRESULT)0);
163 }
164
165
166 BOOL
167 DefWndRedrawIconTitle(HWND hWnd)
168 {
169 PINTERNALPOS lpPos = (PINTERNALPOS)GetPropA(hWnd,
170 (LPSTR)(DWORD)AtomInternalPos);
171 if (lpPos != NULL)
172 {
173 if (lpPos->IconTitle != NULL)
174 {
175 SendMessageA(lpPos->IconTitle, WM_SHOWWINDOW, TRUE, 0);
176 InvalidateRect(lpPos->IconTitle, NULL, TRUE);
177 return(TRUE);
178 }
179 }
180 return(FALSE);
181 }
182
183 BOOL
184 UserHasMenu(HWND hWnd, ULONG Style)
185 {
186 return(!(Style & WS_CHILD) && GetWindowLong(hWnd, GWL_ID) != 0);
187 }
188
189 ULONG
190 UserHasAnyFrameStyle(ULONG Style, ULONG ExStyle)
191 {
192 return((Style & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) ||
193 (ExStyle & WS_EX_DLGMODALFRAME) ||
194 (!(Style & (WS_CHILD | WS_POPUP))));
195 }
196
197 ULONG
198 UserHasDlgFrameStyle(ULONG Style, ULONG ExStyle)
199 {
200 return((ExStyle & WS_EX_DLGMODALFRAME) ||
201 ((Style & WS_DLGFRAME) && (!(Style & WS_THICKFRAME))));
202 }
203
204 ULONG
205 UserHasThickFrameStyle(ULONG Style, ULONG ExStyle)
206 {
207 return((Style & WS_THICKFRAME) &&
208 (!((Style & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)));
209 }
210
211 ULONG
212 UserHasThinFrameStyle(ULONG Style, ULONG ExStyle)
213 {
214 return((Style & WS_BORDER) ||
215 (!(Style & (WS_CHILD | WS_POPUP))));
216 }
217
218 ULONG
219 UserHasBigFrameStyle(ULONG Style, ULONG ExStyle)
220 {
221 return((Style & (WS_THICKFRAME | WS_DLGFRAME)) ||
222 (ExStyle & WS_EX_DLGMODALFRAME));
223 }
224
225 void UserGetInsideRectNC( HWND hWnd, RECT *rect )
226 {
227 RECT WindowRect;
228 ULONG Style;
229 ULONG ExStyle;
230
231 Style = GetWindowLong(hWnd, GWL_STYLE);
232 ExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
233 GetWindowRect(hWnd, &WindowRect);
234 rect->top = rect->left = 0;
235 rect->right = WindowRect.right - WindowRect.left;
236 rect->bottom = WindowRect.bottom - WindowRect.top;
237
238 if (Style & WS_ICONIC)
239 {
240 return;
241 }
242
243 /* Remove frame from rectangle */
244 if (UserHasThickFrameStyle(Style, ExStyle ))
245 {
246 InflateRect( rect, -GetSystemMetrics(SM_CXFRAME),
247 -GetSystemMetrics(SM_CYFRAME) );
248 }
249 else
250 {
251 if (UserHasDlgFrameStyle(Style, ExStyle ))
252 {
253 InflateRect( rect, -GetSystemMetrics(SM_CXDLGFRAME),
254 -GetSystemMetrics(SM_CYDLGFRAME));
255 /* FIXME: this isn't in NC_AdjustRect? why not? */
256 if (ExStyle & WS_EX_DLGMODALFRAME)
257 InflateRect( rect, -1, 0 );
258 }
259 else
260 {
261 if (UserHasThinFrameStyle(Style, ExStyle))
262 {
263 InflateRect(rect, -GetSystemMetrics(SM_CXBORDER),
264 -GetSystemMetrics(SM_CYBORDER));
265 }
266 }
267 }
268 }
269
270 void UserDrawSysMenuButton( HWND hWnd, HDC hDC, BOOL down )
271 {
272 RECT Rect;
273 HDC hDcMem;
274 HBITMAP hSavedBitmap;
275
276 hbSysMenu = LoadBitmap(0, MAKEINTRESOURCE(OBM_CLOSE));
277 UserGetInsideRectNC(hWnd, &Rect);
278 hDcMem = CreateCompatibleDC(hDC);
279 hSavedBitmap = SelectObject(hDcMem, hbSysMenu);
280 BitBlt(hDC, Rect.left + 2, Rect.top +
281 2, 16, 16, hDcMem,
282 (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD) ?
283 GetSystemMetrics(SM_CXSIZE): 0, 0, SRCCOPY);
284 SelectObject(hDcMem, hSavedBitmap);
285 DeleteDC(hDcMem);
286 }
287
288 /* FIXME: Cache bitmaps, then just bitblt instead of calling DFC() (and
289 wasting precious CPU cycles) every time */
290
291 static void UserDrawCloseButton ( HWND hWnd, HDC hDC, BOOL bDown )
292 {
293 RECT rect;
294
295 BOOL bToolWindow = GetWindowLongA( hWnd, GWL_EXSTYLE ) & WS_EX_TOOLWINDOW;
296 INT iBmpWidth = (bToolWindow ? GetSystemMetrics(SM_CXSMSIZE) :
297 GetSystemMetrics(SM_CXSIZE)) - 2;
298 INT iBmpHeight = (bToolWindow ? GetSystemMetrics(SM_CYSMSIZE) :
299 GetSystemMetrics(SM_CYSIZE) - 4);
300 INT OffsetX = UIGetFrameSizeY( hWnd );
301 INT OffsetY = UIGetFrameSizeY( hWnd );
302
303
304 if(!(GetWindowLong( hWnd, GWL_STYLE ) & WS_SYSMENU))
305 {
306 return;
307 }
308 GetWindowRect( hWnd, &rect );
309
310 rect.right = rect.right - rect.left;
311 rect.bottom = rect.bottom - rect.top;
312 rect.left = rect.top = 0;
313 SetRect(&rect,
314 rect.right - OffsetX - iBmpWidth - 3,
315 OffsetY + 2,
316 rect.right - OffsetX - 3,
317 rect.top + iBmpHeight + OffsetY + 2 );
318
319 DrawFrameControl( hDC, &rect, DFC_CAPTION,
320 (DFCS_CAPTIONCLOSE |
321 (bDown ? DFCS_PUSHED : 0) |
322 (IsCloseBoxActive(hWnd) ? 0 : DFCS_INACTIVE)) );
323 }
324
325 static void UserDrawMaxButton( HWND hWnd, HDC hDC, BOOL bDown )
326 {
327
328 RECT rect;
329 INT iBmpWidth = GetSystemMetrics(SM_CXSIZE) - 2;
330 INT iBmpHeight = GetSystemMetrics(SM_CYSIZE) - 4;
331
332 INT OffsetX = UIGetFrameSizeY( hWnd );
333 INT OffsetY = UIGetFrameSizeY( hWnd );
334
335 GetWindowRect( hWnd, &rect );
336
337 if (!IsMinBoxActive(hWnd) && !IsMaxBoxActive(hWnd))
338 return;
339 if ((GetWindowLongA( hWnd, GWL_EXSTYLE ) & WS_EX_TOOLWINDOW) == TRUE)
340 return; /* ToolWindows don't have min/max buttons */
341
342 rect.right = rect.right - rect.left;
343 rect.bottom = rect.bottom - rect.top;
344 rect.left = rect.top = 0;
345 SetRect(&rect,
346 rect.right - OffsetX - (iBmpWidth*2) - 5,
347 OffsetY + 2,
348 rect.right - iBmpWidth - OffsetX - 5,
349 rect.top + iBmpHeight + OffsetY + 2 );
350
351 DrawFrameControl( hDC, &rect, DFC_CAPTION,
352 (IsZoomed(hWnd) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMAX) |
353 (bDown ? DFCS_PUSHED : 0) |
354 (IsMaxBoxActive(hWnd) ? 0 : DFCS_INACTIVE) );
355
356 }
357
358 static void UserDrawMinButton( HWND hWnd, HDC hDC, BOOL bDown )
359 {
360
361 RECT rect;
362 INT iBmpWidth = GetSystemMetrics(SM_CXSIZE) - 2;
363 INT iBmpHeight = GetSystemMetrics(SM_CYSIZE) - 4;
364
365 INT OffsetX = UIGetFrameSizeX( hWnd );
366 INT OffsetY = UIGetFrameSizeY( hWnd );
367
368 GetWindowRect( hWnd, &rect );
369
370 if (!IsMinBoxActive(hWnd) && !IsMaxBoxActive(hWnd))
371 return;
372 if ((GetWindowLongA( hWnd, GWL_EXSTYLE ) & WS_EX_TOOLWINDOW) == TRUE)
373 return; /* ToolWindows don't have min/max buttons */
374
375 rect.right = rect.right - rect.left;
376 rect.bottom = rect.bottom - rect.top;
377 rect.left = rect.top = 0;
378 SetRect(&rect,
379 rect.right - OffsetX - (iBmpWidth*3) - 5,
380 OffsetY + 2,
381 rect.right - (iBmpWidth * 2) - OffsetX - 5,
382 rect.top + iBmpHeight + OffsetY + 2 );
383 DrawFrameControl( hDC, &rect, DFC_CAPTION,
384 DFCS_CAPTIONMIN | (bDown ? DFCS_PUSHED : 0) |
385 (IsMinBoxActive(hWnd) ? 0 : DFCS_INACTIVE) );
386 }
387
388 static void UserDrawCaptionNC( HDC hDC, RECT *rect, HWND hWnd,
389 DWORD style, BOOL active )
390 {
391 RECT r = *rect;
392 char buffer[256];
393 /* FIXME: Implement and Use DrawCaption() */
394 SelectObject( hDC, GetSysColorBrush(active ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION) );
395
396 PatBlt(hDC,rect->left + GetSystemMetrics(SM_CXFRAME), rect->top +
397 GetSystemMetrics(SM_CYFRAME), rect->right - (GetSystemMetrics(SM_CXFRAME) * 2), (rect->top +
398 GetSystemMetrics(SM_CYCAPTION)) - 1, PATCOPY );
399
400 if (style & WS_SYSMENU)
401 {
402 UserDrawSysMenuButton( hWnd, hDC, FALSE);
403 r.left += GetSystemMetrics(SM_CXSIZE) + 1;
404 UserDrawCloseButton( hWnd, hDC, FALSE);
405 r.right -= GetSystemMetrics(SM_CXSMSIZE) + 1;
406 UserDrawMinButton(hWnd, hDC, FALSE);
407 UserDrawMaxButton(hWnd, hDC, FALSE);
408 }
409 if (GetWindowTextA( hWnd, buffer, sizeof(buffer) ))
410 {
411 NONCLIENTMETRICS nclm;
412 HFONT hFont, hOldFont;
413
414 nclm.cbSize = sizeof(NONCLIENTMETRICS);
415 SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, 0, &nclm, 0);
416 SetTextColor(hDC, SysColours[ active ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT]);
417 SetBkMode( hDC, TRANSPARENT );
418 if (style & WS_EX_TOOLWINDOW)
419 hFont = CreateFontIndirectW(&nclm.lfSmCaptionFont);
420 else
421 hFont = CreateFontIndirectW(&nclm.lfCaptionFont);
422 hOldFont = SelectObject(hDC, hFont);
423 TextOutA(hDC, r.left + (GetSystemMetrics(SM_CXDLGFRAME) * 2), rect->top + (nclm.lfCaptionFont.lfHeight / 2), buffer, strlen(buffer));
424 DeleteObject (SelectObject (hDC, hOldFont));
425 }
426 }
427
428 VOID
429 UserDrawFrameNC(HWND hWnd, RECT* rect, BOOL dlgFrame, BOOL active)
430 {
431 HDC hDC = GetWindowDC(hWnd);
432 SelectObject( hDC, GetSysColorBrush(COLOR_WINDOW) );
433 DrawEdge(hDC, rect,EDGE_RAISED, BF_RECT | BF_MIDDLE);
434 }
435
436 void SCROLL_DrawScrollBar (HWND hWnd, HDC hDC, INT nBar, BOOL arrows, BOOL interior);
437
438 VOID
439 DefWndDoPaintNC(HWND hWnd, HRGN clip)
440 {
441 ULONG Active;
442 HDC hDC;
443 RECT rect;
444 ULONG Style;
445 ULONG ExStyle;
446 Active = GetWindowLongW(hWnd, GWL_STYLE) & WIN_NCACTIVATED;
447 Style = GetWindowLong(hWnd, GWL_STYLE);
448 ExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
449
450 hDC = GetDCEx(hWnd, (clip > (HRGN)1) ? clip : 0, DCX_USESTYLE | DCX_WINDOW |
451 ((clip > (HRGN)1) ? (DCX_INTERSECTRGN | DCX_KEEPCLIPRGN) : 0));
452 if (hDC == 0)
453 {
454 return;
455 }
456
457 /* FIXME: Test whether we need to draw anything at all. */
458
459 GetWindowRect(hWnd, &rect);
460 rect.right = rect.right - rect.left;
461 rect.bottom = rect.bottom - rect.top;
462 rect.top = rect.left = 0;
463 SelectObject(hDC, GetSysColorPen(COLOR_WINDOWFRAME));
464 if (UserHasThickFrameStyle(Style, ExStyle))
465 {
466 UserDrawFrameNC(hWnd, &rect, FALSE, Active);
467 }
468 else if (UserHasDlgFrameStyle(Style, ExStyle))
469 {
470 UserDrawFrameNC(hWnd, &rect, TRUE, Active);
471 }
472 if (Style & WS_CAPTION)
473 {
474 RECT r = rect;
475 r.bottom = rect.top + GetSystemMetrics(SM_CYSIZE);
476 rect.top += GetSystemMetrics(SM_CYSIZE) +
477 GetSystemMetrics(SM_CYBORDER);
478 UserDrawCaptionNC(hDC, &r, hWnd, Style, Active);
479 }
480
481 /* FIXME: Draw menu bar. */
482
483 DPRINT("drawing scrollbars..\n");
484 /* Draw scrollbars */
485 if (Style & WS_VSCROLL)
486 SCROLL_DrawScrollBar(hWnd, hDC, SB_VERT, TRUE, TRUE);
487 if (Style & WS_HSCROLL)
488 SCROLL_DrawScrollBar(hWnd, hDC, SB_HORZ, TRUE, TRUE);
489
490 /* FIXME: Draw size box.*/
491
492 ReleaseDC(hWnd, hDC);
493
494 }
495
496 LRESULT
497 DefWndPaintNC(HWND hWnd, HRGN clip)
498 {
499 if (IsWindowVisible(hWnd))
500 {
501 if (IsIconic(hWnd))
502 {
503 DefWndRedrawIconTitle(hWnd);
504 }
505 else
506 {
507 DefWndDoPaintNC(hWnd, clip);
508 }
509 }
510 return(0);
511 }
512
513 LRESULT
514 DefWndHitTestNC(HWND hWnd, POINT Point)
515 {
516 RECT WindowRect;
517 ULONG Style = GetWindowLong(hWnd, GWL_STYLE);
518 ULONG ExStyle = GetWindowLong(hWnd, GWL_EXSTYLE);
519
520 GetWindowRect(hWnd, &WindowRect);
521 if (!PtInRect(&WindowRect, Point))
522 {
523
524 return(HTNOWHERE);
525 }
526 if (Style & WS_MINIMIZE)
527 {
528 return(HTCAPTION);
529 }
530 if (UserHasThickFrameStyle(Style, ExStyle))
531 {
532 InflateRect(&WindowRect, -GetSystemMetrics(SM_CXFRAME),
533 -GetSystemMetrics(SM_CYFRAME));
534 if (!PtInRect(&WindowRect, Point))
535 {
536 if (Point.y < WindowRect.top)
537 {
538 if (Point.x < (WindowRect.left + GetSystemMetrics(SM_CXSIZE)))
539 {
540 return(HTTOPLEFT);
541 }
542 if (Point.x >= (WindowRect.right - GetSystemMetrics(SM_CXSIZE)))
543 {
544 return(HTTOPRIGHT);
545 }
546 return(HTTOP);
547 }
548 if (Point.y >= WindowRect.bottom)
549 {
550 if (Point.x < (WindowRect.left + GetSystemMetrics(SM_CXSIZE)))
551 {
552 return(HTBOTTOMLEFT);
553 }
554 if (Point.x >= (WindowRect.right - GetSystemMetrics(SM_CXSIZE)))
555 {
556 return(HTBOTTOMRIGHT);
557 }
558 return(HTBOTTOM);
559 }
560 if (Point.x < WindowRect.left)
561 {
562 if (Point.y < (WindowRect.top + GetSystemMetrics(SM_CYSIZE)))
563 {
564 return(HTTOPLEFT);
565 }
566 if (Point.y >= (WindowRect.bottom - GetSystemMetrics(SM_CYSIZE)))
567 {
568 return(HTBOTTOMLEFT);
569 }
570 return(HTLEFT);
571 }
572 if (Point.x >= WindowRect.right)
573 {
574 if (Point.y < (WindowRect.top + GetSystemMetrics(SM_CYSIZE)))
575 {
576 return(HTTOPRIGHT);
577 }
578 if (Point.y >= (WindowRect.bottom - GetSystemMetrics(SM_CYSIZE)))
579 {
580 return(HTBOTTOMRIGHT);
581 }
582 return(HTRIGHT);
583 }
584 }
585 }
586 else
587 {
588 if (UserHasDlgFrameStyle(Style, ExStyle))
589 {
590 InflateRect(&WindowRect, -GetSystemMetrics(SM_CXDLGFRAME),
591 -GetSystemMetrics(SM_CYDLGFRAME));
592 }
593 else if (UserHasThinFrameStyle(Style, ExStyle))
594 {
595 InflateRect(&WindowRect, -GetSystemMetrics(SM_CXBORDER),
596 -GetSystemMetrics(SM_CYBORDER));
597 }
598 if (!PtInRect(&WindowRect, Point))
599 {
600 return(HTBORDER);
601 }
602 }
603
604 if ((Style & WS_CAPTION) == WS_CAPTION)
605 {
606 WindowRect.top += (GetSystemMetrics(SM_CYCAPTION) -
607 GetSystemMetrics(SM_CYBORDER));
608 if (!PtInRect(&WindowRect, Point))
609 {
610 if ((Style & WS_SYSMENU) && !(ExStyle & WS_EX_TOOLWINDOW))
611 {
612 WindowRect.left += GetSystemMetrics(SM_CXSIZE);
613 WindowRect.right -= GetSystemMetrics(SM_CXSIZE) + 1;
614 }
615 if (Point.x <= WindowRect.left)
616 {
617 return(HTSYSMENU);
618 }
619 if (WindowRect.right <= Point.x)
620 {
621 return(HTCLOSE);
622 }
623
624 if (Style & WS_MAXIMIZEBOX || Style & WS_MINIMIZEBOX)
625 {
626 WindowRect.right -= GetSystemMetrics(SM_CXSIZE) - 2;
627 }
628 if (Point.x >= WindowRect.right)
629 {
630 return(HTMAXBUTTON);
631 }
632
633 if (Style & WS_MINIMIZEBOX)
634 {
635 WindowRect.right -= GetSystemMetrics(SM_CXSIZE) - 2;
636 }
637 if (Point.x >= WindowRect.right)
638 {
639 return(HTMINBUTTON);
640 }
641 return(HTCAPTION);
642 }
643 }
644
645 ScreenToClient(hWnd, &Point);
646 GetClientRect(hWnd, &WindowRect);
647
648 if (PtInRect(&WindowRect, Point))
649 {
650 return(HTCLIENT);
651 }
652
653 if (Style & WS_VSCROLL)
654 {
655 WindowRect.right += GetSystemMetrics(SM_CXVSCROLL);
656 if (PtInRect(&WindowRect, Point))
657 {
658 return(HTVSCROLL);
659 }
660 }
661
662 if (Style & WS_HSCROLL)
663 {
664 WindowRect.bottom += GetSystemMetrics(SM_CYHSCROLL);
665 if (PtInRect(&WindowRect, Point))
666 {
667 if ((Style & WS_VSCROLL) &&
668 (Point.x >= (WindowRect.right - GetSystemMetrics(SM_CXVSCROLL))))
669 {
670 return(HTSIZE);
671 }
672 return(HTHSCROLL);
673 }
674 }
675
676 if (UserHasMenu(hWnd, Style))
677 {
678 if (Point.y < 0 && Point.x >= 0 && Point.x <= WindowRect.right)
679 {
680 return(HTMENU);
681 }
682 }
683
684 return(HTNOWHERE);
685 }
686
687 VOID
688 DefWndDrawSysButton(HWND hWnd, HDC hDC, BOOL Down)
689 {
690 UNIMPLEMENTED;
691 }
692
693 LRESULT
694 DefWndHandleLButtonDownNC(HWND hWnd, WPARAM wParam, LPARAM lParam)
695 {
696 switch (wParam)
697 {
698 case HTCAPTION:
699 {
700 HWND hTopWnd = GetAncestor(hWnd, GA_ROOT);
701 if (SetActiveWindow(hTopWnd) || GetActiveWindow() == hTopWnd)
702 {
703 SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam);
704 }
705 break;
706 }
707 case HTSYSMENU:
708 {
709 if (GetWindowLong(hWnd, GWL_STYLE) & WS_SYSMENU)
710 {
711 if (!(GetWindowLong(hWnd, GWL_STYLE) & WS_MINIMIZE))
712 {
713 HDC hDC = GetWindowDC(hWnd);
714 DefWndDrawSysButton(hWnd, hDC, TRUE);
715 ReleaseDC(hWnd, hDC);
716 }
717 SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU,
718 lParam);
719 }
720 break;
721 }
722 case HTMENU:
723 {
724 SendMessageA(hWnd, WM_SYSCOMMAND, SC_MOUSEMENU, lParam);
725 break;
726 }
727 case HTHSCROLL:
728 {
729 SendMessageA(hWnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam);
730 break;
731 }
732 case HTVSCROLL:
733 {
734 SendMessageA(hWnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam);
735 break;
736 }
737 case HTMINBUTTON:
738 {
739 UserDrawMinButton(hWnd, GetWindowDC(hWnd), IsMinBoxActive(hWnd) );
740 break;
741 }
742 case HTMAXBUTTON:
743 {
744 UserDrawMaxButton(hWnd,GetWindowDC(hWnd), IsMaxBoxActive(hWnd) );
745 break;
746 }
747 case HTCLOSE:
748 {
749 UserDrawCloseButton(hWnd,GetWindowDC(hWnd),TRUE);
750 break;
751 }
752 case HTLEFT:
753 case HTRIGHT:
754 case HTTOP:
755 case HTBOTTOM:
756 case HTTOPLEFT:
757 case HTTOPRIGHT:
758 case HTBOTTOMLEFT:
759 case HTBOTTOMRIGHT:
760 {
761 SendMessageA(hWnd, WM_SYSCOMMAND, SC_SIZE + wParam - 2, lParam);
762 break;
763 }
764 }
765 return(0);
766 }
767
768 LRESULT
769 DefWndHandleLButtonDblClkNC(HWND hWnd, WPARAM wParam, LPARAM lParam)
770 {
771 UNIMPLEMENTED;
772 return(0);
773 }
774
775 LRESULT
776 DefWndHandleLButtonUpNC(HWND hWnd, WPARAM wParam, LPARAM lParam)
777 {
778 UserDrawMinButton(hWnd,GetWindowDC(hWnd),FALSE);
779 UserDrawMaxButton(hWnd,GetWindowDC(hWnd),FALSE);
780 UserDrawCloseButton(hWnd,GetWindowDC(hWnd),FALSE);
781 switch (wParam)
782 {
783 case HTMINBUTTON:
784 {
785 SendMessageA(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
786 break;
787 }
788 case HTMAXBUTTON:
789 {
790 SendMessageA(hWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
791 break;
792 }
793 case HTCLOSE:
794 {
795 SendMessageA(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
796 break;
797 }
798 }
799 return(0);
800 }
801
802 LRESULT
803 DefWndHandleActiveNC(HWND hWnd, WPARAM wParam)
804 {
805 UNIMPLEMENTED;
806 return(0);
807 }
808
809 VOID
810 DefWndSetRedraw(HWND hWnd, WPARAM wParam)
811 {
812 UNIMPLEMENTED;
813 }
814
815 LRESULT
816 DefWndHandleSetCursor(HWND hWnd, WPARAM wParam, LPARAM lParam)
817 {
818 /* Not for child windows. */
819 if (hWnd != (HWND)wParam)
820 {
821 return(0);
822 }
823
824 switch(LOWORD(lParam))
825 {
826 case HTERROR:
827 {
828 WORD Msg = HIWORD(lParam);
829 if (Msg == WM_LBUTTONDOWN || Msg == WM_MBUTTONDOWN ||
830 Msg == WM_RBUTTONDOWN)
831 {
832 MessageBeep(0);
833 }
834 break;
835 }
836
837 case HTCLIENT:
838 {
839 HICON hCursor = (HICON)GetClassLong(hWnd, GCL_HCURSOR);
840 if (hCursor)
841 {
842 SetCursor(hCursor);
843 return(TRUE);
844 }
845 return(FALSE);
846 }
847
848 case HTLEFT:
849 case HTRIGHT:
850 {
851 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZEWE)));
852 }
853
854 case HTTOP:
855 case HTBOTTOM:
856 {
857 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENS)));
858 }
859
860 case HTTOPLEFT:
861 case HTBOTTOMRIGHT:
862 {
863 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENWSE)));
864 }
865
866 case HTBOTTOMLEFT:
867 case HTTOPRIGHT:
868 {
869 return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENESW)));
870 }
871 }
872 return((LRESULT)SetCursor(LoadCursorW(0, IDC_ARROW)));
873 }
874
875 LRESULT
876 DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, POINT Pt)
877 {
878 switch (wParam)
879 {
880 case SC_CLOSE:
881 SendMessageA(hWnd, WM_CLOSE, 0, 0);
882 break;
883 default:
884 /* FIXME: Implement */
885 UNIMPLEMENTED;
886 break;
887 }
888
889 return(0);
890 }
891
892 VOID
893 DefWndAdjustRect(RECT* Rect, ULONG Style, BOOL Menu, ULONG ExStyle)
894 {
895 if (Style & WS_ICONIC)
896 {
897 return;
898 }
899
900 if (UserHasThickFrameStyle(Style, ExStyle))
901 {
902 InflateRect(Rect, GetSystemMetrics(SM_CXFRAME),
903 GetSystemMetrics(SM_CYFRAME));
904 }
905 else if (UserHasDlgFrameStyle(Style, ExStyle))
906 {
907 InflateRect(Rect, GetSystemMetrics(SM_CXDLGFRAME),
908 GetSystemMetrics(SM_CYDLGFRAME));
909 }
910 else if (UserHasThinFrameStyle(Style, ExStyle))
911 {
912 InflateRect(Rect, GetSystemMetrics(SM_CXBORDER),
913 GetSystemMetrics(SM_CYBORDER));
914 }
915 if (Style & WS_CAPTION)
916 {
917 Rect->top -= (GetSystemMetrics(SM_CYCAPTION) -
918 GetSystemMetrics(SM_CYBORDER)) + 1;
919 }
920 if (Menu)
921 {
922 Rect->top -= GetSystemMetrics(SM_CYMENU) + GetSystemMetrics(SM_CYBORDER);
923 }
924 if (Style & WS_VSCROLL)
925 {
926 Rect->right += GetSystemMetrics(SM_CXVSCROLL) - 1;
927 if (UserHasAnyFrameStyle(Style, ExStyle))
928 {
929 Rect->right++;
930 }
931 }
932 if (Style & WS_HSCROLL)
933 {
934 Rect->bottom += GetSystemMetrics(SM_CYHSCROLL) - 1;
935 if (UserHasAnyFrameStyle(Style, ExStyle))
936 {
937 Rect->bottom++;
938 }
939 }
940 }
941
942 LRESULT STDCALL
943 DefWndNCCalcSize(HWND hWnd, RECT* Rect)
944 {
945 LRESULT Result = 0;
946 LONG Style = GetClassLongW(hWnd, GCL_STYLE);
947 RECT TmpRect = {0, 0, 0, 0};
948
949 if (Style & CS_VREDRAW)
950 {
951 Result |= WVR_VREDRAW;
952 }
953 if (Style & CS_HREDRAW)
954 {
955 Result |= WVR_HREDRAW;
956 }
957
958 if (!(GetWindowLong(hWnd, GWL_STYLE) & WS_MINIMIZE))
959 {
960 DefWndAdjustRect(&TmpRect, GetWindowLong(hWnd, GWL_STYLE),
961 FALSE, GetWindowLong(hWnd, GWL_EXSTYLE));
962 Rect->left -= TmpRect.left;
963 Rect->top -= TmpRect.top;
964 Rect->right -= TmpRect.right;
965 Rect->bottom -= TmpRect.bottom;
966 /* FIXME: Adjust if the window has a menu. */
967 Rect->bottom = max(Rect->top, Rect->bottom);
968 Rect->right = max(Rect->left, Rect->right);
969 }
970 return(Result);
971 }
972
973 LRESULT
974 DefWndHandleWindowPosChanging(HWND hWnd, WINDOWPOS* Pos)
975 {
976 UNIMPLEMENTED;
977 return 0;
978 }
979
980 LRESULT STDCALL
981 User32DefWindowProc(HWND hWnd,
982 UINT Msg,
983 WPARAM wParam,
984 LPARAM lParam,
985 BOOL bUnicode)
986 {
987 switch (Msg)
988 {
989 case WM_NCPAINT:
990 {
991 return(DefWndPaintNC(hWnd, (HRGN)wParam));
992 }
993 case WM_WINDOWPOSCHANGING:
994 {
995 DbgPrint("WM_WINDOWPOSCHANGING\n\n");
996 break;
997 }
998 case WM_NCHITTEST:
999 {
1000 POINT Point;
1001 Point.x = SLOWORD(lParam);
1002 Point.y = SHIWORD(lParam);
1003 return(DefWndHitTestNC(hWnd, Point));
1004 }
1005
1006 case WM_NCLBUTTONDOWN:
1007 {
1008 return(DefWndHandleLButtonDownNC(hWnd, wParam, lParam));
1009 }
1010
1011 case WM_NCLBUTTONUP:
1012 {
1013 return(DefWndHandleLButtonUpNC(hWnd, wParam, lParam));
1014 }
1015
1016 case WM_LBUTTONDBLCLK:
1017 case WM_NCLBUTTONDBLCLK:
1018 {
1019 return(DefWndHandleLButtonDblClkNC(hWnd, wParam, lParam));
1020 }
1021
1022 case WM_NCRBUTTONDOWN:
1023 {
1024 if (wParam == HTCAPTION)
1025 {
1026 SetCapture(hWnd);
1027 }
1028 break;
1029 }
1030 case WM_LBUTTONUP:
1031 {
1032 break;
1033 }
1034 case WM_RBUTTONUP:
1035 {
1036 POINT Pt;
1037 if (hWnd == GetCapture())
1038 {
1039 ReleaseCapture();
1040 }
1041 Pt.x = SLOWORD(lParam);
1042 Pt.y = SHIWORD(lParam);
1043 ClientToScreen(hWnd, &Pt);
1044 lParam = MAKELPARAM(Pt.x, Pt.y);
1045 if (bUnicode)
1046 {
1047 SendMessageW(hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
1048 }
1049 else
1050 {
1051 SendMessageA (hWnd, WM_CONTEXTMENU, (WPARAM)hWnd, lParam);
1052 }
1053 break;
1054 }
1055
1056 case WM_NCRBUTTONUP:
1057 {
1058 /* Wine does nothing here. */
1059 break;
1060 }
1061
1062 case WM_CONTEXTMENU:
1063 {
1064 if (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD)
1065 {
1066 if (bUnicode)
1067 {
1068 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
1069 }
1070 else
1071 {
1072 SendMessageA(hWnd, WM_CONTEXTMENU, wParam, lParam);
1073 }
1074 }
1075 else
1076 {
1077 LONG HitCode;
1078 POINT Pt;
1079
1080 Pt.x = SLOWORD(lParam);
1081 Pt.y = SHIWORD(lParam);
1082
1083 if (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD)
1084 {
1085 ScreenToClient(GetParent(hWnd), &Pt);
1086 }
1087
1088 HitCode = DefWndHitTestNC(hWnd, Pt);
1089
1090 if (HitCode == HTCAPTION || HitCode == HTSYSMENU)
1091 {
1092 TrackPopupMenu(GetSystemMenu(hWnd, FALSE),
1093 TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
1094 Pt.x, Pt.y, 0, hWnd, NULL);
1095 }
1096 }
1097 break;
1098 }
1099
1100 case WM_NCACTIVATE:
1101 {
1102 return(DefWndHandleActiveNC(hWnd, wParam));
1103 }
1104
1105 case WM_NCDESTROY:
1106 {
1107 return(0);
1108 }
1109
1110 case WM_PRINT:
1111 {
1112 return(0);
1113 }
1114
1115 case WM_PAINTICON:
1116 case WM_PAINT:
1117 {
1118 PAINTSTRUCT Ps;
1119 HDC hDC = BeginPaint(hWnd, &Ps);
1120 if (hDC)
1121 {
1122
1123 HICON hIcon;
1124 if (GetWindowLongW(hWnd, GWL_STYLE) & WS_MINIMIZE &&
1125 (hIcon = (HICON)GetClassLongW(hWnd, GCL_HICON)) != NULL)
1126 {
1127 RECT WindowRect;
1128 INT x, y;
1129 GetWindowRect(hWnd, &WindowRect);
1130 x = (WindowRect.right - WindowRect.left -
1131 GetSystemMetrics(SM_CXICON)) / 2;
1132 y = (WindowRect.bottom - WindowRect.top -
1133 GetSystemMetrics(SM_CYICON)) / 2;
1134 DrawIcon(hDC, x, y, hIcon);
1135 }
1136 if(GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_CLIENTEDGE)
1137 {
1138 RECT WindowRect;
1139 GetClientRect(hWnd, &WindowRect);
1140 DrawEdge(hDC, &WindowRect, EDGE_SUNKEN, BF_RECT);
1141 }
1142 EndPaint(hWnd, &Ps);
1143 }
1144 return(0);
1145 }
1146
1147 case WM_SYNCPAINT:
1148 {
1149 HRGN hRgn;
1150 hRgn = CreateRectRgn(0, 0, 0, 0);
1151 if (GetUpdateRgn(hWnd, hRgn, FALSE) != NULLREGION)
1152 {
1153 RedrawWindow(hWnd, NULL, hRgn,
1154 RDW_ERASENOW | RDW_ERASE | RDW_FRAME |
1155 RDW_ALLCHILDREN);
1156 }
1157 DeleteObject(hRgn);
1158 return(0);
1159 }
1160
1161 case WM_SETREDRAW:
1162 {
1163 DefWndSetRedraw(hWnd, wParam);
1164 return(0);
1165 }
1166
1167 case WM_CLOSE:
1168 {
1169 DestroyWindow(hWnd);
1170 return(0);
1171 }
1172
1173 case WM_MOUSEACTIVATE:
1174 {
1175 if (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD)
1176 {
1177 LONG Ret;
1178 if (bUnicode)
1179 {
1180 Ret = SendMessageW(GetParent(hWnd), WM_MOUSEACTIVATE,
1181 wParam, lParam);
1182 }
1183 else
1184 {
1185 Ret = SendMessageA(GetParent(hWnd), WM_MOUSEACTIVATE,
1186 wParam, lParam);
1187 }
1188 if (Ret)
1189 {
1190 return(Ret);
1191 }
1192 }
1193 return((LOWORD(lParam) >= HTCLIENT) ? MA_ACTIVATE : MA_NOACTIVATE);
1194 }
1195
1196 case WM_ACTIVATE:
1197 {
1198 /* Check if the window is minimized. */
1199 if (LOWORD(lParam) != WA_INACTIVE &&
1200 !(GetWindowLong(hWnd, GWL_STYLE) & WS_MINIMIZE))
1201 {
1202 SetFocus(hWnd);
1203 }
1204 break;
1205 }
1206
1207 case WM_MOUSEWHEEL:
1208 {
1209 if (GetWindowLong(hWnd, GWL_STYLE & WS_CHILD))
1210 {
1211 if (bUnicode)
1212 {
1213 return(SendMessageW(GetParent(hWnd), WM_MOUSEWHEEL,
1214 wParam, lParam));
1215 }
1216 else
1217 {
1218 return(SendMessageA(GetParent(hWnd), WM_MOUSEWHEEL,
1219 wParam, lParam));
1220 }
1221 }
1222 break;
1223 }
1224
1225 case WM_ERASEBKGND:
1226 case WM_ICONERASEBKGND:
1227 {
1228
1229 RECT Rect;
1230 HBRUSH hBrush = (HBRUSH)GetClassLongW(hWnd, GCL_HBRBACKGROUND);
1231 GetClipBox((HDC)wParam, &Rect);
1232 FillRect((HDC)wParam, &Rect, hBrush);
1233 return(1);
1234 }
1235
1236 case WM_GETDLGCODE:
1237 {
1238 return(0);
1239 }
1240
1241 /* FIXME: Implement colour controls. */
1242
1243 case WM_SETCURSOR:
1244 {
1245 if (GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD)
1246 {
1247 if (LOWORD(lParam) < HTLEFT || LOWORD(lParam) > HTBOTTOMRIGHT)
1248 {
1249 BOOL bResult;
1250 if (bUnicode)
1251 {
1252 bResult = SendMessageW(GetParent(hWnd), WM_SETCURSOR,
1253 wParam, lParam);
1254 }
1255 else
1256 {
1257 bResult = SendMessageA(GetParent(hWnd), WM_SETCURSOR,
1258 wParam, lParam);
1259 }
1260 if (bResult)
1261 {
1262 return(TRUE);
1263 }
1264 }
1265 }
1266 return(DefWndHandleSetCursor(hWnd, wParam, lParam));
1267 }
1268
1269 case WM_SYSCOMMAND:
1270 {
1271 POINT Pt;
1272 Pt.x = SLOWORD(lParam);
1273 Pt.y = SHIWORD(lParam);
1274 return(DefWndHandleSysCommand(hWnd, wParam, Pt));
1275 }
1276
1277 /* FIXME: Handle key messages. */
1278
1279 case WM_SHOWWINDOW:
1280 {
1281 if (lParam)
1282 {
1283 return(0);
1284 }
1285 /* FIXME: Not done correctly */
1286 if ((GetWindowLongW(hWnd, GWL_STYLE) & WS_VISIBLE && !wParam) ||
1287 (!(GetWindowLongW(hWnd, GWL_STYLE) & WS_VISIBLE) && wParam))
1288 {
1289 return(0);
1290 }
1291 ShowWindow(hWnd, wParam ? SW_SHOWNA : SW_HIDE);
1292 break;
1293 }
1294
1295 case WM_CANCELMODE:
1296 {
1297 /* FIXME: Check for a desktop. */
1298 if (GetCapture() == hWnd)
1299 {
1300 ReleaseCapture();
1301 }
1302 break;
1303 }
1304
1305 case WM_VKEYTOITEM:
1306 case WM_CHARTOITEM:
1307 return(-1);
1308
1309 case WM_DROPOBJECT:
1310 /* FIXME: Implement this. */
1311 break;
1312
1313 case WM_QUERYDROPOBJECT:
1314 {
1315 if (GetWindowLongW(hWnd, GWL_EXSTYLE) & WS_EX_ACCEPTFILES)
1316 {
1317 return(1);
1318 }
1319 break;
1320 }
1321
1322 case WM_QUERYDRAGICON:
1323 {
1324 UINT Len;
1325 HICON hIcon;
1326
1327 hIcon = (HICON)GetClassLongW(hWnd, GCL_HICON);
1328 if (hIcon)
1329 {
1330 return((LRESULT)hIcon);
1331 }
1332 for (Len = 1; Len < 64; Len++)
1333 {
1334 if ((hIcon = LoadIconW(NULL, MAKEINTRESOURCE(Len))) != NULL)
1335 {
1336 return((LRESULT)hIcon);
1337 }
1338 }
1339 return((LRESULT)LoadIconW(0, IDI_APPLICATION));
1340 }
1341
1342 /* FIXME: WM_ISACTIVEICON */
1343
1344 case WM_NOTIFYFORMAT:
1345 {
1346 if (IsWindowUnicode(hWnd))
1347 {
1348 return(NFR_UNICODE);
1349 }
1350 else
1351 {
1352 return(NFR_ANSI);
1353 }
1354 }
1355
1356 case WM_SETICON:
1357 {
1358 INT Index = (wParam != 0) ? GCL_HICON : GCL_HICONSM;
1359 HICON hOldIcon = (HICON)GetClassLongW(hWnd, Index);
1360 SetClassLongW(hWnd, Index, lParam);
1361 SetWindowPos(hWnd, 0, 0, 0, 0, 0,
1362 SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
1363 SWP_NOACTIVATE | SWP_NOZORDER);
1364 return((LRESULT)hOldIcon);
1365 }
1366
1367 case WM_GETICON:
1368 {
1369 INT Index = (wParam != 0) ? GCL_HICON : GCL_HICONSM;
1370 return(GetClassLongW(hWnd, Index));
1371 }
1372
1373 case WM_HELP:
1374 {
1375 if (bUnicode)
1376 {
1377 SendMessageW(GetParent(hWnd), Msg, wParam, lParam);
1378 }
1379 else
1380 {
1381 SendMessageA(GetParent(hWnd), Msg, wParam, lParam);
1382 }
1383 break;
1384 }
1385
1386 case WM_SYSKEYDOWN:
1387 if (HIWORD(lParam) & KEYDATA_ALT)
1388 {
1389 if (wParam == VK_F4) /* Try to close the window */
1390 {
1391 //HWND hTopWnd = GetAncestor(hWnd, GA_ROOT);
1392 HWND hTopWnd = hWnd;
1393 if (!(GetClassLongW(hTopWnd, GCL_STYLE) & CS_NOCLOSE))
1394 {
1395 if (bUnicode)
1396 {
1397 PostMessageW(hTopWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
1398 }
1399 else
1400 {
1401 PostMessageA(hTopWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
1402 }
1403 }
1404 }
1405 }
1406 break;
1407 }
1408 return 0;
1409 }
1410
1411 LRESULT STDCALL
1412 DefWindowProcA(HWND hWnd,
1413 UINT Msg,
1414 WPARAM wParam,
1415 LPARAM lParam)
1416 {
1417 LRESULT Result;
1418 static LPSTR WindowTextAtom = 0;
1419 PSTR WindowText;
1420
1421 switch (Msg)
1422 {
1423 case WM_NCCREATE:
1424 {
1425 CREATESTRUCTA* Cs = (CREATESTRUCTA*)lParam;
1426 if (HIWORD(Cs->lpszName))
1427 {
1428 if (0 == WindowTextAtom)
1429 {
1430 WindowTextAtom =
1431 (LPSTR)(ULONG)GlobalAddAtomA("USER32!WindowTextAtomA");
1432 }
1433 WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
1434 strlen(Cs->lpszName) * sizeof(CHAR));
1435 strcpy(WindowText, Cs->lpszName);
1436 SetPropA(hWnd, WindowTextAtom, WindowText);
1437 }
1438 return(1);
1439 }
1440
1441 case WM_NCCALCSIZE:
1442 {
1443 return(DefWndNCCalcSize(hWnd, (RECT*)lParam));
1444 }
1445
1446 case WM_WINDOWPOSCHANGING:
1447 {
1448 return(DefWndHandleWindowPosChanging(hWnd, (WINDOWPOS*)lParam));
1449 }
1450
1451 case WM_GETTEXTLENGTH:
1452 {
1453 if (WindowTextAtom == 0 ||
1454 (WindowText = GetPropA(hWnd, WindowTextAtom)) == NULL)
1455 {
1456 return(0);
1457 }
1458 return(strlen(WindowText));
1459 }
1460
1461 case WM_GETTEXT:
1462 {
1463 if (WindowTextAtom == 0 ||
1464 (WindowText = GetPropA(hWnd, WindowTextAtom)) == NULL)
1465 {
1466 if (wParam > 1)
1467 {
1468 *((PSTR)lParam) = '\0';
1469 }
1470 return(0);
1471 }
1472 strncpy((LPSTR)lParam, WindowText, wParam);
1473 return(min(wParam, strlen(WindowText)));
1474 }
1475
1476 case WM_SETTEXT:
1477 {
1478 if (0 == WindowTextAtom)
1479 {
1480 WindowTextAtom =
1481 (LPSTR)(DWORD)GlobalAddAtomA("USER32!WindowTextAtomW");
1482 }
1483 if (WindowTextAtom != 0 &&
1484 (WindowText = GetPropA(hWnd, WindowTextAtom)) == NULL)
1485 {
1486 RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText);
1487 }
1488 WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
1489 strlen((PSTR)lParam) * sizeof(CHAR));
1490 strcpy(WindowText, (PSTR)lParam);
1491 SetPropA(hWnd, WindowTextAtom, WindowText);
1492 if (0 != (GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION))
1493 {
1494 DefWndPaintNC(hWnd, (HRGN) 1);
1495 }
1496 Result = (LPARAM) TRUE;
1497 break;
1498 }
1499
1500 case WM_NCDESTROY:
1501 {
1502 if (WindowTextAtom != 0 &&
1503 (WindowText = RemovePropA(hWnd, WindowTextAtom)) == NULL)
1504 {
1505 RtlFreeHeap(GetProcessHeap(), 0, WindowText);
1506 }
1507 return(0);
1508 }
1509
1510 default:
1511 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, FALSE);
1512 break;
1513 }
1514
1515 return(Result);
1516 }
1517
1518 LRESULT STDCALL
1519 DefWindowProcW(HWND hWnd,
1520 UINT Msg,
1521 WPARAM wParam,
1522 LPARAM lParam)
1523 {
1524 LRESULT Result;
1525 static LPWSTR WindowTextAtom = 0;
1526 PWSTR WindowText;
1527
1528 switch (Msg)
1529 {
1530 case WM_NCCREATE:
1531 {
1532 CREATESTRUCTW* Cs = (CREATESTRUCTW*)lParam;
1533 if (HIWORD(Cs->lpszName))
1534 {
1535 if (0 == WindowTextAtom)
1536 {
1537 WindowTextAtom =
1538 (LPWSTR)(DWORD)GlobalAddAtomW(L"USER32!WindowTextAtomW");
1539 }
1540 WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
1541 wcslen(Cs->lpszName) * sizeof(WCHAR));
1542 wcscpy(WindowText, Cs->lpszName);
1543 SetPropW(hWnd, WindowTextAtom, WindowText);
1544 }
1545 return(1);
1546 }
1547
1548 case WM_NCCALCSIZE:
1549 {
1550 return(DefWndNCCalcSize(hWnd, (RECT*)lParam));
1551 }
1552
1553 case WM_WINDOWPOSCHANGING:
1554 {
1555 return(DefWndHandleWindowPosChanging(hWnd, (WINDOWPOS*)lParam));
1556 }
1557
1558 case WM_GETTEXTLENGTH:
1559 {
1560 if (WindowTextAtom == 0 ||
1561 (WindowText = GetPropW(hWnd, WindowTextAtom)) == NULL)
1562 {
1563 return(0);
1564 }
1565 return(wcslen(WindowText));
1566 }
1567
1568 case WM_GETTEXT:
1569 {
1570 if (WindowTextAtom == 0 ||
1571 (WindowText = GetPropW(hWnd, WindowTextAtom)) == NULL)
1572 {
1573 if (wParam > 1)
1574 {
1575 ((PWSTR)lParam) = '\0';
1576 }
1577 return(0);
1578 }
1579 wcsncpy((PWSTR)lParam, WindowText, wParam);
1580 return(min(wParam, wcslen(WindowText)));
1581 }
1582
1583 case WM_SETTEXT:
1584 {
1585 if (WindowTextAtom != 0)
1586 {
1587 WindowTextAtom =
1588 (LPWSTR)(DWORD)GlobalAddAtom(L"USER32!WindowTextAtomW");
1589 }
1590 if (WindowTextAtom != 0 &&
1591 (WindowText = GetPropW(hWnd, WindowTextAtom)) == NULL)
1592 {
1593 RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText);
1594 }
1595 WindowText = RtlAllocateHeap(RtlGetProcessHeap(), 0,
1596 wcslen((PWSTR)lParam) * sizeof(WCHAR));
1597 wcscpy(WindowText, (PWSTR)lParam);
1598 SetPropW(hWnd, WindowTextAtom, WindowText);
1599 if (0 != (GetWindowLongW(hWnd, GWL_STYLE) & WS_CAPTION))
1600 {
1601 DefWndPaintNC(hWnd, (HRGN) 1);
1602 }
1603 Result = (LPARAM) TRUE;
1604 break;
1605 }
1606
1607 case WM_NCDESTROY:
1608 {
1609 if (WindowTextAtom != 0 &&
1610 (WindowText = RemovePropW(hWnd, WindowTextAtom)) == NULL)
1611 {
1612 RtlFreeHeap(RtlGetProcessHeap(), 0, WindowText);
1613 }
1614 return(0);
1615 }
1616
1617 default:
1618 Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, TRUE);
1619 break;
1620 }
1621
1622 return(Result);
1623 }