8
votes

Énumérer les méthodes d'objet COM (IDISPATCH) en utilisant ATL?

Utilisation de ATL (VS2008) Comment puis-je énumérer les méthodes disponibles disponibles sur une interface IDISPatch donnée ( IDISPATCH * )? Je dois rechercher une méthode avec un nom spécifique et, une fois que j'ai le TapID , appelez la méthode (je connais les paramètres de la méthode.) Idéalement, je voudrais faire cela en utilisant les pointeurs intelligents COM ( cCompTR <> ).

est-ce possible?


3 commentaires

Voir cet outil (code source): sourceforge.net/projects/axfuzz/files


Et ceci: codeproject.com/kb/atl/ienum.aspx


Je suis allé chercher d'autres exemples et j'ai également trouvé spec.winprog.org/typeinf2


3 Réponses :


9
votes

Vous ne pouvez pas énumérer toutes les méthodes disponibles à moins que l'objet implémente IDISPatchex.

Toutefois, si vous connaissez le nom de la méthode que vous souhaitez appeler, vous pouvez utiliser getidsofnames pour mapper le nom de la distribution appropriée. < / p> xxx

éditer: Pour complétude, je suppose qu'il existe un moyen d'interroger l'interface iTypeInfo2 (en supposant qu'il existe une bibliothèque de type pour l'objet) à partir de IDISPATCH :: gettypeinfo pour une liste de méthodes, mais je ne l'ai pas fait. Voir l'autre réponse.


2 commentaires

Brillant! Juste ce dont j'avais besoin. Merci beaucoup.


Je crois que j'ai fait tous les points que vous venez de faire dans votre commentaire dans ma réponse. S'il vous plaît lisez-le à nouveau étroitement. En outre, l'affiche voulait juste pouvoir invoquer une méthode qu'il connaissait déjà le nom de. Donc, ma réponse a fourni la solution à ce qu'il voulait vraiment faire, pas nécessairement ce qu'il a demandé. C'est pourquoi, je soupçonne, il a été marqué comme la bonne réponse. Et enfin, merci de me calmer. C'est seulement 1s et 0s.



19
votes

Vous pouvez énumérer les méthodes un itispatch expose via les informations de type. Il y a deux façons d'obtenir les informations de type:


6 commentaires

Bon produit. Merci d'avoir ajouté ceci.


@Franci, lorsqu'une propriété est une matrice, le Vardec retourné a un Varkind = Idispatch. Comment savoir si une propriété est un tableau et si un tableau - Comment puis-je accéder à ses membres? Lorsque l'appel d'appel est invoqué pour obtenir un tableau, le résultat est IDISPATCH. Cet IDISPATCH ne prend pas en charge «article» ou «longueur» ou une propriété similaire.


@URI - Notez que les propriétés ne sont pas des champs et doivent être inspectées via getfununcuc () qui vous donne un Funcdesc , de l'endroit où vous devez aller à ELEMDESCFUNCUN (pour le retour) ou lprgelemdescparam (pour les paramètres). Les tableaux sont généralement retournés comme paramètre de sortie. Vous devez donc inspecter ce dernier. Dans tous les deux, ces deux donnent elemdesc , où vous devez inspecter le tdesk , qui vous retourne un typé , qui basé sur le < Code> Vartype VT Peut être en réalité un arraydesc . Si tel est le cas, vous avez un Safearray .


@Uri - S'il s'avère, il est pas A A SafeArray , la propriété renvoie probablement un "code> itispatch point de pointeur sur un objet qui implémente la matrice comme la fonctionnalité en tant que collection. Vous devez demander à ce IDISPATCH pour ses informations de type et inspecter celui-ci pour comprendre les bonnes méthodes pour accéder aux membres de la collection.


@Uri - Bien sûr, tout cela est basé sur la connaissance que je n'ai pas dépoussié dans environ deux ans, alors je pourrais oublier des détails ... :-)


@Uri - Si votre tableau vient de Jscript, ce n'est pas un safearray, mais un IDISPATCH à un objet de tableau JScript. Voici une description de la différence entre les tableaux VBScript (qui sont SafeArrays) et des tableaux JScript - blogs.msdn.com/b/ericlippert/archive/2003/09/22/53061.aspx .



15
votes

Voici quelques codes que l'énumération (elle insère l'inscription [Dispatch ID] - [Nom de la méthode] sur une carte, mais c'est facile à changer).

///
/// \brief Returns a map of [DispId, Method Name] for the passed-in IDispatch object
///
HRESULT COMTools::GetIDispatchMethods(_In_ IDispatch * pDisp,
                                      _Out_ std::map<long, std::wstring> & methodsMap)
{
    HRESULT hr = S_OK;

    CComPtr<IDispatch> spDisp(pDisp);
    if(!spDisp)
        return E_INVALIDARG;

    CComPtr<ITypeInfo> spTypeInfo;
    hr = spDisp->GetTypeInfo(0, 0, &spTypeInfo);
    if(SUCCEEDED(hr) && spTypeInfo)
    {
        TYPEATTR *pTatt = nullptr;
        hr = spTypeInfo->GetTypeAttr(&pTatt);
        if(SUCCEEDED(hr) && pTatt)
        {
            FUNCDESC * fd = nullptr;
            for(int i = 0; i < pTatt->cFuncs; ++i)
            {
                hr = spTypeInfo->GetFuncDesc(i, &fd);
                if(SUCCEEDED(hr) && fd)
                {
                    CComBSTR funcName;
                    spTypeInfo->GetDocumentation(fd->memid, &funcName, nullptr, nullptr, nullptr);
                    if(funcName.Length()>0)
                    {
                        methodsMap[fd->memid] = funcName;
                    }

                    spTypeInfo->ReleaseFuncDesc(fd);
                }
            }

            spTypeInfo->ReleaseTypeAttr(pTatt);
        }
    }

    return hr;

}


0 commentaires