⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 automationpermissions.cpp

📁 VC++串口通信设。本书详细说明讲解了在VC++环境下编写串口通信得过程。值得一看
💻 CPP
字号:
#include <windows.h>

//////////////////////////////////////////////////////////////
// Class Declaraction for Automation.
// This class is entirely defined inline.
// This class is used to call automation objects using the
//  morefamiliar CreateObject notation available to Visual
//  Basic and Delphi.
//////////////////////////////////////////////////////////////

class CComVariant : public VARIANT
{
public:
    CComVariant(){};
    CComVariant(VARIANT v)
        :VARIANT(v)
    {
    };
    CComVariant(BSTR bstr)
    {
        vt = VT_BSTR;
        bstrVal = bstr;
    };
};

class Automation
{
public:
    // HRESULT returned from last automation call
    HRESULT hresult;
    // IDISPATCH interface pointer for the existing object
    LPDISPATCH pdisp;
    // hold exception info here
    EXCEPINFO excepinfo;
    // hold argument error here
    UINT uArgErr;

    // Constructor, intializes the data members
    Automation();
    // Copy constructor, intialize data members and call AddRef
    Automation(const Automation & rhs);
    // Destructor, if dispatch is not NULL then release it
    virtual ~Automation();

    // assignment operator
    Automation & operator=(const Automation & rhs);

    // Create the dispatch interface object
    HRESULT CreateObject(WCHAR * str);
    // Retrieve the active dispatch object
    HRESULT GetObject(WCHAR * str);

    // Invoke a method
    CComVariant Invoke(WCHAR * str, VARIANT * var = NULL,
                       unsigned int cArgs = 0);
    // retrieve a data members value
    CComVariant Get(WCHAR * str);
    // post a data members value
    HRESULT Put(WCHAR * str, CComVariant & var);
};

//////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////

inline Automation::Automation()
: pdisp(NULL),
hresult(S_OK)
{
}

inline Automation::Automation(const Automation & rhs)
: pdisp(rhs.pdisp),
hresult(rhs.hresult)
{
    // return an exception if the dispatch pointer is NULL
    if (pdisp==NULL)
    {
        hresult = DISP_E_EXCEPTION;
    }
    pdisp->AddRef();
}

inline Automation::~Automation()
{
    // Release the object
    if (pdisp != NULL)
    {
        pdisp->Release();
        pdisp = NULL;
    }
}

//////////////////////////////////////////////////////////////
// Assignment operator
//////////////////////////////////////////////////////////////
inline Automation& Automation::operator=(const Automation& rhs)
{
    // If the previous object was not release, then do it now.
    if (pdisp != NULL)
    {
        pdisp->Release();
        pdisp = NULL;
    }

    pdisp = rhs.pdisp;
    hresult = rhs.hresult;
    pdisp->AddRef();

    return *this;
};

//////////////////////////////////////////////////////////////
// Method GetObject
// Retrieves the active object, does not create a new instance
//////////////////////////////////////////////////////////////

inline HRESULT Automation::GetObject(WCHAR * str)
{
    // If the previous object was not release, then do it now.
    if (pdisp != NULL)
    {
        pdisp->Release();
        pdisp = NULL;
    }

    // Convert the progid to a clsid
    CLSID clsid;
    hresult = ::CLSIDFromProgID(str, &clsid);
    if (hresult)
    {
        // CLSIDFromProgID failed
        return hresult;
    };

    // Retrieve the instance of the object
    LPUNKNOWN punk;
    hresult = ::GetActiveObject(clsid, NULL, &punk);
    if (hresult)
    {
        // GetActiveObject failed
        return hresult;
    };

    // Retrieve the interface pointer
    hresult = punk->QueryInterface(IID_IDispatch,
                                    (LPVOID FAR *)&pdisp);
    if (hresult)
    {
        // QueryInterface failed
        return hresult;
    };

    // Release the IUnknown reference.
    hresult = punk->Release();

    return hresult;
}

//////////////////////////////////////////////////////////////
// Method CreateObject
// Retrieves the a new instance of the object
//////////////////////////////////////////////////////////////

inline HRESULT Automation::CreateObject(WCHAR * str)
{
    // If the previous object was not release, then do it now.
    if (pdisp != NULL)
    {
        pdisp->Release();
        pdisp = NULL;
    }

    // Convert the progid to a clsid
    CLSID clsid;
    hresult = ::CLSIDFromProgID(str, &clsid);
    if (hresult)
    {
        // CLSIDFromProgID failed
        return hresult;
    };

    // Create the instance of the object
    LPUNKNOWN punk;
    hresult = ::CoCreateInstance(clsid, NULL, CLSCTX_SERVER, 
IID_IUnknown, (LPVOID FAR *) &punk);
    if (hresult)
    {
        // CoCreateInstance failed
        return hresult;
    };

    // Retrieve the interface pointer
    hresult = punk->QueryInterface(IID_IDispatch,
                                    (LPVOID FAR *)&pdisp);
    if (hresult)
    {
        // QueryInterface failed
        return hresult;
    };

    // Release the IUnknown reference.
    hresult = punk->Release();

    return hresult;
}

