C++中XMLHTTPRequest异步使用onreadystatuschange

zz/2023/6/3 16:24:21

首先需要编写一个类,实现IDispatch接口,然后把这个类传进去,代码如下:
#ifndef XMLHTTPEVENTSINK_H_
#define XMLHTTPEVENTSINK_H_

#include "msxml.h"
#include <winnt.h>
#include <wtypes.h>
#include <windows.h>

class XMLHttpEventSink : public IDispatch
{
public:
    XMLHttpEventSink(IXMLHttpRequest* request, HANDLE completedEvent) : _refCount(1), _request(request), _completedEvent(completedEvent)
    {
        // Don't increase the reference count to the request object; doing so would create a circular reference
        // and thus a memory leak.
    }
    virtual ~XMLHttpEventSink() { }

    // IUnknown
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject);
STDMETHODIMP_(ULONG) AddRef();
    STDMETHODIMP_(ULONG) Release();

    // IDispatch
STDMETHODIMP GetTypeInfoCount(UINT *pctinfo);
STDMETHODIMP GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo);
STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId);
    STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr);
private:
    LONG _refCount;
    IXMLHttpRequest* _request;
    HANDLE _completedEvent;
};

#endif
-=====================================================
#include "XMLHttpEventSink.h"

STDMETHODIMP XMLHttpEventSink::QueryInterface(const IID &riid, void **ppvObject)
{
    if( ppvObject == NULL )
        return E_INVALIDARG;

    *ppvObject = NULL;

    if( riid == IID_IUnknown )
        *ppvObject = static_cast<IUnknown*>(this);
    else if( riid == IID_IDispatch )
        *ppvObject = static_cast<IDispatch*>(this);

    if( *ppvObject == NULL )
        return E_NOINTERFACE;

    AddRef();

    return S_OK;
}

STDMETHODIMP_(ULONG) XMLHttpEventSink::AddRef()
{
    return InterlockedIncrement(&_refCount);
}

STDMETHODIMP_(ULONG) XMLHttpEventSink::Release()
{
    LONG refCount = InterlockedDecrement(&_refCount);
    if( refCount == 0 )
    {
        delete this;
        return 0;
    }
    else
        return refCount;
}

STDMETHODIMP XMLHttpEventSink::GetTypeInfoCount(UINT *pctinfo)
{
    return E_NOTIMPL;
}

STDMETHODIMP XMLHttpEventSink::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
{
    return E_NOTIMPL;
}

