• C++中XMLHTTPRequest异步使用onreadystatuschange


    首先需要编写一个类,实现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();

  • 相关阅读:
    jquery ajax get 数组参数
    xcopy中文文件名,中文件目录乱码问题
    小程序使用wxParse插件解析html标签图片间距问题
    30分钟彻底弄懂flex布局
    abp ueditor 多图以及文件无法上传
    Lubuntu 18.04 自动登录
    树莓派虚拟环境手动安装HA
    ESP-01S刷ESPEasy固件,接入HA
    百度TTS的来由
    Pi 3B+编译安装python3.6.8
  • 原文地址:https://www.cnblogs.com/yuanxiaoping_21cn_com/p/1332927.html
Copyright © 2020-2023  润新知