Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по программированию на C/С++

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
На первую страницук этому сообщениюк последнему сообщению

Открыть новую тему     Написать ответ в эту тему

karakurt2



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору


Код:
 
 
#include <olectl.h>
#include <stdio.h>
 
bool IsEnumerated(ITypeInfo* pTypeInfo)
{
    bool ok = false;
    if (pTypeInfo)
    {
        LPTYPEATTR pTypeAttr = 0;
        pTypeInfo->GetTypeAttr(&pTypeAttr);
        if (pTypeAttr != 0)
        {
            ok = (pTypeAttr->typekind == TKIND_ENUM);
            pTypeInfo->ReleaseTypeAttr(pTypeAttr);
        }
    }
    return ok;
}
 
bool IsBool(IDispatch* pDispatch, DISPID di)
{
    bool ok = false;
    VARIANT val;
    VariantInit(&val);
    DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
    HRESULT hr = pDispatch->Invoke(di, IID_NULL, LOCALE_USER_DEFAULT, \
                                   DISPATCH_PROPERTYGET, &dispparamsNoArgs, &val, NULL, NULL);
    ok = (SUCCEEDED(hr) && val.vt == VT_BOOL);
    VariantClear(&val);
    return ok;
}
 
bool IsPerPropertyBrowse(IDispatch* pDispatch, DISPID di)
{
    bool ok = false;
    IPerPropertyBrowsing* pBrowse = 0;
    HRESULT hr = pDispatch->QueryInterface(IID_IPerPropertyBrowsing, (void**) &pBrowse);
    if (SUCCEEDED(hr))
    {
        CALPOLESTR castr;
        CADWORD cadw;
        ZeroMemory(&castr, sizeof(castr));
        ZeroMemory(&cadw, sizeof(cadw));
        hr = pBrowse->GetPredefinedStrings(di, &castr, &cadw);
        if (hr == S_OK)
        {
            ULONG i;
            ok = true;
            for (i = 0; i < castr.cElems; ++i)
            {
                char buff[32];
                WideCharToMultiByte(866, 0, castr.pElems[i], -1, buff, 32, 0, 0);
                printf("\n\t%s", buff);
            }
 
            CoTaskMemFree(cadw.pElems);
            for (i = 0; i < castr.cElems; ++i)
            {
                CoTaskMemFree(castr.pElems[i]);
                // SysFreeString(castr.pElems[i]);
            }
            CoTaskMemFree(castr.pElems);
        }
        pBrowse->Release();
    }
    return ok;
}
 
bool IsColor(ITypeInfo* pTypeInfo, DISPID di)
{
    if (di == DISPID_BACKCOLOR || di == DISPID_FORECOLOR \
            || di == DISPID_BORDERCOLOR || di == DISPID_FILLCOLOR)
    {
        return true;
    }
 
    bool ok = false;
    if (pTypeInfo != 0)
    {
        LPTYPEATTR pTypeAttr = 0;
        pTypeInfo->GetTypeAttr(&pTypeAttr);
        if (pTypeAttr)
        {
            if (pTypeAttr->typekind == TKIND_ALIAS)
            {
                ITypeLib *pTypeLib = 0;
                UINT nIndex;
                HRESULT hr = pTypeInfo->GetContainingTypeLib(&pTypeLib, &nIndex);
                if (SUCCEEDED(hr))
                {
                    BSTR bstrName;
                    BSTR bstrDoc;
                    hr = pTypeLib->GetDocumentation(nIndex, &bstrName, &bstrDoc, NULL, NULL);
                    if (SUCCEEDED(hr))
                    {
                        ok = (0 == lstrcmpW(bstrName, L"OLE_COLOR"));
                    }
                    if (bstrName)
                        SysFreeString(bstrName);
                    if (bstrDoc)
                        SysFreeString(bstrDoc);
                    pTypeLib->Release();
                }
            }
            pTypeInfo->ReleaseTypeAttr(pTypeAttr);
        }
    }
    return ok;
}
 
bool IsFont(ITypeInfo* pTypeInfo, DISPID di)
{
    if (di == DISPID_FONT)
        return true;
 
    bool ok = false;
    if (pTypeInfo != 0)
    {
        LPTYPEATTR pTypeAttr = 0;
        pTypeInfo->GetTypeAttr(&pTypeAttr);
        if (pTypeAttr)
        {
            ok = InlineIsEqualGUID(pTypeAttr->guid, IID_IFontDisp);
            pTypeInfo->ReleaseTypeAttr(pTypeAttr);
        }
    }
    return ok;
}
 
bool RegisterProperty(LPDISPATCH pDispatch, DISPID di, \
                      LPTYPEINFO pTypeInfo, LPTYPEINFO pUserTypeInfo)
{
    BSTR bstrName = NULL;
    BSTR bstrDocString = NULL;
    HRESULT hr = pTypeInfo->GetDocumentation(di, &bstrName, &bstrDocString, NULL, NULL);
    if (SUCCEEDED(hr))
    {
        printf("%S: ", bstrName);
        if (IsEnumerated(pUserTypeInfo))
        {
            printf("enum");
        }
        else if (IsBool(pDispatch, di))
        {
            printf("bool");
        }
        else if (IsPerPropertyBrowse(pDispatch, di))
        {
            // printf("browse");
        }
        else if (IsColor(pUserTypeInfo, di))
        {
            printf("color");
        }
        else if (IsFont(pUserTypeInfo, di))
        {
            printf("font");
        }
        else
        {
            printf("generic");
        }
 
        printf("\n");
 
        if (bstrName)
            SysFreeString(bstrName);
 
        if (bstrDocString)
            SysFreeString(bstrDocString);
    }
 
    return false;
}
 
VARTYPE GetUserDefinedType(LPTYPEINFO pTI, HREFTYPE hrt)
{
    VARTYPE vt = VT_USERDEFINED;
    LPTYPEINFO pRTI = 0;
    HRESULT hr = pTI->GetRefTypeInfo(hrt, &pRTI);
    if (SUCCEEDED(hr))
    {
        LPTYPEATTR pTA = 0;
        hr = pRTI->GetTypeAttr(&pTA);
        if (pTA)
        {
            if (SUCCEEDED(hr) && pTA->typekind == TKIND_ALIAS)
            {
                if (pTA->tdescAlias.vt == VT_USERDEFINED)
                {
                    vt = GetUserDefinedType(pRTI, pTA->tdescAlias.hreftype);
                }
                else
                {
                    vt = pTA->tdescAlias.vt;
                }
            }
            pRTI->ReleaseTypeAttr(pTA);
        }
        pRTI->Release();
    }
    return vt;
}
 
HRESULT GetEnumTypeInfo(LPTYPEINFO pTI, HREFTYPE hrt, ITypeInfo** ppEnumInfo)
{
    *ppEnumInfo = 0;
    LPTYPEINFO pRTI = 0;
    HRESULT hr = pTI->GetRefTypeInfo(hrt, &pRTI);
    if (SUCCEEDED(hr))
    {
        hr = E_NOINTERFACE;
        LPTYPEATTR pTA = 0;
        pRTI->GetTypeAttr(&pTA);
        if (pTA)
        {
            switch (pTA->typekind)
            {
            case TKIND_ALIAS:
                if (pTA->tdescAlias.vt == VT_USERDEFINED)
                {
                    hr = GetEnumTypeInfo(pRTI, pTA->tdescAlias.hreftype, ppEnumInfo);
                }
                else
                {
                    *ppEnumInfo = pRTI;
                    pRTI->AddRef();
                    hr = S_OK;
                }
                break;
 
            case TKIND_ENUM:
            case TKIND_DISPATCH:
            {
                *ppEnumInfo = pRTI;
                pRTI->AddRef();
                hr = S_OK;
            }
            break;
            }
            pRTI->ReleaseTypeAttr(pTA);
        }
        pRTI->Release();
    }
    return hr;
}
 
bool QueryProperty(LPDISPATCH pDispatch, LPTYPEINFO pTypeInfo, LPFUNCDESC pFuncDesc)
{
    bool ok = false;
    switch (pFuncDesc->elemdescFunc.tdesc.vt)
    {
    case VT_EMPTY:
    case VT_NULL:
    case VT_I2:
    case VT_I4:
    case VT_R4:
    case VT_R8:
    case VT_CY:
    case VT_DATE:
    case VT_BSTR:
    case VT_ERROR:
    case VT_BOOL:
    case VT_VARIANT:
    case VT_DECIMAL:
    case VT_I1:
    case VT_UI1:
    case VT_UI2:
    case VT_UI4:
    case VT_INT:
    case VT_UINT:
        ok = RegisterProperty(pDispatch, pFuncDesc->memid, pTypeInfo, NULL);
        break;
 
    case VT_USERDEFINED:
    {
        HREFTYPE hRefType = pFuncDesc->elemdescFunc.tdesc.hreftype;
        VARTYPE vt = VT_USERDEFINED;
        LPTYPEINFO pUserTypeInfo = 0;
        HRESULT hr = GetEnumTypeInfo(pTypeInfo, hRefType, &pUserTypeInfo);
        if (FAILED(hr))
        {
            vt = GetUserDefinedType(pTypeInfo, hRefType);
        }
        ok = RegisterProperty(pDispatch, pFuncDesc->memid, pTypeInfo, pUserTypeInfo);
        if (pUserTypeInfo)
        {
            pUserTypeInfo->Release();
        }
    }
    break;
 
    case VT_PTR:
    {
        TYPEDESC *pTypeDesc = pFuncDesc->elemdescFunc.tdesc.lptdesc;
        if (pTypeDesc->vt == VT_USERDEFINED)
        {
            LPTYPEINFO pUserTypeInfo = 0;
            HRESULT hr = GetEnumTypeInfo(pTypeInfo, pTypeDesc->hreftype, &pUserTypeInfo);
            if (SUCCEEDED(hr) && pUserTypeInfo != 0)
            {
                LPTYPEATTR pTypeAttr = 0;
                if (SUCCEEDED(pUserTypeInfo->GetTypeAttr(&pTypeAttr)))
                {
                    if (InlineIsEqualGUID(pTypeAttr->guid, IID_IFontDisp))
                    {
                        ok = RegisterProperty(pDispatch, pFuncDesc->memid, pTypeInfo, pUserTypeInfo);
                    }
                    pUserTypeInfo->ReleaseTypeAttr(pTypeAttr);
                }
                pUserTypeInfo->Release();
            }
        }
    }
    break;
    }
    return ok;
}
 
