Atrybut Programowanie — często zadawane pytania
W tym temacie zamieszczono odpowiedzi na następujące najczęściej zadawane pytania:
Co to jest HRESULT?
Kiedy trzeba określić nazwę parametru dla atrybutu?
Czy można użyć komentarze w bloku atrybut?
Jak atrybuty są oddziałują z dziedziczenia?
Jak używać atrybutów w projekcie ATL nonattributed?
W jaki sposób można użyć pliku .idl w projekcie przypisane?
Czy można zmodyfikować kod, który jest wprowadzany przez atrybut?
W jaki sposób do przodu można zadeklarować interfejsu przypisane?
Czy można używać atrybutów na klasy pochodzącej od klasy, która również używa atrybutów?
Co to jest HRESULT?
HRESULT Jest to typ danych prostego, który jest często używany jako wartości zwracanej przez atrybuty i ATL ogólnie.Poniższej tabeli opisano różne wartości.Więcej wartości są zawarte w pliku nagłówka pliku winerror.h.
Nazwa |
Opis |
Wartość |
---|---|---|
S_OK |
Operacja ukończona pomyślnie |
0x00000000 |
E_UNEXPECTED |
Nieoczekiwany błąd |
0x8000FFFF |
E_NOTIMPL |
Nie zaimplementowano |
0x80004001 |
BŁĄD E_OUTOFMEMORY |
Nie można przydzielić potrzebnej pamięci |
0x8007000E |
WARTOŚĆ E_INVALIDARG |
Jeden lub więcej argumentów są nieprawidłowe |
0x80070057 |
E_NOINTERFACE |
Taki interfejs nie jest obsługiwany |
0x80004002 |
E_POINTER |
Nieprawidłowy wskaźnik |
0x80004003 |
E_HANDLE |
Nieprawidłowe dojście |
0x80070006 |
E_ABORT |
Operacja przerwana |
0x80004004 |
E_FAIL |
Nieokreślony błąd |
0x80004005 |
E_ACCESSDENIED |
Ogólny błąd odmowy dostępu |
0x80070005 |
Kiedy trzeba określić nazwę parametru dla atrybutu?
W większości przypadków Jeśli atrybut ma jeden parametr nazwany tego parametru.Ta nazwa nie jest wymagane przy wstawianiu atrybutu w kodzie.Na przykład, następujący sposób użycia kumulowalnych atrybut:
[coclass, aggregatable(value=allowed)]
class CMyClass
{
// The class declaration
};
jest dokładnie taka sama, jak:
[coclass, aggregatable(allowed)]
class CMyClass
{
// The class declaration
};
Jednakże następujące atrybuty mają pojedynczy, nienazwanych parametrów:
Czy można użyć komentarze w bloku atrybut?
Można użyć zarówno jednowierszowe i wielowierszowe komentarze w obrębie bloku atrybutu.Jednakże nie można użyć albo styl komentarza w nawiasach, posiadający parametrów do atrybutu.
Dozwolone jest:
[ coclass,
progid("MyClass.CMyClass.1"), /* Multiple-line
comment */
threading("both") // Single-line comment
]
Niedozwolone jest:
[ coclass,
progid("MyClass.CMyClass.1" /* Multiple-line comment */ ),
threading("both" // Single-line comment)
]
Jak atrybuty są oddziałują z dziedziczenia?
Zarówno przypisane, jak i unattributed klasy mogą dziedziczyć innych klas, które mogą same być przypisane lub nie.Wynik wynikające z klasą przypisany jest taka sama, jak wynikające z tej klasy, po dostawcy atrybut został przekształcony jego kod.Atrybuty nie są przekazywane do klasy poprzez dziedziczenie C++ pochodne.Dostawca atrybut tylko przekształca kod w pobliżu jego atrybuty.
Jak używać atrybutów w projekcie ATL nonattributed?
Może mieć nonattributed Projekt ATL, którego plik .idl, i chcesz rozpocząć dodawanie obiektów przypisane.W tym przypadku należy użyć Kreatora dodawania klasy zapewnienie kod.
W jaki sposób można użyć pliku .idl w projekcie przypisane?
Może być plik .idl, którego chcesz użyć w projekcie ATL przypisane.W takim przypadku można użyć importidl atrybutu, skompiluj plik .idl w pliku .h (zobacz Stron właściwości MIDL w oknie dialogowym właściwości strony projektu), a następnie dołączyć plik .h w projekcie.
Czy można zmodyfikować kod, który jest wprowadzany przez atrybut?
Niektóre atrybuty wstrzyknięcie kodu do projektu.Zobacz temat wniesiony kodu za pomocą /Fx opcję kompilatora.Jest również możliwe kopiowanie kodu z pliku wniesiony i wkleić go do kodu źródłowego.Pozwala zmodyfikować zachowanie atrybutu.Jednakże może mieć innych częściach swojego kodu, jak również zmodyfikować.
Poniższy przykład jest wynikiem kopiuje kod do pliku kodu źródłowego:
// 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() {}
W jaki sposób do przodu można zadeklarować interfejsu przypisane?
Jeśli zamierzasz oświadczenia do przodu przypisane interfejs, należy zastosować te same atrybuty do przodu deklaracji, że zastosowanie do deklaracji rzeczywiste interfejsu.Należy także zastosować Eksportowanie atrybutu na Twoje zgłoszenie do przodu.
Czy można używać atrybutów na klasy pochodzącej od klasy, która również używa atrybutów?
Nie, za pomocą atrybutów na klasy pochodzącej od klasy, która również używa atrybutów nie jest obsługiwane.