miss programmer
miss programmer

Reputation: 49

How do I make it so a search folder can be saved?

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":

error message

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

Answers (0)

Related Questions