Sdílet prostřednictvím


Nejčastější dotazy týkající se programování v atributu

Toto téma odpovědi na časté otázky následující:

  • Co je Popisovač HRESULT?

  • Když je nutné zadat parametr název atributu

  • Můžete použít komentáře atributu bloku?

  • Atributy interakci s dědičností?

  • Jak lze použít atributy v nonattributed projektu ATL?

  • Použití souboru .idl v přidělené projektu

  • Upravit kód, který je injekčně atributu

  • Jak lze předat prohlašuji přidělené rozhraní?

  • Můžete použít atributy třídy odvozené od třídy, který také používá atributy?

Co je Popisovač HRESULT?

HRESULT Je jednoduchý datový typ, který je často používán jako vrácené hodnoty atributů a ATL obecně.Následující tabulka popisuje různé hodnoty.Další hodnoty jsou obsaženy v souboru winerror.h záhlaví.

Název

Description

Value

S_OK

Úspěšná operace

0x00000000

E_UNEXPECTED

Neočekávaná chyba

0x8000FFFF

E_NOTIMPL

Není implementováno

0x80004001

CHYBA E_OUTOFMEMORY

Nepodařilo se přidělit nezbytnou paměť

0x8007000E

E_INVALIDARG

Jeden nebo více argumentů je neplatných

0x80070057

E_NOINTERFACE

Neznámé rozhraní

0x80004002

E_POINTER

Neplatný ukazatel

0x80004003

E_HANDLE

Neplatný popisovač

0x80070006

E_ABORT

Operace byla přerušena

0x80004004

E_FAIL

Nespecifikovaná chyba

0x80004005

E_ACCESSDENIED

Obecná chyba odepření přístupu

0x80070005

Když je nutné zadat parametr název atributu

Ve většině případů Pokud atribut má jeden parametr parametru název.Tento název není vyžadováno při vkládání atributu v kódu.Například následující použití agregovatelné atribut:

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

je přesně stejná jako:

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

Však mít následující atributy jednoho, nepojmenované parametry:

call_as

pevný obal

cpp_quote

výchozí

Výchozí hodnota

defaultvtable

emitidl

Položka

first_is

helpcontext

soubor nápovědy

helpstring

helpstringcontext

helpstringdll

id

iid_is

importovat

importlib

zahrnout

includelib

last_is

length_is

max_is

no_injected_text

pointer_default

pragma

restricted

size_is

zdroj

switch_is

switch_type

transmit_as

wire_marshal

Můžete použít komentáře atributu bloku?

Můžete použít jeden řádek a více řádků poznámky v rámci bloku atributu.Nelze však použít buď Styl komentáře v závorce hospodářství parametry atribut.

Povoleno je:

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

Zakázáno je:

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

Atributy interakci s dědičností?

Přidělené i unattributed třídy mohou dědit z jiné třídy, které samy nelze přičítat nebo ne.V důsledku vyplývající z přidělené třídy je stejný jako odvozené od třídy po zprostředkovatele atributu byla transformována jeho kód.Atributy nejsou přenášeny do odvozených tříd prostřednictvím dědičnosti C++.Atribut poskytovatele transformuje pouze kód v blízkosti jeho atributy.

Jak lze použít atributy v nonattributed projektu ATL?

Máte nonattributed projektu ATL má soubor .idl a chcete začít přidávat objekty přidělené.V tomto případě stanovit kód pomocí Průvodce přidáním třídy.

Použití souboru .idl v přidělené projektu

Pravděpodobně .idl soubor, který chcete použít v projektu ATL svěřeny.V tomto případě použijete importidl atributu, zkompilujte soubor .idl na soubor s příponou h soubor (viz Jazyk MIDL stránky vlastností v dialogovém okně Vlastnosti stránky projektu) a zahrnout soubor s příponou h souboru v projektu.

Upravit kód, který je injekčně atributu

Některé atributy pro vkládání kódu do projektu.Vloženého kódu lze zobrazit pomocí /Fx volba kompilátoru.Je také možné zkopírovat kód z vloženého souboru a vložit do zdrojového kódu.Umožňuje změnit chování atribut.Pravděpodobně však změnit ostatní části kódu také.

V následující ukázce je výsledkem kopírování vloženého kódu do zdrojového kódu souboru:

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

Jak lze předat prohlašuji přidělené rozhraní?

Pokud budete provádět dopředné deklarace přidělené rozhraní musí stejné atributy pro předávání prohlášení, že u prohlášení skutečné rozhraní.Musí rovněž vztahovat Exportovat vaše dopředné deklarace atributu.

Můžete použít atributy třídy odvozené od třídy, který také používá atributy?

Ne, není podporována pomocí atributů třídy odvozené od třídy, který také používá atributy.

Viz také

Další zdroje

Přidělené Koncepty programování.