Events in the Windows RSS Platform

Events in the Windows RSS Platform

The Windows RSS Platform includes a rich eventing subsystem that developers can use to listen for and respond to feed and folder events. This topic provides design and implementation details of the Windows RSS Platform. Although the emphasis is on the early-bound interfaces (IXFeed*), the event methods apply equally to the Component Object Model (COM) automation interfaces (IFeed*).

This topic contains the following sections:

  • Folder and Feed Events 
    • Folder Events 
    • Feed Events 
  • Registering for Events 
  • Scope and Mask 

Folder and Feed Events

The folder and feed events are detailed below.

An application need not implement all events (event sink methods); however, it must return E_NOTIMPL from each method that is not implemented. If an application returns anything but S_OK or E_NOTIMPL, the eventing system will raise the Error event to report the problem. When this happens, the application must assume that some events have not been raised, and should recover by rereading the feed subscription list as if running for the first time. The Error event can always be raised independent of any specified mask .

Folder Events

The table below lists the events that apply to both IXFeedFolderEvents and IFeedFolderEvents:

Event Description Mask
FolderAdded(path) A subfolder was added. FEM_FOLDEREVENTS
FolderDeleted(path) A subfolder was deleted. FEM_FOLDEREVENTS
FolderRenamed(new,old) A subfolder was renamed. FEM_FOLDEREVENTS
FolderMovedFrom(new,old) A subfolder was moved from this folder to another folder. FEM_FOLDEREVENTS
FolderMovedTo(new,old) A subfolder was moved into this folder. FEM_FOLDEREVENTS
FolderItemCountChanged(path,type,count) The aggregated total of items or unread items changed. FEM_FOLDEREVENTS
FeedAdded(path) A feed was added. FEM_FEEDEVENTS
FeedDeleted(path) A feed was deleted. FEM_FEEDEVENTS
FeedRenamed(new,old) A feed was renamed. FEM_FEEDEVENTS
FeedUrlChanged(path) The URL of a feed changed. FEM_FEEDEVENTS
FeedMovedFrom(new,old) A feed was moved from this folder. FEM_FEEDEVENTS
FeedMovedTo(new,old) A feed was moved to this folder. FEM_FEEDEVENTS
FeedDownloading(path) A feed started downloading. FEM_FEEDEVENTS
FeedDownloadCompleted(path,error) A feed completed downloading (success or error). FEM_FEEDEVENTS
FeedItemCountChanged(path,type,count) The number of items or unread items in a feed changed. FEM_FEEDEVENTS
Error An error occurred in the eventing subsystem. N/A

Feed Events

The following events apply to both IXFeedEvents and IFeedEvents.

Event Description Mask
FeedDeleted(path) The feed was deleted. FEM_FEEDEVENTS
FeedRenamed(new,old) The feed was renamed. FEM_FEEDEVENTS
FeedUrlChanged(path) The URL of the feed changed. FEM_FEEDEVENTS
FeedMoved(new,old) The feed was moved. FEM_FEEDEVENTS
FeedDownloading(path) The feed started downloading. FEM_FEEDEVENTS
FeedDownloadCompleted(path,error) The feed completed downloading (success or error). FEM_FEEDEVENTS
FeedItemCountChanged(path,type,count) The number of items or unread items in the feed changed. FEM_FEEDEVENTS
Error An error occurred in the eventing subsystem. N/A

Enclosures

The Windows RSS Platform does not raise events when enclosures are downloaded. The DownloadStatus property of the FeedEnclosure object indicates whether the download is in progress, failed, or completed.

Because LocalPath is set when the item is created in the Common Feed List, the property may be used to poll the file system until the file arrives. The Background Intelligent Transfer Service (BITS) downloads the enclosure to a temporary location before copying it to the location specified in LocalPath upon completion.

Registering for Events

Applications can register for events on folders and feeds. The event sink interfaces are IXFeedFolderEvents (or IFeedFolderEvents) and IXFeedEvents (or IFeedEvents). The application must implement these interfaces.

  • IXFeedFolderEvents defines event methods—such as add, delete, rename, and move—for folders and subfolders,as well as event methods for feeds that belong to the folders and subfolders.
  • IXFeedEvents contains only the event methods for a particular feed.

To register for events, an application calls the IXFeedFolder.GetWatcher method on a folder or feed, specifying the scope and mask. The interface returned by GetWatcher is an IConnectionPointContainer which is the standard COM interface used to register for events. In short, an application uses the IConnectionPointContainer to register its implementation of the event sink interface (IConnectionPoint). The eventing subsystem will then call back on the connection point. For more information, see Architecture of Connectable Objects.

The next section describes how to limit which events are raised.

Scope and Mask

Only event sink methods that fall within the specified scope will be called. When registering for events on a folder, the application can specify a value from the FEEDS_EVENTS_SCOPE enumeration that indicates which of the events will be fired. It is possible to raise events for a single folder and its feeds, or for the entire Common Feed List hierarchy recursively.

Value Description
FES_SELF_ONLY Raise events for this folder and its feeds.
FES_SELF_AND_CHILDREN_ONLY Raise events for this folder and its feeds, and for its direct subfolders and their feeds.
FES_ALL Raise events for this folder and its feeds, and all subfolders recursively and their feeds.

To limit which events are raised, applications can specify the FEEDS_EVENTS_MASK. This mask determines which events will be raised by the Windows RSS Platform.

Value Description
FEM_FOLDEREVENTS Raise folder events only (added, deleted, renamed, moved).
FEM_FEEDEVENTS Raise feed events only (added, deleted, renamed, moved).

The following conceptual example, written in C++, demonstrates how to subscribe to the folder events for the entire Common Feed List hierarchy.

Note   To receive the events for a single feed only, use the IConnectionPointContainer returned by IXFeed.GetWatcher, and register your IXFeedEvents interface instead of the IXFeedFolderEvents interface, as shown in the example.

IXFeedsManager* pfm;
HRESULT hr = CoCreateInstance(CLSID_XFeedsManager,
                  NULL, CLSCTX_INPROC_SERVER,
                  IID_PPV_ARGS(&pfm));
if (SUCCEEDED(hr))
{
   // Get the root folder
   IXFeedFolder* pff;
   hr = pfm->RootFolder(IID_PPV_ARGS(&pff));
   if (SUCCEEDED(hr))
   {
      // Get the ConnectionPointContainer
      IConnectionPointContainer* pcpc;
      hr = pff->GetWatcher(FES_ALL, 
                  FEM_FOLDEREVENTS | FEM_FEEDEVENTS,
                  IID_PPV_ARGS(&pcpc));
      if (SUCCEEDED(hr))
      {
         // Get the ConnectionPoint
         IConnectionPoint* pcp;
         hr = pcpc->FindConnectionPoint(
                        __uuidof(IXFeedFolderEvents), &pcp);
         if (SUCCEEDED(hr))
         {
            // Get COM class that implements the event callbacks
            IXFeedFolderEvents* pffe;
            pffe = static_cast<IXFeedFolderEvents*>(this);
            
            // Register the callback event sink implementation
            DWORD dwAdviseCookie = 0;
            hr = pcp->Advise(pffe, &dwAdviseCookie);
            
            // Release interfaces
            pcp->Release();
         }
         pcpc->Release();
      }
      pff->Release();
   }
   pfm->Release();
}

For users of C#, the process of subscribing to the event sink is greatly simplified. The following example subscribes to the FeedItemCountChanged event with two lines of code: one to retrieve the event sink and the other to register the event handler.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        // Declaration of FeedList objects
        FeedsManager fm = new FeedsManager();
        IFeedFolder rootFolder = (IFeedFolder)fm.RootFolder;
        IFeedFolderEvents_Event fw;
        
        fw = (IFeedFolderEvents_Event)rootFolder.GetWatcher(
                FEEDS_EVENTS_SCOPE.FES_ALL, 
                FEEDS_EVENTS_MASK.FEM_FEEDEVENTS);
        
        fw.FeedItemCountChanged += new
            IFeedFolderEvents_FeedItemCountChangedEventHandler(fw_FeedItemCountChanged); 
        
        // Enumerate the feed list
        DisplayFeeds();
    }

    void fw_FeedItemCountChanged(string path, int itemCountType, int count)
    {
        MessageBox.Show("Hmmm... Looks like a Refresh is needed...");
        
        // Refresh the feed list
        DisplayFeeds();
    }

    ...