[WIN32SS:NTUSER] Fix Window-snap madness (#1246)
[reactos.git] / win32ss / user / ntuser / defwnd.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Win32k subsystem
4 * PURPOSE: Miscellaneous User functions
5 * FILE: win32ss/user/ntuser/defwnd.c
6 * PROGRAMER:
7 */
8
9 #include <win32k.h>
10 #include <windowsx.h>
11
12 DBG_DEFAULT_CHANNEL(UserDefwnd);
13
14 INT WINAPI DrawTextExWorker( HDC hdc, LPWSTR str, INT i_count,
15 LPRECT rect, UINT flags, LPDRAWTEXTPARAMS dtp );
16
17 INT WINAPI DrawTextW( HDC hdc, LPCWSTR str, INT count, LPRECT rect, UINT flags )
18 {
19 DRAWTEXTPARAMS dtp;
20
21 memset (&dtp, 0, sizeof(dtp));
22 dtp.cbSize = sizeof(dtp);
23 if (flags & DT_TABSTOP)
24 {
25 dtp.iTabLength = (flags >> 8) & 0xff;
26 flags &= 0xffff00ff;
27 }
28 return DrawTextExWorker(hdc, (LPWSTR)str, count, rect, flags, &dtp);
29 }
30
31
32 HBRUSH FASTCALL
33 DefWndControlColor(HDC hDC, UINT ctlType)
34 {
35 if (ctlType == CTLCOLOR_SCROLLBAR)
36 {
37 HBRUSH hb = IntGetSysColorBrush(COLOR_SCROLLBAR);
38 COLORREF bk = IntGetSysColor(COLOR_3DHILIGHT);
39 IntGdiSetTextColor(hDC, IntGetSysColor(COLOR_3DFACE));
40 IntGdiSetBkColor(hDC, bk);
41
42 /* if COLOR_WINDOW happens to be the same as COLOR_3DHILIGHT
43 * we better use 0x55aa bitmap brush to make scrollbar's background
44 * look different from the window background.
45 */
46 if ( bk == IntGetSysColor(COLOR_WINDOW))
47 return gpsi->hbrGray;
48
49 NtGdiUnrealizeObject( hb );
50 return hb;
51 }
52
53 IntGdiSetTextColor(hDC, IntGetSysColor(COLOR_WINDOWTEXT));
54
55 if ((ctlType == CTLCOLOR_EDIT) || (ctlType == CTLCOLOR_LISTBOX))
56 {
57 IntGdiSetBkColor(hDC, IntGetSysColor(COLOR_WINDOW));
58 }
59 else
60 {
61 IntGdiSetBkColor(hDC, IntGetSysColor(COLOR_3DFACE));
62 return IntGetSysColorBrush(COLOR_3DFACE);
63 }
64
65 return IntGetSysColorBrush(COLOR_WINDOW);
66 }
67
68 LRESULT FASTCALL
69 DefWndHandleWindowPosChanging(PWND pWnd, WINDOWPOS* Pos)
70 {
71 POINT maxTrack, minTrack;
72 LONG style = pWnd->style;
73
74 if (Pos->flags & SWP_NOSIZE) return 0;
75 if ((style & WS_THICKFRAME) || ((style & (WS_POPUP | WS_CHILD)) == 0))
76 {
77 co_WinPosGetMinMaxInfo(pWnd, NULL, NULL, &minTrack, &maxTrack);
78 Pos->cx = min(Pos->cx, maxTrack.x);
79 Pos->cy = min(Pos->cy, maxTrack.y);
80 if (!(style & WS_MINIMIZE))
81 {
82 if (Pos->cx < minTrack.x) Pos->cx = minTrack.x;
83 if (Pos->cy < minTrack.y) Pos->cy = minTrack.y;
84 }
85 }
86 else
87 {
88 Pos->cx = max(Pos->cx, 0);
89 Pos->cy = max(Pos->cy, 0);
90 }
91 return 0;
92 }
93
94 LRESULT FASTCALL
95 DefWndHandleWindowPosChanged(PWND pWnd, WINDOWPOS* Pos)
96 {
97 RECT Rect;
98 LONG style = pWnd->style;
99
100 IntGetClientRect(pWnd, &Rect);
101 IntMapWindowPoints(pWnd, (style & WS_CHILD ? IntGetParent(pWnd) : NULL), (LPPOINT) &Rect, 2);
102
103 if (!(Pos->flags & SWP_NOCLIENTMOVE))
104 {
105 co_IntSendMessage(UserHMGetHandle(pWnd), WM_MOVE, 0, MAKELONG(Rect.left, Rect.top));
106 }
107
108 if (!(Pos->flags & SWP_NOCLIENTSIZE) || (Pos->flags & SWP_STATECHANGED))
109 {
110 if (style & WS_MINIMIZE) co_IntSendMessage(UserHMGetHandle(pWnd), WM_SIZE, SIZE_MINIMIZED, 0 );
111 else
112 {
113 WPARAM wp = (style & WS_MAXIMIZE) ? SIZE_MAXIMIZED : SIZE_RESTORED;
114 co_IntSendMessage(UserHMGetHandle(pWnd), WM_SIZE, wp, MAKELONG(Rect.right - Rect.left, Rect.bottom - Rect.top));
115 }
116 }
117 return 0;
118 }
119
120 //
121 // Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
122 //
123 LRESULT FASTCALL
124 DefWndHandleSysCommand(PWND pWnd, WPARAM wParam, LPARAM lParam)
125 {
126 LRESULT lResult = 0;
127 BOOL Hook = FALSE;
128
129 if (ISITHOOKED(WH_CBT) || (pWnd->head.rpdesk->pDeskInfo->fsHooks & HOOKID_TO_FLAG(WH_CBT)))
130 {
131 Hook = TRUE;
132 lResult = co_HOOK_CallHooks(WH_CBT, HCBT_SYSCOMMAND, wParam, lParam);
133
134 if (lResult) return lResult;
135 }
136
137 switch (wParam & 0xfff0)
138 {
139 case SC_MOVE:
140 case SC_SIZE:
141 DefWndDoSizeMove(pWnd, wParam);
142 break;
143
144 case SC_MINIMIZE:
145 if (UserHMGetHandle(pWnd) == UserGetActiveWindow())
146 IntShowOwnedPopups(pWnd,FALSE); // This is done in ShowWindow! Need to retest!
147 co_WinPosShowWindow( pWnd, SW_MINIMIZE );
148 break;
149
150 case SC_MAXIMIZE:
151 if (((pWnd->style & WS_MINIMIZE) != 0) && UserHMGetHandle(pWnd) == UserGetActiveWindow())
152 IntShowOwnedPopups(pWnd,TRUE);
153 co_WinPosShowWindow( pWnd, SW_MAXIMIZE );
154 break;
155
156 case SC_RESTORE:
157 if (((pWnd->style & WS_MINIMIZE) != 0) && UserHMGetHandle(pWnd) == UserGetActiveWindow())
158 IntShowOwnedPopups(pWnd,TRUE);
159 co_WinPosShowWindow( pWnd, SW_RESTORE );
160 break;
161
162 case SC_CLOSE:
163 return co_IntSendMessage(UserHMGetHandle(pWnd), WM_CLOSE, 0, 0);
164
165 case SC_SCREENSAVE:
166 ERR("Screensaver Called!\n");
167 UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_START_SCREENSAVE, 0); // always lParam 0 == not Secure
168 break;
169
170 case SC_HOTKEY:
171 {
172 USER_REFERENCE_ENTRY Ref;
173
174 pWnd = ValidateHwndNoErr((HWND)lParam);
175 if (pWnd)
176 {
177 if (pWnd->spwndLastActive)
178 {
179 pWnd = pWnd->spwndLastActive;
180 }
181 UserRefObjectCo(pWnd, &Ref);
182 co_IntSetForegroundWindow(pWnd);
183 UserDerefObjectCo(pWnd);
184 if (pWnd->style & WS_MINIMIZE)
185 {
186 UserPostMessage(UserHMGetHandle(pWnd), WM_SYSCOMMAND, SC_RESTORE, 0);
187 }
188 }
189 }
190 break;
191 // case SC_DEFAULT:
192 case SC_MOUSEMENU:
193 {
194 POINT Pt;
195 Pt.x = (short)LOWORD(lParam);
196 Pt.y = (short)HIWORD(lParam);
197 MENU_TrackMouseMenuBar(pWnd, wParam & 0x000f, Pt);
198 }
199 break;
200
201 case SC_KEYMENU:
202 MENU_TrackKbdMenuBar(pWnd, wParam, (WCHAR)lParam);
203 break;
204
205
206 default:
207 // We do not support anything else here so we should return normal even when sending a hook.
208 return 0;
209 }
210
211 return(Hook ? 1 : 0); // Don't call us again from user space.
212 }
213
214 PWND FASTCALL
215 co_IntFindChildWindowToOwner(PWND Root, PWND Owner)
216 {
217 PWND Ret;
218 PWND Child, OwnerWnd;
219
220 for(Child = Root->spwndChild; Child; Child = Child->spwndNext)
221 {
222 OwnerWnd = Child->spwndOwner;
223 if(!OwnerWnd)
224 continue;
225
226 if (!(Child->style & WS_POPUP) ||
227 !(Child->style & WS_VISIBLE) ||
228 /* Fixes CMD pop up properties window from having foreground. */
229 Owner->head.pti->MessageQueue != Child->head.pti->MessageQueue)
230 continue;
231
232 if(OwnerWnd == Owner)
233 {
234 Ret = Child;
235 return Ret;
236 }
237 }
238 return NULL;
239 }
240
241 LRESULT
242 DefWndHandleSetCursor(PWND pWnd, WPARAM wParam, LPARAM lParam)
243 {
244 PWND pwndPopUP = NULL;
245 WORD Msg = HIWORD(lParam);
246
247 /* Not for child windows. */
248 if (UserHMGetHandle(pWnd) != (HWND)wParam)
249 {
250 return FALSE;
251 }
252
253 switch((short)LOWORD(lParam))
254 {
255 case HTERROR:
256 {
257 //// This is the real fix for CORE-6129! This was a "Code hole".
258 USER_REFERENCE_ENTRY Ref;
259
260 if (Msg == WM_LBUTTONDOWN)
261 {
262 // Find a pop up window to bring active.
263 pwndPopUP = co_IntFindChildWindowToOwner(UserGetDesktopWindow(), pWnd);
264 if (pwndPopUP)
265 {
266 // Not a child pop up from desktop.
267 if ( pwndPopUP != UserGetDesktopWindow()->spwndChild )
268 {
269 // Get original active window.
270 PWND pwndOrigActive = gpqForeground->spwndActive;
271
272 co_WinPosSetWindowPos(pWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
273
274 UserRefObjectCo(pwndPopUP, &Ref);
275 //UserSetActiveWindow(pwndPopUP);
276 co_IntSetForegroundWindow(pwndPopUP); // HACK
277 UserDerefObjectCo(pwndPopUP);
278
279 // If the change was made, break out.
280 if (pwndOrigActive != gpqForeground->spwndActive)
281 break;
282 }
283 }
284 }
285 ////
286 if (Msg == WM_LBUTTONDOWN || Msg == WM_MBUTTONDOWN ||
287 Msg == WM_RBUTTONDOWN || Msg == WM_XBUTTONDOWN)
288 {
289 if (pwndPopUP)
290 {
291 FLASHWINFO fwi =
292 {sizeof(FLASHWINFO),
293 UserHMGetHandle(pwndPopUP),
294 FLASHW_ALL,
295 gspv.dwForegroundFlashCount,
296 (gpsi->dtCaretBlink >> 3)};
297
298 // Now shake that window!
299 IntFlashWindowEx(pwndPopUP, &fwi);
300 }
301 UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_MESSAGE_BEEP, 0);
302 }
303 break;
304 }
305
306 case HTCLIENT:
307 {
308 if (pWnd->pcls->spcur)
309 {
310 IntSystemSetCursor(pWnd->pcls->spcur);
311 }
312 return FALSE;
313 }
314
315 case HTLEFT:
316 case HTRIGHT:
317 {
318 if (pWnd->style & WS_MAXIMIZE)
319 {
320 break;
321 }
322 IntSystemSetCursor(SYSTEMCUR(SIZEWE));
323 return TRUE;
324 }
325
326 case HTTOP:
327 case HTBOTTOM:
328 {
329 if (pWnd->style & WS_MAXIMIZE)
330 {
331 break;
332 }
333 IntSystemSetCursor(SYSTEMCUR(SIZENS));
334 return TRUE;
335 }
336
337 case HTTOPLEFT:
338 case HTBOTTOMRIGHT:
339 {
340 if (pWnd->style & WS_MAXIMIZE)
341 {
342 break;
343 }
344 IntSystemSetCursor(SYSTEMCUR(SIZENWSE));
345 return TRUE;
346 }
347
348 case HTBOTTOMLEFT:
349 case HTTOPRIGHT:
350 {
351 if (pWnd->style & WS_MAXIMIZE)
352 {
353 break;
354 }
355 IntSystemSetCursor(SYSTEMCUR(SIZENESW));
356 return TRUE;
357 }
358 }
359 IntSystemSetCursor(SYSTEMCUR(ARROW));
360 return FALSE;
361 }
362
363 VOID FASTCALL DefWndPrint( PWND pwnd, HDC hdc, ULONG uFlags)
364 {
365 /*
366 * Visibility flag.
367 */
368 if ( (uFlags & PRF_CHECKVISIBLE) &&
369 !IntIsWindowVisible(pwnd) )
370 return;
371
372 /*
373 * Unimplemented flags.
374 */
375 if ( (uFlags & PRF_CHILDREN) ||
376 (uFlags & PRF_OWNED) ||
377 (uFlags & PRF_NONCLIENT) )
378 {
379 FIXME("WM_PRINT message with unsupported flags\n");
380 }
381
382 /*
383 * Background
384 */
385 if ( uFlags & PRF_ERASEBKGND)
386 co_IntSendMessage(UserHMGetHandle(pwnd), WM_ERASEBKGND, (WPARAM)hdc, 0);
387
388 /*
389 * Client area
390 */
391 if ( uFlags & PRF_CLIENT)
392 co_IntSendMessage(UserHMGetHandle(pwnd), WM_PRINTCLIENT, (WPARAM)hdc, uFlags);
393 }
394
395 BOOL
396 UserPaintCaption(PWND pWnd, INT Flags)
397 {
398 BOOL Ret = FALSE;
399
400 if ( (pWnd->style & WS_VISIBLE) && ((pWnd->style & WS_CAPTION) == WS_CAPTION) )
401 {
402 if (pWnd->state & WNDS_HASCAPTION && pWnd->head.pti->MessageQueue == gpqForeground)
403 Flags |= DC_ACTIVE;
404 /*
405 * When themes are not enabled we can go on and paint the non client area.
406 * However if we do that with themes enabled we will draw a classic frame.
407 * This is solved by sending a themes specific message to notify the themes
408 * engine that the caption needs to be redrawn
409 */
410 if (gpsi->dwSRVIFlags & SRVINFO_APIHOOK)
411 {
412 /*
413 * This will cause uxtheme to either paint the themed caption or call
414 * RealUserDrawCaption in order to draw the classic caption when themes
415 * are disabled but the themes service is enabled
416 */
417 TRACE("UDCB Flags %08x\n");
418 co_IntSendMessage(UserHMGetHandle(pWnd), WM_NCUAHDRAWCAPTION, Flags, 0);
419 }
420 else
421 {
422 HDC hDC = UserGetDCEx(pWnd, NULL, DCX_WINDOW|DCX_USESTYLE);
423 UserDrawCaptionBar(pWnd, hDC, Flags);
424 UserReleaseDC(pWnd, hDC, FALSE);
425 }
426 Ret = TRUE;
427 }
428 // Support window tray
429 return Ret;
430 }
431
432 // WM_SETICON
433 LRESULT FASTCALL
434 DefWndSetIcon(PWND pWnd, WPARAM wParam, LPARAM lParam)
435 {
436 HICON hIcon, hIconSmall, hIconOld;
437
438 if ( wParam > ICON_SMALL2 )
439 {
440 EngSetLastError(ERROR_INVALID_PARAMETER);
441 return 0;
442 }
443 hIconSmall = UserGetProp(pWnd, gpsi->atomIconSmProp, TRUE);
444 hIcon = UserGetProp(pWnd, gpsi->atomIconProp, TRUE);
445
446 hIconOld = wParam == ICON_BIG ? hIcon : hIconSmall;
447
448 switch(wParam)
449 {
450 case ICON_BIG:
451 hIcon = (HICON)lParam;
452 break;
453 case ICON_SMALL:
454 hIconSmall = (HICON)lParam;
455 break;
456 case ICON_SMALL2:
457 ERR("FIXME: Set ICON_SMALL2 support!\n");
458 default:
459 break;
460 }
461
462 UserSetProp(pWnd, gpsi->atomIconProp, hIcon, TRUE);
463 UserSetProp(pWnd, gpsi->atomIconSmProp, hIconSmall, TRUE);
464
465 if ((pWnd->style & WS_CAPTION ) == WS_CAPTION)
466 UserPaintCaption(pWnd, DC_ICON);
467
468 return (LRESULT)hIconOld;
469 }
470
471 LRESULT FASTCALL
472 DefWndGetIcon(PWND pWnd, WPARAM wParam, LPARAM lParam)
473 {
474 HICON hIconRet;
475 if ( wParam > ICON_SMALL2 )
476 {
477 EngSetLastError(ERROR_INVALID_PARAMETER);
478 return 0;
479 }
480 switch(wParam)
481 {
482 case ICON_BIG:
483 hIconRet = UserGetProp(pWnd, gpsi->atomIconProp, TRUE);
484 break;
485 case ICON_SMALL:
486 case ICON_SMALL2:
487 hIconRet = UserGetProp(pWnd, gpsi->atomIconSmProp, TRUE);
488 break;
489 default:
490 break;
491 }
492 return (LRESULT)hIconRet;
493 }
494
495 VOID FASTCALL
496 DefWndScreenshot(PWND pWnd)
497 {
498 RECT rect;
499 HDC hdc;
500 INT w;
501 INT h;
502 HBITMAP hbitmap;
503 HDC hdc2;
504 SETCLIPBDATA scd = {FALSE, FALSE};
505
506 UserOpenClipboard(UserHMGetHandle(pWnd));
507 UserEmptyClipboard();
508
509 hdc = UserGetWindowDC(pWnd);
510 IntGetWindowRect(pWnd, &rect);
511 w = rect.right - rect.left;
512 h = rect.bottom - rect.top;
513
514 hbitmap = NtGdiCreateCompatibleBitmap(hdc, w, h);
515 hdc2 = NtGdiCreateCompatibleDC(hdc);
516 NtGdiSelectBitmap(hdc2, hbitmap);
517
518 NtGdiBitBlt(hdc2, 0, 0, w, h, hdc, 0, 0, SRCCOPY, 0, 0);
519
520 UserSetClipboardData(CF_BITMAP, hbitmap, &scd);
521
522 UserReleaseDC(pWnd, hdc, FALSE);
523 UserReleaseDC(pWnd, hdc2, FALSE);
524
525 UserCloseClipboard();
526 }
527
528 /*
529 Win32k counterpart of User DefWindowProc
530 */
531 LRESULT FASTCALL
532 IntDefWindowProc(
533 PWND Wnd,
534 UINT Msg,
535 WPARAM wParam,
536 LPARAM lParam,
537 BOOL Ansi)
538 {
539 PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
540 LRESULT lResult = 0;
541 USER_REFERENCE_ENTRY Ref;
542
543 if (Msg > WM_USER) return 0;
544
545 switch (Msg)
546 {
547 case WM_GETTEXTLENGTH:
548 {
549 PWSTR buf;
550 ULONG len;
551
552 if (Wnd != NULL && Wnd->strName.Length != 0)
553 {
554 buf = Wnd->strName.Buffer;
555 if (buf != NULL &&
556 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len,
557 buf,
558 Wnd->strName.Length)))
559 {
560 lResult = (LRESULT) (Wnd->strName.Length / sizeof(WCHAR));
561 }
562 }
563 else lResult = 0L;
564
565 break;
566 }
567
568 case WM_GETTEXT: // FIXME: Handle Ansi
569 {
570 PWSTR buf = NULL;
571 PWSTR outbuf = (PWSTR)lParam;
572
573 if (Wnd != NULL && wParam != 0)
574 {
575 if (Wnd->strName.Buffer != NULL)
576 buf = Wnd->strName.Buffer;
577 else
578 outbuf[0] = L'\0';
579
580 if (buf != NULL)
581 {
582 if (Wnd->strName.Length != 0)
583 {
584 lResult = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1);
585 RtlCopyMemory(outbuf,
586 buf,
587 lResult * sizeof(WCHAR));
588 outbuf[lResult] = L'\0';
589 }
590 else
591 outbuf[0] = L'\0';
592 }
593 }
594 break;
595 }
596
597 case WM_SETTEXT: // FIXME: Handle Ansi
598 {
599 DefSetText(Wnd, (PCWSTR)lParam);
600
601 if ((Wnd->style & WS_CAPTION) == WS_CAPTION)
602 UserPaintCaption(Wnd, DC_TEXT);
603 IntNotifyWinEvent(EVENT_OBJECT_NAMECHANGE, Wnd, OBJID_WINDOW, CHILDID_SELF, 0);
604 lResult = 1;
605 break;
606 }
607
608 case WM_SYSCOMMAND:
609 {
610 TRACE("hwnd %p WM_SYSCOMMAND %lx %lx\n", Wnd->head.h, wParam, lParam );
611 lResult = DefWndHandleSysCommand(Wnd, wParam, lParam);
612 break;
613 }
614
615 case WM_SHOWWINDOW:
616 {
617 if ((Wnd->style & WS_VISIBLE) && wParam) break;
618 if (!(Wnd->style & WS_VISIBLE) && !wParam) break;
619 if (!Wnd->spwndOwner) break;
620 if (LOWORD(lParam))
621 {
622 co_WinPosShowWindow(Wnd, wParam ? SW_SHOWNOACTIVATE : SW_HIDE);
623 }
624 break;
625 }
626
627 case WM_CLIENTSHUTDOWN:
628 return IntClientShutdown(Wnd, wParam, lParam);
629
630 case WM_APPCOMMAND:
631 if ( (Wnd->style & (WS_POPUP|WS_CHILD)) != WS_CHILD &&
632 Wnd != co_GetDesktopWindow(Wnd) )
633 {
634 if (!co_HOOK_CallHooks(WH_SHELL, HSHELL_APPCOMMAND, wParam, lParam))
635 co_IntShellHookNotify(HSHELL_APPCOMMAND, wParam, lParam);
636 break;
637 }
638 UserRefObjectCo(Wnd->spwndParent, &Ref);
639 lResult = co_IntSendMessage(UserHMGetHandle(Wnd->spwndParent), WM_APPCOMMAND, wParam, lParam);
640 UserDerefObjectCo(Wnd->spwndParent);
641 break;
642
643 case WM_KEYF1:
644 {
645 HELPINFO hi;
646 HMENU hMenu = UlongToHandle(Wnd->IDMenu);
647 PWND pwndActive = MENU_IsMenuActive();
648 hi.cbSize = sizeof(HELPINFO);
649 hi.MousePos = gpsi->ptCursor;
650 hi.iContextType = HELPINFO_MENUITEM;
651 hi.hItemHandle = pwndActive ? UserHMGetHandle(pwndActive) : UserHMGetHandle(Wnd);
652 hi.iCtrlId = (Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD ? IntMenuItemFromPoint(Wnd, hMenu, hi.MousePos) : 0;
653 hi.dwContextId = IntGetWindowContextHelpId(Wnd);
654
655 co_IntSendMessage( UserHMGetHandle(Wnd), WM_HELP, 0, (LPARAM)&hi );
656 break;
657 }
658
659 case WM_SETICON:
660 {
661 return DefWndSetIcon(Wnd, wParam, lParam);
662 }
663
664 case WM_GETICON:
665 {
666 return DefWndGetIcon(Wnd, wParam, lParam);
667 }
668
669 case WM_HELP:
670 {
671 PWND Parent = IntGetParent(Wnd);
672 co_IntSendMessage(UserHMGetHandle(Parent), Msg, wParam, lParam);
673 break;
674 }
675
676 case WM_LBUTTONDOWN:
677 case WM_RBUTTONDOWN:
678 case WM_MBUTTONDOWN:
679 pti->MessageQueue->QF_flags &= ~(QF_FMENUSTATUS|QF_FMENUSTATUSBREAK);
680 break;
681
682 case WM_NCLBUTTONDOWN:
683 return NC_HandleNCLButtonDown(Wnd, wParam, lParam);
684
685 case WM_NCRBUTTONDOWN:
686 return NC_HandleNCRButtonDown(Wnd, wParam, lParam);
687
688 case WM_LBUTTONDBLCLK:
689 return NC_HandleNCLButtonDblClk(Wnd, HTCLIENT, lParam);
690
691 case WM_NCLBUTTONDBLCLK:
692 return NC_HandleNCLButtonDblClk(Wnd, wParam, lParam);
693
694 case WM_RBUTTONUP:
695 {
696 POINT Pt;
697
698 Pt.x = GET_X_LPARAM(lParam);
699 Pt.y = GET_Y_LPARAM(lParam);
700 IntClientToScreen(Wnd, &Pt);
701 lParam = MAKELPARAM(Pt.x, Pt.y);
702 co_IntSendMessage(UserHMGetHandle(Wnd), WM_CONTEXTMENU, (WPARAM)UserHMGetHandle(Wnd), lParam);
703 break;
704 }
705
706 case WM_NCRBUTTONUP:
707 /*
708 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked
709 * in Windows), but what _should_ we do? According to MSDN :
710 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND
711 * message to the window". When is it appropriate?
712 */
713 ERR("WM_NCRBUTTONUP\n");
714 break;
715
716 case WM_XBUTTONUP:
717 case WM_NCXBUTTONUP:
718 if (HIWORD(wParam) == XBUTTON1 || HIWORD(wParam) == XBUTTON2)
719 {
720 co_IntSendMessage(UserHMGetHandle(Wnd), WM_APPCOMMAND, (WPARAM)UserHMGetHandle(Wnd),
721 MAKELPARAM(LOWORD(wParam), FAPPCOMMAND_MOUSE | HIWORD(wParam)));
722 }
723 break;
724
725
726 case WM_CONTEXTMENU:
727 {
728 if (Wnd->style & WS_CHILD)
729 {
730 co_IntSendMessage(UserHMGetHandle(IntGetParent(Wnd)), Msg, wParam, lParam);
731 }
732 else
733 {
734 POINT Pt;
735 LONG_PTR Style;
736 LONG HitCode;
737
738 Style = Wnd->style;
739
740 Pt.x = GET_X_LPARAM(lParam);
741 Pt.y = GET_Y_LPARAM(lParam);
742 if (Style & WS_CHILD)
743 {
744 IntScreenToClient(IntGetParent(Wnd), &Pt);
745 }
746
747 HitCode = GetNCHitEx(Wnd, Pt);
748
749 if (HitCode == HTCAPTION || HitCode == HTSYSMENU)
750 {
751 PMENU SystemMenu;
752 UINT Flags;
753
754 if((SystemMenu = IntGetSystemMenu(Wnd, FALSE)))
755 {
756 MENU_InitSysMenuPopup(SystemMenu, Wnd->style, Wnd->pcls->style, HitCode);
757
758 if(HitCode == HTCAPTION)
759 Flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON;
760 else
761 Flags = TPM_LEFTBUTTON;
762
763 IntTrackPopupMenuEx(SystemMenu, Flags|TPM_SYSTEM_MENU, Pt.x, Pt.y, Wnd, NULL);
764 }
765 }
766 if (HitCode == HTHSCROLL || HitCode == HTVSCROLL)
767 {
768 WARN("Scroll Menu Not Supported\n");
769 }
770 }
771 break;
772 }
773
774 case WM_KEYDOWN:
775 if (wParam == VK_F10)
776 {
777 pti->MessageQueue->QF_flags |= QF_FF10STATUS;
778
779 if (UserGetKeyState(VK_SHIFT) & 0x8000)
780 {
781 co_IntSendMessage(UserHMGetHandle(Wnd), WM_CONTEXTMENU, (WPARAM)UserHMGetHandle(Wnd), MAKELPARAM(-1, -1));
782 }
783 }
784 if (IS_KEY_DOWN(gafAsyncKeyState, VK_LWIN) || IS_KEY_DOWN(gafAsyncKeyState, VK_RWIN))
785 {
786 HWND hwndTop = UserGetForegroundWindow();
787 PWND topWnd = UserGetWindowObject(hwndTop);
788 if (topWnd)
789 {
790 if ((topWnd->style & WS_THICKFRAME) == 0)
791 {
792 return 0;
793 }
794
795 if (wParam == VK_DOWN)
796 {
797 if (topWnd->style & WS_MAXIMIZE)
798 co_IntSendMessage(hwndTop, WM_SYSCOMMAND, SC_RESTORE, lParam);
799 else
800 co_IntSendMessage(hwndTop, WM_SYSCOMMAND, SC_MINIMIZE, lParam);
801 }
802 else if (wParam == VK_UP)
803 {
804 RECT currentRect;
805 if ((topWnd->InternalPos.NormalRect.right == topWnd->InternalPos.NormalRect.left) ||
806 (topWnd->InternalPos.NormalRect.top == topWnd->InternalPos.NormalRect.bottom))
807 {
808 currentRect = topWnd->rcWindow;
809 }
810 else
811 {
812 currentRect = topWnd->InternalPos.NormalRect;
813 }
814 co_IntSendMessage(hwndTop, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
815
816 // save normal rect if maximazing snapped window
817 topWnd->InternalPos.NormalRect = currentRect;
818 }
819 else if (wParam == VK_LEFT || wParam == VK_RIGHT)
820 {
821 RECT snapRect, normalRect, windowRect;
822 BOOL snapped;
823 normalRect = topWnd->InternalPos.NormalRect;
824 snapped = (normalRect.left != 0 && normalRect.right != 0 &&
825 normalRect.top != 0 && normalRect.bottom != 0);
826
827 if (topWnd->style & WS_MAXIMIZE)
828 {
829 co_IntSendMessage(hwndTop, WM_SYSCOMMAND, SC_RESTORE, lParam);
830 snapped = FALSE;
831 }
832 windowRect = topWnd->rcWindow;
833
834 UserSystemParametersInfo(SPI_GETWORKAREA, 0, &snapRect, 0);
835 if (wParam == VK_LEFT)
836 {
837 snapRect.right = (snapRect.left + snapRect.right) / 2;
838 }
839 else // VK_RIGHT
840 {
841 snapRect.left = (snapRect.left + snapRect.right) / 2;
842 }
843
844 if (snapped)
845 {
846 // if window was snapped but moved to other location - restore normal size
847 if (!IntEqualRect(&snapRect, &windowRect))
848 {
849 RECT empty = {0, 0, 0, 0};
850 co_WinPosSetWindowPos(topWnd,
851 0,
852 normalRect.left,
853 normalRect.top,
854 normalRect.right - normalRect.left,
855 normalRect.bottom - normalRect.top,
856 0);
857 topWnd->InternalPos.NormalRect = empty;
858 }
859 }
860 else
861 {
862 co_WinPosSetWindowPos(topWnd,
863 0,
864 snapRect.left,
865 snapRect.top,
866 snapRect.right - snapRect.left,
867 snapRect.bottom - snapRect.top,
868 0);
869 topWnd->InternalPos.NormalRect = windowRect;
870 }
871 }
872 }
873 }
874 break;
875
876 case WM_SYSKEYDOWN:
877 {
878 if (HIWORD(lParam) & KF_ALTDOWN)
879 { /* Previous state, if the key was down before this message,
880 this is a cheap way to ignore autorepeat keys. */
881 if ( !(HIWORD(lParam) & KF_REPEAT) )
882 {
883 if ( ( wParam == VK_MENU ||
884 wParam == VK_LMENU ||
885 wParam == VK_RMENU ) && !(pti->MessageQueue->QF_flags & QF_FMENUSTATUS)) //iMenuSysKey )
886 pti->MessageQueue->QF_flags |= QF_FMENUSTATUS; //iMenuSysKey = 1;
887 else
888 pti->MessageQueue->QF_flags &= ~QF_FMENUSTATUS; //iMenuSysKey = 0;
889 }
890
891 pti->MessageQueue->QF_flags &= ~QF_FF10STATUS; //iF10Key = 0;
892
893 if (wParam == VK_F4) /* Try to close the window */
894 {
895 PWND top = UserGetAncestor(Wnd, GA_ROOT);
896 if (!(top->style & CS_NOCLOSE))
897 UserPostMessage(UserHMGetHandle(top), WM_SYSCOMMAND, SC_CLOSE, 0);
898 }
899 else if (wParam == VK_SNAPSHOT) // Alt-VK_SNAPSHOT?
900 {
901 PWND pwnd = Wnd;
902 while (IntGetParent(pwnd) != NULL)
903 {
904 pwnd = IntGetParent(pwnd);
905 }
906 ERR("DefWndScreenshot\n");
907 DefWndScreenshot(pwnd);
908 }
909 else if ( wParam == VK_ESCAPE || wParam == VK_TAB ) // Alt-Tab/ESC Alt-Shift-Tab/ESC
910 {
911 WPARAM wParamTmp;
912 HWND Active = UserGetActiveWindow(); // Noticed MDI problem.
913 if (!Active)
914 {
915 FIXME("WM_SYSKEYDOWN VK_ESCAPE no active\n");
916 break;
917 }
918 wParamTmp = UserGetKeyState(VK_SHIFT) & 0x8000 ? SC_PREVWINDOW : SC_NEXTWINDOW;
919 co_IntSendMessage( Active, WM_SYSCOMMAND, wParamTmp, wParam );
920 }
921 }
922 else if( wParam == VK_F10 )
923 {
924 if (UserGetKeyState(VK_SHIFT) & 0x8000)
925 co_IntSendMessage( UserHMGetHandle(Wnd), WM_CONTEXTMENU, (WPARAM)UserHMGetHandle(Wnd), MAKELPARAM(-1, -1) );
926 pti->MessageQueue->QF_flags |= QF_FF10STATUS; //iF10Key = 1;
927 }
928 else if( wParam == VK_ESCAPE && (UserGetKeyState(VK_SHIFT) & 0x8000))
929 co_IntSendMessage( UserHMGetHandle(Wnd), WM_SYSCOMMAND, SC_KEYMENU, ' ' );
930 break;
931 }
932
933 case WM_KEYUP:
934 case WM_SYSKEYUP:
935 {
936 /* Press and release F10 or ALT */
937 if (((wParam == VK_MENU || wParam == VK_LMENU || wParam == VK_RMENU)
938 && (pti->MessageQueue->QF_flags & (QF_FMENUSTATUS|QF_FMENUSTATUSBREAK)) == QF_FMENUSTATUS /*iMenuSysKey*/) ||
939 ((wParam == VK_F10) && pti->MessageQueue->QF_flags & QF_FF10STATUS /*iF10Key*/))
940 co_IntSendMessage( UserHMGetHandle(UserGetAncestor( Wnd, GA_ROOT )), WM_SYSCOMMAND, SC_KEYMENU, 0L );
941 pti->MessageQueue->QF_flags &= ~(QF_FMENUSTATUS|QF_FMENUSTATUSBREAK|QF_FF10STATUS); //iMenuSysKey = iF10Key = 0;
942 break;
943 }
944
945 case WM_SYSCHAR:
946 {
947 pti->MessageQueue->QF_flags &= ~(QF_FMENUSTATUS|QF_FMENUSTATUSBREAK); //iMenuSysKey = 0;
948 if (wParam == VK_RETURN && (Wnd->style & WS_MINIMIZE) != 0)
949 {
950 UserPostMessage( UserHMGetHandle(Wnd), WM_SYSCOMMAND, SC_RESTORE, 0L );
951 break;
952 }
953 if ((HIWORD(lParam) & KF_ALTDOWN) && wParam)
954 {
955 if (wParam == VK_TAB || wParam == VK_ESCAPE) break;
956 if (wParam == VK_SPACE && Wnd->style & WS_CHILD)
957 co_IntSendMessage( UserHMGetHandle(IntGetParent(Wnd)), Msg, wParam, lParam );
958 else
959 co_IntSendMessage( UserHMGetHandle(Wnd), WM_SYSCOMMAND, SC_KEYMENU, wParam );
960 }
961 else /* check for Ctrl-Esc */
962 if (wParam != VK_ESCAPE) UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_MESSAGE_BEEP, 0); //MessageBeep(0);
963 break;
964 }
965
966 case WM_CANCELMODE:
967 {
968 pti->MessageQueue->QF_flags &= ~(QF_FMENUSTATUS|QF_FMENUSTATUSBREAK);
969
970 MENU_EndMenu( Wnd );
971 if (IntGetCaptureWindow() == UserHMGetHandle(Wnd))
972 {
973 IntReleaseCapture();
974 }
975 break;
976 }
977
978 case WM_CLOSE:
979 co_UserDestroyWindow(Wnd);
980 break;
981
982 case WM_CTLCOLORMSGBOX:
983 case WM_CTLCOLOREDIT:
984 case WM_CTLCOLORLISTBOX:
985 case WM_CTLCOLORBTN:
986 case WM_CTLCOLORDLG:
987 case WM_CTLCOLORSTATIC:
988 case WM_CTLCOLORSCROLLBAR:
989 return (LRESULT) DefWndControlColor((HDC)wParam, Msg - WM_CTLCOLORMSGBOX);
990
991 case WM_CTLCOLOR:
992 return (LRESULT) DefWndControlColor((HDC)wParam, HIWORD(lParam));
993
994 case WM_SETCURSOR:
995 {
996 if (Wnd->style & WS_CHILD)
997 {
998 /* with the exception of the border around a resizable wnd,
999 * give the parent first chance to set the cursor */
1000 if (LOWORD(lParam) < HTLEFT || LOWORD(lParam) > HTBOTTOMRIGHT)
1001 {
1002 PWND parent = Wnd->spwndParent;//IntGetParent( Wnd );
1003 if (parent != UserGetDesktopWindow() &&
1004 co_IntSendMessage( UserHMGetHandle(parent), WM_SETCURSOR, wParam, lParam))
1005 return TRUE;
1006 }
1007 }
1008 return DefWndHandleSetCursor(Wnd, wParam, lParam);
1009 }
1010
1011 case WM_MOUSEACTIVATE:
1012 if (Wnd->style & WS_CHILD)
1013 {
1014 LONG Ret;
1015 HWND hwndParent;
1016 PWND pwndParent = IntGetParent(Wnd);
1017 hwndParent = pwndParent ? UserHMGetHandle(pwndParent) : NULL;
1018 if (hwndParent) Ret = co_IntSendMessage(hwndParent, WM_MOUSEACTIVATE, wParam, lParam);
1019 if (Ret) return (Ret);
1020 }
1021 return ( (HIWORD(lParam) == WM_LBUTTONDOWN && LOWORD(lParam) == HTCAPTION) ? MA_NOACTIVATE : MA_ACTIVATE );
1022
1023 case WM_ACTIVATE:
1024 /* The default action in Windows is to set the keyboard focus to
1025 * the window, if it's being activated and not minimized */
1026 if (LOWORD(wParam) != WA_INACTIVE &&
1027 !(Wnd->style & WS_MINIMIZE))
1028 {
1029 //ERR("WM_ACTIVATE %p\n",hWnd);
1030 co_UserSetFocus(Wnd);
1031 }
1032 break;
1033
1034 case WM_MOUSEWHEEL:
1035 if (Wnd->style & WS_CHILD)
1036 {
1037 HWND hwndParent;
1038 PWND pwndParent = IntGetParent(Wnd);
1039 hwndParent = pwndParent ? UserHMGetHandle(pwndParent) : NULL;
1040 return co_IntSendMessage( hwndParent, WM_MOUSEWHEEL, wParam, lParam);
1041 }
1042 break;
1043
1044 case WM_ERASEBKGND:
1045 case WM_ICONERASEBKGND:
1046 {
1047 RECT Rect;
1048 HBRUSH hBrush = Wnd->pcls->hbrBackground;
1049 if (!hBrush) return 0;
1050 if (hBrush <= (HBRUSH)COLOR_MENUBAR)
1051 {
1052 hBrush = IntGetSysColorBrush(HandleToUlong(hBrush));
1053 }
1054 if (Wnd->pcls->style & CS_PARENTDC)
1055 {
1056 /* can't use GetClipBox with a parent DC or we fill the whole parent */
1057 IntGetClientRect(Wnd, &Rect);
1058 GreDPtoLP((HDC)wParam, (LPPOINT)&Rect, 2);
1059 }
1060 else
1061 {
1062 GdiGetClipBox((HDC)wParam, &Rect);
1063 }
1064 FillRect((HDC)wParam, &Rect, hBrush);
1065 return (1);
1066 }
1067
1068 case WM_GETHOTKEY:
1069 //ERR("WM_GETHOTKEY\n");
1070 return DefWndGetHotKey(Wnd);
1071 case WM_SETHOTKEY:
1072 //ERR("WM_SETHOTKEY\n");
1073 return DefWndSetHotKey(Wnd, wParam);
1074
1075 case WM_NCHITTEST:
1076 {
1077 POINT Point;
1078 Point.x = GET_X_LPARAM(lParam);
1079 Point.y = GET_Y_LPARAM(lParam);
1080 return GetNCHitEx(Wnd, Point);
1081 }
1082
1083 case WM_PRINT:
1084 {
1085 DefWndPrint(Wnd, (HDC)wParam, lParam);
1086 return (0);
1087 }
1088
1089 case WM_SYSCOLORCHANGE:
1090 {
1091 /* force to redraw non-client area */
1092 UserPaintCaption(Wnd, DC_NC);
1093 /* Use InvalidateRect to redraw client area, enable
1094 * erase to redraw all subcontrols otherwise send the
1095 * WM_SYSCOLORCHANGE to child windows/controls is required
1096 */
1097 co_UserRedrawWindow( Wnd, NULL, NULL, RDW_ALLCHILDREN|RDW_INVALIDATE|RDW_ERASE);
1098 return (0);
1099 }
1100
1101 case WM_PAINTICON:
1102 case WM_PAINT:
1103 {
1104 PAINTSTRUCT Ps;
1105 HDC hDC;
1106
1107 /* If already in Paint and Client area is not empty just return. */
1108 if (Wnd->state2 & WNDS2_STARTPAINT && !RECTL_bIsEmptyRect(&Wnd->rcClient))
1109 {
1110 ERR("In Paint and Client area is not empty!\n");
1111 return 0;
1112 }
1113
1114 hDC = IntBeginPaint(Wnd, &Ps);
1115 if (hDC)
1116 {
1117 if (((Wnd->style & WS_MINIMIZE) != 0) && (Wnd->pcls->spicn))
1118 {
1119 RECT ClientRect;
1120 INT x, y;
1121
1122 ERR("Doing Paint and Client area is empty!\n");
1123 IntGetClientRect(Wnd, &ClientRect);
1124 x = (ClientRect.right - ClientRect.left - UserGetSystemMetrics(SM_CXICON)) / 2;
1125 y = (ClientRect.bottom - ClientRect.top - UserGetSystemMetrics(SM_CYICON)) / 2;
1126 UserReferenceObject(Wnd->pcls->spicn);
1127 UserDrawIconEx(hDC, x, y, Wnd->pcls->spicn, 0, 0, 0, 0, DI_NORMAL | DI_COMPAT | DI_DEFAULTSIZE);
1128 UserDereferenceObject(Wnd->pcls->spicn);
1129 }
1130
1131 IntEndPaint(Wnd, &Ps);
1132 }
1133 return (0);
1134 }
1135
1136 case WM_SYNCPAINT:
1137 {
1138 HRGN hRgn;
1139 Wnd->state &= ~WNDS_SYNCPAINTPENDING;
1140 TRACE("WM_SYNCPAINT\n");
1141 hRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
1142 if (hRgn)
1143 {
1144 if (co_UserGetUpdateRgn(Wnd, hRgn, FALSE) != NULLREGION)
1145 {
1146 PREGION pRgn = REGION_LockRgn(hRgn);
1147 if (pRgn) REGION_UnlockRgn(pRgn);
1148 if (!wParam)
1149 wParam = (RDW_ERASENOW | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN);
1150 co_UserRedrawWindow(Wnd, NULL, pRgn, wParam);
1151 }
1152 GreDeleteObject(hRgn);
1153 }
1154 return 0;
1155 }
1156
1157 case WM_SETREDRAW:
1158 if (wParam)
1159 {
1160 if (!(Wnd->style & WS_VISIBLE))
1161 {
1162 IntSetStyle( Wnd, WS_VISIBLE, 0 );
1163 Wnd->state |= WNDS_SENDNCPAINT;
1164 }
1165 }
1166 else
1167 {
1168 if (Wnd->style & WS_VISIBLE)
1169 {
1170 co_UserRedrawWindow( Wnd, NULL, NULL, RDW_ALLCHILDREN | RDW_VALIDATE );
1171 IntSetStyle( Wnd, 0, WS_VISIBLE );
1172 }
1173 }
1174 return 0;
1175
1176 case WM_WINDOWPOSCHANGING:
1177 {
1178 return (DefWndHandleWindowPosChanging(Wnd, (WINDOWPOS*)lParam));
1179 }
1180
1181 case WM_WINDOWPOSCHANGED:
1182 {
1183 return (DefWndHandleWindowPosChanged(Wnd, (WINDOWPOS*)lParam));
1184 }
1185
1186 case WM_NCCALCSIZE:
1187 {
1188 return NC_HandleNCCalcSize( Wnd, wParam, (RECTL *)lParam, FALSE );
1189 }
1190
1191 case WM_NCACTIVATE:
1192 {
1193 return NC_HandleNCActivate( Wnd, wParam, lParam );
1194 }
1195
1196 //
1197 // NC Paint mode.
1198 //
1199 case WM_NCPAINT:
1200 {
1201 HDC hDC = UserGetDCEx(Wnd, (HRGN)wParam, DCX_WINDOW | DCX_INTERSECTRGN | DCX_USESTYLE | DCX_KEEPCLIPRGN);
1202 Wnd->state |= WNDS_FORCEMENUDRAW;
1203 NC_DoNCPaint(Wnd, hDC, -1);
1204 Wnd->state &= ~WNDS_FORCEMENUDRAW;
1205 UserReleaseDC(Wnd, hDC, FALSE);
1206 return 0;
1207 }
1208 //
1209 // Draw Caption mode.
1210 //
1211 // wParam are DC_* flags.
1212 //
1213 case WM_NCUAHDRAWCAPTION:
1214 {
1215 HDC hDC = UserGetDCEx(Wnd, NULL, DCX_WINDOW|DCX_USESTYLE);
1216 TRACE("WM_NCUAHDRAWCAPTION: wParam DC_ flags %08x\n",wParam);
1217 UserDrawCaptionBar(Wnd, hDC, wParam|DC_FRAME); // Include DC_FRAME to comp for drawing glich.
1218 UserReleaseDC(Wnd, hDC, FALSE);
1219 return 0;
1220 }
1221 //
1222 // Draw Frame mode.
1223 //
1224 // wParam is HDC, lParam are DC_ACTIVE and or DC_REDRAWHUNGWND.
1225 //
1226 case WM_NCUAHDRAWFRAME:
1227 {
1228 TRACE("WM_NCUAHDRAWFRAME: wParam hDC %p lParam DC_ flags %08x\n",wParam,lParam);
1229 NC_DoNCPaint(Wnd, (HDC)wParam, lParam|DC_NC);
1230 return 0;
1231 }
1232
1233 /* ReactOS only. */
1234 case WM_CBT:
1235 {
1236 switch (wParam)
1237 {
1238 case HCBT_MOVESIZE:
1239 {
1240 RECTL rt;
1241
1242 if (lParam)
1243 {
1244 _SEH2_TRY
1245 {
1246 ProbeForRead((PVOID)lParam,
1247 sizeof(RECT),
1248 1);
1249
1250 RtlCopyMemory(&rt,
1251 (PVOID)lParam,
1252 sizeof(RECT));
1253 }
1254 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1255 {
1256 lResult = 1;
1257 }
1258 _SEH2_END;
1259 }
1260 if (!lResult)
1261 lResult = co_HOOK_CallHooks(WH_CBT, HCBT_MOVESIZE, (WPARAM)Wnd->head.h, lParam ? (LPARAM)&rt : 0);
1262 }
1263 break;
1264 }
1265 break;
1266 }
1267 break;
1268 }
1269 return lResult;
1270 }
1271
1272 /* EOF */