Supporting Windows Search with MFC

Introduction

The revival of MFC that began with the Visual C++ 2008 Feature Pack continues with Visual C++ 2010, and a whole new range of options that allow rich integration with advanced Windows features like Windows Search are now provided out- of-the-box. By providing a link between familiar MFC features like the Document-View architecture, the new Windows 7 features can be easily incorporated into a code- base with minimal work.

Windows Search has been through a number of forms and iterations before arriving at the consistent and integrated product available across the supported Windows operating systems today. Windows Search started life as the Indexing Service on Windows XP, which was then built upon with Windows Desktop Search (WDS). The initial versions of WDS was publicly branded MSN Desktop Search (and came with the MSN Toolbar), with Version 3 (released in 2007) available as a stand-alone installation and re-branded to Windows Desktop Search. For Windows Vista, Windows Server 2008 and Windows 7, WDS was integrated deeply into Windows and had its name compacted further to simply 'Windows Search'. Windows Search 4, released in 2008, is available for installation on all Windows versions from XP onwards, and has a large feature set as described in Knowledge Base article 940157.

There are two basic techniques that Windows Search uses to extract and categorize information from a file. The simplest technique is to catalogue the metadata available from a file, which is exposed to Windows Search in the form of properties. Extensible file properties are one of the surviving remnants of the Object File System and Windows File System (which were part of the wider 'Project Cairo' that was promised at the 1991 PDC and never delivered in coherent product form) that allow arbitrary metadata properties to be attached to a file. Digital media files and Office documents are two of the most successful and prominent example of files that make use of properties to expose metadata about their contents, allowing Windows Search to locate Office documents with a particular Author property and MP3 files from a particular artist. Windows ships with a schema that defines over two hundred standard properties, and this schema can be extended via property descriptor files and property handlers as defined in the MSDN library.

For data stored in some file types, simple metadata is not enough to allow Windows Search to gather enough information about the data stored in the file. For example, the Outlook PST file which contains emails, contacts and calendar appointments cannot adequately expose its contents to Windows Search through the use of metadata properties, and this is where Windows Search Filters come in. Filters, which are implemented through the COM IFilter interface, are called by Windows Search to extract key pieces of indexable data for a particular file which can then be used to locate the indexed item when a user enters search criteria relevant to it. An IFilter-implementation is associated with a particular file extension, which makes MFC a natural candidate for supporting Windows Search Filters with its simple support for file extension handling.

Choosing to support Search Filters in an MFC application is done as part of the MFC application wizard as shown in Figure 1, with the Filter option enabled once a file extension has been nominated. When the Filter option is selected (or either of the Preview or Thumbnail options), a separate ATL COM DLL project will be added to the MFC solution, and this will contain the skeleton implementation of IFilter and the other secondary COM interfaces required. The CDocument-derived MFC class is shared between the main MFC Windows application project and the ATL handler project, allowing the same code that is used in standard application execution to be re-used to extract key data when the file is indexed by Windows Search.


Figure 1. MFC Options for Windows Integration.

The methods required to support IFilter in the CDocument- derived class are conditionally compiled by surrounding them with #ifdef SHARED_HANDLERS directives. SHARED_HANDLERS is defined for the ATL DLL project, but is not defined for the main MFC application, and this nifty bit of engineering allows the same code-base to be effectively used for both main application flow and Windows integration.

The easiest way to see the effectiveness and simplicity of the MFC integration with Windows is with a quick demonstration project--a minimalist note keeping program that allows a user to create and save notes that have both a title and body. The familiar and long-serving MFC document- view architecture makes creating the application straightforward, with the Document-derived class containing member variables for the data of each note that is then read by the View-derived class and displayed on the screen. The basics of the document definition and archiving are:

 class CMfcNoteDoc : public CDocument
 {
 public:
  CString m_title;
  CString m_body;
 }
 
 void CMfcNoteDoc::Serialize(CArchive& ar)
 {
  if (ar.IsStoring())
  {
  ar << m_title;
  ar << m_body;
  }
  else
  {
  ar >> m_title;
  ar >> m_body;
  }
 }

The App-Wizard generated code contains the following IFilter-related methods in the document class:

 // Support for Search Handlers
 void CMfcNoteDoc::InitializeSearchContent()
 {
  CString strSearchContent;
  // Set search contents from document's data. 
  // The content parts should be separated by ";"
 
  // For example: strSearchContent = _T("point;rectangle;circle;ole object;");
  SetSearchContent(strSearchContent);
 }
 
 void CMfcNoteDoc::SetSearchContent(const CString& value)
 {
  if (value.IsEmpty())
  {
  RemoveChunk(PKEY_Search_Contents.fmtid, PKEY_Search_Contents.pid);
  }
  else
  {
  CMFCFilterChunkValueImpl *pChunk = NULL;
  ATLTRY(pChunk = new CMFCFilterChunkValueImpl);
  if (pChunk != NULL)
  {
   pChunk->SetTextValue(PKEY_Search_Contents, value, CHUNK_TEXT);
   SetChunkValue(pChunk);
  }
  }
 }

By default, InitializeSearchContent calls SetSearchContent with an empty string, and when Windows Search indexes the contents of files created by the MFC application, no data will be available, and the file contents will not be indexed. Adding a meaningful implementation to SetSearchContent is generally pretty easy--SetSearch contents will be called by the Windows Search indexer after the MFC infrastructure has called the standard CDocument Serialize method, so all the member variables will be fully populated by the document's contents. For the MfcNote sample application, indexing the note title seems like a reasonable compromise between efficiency and completeness, so the implementation can be adapted to a single line of code.

 void CMfcNoteDoc::InitializeSearchContent()
 {
  SetSearchContent(m_title); //index note title
 }

The sample demonstrates how easily MFC-based applications can integrate fully into the full-text capabilities of Windows Search. Without over selling the elegance and power of Windows Search integration, this new feature is a return to MFC's glory days where rich Windows integration was available with minimal development overhead. In the lead-up to the full release of Visual C++ 2010, more of the great new enhancements to MFC will be covered.



Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: August 14, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT Data protection has long been considered "overhead" by many organizations in the past, many chalking it up to an insurance policy or an extended warranty you may never use. The realities of today make data protection a must-have, as we live in a data driven society. The digital assets we create, share, and collaborate with others on must be managed and protected for many purposes. Check out this upcoming eSeminar and join eVault Chief Technology …

  • As a development and deployment platform, RHEL offers an efficient, scalable, and robust operating environment with certified security and flexible deployment options in physical and virtualized environments. To assess and quantify the business benefits of RHEL, IDC recently conducted in-depth interviews with IT staff members of 21 companies using RHEL servers. The organizations represent a broad range of industries and have an average of 22,700 employees. RHEL servers accounted for 23% of the servers …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds