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 /* Win: xxxRealDefWindowProc */ 535 LRESULT FASTCALL 536 IntDefWindowProc( 537 PWND Wnd, 538 UINT Msg, 539 WPARAM wParam, 540 LPARAM lParam, 541 BOOL Ansi) 542 { 543 PTHREADINFO pti = PsGetCurrentThreadWin32Thread(); 544 LRESULT lResult = 0; 545 USER_REFERENCE_ENTRY Ref; 546 547 if (Msg > WM_USER) return 0; 548 549 switch (Msg) 550 { 551 case WM_DEVICECHANGE: 552 return TRUE; 553 554 case WM_GETTEXTLENGTH: 555 { 556 PWSTR buf; 557 ULONG len; 558 559 if (Wnd != NULL && Wnd->strName.Length != 0) 560 { 561 buf = Wnd->strName.Buffer; 562 if (buf != NULL && 563 NT_SUCCESS(RtlUnicodeToMultiByteSize(&len, 564 buf, 565 Wnd->strName.Length))) 566 { 567 lResult = (LRESULT) (Wnd->strName.Length / sizeof(WCHAR)); 568 } 569 } 570 else lResult = 0L; 571 572 break; 573 } 574 575 case WM_GETTEXT: // FIXME: Handle Ansi 576 { 577 PWSTR buf = NULL; 578 PWSTR outbuf = (PWSTR)lParam; 579 580 if (Wnd != NULL && wParam != 0) 581 { 582 if (Wnd->strName.Buffer != NULL) 583 buf = Wnd->strName.Buffer; 584 else 585 outbuf[0] = L'\0'; 586 587 if (buf != NULL) 588 { 589 if (Wnd->strName.Length != 0) 590 { 591 lResult = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1); 592 RtlCopyMemory(outbuf, 593 buf, 594 lResult * sizeof(WCHAR)); 595 outbuf[lResult] = L'\0'; 596 } 597 else 598 outbuf[0] = L'\0'; 599 } 600 } 601 break; 602 } 603 604 case WM_SETTEXT: // FIXME: Handle Ansi 605 { 606 DefSetText(Wnd, (PCWSTR)lParam); 607 608 if ((Wnd->style & WS_CAPTION) == WS_CAPTION) 609 UserPaintCaption(Wnd, DC_TEXT); 610 IntNotifyWinEvent(EVENT_OBJECT_NAMECHANGE, Wnd, OBJID_WINDOW, CHILDID_SELF, 0); 611 lResult = 1; 612 break; 613 } 614 615 case WM_SYSCOMMAND: 616 { 617 TRACE("hwnd %p WM_SYSCOMMAND %lx %lx\n", Wnd->head.h, wParam, lParam ); 618 lResult = DefWndHandleSysCommand(Wnd, wParam, lParam); 619 break; 620 } 621 622 case WM_SHOWWINDOW: 623 { 624 if ((Wnd->style & WS_VISIBLE) && wParam) break; 625 if (!(Wnd->style & WS_VISIBLE) && !wParam) break; 626 if (!Wnd->spwndOwner) break; 627 if (LOWORD(lParam)) 628 { 629 co_WinPosShowWindow(Wnd, wParam ? SW_SHOWNOACTIVATE : SW_HIDE); 630 } 631 break; 632 } 633 634 case WM_CLIENTSHUTDOWN: 635 return IntClientShutdown(Wnd, wParam, lParam); 636 637 case WM_APPCOMMAND: 638 if ( (Wnd->style & (WS_POPUP|WS_CHILD)) != WS_CHILD && 639 Wnd != co_GetDesktopWindow(Wnd) ) 640 { 641 if (!co_HOOK_CallHooks(WH_SHELL, HSHELL_APPCOMMAND, wParam, lParam)) 642 co_IntShellHookNotify(HSHELL_APPCOMMAND, wParam, lParam); 643 break; 644 } 645 UserRefObjectCo(Wnd->spwndParent, &Ref); 646 lResult = co_IntSendMessage(UserHMGetHandle(Wnd->spwndParent), WM_APPCOMMAND, wParam, lParam); 647 UserDerefObjectCo(Wnd->spwndParent); 648 break; 649 650 case WM_KEYF1: 651 { 652 HELPINFO hi; 653 HMENU hMenu = UlongToHandle(Wnd->IDMenu); 654 PWND pwndActive = MENU_IsMenuActive(); 655 hi.cbSize = sizeof(HELPINFO); 656 hi.MousePos = gpsi->ptCursor; 657 hi.iContextType = HELPINFO_MENUITEM; 658 hi.hItemHandle = pwndActive ? UserHMGetHandle(pwndActive) : UserHMGetHandle(Wnd); 659 hi.iCtrlId = (Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD ? IntMenuItemFromPoint(Wnd, hMenu, hi.MousePos) : 0; 660 hi.dwContextId = IntGetWindowContextHelpId(Wnd); 661 662 co_IntSendMessage( UserHMGetHandle(Wnd), WM_HELP, 0, (LPARAM)&hi ); 663 break; 664 } 665 666 case WM_SETICON: 667 { 668 return DefWndSetIcon(Wnd, wParam, lParam); 669 } 670 671 case WM_GETICON: 672 { 673 return DefWndGetIcon(Wnd, wParam, lParam); 674 } 675 676 case WM_HELP: 677 { 678 PWND Parent = IntGetParent(Wnd); 679 co_IntSendMessage(UserHMGetHandle(Parent), Msg, wParam, lParam); 680 break; 681 } 682 683 case WM_LBUTTONDOWN: 684 case WM_RBUTTONDOWN: 685 case WM_MBUTTONDOWN: 686 pti->MessageQueue->QF_flags &= ~(QF_FMENUSTATUS|QF_FMENUSTATUSBREAK); 687 break; 688 689 case WM_NCLBUTTONDOWN: 690 return NC_HandleNCLButtonDown(Wnd, wParam, lParam); 691 692 case WM_NCRBUTTONDOWN: 693 return NC_HandleNCRButtonDown(Wnd, wParam, lParam); 694 695 case WM_LBUTTONDBLCLK: 696 return NC_HandleNCLButtonDblClk(Wnd, HTCLIENT, lParam); 697 698 case WM_NCLBUTTONDBLCLK: 699 return NC_HandleNCLButtonDblClk(Wnd, wParam, lParam); 700 701 case WM_RBUTTONUP: 702 { 703 POINT Pt; 704 705 Pt.x = GET_X_LPARAM(lParam); 706 Pt.y = GET_Y_LPARAM(lParam); 707 IntClientToScreen(Wnd, &Pt); 708 lParam = MAKELPARAM(Pt.x, Pt.y); 709 co_IntSendMessage(UserHMGetHandle(Wnd), WM_CONTEXTMENU, (WPARAM)UserHMGetHandle(Wnd), lParam); 710 break; 711 } 712 713 case WM_NCRBUTTONUP: 714 /* 715 * FIXME : we must NOT send WM_CONTEXTMENU on a WM_NCRBUTTONUP (checked 716 * in Windows), but what _should_ we do? According to MSDN : 717 * "If it is appropriate to do so, the system sends the WM_SYSCOMMAND 718 * message to the window". When is it appropriate? 719 */ 720 ERR("WM_NCRBUTTONUP\n"); 721 break; 722 723 case WM_XBUTTONUP: 724 case WM_NCXBUTTONUP: 725 if (HIWORD(wParam) == XBUTTON1 || HIWORD(wParam) == XBUTTON2) 726 { 727 co_IntSendMessage(UserHMGetHandle(Wnd), WM_APPCOMMAND, (WPARAM)UserHMGetHandle(Wnd), 728 MAKELPARAM(LOWORD(wParam), FAPPCOMMAND_MOUSE | HIWORD(wParam))); 729 } 730 break; 731 732 733 case WM_CONTEXTMENU: 734 { 735 if (Wnd->style & WS_CHILD) 736 { 737 co_IntSendMessage(UserHMGetHandle(IntGetParent(Wnd)), Msg, (WPARAM)UserHMGetHandle(Wnd), lParam); 738 } 739 else 740 { 741 POINT Pt; 742 LONG_PTR Style; 743 LONG HitCode; 744 745 Style = Wnd->style; 746 747 Pt.x = GET_X_LPARAM(lParam); 748 Pt.y = GET_Y_LPARAM(lParam); 749 if (Style & WS_CHILD) 750 { 751 IntScreenToClient(IntGetParent(Wnd), &Pt); 752 } 753 754 HitCode = GetNCHitEx(Wnd, Pt); 755 756 if (HitCode == HTCAPTION || HitCode == HTSYSMENU) 757 { 758 PMENU SystemMenu; 759 UINT Flags; 760 761 if((SystemMenu = IntGetSystemMenu(Wnd, FALSE))) 762 { 763 MENU_InitSysMenuPopup(SystemMenu, Wnd->style, Wnd->pcls->style, HitCode); 764 765 if(HitCode == HTCAPTION) 766 Flags = TPM_LEFTBUTTON | TPM_RIGHTBUTTON; 767 else 768 Flags = TPM_LEFTBUTTON; 769 770 IntTrackPopupMenuEx(SystemMenu, Flags|TPM_SYSTEM_MENU, Pt.x, Pt.y, Wnd, NULL); 771 } 772 } 773 if (HitCode == HTHSCROLL || HitCode == HTVSCROLL) 774 { 775 WARN("Scroll Menu Not Supported\n"); 776 } 777 } 778 break; 779 } 780 781 case WM_KEYDOWN: 782 if (wParam == VK_F10) 783 { 784 pti->MessageQueue->QF_flags |= QF_FF10STATUS; 785 786 if (UserGetKeyState(VK_SHIFT) & 0x8000) 787 { 788 co_IntSendMessage(UserHMGetHandle(Wnd), WM_CONTEXTMENU, (WPARAM)UserHMGetHandle(Wnd), MAKELPARAM(-1, -1)); 789 } 790 } 791 if (g_bWindowSnapEnabled && (IS_KEY_DOWN(gafAsyncKeyState, VK_LWIN) || IS_KEY_DOWN(gafAsyncKeyState, VK_RWIN))) 792 { 793 BOOL IsTaskBar; 794 DWORD StyleTB; 795 DWORD ExStyleTB; 796 HWND hwndTop = UserGetForegroundWindow(); 797 PWND topWnd = UserGetWindowObject(hwndTop); 798 799 // MS Doc: foreground window can be NULL, e.g. when window is losing activation 800 if (!topWnd) 801 return 0; 802 803 // We want to forbid snapping operations on the TaskBar 804 // We use a heuristic for detecting the TaskBar Wnd by its typical Style & ExStyle Values 805 ExStyleTB = (topWnd->ExStyle & WS_EX_TOOLWINDOW); 806 StyleTB = (topWnd->style & (WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)); 807 IsTaskBar = (StyleTB == (WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)) 808 && (ExStyleTB == WS_EX_TOOLWINDOW); 809 TRACE("ExStyle=%x Style=%x IsTaskBar=%d\n", ExStyleTB, StyleTB, IsTaskBar); 810 811 if (!IsTaskBar) 812 { 813 if ((topWnd->style & WS_THICKFRAME) == 0) 814 return 0; 815 816 if (wParam == VK_DOWN) 817 { 818 if (topWnd->style & WS_MAXIMIZE) 819 { 820 co_IntSendMessage(hwndTop, WM_SYSCOMMAND, SC_RESTORE, lParam); 821 822 /* "Normal size" must be erased after restoring, otherwise it will block next side snap actions */ 823 RECTL_vSetEmptyRect(&topWnd->InternalPos.NormalRect); 824 } 825 else 826 { 827 co_IntSendMessage(hwndTop, WM_SYSCOMMAND, SC_MINIMIZE, lParam); 828 } 829 } 830 else if (wParam == VK_UP) 831 { 832 RECT currentRect; 833 if ((topWnd->InternalPos.NormalRect.right == topWnd->InternalPos.NormalRect.left) || 834 (topWnd->InternalPos.NormalRect.top == topWnd->InternalPos.NormalRect.bottom)) 835 { 836 currentRect = topWnd->rcWindow; 837 } 838 else 839 { 840 currentRect = topWnd->InternalPos.NormalRect; 841 } 842 co_IntSendMessage(hwndTop, WM_SYSCOMMAND, SC_MAXIMIZE, 0); 843 844 // save normal rect if maximazing snapped window 845 topWnd->InternalPos.NormalRect = currentRect; 846 } 847 else if (wParam == VK_LEFT || wParam == VK_RIGHT) 848 { 849 RECT snapRect, normalRect, windowRect; 850 BOOL snapped; 851 normalRect = topWnd->InternalPos.NormalRect; 852 snapped = (normalRect.left != 0 && normalRect.right != 0 && 853 normalRect.top != 0 && normalRect.bottom != 0); 854 855 if (topWnd->style & WS_MAXIMIZE) 856 { 857 co_IntSendMessage(hwndTop, WM_SYSCOMMAND, SC_RESTORE, lParam); 858 snapped = FALSE; 859 } 860 windowRect = topWnd->rcWindow; 861 862 UserSystemParametersInfo(SPI_GETWORKAREA, 0, &snapRect, 0); 863 if (wParam == VK_LEFT) 864 { 865 snapRect.right = (snapRect.left + snapRect.right) / 2; 866 } 867 else // VK_RIGHT 868 { 869 snapRect.left = (snapRect.left + snapRect.right) / 2; 870 } 871 872 if (snapped) 873 { 874 // if window was snapped but moved to other location - restore normal size 875 if (!IntEqualRect(&snapRect, &windowRect)) 876 { 877 RECT empty = {0, 0, 0, 0}; 878 co_WinPosSetWindowPos(topWnd, 879 0, 880 normalRect.left, 881 normalRect.top, 882 normalRect.right - normalRect.left, 883 normalRect.bottom - normalRect.top, 884 0); 885 topWnd->InternalPos.NormalRect = empty; 886 } 887 } 888 else 889 { 890 co_WinPosSetWindowPos(topWnd, 891 0, 892 snapRect.left, 893 snapRect.top, 894 snapRect.right - snapRect.left, 895 snapRect.bottom - snapRect.top, 896 0); 897 topWnd->InternalPos.NormalRect = windowRect; 898 } 899 } 900 } 901 } 902 break; 903 904 case WM_SYSKEYDOWN: 905 { 906 if (HIWORD(lParam) & KF_ALTDOWN) 907 { /* Previous state, if the key was down before this message, 908 this is a cheap way to ignore autorepeat keys. */ 909 if ( !(HIWORD(lParam) & KF_REPEAT) ) 910 { 911 if ( ( wParam == VK_MENU || 912 wParam == VK_LMENU || 913 wParam == VK_RMENU ) && !(pti->MessageQueue->QF_flags & QF_FMENUSTATUS)) //iMenuSysKey ) 914 pti->MessageQueue->QF_flags |= QF_FMENUSTATUS; //iMenuSysKey = 1; 915 else 916 pti->MessageQueue->QF_flags &= ~QF_FMENUSTATUS; //iMenuSysKey = 0; 917 } 918 919 pti->MessageQueue->QF_flags &= ~QF_FF10STATUS; //iF10Key = 0; 920 921 if (wParam == VK_F4) /* Try to close the window */ 922 { 923 PWND top = UserGetAncestor(Wnd, GA_ROOT); 924 if (!(top->style & CS_NOCLOSE)) 925 UserPostMessage(UserHMGetHandle(top), WM_SYSCOMMAND, SC_CLOSE, 0); 926 } 927 else if (wParam == VK_SNAPSHOT) // Alt-VK_SNAPSHOT? 928 { 929 PWND pwnd = Wnd; 930 while (IntGetParent(pwnd) != NULL) 931 { 932 pwnd = IntGetParent(pwnd); 933 } 934 ERR("DefWndScreenshot\n"); 935 DefWndScreenshot(pwnd); 936 } 937 else if ( wParam == VK_ESCAPE || wParam == VK_TAB ) // Alt-Tab/ESC Alt-Shift-Tab/ESC 938 { 939 WPARAM wParamTmp; 940 HWND Active = UserGetActiveWindow(); // Noticed MDI problem. 941 if (!Active) 942 { 943 FIXME("WM_SYSKEYDOWN VK_ESCAPE no active\n"); 944 break; 945 } 946 wParamTmp = UserGetKeyState(VK_SHIFT) & 0x8000 ? SC_PREVWINDOW : SC_NEXTWINDOW; 947 co_IntSendMessage( Active, WM_SYSCOMMAND, wParamTmp, wParam ); 948 } 949 else if (wParam == VK_SHIFT) // Alt+Shift 950 { 951 RTL_ATOM ClassAtom = 0; 952 UNICODE_STRING ustrClass, ustrWindow; 953 HWND hwndSwitch; 954 955 RtlInitUnicodeString(&ustrClass, L"kbswitcher"); 956 RtlInitUnicodeString(&ustrWindow, L""); 957 958 IntGetAtomFromStringOrAtom(&ustrClass, &ClassAtom); 959 960 hwndSwitch = IntFindWindow(UserGetDesktopWindow(), NULL, ClassAtom, &ustrWindow); 961 if (hwndSwitch) 962 { 963 #define ID_NEXTLAYOUT 10003 964 UserPostMessage(hwndSwitch, WM_COMMAND, ID_NEXTLAYOUT, (LPARAM)UserHMGetHandle(Wnd)); 965 } 966 } 967 } 968 else if( wParam == VK_F10 ) 969 { 970 if (UserGetKeyState(VK_SHIFT) & 0x8000) 971 co_IntSendMessage( UserHMGetHandle(Wnd), WM_CONTEXTMENU, (WPARAM)UserHMGetHandle(Wnd), MAKELPARAM(-1, -1) ); 972 pti->MessageQueue->QF_flags |= QF_FF10STATUS; //iF10Key = 1; 973 } 974 else if( wParam == VK_ESCAPE && (UserGetKeyState(VK_SHIFT) & 0x8000)) 975 co_IntSendMessage( UserHMGetHandle(Wnd), WM_SYSCOMMAND, SC_KEYMENU, ' ' ); 976 break; 977 } 978 979 case WM_KEYUP: 980 case WM_SYSKEYUP: 981 { 982 /* Press and release F10 or ALT */ 983 if (((wParam == VK_MENU || wParam == VK_LMENU || wParam == VK_RMENU) 984 && (pti->MessageQueue->QF_flags & (QF_FMENUSTATUS|QF_FMENUSTATUSBREAK)) == QF_FMENUSTATUS /*iMenuSysKey*/) || 985 ((wParam == VK_F10) && pti->MessageQueue->QF_flags & QF_FF10STATUS /*iF10Key*/)) 986 co_IntSendMessage( UserHMGetHandle(UserGetAncestor( Wnd, GA_ROOT )), WM_SYSCOMMAND, SC_KEYMENU, 0L ); 987 pti->MessageQueue->QF_flags &= ~(QF_FMENUSTATUS|QF_FMENUSTATUSBREAK|QF_FF10STATUS); //iMenuSysKey = iF10Key = 0; 988 break; 989 } 990 991 case WM_SYSCHAR: 992 { 993 pti->MessageQueue->QF_flags &= ~(QF_FMENUSTATUS|QF_FMENUSTATUSBREAK); //iMenuSysKey = 0; 994 if (wParam == VK_RETURN && (Wnd->style & WS_MINIMIZE) != 0) 995 { 996 UserPostMessage( UserHMGetHandle(Wnd), WM_SYSCOMMAND, SC_RESTORE, 0L ); 997 break; 998 } 999 if ((HIWORD(lParam) & KF_ALTDOWN) && wParam) 1000 { 1001 if (wParam == VK_TAB || wParam == VK_ESCAPE) break; 1002 if (wParam == VK_SPACE && Wnd->style & WS_CHILD) 1003 co_IntSendMessage( UserHMGetHandle(IntGetParent(Wnd)), Msg, wParam, lParam ); 1004 else 1005 co_IntSendMessage( UserHMGetHandle(Wnd), WM_SYSCOMMAND, SC_KEYMENU, wParam ); 1006 } 1007 else /* check for Ctrl-Esc */ 1008 if (wParam != VK_ESCAPE) UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_MESSAGE_BEEP, 0); //MessageBeep(0); 1009 break; 1010 } 1011 1012 case WM_CANCELMODE: 1013 { 1014 pti->MessageQueue->QF_flags &= ~(QF_FMENUSTATUS|QF_FMENUSTATUSBREAK); 1015 1016 MENU_EndMenu( Wnd ); 1017 if (IntGetCaptureWindow() == UserHMGetHandle(Wnd)) 1018 { 1019 IntReleaseCapture(); 1020 } 1021 break; 1022 } 1023 1024 case WM_CLOSE: 1025 co_UserDestroyWindow(Wnd); 1026 break; 1027 1028 case WM_CTLCOLORMSGBOX: 1029 case WM_CTLCOLOREDIT: 1030 case WM_CTLCOLORLISTBOX: 1031 case WM_CTLCOLORBTN: 1032 case WM_CTLCOLORDLG: 1033 case WM_CTLCOLORSTATIC: 1034 case WM_CTLCOLORSCROLLBAR: 1035 return (LRESULT) DefWndControlColor((HDC)wParam, Msg - WM_CTLCOLORMSGBOX); 1036 1037 case WM_CTLCOLOR: 1038 return (LRESULT) DefWndControlColor((HDC)wParam, HIWORD(lParam)); 1039 1040 case WM_SETCURSOR: 1041 { 1042 if (Wnd->style & WS_CHILD) 1043 { 1044 /* with the exception of the border around a resizable wnd, 1045 * give the parent first chance to set the cursor */ 1046 if (LOWORD(lParam) < HTLEFT || LOWORD(lParam) > HTBOTTOMRIGHT) 1047 { 1048 PWND parent = Wnd->spwndParent;//IntGetParent( Wnd ); 1049 if (parent != UserGetDesktopWindow() && 1050 co_IntSendMessage( UserHMGetHandle(parent), WM_SETCURSOR, wParam, lParam)) 1051 return TRUE; 1052 } 1053 } 1054 return DefWndHandleSetCursor(Wnd, wParam, lParam); 1055 } 1056 1057 case WM_MOUSEACTIVATE: 1058 if (Wnd->style & WS_CHILD) 1059 { 1060 LONG Ret; 1061 HWND hwndParent; 1062 PWND pwndParent = IntGetParent(Wnd); 1063 hwndParent = pwndParent ? UserHMGetHandle(pwndParent) : NULL; 1064 if (hwndParent) Ret = co_IntSendMessage(hwndParent, WM_MOUSEACTIVATE, wParam, lParam); 1065 if (Ret) return (Ret); 1066 } 1067 return ( (HIWORD(lParam) == WM_LBUTTONDOWN && LOWORD(lParam) == HTCAPTION) ? MA_NOACTIVATE : MA_ACTIVATE ); 1068 1069 case WM_ACTIVATE: 1070 /* The default action in Windows is to set the keyboard focus to 1071 * the window, if it's being activated and not minimized */ 1072 if (LOWORD(wParam) != WA_INACTIVE && 1073 !(Wnd->style & WS_MINIMIZE)) 1074 { 1075 //ERR("WM_ACTIVATE %p\n",hWnd); 1076 co_UserSetFocus(Wnd); 1077 } 1078 break; 1079 1080 case WM_MOUSEWHEEL: 1081 if (Wnd->style & WS_CHILD) 1082 { 1083 HWND hwndParent; 1084 PWND pwndParent = IntGetParent(Wnd); 1085 hwndParent = pwndParent ? UserHMGetHandle(pwndParent) : NULL; 1086 return co_IntSendMessage( hwndParent, WM_MOUSEWHEEL, wParam, lParam); 1087 } 1088 break; 1089 1090 case WM_ERASEBKGND: 1091 case WM_ICONERASEBKGND: 1092 { 1093 RECT Rect; 1094 HBRUSH hBrush = Wnd->pcls->hbrBackground; 1095 if (!hBrush) return 0; 1096 if (hBrush <= (HBRUSH)COLOR_MENUBAR) 1097 { 1098 hBrush = IntGetSysColorBrush(HandleToUlong(hBrush)); 1099 } 1100 if (Wnd->pcls->style & CS_PARENTDC) 1101 { 1102 /* can't use GetClipBox with a parent DC or we fill the whole parent */ 1103 IntGetClientRect(Wnd, &Rect); 1104 GreDPtoLP((HDC)wParam, (LPPOINT)&Rect, 2); 1105 } 1106 else 1107 { 1108 GdiGetClipBox((HDC)wParam, &Rect); 1109 } 1110 FillRect((HDC)wParam, &Rect, hBrush); 1111 return (1); 1112 } 1113 1114 case WM_GETHOTKEY: 1115 //ERR("WM_GETHOTKEY\n"); 1116 return DefWndGetHotKey(Wnd); 1117 case WM_SETHOTKEY: 1118 //ERR("WM_SETHOTKEY\n"); 1119 return DefWndSetHotKey(Wnd, wParam); 1120 1121 case WM_NCHITTEST: 1122 { 1123 POINT Point; 1124 Point.x = GET_X_LPARAM(lParam); 1125 Point.y = GET_Y_LPARAM(lParam); 1126 return GetNCHitEx(Wnd, Point); 1127 } 1128 1129 case WM_PRINT: 1130 { 1131 DefWndPrint(Wnd, (HDC)wParam, lParam); 1132 return (0); 1133 } 1134 1135 case WM_SYSCOLORCHANGE: 1136 { 1137 /* force to redraw non-client area */ 1138 UserPaintCaption(Wnd, DC_NC); 1139 /* Use InvalidateRect to redraw client area, enable 1140 * erase to redraw all subcontrols otherwise send the 1141 * WM_SYSCOLORCHANGE to child windows/controls is required 1142 */ 1143 co_UserRedrawWindow( Wnd, NULL, NULL, RDW_ALLCHILDREN|RDW_INVALIDATE|RDW_ERASE); 1144 return (0); 1145 } 1146 1147 case WM_PAINTICON: 1148 case WM_PAINT: 1149 { 1150 PAINTSTRUCT Ps; 1151 HDC hDC; 1152 1153 /* If already in Paint and Client area is not empty just return. */ 1154 if (Wnd->state2 & WNDS2_STARTPAINT && !RECTL_bIsEmptyRect(&Wnd->rcClient)) 1155 { 1156 ERR("In Paint and Client area is not empty!\n"); 1157 return 0; 1158 } 1159 1160 hDC = IntBeginPaint(Wnd, &Ps); 1161 if (hDC) 1162 { 1163 if (((Wnd->style & WS_MINIMIZE) != 0) && (Wnd->pcls->spicn)) 1164 { 1165 RECT ClientRect; 1166 INT x, y; 1167 1168 ERR("Doing Paint and Client area is empty!\n"); 1169 IntGetClientRect(Wnd, &ClientRect); 1170 x = (ClientRect.right - ClientRect.left - UserGetSystemMetrics(SM_CXICON)) / 2; 1171 y = (ClientRect.bottom - ClientRect.top - UserGetSystemMetrics(SM_CYICON)) / 2; 1172 UserReferenceObject(Wnd->pcls->spicn); 1173 UserDrawIconEx(hDC, x, y, Wnd->pcls->spicn, 0, 0, 0, 0, DI_NORMAL | DI_COMPAT | DI_DEFAULTSIZE); 1174 UserDereferenceObject(Wnd->pcls->spicn); 1175 } 1176 1177 IntEndPaint(Wnd, &Ps); 1178 } 1179 return (0); 1180 } 1181 1182 case WM_SYNCPAINT: 1183 { 1184 HRGN hRgn; 1185 Wnd->state &= ~WNDS_SYNCPAINTPENDING; 1186 TRACE("WM_SYNCPAINT\n"); 1187 hRgn = NtGdiCreateRectRgn(0, 0, 0, 0); 1188 if (hRgn) 1189 { 1190 if (co_UserGetUpdateRgn(Wnd, hRgn, FALSE) != NULLREGION) 1191 { 1192 PREGION pRgn = REGION_LockRgn(hRgn); 1193 if (pRgn) REGION_UnlockRgn(pRgn); 1194 if (!wParam) 1195 wParam = (RDW_ERASENOW | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN); 1196 co_UserRedrawWindow(Wnd, NULL, pRgn, wParam); 1197 } 1198 GreDeleteObject(hRgn); 1199 } 1200 return 0; 1201 } 1202 1203 case WM_SETREDRAW: 1204 if (wParam) 1205 { 1206 if (!(Wnd->style & WS_VISIBLE)) 1207 { 1208 IntSetStyle( Wnd, WS_VISIBLE, 0 ); 1209 Wnd->state |= WNDS_SENDNCPAINT; 1210 } 1211 } 1212 else 1213 { 1214 if (Wnd->style & WS_VISIBLE) 1215 { 1216 co_UserRedrawWindow( Wnd, NULL, NULL, RDW_ALLCHILDREN | RDW_VALIDATE ); 1217 IntSetStyle( Wnd, 0, WS_VISIBLE ); 1218 } 1219 } 1220 return 0; 1221 1222 case WM_WINDOWPOSCHANGING: 1223 { 1224 return (DefWndHandleWindowPosChanging(Wnd, (WINDOWPOS*)lParam)); 1225 } 1226 1227 case WM_WINDOWPOSCHANGED: 1228 { 1229 return (DefWndHandleWindowPosChanged(Wnd, (WINDOWPOS*)lParam)); 1230 } 1231 1232 case WM_NCCALCSIZE: 1233 { 1234 return NC_HandleNCCalcSize( Wnd, wParam, (RECTL *)lParam, FALSE ); 1235 } 1236 1237 case WM_NCACTIVATE: 1238 { 1239 return NC_HandleNCActivate( Wnd, wParam, lParam ); 1240 } 1241 1242 // 1243 // NC Paint mode. 1244 // 1245 case WM_NCPAINT: 1246 { 1247 HDC hDC = UserGetDCEx(Wnd, (HRGN)wParam, DCX_WINDOW | DCX_INTERSECTRGN | DCX_USESTYLE | DCX_KEEPCLIPRGN); 1248 Wnd->state |= WNDS_FORCEMENUDRAW; 1249 NC_DoNCPaint(Wnd, hDC, -1); 1250 Wnd->state &= ~WNDS_FORCEMENUDRAW; 1251 UserReleaseDC(Wnd, hDC, FALSE); 1252 return 0; 1253 } 1254 // 1255 // Draw Caption mode. 1256 // 1257 // wParam are DC_* flags. 1258 // 1259 case WM_NCUAHDRAWCAPTION: 1260 { 1261 HDC hDC = UserGetDCEx(Wnd, NULL, DCX_WINDOW|DCX_USESTYLE); 1262 TRACE("WM_NCUAHDRAWCAPTION: wParam DC_ flags %08x\n",wParam); 1263 UserDrawCaptionBar(Wnd, hDC, wParam | DC_FRAME); // Include DC_FRAME to comp for drawing glitch. 1264 UserReleaseDC(Wnd, hDC, FALSE); 1265 return 0; 1266 } 1267 // 1268 // Draw Frame mode. 1269 // 1270 // wParam is HDC, lParam are DC_ACTIVE and or DC_REDRAWHUNGWND. 1271 // 1272 case WM_NCUAHDRAWFRAME: 1273 { 1274 TRACE("WM_NCUAHDRAWFRAME: wParam hDC %p lParam DC_ flags %08x\n",wParam,lParam); 1275 NC_DoNCPaint(Wnd, (HDC)wParam, lParam|DC_NC); 1276 return 0; 1277 } 1278 1279 /* ReactOS only. */ 1280 case WM_CBT: 1281 { 1282 switch (wParam) 1283 { 1284 case HCBT_MOVESIZE: 1285 { 1286 RECTL rt; 1287 1288 if (lParam) 1289 { 1290 _SEH2_TRY 1291 { 1292 ProbeForRead((PVOID)lParam, 1293 sizeof(RECT), 1294 1); 1295 1296 RtlCopyMemory(&rt, 1297 (PVOID)lParam, 1298 sizeof(RECT)); 1299 } 1300 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 1301 { 1302 lResult = 1; 1303 } 1304 _SEH2_END; 1305 } 1306 if (!lResult) 1307 lResult = co_HOOK_CallHooks(WH_CBT, HCBT_MOVESIZE, (WPARAM)Wnd->head.h, lParam ? (LPARAM)&rt : 0); 1308 } 1309 break; 1310 } 1311 break; 1312 } 1313 break; 1314 } 1315 return lResult; 1316 } 1317 1318 /* EOF */ 1319