如何定制一款12306抢票浏览器――用户界面(二)
ESULT CDeal12306WebPage::GetTrainNoPassengersInSettingPage( CComPtr & spDoc,
StTrainNoPassengerInfo & stTrainPassenger )
{
HRESULT hr = E_FAIL;
do {
CComPtr spBody;
hr = spDoc->get_body(&spBody);
CHECKHRPOINTER(hr, spBody);
CComPtr spTable;
hr = GetElementByID(spBody, L"passengertable", spTable);
CHECKHRPOINTER(hr, spTable);
CComPtr spTBody;
hr = GetElementByIndex( spTable, 0, spTBody);
CHECKHRPOINTER(hr, spTBody);
for ( int i = 0; i < MAXPASSENGERCOUNT; i++ ) {
CString cstrTrID;
cstrTrID.Format(PASSENGERID, i + 1);
CComPtr spTr;
hr = GetElementByID( spTBody, cstrTrID, spTr);
CHECKHRPOINTER(hr, spTr);
StSinglePassengerInfo stSinglePassenger;
hr = GetPassengerInfo(spTr, stSinglePassenger);
CHECKHR(hr);
if ( FALSE == stSinglePassenger.cstrName.IsEmpty() &&
FALSE == stSinglePassenger.cstrTicket.IsEmpty() &&
FALSE == stSinglePassenger.cstrCardNo.IsEmpty() &&
FALSE == stSinglePassenger.cstrCardtype.IsEmpty() &&
FALSE == stSinglePassenger.cstrMobileNo.IsEmpty() &&
0 != stSinglePassenger.ListSeat.size()) {
stTrainPassenger.vecPassengerInfo.push_back(stSinglePassenger);
}
}
hr = GetTrainNoInSettingPage(spDoc, stTrainPassenger.cstrTrainNo);
} while (0);
return hr;
}
这段代码大致意思是在“设置”页面中,找到id为passengertable的元素spTable,然后找到spTable下第一个元素spTBody。spTBody下保存着每个乘客的信息,其中第一个乘客信息保存在id是“passenger_1”的元素下,第二个保存在“passenger_2”元素下……当单个乘客所有信息都不为空时,将其保存在一个stTrainPassenger.vecPassengerInfo中。最后我们要获取火车车次的信息,将其保存在stTrainPassenger.cstrTrainNo中。
上面的函数大部分是经过封装的。其中几个经常用的函数是
[cpp]
HRESULT GetElementCollection(CComPtr & spElem,
CComPtr & spElemCollection );
enum EQUERYTYPE {
EID,
ETAGNAME,
ECLASSNAME,
};
// 通过ID获取指定节点下第一个ID为cstrID的子节点
HRESULT GetElementByID(CComPtr & spElem,
const CString & cstrID,
CComPtr & spResElem);
// 通过ClassName获取指定节点下第一个class为cstrClassName的子节点
HRESULT GetElementByClassName(CComPtr & spElem,
const CString & cstrClassName,
CComPtr & spResElem);
// 通过TagName获取指定节点下第一个tag为cstrTagName的子节点
HRESULT GetElementByTagsName(CComPtr & spElem,
const CString & cstrTagName,
CComPtr & spResElem);
// 通过ID获取指定节点下第lindex子节点
HRESULT GetElementByIndex(CComPtr & spElem,
LONG lIndex,
CComPtr & spResElem);
HRESULT GetElement(CComPtr & spElem,
EQUERYTYPE eType, const CString & cstrValue,
CComPtr & spResElem);
对应的实现代码是
[cpp]
HRESULT CDeal12306WebPage::GetElementCollection( CComPtr & spElem, CComPtr & spElemCollection )
{
HRESULT hr = S_FALSE;
do {
CComPtr spDispatch;
hr = spElem->get_children(&spDispatch);
CHECKHR(hr);
hr = spDispatch->QueryInterface( IID_IHTMLElementCollection, (LPVOID*)&spElemCollection);
CHECKHR(hr);
} while (0);
return hr;
}
HRESULT CDeal12306WebPage::GetElementByID( CComPtr & spElem,
const CString & cstrID, CComPtr & spResElem )
{
retu