如何定制一款12306抢票浏览器——启动“人”线程
启动“人”线程
在《如何定制一款12306抢票浏览器——构架》一文中,我们提到“人”线程。对于熟悉Window编程的同学来说,线程间通信和信息传递不是难题。但是由于浏览器和我们“人”线程之间传递的是COM对象,这个过程就没有那么简单了。(转载请指明出于breaksoftware的csdn博客)
首先我们要明确下传递的到底是什么COM对象。一般来说,如果我们要操控浏览器中的页面,都是从IWebBrowser接口对象开始的。我们这儿也是要传递这个接口对象
VOID CAutoMan::ThreadFun(){ m_dwQueryTime = QUERYTIMESLOW; while ( WAIT_TIMEOUT == WaitForSingleObject(m_hStopEvent, m_dwQueryTime )) { ConvertInterface(); if ( NULL == m_spWindow ) { continue; } CComBSTR bstrUrl; HRESULT hr = m_spWindow->get_LocationURL(&bstrUrl); CComPtr<IHTMLDocument2> spDoc; CComPtr<IDispatch> spDispatch; hr = m_spWindow->get_Document(&spDispatch); if ( FAILED(hr) || NULL == spDispatch ){ continue; } hr = spDispatch->QueryInterface( IID_IHTMLDocument2, (LPVOID*)&spDoc); try { if ( m_DealWebPage.IsQueryPage(spDoc, bstrUrl)) { hr = m_DealWebPage.InsertButtonInQueryPage(spDoc); if ( m_bStartQuery ) { hr = m_DealWebPage.QueryTicketsInfo(spDoc); if (FAILED(hr)) { hr = m_DealWebPage.StartQueryInQueryPage(spDoc); } } else { } } else if ( m_DealWebPage.IsBookingPage(spDoc, bstrUrl) ) { hr = m_DealWebPage.BookTickets(spDoc); if (SUCCEEDED(hr)) { // 待处理,退出线程 } else { } } } catch(...) { } }}“人”线程会每隔m_dwQueryTime毫秒进行一次轮询操作。操作的内容就是:
1 查询当前URL
2 如果当前URL是订票查询页面(m_DealWebPage.IsQueryPage(spDoc, bstrUrl)),则进行
A 插入控制按钮(hr = m_DealWebPage.InsertButtonInQueryPage(spDoc);)
B 检查是否有票(hr = m_DealWebPage.QueryTicketsInfo(spDoc);)
C 在不存在其票的情况下点击刷新按钮的操作(hr = m_DealWebPage.StartQueryInQueryPage(spDoc);)
3 如果当前是确认订单页面(m_DealWebPage.IsBookingPage(spDoc, bstrUrl)),则进行订票操作(hr = m_DealWebPage.BookTickets(spDoc);)
由于为时已晚,我无法图文并茂的讲解之后的订票过程。今天就到此休息了,今天晚上我会结合12306页面讲解其上详细的过程。