SwyxIt can ask a plug-in to find a number for a name, e.g. when you use the phonebook search function. A plug-in needs to support this custom COM interface which is defined in the SDK (CLMGgrPub.idl):
[
object,
uuid(f8e55548-4c00-11d3-80bc-00105a653379),
helpstring("IFulltextSearchAddIn Interface"),
pointer_default(unique)
]
interface IFulltextSearchAddIn : IUnknown
{
HRESULT FulltextSearchInContacts(
[in] BSTR bstrSearchText,
[in] BOOL bEnableSearchInNumbers,
[in] IDispatch* pISearchResultCollection);
};
In managed code this interface definition is
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("f8e55548-4c00-11d3-80bc-00105a653379"),
AutomationProxy(false)]
public interface IFulltextSearchAddIn
{
[PreserveSig()]
[return: MarshalAs(UnmanagedType.Error)]
int FulltextSearchInContacts(
[MarshalAs(UnmanagedType.BStr), In()] string searchText,
[MarshalAs(UnmanagedType.Bool), In()] bool enableSearchInNumbers,
[MarshalAs(UnmanagedType.IDispatch), In(), Out()] object searchResultCollection);
}
The interface has some unusual semantics. The third parameter is an IDispatch based interface which is defined in CLMgrPub.idl like this:
[
object,
uuid(f8e55543-4c00-11d3-80bc-00105a653379),
dual,
helpstring("INameNumberSearchResultCollection Interface"),
oleautomation,
pointer_default(unique)
]
interface INameNumberSearchResultCollection : IDispatch
{
[propget, restricted, id(DISPID_NEWENUM)]
HRESULT _NewEnum([out, retval] IUnknown** pVal);
[id(DISPID_VALUE)]
HRESULT Item([in] VARIANT index, [out, retval] VARIANT* pVariant);
[propget, id(1)]
HRESULT Count([out, retval] long *pVal);
[propget, id(2)]
HRESULT CreateItem([out, retval] IDispatch** ppVal);
[id(3)]
HRESULT AddItem([in] IDispatch* pVal);
};
It’s an input parameter, i.e. SwyxIt provides such a collection object to your plug-in. You just have to fill it with data.
As you can see from the definition INameNumberSearchResultCollection is an automation interface. We can just add a COM reference to clmgr.exe to our project in Visual Studio and the framework creates a runtime callable wrapper (RCW) for it. The items in this collection are NameNumberSearchResult objects. Fortunately the interface of that object is an automation interface too and the RCW has a definition of it, too.
Here’s a small sample implementation of the search function:
1: public int FulltextSearchInContacts(
2: string searchText,
3: bool enableSearchInNumbers,
4: object searchResultCollection)
5: {
6: NameNumberSearchResultCollection resultCollection = (NameNumberSearchResultCollection)searchResultCollection;
7:
8: // This is a sample, we find "Swyx" only.
9: // Note: Swyxit always provides lower case text.
10: if (searchText.Contains("swyx"))
11: {
12: NameNumberSearchResult result = new NameNumberSearchResult();
13: result.Name = "Swyx Solutions AG (SampleAddIn result)";
14: result.Number = "+4923147770";
15: resultCollection.AddItem(result);
16: }
17:
18: return 0;
19: }
20:
As you can see on line 6 the third parameter can be casted to a NameNumberSearchResultCollection. You just have to implement your search logic, create NameNumberSearchResult for each result and add it to the collection with AddItem() (lines 12 to 15).
Important: Per default full-text search is not enabled for SwyxIt! plug-ins. You have to create a REG_DWORD registry value named
FulltextSearchAddinEnabled
and set it to 1. It’s located in the registry key of your plug-in (See the previous blog entry). Without that registry value SwyxIt does not use the plug-in’s IFullTextSearchAddIn interface.
Last, but not least, here’s the updated sample plugin from the previous post. Have fun.