diff --git a/reactos/win32ss/include/callback.h b/reactos/win32ss/include/callback.h index 2149242005f..d491f96c9c8 100644 --- a/reactos/win32ss/include/callback.h +++ b/reactos/win32ss/include/callback.h @@ -11,7 +11,8 @@ #define USER32_CALLBACK_CLIENTTHREADSTARTUP (7) #define USER32_CALLBACK_CLIENTLOADLIBRARY (8) #define USER32_CALLBACK_GETCHARSETINFO (9) -#define USER32_CALLBACK_MAXIMUM (9) +#define USER32_CALLBACK_COPYIMAGE (10) +#define USER32_CALLBACK_MAXIMUM (10) typedef struct _WINDOWPROC_CALLBACK_ARGUMENTS { @@ -81,6 +82,15 @@ typedef struct _LOADMENU_CALLBACK_ARGUMENTS WCHAR MenuName[1]; } LOADMENU_CALLBACK_ARGUMENTS, *PLOADMENU_CALLBACK_ARGUMENTS; +typedef struct _COPYIMAGE_CALLBACK_ARGUMENTS +{ + HANDLE hImage; + UINT uType; + int cxDesired; + int cyDesired; + UINT fuFlags; +} COPYIMAGE_CALLBACK_ARGUMENTS, *PCOPYIMAGE_CALLBACK_ARGUMENTS; + typedef struct _CLIENT_LOAD_LIBRARY_ARGUMENTS { UNICODE_STRING strLibraryName; @@ -95,6 +105,8 @@ typedef struct _GET_CHARSET_INFO CHARSETINFO Cs; } GET_CHARSET_INFO, *PGET_CHARSET_INFO; +NTSTATUS WINAPI +User32CallCopyImageFromKernel(PVOID Arguments, ULONG ArgumentLength); NTSTATUS WINAPI User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength); NTSTATUS WINAPI diff --git a/reactos/win32ss/include/ntuser.h b/reactos/win32ss/include/ntuser.h index b83515328e1..e64fa9dfa30 100644 --- a/reactos/win32ss/include/ntuser.h +++ b/reactos/win32ss/include/ntuser.h @@ -476,6 +476,9 @@ typedef struct _CLS HANDLE hIconSm; /* FIXME - Use pointer! */ //PCURSOR spicnSm; + //// ReactOS dosn't suppot cache icons. + HICON hIconSmIntern; /* Internal small icon, derived from hIcon */ + //// UINT Unicode : 1; // !CSF_ANSIPROC UINT Global : 1; // CS_GLOBALCLASS or CSF_SERVERSIDEPROC UINT MenuNameIsString : 1; diff --git a/reactos/win32ss/user/ntuser/callback.c b/reactos/win32ss/user/ntuser/callback.c index fc38fb583f6..833da09d684 100644 --- a/reactos/win32ss/user/ntuser/callback.c +++ b/reactos/win32ss/user/ntuser/callback.c @@ -881,6 +881,59 @@ co_IntClientThreadSetup(VOID) return Status; } + +HANDLE FASTCALL +co_IntCopyImage(HANDLE hnd, UINT type, INT desiredx, INT desiredy, UINT flags) +{ + HANDLE Handle; + NTSTATUS Status; + ULONG ArgumentLength, ResultLength; + PVOID Argument, ResultPointer; + PCOPYIMAGE_CALLBACK_ARGUMENTS Common; + + ArgumentLength = ResultLength = 0; + Argument = ResultPointer = NULL; + + ArgumentLength = sizeof(COPYIMAGE_CALLBACK_ARGUMENTS); + + Argument = IntCbAllocateMemory(ArgumentLength); + if (NULL == Argument) + { + ERR("CopyImage callback failed: out of memory\n"); + return 0; + } + Common = (PCOPYIMAGE_CALLBACK_ARGUMENTS) Argument; + + Common->hImage = hnd; + Common->uType = type; + Common->cxDesired = desiredx; + Common->cyDesired = desiredy; + Common->fuFlags = flags; + + UserLeaveCo(); + + Status = KeUserModeCallback(USER32_CALLBACK_COPYIMAGE, + Argument, + ArgumentLength, + &ResultPointer, + &ResultLength); + + + UserEnterCo(); + + Handle = *(HANDLE*)ResultPointer; + + IntCbFreeMemory(Argument); + + if (!NT_SUCCESS(Status)) + { + ERR("CopyImage callback failed!\n"); + return 0; + } + + return Handle; +} + BOOL APIENTRY co_IntGetCharsetInfo(LCID Locale, PCHARSETINFO pCs) diff --git a/reactos/win32ss/user/ntuser/callback.h b/reactos/win32ss/user/ntuser/callback.h index 68821294c58..5537e726ec8 100644 --- a/reactos/win32ss/user/ntuser/callback.h +++ b/reactos/win32ss/user/ntuser/callback.h @@ -67,3 +67,5 @@ co_IntClientLoadLibrary(PUNICODE_STRING strLibName, BOOL APIENTRY co_IntGetCharsetInfo(LCID Locale, PCHARSETINFO pCs); + +HANDLE FASTCALL co_IntCopyImage(HANDLE,UINT,INT,INT,UINT); diff --git a/reactos/win32ss/user/ntuser/class.c b/reactos/win32ss/user/ntuser/class.c index 2f29ec18c11..0bc2496e274 100644 --- a/reactos/win32ss/user/ntuser/class.c +++ b/reactos/win32ss/user/ntuser/class.c @@ -997,9 +997,13 @@ IntCreateClass(IN CONST WNDCLASSEXW* lpwcx, Class->cbclsExtra = lpwcx->cbClsExtra; Class->cbwndExtra = lpwcx->cbWndExtra; Class->hModule = lpwcx->hInstance; - Class->hIcon = lpwcx->hIcon; /* FIXME */ - Class->hIconSm = lpwcx->hIconSm; /* FIXME */ - Class->hCursor = lpwcx->hCursor; /* FIXME */ + Class->hIcon = lpwcx->hIcon; + Class->hIconSm = lpwcx->hIconSm; + Class->hIconSmIntern = lpwcx->hIcon && !lpwcx->hIconSm ? + co_IntCopyImage( lpwcx->hIcon, IMAGE_ICON, + UserGetSystemMetrics( SM_CXSMICON ), + UserGetSystemMetrics( SM_CYSMICON ), 0 ) : NULL; + Class->hCursor = lpwcx->hCursor; Class->hbrBackground = lpwcx->hbrBackground; /* Make a copy of the string */ @@ -1711,6 +1715,30 @@ IntSetClassMenuName(IN PCLS Class, return Ret; } +//// Do this for now in anticipation of new cursor icon code. +BOOLEAN FASTCALL IntDestroyCurIconObject(PCURICON_OBJECT, PPROCESSINFO); + +BOOL FASTCALL +IntClassDestroyIcon(HANDLE hCurIcon) +{ + PCURICON_OBJECT CurIcon; + BOOL Ret; + + if (!(CurIcon = UserGetCurIconObject(hCurIcon))) + { + + ERR("hCurIcon was not found!\n"); + return FALSE; + } + Ret = IntDestroyCurIconObject(CurIcon, PsGetCurrentProcessWin32Process()); + /* Note: IntDestroyCurIconObject will remove our reference for us! */ + if (!Ret) + { + ERR("hCurIcon was not Destroyed!\n"); + } + return Ret; +} + ULONG_PTR UserSetClassLongPtr(IN PCLS Class, IN INT Index, @@ -1718,6 +1746,7 @@ UserSetClassLongPtr(IN PCLS Class, IN BOOL Ansi) { ULONG_PTR Ret = 0; + HANDLE hIconSmIntern = NULL; /* NOTE: For GCLP_MENUNAME and GCW_ATOM this function may raise an exception! */ @@ -1806,6 +1835,20 @@ UserSetClassLongPtr(IN PCLS Class, case GCLP_HICON: /* FIXME: Get handle from pointer to ICON object */ Ret = (ULONG_PTR)Class->hIcon; + if (Class->hIcon == (HANDLE)NewLong) break; + if (Ret && Class->hIconSmIntern) + { + IntClassDestroyIcon(Class->hIconSmIntern); + Class->CSF_flags &= ~CSF_CACHEDSMICON; + Class->hIconSmIntern = NULL; + } + if (NewLong && !Class->hIconSm) + { + hIconSmIntern = Class->hIconSmIntern = co_IntCopyImage( (HICON)NewLong, IMAGE_ICON, + UserGetSystemMetrics( SM_CXSMICON ), + UserGetSystemMetrics( SM_CYSMICON ), 0 ); + Class->CSF_flags |= CSF_CACHEDSMICON; + } Class->hIcon = (HANDLE)NewLong; /* Update the clones */ @@ -1813,6 +1856,7 @@ UserSetClassLongPtr(IN PCLS Class, while (Class != NULL) { Class->hIcon = (HANDLE)NewLong; + Class->hIconSmIntern = hIconSmIntern; Class = Class->pclsNext; } break; @@ -1820,6 +1864,35 @@ UserSetClassLongPtr(IN PCLS Class, case GCLP_HICONSM: /* FIXME: Get handle from pointer to ICON object */ Ret = (ULONG_PTR)Class->hIconSm; + if (Class->hIconSm == (HANDLE)NewLong) break; +/* if (Ret && !NewLong) + { + hIconSmIntern = Class->hIconSmIntern = Class->hIcon ? co_IntCopyImage( Class->hIcon, IMAGE_ICON, + UserGetSystemMetrics( SM_CXSMICON ), + UserGetSystemMetrics( SM_CYSMICON ), 0 ) : NULL; + Class->CSF_flags |= CSF_CACHEDSMICON; + } + else if (!Ret && NewLong && Class->hIconSmIntern) + { + IntClassDestroyIcon(Class->hIconSmIntern); + Class->CSF_flags &= ~CSF_CACHEDSMICON; + Class->hIconSmIntern = NULL; + } +*/ + if (Class->CSF_flags & CSF_CACHEDSMICON) + { + if (Class->hIconSmIntern) IntClassDestroyIcon(Class->hIconSmIntern); + Class->CSF_flags &= ~CSF_CACHEDSMICON; + Class->hIconSmIntern = NULL; + Ret = 0; + } + if (Class->hIcon && !Class->hIconSmIntern) + { + hIconSmIntern = Class->hIconSmIntern = co_IntCopyImage( Class->hIcon, IMAGE_ICON, + UserGetSystemMetrics( SM_CXSMICON ), + UserGetSystemMetrics( SM_CYSMICON ), 0 ); + if (hIconSmIntern) Class->CSF_flags |= CSF_CACHEDSMICON; + } Class->hIconSm = (HANDLE)NewLong; /* Update the clones */ @@ -1827,6 +1900,7 @@ UserSetClassLongPtr(IN PCLS Class, while (Class != NULL) { Class->hIconSm = (HANDLE)NewLong; + Class->hIconSmIntern = hIconSmIntern; Class = Class->pclsNext; } break; @@ -1952,7 +2026,8 @@ UserGetClassInfo(IN PCLS Class, /* FIXME: Return the string? Okay! This is performed in User32! */ //lpwcx->lpszClassName = (LPCWSTR)((ULONG_PTR)Class->atomClassName); - lpwcx->hIconSm = Class->hIconSm; /* FIXME: Get handle from pointer */ + /* FIXME: Get handle from pointer */ + lpwcx->hIconSm = Class->hIconSm ? Class->hIconSm : Class->hIconSmIntern; return TRUE; } diff --git a/reactos/win32ss/user/user32/misc/dllmain.c b/reactos/win32ss/user/user32/misc/dllmain.c index 6acb40fc4c6..156629e7075 100644 --- a/reactos/win32ss/user/user32/misc/dllmain.c +++ b/reactos/win32ss/user/user32/misc/dllmain.c @@ -206,6 +206,7 @@ PVOID apfnDispatch[USER32_CALLBACK_MAXIMUM + 1] = User32CallClientThreadSetupFromKernel, User32CallClientLoadLibraryFromKernel, User32CallGetCharsetInfo, + User32CallCopyImageFromKernel, }; /* diff --git a/reactos/win32ss/user/user32/windows/class.c b/reactos/win32ss/user/user32/windows/class.c index 8fe30360918..72071d2c7f0 100644 --- a/reactos/win32ss/user/user32/windows/class.c +++ b/reactos/win32ss/user/user32/windows/class.c @@ -562,7 +562,7 @@ IntGetClassLongA(PWND Wnd, PCLS Class, int nIndex) case GCLP_HICONSM: /* FIXME - get handle from pointer to ICON object */ - Ret = (ULONG_PTR)Class->hIconSm; + Ret = (ULONG_PTR)(Class->hIconSm ? Class->hIconSm : Class->hIconSmIntern); break; case GCLP_WNDPROC: @@ -639,7 +639,7 @@ IntGetClassLongW (PWND Wnd, PCLS Class, int nIndex) case GCLP_HICONSM: /* FIXME - get handle from pointer to ICON object */ - Ret = (ULONG_PTR)Class->hIconSm; + Ret = (ULONG_PTR)(Class->hIconSm ? Class->hIconSm : Class->hIconSmIntern); break; case GCLP_WNDPROC: diff --git a/reactos/win32ss/user/user32/windows/cursoricon.c b/reactos/win32ss/user/user32/windows/cursoricon.c index a2688a444c1..6a6be37fbe8 100644 --- a/reactos/win32ss/user/user32/windows/cursoricon.c +++ b/reactos/win32ss/user/user32/windows/cursoricon.c @@ -2190,3 +2190,20 @@ BOOL get_icon_size(HICON hIcon, SIZE *size) return TRUE; } + +NTSTATUS WINAPI +User32CallCopyImageFromKernel(PVOID Arguments, ULONG ArgumentLength) +{ + PCOPYIMAGE_CALLBACK_ARGUMENTS Common; + HANDLE Result; + Common = (PCOPYIMAGE_CALLBACK_ARGUMENTS) Arguments; + + Result = CopyImage(Common->hImage, + Common->uType, + Common->cxDesired, + Common->cyDesired, + Common->fuFlags); + + return ZwCallbackReturn(&Result, sizeof(HANDLE), STATUS_SUCCESS); +} + diff --git a/reactos/win32ss/user/user32/windows/cursoricon_new.c b/reactos/win32ss/user/user32/windows/cursoricon_new.c index d11bbef2fc3..d622d563e24 100644 --- a/reactos/win32ss/user/user32/windows/cursoricon_new.c +++ b/reactos/win32ss/user/user32/windows/cursoricon_new.c @@ -1442,6 +1442,23 @@ CURSORICON_CopyImage( return hicon; } +NTSTATUS WINAPI +User32CallCopyImageFromKernel(PVOID Arguments, ULONG ArgumentLength) +{ + PCOPYIMAGE_CALLBACK_ARGUMENTS Common; + HANDLE Result; + Common = (PCOPYIMAGE_CALLBACK_ARGUMENTS) Arguments; + + Result = CopyImage(Common->hImage, + Common->uType, + Common->cxDesired, + Common->cyDesired, + Common->fuFlags); + + return ZwCallbackReturn(&Result, sizeof(HANDLE), STATUS_SUCCESS); +} + + /************* PUBLIC FUNCTIONS *******************/ HANDLE WINAPI CopyImage(