15
15
16
16
namespace Files . App . Storage
17
17
{
18
- public unsafe static partial class WindowsStorableHelpers
18
+ public unsafe static partial class WindowsStorageHelpers
19
19
{
20
20
public unsafe static HRESULT GetPropertyValue < TValue > ( this IWindowsStorable storable , string propKey , out TValue value )
21
21
{
@@ -149,33 +149,56 @@ public unsafe static HRESULT TryGetShellTooltip(this IWindowsStorable storable,
149
149
150
150
public static IEnumerable < ShellNewItem > GetShellNewItems ( this IWindowsStorable storable )
151
151
{
152
+ if ( storable is not WindowsFolder folder )
153
+ return [ ] ;
154
+
152
155
HRESULT hr = default ;
153
156
154
- using ComPtr < IContextMenu > pNewMenu = default ;
157
+ IContextMenu * pNewMenu = default ;
155
158
using ComPtr < IShellExtInit > pShellExtInit = default ;
156
159
using ComPtr < IContextMenu2 > pContextMenu2 = default ;
157
160
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 ;
162
174
163
- // Initialize CNewMenu with the PIDL of the folder
164
175
ITEMIDLIST * pFolderPidl = default ;
165
176
hr = PInvoke . SHGetIDListFromObject ( ( IUnknown * ) storable . ThisPtr , & pFolderPidl ) ;
177
+ if ( hr . ThrowIfFailedOnDebug ( ) . Failed )
178
+ return [ ] ;
179
+
166
180
hr = pShellExtInit . Get ( ) ->Initialize ( pFolderPidl , null , default ) ;
181
+ if ( hr . ThrowIfFailedOnDebug ( ) . Failed )
182
+ return [ ] ;
167
183
168
184
// Inserts "New (&W)"
169
185
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 [ ] ;
171
189
172
190
// Invokes CNewMenu::_InitMenuPopup(), which populates the hSubMenu
173
191
HMENU hSubMenu = PInvoke . GetSubMenu ( hMenu , 0 ) ;
174
192
hr = pContextMenu2 . Get ( ) ->HandleMenuMsg ( PInvoke . WM_INITMENUPOPUP , ( WPARAM ) ( nuint ) hSubMenu . Value , 0 ) ;
193
+ if ( hr . ThrowIfFailedOnDebug ( ) . Failed )
194
+ return [ ] ;
175
195
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
177
201
List < ShellNewItem > shellNewItems = [ ] ;
178
- uint dwCount = ( uint ) PInvoke . GetMenuItemCount ( hSubMenu ) ;
179
202
for ( uint dwIndex = 0 ; dwIndex < dwCount ; dwIndex ++ )
180
203
{
181
204
MENUITEMINFOW mii = default ;
@@ -186,8 +209,6 @@ public static IEnumerable<ShellNewItem> GetShellNewItems(this IWindowsStorable s
186
209
187
210
if ( PInvoke . GetMenuItemInfo ( hSubMenu , dwIndex , true , & mii ) )
188
211
{
189
- Console . WriteLine ( $ "{ dwIndex : X} : { mii . wID : X} , { mii . fState } , { mii . dwTypeData } ") ;
190
-
191
212
shellNewItems . Add ( new ( )
192
213
{
193
214
Id = mii . wID ,
@@ -201,5 +222,33 @@ public static IEnumerable<ShellNewItem> GetShellNewItems(this IWindowsStorable s
201
222
202
223
return shellNewItems ;
203
224
}
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
+ }
204
253
}
205
254
}
0 commit comments