一个RSS阅读器类

 

class CFeedItem
{//RSS条目
public:
    CFeedItem();
    
virtual ~CFeedItem();
public:
    CString        m_strAuthor;
//作者
    CString        m_strCategory;//类别
    CString        m_strDescription;//描述信息
    CString        m_strLink;//链接地址
    CString        m_strPubDate;//发布日期
    CString        m_strSubject;//主题
    CString        m_strTitle;//标题
    CString        m_strReadStatus;//是否已读
}
;


class CFeedSource  
{//RSS源
public:
    CFeedSource();
    
virtual ~CFeedSource();

public:
    CString        m_strCopyright;
//版权
    CString        m_strDescription;//描述信息
    CString        m_strGenerator;//生产者
    CString        m_strLanguage;//语言
    CString        m_strLastBuildDate;//上次构建日期
    CString        m_strLink;//链接地址
    CString        m_strTitle;//标题
    CString        m_strTtl;
    CString        m_strWebMaster;
//管理员
    CString        m_strImageDescription;//图片描述信息
    CString        m_strImageHeight;//图片高度
    CString        m_strImageWidth;//图片宽度
    CString        m_strImageLink;//图片链接地址
    CString        m_strImageTitle;//图片标题
    CString        m_strImageUrl;//图片Url
    CString        m_strVersion;//图片版本
}
;


class CFeed
{//RSS种子
public:
    CFeed();
    CFeed( CString strXMLFile );
    
virtual ~CFeed();
public:
    
static void RefreshAll();
    
static void MarkItemRead( CString strLink );
    
static void DeleteFeedSource( CString strLink );
    
static void DeleteListArray( CStringArray& strLinkArray );
    
static void GetFeedSourceList( CStringArray& strTitleArray, CStringArray& strLinkArray );
    
void LoadLocal( CString& strLink );
    
void BuildFromFile( CString strXMLFile );
    CFeedSource                        m_source;        
// Feed Source
    CArray<CFeedItem,CFeedItem>        m_item;            // Feed Item
    BOOL                            m_bAdded;
    
void Save( BOOL bSaveSource = TRUE );
private:
    
static CString EscapeQuote( CString strValue );
    
static CString GetModuleFileDir();
    
static CString GetFieldValue( FieldsPtr fields, long nIndex );
    
static CString GetComError( _com_error& e );
    
static BOOL ExecuteSQL( _ConnectionPtr& pCnn, CString& strSQL, CString& strMsg );
    
void GetVersion(MSXML2::IXMLDOMNode *pNode);
    
void IterateChildNodes(MSXML2::IXMLDOMNode *pNode);
    
void BuildImage(MSXML2::IXMLDOMNode *pNode);
    
void BuildItem(MSXML2::IXMLDOMNode *pNode);
    MSXML2::IXMLDOMDocument2
*        m_pDoc;            // XML DOM Document
    int                                m_nDepth;
}
;




// FeedSource.cpp: implementation of the CFeedSource class.
//
//////////////////////////////////////////////////////////////////////

#include 
"stdafx.h"
#include 
"AgileReader.h"
#include 
"FeedSource.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CFeedItem::CFeedItem()
{
}


CFeedItem::
~CFeedItem()
{
}


CFeedSource::CFeedSource()
{

}


CFeedSource::
~CFeedSource()
{

}


CFeed::CFeed()
{
    m_pDoc 
= NULL;
    m_nDepth 
= 0;
    m_bAdded 
= FALSE;
}


CFeed::CFeed( CString strXMLFile )
{
    m_pDoc 
= NULL;
    m_nDepth 
= 0;
    m_bAdded 
= FALSE;
    BuildFromFile( strXMLFile );
}


CFeed::
~CFeed()
{

}


