Phinecos(洞庭散人)
光荣在于平淡,艰巨因为漫长
一个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
"
) )