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