STDMETHODIMP XMLHttpEventSink::GetIDsOfNames(const IID &riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
{
    return E_NOTIMPL;
}

STDMETHODIMP XMLHttpEventSink::Invoke(DISPID dispIdMember, const IID &riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
    // Since this class isn't used for anything else, Invoke will get called only for onreadystatechange, and
    // dispIdMember will always be 0.

long state;
// Retrieve the state
_request->get_readyState(&state);
    if (state == 4)
    {
        // The request has completed.
        // Get the request status.
        long status;
        _request->get_status(&status);

       if( status == 200 )
  {
   // Get the response body if we were successful.
   BSTR body;
   _request->get_responseText(&body);
  }

        // Signal the main thread we're done.
        SetEvent(_completedEvent);
    }
return S_OK;
}
-===================================================
调用代码:
CoInitialize(NULL);
IXMLHttpRequest* pRequest = GetXMLHTTP();

pRequest->setRequestHeader(L"Content-Type", L"text/xml");
pRequest->setRequestHeader("SOAPAction","http://schemas.microsoft.com/exchange/services/2006/messages/FindItem");
WideString url = L"http://mail.pudong.sh/ews/exchange.asmx";

tagVARIANT account;
account.vt = VT_BSTR;
account.bstrVal = L"MailAdmin@pudong.sh";

tagVARIANT password;
password.vt = VT_BSTR;

password.bstrVal = L"App1234";
tagVARIANT bAsync;
bAsync.vt = VT_BOOL;
bAsync.boolVal = FALSE;

WideString dataStr = L"";
tagVARIANT data;
data.vt = VT_BSTR;
data.bstrVal = dataStr.c_bstr();

HANDLE completedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
pRequest->open(L"POST", url.c_bstr(), bAsync, account, password);

IDispatch *sink = new XMLHttpEventSink(pRequest, completedEvent);
pRequest->put_onreadystatechange(sink);
pRequest->send(data);

sink->Release();
pRequest->Release();

WaitForSingleObject(completedEvent, INFINITE);
CloseHandle(completedEvent);

CoUninitialize();

转载于:https://www.cnblogs.com/yuanxiaoping_21cn_com/archive/2008/11/13/1332927.html

http://www.ngui.cc/zz/483574.html

相关文章

自定义用户控件显示属性分类、描述、默认值

在网上查了相关资料&#xff0c;大概例子如下&#xff1a;using System.ComponentModel; bool _IsCheck true; [Bindable(true), DefaultValue(true), Category("Flash 播放器窗口模式"), Description("描述中")] public bool IsCheck { …

.NET Remoting Security使用小结 – TcpChannel

谈到Security需要从下面四个方面考虑&#xff1a; 1. Authentication&#xff1a;防止非法用户的调用。 2. Authorization&#xff1a;防止合法但权限不够的用户调用。 3. Encryption&#xff1a;防止数据在传输过程中被窃取。 4. Sign&#xff1a;防止…

Flash Socket通信的安全策略问题

弄了半天没有解决&#xff0c;在ide里发布没为&#xff0c;放到web上就安全问题。哎 记个笔记&#xff1a;虽然还没有搞定. 参考文章 flash xmlsocket policy 问题Policy file changes in Flash Player 9Setting up a socket policy file serverUnderstanding Flash Player 9 A…

1.3.2 Jetty 的基本配置(2)

1.3.2 Jetty 的基本配置&#xff08;2&#xff09; 3. 配置 JNDI 绑定 Jetty 同样可以整合 DBCP、 C3PO 等数据源来提供容器管理的数据源。提供容器管理的数据源&#xff0c;只是 Jetty JNDI 绑定功能之一。 下面介绍如何在 Jetty 绑定 JNDI&#xff0c;以及 JNDI 的使用。 增加…

潘石屹语录

★我是一个纯粹的商人&#xff0c;不管做什么行业&#xff0c;只要纯粹就好&#xff0c;人就怕不纯粹。 ★不赚钱的商人是不道德的&#xff0c;不赚钱你就只能确保自己的生活&#xff0c;不能给员工好的工资福利待遇&#xff0c;不能给国家上缴利税&#xff0c;不能给客户带来实…

Windows 电源管理

电源管理 Windows CE是典型的使用电池供电的系统。这使得正确操作系统十分关键&#xff0c;应用程序大多数时间都不需要关注Windows CE 设备的电源损耗&#xff0c;但是在某些时候&#xff0c;你可能要注意这些损耗。当用户关闭了一个使用电池的Windows CE 设备&#xff0c;电源…

Asp.net(C#)中备份还原SQL Server数据库实现

在web中&#xff0c;安全性主要体现在两个方面&#xff1a;一个是程序安全性&#xff0c;即防止网页在插入恶意代码&#xff1b;另一个是数据库安全性&#xff0c;这个我们可以经常备份数据库来实现。 在文中&#xff0c;我将演示如果在网页中备份和恢复数据库。 其实备份和恢复…

silverlight寻奇 - Graphite

Graphite是一个能自动布局的图表控件。 目前它已经有了silverlight 2 和 wpf的版本。观看demo时按下“Ctrl”键再做点击操作。 原文地址&#xff1a;http://www.orbifold.net/default/?page_id1270 Features common to both versions Styling: nodes can be styled or templ…

NTLDR is missing 的解决方法

NTLDR is missing 的解决方法 NTLDR文件是win nt/win200/WinXP的引导文件&#xff0c;当此文件丢失时启动系统会提示"NTLDR is missing..."并要求按任意键重新启动&#xff0c;不能正确进入系统 。所以应该在系统正常的时候给予备份。 NTLDR文件是做什么的…

iframe 跨域 cookies操作

192.168.14.69:http://192.168.14.69/payweb/iframe/default.aspx 客户端页面 通过js 动态输出iframe到localhost &#xff1a;default.aspx js Codevar linkswindow.document.getElementsByTagName(link);var link;for(var i0;i<links.length;i){ if(links[i].rel.toLow…