用 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 = "http://www.google.cn/";
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 = "http://127.0.0.1:9090/";
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. 如果在未响应时,提前退出程序,又该如何释放内存?