Wednesday, June 07, 2006

Code-wise speaking, I haven’t done big improvements since my previous post on this matter.  But I’ve spent a considerable amount of time to figure out that this technology is not ready for Foxpro, if it will ever be.

 

I’ll go directly to the point:

With the new Internet Explorer 7 (Beta 2) we also get the RSS Platform (in ways of a DLL file @ c:\windows\system32\msfeeds.dll).

 

Yes, you need to install this Beta if you want to test the code posted here.

If you have concerns about replacing your beloved IE 6 installation, shall I say then that you can always uninstall?

 

Once you’ve got IE7 Beta2 installed, all you need to do from the command window:

      

The Feeds ‘property’, holds all of your subscribed feeds collection, following the example from the picture above, the following code will print all those feeds names:

 

oFeedManager=NEWOBJECT("Microsoft.FeedsManager")

oRootFolder=oFeedManager.RootFolder

oAllMyFeeds=oRootFolder.Feeds

FOR EACH oCurrFeed in oAllMyFeeds

      ?oCurrFeed.name

NEXT

 

The RSS API has been well documented at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/feedsapi/rss/overviews/msfeeds_ovw.asp , take a look at it to learn more about how this API is structured and the usage for the different methods, properties and events that are available.

 

Sorry, did I say ‘events’? Well ignore that for the Foxpro scenario, as you’ll read in the “Issues, issues....” section of this post, RSS events don’t work in VFP.

 

 

My approach: a goodwill attempt.

 

Here’s a very simple form rssreader.zip (8.24 KB), don't expect it to be bullet proof,  but it will allow you to add feeds and see their contents, as well as to get an idea of the potential.

 

This example uses a Treeview control to populate the feeds, a microsoft web browser control to show the Feed entries in html format, and eventually if you are connected to the internet, click on 'show web' checkbox to see the blog entry directly from the original.

 

Remember the 'download issue' I referred to in this post "ISSUES ", so you don't get frustrated on me, I am just the messenger.

 

My design is far from what I would like, but from a VFP perspective, this API’s state-of-the-art does not deserve more efforts from my side until I get a clear sign that it will work seamlessly.

 

For the reasons exposed, I can’t justify building a wrapper class for the API to make all the functionality reusable with other controls than the Treeview, but for the most part, the code (form) I built is a good sample of the potential for a good part of what  the API allows FoxPro to do.

 

It is a pity indeed because, being able to see from VFP the same RSS info that our current IE7 installation sees, it would open a great potential for our FoxPro applications.

You may think why bother building another news aggregator, but I am thinking more about interchanging information between different systems rather than anything else, if you know what I mean.

Maybe for RSS functionality from VFP we will have to implement it ourselves via NET4COM or like YAG commented in my previous post, SEDNA’s MY will take care of it.

 

 

ISSUES, ISSUES ….

 

Implementing Interfaces: I wasn’t able to implement interfaces (read the details below),  this is a huge constraint. Not being able to listen and respond to folder or feed events makes it a nonstarter to use this API for serious development from VFP.

 

Download/Update/Refresh: There’s something wrong with either the API implementation of the Feed Download Engine, or the Engine itself.

 

I haven’t been able to download more than 4 Feeds in a row without the API becoming non responsive and stalling Foxpro, to finally get an ole error message. In order to see this behavior you may have to leave the Foxpro session alone for several minutes, i.e., 20 or more.

 

Want to try this? If you use my example form, you’ll notice that whenever you click on the Feed (parent treeview element) it will ask you to perform a download.

 In case you answer YES, the download should be a quick process, 1 or 2 seconds, and you should have inmediate access to the item, i.e., you click on a entry and you see the html page.

If this isn't the case, it mens that VFP is still waiting a response from the API, in the meantime, you will be able to click on other areas of the form except for the rest of the foxpro development environment, until an ole error pops up:

 

Internet Explorer 7 (Beta2) does not update automatically:

IE7 itself does not refresh its screen automatically when new feed items are created unless you F5 or click on the Feed Entry. In some cases, even doing so would not update items on a feed until you manually refresh it (right click-context menu option), try subscribing to any feed from Craigslist.org to see the results in 5 minutes.

 

Delete Feeds: Deleting a feed programmatically is available as a method but not possible, an error pops up claiming that the feed is in use by another process and can’t be accessed:

  

 

You have to use IE 7 Feed Manager to delete a feed instead.

Deleting a feed item does work though.

 

 

ADDENDUM

 

Implementing Interfaces Issues Detailed.

 

Please, bear with me on these 3 steps:

 

1. Open Object Browser and ‘browse’ for c:\windows\system32\msfeeds.dll.

2. Expand the Interfaces branch,

3. Drag and drop the IFeedFolder interface inside an empty .prg.

 

This is the message I’ve got invariably when dragging and dropping from the object browser

 

 

By ignoring the error a couple of times, finally you’ll get the code, but still it will error when you run it.