/////////////////////////////////////////////////////////////////////////////
// Build XML Feed Information from an XML File
//
// strXMLFile:        Parsed in XML File Name
// This function will build Feed Object from scratch by parsing XML Feed Information
// Result is stored in m_source and m_item objects
//
void CFeed::BuildFromFile(CString strXMLFile)
{
    CString        strTmpFile 
= GetModuleFileDir() + _T("\\AgileReader.xml");

    
// Step 0. Download XML File
    if ( URLDownloadToFile( NULL, strXMLFile, strTmpFile,0, NULL ) != S_OK )
    
{//下载XML文件
        AfxMessageBox( _T("Failed to download "+ strXMLFile );
        
return;
    }



    
// Step 1. Open XML Document, if open fails, then return
    if ( m_pDoc != NULL )
    
{
        m_pDoc
->Release();
        m_pDoc 
= NULL;
    }

    
if ( SUCCEEDED (CoCreateInstance(MSXML2::CLSID_DOMDocument,
                                    NULL,
                                    CLSCTX_INPROC_SERVER,
                                    MSXML2::IID_IXMLDOMDocument,
                                    reinterpret_cast
<void**>(&m_pDoc))))

    m_pDoc
->put_async( VARIANT_FALSE );
    
if ( m_pDoc->load( _bstr_t(strTmpFile) ) == VARIANT_FALSE )
    
{//加载XML文档
        
// Failed to load XML Document, report error message
        AfxMessageBox( _T("Failed to load XML Document") );
        
return;
    }


    
// Step 2. Get version property if it is available
    
// Step 3. Iterate to channel node, get the following child items
    
// title
    
// link
    
// description
    
// language
    
// copyright
    
// webMaster
    
// lastBuildDate
    
// ttl
    
// generator
    
// Then go to image node, get the following items
    
//        title
    
//        url
    
//        link
    
//        width
    
//        height
    
//        description

    
// Step 4. go to item node, get the following items
    
//        title
    
//        description
    
//        link
    
//        author
    
//        category
    
//        pubDate
    
//        subject
    MSXML2::IXMLDOMNode        *pNode = NULL;
    
if ( SUCCEEDED(m_pDoc->QueryInterface(MSXML2::IID_IXMLDOMNode, 
                reinterpret_cast
<void**>(&pNode))))
    
{
        IterateChildNodes(pNode);
        pNode
->Release();
        pNode 
= NULL;
    }


    
// We are not using smart pointer, so we have to release it outself
    if ( m_pDoc )
    
{
        m_pDoc
->Release();
        m_pDoc 
= NULL;
    }

}


/////////////////////////////////////////////////////////////////////////////
// Get Feed Version Information
//
void CFeed::GetVersion(MSXML2::IXMLDOMNode *pNode)
{
}


/////////////////////////////////////////////////////////////////////////////
// Iterate Child Node
//
void CFeed::IterateChildNodes(MSXML2::IXMLDOMNode *pNode)
{//迭代访问所有子节点
    BSTR        bstrNodeName;

    
if ( pNode )
    
{
        m_nDepth
++;
        CString strOutput;
        pNode
->get_nodeName(&bstrNodeName);

        
//
        
// Find out the node type (as a string).
        
//
        BSTR bstrNodeType;
        pNode
->get_nodeTypeString(&bstrNodeType);
        CString strType;
        strType 
= CString( bstrNodeType );
        SysFreeString(bstrNodeType);

        MSXML2::DOMNodeType eEnum;
        pNode
->get_nodeType(&eEnum);

        CString strValue;
        BSTR bstrValue;
        
switch( eEnum )
        
{
            
case MSXML2::NODE_TEXT:
            
{
                
// Text string in the XML document
                BSTR bstrValue;
                pNode
->get_text(&bstrValue);
                strOutput 
= CString( bstrValue );
                SysFreeString(bstrValue);
                
break;
            }

            
case MSXML2::NODE_COMMENT:
            
{
                
// Comment in the XML document
                VARIANT vValue;
                pNode
->get_nodeValue(&vValue);
                VariantClear(
&vValue);
                
break;
            }

            
case MSXML2::NODE_PROCESSING_INSTRUCTION:
            
{
                
// Processing instruction
                strOutput = CString( bstrNodeName );
                
break;
            }

            
case MSXML2::NODE_ELEMENT:
            
{
                
// Element
                strOutput = CString( bstrNodeName );
                
if ( strOutput == _T("rss") )
                
{
                    GetVersion( pNode );
                }

                
else if ( strOutput == _T("copyright") )
                
{
                    pNode
->get_text(&bstrValue);
                    m_source.m_strCopyright 
= CString( bstrValue );
                }

                
else if ( strOutput == _T("title"&& m_nDepth == 4 )
                
{
                    pNode
->get_text(&bstrValue);
                    m_source.m_strTitle 
= CString( bstrValue );
                }

                
else if ( strOutput == _T("link"&& m_nDepth == 4 )
                
{
                    pNode
->get_text(&bstrValue);
                    m_source.m_strLink 
= CString( bstrValue );
                }

                
else if ( strOutput == _T("description"&& m_nDepth == 4 )
                
{
                    pNode
->get_text(&bstrValue);
                    m_source.m_strDescription 
= CString( bstrValue );
                }

                
else if ( strOutput == _T("language") )
                
{
                    pNode
->get_text(&bstrValue);
                    m_source.m_strLanguage 
= CString( bstrValue );
                }

                
else if ( strOutput == _T("webMaster") )
                
{
                    pNode
->get_text(&bstrValue);
                    m_source.m_strWebMaster 
= CString( bstrValue );
                }

                
else if ( strOutput == _T("lastBuildDate") )
                
{
                    pNode
->get_text(&bstrValue);
                    m_source.m_strLastBuildDate 
= CString( bstrValue );
                }

                
else if ( strOutput == _T("ttl") )