[Win32ss]
authorJames Tabor <james.tabor@reactos.org>
Wed, 9 Oct 2013 01:11:44 +0000 (01:11 +0000)
committerJames Tabor <james.tabor@reactos.org>
Wed, 9 Oct 2013 01:11:44 +0000 (01:11 +0000)
- Fix class icon tests. Still two more to go, investigating.

svn path=/trunk/; revision=60587

reactos/win32ss/include/callback.h
reactos/win32ss/include/ntuser.h
reactos/win32ss/user/ntuser/callback.c
reactos/win32ss/user/ntuser/callback.h
reactos/win32ss/user/ntuser/class.c
reactos/win32ss/user/user32/misc/dllmain.c
reactos/win32ss/user/user32/windows/class.c
reactos/win32ss/user/user32/windows/cursoricon.c
reactos/win32ss/user/user32/windows/cursoricon_new.c

index 2149242..d491f96 100644 (file)
@@ -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
index b835153..e64fa9d 100644 (file)
@@ -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;
index fc38fb5..833da09 100644 (file)
@@ -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)
index 6882129..5537e72 100644 (file)
@@ -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);
index 2f29ec1..0bc2496 100644 (file)
@@ -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;
 }
index 6acb40f..156629e 100644 (file)
@@ -206,6 +206,7 @@ PVOID apfnDispatch[USER32_CALLBACK_MAXIMUM + 1] =
     User32CallClientThreadSetupFromKernel,
     User32CallClientLoadLibraryFromKernel,
     User32CallGetCharsetInfo,
+    User32CallCopyImageFromKernel,
 };
 
 /*
index 8fe3036..72071d2 100644 (file)
@@ -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:
index a2688a4..6a6be37 100644 (file)
@@ -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);
+}
+
index d11bbef..d622d56 100644 (file)
@@ -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(