//////////////////////////////////////////////////////////////
// Method Get
// Retrieves the property's value
//////////////////////////////////////////////////////////////

inline CComVariant Automation::Get(WCHAR * str)
{
    // return an exception if the dispatch pointer is NULL
    if (pdisp==NULL)
    {
        hresult = DISP_E_EXCEPTION;
        return CComVariant();
    }

    // Retrieve the dispatch id for the function name
    DISPID dispid;
    hresult = pdisp->GetIDsOfNames(IID_NULL, &str, 1,
                                LOCALE_USER_DEFAULT, &dispid);
    if (hresult)
    {
        // GetIDsOfNames failed
        return CComVariant();
    };

    // Invoke the property GET
    DISPPARAMS dispparams = {0};
    VARIANTARG variantarg;
    VariantInit(&variantarg);
    ::memset(&excepinfo, 0, sizeof(EXCEPINFO));
    uArgErr = 0;
    hresult = pdisp->Invoke(dispid, IID_NULL,
                            LOCALE_USER_DEFAULT,
                            DISPATCH_PROPERTYGET,
                            &dispparams, &variantarg,
                            &excepinfo, &uArgErr);
    if (hresult)
    {
        // Invoke failed
        return CComVariant();
    };

    // return to lhs
    return CComVariant(variantarg);
}

//////////////////////////////////////////////////////////////
// Method Put
// Posts the property's value
//////////////////////////////////////////////////////////////

inline HRESULT Automation::Put(WCHAR * str, CComVariant & var)
{
    // return an exception if the dispatch pointer is NULL
    if (pdisp==NULL)
    {
        hresult = DISP_E_EXCEPTION;
        return hresult;
    }

    // Retrieve the dispatch id for the function name
    DISPID dispid;
    hresult = pdisp->GetIDsOfNames(IID_NULL, &str, 1,
                                LOCALE_USER_DEFAULT, &dispid);
    if (hresult)
    {
        // GetIDsOfNames failed
        return hresult;
    };

    // Invoke the property PUT
    DISPPARAMS dispparams = {0};
    dispparams.rgvarg = &var;
    DISPID x = DISPID_PROPERTYPUT;
    dispparams.rgdispidNamedArgs = &x;
    dispparams.cArgs = 1;
    dispparams.cNamedArgs = 1;
    VARIANTARG variantarg;
    VariantInit(&variantarg);
    ::memset(&excepinfo, 0, sizeof(EXCEPINFO));
    uArgErr = 0;

    // I'm not sure why you have to call PUTREF with these type
    // but I encountered similar code in "ATLCTL.CPP"
    if (var.vt == VT_UNKNOWN || var.vt == VT_DISPATCH ||
        (var.vt & VT_ARRAY) || (var.vt & VT_BYREF))
    {
        hresult = pdisp->Invoke(dispid, IID_NULL,
                                LOCALE_USER_DEFAULT,
                                DISPATCH_PROPERTYPUTREF,
                                &dispparams, &variantarg,
                                &excepinfo, &uArgErr);
        if (SUCCEEDED(hresult))
            return hresult;
    }

    // If the previous failed or the type did not match then
    // make the standard call.
    hresult = pdisp->Invoke(dispid, IID_NULL,
                            LOCALE_USER_DEFAULT,
                            DISPATCH_PROPERTYPUT,
                            &dispparams, &variantarg,
                            &excepinfo, &uArgErr);

    return hresult;
}

//////////////////////////////////////////////////////////////
// Method Invoke
// Executes the method
//////////////////////////////////////////////////////////////

inline CComVariant Automation::Invoke(WCHAR * str,
                            VARIANT * var, unsigned int cArgs)
{
    // return an exception if the dispatch pointer is NULL
    if (pdisp==NULL)
    {
        hresult = DISP_E_EXCEPTION;
        return CComVariant();
    }

    // Retrieve the dispatch id for the function name
    DISPID dispid;
    hresult = pdisp->GetIDsOfNames(IID_NULL, &str, 1,
                                LOCALE_USER_DEFAULT, &dispid);
    if (hresult)
    {
        // GetIDsOfNames failed
        return CComVariant();
    };

    // Invoke the method
    DISPPARAMS dispparams = {0};
    dispparams.rgvarg = var;
    dispparams.cArgs = cArgs;
    VARIANTARG variantarg;
    VariantInit(&variantarg);
    ::memset(&excepinfo, 0, sizeof(EXCEPINFO));
    uArgErr = 0;
    hresult = pdisp->Invoke(dispid, IID_NULL,
                            LOCALE_USER_DEFAULT,
                            DISPATCH_METHOD,
                            &dispparams, &variantarg,
                            &excepinfo, &uArgErr);
    if (hresult)
    {
        return CComVariant();
    };

    return CComVariant(variantarg);
}

int main(int, char **)
{
    CoInitialize(NULL);
    {
    Automation ob;
    ob.CreateObject(L"MyAutomationServer.MyAutomationObject");
    long l = ob.Get(L"Hello").lVal;
    }
    CoUninitialize();
    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -