Düzenle

Aracılığıyla paylaş


Öznitelik programlama SSS

HRESULT nedir?

HRESULT, genellikle öznitelikler ve genel olarak ATL tarafından dönüş değeri olarak kullanılan basit bir veri türüdür. Aşağıdaki tabloda çeşitli değerler açıklanmaktadır. winerror.h üst bilgi dosyasında daha fazla değer bulunur.

Veri Akışı Adı Açıklama Değer
S_OK İşlem başarılı 0x00000000
E_UNEXPECTED Beklenmeyen hata 0x8000FFFF
E_NOTIMPL Uygulanmadı 0x80004001
E_OUTOFMEMORY Gerekli bellek ayrılamadı 0x8007000E
E_INVALIDARG Bir veya daha fazla bağımsız değişken geçersiz 0x80070057
E_NOINTERFACE Böyle bir arabirim desteklenmiyor 0x80004002
E_POINTER Geçersiz işaretçi 0x80004003
E_HANDLE Geçersiz tanıtıcı 0x80070006
E_ABORT İşlem durduruldu 0x80004004
E_FAIL Belirtilmeyen hata 0x80004005
E_ACCESSDENIED Genel erişim reddedildi hatası 0x80070005

Bir öznitelik için parametre adını ne zaman belirtmem gerekiyor?

Çoğu durumda, özniteliğin tek bir parametresi varsa, bu parametre adlandırılır. Kodunuza özniteliği eklenirken bu ad gerekli değildir. Örneğin, aşağıdaki toplayıcı özniteliği kullanımı:

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

aşağıdakiyle tam olarak aynıdır:

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

Ancak, aşağıdaki özniteliklerin tek ve adsız parametreleri vardır:

Öznitelik bloğunda açıklamaları kullanabilir miyim?

Öznitelik bloğunda hem tek satırlı hem de çok satırlı açıklamaları kullanabilirsiniz. Ancak, parametreleri bir öznitelikte tutarak parantez içinde açıklama stillerinden birini kullanamazsınız.

Aşağıdakilere izin verilir:

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

Aşağıdakilere izin verilmiyor:

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

Öznitelikler devralma ile nasıl etkileşim kurar?

Hem öznitelikli hem de dağıtılmamış sınıfları diğer sınıflardan devralabilirsiniz; bunlar kendilerine atfedilebilir veya atfedilemez. Öznitelikli bir sınıftan türetmenin sonucu, öznitelik sağlayıcısı kodunu dönüştürdükten sonra bu sınıftan türetilmesiyle aynıdır. Öznitelikler C++ devralma yoluyla türetilmiş sınıflara iletilmez. Öznitelik sağlayıcısı yalnızca özniteliklerinin yakınındaki kodu dönüştürür.

Öznitelikleri, dağıtılmayan bir ATL projesinde nasıl kullanabilirim?

.idl dosyası olan, dağıtılmayan bir ATL projeniz olabilir ve öznitelikli nesneler eklemeye başlamak isteyebilirsiniz. Bu durumda, kodu sağlamak için Sınıf Ekleme Sihirbazı'nı kullanın.

Öznitelikli bir projede .idl dosyasını nasıl kullanabilirim?

ATL öznitelikli projenizde kullanmak istediğiniz bir .idl dosyanız olabilir. Bu durumda, importidl özniteliğini kullanır, .idl dosyasını bir .h dosyasına derlersiniz (projenin Özellik Sayfaları iletişim kutusundaki MIDL Özellik Sayfaları'na bakın) ve ardından .h dosyasını projenize eklersiniz.

Bir öznitelik tarafından eklenen kodu değiştirebilir miyim?

Bazı öznitelikler projenize kod ekler. Eklenen kodu /Fx derleyici seçeneğini kullanarak görebilirsiniz. Eklenen dosyadan kodu kopyalayıp kaynak kodunuz içine yapıştırmak da mümkündür. Bu, özniteliğin davranışını değiştirmenize olanak tanır. Ancak kodunuzun diğer bölümlerini de değiştirmeniz gerekebilir.

Aşağıdaki örnek, eklenen kodun bir kaynak kod dosyasına kopyalanmasının sonucudur:

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

Öznitelikli arabirim bildirmeyi nasıl iletebilirim?

Öznitelikli bir arabirimin ileri bildirimini yapacaksanız, gerçek arabirim bildirimine uyguladığınız iletme bildirimine aynı öznitelikleri uygulamanız gerekir. İletme bildiriminize dışarı aktarma özniteliğini de uygulamanız gerekir.

Öznitelikleri de kullanan bir sınıftan türetilmiş bir sınıfta öznitelikleri kullanabilir miyim?

Hayır, öznitelikleri de kullanan bir sınıftan türetilen bir sınıfta özniteliklerin kullanılması desteklenmez.