c++怎样请编写函数fun,该函数的功能是查询功能

C++&查询硬件与系统配置的API函数
ActivateKeyboardLayout
激活一个新的键盘布局。键盘布局定义了按键在一种物理性键盘上的位置与含义
用于生成简单的声音
将一个字串从ANSI字符集转换到OEM字符集
ClipCursor
将指针限制到指定区域
ConvertDefaultLocale
将一个特殊的地方标识符转换成真实的地方ID
CreateCaret
根据指定的信息创建一个插入符(光标),并将它选定为指定窗口的默认插入符
DestroyCaret
清除(破坏)一个插入符
EnumCalendarInfo
枚举在指定“地方”环境中可用的日历信息
EnumDateFormats
列举指定的“当地”设置中可用的长、短日期格式
EnumSystemCodePages
枚举系统中已安装或支持的代码页
EnumSystemLocales
枚举系统已经安装或提供支持的“地方”设置
EnumTimeFormats
枚举一个指定的地方适用的时间格式
ExitWindowsEx
退出windows,并用特定的选项重新启动
ExpandEnvironmentStrings
扩充环境字串
FreeEnvironmentStrings
翻译指定的环境字串块
判断目前正在生效的ANSI代码页
GetAsyncKeyState
判断函数调用时指定虚拟键的状态
GetCaretBlinkTime
判断插入符光标的闪烁频率
GetCaretPos
判断插入符的当前位置
GetClipCursor
取得一个矩形,用于描述目前为鼠标指针规定的剪切区域
GetCommandLine
获得指向当前命令行缓冲区的一个指针
GetComputerName
取得这台计算机的名称
取得与指定代码页有关的信息
GetCurrencyFormat
针对指定的“地方”设置,根据货币格式格式化一个数字
获取目前选择的鼠标指针的句柄
GetCursorPos
获取鼠标指针的当前位置
GetDateFormat
针对指定的“当地”格式,对一个系统日期进行格式化
GetDoubleClickTime
判断连续两次鼠标单击之间会被处理成双击事件的间隔时间
GetEnvironmentStrings
为包含了当前环境字串设置的一个内存块分配和返回一个句柄
GetEnvironmentVariable
取得一个环境变量的值
GetInputState
判断是否存在任何待决(等待处理)的鼠标或键盘事件
GetKBCodePage
由GetOEMCP取代,两者功能完全相同
GetKeyboardLayout
取得一个句柄,描述指定应用程序的键盘布局
GetKeyboardLayoutList
获得系统适用的所有键盘布局的一个列表
GetKeyboardLayoutName
取得当前活动键盘布局的名称
GetKeyboardState
取得键盘上每个虚拟键当前的状态
GetKeyboardType
了解与正在使用的键盘有关的信息
GetKeyNameText
在给出扫描码的前提下,判断键名
GetKeyState
针对已处理过的按键,在最近一次输入信息时,判断指定虚拟键的状态
GetLastError
针对之前调用的api函数,用这个函数取得扩展错误信息
GetLocaleInfo
取得与指定“地方”有关的信息
GetLocalTime
取得本地日期和时间
GetNumberFormat
针对指定的“地方”,按特定的格式格式化一个数字
判断在OEM和ANSI字符集间转换的windows代码页
GetQueueStatus
判断应用程序消息队列中待决(等待处理)的消息类型
GetSysColor
判断指定windows显示对象的颜色
GetSystemDefaultLangID
取得系统的默认语言ID
GetSystemDefaultLCID
取得当前的默认系统“地方”
GetSystemInfo
取得与底层硬件平台有关的信息
GetSystemMetrics
返回与windows环境有关的信息
GetSystemPowerStatus
获得与当前系统电源状态有关的信息
GetSystemTime
取得当前系统时间,这个时间采用的是“协同世界时间”(即UTC,也叫做GMT)格式
GetSystemTimeAdjustment
使内部系统时钟与一个外部的时钟信号源同步
GetThreadLocale
取得当前线程的地方ID
GetTickCount
用于获取自windows启动以来经历的时间长度(毫秒)
GetTimeFormat
针对当前指定的“地方”,按特定的格式格式化一个系统时间
GetTimeZoneInformation
取得与系统时区设置有关的信息
GetUserDefaultLangID
为当前用户取得默认语言ID
GetUserDefaultLCID
取得当前用户的默认“地方”设置
GetUserName
取得当前用户的名字
GetVersion
判断当前运行的Windows和DOS版本
GetVersionEx
取得与平台和操作系统有关的版本信息
在指定的窗口隐藏插入符(光标)
IsValidCodePage
判断一个代码页是否有效
IsValidLocale
判断地方标识符是否有效
keybd_event
这个函数模拟了键盘行动
LoadKeyboardLayout
载入一个键盘布局
MapVirtualKey
根据指定的映射类型,执行不同的扫描码和字符转换
MapVirtualKeyEx
根据指定的映射类型,执行不同的扫描码和字符转换
MessageBeep
播放一个系统声音。系统声音的分配方案是在控制面板里决定的
mouse_event
模拟一次鼠标事件
OemKeyScan
判断OEM字符集中的一个ASCII字符的扫描码和Shift键状态
将OEM字符集的一个字串转换到ANSI字符集
SetCaretBlinkTime
指定插入符(光标)的闪烁频率
SetCaretPos
指定插入符的位置
SetComputerName
设置新的计算机名
将指定的鼠标指针设为当前指针
SetCursorPos
设置指针的位置
SetDoubleClickTime
设置连续两次鼠标单击之间能使系统认为是双击事件的间隔时间
SetEnvironmentVariable
将一个环境变量设为指定的值
SetKeyboardState
设置每个虚拟键当前在键盘上的状态
SetLocaleInfo
改变用户“地方”设置信息
SetLocalTime
设置当前地方时间
SetSysColors
设置指定窗口显示对象的颜色
SetSystemCursor
改变任何一个标准系统指针
SetSystemTime
设置当前系统时间
SetSystemTimeAdjustment
定时添加一个校准值使内部系统时钟与一个外部的时钟信号源同步
SetThreadLocale
为当前线程设置地方
SetTimeZoneInformation
设置系统时区信息
在指定的窗口里显示插入符(光标)
ShowCursor
控制鼠标指针的可视性
SwapMouseButton
决定是否互换鼠标左右键的功能
SystemParametersInfo
获取和设置数量众多的windows系统参数
SystemTimeToTzSpecificLocalTime
将时间转换成地方时间
根据当前的扫描码和键盘信息,将一个虚拟键转换成ASCII字符
根据当前的扫描码和键盘信息,将一个虚拟键转换成Unicode字符
UnloadKeyboardLayout
卸载指定的键盘布局
针对Windows字符集中一个ASCII字符,判断虚拟键码和Shift键的状态
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。如何定制一款12306抢票浏览器——实现自动查询和预定功能
& & &检查是否进入订票页面
& & & & 判断是否进入订票页面,我是确定了两个标准:&
& & & & 1 网址是否为http://www.12306.cn/mormhweb/kyfw/
& & & & 2 该页面否有查询按钮
BOOL CDeal12306WebPage::IsQueryPage( CComPtr&IHTMLDocument2& & spDoc, CComBSTR & bstrUrl ) &
& & HRESULT hr = E_FAIL; &
& & do &{ &
& & & & CString cstrUrl = CString((LPWSTR)bstrUrl); &
& & & & if ( 0 == cstrUrl.CompareNoCase(LOGIN12306URL) ) { &
& & & & & & CComPtr&IHTMLElement& spQueryB &
& & & & & & hr = GetQueryButtonInQueryPage( spDoc, spQueryButton); &
& & & & & & CHECKHRPOINTER(hr, spQueryButton); &
& & & & } &
& & } while (0); &
& & return FAILED(hr) ? FALSE : TRUE; &
& & & & &URL很好检测,那么我们如何判断是否存在查询按钮呢?我们先看一下订票页面的页面特征。
& & & & 解决跨域问题
& & & & 可以见得订票页面内部嵌入了两个Iframe,而我们关心的那块页面恰恰就是最里面一层IFrame。那我们直接通过最外层的Doc获取到最里面的Doc,然后在最里面的Doc执行有关的查询操作即可。然而熟悉javascript的同学可能马上就会想到&跨域&问题。其实在层面,跨域问题是很好解决的。
HRESULT CDeal12306WebPage::GetIFrameDoc( CComPtr&IHTMLDocument2&& spDoc, &&
& & const CString& cstrIFrameName, CComPtr&IHTMLDocument2&& spInnerDoc ) &
& & HRESULT hr = E_FAIL; &
& & do { &
& & & & CComQIPtr&IHTMLFramesCollection2& spFrameC &
& & & & hr = spDoc-&get_frames(&spFrameCollection); &
& & & & CHECKHRPOINTER(hr, spFrameCollection); &
& & & & CComVariant IframeNameReq = CComBSTR(cstrIFrameName.GetString()); &
& & & & CComVariant FrameP &
& & & & hr = spFrameCollection-&item(&IframeNameReq, &FramePage); &
& & & & CHECKHRPOINTER(hr,FramePage.pdispVal); &
& & & & CComPtr&IHTMLWindow2& spIFrameP &
& & & & hr = FramePage.pdispVal-&QueryInterface(IID_IHTMLWindow2, (LPVOID*)&spIFramePage); &
& & & & CHECKHRPOINTER(hr, spIFramePage); &
& & & & hr = spIFramePage-&get_document(&spInnerDoc); &
& & & & if ( E_ACCESSDENIED == hr ) { &
& & & & & & CComQIPtr&IServiceProvider& spServiceProvider = spIFrameP &
& & & & & & CHECKPOINT(spServiceProvider); &
& & & & & & CComQIPtr&IWebBrowser2& spInnerWebB &
& & & & & & hr = spServiceProvider-&QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (LPVOID*)&spInnerWebBrowser); &
& & & & & & CHECKHRPOINTER(hr, spInnerWebBrowser); &
& & & & & & CComPtr&IDispatch& spD &
& & & & & & hr = spInnerWebBrowser-&get_Document(&spDisp); &
& & & & & & CHECKHRPOINTER(hr, spDisp); &
& & & & & & hr = spDisp-&QueryInterface(IID_IHTMLDocument2, (LPVOID*)&spInnerDoc); &
& & & & & & CHECKHRPOINTER(hr, spInnerDoc); &
& & & & } &
& & } while (0); &
& & & & 上面这个函数试图在spDoc页面中获取其内嵌的名字是cstrIFrameName的IFrame的Doc。于是我们要获取其中最里面一层Iframe的Doc可以如下调用
HRESULT CDeal12306WebPage::GetIFrameNamedIFramePageDoc( CComPtr&IHTMLDocument2& & spDoc, &&
& & CComPtr&IHTMLDocument2& & spInnerDoc ) &
& & HRESULT hr = E_FAIL; &
& & do { &
& & & & hr = &GetIFrameDoc(spDoc, L&iframepage&, spInnerDoc); &
& & & & CHECKHRPOINTER(hr, spInnerDoc); &
& & } while (0); &
HRESULT CDeal12306WebPage::GetIFrameNamedMainDoc( CComPtr&IHTMLDocument2& & spIFramPageDoc, &
& & CComPtr&IHTMLDocument2& & spMainDoc ) &
& & HRESULT hr = E_FAIL; &
& & do { &
& & & & hr = &GetIFrameDoc(spIFramPageDoc, L&main&, spMainDoc); &
& & & & CHECKHRPOINTER(hr, spMainDoc); &
& & } while (0); &
HRESULT CDeal12306WebPage::GetMainDoc( CComPtr&IHTMLDocument2& & spDoc, &
& & CComPtr&IHTMLDocument2& & spMainDoc ) &
& & HRESULT hr = E_FAIL; &
& & do { &
& & & & CComPtr&IHTMLDocument2& spIFramePageD &
& & & & hr = GetIFrameNamedIFramePageDoc(spDoc, spIFramePageDoc); &
& & & & CHECKHRPOINTER(hr, spIFramePageDoc); &
& & & & hr = GetIFrameNamedMainDoc(spIFramePageDoc, spMainDoc); &
& & & & CHECKHRPOINTER(hr, spMainDoc); &
& & } while (0); &
& & & & 当我们获得最里层的Doc后,我们将根据页面结构获取Class为cx_from的Table元素。
& & & & & 获取这个Table的原因是,之后我们会以该Table为节点,执行&查询按钮&查找的操作。
HRESULT CDeal12306WebPage::GetQueryButtonInQueryPage( CComPtr&IHTMLDocument2& & spDoc, CComPtr&IHTMLElement& & spQueryButtonElem ) &
& & HRESULT hr = E_FAIL; &
& & do &{ &
& & & & CComPtr&IHTMLDocument2& spMainD &
& & & & hr = GetMainDoc( spDoc, spMainDoc); &
& & & & CHECKHRPOINTER(hr, spMainDoc); &
& & & & CComPtr&IHTMLElement& spEnter_wE &
& & & & hr = GetEnter_wElement(spMainDoc, spEnter_wElem ); &
& & & & CHECKHRPOINTER(hr, spEnter_wElem); &
& & & & CComPtr&IHTMLElement& spQueryT &
& & & & hr = GetQueryTable(spEnter_wElem, spQueryTable); &
& & & & CHECKHRPOINTER(hr, spQueryTable); &
& & & & CComPtr&IHTMLButtonElement& spQueryB &
& & & & hr = GetQueryButtonInQueryPage(spQueryTable, spQueryButton); &
& & & & CHECKHRPOINTER(hr, spQueryButton); &
& & & & hr = spQueryButton-&QueryInterface(IID_IHTMLElement, (LPVOID*)& spQueryButtonElem); &
& & & & CHECKHRPOINTER(hr, spQueryButtonElem); &
& & } while (0); &
& & & & 查询按钮在这个table中的位置是
& & & & 于是通过该Table查询&查询&按钮的代码是
HRESULT CDeal12306WebPage::GetQueryButtonInQueryPage( CComPtr&IHTMLElement&& spQueryTable, &&
& & CComPtr&IHTMLButtonElement& & spQueryButton ) &
& & HRESULT hr = E_FAIL; &
& & do { &
& & & & CComPtr&IHTMLElement& spTB &
& & & & hr = GetElementByIndex(spQueryTable, 0, spTBody); &
& & & & CHECKHRPOINTER(hr, spTBody); &
& & & & CComPtr&IHTMLElement& spFirstTR; &
& & & & hr = GetElementByIndex(spTBody, 0, spFirstTR); &
& & & & CHECKHRPOINTER(hr, spFirstTR); &
& & & & CComPtr&IHTMLElement& spEighthTR; &
& & & & hr = GetElementByIndex(spFirstTR, 8, spEighthTR); &
& & & & CHECKHRPOINTER(hr, spEighthTR); &
& & & & CComPtr&IHTMLElement& spButtonT &
& & & & hr = GetElementByIndex(spEighthTR, 0, spButtonTemp); &
& & & & CHECKHRPOINTER(hr, spButtonTemp); &
& & & & hr = spButtonTemp-&QueryInterface(IID_IHTMLButtonElement, (LPVOID*)&spQueryButton); &
& & & & CHECKHRPOINTER(hr, spQueryButton); &
& & } while (0); &
& & & & 插入开始和停止自动查询按钮
& & & & 为了在该页面中提供给用于控制开启和关闭自动查询功能的按钮,我插入了两个按钮。如下图
& & & & 我们看下&单程&和&返程&按钮的页面结构
& & & & 我会在Name为querySingleForm的form下的class为cx_tab的Div下插入&开始&和&停止&按钮。
HRESULT CDeal12306WebPage::InsertButtonInQueryPage( CComPtr&IHTMLDocument2& & spDoc ) &
& & HRESULT hr = E_FAIL; &
& & do &{ &
& & & & CComPtr&IHTMLDocument2& spMainD &
& & & & hr = GetMainDoc( spDoc, spMainDoc); &
& & & & CHECKHRPOINTER(hr, spMainDoc); &
& & & & CComPtr&IHTMLElement& spEnter_wE &
& & & & hr = GetEnter_wElement(spMainDoc, spEnter_wElem ); &
& & & & CHECKHRPOINTER(hr, spEnter_wElem); &
& & & & CComPtr&IHTMLElement& spF &
& & & & hr = GetQuerySingleForm(spEnter_wElem, spForm); &
& & & & CHECKHRPOINTER(hr, spForm); &
& & & & hr = InsertButtons( spForm ); &
& & } while (0); &
HRESULT CDeal12306WebPage::InsertButtons(CComPtr&IHTMLElement& & spEnter_wElem ) &
& & HRESULT hr = E_FAIL; &
& & do { &
& & & & CComPtr&IHTMLElement& spD &
& & & & hr &= GetInsertButtonElem(spEnter_wElem, spDiv); &
& & & & if ( &FALSE == IsStartButtonExist(spDiv) ) { &
& & & & & & hr = InsertStartButton(spDiv); &
& & & & & & CHECKHR(hr); &
#ifdef DEBUG &
& & & & & & if ( FALSE == IsStartButtonExist(spDiv) ) { &
& & & & & & & & DebugBreak(); &
& & & & & & } &
& & & & } &
& & & & &&
& & & & if ( FALSE == IsStopButtonExist(spDiv) ) { &
& & & & & & hr = InsertStopButton(spDiv); &
& & & & & & CHECKHR(hr); &
#ifdef DEBUG &
& & & & & & if ( FALSE == IsStopButtonExist(spDiv) ) { &
& & & & & & & & DebugBreak(); &
& & & & & & } &
& & & & } &
& & & & &&
& & } while (0); &
HRESULT CDeal12306WebPage::GetInsertButtonElem( CComPtr&IHTMLElement& & spForm, &&
& & CComPtr&IHTMLElement& & spDiv ) &
& & HRESULT hr = E_FAIL; &
& & do { &
& & & & CComPtr&IHTMLElement& spCx_TabD &
& & & & hr = GetElementByClassName(spForm, L&cx_tab&, spCx_TabDiv); &
& & & & CHECKHRPOINTER(hr, spCx_TabDiv); &
& & & & hr = GetElementByIndex(spCx_TabDiv, 0, spDiv); &
& & & & CHECKHRPOINTER(hr, spDiv); &
& & } while (0); &
HRESULT CDeal12306WebPage::InsertStartButton( CComPtr&IHTMLElement& & spElem ) &
& & HRESULT hr = E_FAIL; &
& & do { &
& & & & CComBSTR bstrWhere(L&beforeEnd&); &
& & & & CString cstrHTML; &
& & & & cstrHTML.Format( BUTTONFORMAT, STARTBUTTONID, STARTCOMD, L&开始& ); &
& & & & CComBSTR bstrHTML(cstrHTML.GetString()); &
& & & & hr = spElem-&insertAdjacentHTML( bstrWhere, bstrHTML ); &
& & & & CHECKHR(hr); &
& & } while (0); &
HRESULT CDeal12306WebPage::InsertStopButton( CComPtr&IHTMLElement& & spElem ) &
& & HRESULT hr = E_FAIL; &
& & do { &
& & & & CComBSTR bstrWhere(L&beforeEnd&); &
& & & & CString cstrHTML; &
& & & & cstrHTML.Format( BUTTONFORMAT, STOPBUTTONID, STOPCMD, L&停止& ); &
& & & & CComBSTR bstrHTML(cstrHTML.GetString()); &
& & & & hr = spElem-&insertAdjacentHTML( bstrWhere, bstrHTML ); &
& & & & CHECKHR(hr); &
& & } while (0); &
#define BUTTONFORMAT & &L&&li id=\&%s\&&&a href=\&%s\& style=\&width:50height:30\&&%s&/a&&/li&& &
#define STARTBUTTONID & L&StartButton& &
#define STOPBUTTONID & &L&StopButton& &
#define STARTCOMD & & & L&http://www.12306.cn/mormhweb/kyfw/StartQuery.fl& &
#define STOPCMD & & & & L&http://www.12306.cn/mormhweb/kyfw/StopQuery.fl& &
& & & & 当我们点击开始按钮是,页面将试图跳转到http://www.12306.cn/mormhweb/kyfw/StartQuery.fl,此时,我将终止该跳转,同时将&开启查询&标志设置为TRUE。
[cpp] view plaincopy
void CBrowserHost::BeforeNavigate2(IDispatch *pDisp, VARIANT *url, &
& & & & VARIANT *Flags, VARIANT *TargetFrameName, VARIANT *PostData, &
& & & & VARIANT *Headers, VARIANT_BOOL *Cancel) &
& & do &{ &
& & & & if ( NULL != url ) { &
& & & & & & CString cstrUrl((LPWSTR)(url-&bstrVal)); &
& & & & & & if ( 0 == cstrUrl.CompareNoCase(SETTINGOK) ) { &
& & & & & & & &&& &
& & & & & & } &
& & & & & & else if ( 0 == cstrUrl.CompareNoCase(STARTCOMD) ) { &
& & & & & & & & *Cancel = VARIANT_TRUE; &
& & & & & & & & m_AutoMan.SetStart(TRUE); &
& & & & & & & & &
& & & & & & } &
& & & & & & else if ( &0 == cstrUrl.CompareNoCase(STOPCMD) ) { &
& & & & & & & & *Cancel = VARIANT_TRUE; &
& & & & & & & & m_AutoMan.SetStart(FALSE); &
& & & & & & & & &
& & & & & & } &
& & & & } &
& & & & *Cancel = VARIANT_FALSE; &
& & } while (0); &
& & & & 点击停止按钮原理同点击开始按钮原理一致。此处不再赘述。
& & & & 当用户选择好出发地和目的地及时间后,用户点击查询按钮。并点击&开始&按钮。我们的&人&线程就开始了自动查询操作。
& & & & 查询是否存在票,有票则预定,无票则再次查询
& & & & 当我们执行完一次查询后,我们要查看下搜索结果列表信息中用户选择的车次是否存在票。我们先看一下页面结构
& & & & 其查找该节点的方法如下
HRESULT CDeal12306WebPage::QueryTicketsInfo( CComPtr&IHTMLDocument2& & spDoc ) &
& & HRESULT hr = E_FAIL; &
& & do &{ &
& & & & CComPtr&IHTMLDocument2& spMainD &
& & & & hr = GetMainDoc( spDoc, spMainDoc); &
& & & & CHECKHRPOINTER(hr, spMainDoc); &
& & & & CComPtr&IHTMLElement& spEnter_wE &
& & & & hr = GetEnter_wElement(spMainDoc, spEnter_wElem ); &
& & & & CHECKHRPOINTER(hr, spEnter_wElem); &
& & & & CComPtr&IHTMLElement& spIDG &
& & & & hr = GetElementByID( spEnter_wElem, L&gridbox&, spIDGridbox); &
& & & & CHECKHRPOINTER(hr, spIDGridbox); &
& & & & CComPtr&IHTMLElement& spT &
& & & & hr = GetElementByIndex( spIDGridbox, 0, spTable); &
& & & & CHECKHRPOINTER(hr, spTable); &
& & & & CComPtr&IHTMLElement& spT &
& & & & hr = GetElementByIndex( spTable, 0, spTbody); &
& & & & CHECKHRPOINTER(hr, spTbody); &
& & & & CComPtr&IHTMLElement& spTr; &
& & & & hr = GetElementByIndex( spTbody, 1, spTr); &
& & & & CHECKHRPOINTER(hr, spTr); &
& & & & CComPtr&IHTMLElement& spTd; &
& & & & hr = GetElementByIndex(spTr, 0, spTd); &
& & & & CHECKHRPOINTER(hr, spTd); &
& & & & CComPtr&IHTMLElement& spD &
& & & & hr = GetElementByIndex(spTd, 0, spDiv); &
& & & & CHECKHRPOINTER(hr, spDiv); &
& & & & CComPtr&IHTMLElement& spDiv2; &
& & & & hr = GetElementByIndex(spDiv, 0, spDiv2); &
& & & & CHECKHRPOINTER(hr, spDiv2); &
& & & & CComPtr&IHTMLElement& spTable2; &
& & & & hr = GetElementByIndex(spDiv2, 0, spTable2); &
& & & & CHECKHRPOINTER(hr, spTable2); &
& & & & CComPtr&IHTMLElement& spTbody2; &
& & & & hr = GetElementByIndex(spTable2, 0, spTbody2); &
& & & & CHECKHRPOINTER(hr, spTbody2); &
& & & & CComPtr&IHTMLElementCollection& spElemC &
& & & & hr = GetElementCollection(spTbody2, spElemCollection ); &
& & & & CHECKHRPOINTER(hr, spElemCollection); &
& & & & long lCount = 0; &
& & & & hr = spElemCollection-&get_length(&lCount); &
& & & & CHECKHR(hr); &
& & & & for ( long lindex = 0; lindex & lC lindex++ ) { &
& & & & & & if ( 0 == lindex ) { &
& & & & & & & & &
& & & & & & } &
& & & & & & CComVariant VarIndex = &
& & & & & & CComPtr&IDispatch& spDispatchE &
& & & & & & hr = spElemCollection-&item( VarIndex, VarIndex, &spDispatchElem ); &
& & & & & & CHECKHRPOINTER(hr,spDispatchElem); &
& & & & & & &&
& & & & & & CComPtr&IHTMLElement& spChildTr; &
& & & & & & hr = spDispatchElem-&QueryInterface(IID_IHTMLElement, (LPVOID*)& spChildTr); &
& & & & & & CHECKHRPOINTER(hr, spChildTr); &
& & & & & & hr = GetQueryInfoInTr( spChildTr ); &
& & & & & & if ( SUCCEEDED(hr) ) { &
& & & & & & & & // 点击了订购按钮了 &
& & & & & & & & &
& & & & & & } &
& & & & } &
& & } while (0); &
& & & & 上述代码执行到第57行时,for循环将逐个读取每列车的信息。为了最快速达到点击&预定&按钮,我将判断的操作放在GetQueryInfoInTr中。
HRESULT CDeal12306WebPage::GetQueryInfoInTr( CComPtr&IHTMLElement& & spElem) &
& & HRESULT hr = E_FAIL; &
& & do { &
& & & & CComPtr&IHTMLElementCollection& spElemC &
& & & & hr = GetElementCollection(spElem, spElemCollection ); &
& & & & CHECKHRPOINTER(hr, spElemCollection); &
& & & & long lCount = 0; &
& & & & hr = spElemCollection-&get_length(&lCount); &
& & & & CHECKHR(hr); &
& & & & StTrainInfo stTraininfoI &
& & & & for ( long lindex = 0; lindex & lC lindex++ ) { &
& & & & & & CComVariant VarIndex = &
& & & & & & CComPtr&IDispatch& spDispatchE &
& & & & & & hr = spElemCollection-&item( VarIndex, VarIndex, &spDispatchElem ); &
& & & & & & CHECKHRPOINTER(hr,spDispatchElem); &
& & & & & & CComPtr&IHTMLElement& spChildTd; &
& & & & & & hr = spDispatchElem-&QueryInterface(IID_IHTMLElement, (LPVOID*)& spChildTd); &
& & & & & & CHECKHRPOINTER(hr, spChildTd); &
& & & & & & hr = GetQueryInfoSubItem( spChildTd, stTraininfoItem, lindex ); & &&
& & & & & & CHECKHR(hr); &
& & & & } &
& & & & &&
& & & & CHECKHR(hr); &
& & & & CComPtr&IHTMLElement& spTd; &
& & & & hr = GetElementByIndex( spElem, lCount - 1, spTd); &
& & & & CHECKHRPOINTER(hr, spTd); &
& & & & CComPtr&IHTMLElement& spB &
& & & & hr = GetElementByIndex( spTd, 0, spButton ); &
& & & & CHECKHRPOINTER(hr, spButton); &
& & & & CComBSTR bstrClassN &
& & & & hr = spButton-&get_className(&bstrClassName); &
& & & & CHECKHR(hr); &
& & & & CString cstrClassName = bstrClassN &
& & & & if ( 0 == cstrClassName.CompareNoCase(HAVETICKETSACLASS) ) { &
& & & & & & hr = spButton-&click(); &
& & & & } &
& & & & else { &
& & & & & & // 还没有票 &
& & & & } &
& & & & m_VecTrainInfo.push_back(stTraininfoItem); &
& & } while (0); &
& & & & 我这儿做了简化:只要&预定&按钮变成可点击,即点击之。其实这儿应该做更多的判断,比如用户的席别是否有票。上述代码第44行,即是点击&预定&按钮的操作。
& & & & 如果没有票,则我们点击&查询&按钮。
HRESULT CDeal12306WebPage::StartQueryInQueryPage( CComPtr&IHTMLDocument2& & spDoc ) &
& & HRESULT hr = S_FALSE; &
& & do &{ &
& & & & CComPtr&IHTMLElement& spQueryB &
& & & & hr = GetQueryButtonInQueryPage( spDoc, spQueryButton); &
& & & & CHECKHRPOINTER(hr, spQueryButton); &
& & & & hr = spQueryButton-&click(); &
& & } while (0); &
& & & & 如此,我们便实现了自动查询和自动订票的功能。

我要回帖

更多关于 请编写函数fun,该函数的功能是 的文章

 

随机推荐