HRESULT QueryControl()
{
    CLSID cid;
    HRESULT hr = CLSIDFromProgID(OLESTR("MSCAL.Calendar"), &cid);
    if (FAILED(hr))
    {
        return hr;
    }
 
    LPDISPATCH pDispatch = 0;
    hr = CoCreateInstance(cid, NULL, CLSCTX_INPROC_SERVER, \
                          IID_IDispatch, (void**) &pDispatch);
    if (FAILED(hr))
    {
        return hr;
    }
 
    LPTYPEINFO pTypeInfo = 0;
    hr = pDispatch->GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, &pTypeInfo);
    if (FAILED(hr))
    {
        pDispatch->Release();
        return hr;
    }
 
    LPTYPEATTR pTypeAttr = 0;
    hr = pTypeInfo->GetTypeAttr(&pTypeAttr);
    if (FAILED(hr))
    {
        pTypeInfo->Release();
        pDispatch->Release();
    }
 
    if (pTypeAttr->typekind == TKIND_INTERFACE)
    {
        // If the TKIND_DISPATCH type description is for a dual interface,
        // the TKIND_INTERFACE type description can be obtained by calling
        // GetRefTypeOfImplType with an index of -1, and by passing the returned
        // pRefType handle to GetRefTypeInfo to retrieve the type information.
 
        HREFTYPE hRefType;
        hr = pTypeInfo->GetRefTypeOfImplType(-1, &hRefType);
        if (SUCCEEDED(hr))
        {
            LPTYPEINFO pRefTypeInfo = 0;
            hr = pTypeInfo->GetRefTypeInfo(hRefType, &pRefTypeInfo);
            if (SUCCEEDED(hr))
            {
                pTypeInfo->ReleaseTypeAttr(pTypeAttr);
                pTypeInfo->Release();
                pTypeInfo = pRefTypeInfo;
                hr = pTypeInfo->GetTypeAttr(&pTypeAttr);
                if (FAILED(hr))
                {
                    pTypeInfo->Release();
                    pDispatch->Release();
                    return hr;
                }
            }
        }
    }
 
    // sweep through looking for property put
    const int MAX_MEMBERID = 0x100;
    MEMBERID memberid[MAX_MEMBERID], *pMI = memberid;
    for (int i = 0; i < pTypeAttr->cFuncs; ++i)
    {
        LPFUNCDESC pFuncDesc = 0;
        hr = pTypeInfo->GetFuncDesc(i, &pFuncDesc);
        if (SUCCEEDED(hr))
        {
            if (pFuncDesc->invkind & INVOKE_PROPERTYPUT)
            {
                if (pMI - memberid < MAX_MEMBERID)
                {
                    *pMI++ = pFuncDesc->memid;
                }
                else
                {
                    pTypeInfo->Release();
                    pDispatch->Release();
                    return E_OUTOFMEMORY;
                }
            }
            pTypeInfo->ReleaseFuncDesc(pFuncDesc);
        }
    }
 
    // now find prop get methods
    for (int i = 0; i < pTypeAttr->cFuncs; ++i)
    {
        LPFUNCDESC pFuncDesc = 0;
        hr = pTypeInfo->GetFuncDesc(i, &pFuncDesc);
        if (SUCCEEDED(hr))
        {
            if ((pFuncDesc->invkind & INVOKE_PROPERTYGET) != 0 && (pFuncDesc->wFuncFlags
                    & (FUNCFLAG_FRESTRICTED | FUNCFLAG_FHIDDEN | FUNCFLAG_FNONBROWSABLE)) == 0)
            {
                for (MEMBERID *pMI2 = memberid; pMI2 < pMI; ++pMI2)
                {
                    if (pFuncDesc->memid == *pMI2)
                    {
                        QueryProperty(pDispatch, pTypeInfo, pFuncDesc);
                        break;
                    }
                }
            }
            pTypeInfo->ReleaseFuncDesc(pFuncDesc);
        }
    }
 
    pTypeInfo->ReleaseTypeAttr(pTypeAttr);
    pTypeInfo->Release();
    pDispatch->Release();
    return S_OK;
}
 
int main()
{
    HRESULT hr = OleInitialize(NULL);
    if (SUCCEEDED(hr))
    {
        hr = QueryControl();
        OleUninitialize();
    }
    return (SUCCEEDED(hr)? 0: 1);
}
 
 
 


Всего записей: 733 | Зарегистр. 06-12-2003 | Отправлено: 14:40 31-01-2011
Открыть новую тему     Написать ответ в эту тему

На первую страницук этому сообщениюк последнему сообщению

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по программированию на C/С++


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru