diff --git a/win32ss/include/callback.h b/win32ss/include/callback.h index 9fdf265ba59a4..69e4e1f5c92a8 100644 --- a/win32ss/include/callback.h +++ b/win32ss/include/callback.h @@ -62,6 +62,15 @@ typedef struct _HOOKPROC_CALLBACK_ARGUMENTS WCHAR ModuleName[512]; } HOOKPROC_CALLBACK_ARGUMENTS, *PHOOKPROC_CALLBACK_ARGUMENTS; +typedef struct _LOADIMAGE_CALLBACK_ARGUMENTS +{ + UINT ImageType; + int cxDesired; + int cyDesired; + UINT fuFlags; + WCHAR ImageName[MAX_PATH]; +} LOADIMAGE_CALLBACK_ARGUMENTS, *PLOADIMAGE_CALLBACK_ARGUMENTS; + typedef struct _HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS { CREATESTRUCTW Cs; /* lpszName and lpszClass replaced by offsets */ @@ -128,6 +137,26 @@ typedef struct _GET_CHARSET_INFO CHARSETINFO Cs; } GET_CHARSET_INFO, *PGET_CHARSET_INFO; +typedef struct _LOADCURSORS_CALLBACK_ARGUMENTS +{ + HCURSOR hCursorArrow; + HCURSOR hCursorIbeam; + HCURSOR hCursorWait; + HCURSOR hCursorCross; + HCURSOR hCursorUp; + HCURSOR hCursorIcon; + HCURSOR hCursorSize; + HCURSOR hCursorSizeNwse; + HCURSOR hCursorSizeNesw; + HCURSOR hCursorSizeWe; + HCURSOR hCursorSizeNs; + HCURSOR hCursorSizeAll; + HCURSOR hCursorNo; + HCURSOR hCursorHand; + HCURSOR hCursorAppStarting; + HCURSOR hCursorHelp; +} LOADCURSORS_CALLBACK_ARGUMENTS, *PLOADCURSORS_CALLBACK_ARGUMENTS; + typedef struct _SETWNDICONS_CALLBACK_ARGUMENTS { HICON hIconSample; @@ -185,6 +214,8 @@ typedef struct _IMMLOADLAYOUT_CALLBACK_OUTPUT IMEINFOEX iiex; } IMMLOADLAYOUT_CALLBACK_OUTPUT, *PIMMLOADLAYOUT_CALLBACK_OUTPUT; +NTSTATUS WINAPI +User32CallLoadImageFromKernel(PVOID Arguments, ULONG ArgumentLength); NTSTATUS WINAPI User32CallCopyImageFromKernel(PVOID Arguments, ULONG ArgumentLength); NTSTATUS WINAPI diff --git a/win32ss/include/u32cb.h b/win32ss/include/u32cb.h index 168df49f7dc61..3f4233de4fec4 100644 --- a/win32ss/include/u32cb.h +++ b/win32ss/include/u32cb.h @@ -16,13 +16,14 @@ DEFINE_USER32_CALLBACK(USER32_CALLBACK_LOADMENU, 6, User32CallLoa DEFINE_USER32_CALLBACK(USER32_CALLBACK_CLIENTTHREADSTARTUP, 7, User32CallClientThreadSetupFromKernel) DEFINE_USER32_CALLBACK(USER32_CALLBACK_CLIENTLOADLIBRARY, 8, User32CallClientLoadLibraryFromKernel) DEFINE_USER32_CALLBACK(USER32_CALLBACK_GETCHARSETINFO, 9, User32CallGetCharsetInfo) -DEFINE_USER32_CALLBACK(USER32_CALLBACK_COPYIMAGE, 10, User32CallCopyImageFromKernel) -DEFINE_USER32_CALLBACK(USER32_CALLBACK_SETWNDICONS, 11, User32CallSetWndIconsFromKernel) -DEFINE_USER32_CALLBACK(USER32_CALLBACK_DELIVERUSERAPC, 12, User32DeliverUserAPC) -DEFINE_USER32_CALLBACK(USER32_CALLBACK_DDEPOST, 13, User32CallDDEPostFromKernel) -DEFINE_USER32_CALLBACK(USER32_CALLBACK_DDEGET, 14, User32CallDDEGetFromKernel) -DEFINE_USER32_CALLBACK(USER32_CALLBACK_SETOBM, 15, User32CallOBMFromKernel) -DEFINE_USER32_CALLBACK(USER32_CALLBACK_LPK, 16, User32CallLPKFromKernel) -DEFINE_USER32_CALLBACK(USER32_CALLBACK_UMPD, 17, User32CallUMPDFromKernel) -DEFINE_USER32_CALLBACK(USER32_CALLBACK_IMMPROCESSKEY, 18, User32CallImmProcessKeyFromKernel) -DEFINE_USER32_CALLBACK(USER32_CALLBACK_IMMLOADLAYOUT, 19, User32CallImmLoadLayoutFromKernel) +DEFINE_USER32_CALLBACK(USER32_CALLBACK_LOADIMAGE, 10, User32CallLoadImageFromKernel) +DEFINE_USER32_CALLBACK(USER32_CALLBACK_COPYIMAGE, 11, User32CallCopyImageFromKernel) +DEFINE_USER32_CALLBACK(USER32_CALLBACK_SETWNDICONS, 12, User32CallSetWndIconsFromKernel) +DEFINE_USER32_CALLBACK(USER32_CALLBACK_DELIVERUSERAPC, 13, User32DeliverUserAPC) +DEFINE_USER32_CALLBACK(USER32_CALLBACK_DDEPOST, 14, User32CallDDEPostFromKernel) +DEFINE_USER32_CALLBACK(USER32_CALLBACK_DDEGET, 15, User32CallDDEGetFromKernel) +DEFINE_USER32_CALLBACK(USER32_CALLBACK_SETOBM, 16, User32CallOBMFromKernel) +DEFINE_USER32_CALLBACK(USER32_CALLBACK_LPK, 17, User32CallLPKFromKernel) +DEFINE_USER32_CALLBACK(USER32_CALLBACK_UMPD, 18, User32CallUMPDFromKernel) +DEFINE_USER32_CALLBACK(USER32_CALLBACK_IMMPROCESSKEY, 19, User32CallImmProcessKeyFromKernel) +DEFINE_USER32_CALLBACK(USER32_CALLBACK_IMMLOADLAYOUT, 20, User32CallImmLoadLayoutFromKernel) diff --git a/win32ss/user/ntuser/callback.c b/win32ss/user/ntuser/callback.c index 801e8e971dbaa..a906224cf9a95 100644 --- a/win32ss/user/ntuser/callback.c +++ b/win32ss/user/ntuser/callback.c @@ -465,27 +465,33 @@ co_IntLoadSysMenuTemplate(VOID) return (HMENU)Result; } -extern HCURSOR gDesktopCursor; - BOOL APIENTRY co_IntLoadDefaultCursors(VOID) { NTSTATUS Status; - PVOID ResultPointer; - ULONG ResultLength; - BOOL DefaultCursor = TRUE; + PVOID Argument, ResultPointer; + ULONG ArgumentLength, ResultLength; + PLOADCURSORS_CALLBACK_ARGUMENTS Common; /* Do not allow the desktop thread to do callback to user mode */ ASSERT(PsGetCurrentThreadWin32Thread() != gptiDesktopThread); ResultPointer = NULL; - ResultLength = sizeof(HCURSOR); + ResultLength = ArgumentLength = sizeof(LOADCURSORS_CALLBACK_ARGUMENTS); + + Argument = IntCbAllocateMemory(ArgumentLength); + if (!Argument) + { + ERR("Load Default Cursors callback failed: out of memory\n"); + return FALSE; + } + Common = (PLOADCURSORS_CALLBACK_ARGUMENTS)Argument; UserLeaveCo(); Status = KeUserModeCallback(USER32_CALLBACK_LOADDEFAULTCURSORS, - &DefaultCursor, - sizeof(BOOL), + Argument, + ArgumentLength, &ResultPointer, &ResultLength); @@ -493,11 +499,31 @@ co_IntLoadDefaultCursors(VOID) if (!NT_SUCCESS(Status)) { + ERR("Load Default Cursors callback failed!\n"); + IntCbFreeMemory(Argument); return FALSE; } - /* HACK: The desktop class doen't have a proper cursor yet, so set it here */ - gDesktopCursor = *((HCURSOR*)ResultPointer); + RtlMoveMemory(Common, ResultPointer, ArgumentLength); + + NtUserSetSystemCursor(Common->hCursorArrow, OCR_NORMAL); + NtUserSetSystemCursor(Common->hCursorIbeam, OCR_IBEAM); + NtUserSetSystemCursor(Common->hCursorWait, OCR_WAIT); + NtUserSetSystemCursor(Common->hCursorCross, OCR_CROSS); + NtUserSetSystemCursor(Common->hCursorUp, OCR_UP); + NtUserSetSystemCursor(Common->hCursorIcon, OCR_ICON); + NtUserSetSystemCursor(Common->hCursorSize, OCR_SIZE); + NtUserSetSystemCursor(Common->hCursorSizeAll, OCR_SIZEALL); + NtUserSetSystemCursor(Common->hCursorSizeNwse, OCR_SIZENWSE); + NtUserSetSystemCursor(Common->hCursorSizeNesw, OCR_SIZENESW); + NtUserSetSystemCursor(Common->hCursorSizeWe, OCR_SIZEWE); + NtUserSetSystemCursor(Common->hCursorSizeNs, OCR_SIZENS); + NtUserSetSystemCursor(Common->hCursorNo, OCR_NO); + NtUserSetSystemCursor(Common->hCursorHand, OCR_HAND); + NtUserSetSystemCursor(Common->hCursorAppStarting, OCR_APPSTARTING); + NtUserSetSystemCursor(Common->hCursorHelp, OCR_HELP); + + IntCbFreeMemory(Argument); return TRUE; } @@ -981,6 +1007,61 @@ co_IntClientThreadSetup(VOID) return Status; } +HANDLE FASTCALL +co_IntLoadImage(LPCWSTR name, UINT type, INT desiredx, INT desiredy, UINT flags) +{ + HANDLE Handle; + NTSTATUS Status; + ULONG ArgumentLength, ResultLength; + PVOID Argument, ResultPointer; + PLOADIMAGE_CALLBACK_ARGUMENTS Common; + + ArgumentLength = ResultLength = 0; + Argument = ResultPointer = NULL; + + ArgumentLength = sizeof(LOADIMAGE_CALLBACK_ARGUMENTS); + + Argument = IntCbAllocateMemory(ArgumentLength); + if (!Argument) + { + ERR("LoadImage callback failed: out of memory\n"); + return 0; + } + Common = (PLOADIMAGE_CALLBACK_ARGUMENTS) Argument; + + RtlStringCchCopyW(Common->ImageName, wcslen(name) + 1, name); + + Common->ImageType = type; + Common->cxDesired = desiredx; + Common->cyDesired = desiredy; + Common->fuFlags = flags; + + UserLeaveCo(); + + Status = KeUserModeCallback(USER32_CALLBACK_LOADIMAGE, + Argument, + ArgumentLength, + &ResultPointer, + &ResultLength); + + + UserEnterCo(); + + if (NT_SUCCESS(Status)) + { + Handle = *(HANDLE*)ResultPointer; + } + else + { + ERR("LoadImage callback failed\n"); + Handle = NULL; + } + + IntCbFreeMemory(Argument); + + return Handle; +} + HANDLE FASTCALL co_IntCopyImage(HANDLE hnd, UINT type, INT desiredx, INT desiredy, UINT flags) { diff --git a/win32ss/user/ntuser/callback.h b/win32ss/user/ntuser/callback.h index dde7152a95250..ba66fe9d5aaab 100644 --- a/win32ss/user/ntuser/callback.h +++ b/win32ss/user/ntuser/callback.h @@ -70,6 +70,7 @@ BOOL APIENTRY co_IntGetCharsetInfo(LCID Locale, PCHARSETINFO pCs); +HANDLE FASTCALL co_IntLoadImage(LPCWSTR,UINT,INT,INT,UINT); HANDLE FASTCALL co_IntCopyImage(HANDLE,UINT,INT,INT,UINT); BOOL FASTCALL co_IntSetWndIcons(VOID); diff --git a/win32ss/user/ntuser/cursoricon.c b/win32ss/user/ntuser/cursoricon.c index f0fdbac223e32..480b129fe4d88 100644 --- a/win32ss/user/ntuser/cursoricon.c +++ b/win32ss/user/ntuser/cursoricon.c @@ -85,6 +85,9 @@ IntInsertCursorIntoList( NT_ASSERT((pcur->CURSORF_flags & (CURSORF_GLOBAL|CURSORF_LRSHARED)) != 0); NT_ASSERT((pcur->CURSORF_flags & CURSORF_LINKED) == 0); + /* Don't cache *.ani */ + if (pcur->CURSORF_flags & CURSORF_ACON) return; + /* Get the right list head */ ppcurHead = (pcur->CURSORF_flags & CURSORF_GLOBAL) ? &gcurFirst : &ppi->pCursorCache; @@ -374,7 +377,8 @@ FreeCurIconObject( UserDereferenceObject(AniCurIcon->aspcur[i]); NT_VERIFY(IntDestroyCurIconObject(AniCurIcon->aspcur[i]) == TRUE); } - ExFreePoolWithTag(AniCurIcon->aspcur, USERTAG_CURSOR); + if (AniCurIcon->aspcur) + ExFreePoolWithTag(AniCurIcon->aspcur, USERTAG_CURSOR); } if (CurIcon->CURSORF_flags & CURSORF_LRSHARED) @@ -852,6 +856,47 @@ NtUserDestroyCursor( return ret; } +PCURICON_OBJECT +UserFindExistingCursorIcon( + _In_ PCURICON_OBJECT CurIcon, + _In_ RTL_ATOM atomModName, + _In_ PUNICODE_STRING pustrRsrc, + _In_ FINDEXISTINGCURICONPARAM* param) +{ + for (; CurIcon; CurIcon = CurIcon->pcurNext) + { + /* Icon/cursor */ + if (param->bIcon != is_icon(CurIcon)) + { + 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(pustrRsrc->Buffer)) + { + /* One is an INT resource and the other is not -> no match */ + continue; + } + + if (IS_INTRESOURCE(CurIcon->strName.Buffer)) + { + if (CurIcon->strName.Buffer == pustrRsrc->Buffer) + { + /* INT resources match */ + return CurIcon; + } + } + else if (RtlEqualUnicodeString(pustrRsrc, &CurIcon->strName, TRUE)) + { + /* Resource name strings match */ + return CurIcon; + } + } + } + return NULL; +} /* * @implemented @@ -900,82 +945,9 @@ NtUserFindExistingCursorIcon( } UserEnterShared(); - CurIcon = pProcInfo->pCursorCache; - 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; - } - - /* 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; - } - } + CurIcon = UserFindExistingCursorIcon(pProcInfo->pCursorCache, atomModName, &ustrRsrcSafe, ¶mSafe); + if (!CurIcon) + CurIcon = UserFindExistingCursorIcon(gcurFirst, atomModName, &ustrRsrcSafe, ¶mSafe); if (CurIcon) Ret = UserHMGetHandle(CurIcon); UserLeave(); @@ -2202,9 +2174,8 @@ NtUserSetSystemCursor( HCURSOR hcur, DWORD id) { - PCURICON_OBJECT pcur, pcurOrig = NULL; + PCURICON_OBJECT pcur; int i; - PPROCESSINFO ppi; BOOL Ret = FALSE; UserEnterExclusive(); @@ -2222,31 +2193,27 @@ NtUserSetSystemCursor( 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; - pcur->head.ppi = NULL; - IntInsertCursorIntoList(pcur); - Ret = TRUE; - } - break; + /* Check if cursor is already set */ + if (pcur == gasyscur[i].handle) + { + ERR("Cursor %p is already set\n", pcur); + Ret = TRUE; + goto Exit; + } + + pcur->CURSORF_flags |= CURSORF_GLOBAL; + if ((pcur->CURSORF_flags & CURSORF_LINKED) != 0) + pcur->CURSORF_flags &= ~CURSORF_LINKED; + gasyscur[i].handle = pcur; + IntInsertCursorIntoList(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(); diff --git a/win32ss/user/ntuser/defwnd.c b/win32ss/user/ntuser/defwnd.c index a9f4aa0bb34ab..b8f3514f13d2d 100644 --- a/win32ss/user/ntuser/defwnd.c +++ b/win32ss/user/ntuser/defwnd.c @@ -242,12 +242,21 @@ co_IntFindChildWindowToOwner(PWND Root, PWND Owner) LRESULT DefWndHandleSetCursor(PWND pWnd, WPARAM wParam, LPARAM lParam) { - PWND pwndPopUP = NULL; + PWND pwndCur, pwndPopUP = NULL; WORD Msg = HIWORD(lParam); + HWND hwndCur = (HWND)wParam; - /* Not for child windows. */ - if (UserHMGetHandle(pWnd) != (HWND)wParam) + /* Validate the window */ + if (!hwndCur) + return FALSE; + pwndCur = UserGetWindowObject(hwndCur); + if (!pwndCur) + return FALSE; + + /* Handle window menu mode */ + if (Msg == 0) { + IntSystemSetCursor(SYSTEMCUR(ARROW)); return FALSE; } @@ -306,9 +315,9 @@ DefWndHandleSetCursor(PWND pWnd, WPARAM wParam, LPARAM lParam) case HTCLIENT: { - if (pWnd->pcls->spcur) + if (pwndCur->pcls->spcur) { - IntSystemSetCursor(pWnd->pcls->spcur); + IntSystemSetCursor(pwndCur->pcls->spcur); } return FALSE; } @@ -356,8 +365,24 @@ DefWndHandleSetCursor(PWND pWnd, WPARAM wParam, LPARAM lParam) IntSystemSetCursor(SYSTEMCUR(SIZENESW)); return TRUE; } + case HTGROWBOX: + { + IntSystemSetCursor(SYSTEMCUR(SIZEALL)); + return TRUE; + } + case HTHELP: + { + if (pWnd->style & WS_MAXIMIZE) + { + break; + } + IntSystemSetCursor(SYSTEMCUR(HELP)); + return TRUE; + } + default: + IntSystemSetCursor(SYSTEMCUR(ARROW)); + break; } - IntSystemSetCursor(SYSTEMCUR(ARROW)); return FALSE; } diff --git a/win32ss/user/ntuser/desktop.c b/win32ss/user/ntuser/desktop.c index 6ccb291ac8231..7bfca2c1cd0aa 100644 --- a/win32ss/user/ntuser/desktop.c +++ b/win32ss/user/ntuser/desktop.c @@ -35,7 +35,6 @@ DWORD gdwNOIOSectionSize = 128; // A guess, for one or more of the first thre PDESKTOP gpdeskInputDesktop = NULL; HDC ScreenDeviceContext = NULL; PTHREADINFO gptiDesktopThread = NULL; -HCURSOR gDesktopCursor = NULL; PKEVENT gpDesktopThreadStartedEvent = NULL; /* OBJECT CALLBACKS **********************************************************/ @@ -1440,7 +1439,7 @@ DesktopWindowProc(PWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *lRe { PAINTSTRUCT Ps; ULONG Value; - //ERR("DesktopWindowProc\n"); + TRACE("DesktopWindowProc\n"); *lResult = 0; @@ -1485,25 +1484,6 @@ DesktopWindowProc(PWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *lRe co_UserRedrawWindow(Wnd, NULL, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN); return TRUE; - case WM_SETCURSOR: - { - PCURICON_OBJECT pcurOld, pcurNew; - pcurNew = UserGetCurIconObject(gDesktopCursor); - if (!pcurNew) - { - return TRUE; - } - - pcurNew->CURSORF_flags |= CURSORF_CURRENT; - pcurOld = UserSetCursor(pcurNew, FALSE); - if (pcurOld) - { - pcurOld->CURSORF_flags &= ~CURSORF_CURRENT; - UserDereferenceObject(pcurOld); - } - return TRUE; - } - case WM_WINDOWPOSCHANGING: { PWINDOWPOS pWindowPos = (PWINDOWPOS)lParam; @@ -1514,6 +1494,7 @@ DesktopWindowProc(PWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *lRe } break; } + default: TRACE("DWP calling IDWP Msg %d\n",Msg); //*lResult = IntDefWindowProc(Wnd, Msg, wParam, lParam, FALSE); @@ -1554,7 +1535,10 @@ VOID NTAPI DesktopThreadMain(VOID) /* Register system classes. This thread does not belong to any desktop so the classes will be allocated from the shared heap */ - UserRegisterSystemClasses(); + if (!(gptiDesktopThread->ppi->W32PF_flags & W32PF_CLASSESREGISTERED)) + { + UserRegisterSystemClasses(); + } KeSetEvent(gpDesktopThreadStartedEvent, IO_NO_INCREMENT, FALSE); diff --git a/win32ss/user/ntuser/msgqueue.c b/win32ss/user/ntuser/msgqueue.c index e26a3b6595262..4ac045c0109cc 100644 --- a/win32ss/user/ntuser/msgqueue.c +++ b/win32ss/user/ntuser/msgqueue.c @@ -17,7 +17,8 @@ static PPAGED_LOOKASIDE_LIST pgMessageLookasideList; static PPAGED_LOOKASIDE_LIST pgSendMsgLookasideList; INT PostMsgCount = 0; INT SendMsgCount = 0; -PUSER_MESSAGE_QUEUE gpqCursor; +PUSER_MESSAGE_QUEUE gpqCursor = NULL; +PACON gAniCursor = NULL; ULONG_PTR gdwMouseMoveExtraInfo = 0; DWORD gdwMouseMoveTimeStamp = 0; LIST_ENTRY usmList; @@ -136,19 +137,22 @@ UserSetCursor( { /* Call GDI to set the new screen cursor */ PCURICON_OBJECT CursorFrame = NewCursor; - if(NewCursor->CURSORF_flags & CURSORF_ACON) + if (NewCursor->CURSORF_flags & CURSORF_ACON) { - FIXME("Should animate the cursor, using only the first frame now.\n"); - CursorFrame = ((PACON)NewCursor)->aspcur[0]; + gAniCursor = (PACON)NewCursor; + IntSetTimer(pWnd, ID_EVENT_SYSTIMER_ANIMATECURSOR, ((PACON)NewCursor)->ajifRate[((PACON)NewCursor)->iicur] * 100 / 6, SystemTimerProc, TMRF_SYSTEM); + CursorFrame = ((PACON)NewCursor)->aspcur[((PACON)NewCursor)->aicur[((PACON)NewCursor)->iicur]]; } GreSetPointerShape(hdcScreen, - CursorFrame->hbmAlpha ? NULL : NewCursor->hbmMask, - CursorFrame->hbmAlpha ? NewCursor->hbmAlpha : NewCursor->hbmColor, + CursorFrame->hbmAlpha ? NULL : CursorFrame->hbmMask, + CursorFrame->hbmAlpha ? CursorFrame->hbmAlpha : CursorFrame->hbmColor, CursorFrame->xHotspot, CursorFrame->yHotspot, gpsi->ptCursor.x, gpsi->ptCursor.y, - CursorFrame->hbmAlpha ? SPS_ALPHA : 0); + NewCursor->CURSORF_flags & CURSORF_ACON ? + (SPS_ANIMATEUPDATE | (CursorFrame->hbmAlpha ? SPS_ALPHA : 0)) : + (CursorFrame->hbmAlpha ? SPS_ALPHA : 0)); } else /* Note: OldCursor != NewCursor so we have to hide cursor */ { @@ -680,7 +684,8 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook MessageQueue->CursorObject->yHotspot, gpsi->ptCursor.x, gpsi->ptCursor.y, - MessageQueue->CursorObject->hbmAlpha ? SPS_ALPHA : 0); + MessageQueue->CursorObject->CURSORF_flags & CURSORF_ACON ? + SPS_ANIMATEUPDATE : (MessageQueue->CursorObject->hbmAlpha ? SPS_ALPHA : 0)); } else GreMovePointer(hdcScreen, Msg->pt.x, Msg->pt.y); diff --git a/win32ss/user/ntuser/nonclient.c b/win32ss/user/ntuser/nonclient.c index 796f577269062..afeaece6772a7 100644 --- a/win32ss/user/ntuser/nonclient.c +++ b/win32ss/user/ntuser/nonclient.c @@ -2100,6 +2100,13 @@ GetNCHitEx(PWND pWnd, POINT pt) rcWindow.right -= UserGetSystemMetrics(SM_CXSIZE); if (pt.x > rcWindow.right) return HTMINBUTTON; } + + /* Check help button */ + if (ExStyle & WS_EX_CONTEXTHELP && !(ExStyle & WS_EX_TOOLWINDOW)) + { + rcWindow.right -= UserGetSystemMetrics(SM_CXSIZE); + if (pt.x > rcWindow.right) return HTHELP; + } } return HTCAPTION; } diff --git a/win32ss/user/ntuser/sysparams.c b/win32ss/user/ntuser/sysparams.c index 95bfbe7ca78e3..ff15eecc84b8e 100644 --- a/win32ss/user/ntuser/sysparams.c +++ b/win32ss/user/ntuser/sysparams.c @@ -58,6 +58,23 @@ static const WCHAR* VAL_HOVERWIDTH = L"MouseHoverWidth"; static const WCHAR* VAL_HOVERHEIGHT = L"MouseHoverHeight"; static const WCHAR* VAL_SENSITIVITY = L"MouseSensitivity"; +static const WCHAR* KEY_CURSORS = L"Control Panel\\Cursors"; +static const WCHAR* VAL_APPSTARTING = L"AppStarting"; +static const WCHAR* VAL_ARROW = L"Arrow"; +static const WCHAR* VAL_CROSS = L"Crosshair"; +static const WCHAR* VAL_HAND = L"Hand"; +static const WCHAR* VAL_HELP = L"Help"; +static const WCHAR* VAL_IBEAM = L"IBeam"; +static const WCHAR* VAL_NO = L"No"; +//static const WCHAR* VAL_NWPEN = L"NWPen"; +static const WCHAR* VAL_SIZEALL = L"SizeAll"; +static const WCHAR* VAL_SIZENESW = L"SizeNESW"; +static const WCHAR* VAL_SIZENS = L"SizeNS"; +static const WCHAR* VAL_SIZENWSE = L"SizeNWSE"; +static const WCHAR* VAL_SIZEWE = L"SizeWE"; +static const WCHAR* VAL_UPARROW = L"UpArrow"; +static const WCHAR* VAL_WAIT = L"Wait"; + static const WCHAR* KEY_DESKTOP = L"Control Panel\\Desktop"; static const WCHAR* VAL_SCRTO = L"ScreenSaveTimeOut"; static const WCHAR* VAL_SCRNSV = L"SCRNSAVE.EXE"; @@ -130,6 +147,13 @@ SpiLoadInt(PCWSTR pwszKey, PCWSTR pwszValue, INT iValue) return _wtoi(awcBuffer); } +static +BOOL +SpiLoadString(PCWSTR pwszKey, PCWSTR pwszValue, LPWSTR pwszBuffer, ULONG cbSize) +{ + return RegReadUserSetting(pwszKey, pwszValue, REG_EXPAND_SZ, pwszBuffer, cbSize); +} + static DWORD SpiLoadUserPrefMask(DWORD dValue) @@ -163,6 +187,60 @@ SpiLoadMouse(PCWSTR pwszValue, INT iValue) return SpiLoadInt(KEY_MOUSE, pwszValue, iValue); } +static +BOOL +SpiLoadCursor(PCWSTR pwszValue, LPWSTR pwszBuffer, ULONG cbSize) +{ + return SpiLoadString(KEY_CURSORS, pwszValue, pwszBuffer, cbSize); +} + +static +VOID +SpiReloadSystemCursor(PCWSTR pwszValue, DWORD dwId) +{ + WCHAR wchCursorPath[MAX_PATH]; + HANDLE hCursor; + ULONG cbSize; + + cbSize = sizeof(wchCursorPath); + if (!SpiLoadCursor(pwszValue, wchCursorPath, cbSize)) + { + ERR("Failed to get cursor path from registry for %ls\n", pwszValue); + return; + } + hCursor = co_IntLoadImage(wchCursorPath, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE); + if (!hCursor) + { + ERR("Failed to load cursor %ls\n", wchCursorPath); + return; + } + if (!NtUserSetSystemCursor(hCursor, dwId)) + { + ERR("NtUserSetSystemCursor failed with error %d\n", EngGetLastError()); + return; + } +} + +static +VOID +SpiReloadAllSystemCursors(VOID) +{ + SpiReloadSystemCursor(VAL_ARROW, OCR_NORMAL); + SpiReloadSystemCursor(VAL_IBEAM, OCR_IBEAM); + SpiReloadSystemCursor(VAL_WAIT, OCR_WAIT); + SpiReloadSystemCursor(VAL_CROSS, OCR_CROSS); + SpiReloadSystemCursor(VAL_UPARROW, OCR_UP); + SpiReloadSystemCursor(VAL_SIZENWSE, OCR_SIZENWSE); + SpiReloadSystemCursor(VAL_SIZENESW, OCR_SIZENESW); + SpiReloadSystemCursor(VAL_SIZEWE, OCR_SIZEWE); + SpiReloadSystemCursor(VAL_SIZENS, OCR_SIZENS); + SpiReloadSystemCursor(VAL_SIZEALL, OCR_SIZEALL); + SpiReloadSystemCursor(VAL_NO, OCR_NO); + SpiReloadSystemCursor(VAL_HAND, OCR_HAND); + SpiReloadSystemCursor(VAL_APPSTARTING, OCR_APPSTARTING); + SpiReloadSystemCursor(VAL_HELP, OCR_HELP); +} + static INT SpiLoadMetric(PCWSTR pwszValue, INT iValue) @@ -348,6 +426,9 @@ SpiUpdatePerUserSystemParameters(VOID) /* Update SystemMetrics */ InitMetrics(); + /* Load system cursors from registry */ + SpiReloadAllSystemCursors(); + if (gbSpiInitialized && gpsi) { if (gspv.bKbdPref) gpsi->dwSRVIFlags |= SRVINFO_KBDPREF; @@ -1446,7 +1527,7 @@ SpiGetSet(UINT uiAction, UINT uiParam, PVOID pvParam, FLONG fl) return SpiSetBool(&gspv.bPwrOffActive, uiParam, KEY_DESKTOP, L"PowerOffActive", fl); case SPI_SETCURSORS: - ERR("SPI_SETCURSORS is unimplemented\n"); + SpiReloadAllSystemCursors(); break; case SPI_SETICONS: diff --git a/win32ss/user/ntuser/timer.c b/win32ss/user/ntuser/timer.c index 4a9fd3c44ae52..93680d3085714 100644 --- a/win32ss/user/ntuser/timer.c +++ b/win32ss/user/ntuser/timer.c @@ -24,6 +24,8 @@ static RTL_BITMAP WindowLessTimersBitMap; static PVOID WindowLessTimersBitMapBuffer; static ULONG HintIndex = 1; +extern PACON gAniCursor; + ERESOURCE TimerLock; #define IntLockWindowlessTimerBitmap() \ @@ -356,6 +358,28 @@ SystemTimerProc(HWND hwnd, } return; + case ID_EVENT_SYSTIMER_ANIMATECURSOR: + { + PACON pacon = gAniCursor; + PCURICON_OBJECT pcurFrame; + if (!pacon || !pacon->aspcur || !pacon->aicur || pacon->iicur < 0) + { + ERR("Killing the timer... ;(\n"); + break; + } + pcurFrame = pacon->aspcur[pacon->aicur[pacon->iicur]]; + if (!pcurFrame) + { + ERR("Killing the timer... ;(\n"); + break; + } + IntSystemSetCursor(pcurFrame); + pacon->iicur += 1; + if (pacon->iicur >= pacon->cicur) + pacon->iicur = 0; + } + return; + default: ERR("System Timer Proc invalid id %u!\n", idEvent); break; diff --git a/win32ss/user/ntuser/timer.h b/win32ss/user/ntuser/timer.h index 8ca2fe8ebd064..7fed6d312872b 100644 --- a/win32ss/user/ntuser/timer.h +++ b/win32ss/user/ntuser/timer.h @@ -25,6 +25,7 @@ typedef struct _TIMER #define TMRF_TIFROMWND 0x0040 #define ID_EVENT_SYSTIMER_MOUSEHOVER ID_TME_TIMER +#define ID_EVENT_SYSTIMER_ANIMATECURSOR (0xFFF9) #define ID_EVENT_SYSTIMER_FLASHWIN (0xFFF8) #define ID_EVENT_SYSTIMER_TRACKWIN (0xFFF7) #define ID_EVENT_SYSTIMER_ANIMATEDFADE (0xFFF6) diff --git a/win32ss/user/user32/misc/desktop.c b/win32ss/user/user32/misc/desktop.c index 862ff16503437..634924afca238 100644 --- a/win32ss/user/user32/misc/desktop.c +++ b/win32ss/user/user32/misc/desktop.c @@ -63,9 +63,6 @@ DesktopWndProcW(HWND Wnd, break; } - case WM_SETCURSOR: - return (LRESULT)SetCursor(LoadCursorW(0, (LPCWSTR)IDC_ARROW)); - default: return DefWindowProcW(Wnd, Msg, wParam, lParam); } diff --git a/win32ss/user/user32/misc/dllmain.c b/win32ss/user/user32/misc/dllmain.c index c3c8451985a62..5f221e9dbea34 100644 --- a/win32ss/user/user32/misc/dllmain.c +++ b/win32ss/user/user32/misc/dllmain.c @@ -212,6 +212,9 @@ PVOID apfnDispatch[USER32_CALLBACK_COUNT] = #undef DEFINE_USER32_CALLBACK +VOID +LoadSystemCursors(VOID); + VOID WINAPI GdiProcessSetup(VOID); @@ -306,6 +309,11 @@ ClientThreadSetupHelper(BOOL IsCallback) TRACE("Checkpoint (MenuInit)\n"); if (MenuInit()) { + /* Load system cursors */ + TRACE("Checkpoint (CursorsInit)\n"); + //if (gfServerProcess) // FIXME + LoadSystemCursors(); + TRACE("Checkpoint initialization done OK\n"); InitializeCriticalSection(&U32AccelCacheLock); LoadAppInitDlls(); diff --git a/win32ss/user/user32/windows/cursoricon.c b/win32ss/user/user32/windows/cursoricon.c index 531c29abe576f..f134ce81faea7 100644 --- a/win32ss/user/user32/windows/cursoricon.c +++ b/win32ss/user/user32/windows/cursoricon.c @@ -16,59 +16,125 @@ WINE_DECLARE_DEBUG_CHANNEL(icon); #undef MAKEINTRESOURCE #define MAKEINTRESOURCE MAKEINTRESOURCEW -/************* USER32 INTERNAL FUNCTIONS **********/ +typedef struct +{ + LPCWSTR resource_name; + HANDLE cursor; + LPCWSTR registry_name; +} SYSTEMCURSOR; -VOID LoadSystemCursors(VOID) +static SYSTEMCURSOR g_SysCursors[] = { - 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); - } -} + {IDC_ARROW, NULL, L"Arrow" }, + {IDC_IBEAM, NULL, L"IBeam" }, + {IDC_WAIT, NULL, L"Wait" }, + {IDC_CROSS, NULL, L"Crosshair" }, + {IDC_UPARROW, NULL, L"UpArrow" }, + {IDC_ICON, NULL, L"" }, + {IDC_SIZE, NULL, L"" }, + {IDC_SIZENWSE, NULL, L"SizeNWSE" }, + {IDC_SIZENESW, NULL, L"SizeNESW" }, + {IDC_SIZEWE, NULL, L"SizeWE" }, + {IDC_SIZENS, NULL, L"SizeNS" }, + {IDC_SIZEALL, NULL, L"SizeAll" }, + {IDC_NO, NULL, L"No" }, + {IDC_HAND, NULL, L"Hand" }, + {IDC_APPSTARTING,NULL, L"AppStarting" }, + {IDC_HELP, NULL, L"Help" }, +}; -/* This callback routine is called directly after switching to gui mode */ -NTSTATUS -WINAPI -User32SetupDefaultCursors(PVOID Arguments, - ULONG ArgumentLength) +/************* USER32 INTERNAL FUNCTIONS **********/ + +VOID +LoadSystemCursors(VOID) { - BOOL *DefaultCursor = (BOOL*)Arguments; - HCURSOR hCursor; + UINT i; + LSTATUS result; + HKEY hCursorsKey; + DWORD type, size = MAX_PATH * sizeof(WCHAR); + WCHAR szCursorPath[MAX_PATH], szExpanded[MAX_PATH]; - /* Load system cursors first */ - LoadSystemCursors(); + for (i = 0; i < _countof(g_SysCursors); i++) + { + /* Try to load defaults first */ + g_SysCursors[i].cursor = LoadImageW(NULL, g_SysCursors[i].resource_name, IMAGE_CURSOR, 0, 0, LR_SHARED | LR_DEFAULTSIZE); + TRACE("Cursor handle %p\n", g_SysCursors[i].cursor); + } - if(*DefaultCursor) + result = RegOpenKeyExW(HKEY_CURRENT_USER, + L"Control Panel\\Cursors", + 0, + KEY_READ, + &hCursorsKey); + if (result == ERROR_SUCCESS) { - /* set default cursor */ - hCursor = LoadCursorW(0, IDC_ARROW); - SetCursor(hCursor); + for (i = 0; i < _countof(g_SysCursors); i++) + { + result = RegQueryValueExW(hCursorsKey, + g_SysCursors[i].registry_name, + NULL, + &type, + (LPBYTE)szCursorPath, + &size); + if (result == ERROR_SUCCESS && type == REG_EXPAND_SZ) + { + ExpandEnvironmentStringsW(szCursorPath, + szExpanded, + _countof(szExpanded)); + + g_SysCursors[i].cursor = LoadImageW(NULL, szExpanded, IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE); + TRACE("Cursor name %S, cursor handle %p\n", g_SysCursors[i].registry_name, g_SysCursors[i].cursor); + } + } + RegCloseKey(hCursorsKey); } - else +} + +HANDLE +GetSystemCursor( + _In_ LPCWSTR lpCursorName) +{ + UINT i; + for (i = 0; i < _countof(g_SysCursors); i++) { - /* FIXME load system cursor scheme */ - SetCursor(0); - hCursor = LoadCursorW(0, IDC_ARROW); - SetCursor(hCursor); + if (lpCursorName == g_SysCursors[i].resource_name) + { + TRACE("Match!!\n"); + return g_SysCursors[i].cursor; + } } + TRACE("Not found :(\n"); + return NULL; +} - return(ZwCallbackReturn(&hCursor, sizeof(HCURSOR), STATUS_SUCCESS)); +/* This callback routine is called directly after switching to gui mode */ +NTSTATUS +WINAPI +User32SetupDefaultCursors(PVOID Arguments, + ULONG ArgumentLength) +{ + PLOADCURSORS_CALLBACK_ARGUMENTS Common = Arguments; + + ERR("Loading System Cursors\n"); + + Common->hCursorArrow = LoadImageW(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); + Common->hCursorIbeam = LoadImageW(NULL, IDC_IBEAM, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); + Common->hCursorWait = LoadImageW(NULL, IDC_WAIT, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); + Common->hCursorCross = LoadImageW(NULL, IDC_CROSS, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); + Common->hCursorUp = LoadImageW(NULL, IDC_UPARROW, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); + Common->hCursorIcon = LoadImageW(NULL, IDC_ICON, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); + Common->hCursorSize = LoadImageW(NULL, IDC_SIZE, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); + Common->hCursorSizeNwse = LoadImageW(NULL, IDC_SIZENWSE, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); + Common->hCursorSizeNesw = LoadImageW(NULL, IDC_SIZENESW, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); + Common->hCursorSizeWe = LoadImageW(NULL, IDC_SIZEWE, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); + Common->hCursorSizeNs = LoadImageW(NULL, IDC_SIZENS, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); + Common->hCursorSizeAll = LoadImageW(NULL, IDC_SIZEALL, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); + Common->hCursorNo = LoadImageW(NULL, IDC_NO, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); + Common->hCursorHand = LoadImageW(NULL, IDC_HAND, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); + Common->hCursorAppStarting = LoadImageW(NULL, IDC_APPSTARTING, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); + Common->hCursorHelp = LoadImageW(NULL, IDC_HELP, IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); + + return ZwCallbackReturn(Arguments, ArgumentLength, STATUS_SUCCESS); } BOOL get_icon_size(HICON hIcon, SIZE *size) @@ -1372,7 +1438,6 @@ BITMAP_LoadImageW( return hbmpRet; } - static HANDLE CURSORICON_LoadFromFileW( @@ -1387,6 +1452,7 @@ CURSORICON_LoadFromFileW( const CURSORICONFILEDIR *dir; DWORD filesize = 0; LPBYTE bits; + BOOL bAnimated = FALSE; HANDLE hCurIcon = NULL; CURSORDATA cursorData; @@ -1399,8 +1465,10 @@ CURSORICON_LoadFromFileW( /* Check for .ani. */ if (memcmp( bits, "RIFF", 4 ) == 0) { - UNIMPLEMENTED; - goto end; + CURSORICON_GetCursorDataFromANI(&cursorData, bits, filesize, fuLoad); + cursorData.CURSORF_flags = (CURSORF_FROMRESOURCE | CURSORF_LRSHARED | CURSORF_ACON); + bAnimated = TRUE; + goto create; } dir = (CURSORICONFILEDIR*) bits; @@ -1422,12 +1490,13 @@ CURSORICON_LoadFromFileW( /* Do the dance */ if(!CURSORICON_GetCursorDataFromBMI(&cursorData, (BITMAPINFO*)(&bits[entry->dwDIBOffset]))) - { - ERR("Failing File is \n '%S'.\n", lpszName); - goto end; - } + { + ERR("Failing File is \n '%S'.\n", lpszName); + goto end; + } - hCurIcon = NtUserxCreateEmptyCurObject(FALSE); +create: + hCurIcon = NtUserxCreateEmptyCurObject(bAnimated); if(!hCurIcon) goto end; @@ -2130,7 +2199,7 @@ HCURSOR WINAPI LoadCursorA( IMAGE_CURSOR, 0, 0, - LR_SHARED | LR_DEFAULTSIZE ); + LR_SHARED | LR_DEFAULTSIZE); } HCURSOR WINAPI LoadCursorW( @@ -2138,14 +2207,20 @@ HCURSOR WINAPI LoadCursorW( _In_ LPCWSTR lpCursorName ) { + HCURSOR hCursor; + TRACE("%p, %s\n", hInstance, debugstr_w(lpCursorName)); - return LoadImageW(hInstance, + // HACK! + hCursor = GetSystemCursor(lpCursorName); + if (!hCursor)// + hCursor = LoadImageW(hInstance, lpCursorName, IMAGE_CURSOR, 0, 0, - LR_SHARED | LR_DEFAULTSIZE ); + LR_SHARED | LR_DEFAULTSIZE); + return hCursor; } HCURSOR WINAPI LoadCursorFromFileA( @@ -2257,6 +2332,36 @@ HANDLE WINAPI LoadImageW( return NULL; } +NTSTATUS WINAPI +User32CallLoadImageFromKernel(PVOID Arguments, ULONG ArgumentLength) +{ + PLOADIMAGE_CALLBACK_ARGUMENTS Common; + HANDLE Result; + DWORD Ret; + WCHAR ExpandedFilePath[MAX_PATH]; + Common = (PLOADIMAGE_CALLBACK_ARGUMENTS) Arguments; + + TRACE("User32CallLoadImageFromKernel called\n"); + + Ret = ExpandEnvironmentStringsW(Common->ImageName, + ExpandedFilePath, + _countof(ExpandedFilePath)); + if (!Ret) + { + ERR("ExpandEnvironmentStringsW failed with error %d\n", GetLastError()); + return ZwCallbackReturn(NULL, 0, STATUS_UNSUCCESSFUL); + } + + Result = LoadImageW(NULL, + ExpandedFilePath, + Common->ImageType, + Common->cxDesired, + Common->cyDesired, + Common->fuFlags); + + return ZwCallbackReturn(&Result, sizeof(HANDLE), STATUS_SUCCESS); +} + int WINAPI LookupIconIdFromDirectory( _In_ PBYTE presbits, _In_ BOOL fIcon diff --git a/win32ss/user/user32/windows/dialog.c b/win32ss/user/user32/windows/dialog.c index 784b43b9493cb..858a03e7a73d0 100644 --- a/win32ss/user/user32/windows/dialog.c +++ b/win32ss/user/user32/windows/dialog.c @@ -842,6 +842,8 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate, template.style |= DS_3DLOOK; if (template.style & DS_MODALFRAME) template.exStyle |= WS_EX_DLGMODALFRAME; + if (template.style & DS_CONTEXTHELP) + template.exStyle |= WS_EX_CONTEXTHELP; if ((template.style & DS_CONTROL) || !(template.style & WS_CHILD)) template.exStyle |= WS_EX_CONTROLPARENT; AdjustWindowRectEx( &rect, template.style, (hMenu != 0), template.exStyle );