Partager via


Programmation par attributs (FAQ)

Cette rubrique fournit à des questions suivant :

  • Qu'est-ce qu'un HRESULT ?

  • Lorsque faire pour dois spécifier le nom de paramètre pour un attribut ?

  • Puis -je utiliser des commentaires dans un bloc d'attributs ?

  • comment les attributs interagissent-ils avec l'héritage ?

  • Comment puis -je utiliser des attributs dans un projet ATL sans attributs ?

  • Comment puis -je utiliser un fichier .idl dans un projet attribué ?

  • Puis -je modifier le code qui est injecté par un attribut ?

  • Comment puis -je transférer déclare une interface avec attributs ?

  • Puis -je utiliser des attributs d'une classe dérivée d'une classe qui utilise également des attributs ?

Qu'est-ce qu'un HRESULT ?

HRESULT est un type de données simple qui est souvent utilisé comme valeur de retour par des attributs et ATL en général. le tableau suivant décrit les différentes valeurs. Plus de valeurs figurent dans le fichier d'en-tête winerror.h.

Nom

Description

Valeur

S_OK

opération réussie

0x00000000

E_UNEXPECTED

Défaillance inattendue

0x8000FFFF

E_NOTIMPL

non implémenté

0x80004001

E_OUTOFMEMORY

Pour allouer de la mémoire nécessaire

0x8007000E

E_INVALIDARG

un ou plusieurs arguments sont valides

0x80070057

E_NOINTERFACE

Aucun ces interface prise en charge

0x80004002

E_POINTER

Pointeur non valide

0x80004003

E_HANDLE

handle valide

0x80070006

E_ABORT

opération interrompue

0x80004004

E_FAIL

échec non spécifié

0x80004005

E_ACCESSDENIED

erreur générale d'accès refusé

0x80070005

Lorsque faire pour dois spécifier le nom de paramètre pour un attribut ?

Dans la plupart des cas, si l'attribut possède un paramètre unique, ce paramètre est nommé. Ce nom n'est pas requis en insérant l'attribut dans votre code. par exemple, l'utilisation suivante de l'attribut d' aggregatable :

[coclass, aggregatable(value=allowed)]
class CMyClass
{
// The class declaration
};

est exactement le même que :

[coclass, aggregatable(allowed)]
class CMyClass
{
// The class declaration
};

Toutefois, les attributs suivants ont unique, paramètres sans nom :

call_as

case

cpp_quote

par défaut

defaultvalue

defaultvtable

emitidl

entrée

first_is

helpcontext

helpfile

helpstring

helpstringcontext

helpstringdll

id

iid_is

import

importlib

incluez

includelib

last_is

length_is

max_is

no_injected_text

pointer_default

pragma

restricted

size_is

source

switch_is

switch_type

transmit_as

wire_marshal

Puis -je utiliser des commentaires dans un bloc d'attributs ?

Vous pouvez utiliser des commentaires sur une seule ligne et sur plusieurs lignes dans un bloc d'attributs. Toutefois, vous ne pouvez pas utiliser l'un ou l'autre de style de commentaire entre parenthèses maintenant les paramètres dans un attribut.

Il permet les éléments suivants :

[ coclass,
   progid("MyClass.CMyClass.1"), /* Multiple-line
                                       comment */
   threading("both") // Single-line comment
]

Ce qui suit est interdit :

[ coclass,
   progid("MyClass.CMyClass.1" /* Multiple-line comment */ ),
   threading("both" // Single-line comment)
]

comment les attributs interagissent-ils avec l'héritage ?

Vous pouvez hériter des classes attribuées et non attribuées d'autres classes, qui peuvent être réaffectées ou pas. Le résultat de la dérivation d'une classe avec attributs est le même que dérivant de cette classe après que le fournisseur d'attribut a transformé son code. Les attributs ne sont pas transmis aux classes dérivées via l'héritage C++. Le code de transformations du fournisseur d'attribut que à proximité de ses attributs.

Comment puis -je utiliser des attributs dans un projet ATL sans attributs ?

Vous pouvez avoir un projet ATL sans attributs, qui comporte un fichier .idl, et vous pouvez démarrer des objets avec attributs d'addition. Dans ce cas, utilisez l'Assistant pour ajouter une classe pour fournir le code.

Comment puis -je utiliser un fichier .idl dans un projet attribué ?

Vous pouvez utiliser un fichier .idl à utiliser dans votre projet attribué par ATL. Dans ce cas, vous pouvez utiliser l'attribut d' importidl , compilez le fichier .idl à un fichier .h (consultez Pages de propriétés MIDL dans la boîte de dialogue pages de propriétés du projet), puis inclure le fichier .h dans votre projet.

Puis -je modifier le code qui est injecté par un attribut ?

Certains attributs injectent un code dans votre projet. Vous pouvez consulter le code injecté à l'aide de l'option du compilateur de /Fx . Il est également possible de copier le code dans le fichier injecté et de le coller dans votre code source. Cela vous permet de modifier le comportement de l'attribut. Toutefois, vous devrez peut-être modifier d'autres parties de votre code également.

l'exemple suivant est le résultat de code injecté par copie dans un fichier de code source :

// attr_injected.cpp
// compile with: comsupp.lib
#define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>

[ module(name="MyLibrary") ];

// ITestTest
[ 
   object,
   uuid("DADECE00-0FD2-46F1-BFD3-6A0579CA1BC4"),
   dual,
   helpstring("ITestTest Interface"),
   pointer_default(unique)
]

__interface ITestTest : IDispatch {
   [id(1), helpstring("method DoTest")] 
   HRESULT DoTest([in] BSTR str);
};

// _ITestTestEvents
[
   uuid("12753B9F-DEF4-49b0-9D52-A79C371F2909"),
   dispinterface,
   helpstring("_ITestTestEvents Interface")
]

__interface _ITestTestEvents {
   [id(1), helpstring("method BeforeChange")] HRESULT BeforeChange([in] BSTR str, [in,out] VARIANT_BOOL* bCancel);
};

// CTestTest
[
   coclass,
   threading(apartment),
   vi_progid("TestATL1.TestTest"),
   progid("TestATL1.TestTest.1"),
   version(1.0),
   uuid("D9632007-14FA-4679-9E1C-28C9A949E784"),
   // this line would be commented out from original file
   // event_source("com"),
   // this line would be added to support injected code
   source(_ITestTestEvents),
   helpstring("TestTest Class")
]

class ATL_NO_VTABLE CTestTest : public ITestTest,
// the following base classes support added injected code
public IConnectionPointContainerImpl<CTestTest>,
public IConnectionPointImpl<CTestTest, &__uuidof(::_ITestTestEvents), CComDynamicUnkArray>
{
public:
   CTestTest() {
   }
   // this line would be commented out from original file
   // __event __interface _ITestTestEvents;
   DECLARE_PROTECT_FINAL_CONSTRUCT()
   HRESULT FinalConstruct() {
      return S_OK;
   }

void FinalRelease() {}

public:
   CComBSTR m_value;
   STDMETHOD(DoTest)(BSTR str) {
      VARIANT_BOOL bCancel = FALSE;
      BeforeChange(str,&bCancel);
      if (bCancel) {
          return Error("Error : Someone don't want us to change the value");
      }

     m_value =str;
     return S_OK;
    }
// the following was copied in from the injected code.
HRESULT BeforeChange(::BSTR i1,::VARIANT_BOOL* i2) {
   HRESULT hr = S_OK;
   IConnectionPointImpl<CTestTest, &__uuidof(_ITestTestEvents), CComDynamicUnkArray>* p = this;
   VARIANT rgvars[2];
   Lock();
   IUnknown** pp = p->m_vec.begin();
   Unlock();
   while (pp < p->m_vec.end()) {
      if (*pp != NULL) {
         IDispatch* pDispatch = (IDispatch*) *pp;
         ::VariantInit(&rgvars[1]);
         rgvars[1].vt = VT_BSTR;
         V_BSTR(&rgvars[1])= (BSTR) i1;
         ::VariantInit(&rgvars[0]);
         rgvars[0].vt = (VT_BOOL | VT_BYREF);
         V_BOOLREF(&rgvars[0])= (VARIANT_BOOL*) i2;
         DISPPARAMS disp = { rgvars, NULL, 2, 0 };
         VARIANT ret_val;
         hr = __ComInvokeEventHandler(pDispatch, 1, 1, &disp, &ret_val);
         if (FAILED(hr))
            break;
      }
      pp++;
   }
   return hr;
}

BEGIN_CONNECTION_POINT_MAP(CTestTest)
CONNECTION_POINT_ENTRY(__uuidof(::_ITestTestEvents))
END_CONNECTION_POINT_MAP()
// end added code section

// _ITestCtrlEvents Methods
public:
};

int main() {}

Comment puis -je transférer déclare une interface avec attributs ?

Si vous souhaitez effectuer une déclaration anticipée d'une interface avec attributs, vous devez appliquer les mêmes attributs à la déclaration anticipée que vous appliquez à la déclaration réelle de l'interface. Vous devez également appliquer l'attribut importer à votre déclaration anticipée.

Puis -je utiliser des attributs d'une classe dérivée d'une classe qui utilise également des attributs ?

Non, à l'aide de les attributs d'une classe dérivée d'une classe qui utilise également des attributs n'est pas pris en charge.

Voir aussi

Autres ressources

Concepts de programmation par attributs