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