Compartilhar via


Perguntas freqüentes sobre programação de atributo

Este tópico responde a perguntas freqüentes a seguir:

  • O que é um HRESULT?

  • Quando é necessário especificar o nome de parâmetro para um atributo?

  • Pode usar comentários em um bloco de atributo?

  • Como os atributos interagem com herança?

  • Como usar atributos em um projeto do ATL nonattributed?

  • Como posso usar um arquivo. idl em um projeto atribuído?

  • Posso modificar o código que é injetado por um atributo?

  • Como eu declaro frente uma interface atribuída?

  • Pode usar atributos em uma classe derivada de uma classe que também usa atributos?

O que é um HRESULT?

Um HRESULT é um tipo de dados simples que é freqüentemente usado como um valor de retorno, atributos e ATL em geral.A tabela a seguir descreve os vários valores.Valores mais estão contidos no arquivo de cabeçalho Winerror. h.

Nome

Descrição

Valor

S_OK

Operação bem-sucedida

0x00000000

E_UNEXPECTED

Falha inesperada

0x8000FFFF

E_NOTIMPL

Não implementado

0x80004001

E_OUTOFMEMORY

Falha ao alocar memória necessária

0x8007000E

E_INVALIDARG

Um ou mais argumentos são inválidos

0x80070057

E_NOINTERFACE

Nenhuma interface suportada

0x80004002

E_POINTER

Ponteiro inválido

0x80004003

E_HANDLE

Identificador inválido

0x80070006

E_ABORT

Operação anulada

0x80004004

E_FAIL

Falha não especificada

0x80004005

E_ACCESSDENIED

Acesso geral negado erro

0x80070005

Quando é necessário especificar o nome de parâmetro para um atributo?

Na maioria dos casos, se o atributo tem um único parâmetro, esse parâmetro é chamado.Esse nome não é necessário ao inserir o atributo no seu código.Por exemplo, o seguinte uso da agregável atributo:

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

é exatamente igual:

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

No entanto, os seguintes atributos têm parâmetros único, sem nome:

call_as

Caso

cpp_quote

Padrão

Valor padrão

defaultvtable

emitidl

entrada

first_is

HelpContext

arquivo de ajuda

HelpString

helpstringcontext

helpstringdll

id

iid_is

Importar

importlib

incluir

includelib

last_is

length_is

max_is

no_injected_text

pointer_default

pragma

restrito

size_is

fonte

switch_is

switch_type

transmit_as

wire_marshal

Pode usar comentários em um bloco de atributo?

Você pode usar os comentários de linha única e de várias linhas dentro de um bloco de atributo.No entanto, você não pode usar dois estilos de comentário dentro dos parênteses, mantendo os parâmetros para um atributo.

É permitido o seguinte:

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

A seguir não é permitida:

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

Como os atributos interagem com herança?

Você pode herdar classes atribuídas e unattributed de outras classes, que pode ser eles próprios ser atribuídos ou não.O resultado da derivação de uma classe atribuído em grande parte é o mesmo que derivar dessa classe depois que o provedor de atributo transformou seu código.Atributos não são transmitidos para derivadas de classes através de herança do C++.Um provedor de atributo apenas transforma código perto de seus atributos.

Como usar atributos em um projeto do ATL nonattributed?

Você pode ter um projeto ATL nonattributed, que tem um arquivo. idl, e você talvez queira começar a adicionar objetos atribuídos.Nesse caso, use o Assistente para adicionar classe para fornecer o código.

Como posso usar um arquivo. idl em um projeto atribuído?

Você pode ter um arquivo. idl que você deseja usar em seu projeto ATL atribuído.Nesse caso, você usaria o importidl de atributo, compile o arquivo. idl para um arquivo. h (consulte a Páginas de propriedades de MIDL na caixa de diálogo de páginas de propriedades do projeto) e, em seguida, incluir o arquivo. h em seu projeto.

Posso modificar o código que é injetado por um atributo?

Alguns atributos injetar código no seu projeto.Você pode ver o código injetado usando o /Fx opção de compilador.Também é possível copiar o código do arquivo injetado e colá-lo em seu código-fonte.Isso permite que você modificar o comportamento do atributo.No entanto, talvez você precise modificar outras partes do seu código também.

O exemplo a seguir é o resultado de copiar o código injetado em um arquivo de código-fonte:

// 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() {}

Como eu declaro frente uma interface atribuída?

Se você for fazer uma declaração de reenvio de uma interface atribuído em grande parte, você deve aplicar os mesmos atributos para a declaração de reenvio aplicáveis para a declaração de interface real.Você também deve aplicar o exportação atributo à declaração de encaminhamento.

Pode usar atributos em uma classe derivada de uma classe que também usa atributos?

Não, não há suporte para o uso de atributos em uma classe derivada de uma classe que também usa atributos.

Consulte também

Outros recursos

Atribuídos conceitos de programação