次の方法で共有


属性プログラミングの FAQ

このトピックでは次のよく寄せられる質問とその回答 :

  • HRESULT は何ですか。

  • My は属性のパラメーター名を指定する必要があります。

  • 今日は属性ブロックでコメントを使用できますか。

  • 属性はどの程度の継承と対話しているか。

  • 引数に属性なし ATL プロジェクトで属性を使用できますか。

  • 引数に属性付きプロジェクトの .idl ファイルを使用できますか。

  • 今日は属性によって挿入されたコードを変更できますか。

  • 引数に宣言する属性付きインターフェイスを転送したらいいのでしょうか。

  • My は属性を使用するクラスの派生クラス属性を使用できますか。

HRESULT は何ですか。

HRESULT は属性と ATL で戻り値として一般によく使用される単純型です。次の表に各種の値を示します。以上の値はwinerror.h ヘッダー ファイルに含まれています。

名前

Description

S_OK

通常の操作

0x00000000

E_UNEXPECTED

予期しないエラー

0x8000FFFF

E_NOTIMPL

実装されていません

0x80004001

E_OUTOFMEMORY

必要なメモリはできません。

0x8007000E

E_INVALIDARG

一つ以上の引数が無効です

0x80070057

E_NOINTERFACE

サポートされるようなインターフェイスなし

0x80004002

E_POINTER

無効なポインター

0x80004003

E_HANDLE

無効なハンドル

0x80070006

E_ABORT

中止操作

0x80004004

E_FAIL

未指定のエラー

0x80004005

E_ACCESSDENIED

一般的なアクセス拒否エラー

0x80070005

My は属性のパラメーター名を指定する必要があります。

ほとんどの場合属性に一つのパラメーターがの場合そのパラメーターの名前はです。この名前はコードの属性を挿入する必要があります。たとえばaggregatable の属性の使用 :

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

これはと同じです :

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

ただし次の属性に単一の無名のパラメーターがあります :

call_as

case

cpp_quote

default

defaultvalue

defaultvtable

out

エントリ

first_is

helpcontext

helpfile

helpstring

helpstringcontext

helpstringdll

id

iid_is

import

importlib

必要

includelib

last_is

length_is

max_is

no_injected_text

pointer_default

プラグマ

restricted

size_is

source

switch_is

switch_type

transmit_as

wire_marshal

今日は属性ブロックでコメントを使用できますか。

属性ブロック内の単一行と複数行のコメントを使用できます。ただし属性のパラメーターを保持するかっこ内のコメントのいずれかのスタイルを使用できません。

次に許可されています :

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

次に設定されています :

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

属性はどの程度の継承と対話しているか。

独自の場合も属性を使用する他のクラスから属性付き ATL オブジェクトと属性のないクラス継承できます。属性付きクラスから派生した結果は属性プロバイダーの後にそのクラスから派生するコードを追加することも同じです。属性はC++ の継承は派生クラスに転送されません。属性プロバイダーは属性の近くにのみコードを変換します。

引数に属性なし ATL プロジェクトで属性を使用できますか。

.idl ファイルを使用して属性付きオブジェクトを追加するときに開始し属性なし ATL プロジェクトが必要です。このコードを提供するためにクラスの追加ウィザードを使用します。

引数に属性付きプロジェクトの .idl ファイルを使用できますか。

ATL によって属性付きプロジェクトで使用する .idl ファイルがある場合があります。この場合.h ファイルに importidl の属性をコンパイルして .idl ファイル (プロジェクトの [プロパティ ページ] ダイアログ ボックスの [MIDL] プロパティ ページ を参照)プロジェクトに含める .h ファイルを使用します。

今日は属性によって挿入されたコードを変更できますか。

一部の属性はプロジェクトにコードを挿入します。/Fx コンパイラ オプションを使用して挿入されたコードを表示できます。挿入されたファイルのコードをコピーしソース・コードに貼り付けることもできます。これにより属性の動作を変更することができます。ただしコードの他の部分も変更する必要があります。

次の例はソース・コード ファイルに挿入されたコードをコピーした結果です :

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

引数に宣言する属性付きインターフェイスを転送したらいいのでしょうか。

属性付きインターフェイスの事前の宣言を作ろうな場合実際のインターフェイス宣言に適用する事前宣言に同じ属性を適用する必要があります。また事前宣言にエクスポート属性を適用する必要があります。

My は属性を使用するクラスの派生クラス属性を使用できますか。

また属性を使用するクラスの派生クラス属性を使用してではサポートされません。

参照

その他の技術情報

属性付きプログラミングの概念