diff --git a/reactos/win32ss/include/callback.h b/reactos/win32ss/include/callback.h index d00a60de889..51daaa221e7 100644 --- a/reactos/win32ss/include/callback.h +++ b/reactos/win32ss/include/callback.h @@ -113,8 +113,13 @@ typedef struct _GET_CHARSET_INFO typedef struct _SETWNDICONS_CALLBACK_ARGUMENTS { - HICON hIconSmWindows; + HICON hIconSample; + HICON hIconHand; + HICON hIconQuestion; + HICON hIconBang; + HICON hIconNote; HICON hIconWindows; + HICON hIconSmWindows; } SETWNDICONS_CALLBACK_ARGUMENTS, *PSETWNDICONS_CALLBACK_ARGUMENTS; typedef struct _DDEPOSTGET_CALLBACK_ARGUMENTS diff --git a/reactos/win32ss/include/ntuser.h b/reactos/win32ss/include/ntuser.h index 154849984fc..95e705e8b44 100644 --- a/reactos/win32ss/include/ntuser.h +++ b/reactos/win32ss/include/ntuser.h @@ -1006,6 +1006,7 @@ typedef struct _PROPERTY LIST_ENTRY PropListEntry; HANDLE Data; ATOM Atom; + WORD fs; } PROPERTY, *PPROPERTY; typedef struct _BROADCASTPARM @@ -3184,13 +3185,13 @@ NtUserSetWindowsHookEx( HOOKPROC HookProc, BOOL Ansi); -DWORD +BOOL NTAPI NtUserSetWindowStationUser( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3); + HWINSTA hWindowStation, + PLUID pluid, + PSID psid, + DWORD size); WORD NTAPI NtUserSetWindowWord(HWND hWnd, INT Index, WORD NewVal); diff --git a/reactos/win32ss/user/ntuser/callback.c b/reactos/win32ss/user/ntuser/callback.c index 5c1998cda61..705cab4a8e8 100644 --- a/reactos/win32ss/user/ntuser/callback.c +++ b/reactos/win32ss/user/ntuser/callback.c @@ -2,7 +2,7 @@ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Win32k subsystem * PURPOSE: Callback to usermode support - * FILE: subsystems/win32/win32k/ntuser/callback.c + * FILE: win32ss/user/ntuser/callback.c * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net) * Thomas Weidenmueller (w3seek@users.sourceforge.net) * NOTES: Please use the Callback Memory Management functions for @@ -357,7 +357,7 @@ co_IntCallWindowProc(WNDPROC Proc, if (!NT_SUCCESS(Status)) { - ERR("Call to user mode failed!\n"); + ERR("Call to user mode failed! %p\n",Status); if (lParamBufferSize != -1) { IntCbFreeMemory(Arguments); @@ -1082,21 +1082,29 @@ co_IntSetWndIcons(VOID) UserEnterCo(); - /* FIXME: Need to setup Registry System Cursor & Icons via Callbacks at init time! */ + if (!NT_SUCCESS(Status)) + { + ERR("Set Window Icons callback failed!\n"); + IntCbFreeMemory(Argument); + return FALSE; + } + RtlMoveMemory(Common, ResultPointer, ArgumentLength); gpsi->hIconSmWindows = Common->hIconSmWindows; gpsi->hIconWindows = Common->hIconWindows; + IntLoadSystenIcons(Common->hIconSample, OIC_SAMPLE); + IntLoadSystenIcons(Common->hIconHand, OIC_HAND); + IntLoadSystenIcons(Common->hIconQuestion, OIC_QUES); + IntLoadSystenIcons(Common->hIconBang, OIC_BANG); + IntLoadSystenIcons(Common->hIconNote, OIC_NOTE); + IntLoadSystenIcons(gpsi->hIconWindows, OIC_WINLOGO); + IntLoadSystenIcons(gpsi->hIconSmWindows, OIC_WINLOGO+1); + ERR("hIconSmWindows %p hIconWindows %p \n",gpsi->hIconSmWindows,gpsi->hIconWindows); IntCbFreeMemory(Argument); - if (!NT_SUCCESS(Status)) - { - ERR("Set Window Icons callback failed!\n"); - return FALSE; - } - return TRUE; } diff --git a/reactos/win32ss/user/ntuser/class.c b/reactos/win32ss/user/ntuser/class.c index c437d745309..623fd651304 100644 --- a/reactos/win32ss/user/ntuser/class.c +++ b/reactos/win32ss/user/ntuser/class.c @@ -2,7 +2,7 @@ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Win32k subsystem * PURPOSE: Window classes - * FILE: subsystems/win32/win32k/ntuser/class.c + * FILE: win32ss/user/ntuser/class.c * PROGRAMER: Thomas Weidenmueller */ @@ -38,7 +38,7 @@ REGISTER_SYSCLASS DefaultServerClasses[] = CS_GLOBALCLASS|CS_DBLCLKS, NULL, // Use User32 procs sizeof(ULONG)*2, - (HICON)IDC_ARROW, + (HICON)OCR_NORMAL, (HBRUSH)(COLOR_BACKGROUND), FNID_DESKTOP, ICLS_DESKTOP @@ -47,7 +47,7 @@ REGISTER_SYSCLASS DefaultServerClasses[] = CS_VREDRAW|CS_HREDRAW|CS_SAVEBITS, NULL, // Use User32 procs sizeof(LONG), - (HICON)IDC_ARROW, + (HICON)OCR_NORMAL, NULL, FNID_SWITCH, ICLS_SWITCH @@ -56,7 +56,7 @@ REGISTER_SYSCLASS DefaultServerClasses[] = CS_DBLCLKS|CS_SAVEBITS, NULL, // Use User32 procs sizeof(LONG), - (HICON)IDC_ARROW, + (HICON)OCR_NORMAL, (HBRUSH)(COLOR_MENU + 1), FNID_MENU, ICLS_MENU @@ -65,7 +65,7 @@ REGISTER_SYSCLASS DefaultServerClasses[] = CS_DBLCLKS|CS_VREDRAW|CS_HREDRAW|CS_PARENTDC, NULL, // Use User32 procs sizeof(SBWND)-sizeof(WND), - (HICON)IDC_ARROW, + (HICON)OCR_NORMAL, NULL, FNID_SCROLLBAR, ICLS_SCROLLBAR @@ -75,7 +75,7 @@ REGISTER_SYSCLASS DefaultServerClasses[] = CS_PARENTDC|CS_DBLCLKS, NULL, // Use User32 procs 0, - (HICON)IDC_ARROW, + (HICON)OCR_NORMAL, 0, FNID_TOOLTIPS, ICLS_TOOLTIPS @@ -85,7 +85,7 @@ REGISTER_SYSCLASS DefaultServerClasses[] = 0, NULL, // Use User32 procs 0, - (HICON)IDC_ARROW, + (HICON)OCR_NORMAL, 0, FNID_ICONTITLE, ICLS_ICONTITLE @@ -94,7 +94,7 @@ REGISTER_SYSCLASS DefaultServerClasses[] = CS_GLOBALCLASS, NULL, // Use User32 procs 0, - (HICON)IDC_ARROW, + (HICON)OCR_NORMAL, NULL, FNID_MESSAGEWND, ICLS_HWNDMESSAGE @@ -2424,7 +2424,8 @@ UserRegisterSystemClasses(VOID) wc.cbClsExtra = 0; wc.cbWndExtra = DefaultServerClasses[i].ExtraBytes; wc.hIcon = NULL; - wc.hCursor = DefaultServerClasses[i].hCursor; + //// System Cursors should be initilized!!! + wc.hCursor = DefaultServerClasses[i].hCursor == (HICON)OCR_NORMAL ? UserHMGetHandle(SYSTEMCUR(ARROW)) : NULL; hBrush = DefaultServerClasses[i].hBrush; if (hBrush <= (HBRUSH)COLOR_MENUBAR) { diff --git a/reactos/win32ss/user/ntuser/cursoricon.c b/reactos/win32ss/user/ntuser/cursoricon.c index 4da91bb7420..0a4ff41b0e0 100644 --- a/reactos/win32ss/user/ntuser/cursoricon.c +++ b/reactos/win32ss/user/ntuser/cursoricon.c @@ -1593,4 +1593,16 @@ NtUserGetCursorFrameInfo( return 0; } +/* + * @unimplemented + */ +BOOL +APIENTRY +NtUserSetSystemCursor( + HCURSOR hcur, + DWORD id) +{ + return FALSE; +} + /* EOF */ diff --git a/reactos/win32ss/user/ntuser/cursoricon.h b/reactos/win32ss/user/ntuser/cursoricon.h index aaf6ae289c3..c5d7f5f5fcd 100644 --- a/reactos/win32ss/user/ntuser/cursoricon.h +++ b/reactos/win32ss/user/ntuser/cursoricon.h @@ -114,6 +114,43 @@ typedef struct _SYSTEM_CURSORINFO BOOL ScreenSaverRunning; } SYSTEM_CURSORINFO, *PSYSTEM_CURSORINFO; +typedef struct { + DWORD type; + PCURICON_OBJECT handle; +} SYSTEMCURICO; + +extern SYSTEMCURICO gasysico[]; +extern SYSTEMCURICO gasyscur[]; + +#define ROIC_SAMPLE 0 +#define ROIC_HAND 1 +#define ROIC_QUES 2 +#define ROIC_BANG 3 +#define ROIC_NOTE 4 +#define ROIC_WINLOGO 5 + +#define ROCR_ARROW 0 +#define ROCR_IBEAM 1 +#define ROCR_WAIT 2 +#define ROCR_CROSS 3 +#define ROCR_UP 4 +#define ROCR_SIZE 5 +#define ROCR_ICON 6 +#define ROCR_SIZENWSE 7 +#define ROCR_SIZENESW 8 +#define ROCR_SIZEWE 9 +#define ROCR_SIZENS 10 +#define ROCR_SIZEALL 11 +#define ROCR_NO 12 +#define ROCR_HAND 13 +#define ROCR_APPSTARTING 14 +#define ROCR_HELP 15 + +#define SYSTEMCUR(func) (gasyscur[ROCR_ ## func].handle) +#define SYSTEMICO(func) (gasysico[ROIC_ ## func].handle) + +VOID IntLoadSystenIcons(HICON,DWORD); + BOOL InitCursorImpl(VOID); HANDLE IntCreateCurIconHandle(BOOLEAN Anim); diff --git a/reactos/win32ss/user/ntuser/cursoricon_new.c b/reactos/win32ss/user/ntuser/cursoricon_new.c index bc454d01c91..94ea1426009 100644 --- a/reactos/win32ss/user/ntuser/cursoricon_new.c +++ b/reactos/win32ss/user/ntuser/cursoricon_new.c @@ -24,6 +24,42 @@ DBG_DEFAULT_CHANNEL(UserIcon); SYSTEM_CURSORINFO gSysCursorInfo; +PCURICON_OBJECT gcurFirst = NULL; // After all is done, this should be WINLOGO! + +// +// System Cursors +// +SYSTEMCURICO gasyscur[] = { + {OCR_NORMAL, NULL}, + {OCR_IBEAM, NULL}, + {OCR_WAIT, NULL}, + {OCR_CROSS, NULL}, + {OCR_UP, NULL}, + {OCR_ICON, NULL}, + {OCR_SIZE, NULL}, + {OCR_SIZENWSE, NULL}, + {OCR_SIZENESW, NULL}, + {OCR_SIZEWE, NULL}, + {OCR_SIZENS, NULL}, + {OCR_SIZEALL, NULL}, + {OCR_NO, NULL}, + {OCR_HAND, NULL}, + {OCR_APPSTARTING,NULL}, + {OCR_HELP, NULL}, + }; + +// +// System Icons +// +SYSTEMCURICO gasysico[] = { + {OIC_SAMPLE, NULL}, + {OIC_HAND, NULL}, + {OIC_QUES, NULL}, + {OIC_BANG, NULL}, + {OIC_NOTE, NULL}, + {OIC_WINLOGO,NULL}, + }; + BOOL InitCursorImpl(VOID) { @@ -39,6 +75,57 @@ InitCursorImpl(VOID) return TRUE; } +VOID +IntLoadSystenIcons(HICON hcur, DWORD id) +{ + PCURICON_OBJECT pcur; + int i; + PPROCESSINFO ppi; + + if (hcur) + { + pcur = UserGetCurIconObject(hcur); + if (!pcur) + { + EngSetLastError(ERROR_INVALID_CURSOR_HANDLE); + return; + } + + ppi = PsGetCurrentProcessWin32Process(); + + if (!(ppi->W32PF_flags & W32PF_CREATEDWINORDC)) + return; + + // Set Small Window Icon and do not link. + if ( id == OIC_WINLOGO+1 ) + { + pcur->CURSORF_flags |= CURSORF_GLOBAL; + UserReferenceObject(pcur); + pcur->head.ppi = NULL; + return; + } + + for(i = 0 ; i < 6; i++) + { + if (gasysico[i].type == id) + { + gasysico[i].handle = pcur; + pcur->CURSORF_flags |= CURSORF_GLOBAL|CURSORF_LINKED; + UserReferenceObject(pcur); + // + // The active switch between LR shared and Global public. + // This is hacked around to support this while at the initial system start up. + // + pcur->head.ppi = NULL; + // + pcur->pcurNext = gcurFirst; + gcurFirst = pcur; + return; + } + } + } +} + PSYSTEM_CURSORINFO IntGetSysCursorInfo() { @@ -183,6 +270,7 @@ IntDestroyCurIconObject( ASSERT(CacheCurIcon != NULL); UserDereferenceObject(CurIcon); } + CurIcon->CURSORF_flags &= ~CURSORF_LINKED; } /* We just mark the handle as being destroyed. @@ -456,7 +544,7 @@ NtUserGetIconSize( BOOL bRet = FALSE; TRACE("Enter NtUserGetIconSize\n"); - UserEnterExclusive(); + UserEnterShared(); if (!(CurIcon = UserGetCurIconObject(hCurIcon))) { @@ -515,7 +603,7 @@ NtUserGetCursorInfo( DECLARE_RETURN(BOOL); TRACE("Enter NtUserGetCursorInfo\n"); - UserEnterExclusive(); + UserEnterShared(); CurInfo = IntGetSysCursorInfo(); CurIcon = (PCURICON_OBJECT)CurInfo->CurrentCursorObject; @@ -562,10 +650,14 @@ APIENTRY UserClipCursor( RECTL *prcl) { - /* FIXME: Check if process has WINSTA_WRITEATTRIBUTES */ PSYSTEM_CURSORINFO CurInfo; PWND DesktopWindow = NULL; + if (!CheckWinstaAttributeAccess(WINSTA_WRITEATTRIBUTES)) + { + return FALSE; + } + CurInfo = IntGetSysCursorInfo(); DesktopWindow = UserGetDesktopWindow(); @@ -667,6 +759,14 @@ NtUserDestroyCursor( if (!bForce) { + /* Can not destroy global objects */ + if (CurIcon->head.ppi == NULL) + { + ERR("Trying to delete global cursor!\n"); + ret = TRUE; + goto leave; + } + /* Maybe we have good reasons not to destroy this object */ if (CurIcon->head.ppi != PsGetCurrentProcessWin32Process()) { @@ -750,7 +850,7 @@ NtUserFindExistingCursorIcon( goto done; } - UserEnterExclusive(); + UserEnterShared(); CurIcon = pProcInfo->pCursorCache; while(CurIcon) { @@ -770,7 +870,7 @@ NtUserFindExistingCursorIcon( CurIcon = CurIcon->pcurNext; continue; } - + if (IS_INTRESOURCE(CurIcon->strName.Buffer)) { if (CurIcon->strName.Buffer == ustrRsrcSafe.Buffer) @@ -787,6 +887,47 @@ NtUserFindExistingCursorIcon( } CurIcon = CurIcon->pcurNext; } + // + // Now search Global Cursors or Icons. + // + if(CurIcon == NULL) + { + CurIcon = gcurFirst; + while(CurIcon) + { + /* Icon/cursor */ + if (paramSafe.bIcon != is_icon(CurIcon)) + { + CurIcon = CurIcon->pcurNext; + continue; + } + /* See if module names match */ + if (atomModName == CurIcon->atomModName) + { + /* They do. Now see if this is the same resource */ + if (IS_INTRESOURCE(CurIcon->strName.Buffer) != IS_INTRESOURCE(ustrRsrcSafe.Buffer)) + { + /* One is an INT resource and the other is not -> no match */ + CurIcon = CurIcon->pcurNext; + continue; + } + if (IS_INTRESOURCE(CurIcon->strName.Buffer)) + { + if (CurIcon->strName.Buffer == ustrRsrcSafe.Buffer) + { + /* INT resources match */ + break; + } + } + else if (RtlCompareUnicodeString(&ustrRsrcSafe, &CurIcon->strName, TRUE) == 0) + { + /* Resource name strings match */ + break; + } + } + CurIcon = CurIcon->pcurNext; + } + } if(CurIcon) Ret = CurIcon->head.h; UserLeave(); @@ -807,14 +948,18 @@ APIENTRY NtUserGetClipCursor( RECTL *lpRect) { - /* FIXME: Check if process has WINSTA_READATTRIBUTES */ PSYSTEM_CURSORINFO CurInfo; RECTL Rect; NTSTATUS Status; DECLARE_RETURN(BOOL); TRACE("Enter NtUserGetClipCursor\n"); - UserEnterExclusive(); + UserEnterShared(); + + if (!CheckWinstaAttributeAccess(WINSTA_READATTRIBUTES)) + { + RETURN(FALSE); + } if (!lpRect) RETURN(FALSE); @@ -881,6 +1026,21 @@ NtUserSetCursor( if (pcurOld) { hOldCursor = pcurOld->head.h; + /* + Problem: + + System Global Cursors start out having at least 2 lock counts. If a system + cursor is the default cursor and is returned to the caller twice in its + life, the count will reach zero. Causing an assert to occur in objects. + + This fixes a SeaMonkey crash while the mouse crosses a boundary. + */ + if (pcurOld->CURSORF_flags & CURSORF_GLOBAL) + { + TRACE("Returning Global Cursor hcur %p\n",hOldCursor); + goto leave; + } + /* See if it was destroyed in the meantime */ if (UserObjectInDestroy(hOldCursor)) hOldCursor = NULL; @@ -1015,6 +1175,11 @@ NtUserSetCursorIconData( if(CurIcon->CURSORF_flags & CURSORF_LRSHARED) { IsShared = TRUE; + } + + // Support global public cursors and icons too. + if(!IsAnim || IsShared) + { if(pustrRsrc && pustrModule) { UNICODE_STRING ustrModuleSafe; @@ -1054,12 +1219,13 @@ NtUserSetCursorIconData( UserReferenceObject(CurIcon); CurIcon->pcurNext = ppi->pCursorCache; ppi->pCursorCache = CurIcon; + CurIcon->CURSORF_flags |= CURSORF_LINKED; } Ret = TRUE; done: - if(!Ret && IsShared) + if(!Ret && (!IsAnim || IsShared)) { if(!IS_INTRESOURCE(CurIcon->strName.Buffer)) ExFreePoolWithTag(CurIcon->strName.Buffer, TAG_STRING); @@ -1555,7 +1721,7 @@ NtUserGetCursorFrameInfo( NTSTATUS Status = STATUS_SUCCESS; TRACE("Enter NtUserGetCursorFrameInfo\n"); - UserEnterExclusive(); + UserEnterShared(); if (!(CurIcon = UserGetCurIconObject(hCursor))) { @@ -1607,4 +1773,66 @@ NtUserGetCursorFrameInfo( return ret; } +/* + * @implemented + */ +BOOL +APIENTRY +NtUserSetSystemCursor( + HCURSOR hcur, + DWORD id) +{ + PCURICON_OBJECT pcur, pcurOrig = NULL; + int i; + PPROCESSINFO ppi; + BOOL Ret = FALSE; + UserEnterExclusive(); + + if (!CheckWinstaAttributeAccess(WINSTA_WRITEATTRIBUTES)) + { + goto Exit; + } + + if (hcur) + { + pcur = UserGetCurIconObject(hcur); + if (!pcur) + { + EngSetLastError(ERROR_INVALID_CURSOR_HANDLE); + goto Exit; + } + + ppi = PsGetCurrentProcessWin32Process(); + + for(i = 0 ; i < 16; i++) + { + if (gasyscur[i].type == id) + { + pcurOrig = gasyscur[i].handle; + + if (pcurOrig) break; + + if (ppi->W32PF_flags & W32PF_CREATEDWINORDC) + { + gasyscur[i].handle = pcur; + pcur->CURSORF_flags |= CURSORF_GLOBAL|CURSORF_LINKED; + UserReferenceObject(pcur); + pcur->head.ppi = NULL; + pcur->pcurNext = gcurFirst; + gcurFirst = pcur; + Ret = TRUE; + } + break; + } + } + if (pcurOrig) + { + FIXME("Need to copy cursor data or do something! pcurOrig %p new pcur %p\n",pcurOrig,pcur); + } + } +Exit: + UserLeave(); + return Ret; +} + /* EOF */ diff --git a/reactos/win32ss/user/ntuser/defwnd.c b/reactos/win32ss/user/ntuser/defwnd.c index dc6035c5bc9..e7e21be47f8 100644 --- a/reactos/win32ss/user/ntuser/defwnd.c +++ b/reactos/win32ss/user/ntuser/defwnd.c @@ -754,7 +754,6 @@ DefWndHandleSysCommand(PWND pWnd, WPARAM wParam, LPARAM lParam) return(Hook ? 1 : 0); // Don't call us again from user space. } -#if 0 // Keep it for later! PWND FASTCALL co_IntFindChildWindowToOwner(PWND Root, PWND Owner) { @@ -767,6 +766,12 @@ co_IntFindChildWindowToOwner(PWND Root, PWND Owner) if(!OwnerWnd) continue; + if (!(Child->style & WS_POPUP) || + !(Child->style & WS_VISIBLE) || + /* Fixes CMD pop up properties window from having foreground. */ + Owner->head.pti->MessageQueue != Child->head.pti->MessageQueue) + continue; + if(OwnerWnd == Owner) { Ret = Child; @@ -775,7 +780,128 @@ co_IntFindChildWindowToOwner(PWND Root, PWND Owner) } return NULL; } -#endif + +LRESULT +DefWndHandleSetCursor(PWND pWnd, WPARAM wParam, LPARAM lParam) +{ + PWND pwndPopUP = NULL; + WORD Msg = HIWORD(lParam); + + /* Not for child windows. */ + if (UserHMGetHandle(pWnd) != (HWND)wParam) + { + return FALSE; + } + + switch((short)LOWORD(lParam)) + { + case HTERROR: + { + //// This is the real fix for CORE-6129! This was a "Code Whole". + USER_REFERENCE_ENTRY Ref; + + if (Msg == WM_LBUTTONDOWN) + { + // Find a pop up window to bring active. + pwndPopUP = co_IntFindChildWindowToOwner(UserGetDesktopWindow(), pWnd); + if (pwndPopUP) + { + // Not a child pop up from desktop. + if ( pwndPopUP != UserGetDesktopWindow()->spwndChild ) + { + // Get original active window. + PWND pwndOrigActive = gpqForeground->spwndActive; + + co_WinPosSetWindowPos(pWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + + UserRefObjectCo(pwndPopUP, &Ref); + //UserSetActiveWindow(pwndPopUP); + co_IntSetForegroundWindow(pwndPopUP); // HACK + UserDerefObjectCo(pwndPopUP); + + // If the change was made, break out. + if (pwndOrigActive != gpqForeground->spwndActive) + break; + } + } + } + //// + if (Msg == WM_LBUTTONDOWN || Msg == WM_MBUTTONDOWN || + Msg == WM_RBUTTONDOWN || Msg == WM_XBUTTONDOWN) + { + if (pwndPopUP) + { + FLASHWINFO fwi = + {sizeof(FLASHWINFO), + UserHMGetHandle(pwndPopUP), + FLASHW_ALL, + gspv.dwForegroundFlashCount, + (gpsi->dtCaretBlink >> 3)}; + + // Now shake that window! + IntFlashWindowEx(pwndPopUP, &fwi); + } + UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_MESSAGE_BEEP, 0); + } + break; + } + + case HTCLIENT: + { + if (pWnd->pcls->spcur) + { + UserSetCursor(pWnd->pcls->spcur, FALSE); + } + return FALSE; + } + + case HTLEFT: + case HTRIGHT: + { + if (pWnd->style & WS_MAXIMIZE) + { + break; + } + UserSetCursor(SYSTEMCUR(SIZEWE), FALSE); + return TRUE; + } + + case HTTOP: + case HTBOTTOM: + { + if (pWnd->style & WS_MAXIMIZE) + { + break; + } + UserSetCursor(SYSTEMCUR(SIZENS), FALSE); + return TRUE; + } + + case HTTOPLEFT: + case HTBOTTOMRIGHT: + { + if (pWnd->style & WS_MAXIMIZE) + { + break; + } + UserSetCursor(SYSTEMCUR(SIZENWSE), FALSE); + return TRUE; + } + + case HTBOTTOMLEFT: + case HTTOPRIGHT: + { + if (pWnd->style & WS_MAXIMIZE) + { + break; + } + UserSetCursor(SYSTEMCUR(SIZENESW), FALSE); + return TRUE; + } + } + UserSetCursor(SYSTEMCUR(ARROW), FALSE); + return FALSE; +} VOID FASTCALL DefWndPrint( PWND pwnd, HDC hdc, ULONG uFlags) { @@ -887,6 +1013,23 @@ IntDefWindowProc( case WM_CTLCOLOR: return (LRESULT) DefWndControlColor((HDC)wParam, HIWORD(lParam)); + case WM_SETCURSOR: + { + if (Wnd->style & WS_CHILD) + { + /* with the exception of the border around a resizable wnd, + * give the parent first chance to set the cursor */ + if (LOWORD(lParam) < HTLEFT || LOWORD(lParam) > HTBOTTOMRIGHT) + { + PWND parent = Wnd->spwndParent;//IntGetParent( Wnd ); + if (parent != UserGetDesktopWindow() && + co_IntSendMessage( UserHMGetHandle(parent), WM_SETCURSOR, wParam, lParam)) + return TRUE; + } + } + return DefWndHandleSetCursor(Wnd, wParam, lParam); + } + case WM_ACTIVATE: /* The default action in Windows is to set the keyboard focus to * the window, if it's being activated and not minimized */ @@ -1094,12 +1237,11 @@ PCURICON_OBJECT FASTCALL NC_IconForWindow( PWND pWnd ) { PCURICON_OBJECT pIcon = NULL; HICON hIcon; - // First thing to do, init the Window Logo icons. - if (!gpsi->hIconSmWindows) co_IntSetWndIcons(); //FIXME: Some callers use this function as if it returns a boolean saying "this window has an icon". //FIXME: Hence we must return a pointer with no reference count. //FIXME: This is bad and we should feel bad. + //FIXME: Stop whining over wine code. hIcon = UserGetProp(pWnd, gpsi->atomIconSmProp); if (!hIcon) hIcon = UserGetProp(pWnd, gpsi->atomIconProp); diff --git a/reactos/win32ss/user/ntuser/input.c b/reactos/win32ss/user/ntuser/input.c index 9bed4a7ac59..10e41c2771d 100644 --- a/reactos/win32ss/user/ntuser/input.c +++ b/reactos/win32ss/user/ntuser/input.c @@ -2,7 +2,7 @@ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Win32k subsystem * PURPOSE: General input functions - * FILE: subsystems/win32/win32k/ntuser/input.c + * FILE: win32ss/user/ntuser/input.c * PROGRAMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) * Rafal Harabien (rafalh@reactos.org) */ @@ -450,6 +450,7 @@ UserAttachThreadInput(PTHREADINFO ptiFrom, PTHREADINFO ptiTo, BOOL fAttach) { MSG msg; PATTACHINFO pai; + PCURICON_OBJECT CurIcon; /* Can not be the same thread. */ if (ptiFrom == ptiTo) return STATUS_INVALID_PARAMETER; @@ -497,7 +498,6 @@ UserAttachThreadInput(PTHREADINFO ptiFrom, PTHREADINFO ptiTo, BOOL fAttach) ERR("ptiFrom is Foreground\n"); ptiTo->MessageQueue->spwndActive = ptiFrom->MessageQueue->spwndActive; ptiTo->MessageQueue->spwndFocus = ptiFrom->MessageQueue->spwndFocus; - ptiTo->MessageQueue->CursorObject = ptiFrom->MessageQueue->CursorObject; ptiTo->MessageQueue->spwndCapture = ptiFrom->MessageQueue->spwndCapture; ptiTo->MessageQueue->QF_flags ^= ((ptiTo->MessageQueue->QF_flags ^ ptiFrom->MessageQueue->QF_flags) & QF_CAPTURELOCKED); ptiTo->MessageQueue->CaretInfo = ptiFrom->MessageQueue->CaretInfo; @@ -510,10 +510,24 @@ UserAttachThreadInput(PTHREADINFO ptiFrom, PTHREADINFO ptiTo, BOOL fAttach) ERR("ptiFrom NOT Foreground\n"); } + CurIcon = ptiFrom->MessageQueue->CursorObject; + MsqDestroyMessageQueue(ptiFrom); + if (CurIcon && UserObjectInDestroy(UserHMGetHandle(CurIcon))) + { + CurIcon = NULL; + } + ptiFrom->MessageQueue = ptiTo->MessageQueue; + // Pass cursor From if To is null. Pass test_SetCursor parent_id == current pti ID. + if (CurIcon && ptiTo->MessageQueue->CursorObject == NULL) + { + ptiTo->MessageQueue->CursorObject = CurIcon; + UserReferenceObject(CurIcon); + } + ptiFrom->MessageQueue->cThreads++; ERR("ptiTo S Share count %d\n", ptiFrom->MessageQueue->cThreads); @@ -603,14 +617,14 @@ NtUserAttachThreadInput( BOOL Ret = FALSE; UserEnterExclusive(); - ERR("Enter NtUserAttachThreadInput %s\n",(fAttach ? "TRUE" : "FALSE" )); + TRACE("Enter NtUserAttachThreadInput %s\n",(fAttach ? "TRUE" : "FALSE" )); pti = IntTID2PTI((HANDLE)idAttach); ptiTo = IntTID2PTI((HANDLE)idAttachTo); if ( !pti || !ptiTo ) { - ERR("AttachThreadInput pti or ptiTo NULL.\n"); + TRACE("AttachThreadInput pti or ptiTo NULL.\n"); EngSetLastError(ERROR_INVALID_PARAMETER); goto Exit; } @@ -618,13 +632,13 @@ NtUserAttachThreadInput( Status = UserAttachThreadInput( pti, ptiTo, fAttach); if (!NT_SUCCESS(Status)) { - ERR("AttachThreadInput Error Status 0x%x. \n",Status); + TRACE("AttachThreadInput Error Status 0x%x. \n",Status); EngSetLastError(RtlNtStatusToDosError(Status)); } else Ret = TRUE; Exit: - ERR("Leave NtUserAttachThreadInput, ret=%d\n",Ret); + TRACE("Leave NtUserAttachThreadInput, ret=%d\n",Ret); UserLeave(); return Ret; } diff --git a/reactos/win32ss/user/ntuser/msgqueue.c b/reactos/win32ss/user/ntuser/msgqueue.c index e45b052cb8b..6f4141cdc1a 100644 --- a/reactos/win32ss/user/ntuser/msgqueue.c +++ b/reactos/win32ss/user/ntuser/msgqueue.c @@ -86,12 +86,6 @@ UserSetCursor( pti = PsGetCurrentThreadWin32Thread(); MessageQueue = pti->MessageQueue; - /* Get the screen DC */ - if(!(hdcScreen = IntGetScreenDC())) - { - return NULL; - } - OldCursor = MessageQueue->CursorObject; /* Check if cursors are different */ @@ -105,10 +99,22 @@ UserSetCursor( if (MessageQueue->iCursorLevel < 0) return OldCursor; + // Fixes the error message "Not the same cursor!". + if (gpqCursor == NULL) + { + gpqCursor = MessageQueue; + } + /* Update cursor if this message queue controls it */ pWnd = IntTopLevelWindowFromPoint(gpsi->ptCursor.x, gpsi->ptCursor.y); if (pWnd && pWnd->head.pti->MessageQueue == MessageQueue) { + /* Get the screen DC */ + if (!(hdcScreen = IntGetScreenDC())) + { + return NULL; + } + if (NewCursor) { /* Call GDI to set the new screen cursor */ @@ -681,7 +687,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook } else GreMovePointer(hdcScreen, Msg->pt.x, Msg->pt.y); } - /* Check if w have to hide cursor */ + /* Check if we have to hide cursor */ else if (CurInfo->ShowingCursor >= 0) GreMovePointer(hdcScreen, -1, -1); @@ -1053,20 +1059,21 @@ co_MsqSendMessage(PTHREADINFO ptirec, ASSERT(ptirec->pcti); // Send must have a client side to receive it!!!! /* Don't send from or to a dying thread */ - if (pti->TIF_flags & TIF_INCLEANUP || ptirec->TIF_flags & TIF_INCLEANUP) - { - // Unless we are dying and need to tell our parents. - if (pti->TIF_flags & TIF_INCLEANUP && !(ptirec->TIF_flags & TIF_INCLEANUP)) - { + if (pti->TIF_flags & TIF_INCLEANUP || ptirec->TIF_flags & TIF_INCLEANUP) + { + // Unless we are dying and need to tell our parents. + if (pti->TIF_flags & TIF_INCLEANUP && !(ptirec->TIF_flags & TIF_INCLEANUP)) + { // Parent notify is the big one. Fire and forget! TRACE("Send message from dying thread %d\n",Msg); co_MsqSendMessageAsync(ptirec, Wnd, Msg, wParam, lParam, NULL, 0, FALSE, HookMessage); - } - if (uResult) *uResult = -1; - TRACE("MsqSM: Msg %d Current pti %lu or Rec pti %lu\n", Msg, pti->TIF_flags & TIF_INCLEANUP, ptirec->TIF_flags & TIF_INCLEANUP); - return STATUS_UNSUCCESSFUL; - } + } + if (uResult) *uResult = -1; + TRACE("MsqSM: Msg %d Current pti %lu or Rec pti %lu\n", Msg, pti->TIF_flags & TIF_INCLEANUP, ptirec->TIF_flags & TIF_INCLEANUP); + return STATUS_UNSUCCESSFUL; + } + // Should we do the same for No Wait? if ( HookMessage == MSQ_NORMAL ) { pWnd = ValidateHwndNoErr(Wnd); @@ -1511,6 +1518,8 @@ BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, UINT first, UINT // Null window or not the same "Hardware" message queue. if (pwndMsg == NULL || pwndMsg->head.pti->MessageQueue != pti->MessageQueue) { + // Crossing a boundary, so set cursor. See default message queue cursor. + UserSetCursor(SYSTEMCUR(ARROW), FALSE); /* Remove and ignore the message */ *RemoveMessages = TRUE; return FALSE; @@ -2074,7 +2083,12 @@ MsqInitializeMessageQueue(PTHREADINFO pti, PUSER_MESSAGE_QUEUE MessageQueue) InitializeListHead(&MessageQueue->HardwareMessagesListHead); // Keep here! MessageQueue->spwndFocus = NULL; MessageQueue->iCursorLevel = 0; - MessageQueue->CursorObject = NULL; + MessageQueue->CursorObject = SYSTEMCUR(WAIT); // See test_initial_cursor. + if (MessageQueue->CursorObject) + { + TRACE("Default cursor hcur %p\n",UserHMGetHandle(MessageQueue->CursorObject)); + UserReferenceObject(MessageQueue->CursorObject); + } RtlCopyMemory(MessageQueue->afKeyState, gafAsyncKeyState, sizeof(gafAsyncKeyState)); MessageQueue->ptiMouse = pti; MessageQueue->ptiKeyboard = pti; diff --git a/reactos/win32ss/user/ntuser/ntstubs.c b/reactos/win32ss/user/ntuser/ntstubs.c index 1374a069084..6083e130f6e 100644 --- a/reactos/win32ss/user/ntuser/ntstubs.c +++ b/reactos/win32ss/user/ntuser/ntstubs.c @@ -1111,25 +1111,6 @@ NtUserAlterWindowStyle(DWORD Unknown0, return(0); } -/* - * NtUserSetWindowStationUser - * - * Status - * @unimplemented - */ - -DWORD APIENTRY -NtUserSetWindowStationUser( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3) -{ - STUB - - return 0; -} - BOOL APIENTRY NtUserAddClipboardFormatListener( HWND hwnd ) @@ -1156,16 +1137,4 @@ BOOL APIENTRY NtUserGetUpdatedClipboardFormats( return FALSE; } -/* - * @unimplemented - */ -BOOL -APIENTRY -NtUserSetSystemCursor( - HCURSOR hcur, - DWORD id) -{ - return FALSE; -} - /* EOF */ diff --git a/reactos/win32ss/user/ntuser/win32.h b/reactos/win32ss/user/ntuser/win32.h index 25215ce2dec..1ad915b15cd 100644 --- a/reactos/win32ss/user/ntuser/win32.h +++ b/reactos/win32ss/user/ntuser/win32.h @@ -252,10 +252,14 @@ typedef struct _PROCESSINFO ACCESS_MASK amwinsta; DWORD dwHotkey; HMONITOR hMonitor; + UINT iClipSerialNumber; struct _CURICON_OBJECT* pCursorCache; + PVOID pClientBase; + DWORD dwLpkEntryPoints; + PVOID pW32Job; + DWORD dwImeCompatFlags; LUID luidSession; USERSTARTUPINFO usi; - PVOID pW32Job; DWORD dwLayout; DWORD dwRegisteredClasses; diff --git a/reactos/win32ss/user/ntuser/winsta.c b/reactos/win32ss/user/ntuser/winsta.c index 8ffaedc7509..9bf8bdfeafb 100644 --- a/reactos/win32ss/user/ntuser/winsta.c +++ b/reactos/win32ss/user/ntuser/winsta.c @@ -2,7 +2,7 @@ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Win32k subsystem * PURPOSE: Window stations - * FILE: subsystems/win32/win32k/ntuser/winsta.c + * FILE: win32ss/user/ntuser/winsta.c * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net) * TODO: The process window station is created on * the first USER32/GDI32 call not related @@ -295,7 +295,7 @@ co_IntInitializeDesktopGraphics(VOID) co_IntLoadDefaultCursors(); /* Setup the icons */ - //co_IntSetWndIcons(); + co_IntSetWndIcons(); /* Show the desktop */ pdesk = IntGetActiveDesktop(); @@ -1437,7 +1437,7 @@ NtUserLockWorkStation(VOID) } BOOL APIENTRY -NEW_NtUserSetWindowStationUser( +NtUserSetWindowStationUser( HWINSTA hWindowStation, PLUID pluid, PSID psid, diff --git a/reactos/win32ss/user/user32/misc/dllmain.c b/reactos/win32ss/user/user32/misc/dllmain.c index 29285600fdc..52d138ca732 100644 --- a/reactos/win32ss/user/user32/misc/dllmain.c +++ b/reactos/win32ss/user/user32/misc/dllmain.c @@ -580,13 +580,18 @@ User32CallSetWndIconsFromKernel(PVOID Arguments, ULONG ArgumentLength) { PSETWNDICONS_CALLBACK_ARGUMENTS Common = Arguments; - if (!hIconSmWindows) + if (!gpsi->hIconSmWindows) { - hIconSmWindows = LoadImageW(0, IDI_WINLOGO, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR); - hIconWindows = LoadImageW(0, IDI_WINLOGO, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR); + Common->hIconSample = LoadImageW(0, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE); + Common->hIconHand = LoadImageW(0, IDI_HAND, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE); + Common->hIconQuestion = LoadImageW(0, IDI_QUESTION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE); + Common->hIconBang = LoadImageW(0, IDI_EXCLAMATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE); + Common->hIconNote = LoadImageW(0, IDI_ASTERISK, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE); + Common->hIconWindows = LoadImageW(0, IDI_WINLOGO, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE); + Common->hIconSmWindows = LoadImageW(0, IDI_WINLOGO, IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0); + hIconWindows = Common->hIconWindows; + hIconSmWindows = Common->hIconSmWindows; } - Common->hIconSmWindows = hIconSmWindows; - Common->hIconWindows = hIconWindows; ERR("hIconSmWindows %p hIconWindows %p \n",hIconSmWindows,hIconWindows); return ZwCallbackReturn(Arguments, ArgumentLength, STATUS_SUCCESS); } diff --git a/reactos/win32ss/user/user32/misc/winsta.c b/reactos/win32ss/user/user32/misc/winsta.c index 0f70e806bc7..73eb010a637 100644 --- a/reactos/win32ss/user/user32/misc/winsta.c +++ b/reactos/win32ss/user/user32/misc/winsta.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll - * FILE: lib/user32/misc/winsta.c + * FILE: win32ss/user/user32/misc/winsta.c * PURPOSE: Window stations * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net) * UPDATE HISTORY: @@ -388,16 +388,16 @@ OpenWindowStationW(LPCWSTR lpszWinSta, /* * @unimplemented */ -DWORD +BOOL WINAPI SetWindowStationUser( - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4 + HWINSTA hWindowStation, + PLUID pluid, + PSID psid, + DWORD size ) { - return NtUserSetWindowStationUser(Unknown1, Unknown2, Unknown3, Unknown4); + return NtUserSetWindowStationUser(hWindowStation, pluid, psid, size); } /* EOF */ diff --git a/reactos/win32ss/user/user32/windows/cursoricon_new.c b/reactos/win32ss/user/user32/windows/cursoricon_new.c index 747cf12389f..c0b29e331c8 100644 --- a/reactos/win32ss/user/user32/windows/cursoricon_new.c +++ b/reactos/win32ss/user/user32/windows/cursoricon_new.c @@ -1,7 +1,7 @@ /* * PROJECT: ReactOS user32.dll * COPYRIGHT: GPL - See COPYING in the top level directory - * FILE: dll/win32/user32/windows/cursoricon.c + * FILE: win32ss/user//user32/windows/cursoricon.c * PURPOSE: cursor and icons implementation * PROGRAMMER: Jérôme Gardou (jerome.gardou@reactos.org) */ @@ -20,6 +20,30 @@ WINE_DECLARE_DEBUG_CHANNEL(icon); /************* USER32 INTERNAL FUNCTIONS **********/ +VOID LoadSystemCursors(VOID) +{ + if (!gpsi->hIconSmWindows) + { + ERR("Loading System Cursors\n"); + NtUserSetSystemCursor(LoadImageW( 0, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE ), OCR_NORMAL); + NtUserSetSystemCursor(LoadImageW( 0, IDC_IBEAM, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE ), OCR_IBEAM); + NtUserSetSystemCursor(LoadImageW( 0, IDC_WAIT, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE ), OCR_WAIT); + NtUserSetSystemCursor(LoadImageW( 0, IDC_CROSS, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE ), OCR_CROSS); + NtUserSetSystemCursor(LoadImageW( 0, IDC_UPARROW, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE ), OCR_UP); + NtUserSetSystemCursor(LoadImageW( 0, IDC_ICON, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE ), OCR_ICON); + NtUserSetSystemCursor(LoadImageW( 0, IDC_SIZE, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE ), OCR_SIZE); + NtUserSetSystemCursor(LoadImageW( 0, IDC_SIZENWSE, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE ), OCR_SIZENWSE); + NtUserSetSystemCursor(LoadImageW( 0, IDC_SIZENESW, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE ), OCR_SIZENESW); + NtUserSetSystemCursor(LoadImageW( 0, IDC_SIZEWE, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE ), OCR_SIZEWE); + NtUserSetSystemCursor(LoadImageW( 0, IDC_SIZENS, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE ), OCR_SIZENS); + NtUserSetSystemCursor(LoadImageW( 0, IDC_SIZEALL, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE ), OCR_SIZEALL); + NtUserSetSystemCursor(LoadImageW( 0, IDC_NO, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE ), OCR_NO); + NtUserSetSystemCursor(LoadImageW( 0, IDC_HAND, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE ), OCR_HAND); + NtUserSetSystemCursor(LoadImageW( 0, IDC_APPSTARTING, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE ), OCR_APPSTARTING); + NtUserSetSystemCursor(LoadImageW( 0, IDC_HELP, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE ), OCR_HELP); + } +} + /* This callback routine is called directly after switching to gui mode */ NTSTATUS WINAPI @@ -29,6 +53,9 @@ User32SetupDefaultCursors(PVOID Arguments, BOOL *DefaultCursor = (BOOL*)Arguments; HCURSOR hCursor; + /* Load system cursors first */ + LoadSystemCursors(); + if(*DefaultCursor) { /* set default cursor */ @@ -1397,29 +1424,25 @@ CURSORICON_LoadImageW( BOOL bStatus; UNICODE_STRING ustrRsrc; UNICODE_STRING ustrModule = {0, 0, NULL}; - + /* Fix width/height */ if(fuLoad & LR_DEFAULTSIZE) { if(!cxDesired) cxDesired = GetSystemMetrics(bIcon ? SM_CXICON : SM_CXCURSOR); if(!cyDesired) cyDesired = GetSystemMetrics(bIcon ? SM_CYICON : SM_CYCURSOR); } - + if(fuLoad & LR_LOADFROMFILE) { return CURSORICON_LoadFromFileW(lpszName, cxDesired, cyDesired, fuLoad, bIcon); } - + /* Check if caller wants OEM icons */ if(!hinst) hinst = User32Instance; - - if(fuLoad & LR_SHARED) - { - DWORD size = MAX_PATH; - FINDEXISTINGCURICONPARAM param; - TRACE("Checking for an LR_SHARED cursor/icon.\n"); + if(lpszName) + { /* Prepare the resource name string */ if(IS_INTRESOURCE(lpszName)) { @@ -1429,7 +1452,11 @@ CURSORICON_LoadImageW( } else RtlInitUnicodeString(&ustrRsrc, lpszName); + } + if(hinst) + { + DWORD size = MAX_PATH; /* Get the module name string */ while (TRUE) { @@ -1460,7 +1487,13 @@ CURSORICON_LoadImageW( ustrModule.MaximumLength = size * sizeof(WCHAR); break; } - + } + + if(fuLoad & LR_SHARED) + { + FINDEXISTINGCURICONPARAM param; + + TRACE("Checking for an LR_SHARED cursor/icon.\n"); /* Ask win32k */ param.bIcon = bIcon; param.cx = cxDesired; @@ -1469,7 +1502,7 @@ CURSORICON_LoadImageW( if(hCurIcon) { /* Woohoo, got it! */ - TRACE("MATCH!\n"); + TRACE("MATCH! %p\n",hCurIcon); HeapFree(GetProcessHeap(), 0, ustrModule.Buffer); return hCurIcon; } @@ -1484,18 +1517,18 @@ CURSORICON_LoadImageW( /* We let FindResource, LoadResource, etc. call SetLastError */ if(!hrsrc) goto done; - + handle = LoadResource(hinst, hrsrc); if(!handle) goto done; - + dir = LockResource(handle); if(!dir) goto done; - + wResId = LookupIconIdFromDirectoryEx((PBYTE)dir, bIcon, cxDesired, cyDesired, fuLoad); FreeResource(handle); - + /* Get the relevant resource pointer */ hrsrc = FindResourceW( hinst, @@ -1503,11 +1536,11 @@ CURSORICON_LoadImageW( bIcon ? RT_ICON : RT_CURSOR); if(!hrsrc) goto done; - + handle = LoadResource(hinst, hrsrc); if(!handle) goto done; - + bits = LockResource(handle); if(!bits) { @@ -1531,32 +1564,31 @@ CURSORICON_LoadImageW( cursorData.cx = cxDesired; cursorData.cy = cyDesired; cursorData.rt = (USHORT)((ULONG_PTR)(bIcon ? RT_ICON : RT_CURSOR)); - + /* Get the bitmaps */ bStatus = CURSORICON_GetCursorDataFromBMI( &cursorData, (BITMAPINFO*)bits); - + FreeResource( handle ); - + if(!bStatus) goto done; - + /* Create the handle */ hCurIcon = NtUserxCreateEmptyCurObject(FALSE); if(!hCurIcon) { goto end_error; } - - /* Tell win32k */ + if(fuLoad & LR_SHARED) { cursorData.CURSORF_flags |= CURSORF_LRSHARED; - bStatus = NtUserSetCursorIconData(hCurIcon, &ustrModule, &ustrRsrc, &cursorData); } - else - bStatus = NtUserSetCursorIconData(hCurIcon, NULL, NULL, &cursorData); + + /* Tell win32k */ + bStatus = NtUserSetCursorIconData(hCurIcon, hinst ? &ustrModule : NULL, lpszName ? &ustrRsrc : NULL, &cursorData); if(!bStatus) { @@ -1575,7 +1607,7 @@ end_error: DeleteObject(cursorData.hbmMask); if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor); if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha); - + return NULL; } @@ -2580,8 +2612,15 @@ BOOL WINAPI SetSystemCursor( _In_ DWORD id ) { - UNIMPLEMENTED; - return FALSE; + if (hcur == NULL) + { + hcur = LoadImageW( 0, MAKEINTRESOURCE(id), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE ); + if (hcur == NULL) + { + return FALSE; + } + } + return NtUserSetSystemCursor(hcur,id); } BOOL WINAPI SetCursorPos( diff --git a/reactos/win32ss/user/user32/windows/defwnd.c b/reactos/win32ss/user/user32/windows/defwnd.c index 0dbf03d698b..a660666df48 100644 --- a/reactos/win32ss/user/user32/windows/defwnd.c +++ b/reactos/win32ss/user/user32/windows/defwnd.c @@ -2,7 +2,7 @@ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll - * FILE: dll/win32/user32/windows/defwnd.c + * FILE: win32ss/user/user32/windows/defwnd.c * PURPOSE: Window management * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net) * UPDATE HISTORY: @@ -183,109 +183,6 @@ IntFindChildWindowToOwner(HWND hRoot, HWND hOwner) return NULL; } -LRESULT -DefWndHandleSetCursor(HWND hWnd, WPARAM wParam, LPARAM lParam, ULONG Style) -{ - /* Not for child windows. */ - if (hWnd != (HWND)wParam) - { - return 0; - } - - switch((short)LOWORD(lParam)) - { - case HTERROR: - { - //// This is the real fix for CORE-6129! - HWND hwndPopUP; - WORD Msg = HIWORD(lParam); - - if (Msg == WM_LBUTTONDOWN) - { - // Find a pop up window to bring active. - hwndPopUP = IntFindChildWindowToOwner(GetDesktopWindow(), hWnd); - if (hwndPopUP) - { - // Not a child pop up from desktop. - if ( hwndPopUP != GetWindow(GetDesktopWindow(), GW_CHILD) ) - { - // Get original active window. - HWND hwndOrigActive = GetActiveWindow(); - - SetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); - - //SetActiveWindow(hwndPopUP); - SetForegroundWindow(hwndPopUP); // HACK - - // If the change was made, break out. - if (hwndOrigActive != GetActiveWindow()) - break; - } - } - } - //// - if (Msg == WM_LBUTTONDOWN || Msg == WM_MBUTTONDOWN || - Msg == WM_RBUTTONDOWN || Msg == WM_XBUTTONDOWN) - { - ERR("Beep!\n"); - MessageBeep(0); - } - break; - } - - case HTCLIENT: - { - HICON hCursor = (HICON)GetClassLongPtrW(hWnd, GCL_HCURSOR); - if (hCursor) - { - SetCursor(hCursor); - return TRUE; - } - return FALSE; - } - - case HTLEFT: - case HTRIGHT: - { - if (Style & WS_MAXIMIZE) - { - break; - } - return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZEWE))); - } - - case HTTOP: - case HTBOTTOM: - { - if (Style & WS_MAXIMIZE) - { - break; - } - return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENS))); - } - - case HTTOPLEFT: - case HTBOTTOMRIGHT: - { - if (Style & WS_MAXIMIZE) - { - break; - } - return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENWSE))); - } - case HTBOTTOMLEFT: - case HTTOPRIGHT: - { - if (GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_MAXIMIZE) - { - break; - } - return((LRESULT)SetCursor(LoadCursorW(0, IDC_SIZENESW))); - } - } - return((LRESULT)SetCursor(LoadCursorW(0, IDC_ARROW))); -} - /*********************************************************************** * DefWndTrackScrollBar * @@ -894,34 +791,6 @@ User32DefWindowProc(HWND hWnd, case WM_CTLCOLOR: return (LRESULT) DefWndControlColor((HDC)wParam, HIWORD(lParam)); - case WM_SETCURSOR: - { - LONG_PTR Style = GetWindowLongPtrW(hWnd, GWL_STYLE); - - if (Style & WS_CHILD) - { - /* with the exception of the border around a resizable wnd, - * give the parent first chance to set the cursor */ - if (LOWORD(lParam) < HTLEFT || LOWORD(lParam) > HTBOTTOMRIGHT) - { - HWND parent = GetParent( hWnd ); - if (bUnicode) - { - if (parent != GetDesktopWindow() && - SendMessageW( parent, WM_SETCURSOR, wParam, lParam)) - return TRUE; - } - else - { - if (parent != GetDesktopWindow() && - SendMessageA( parent, WM_SETCURSOR, wParam, lParam)) - return TRUE; - } - } - } - return (DefWndHandleSetCursor(hWnd, wParam, lParam, Style)); - } - case WM_SYSCOMMAND: return (DefWndHandleSysCommand(hWnd, wParam, lParam));