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:
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.