1515
1616namespace Files . App . Storage
1717{
18- public unsafe static partial class WindowsStorableHelpers
18+ public unsafe static partial class WindowsStorageHelpers
1919 {
2020 public unsafe static HRESULT GetPropertyValue < TValue > ( this IWindowsStorable storable , string propKey , out TValue value )
2121 {
@@ -149,33 +149,56 @@ public unsafe static HRESULT TryGetShellTooltip(this IWindowsStorable storable,
149149
150150 public static IEnumerable < ShellNewItem > GetShellNewItems ( this IWindowsStorable storable )
151151 {
152+ if ( storable is not WindowsFolder folder )
153+ return [ ] ;
154+
152155 HRESULT hr = default ;
153156
154- using ComPtr < IContextMenu > pNewMenu = default ;
157+ IContextMenu * pNewMenu = default ;
155158 using ComPtr < IShellExtInit > pShellExtInit = default ;
156159 using ComPtr < IContextMenu2 > pContextMenu2 = default ;
157160
158- // Instantiate CNewMenu as IContextMenu, IContextMenu2, and IShellExtInit
159- hr = PInvoke . CoCreateInstance ( CLSID . CLSID_NewMenu , null , CLSCTX . CLSCTX_INPROC_SERVER , IID . IID_IContextMenu , ( void * * ) pNewMenu . GetAddressOf ( ) ) ;
160- hr = pNewMenu . Get ( ) ->QueryInterface ( IID . IID_IContextMenu2 , ( void * * ) pContextMenu2 . GetAddressOf ( ) ) ;
161- hr = pNewMenu . Get ( ) ->QueryInterface ( IID . IID_IShellExtInit , ( void * * ) pShellExtInit . GetAddressOf ( ) ) ;
161+ hr = PInvoke . CoCreateInstance ( CLSID . CLSID_NewMenu , null , CLSCTX . CLSCTX_INPROC_SERVER , IID . IID_IContextMenu , ( void * * ) & pNewMenu ) ;
162+ if ( hr . ThrowIfFailedOnDebug ( ) . Failed )
163+ return [ ] ;
164+
165+ hr = pNewMenu ->QueryInterface ( IID . IID_IContextMenu2 , ( void * * ) pContextMenu2 . GetAddressOf ( ) ) ;
166+ if ( hr . ThrowIfFailedOnDebug ( ) . Failed )
167+ return [ ] ;
168+
169+ hr = pNewMenu ->QueryInterface ( IID . IID_IShellExtInit , ( void * * ) pShellExtInit . GetAddressOf ( ) ) ;
170+ if ( hr . ThrowIfFailedOnDebug ( ) . Failed )
171+ return [ ] ;
172+
173+ folder . NewMenuPtr = pNewMenu ;
162174
163- // Initialize CNewMenu with the PIDL of the folder
164175 ITEMIDLIST * pFolderPidl = default ;
165176 hr = PInvoke . SHGetIDListFromObject ( ( IUnknown * ) storable . ThisPtr , & pFolderPidl ) ;
177+ if ( hr . ThrowIfFailedOnDebug ( ) . Failed )
178+ return [ ] ;
179+
166180 hr = pShellExtInit . Get ( ) ->Initialize ( pFolderPidl , null , default ) ;
181+ if ( hr . ThrowIfFailedOnDebug ( ) . Failed )
182+ return [ ] ;
167183
168184 // Inserts "New (&W)"
169185 HMENU hMenu = PInvoke . CreatePopupMenu ( ) ;
170- hr = pNewMenu . Get ( ) ->QueryContextMenu ( hMenu , 0 , 1 , 256 , 0 ) ;
186+ hr = pNewMenu ->QueryContextMenu ( hMenu , 0 , 1 , 256 , 0 ) ;
187+ if ( hr . ThrowIfFailedOnDebug ( ) . Failed )
188+ return [ ] ;
171189
172190 // Invokes CNewMenu::_InitMenuPopup(), which populates the hSubMenu
173191 HMENU hSubMenu = PInvoke . GetSubMenu ( hMenu , 0 ) ;
174192 hr = pContextMenu2 . Get ( ) ->HandleMenuMsg ( PInvoke . WM_INITMENUPOPUP , ( WPARAM ) ( nuint ) hSubMenu . Value , 0 ) ;
193+ if ( hr . ThrowIfFailedOnDebug ( ) . Failed )
194+ return [ ] ;
175195
176- // Enumerate and populate the list
196+ uint dwCount = unchecked ( ( uint ) PInvoke . GetMenuItemCount ( hSubMenu ) ) ;
197+ if ( dwCount is unchecked ( ( uint ) - 1 ) )
198+ return [ ] ;
199+
200+ // Enumerates and populates the list
177201 List < ShellNewItem > shellNewItems = [ ] ;
178- uint dwCount = ( uint ) PInvoke . GetMenuItemCount ( hSubMenu ) ;
179202 for ( uint dwIndex = 0 ; dwIndex < dwCount ; dwIndex ++ )
180203 {
181204 MENUITEMINFOW mii = default ;
@@ -186,8 +209,6 @@ public static IEnumerable<ShellNewItem> GetShellNewItems(this IWindowsStorable s
186209
187210 if ( PInvoke . GetMenuItemInfo ( hSubMenu , dwIndex , true , & mii ) )
188211 {
189- Console . WriteLine ( $ "{ dwIndex : X} : { mii . wID : X} , { mii . fState } , { mii . dwTypeData } ") ;
190-
191212 shellNewItems . Add ( new ( )
192213 {
193214 Id = mii . wID ,
@@ -201,5 +222,33 @@ public static IEnumerable<ShellNewItem> GetShellNewItems(this IWindowsStorable s
201222
202223 return shellNewItems ;
203224 }
225+
226+ public static bool InvokeShellNewItem ( this IWindowsStorable storable , ShellNewItem item )
227+ {
228+ if ( storable is not WindowsFolder folder )
229+ return false ;
230+
231+ HRESULT hr = default ;
232+
233+ CMINVOKECOMMANDINFO cmici = default ;
234+ cmici . cbSize = ( uint ) sizeof ( CMINVOKECOMMANDINFO ) ;
235+ cmici . lpVerb = ( PCSTR ) ( byte * ) item . Id ;
236+ cmici . nShow = ( int ) SHOW_WINDOW_CMD . SW_SHOWNORMAL ;
237+
238+ if ( folder . NewMenuPtr is null )
239+ {
240+ IContextMenu * pNewMenu = default ;
241+
242+ hr = PInvoke . CoCreateInstance ( CLSID . CLSID_NewMenu , null , CLSCTX . CLSCTX_INPROC_SERVER , IID . IID_IContextMenu , ( void * * ) & pNewMenu ) ;
243+ if ( hr . ThrowIfFailedOnDebug ( ) . Failed )
244+ return false ;
245+
246+ folder . NewMenuPtr = pNewMenu ;
247+ }
248+
249+ folder . NewMenuPtr ->InvokeCommand ( & cmici ) ;
250+
251+ return false ;
252+ }
204253 }
205254}
0 commit comments