This line (automatically generated by the previously described process),

 

IMPLEMENTS IFeedFolder IN "Feeds.FeedWatcher"

 

, needs to be replaced manually by this other line

 

IMPLEMENTS IFeedFolder IN "msfeeds.dll"

 

(To me this is one more clue indicating there’s something wrong.)

 

So, with these modifications, at least the class code runs, but it fails when trying to establish the link between the two classes, event and Feed, as shown in the following code:

 

oFeedMgr = NEWOBJECT("Microsoft.FeedsManager")

oRootFolder = oFeedMgr.RootFolder

 

oFeeds=oRootFolder.Feeds

oFeed1=oFeeds.Item(1)

 

x=NEWOBJECT("myclass")

 

IF !VARTYPE(x)=="O"

        MESSAGEBOX("Couldn't create class x")

ENDIF

 

WAIT WINDOW IIF(EVENTHANDLER(oFeed1,x),"Event Handler succesful","Event Handler Failed")

 

DEFINE CLASS myclass AS session OLEPUBLIC

 

        IMPLEMENTS IFeedFolder IN "msfeeds.dll"

 

        PROCEDURE IFeedFolder_get_Feeds() AS VARIANT;

                              HELPSTRING "Retrieves the collection of feeds in this folder."

        * add user code here

        ENDPROC

 

        PROCEDURE IFeedFolder_get_Subfolders() AS VARIANT;

                              HELPSTRING "Retrieves the collection of subfolders in this folder."

        * add user code here

        ENDPROC

 

        PROCEDURE IFeedFolder_CreateFeed(name AS STRING, url AS STRING) AS VARIANT;

                              HELPSTRING "Creates a new RSS feed, and subscribes to it."

        * add user code here

        ENDPROC

 

        PROCEDURE IFeedFolder_CreateSubfolder(name AS STRING) AS VARIANT;

                              HELPSTRING "Creates a new subfolder in the folder."

        * add user code here

        ENDPROC

 

        PROCEDURE IFeedFolder_ExistsFeed(name AS STRING) AS LOGICAL;

                              HELPSTRING "Checks if a feed exists."

        * add user code here

        ENDPROC

 

        PROCEDURE IFeedFolder_GetFeed(name AS STRING) AS VARIANT;

                              HELPSTRING "Retrieves a feed by its name."

        * add user code here

        ENDPROC

 

        PROCEDURE IFeedFolder_ExistsSubfolder(name AS STRING) AS LOGICAL;

                              HELPSTRING "Checks if a subfolder exists."

        * add user code here

        ENDPROC

 

        PROCEDURE IFeedFolder_GetSubfolder(name AS STRING) AS VARIANT;

                              HELPSTRING "Retrieves a subfolder by its name."

        * add user code here

        ENDPROC

 

        PROCEDURE IFeedFolder_Delete() AS VOID;

                              HELPSTRING "Deletes this folder and all of its contents."

        * add user code here

        ENDPROC

 

        PROCEDURE IFeedFolder_get_name() AS STRING;

                              HELPSTRING "Retrieves the name of the current folder."

        * add user code here

        ENDPROC

 

        PROCEDURE IFeedFolder_Rename(name AS STRING) AS VOID;

                              HELPSTRING "Renames the folder."

        * add user code here

        ENDPROC

 

        PROCEDURE IFeedFolder_get_path() AS STRING;

                              HELPSTRING "Retrieves the path of the current folder."

        * add user code here

        ENDPROC

 

        PROCEDURE IFeedFolder_Move(newParentPath AS STRING) AS VOID;

                              HELPSTRING "Moves the feed folder to a new location."

        * add user code here

        ENDPROC

 

        PROCEDURE IFeedFolder_get_Parent() AS VARIANT;

                              HELPSTRING "Retrieves the parent of the current feed folder."

        * add user code here

        ENDPROC

 

        PROCEDURE IFeedFolder_get_IsRoot() AS LOGICAL;

                              HELPSTRING "Checks to see whether the current folder is the root folder."

        * add user code here

        ENDPROC

 

        PROCEDURE IFeedFolder_get_TotalUnreadItemCount() AS Number;

                              HELPSTRING "Retrieves the total (aggregated) number of unread items."

        * add user code here

        ENDPROC

 

        PROCEDURE IFeedFolder_get_TotalItemCount() AS Number;

                              HELPSTRING "Retrieves the total (aggregated) number of items."

        * add user code here

        ENDPROC

 

        PROCEDURE IFeedFolder_GetWatcher(scope AS VARIANT, mask AS VARIANT) AS VARIANT;

                              HELPSTRING "Retrieves the appropriate interface for events."

        * add user code here

        ENDPROC

 

ENDDEFINE

 

 

Getwatcher

 

Interesting to remark, there is a method FOLDER/FEED .GETWATCHER(par1,par2) that is supposed to return an object reference of an interface for events, despite it executes without errors and returns a vartype reference “O”, in reality is an empty object.