MSXML.XMLHttp

用 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. 如果在未响应时,提前退出程序,又该如何释放内存?

你可能感兴趣的:(MSXML.XMLHttp)