用 MSXML.XMLHttp 獲取網頁數據,如果是“同步”,那么
Step 1.?
在 BOOL CTestApp::InitInstance() 和 int CWinApp::ExitInstance()?分別加上??
?CoInitialize(NULL);? // 初始化 COM?? 和 ?CoUninitialize(); // 反初始化 COM
Step 2.
在使用的地方加上頭文件?
#import <msxml4.dll>
using namespace MSXML2;
Step3.
void CTestDlg::OnButton1()
{
?CString strResult;
?
?IXMLHTTPRequestPtr httpRes;
?HRESULT hr=httpRes.CreateInstance("MSXML2.XMLHTTP");
?if (!SUCCEEDED(hr) )
?{
??AfxMessageBox("無法創建XMLHTTP對象,請檢查是否安裝了MS XML運行庫!");
?}
?try
?{
??LPCTSTR url = "??
??httpRes->open("Get", url, VARIANT_FALSE, "", "");
??httpRes->send();
??if( (httpRes->readyState) == 4) //4時表示數據已加載完
??{
???strResult = httpRes->responseText.copy();
???AfxMessageBox(strResult);
??}
??httpRes.Release();
?}
?catch (_com_error &e)
?{
??AfxMessageBox(e.Description());???
?}
?}
這樣就完工了
如果是“異步”調用
Step1.
// XMLSink.h: interface for the CXMLSink class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_XMLSINK_H__95AD1101_6F98_45C9_9EE3_EC266BBF514B__INCLUDED_)
#define AFX_XMLSINK_H__95AD1101_6F98_45C9_9EE3_EC266BBF514B__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#import "msxml4.dll"
using namespace MSXML2;??
class CXMLSink : public IDispatch
{
public:
?CXMLSink();
?virtual ~CXMLSink();
?// for IUnknown
?STDMETHOD(QueryInterface)(REFIID riid, LPVOID* ppv);
?STDMETHOD_(ULONG, AddRef)();
?STDMETHOD_(ULONG, Release)();
?// for IDispatch
?STDMETHOD(GetTypeInfoCount)(UINT* pctinfo);
?STDMETHOD(GetTypeInfo)(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo);
?STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId);
??? STDMETHOD(Invoke)(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS __RPC_FAR *pDispParams, VARIANT __RPC_FAR *pVarResult, EXCEPINFO __RPC_FAR *pExcepInfo, UINT __RPC_FAR *puArgErr);
?//
?void SetEventSource(IUnknown* punk);
private:
?IUnknown*?? m_pEventSource;
?DWORD?? m_dwRef;
};
#endif // !defined(AFX_XMLSINK_H__95AD1101_6F98_45C9_9EE3_EC266BBF514B__INCLUDED_)
Step 2.
// XMLSink.cpp: implementation of the CXMLSink class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "XMLSink.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CXMLSink::CXMLSink() : m_dwRef(1), m_pEventSource(NULL)
{
}
CXMLSink::~CXMLSink()
{
?if(m_pEventSource)??
??m_pEventSource->Release();??
?m_pEventSource = NULL;?
}
// IUnknown method
STDMETHODIMP CXMLSink::QueryInterface(REFIID riid, LPVOID* ppv)??
{??
?OutputDebugString(_T("QueryInterface \n"));
?
?*ppv = NULL;??
?if(IID_IUnknown == riid)??
?{??
??*ppv = (LPUNKNOWN)this;??
??AddRef();
??return NOERROR;??
?}??
?else if (IID_IDispatch == riid)??
?{??
??*ppv = (IDispatch*)this;??
??AddRef();??
??return NOERROR;??
?}??
?else??
?{
??return E_NOTIMPL;??
?}
}??
STDMETHODIMP_(ULONG) CXMLSink::AddRef()
{
?return ++m_dwRef;
}??
STDMETHODIMP_(ULONG) CXMLSink::Release()??
{??
?if(--m_dwRef == 0)??
?{??
??delete this;??
??return 0;??
?}
?
?return m_dwRef;??
}??
// IDispatch method??
STDMETHODIMP CXMLSink::GetTypeInfoCount(UINT* pctinfo)
{
?OutputDebugString(_T("GetTypeInfoCount\n"));
?return E_NOTIMPL;
}??
STDMETHODIMP CXMLSink::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo)
{
?OutputDebugString(_T("GetTypeInfo\n"));??
?return E_NOTIMPL;
}??
STDMETHODIMP CXMLSink::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId)
{
?OutputDebugString(_T("GetIDsOfNames\n"));
?return E_NOTIMPL;
}?
????????????????
STDMETHODIMP CXMLSink::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS __RPC_FAR *pDispParams,??
????????????????? VARIANT __RPC_FAR *pVarResult, EXCEPINFO __RPC_FAR *pExcepInfo, UINT __RPC_FAR *puArgErr)??
{??
?OutputDebugString(_T("Invoke\n"));
?
?MSXML2::IXMLHTTPRequestPtr xmldom(m_pEventSource);?
?
?if(xmldom)??
?{??
??long lReadyState;??
??xmldom->get_readyState(&lReadyState);??
??
??char buf[256];??
??wsprintf(buf, "get_readystate return %d \n", lReadyState);??
??
??OutputDebugString(_T(buf));
??
??if(lReadyState == 4)??
??{??
???CString strResult = xmldom->GetresponseText().copy();
???AfxMessageBox(strResult);
??}
?}
?return NOERROR;??
}??
void CXMLSink::SetEventSource(IUnknown* punk)
{
?m_pEventSource = punk;
?if(punk)??
??punk->AddRef();
}?
Step 3.
private:
?CXMLSink m_XmlSink;
?IXMLHTTPRequestPtr m_httpRes;
Step 4.
void CDlg::OnButton1()
{
?CString strResult;
?
?HRESULT hr = m_httpRes.CreateInstance("MSXML2.XMLHTTP");
?if (!SUCCEEDED(hr) )
?{
??AfxMessageBox("無法創建XMLHTTP對象,請檢查是否安裝了MS XML運行庫!");
?}
?m_XmlSink.SetEventSource(m_httpRes);
?try
?{
??LPCTSTR url = "??
??m_httpRes->open("Get", url, VARIANT_TRUE, "", "");
??m_httpRes->put_onreadystatechange(&m_XmlSink);
??m_httpRes->send();
?}
?catch (_com_error &e)
?{
??AfxMessageBox(e.Description());???
?}
}
異步方式還未解決的問題;
1. 如果一直沒響應,超時如何處理?
2. 如果在未響應時,提前退出程序,又該如何釋放內存?