Reputation: 49
I'm creating a Windows Explorer-like application and I've also implemented search folders and everything works fine, except I can not save the search from the right-click IContextMenu
. It gives me (freely translated) "The search query can not be saved. Use another name or save the query in another location":
This is how I create the IShellItem2
that is then enumerated and used to create an IShellFolder
from which I create an IContextMenu
on which I invoke the "Save query" command:
Private Shared Function getShellItem(terms As String, parent As Folder) As IShellItem2
Dim factory As ISearchFolderItemFactory = Activator.CreateInstance(Type.GetTypeFromCLSID(Guids.CLSID_SearchFolderItemFactory))
Dim arr As IShellItemArray
Dim pidls As List(Of Pidl)
If parent.Pidl.Equals(Shell.GetSpecialFolder("This pc").Pidl) Then
pidls = parent.GetItems().Where(Function(i) TypeOf i Is Folder).Select(Function(i) i.Pidl).ToList()
Else
pidls = New List(Of Pidl)() From {parent.Pidl}
End If
Functions.SHCreateShellItemArrayFromIDLists(pidls.Count, pidls.Select(Function(p) p.AbsolutePIDL).ToArray(), arr)
factory.SetScope(arr)
Dim qpm As IQueryParserManager = Activator.CreateInstance(Type.GetTypeFromCLSID(Guids.CLSID_QueryParserManager))
Dim qp As IQueryParser
qpm.CreateLoadedParser("SystemIndex", &H800, GetType(IQueryParser).GUID, qp)
Dim qs As IQuerySolution
qp.Parse(terms, Nothing, qs)
Dim cond As ICondition
qs.GetQuery(cond, Nothing)
Dim st As SYSTEMTIME
Functions.GetLocalTime(st)
Dim resolvedCond As ICondition
qs.Resolve(cond, &H40, st, resolvedCond)
factory.SetCondition(resolvedCond)
factory.SetDisplayName("Search results for " & parent.DisplayName)
factory.SetFolderTypeID(Guids.FOLDERTYPEID_GenericSearchResults)
Dim shellItem As IShellItem2
factory.GetShellItem(GetType(IShellItem2).GUID, shellItem)
Return shellItem
End Function
This is how I invoke the command:
Dim cmi As New CMInvokeCommandInfoEx
Debug.WriteLine("InvokeCommand " & id.Item1 & ", " & id.Item2)
If id.Item1 > 0 Then
cmi.lpVerb = New IntPtr(id.Item1)
cmi.lpVerbW = New IntPtr(id.Item1)
Else
cmi.lpVerb = Marshal.StringToHGlobalAnsi(id.Item2)
cmi.lpVerbW = Marshal.StringToHGlobalUni(id.Item2)
End If
cmi.fMask = CMIC.UNICODE Or CMIC.ASYNCOK
If Keyboard.Modifiers.HasFlag(ModifierKeys.Control) Then cmi.fMask = cmi.fMask Or CMIC.CONTROL_DOWN
If Keyboard.Modifiers.HasFlag(ModifierKeys.Shift) Then cmi.fMask = cmi.fMask Or CMIC.SHIFT_DOWN
cmi.nShow = SW.SHOWNORMAL
cmi.cbSize = CUInt(Marshal.SizeOf(cmi))
Dim h As HRESULT = _contextMenu.InvokeCommand(cmi)
Debug.WriteLine("InvokeCommand returned " & h.ToString())
You can find the full source code to this project at https://sourceforge.net/projects/laila-shell/ if you're interested in taking a look.
Upvotes: 0
Views: 45