カスタム プロパティ、イベント、およびコントロール パターンを登録する
カスタム プロパティ、イベント、またはコントロール パターンを使用するには、プロバイダーとクライアントの両方が実行時にプロパティ、イベント、またはコントロール パターンを登録する必要があります。 登録はアプリケーション プロセス内でグローバルに有効であり、プロセスが終了するか、最後の Microsoft UI オートメーション 要素オブジェクト (IUIAutomation または IRawElementProviderSimple) がプロセス内で解放されるまで有効です。
再生成には、カスタム プロパティ、イベント、またはコントロール パターンに関する詳細情報と共に、GUID をUI オートメーションに渡す必要があります。 同じ情報を使用して同じ GUID を 2 回目に登録しようとすると成功しますが、同じ GUID を 2 回目に登録しようとしても、異なる情報 (異なる型のカスタム プロパティなど) を使用しようとすると失敗します。 今後、カスタム仕様が受け入れられ、UI オートメーション コアに統合される場合、UI オートメーションはカスタム登録情報を検証し、"公式" フレームワーク実装の代わりに既に登録されているコードを使用するため、アプリケーションの互換性の問題が最小限に抑えられます。 既に登録されているプロパティ、イベント、またはコントロール パターンを削除することはできません。
このトピックは、次のセクションで構成されています。
カスタム プロパティとイベントの登録
カスタム プロパティまたはイベントを登録すると、プロバイダーとクライアントはプロパティまたはイベントの ID を取得できます。これにより、ID をパラメーターとして受け取るさまざまな API メソッドに渡すことができます。
プロパティまたはイベントを登録するには:
- カスタム プロパティまたはイベントの GUID を定義します。
-
UIAutomationPropertyInfo または UIAutomationEventInfo 構造体に、カスタム プロパティまたはイベントの名前を含む GUID および非ローカライズ可能な文字列を含む、プロパティまたはイベントに関する情報を入力します。 また、カスタム プロパティでは、プロパティのデータ型を指定する必要があります。たとえば、プロパティが整数か文字列かを指定します。 データ型は、 UIAutomationType 列挙で指定された次のいずれかの型である必要があります。 カスタム プロパティでは、他のデータ型はサポートされていません。
- UIAutomationType_Bool
- UIAutomationType_Double
- UIAutomationType_Element
- UIAutomationType_Int
- UIAutomationType_Point
- UIAutomationType_String
- CoCreateInstance 関数を使用して、CUIAutomationRegistrar オブジェクトのインスタンスを作成し、オブジェクトの IUIAutomationRegistrar インターフェイスへのポインターを取得します。
- IUIAutomationRegistrar::RegisterProperty メソッドまたは RegisterEvent メソッドを呼び出し、UIAutomationPropertyInfo 構造体または UIAutomationEventInfo 構造体のアドレスを渡します。
IUIAutomationRegistrar::RegisterProperty メソッドまたは RegisterEvent メソッドは、このような識別子をパラメーターとして受け取る任意のUI オートメーション メソッドにアプリケーションが渡すことができるプロパティ ID またはイベント ID を返します。 たとえば、登録済みのプロパティ ID を IUIAutomationElement::GetCurrentPropertyValue メソッドまたは IUIAutomation::CreatePropertyCondition メソッドに渡すことができます。
次の例では、カスタム プロパティを登録する方法を示します。
// Declare a variable for holding the custom property ID.
PATTERNID g_MyCustomPropertyID;
// Define a GUID for the custom property.
GUID GUID_MyCustomProperty = { 0x82f383ff, 0x4b4d, 0x40d3,
{ 0x8e, 0xd2, 0x90, 0xb5, 0x25, 0x8e, 0xaa, 0x19 } };
HRESULT RegisterProperty()
{
// Fill the structure with the GUID, name, and data type.
UIAutomationPropertyInfo MyCustomPropertyInfo =
{
GUID_MyCustomProperty,
L"MyCustomProp",
UIAutomationType_String
};
// Create the registrar object and get the IUIAutomationRegistrar
// interface pointer.
IUIAutomationRegistrar * pUIARegistrar = NULL;
CoCreateInstance(CLSID_CUIAutomationRegistrar, NULL, CLSCTX_INPROC_SERVER,
IID_IUIAutomationRegistrar, (void **)&pUIARegistrar);
if (pUIARegistrar == NULL)
return E_NOINTERFACE;
// Register the property and retrieve the property ID.
HRESULT hr = pUIARegistrar->RegisterProperty(&MyCustomPropertyInfo, &g_MyCustomPropertyID);
pUIARegistrar->Release();
return hr;
}
IUIAutomationRegistrar::RegisterProperty メソッドと RegisterEvent メソッドによって取得されるプロパティとイベント識別子は、それらを取得するアプリケーションのコンテキストでのみ有効であり、アプリケーションの有効期間中のみ有効です。 登録メソッドは、同じアプリケーションの異なるランタイム インスタンスで呼び出されると、同じ GUID に対して異なる整数値を返すことができます。
カスタム プロパティまたはイベントの登録を解除するメソッドはありません。 代わりに、最後のUI オートメーション オブジェクトが解放されると、暗黙的に登録解除されます。
重要
コードが Microsoft Active Accessibility (MSAA) クライアントの場合は、カスタム プロパティの値を変更するときに NotifyWinEvent 関数を呼び出す必要があります。
カスタム コントロール パターンの実装
カスタム コントロール パターンは、UI オートメーション API には含まれていませんが、実行時にサード パーティによって提供されます。 クライアント アプリケーションとプロバイダー アプリケーションの開発者は連携して、コントロール パターンでサポートされるメソッド、プロパティ、イベントなど、カスタム コントロール パターンを定義する必要があります。 コントロール パターンを定義した後、クライアントとプロバイダーの両方が、実行時にコントロール パターンを登録するコードと共に、サポートコンポーネント オブジェクト モデル (COM) オブジェクトを実装する必要があります。 カスタム コントロール パターンには、クライアント ラッパーとパターン ハンドラーという 2 つの COM オブジェクトの実装が必要です。
注意
次のトピックの例では、既存の Value コントロール パターンの機能を複製するカスタム コントロール パターンを実装する方法を示します。 これらの例は、説明のみを目的としています。 実際のカスタム コントロール パターンには、標準のUI オートメーションコントロール パターンでは使用できない機能が用意されている必要があります。
クライアント ラッパーとパターン ハンドラー
クライアント ラッパーは、カスタム コントロール パターンによって公開されるプロパティと呼び出しメソッドを取得するためにクライアントによって使用される API を実装します。 API は、すべてのプロパティ要求とメソッド呼び出しを UI オートメーション コアに渡す COM インターフェイスとして実装され、要求と呼び出しがプロバイダーにマーシャリングされます。
カスタム コントロール パターンを登録するコードでは、UI オートメーションクライアント ラッパー オブジェクトのインスタンスを作成するために使用できるクラス ファクトリを指定する必要があります。 カスタム コントロール パターンが正常に登録されると、UI オートメーションは、プロパティ要求とメソッド呼び出しをUI オートメーション コアに転送するためにクライアントによって使用される IUIAutomationPatternInstance インターフェイス ポインターを返します。
プロバイダー側では、UI オートメーション コアは、クライアントからのプロパティ要求とメソッド呼び出しを受け取り、それらをパターン ハンドラー オブジェクトに渡します。 その後、パターン ハンドラーは、カスタム コントロール パターンのプロバイダー インターフェイスで適切なメソッドを呼び出します。
カスタム コントロール パターンを登録するコードは、パターン ハンドラー オブジェクトを作成し、コントロール パターンを登録するときに、UI オートメーションにオブジェクトの IUIAutomationPatternHandler インターフェイスへのポインターを提供します。
次の図は、クライアント プロパティの要求またはメソッド呼び出しがクライアント ラッパーから、UI オートメーションコア コンポーネントを経由してパターン ハンドラーに、プロバイダー インターフェイスに流れる方法を示しています。
クライアント ラッパーおよびパターン ハンドラー インターフェイスを実装するオブジェクトは、フリー スレッドである必要があります。 また、UI オートメーション コアは、中間マーシャリング コードなしでオブジェクトを直接呼び出すことができる必要があります。
クライアント ラッパーの実装
クライアント ラッパーは、クライアントがカスタム コントロール パターンでサポートされているプロパティと呼び出しメソッドを要求するために使用する IXxxPattern インターフェイスを公開するオブジェクトです。 インターフェイスは、サポートされている各プロパティ (get_CurrentXxx メソッドと get_CachedXxx メソッド) の "getter" メソッドのペアと、サポートされている各メソッドの "呼び出し元" メソッドで構成されます。 オブジェクトがインスタンス化されると、オブジェクト コンストラクターは、UI オートメーション コアによって実装される IUIAutomationPatternInstance インターフェイスへのポインターを受け取ります。 IXxxPattern インターフェイスのメソッドでは、IUIAutomationPatternInstance::GetProperty メソッドと CallMethod メソッドを使用して、プロパティ要求とメソッド呼び出しを UI オートメーション コアに転送します。
次の例では、1 つのプロパティをサポートする単純なカスタム コントロール パターンのクライアント ラッパー オブジェクトを実装する方法を示します。 より複雑な例については、「 カスタム コントロール パターンの実装例」を参照してください。
// Define the client interface.
interface __declspec(uuid("c78b266d-b2c0-4e9d-863b-e3f74a721d47"))
IMyCustomPattern : public IUnknown
{
STDMETHOD (get_CurrentIsReadOnly)(BOOL * pIsReadOnly) = 0;
STDMETHOD (get_CachedIsReadOnly)(BOOL * pIsReadOnly) = 0;
};
// Implement the client wrapper class.
class CMyValuePatternClientWrapper :
public IMyCustomPattern
{
IUIAutomationPatternInstance * _pInstance;
public:
// Get IUIAutomationPatternInstance interface pointer from the
// UI Automation core.
CMyValuePatternClientWrapper(IUIAutomationPatternInstance * pInstance)
: _pInstance(pInstance)
{
_pInstance->AddRef();
}
~CMyValuePatternClientWrapper()
{
_pInstance->Release();
}
// Note: Put standard IUnknown implementation here.
STDMETHODIMP get_CurrentIsReadOnly(BOOL * pIsReadOnly)
{
return _pInstance->GetProperty(0, FALSE, UIAutomationType_Bool, pIsReadOnly);
}
STDMETHODIMP get_CachedIsReadOnly(BOOL * pIsReadOnly)
{
return _pInstance->GetProperty(0, TRUE, UIAutomationType_Bool, pIsReadOnly);
}
};
パターン ハンドラーの実装
パターン ハンドラーは、 IUIAutomationPatternHandler インターフェイスを実装するオブジェクトです。 このインターフェイスには、 IUIAutomationPatternHandler::CreateClientWrapper と Dispatch の 2 つのメソッドがあります。 CreateClientWrapper メソッドは、UI オートメーション コアによって呼び出され、IUIAutomationPatternInstance インターフェイスへのポインターを受け取ります。 CreateClientWrapper は、クライアント ラッパー オブジェクトをインスタンス化し、 IUIAutomationPatternInstance インターフェイス ポインターをクライアント ラッパー コンストラクターに渡すことによって応答します。
Dispatch メソッドは、カスタム コントロール パターンのプロバイダー インターフェイスにプロパティ要求とメソッド呼び出しを渡すために、UI オートメーション コアによって使用されます。 パラメーターには、プロバイダー インターフェイスへのポインター、呼び出されるプロパティ getter またはメソッドの 0 から始まるインデックス、およびプロバイダーに渡すパラメーターを含む UIAutomationParameter 構造体の配列が含まれます。 パターン ハンドラーは、index パラメーターを調べて呼び出すプロバイダー メソッドを特定し、そのプロバイダー インターフェイスを呼び出して UIAutomationParameter 構造体に含まれるパラメーターを渡すことで応答します。
パターン ハンドラー オブジェクトは、コントロール パターンが登録される前に、カスタム コントロール パターンを登録するのと同じコードによってインスタンス化されます。 コードは、登録時にパターン ハンドラー オブジェクトの IUIAutomationPatternHandler インターフェイス ポインターを UI オートメーション コアに渡す必要があります。
次の例は、1 つのプロパティをサポートする単純なカスタム コントロール パターンのパターン ハンドラー オブジェクトを実装する方法を示しています。 より複雑な例については、「 カスタム コントロール パターンの実装例」を参照してください。
// Define the provider interface.
interface __declspec(uuid("9f5266dd-f0ab-4562-8175-c383abb2569e"))
IMyValueProvider : public IUnknown
{
STDMETHOD (get_IsReadOnly)(BOOL * pIsReadOnly) = 0;
};
// Index used by IUIAutomationPatternHandler::Dispatch.
const int MyValue_GetIsReadOnly = 0;
// Define the pattern handler class.
class CMyValuePatternHandler : public IUIAutomationPatternHandler
{
public:
// Put standard IUnknown implementation here.
STDMETHODIMP CreateClientWrapper(
IUIAutomationPatternInstance * pPatternInstance,
IUnknown ** pClientWrapper)
{
*pClientWrapper = new CMyValuePatternClientWrapper(pPatternInstance);
if (*pClientWrapper == NULL)
return E_INVALIDARG;
return S_OK;
}
STDMETHODIMP Dispatch (IUnknown * pTarget, UINT index,
const struct UIAutomationParameter *pParams, UINT cParams)
{
switch(index)
{
case MyValue_GetIsReadOnly:
return ((IMyValueProvider*)pTarget)->get_IsReadOnly((BOOL*)pParams[0].pData);
}
return E_INVALIDARG;
}
};
カスタム コントロール パターンの登録
使用する前に、プロバイダーとクライアントの両方でカスタム コントロール パターンを登録する必要があります。 登録により、UI オートメーション コアにコントロール パターンに関する詳細情報が提供され、コントロール パターン ID と、コントロール パターンでサポートされるプロパティとイベントの ID がプロバイダーまたはクライアントに提供されます。 プロバイダー側では、関連付けられたコントロールが WM_GETOBJECT メッセージを処理する前に、または同時にカスタム コントロール パターンを登録する必要があります。
カスタム コントロール パターンを登録する場合、プロバイダーまたはクライアントは次の情報を提供します。
- カスタム コントロール パターンの GUID。
- カスタム コントロール パターンの名前を含む、割り当て不可能な文字列。
- カスタム コントロール パターンをサポートするプロバイダー インターフェイスの GUID。
- カスタム コントロール パターンをサポートするクライアント インターフェイスの GUID。
- カスタム コントロール パターンでサポートされるプロパティを記述する UIAutomationPropertyInfo 構造体の配列。 プロパティごとに、GUID、プロパティ名、およびデータ型を指定する必要があります。
- カスタム コントロール パターンでサポートされるメソッドを記述する UIAutomationMethodInfo 構造体の配列。 各メソッドの構造体には、メソッド名、パラメーターの数、パラメーター データ型の一覧、およびパラメーター名の一覧という情報が含まれます。
- カスタム コントロール パターンによって発生するイベントを記述する UIAutomationEventInfo 構造体の配列。 イベントごとに、GUID とイベント名を指定する必要があります。
- カスタム コントロール パターンをクライアントで使用できるようにするパターン ハンドラー オブジェクトの IUIAutomationPatternHandler インターフェイスのアドレス。
カスタム コントロール パターンを登録するには、プロバイダーまたはクライアント コードで次の手順を実行する必要があります。
- UIAutomationPatternInfo 構造体に上記の情報を入力します。
- CoCreateInstance 関数を使用して、CUIAutomationRegistrar オブジェクトのインスタンスを作成し、オブジェクトの IUIAutomationRegistrar インターフェイスへのポインターを取得します。
- UIAutomationPatternInfo 構造体のアドレスを渡して、IUIAutomationRegistrar::RegisterPattern メソッドを呼び出します。
RegisterPattern メソッドは、コントロール パターン ID と、プロパティ ID とイベント ID の一覧を返します。 アプリケーションは、このような識別子をパラメーターとして受け取る任意のUI オートメーションメソッドにこれらの ID を渡すことができます。 たとえば、 IUIAutomationElement::GetCurrentPattern メソッドに登録済みのパターン ID を渡して、コントロール パターンのプロバイダー インターフェイスへのポインターを取得できます。
カスタム コントロール パターンの登録を解除するメソッドはありません。 代わりに、最後のUI オートメーション オブジェクトが解放されると、暗黙的に登録解除されます。
カスタム コントロール パターンを登録する方法を示す例については、次のセクションを参照してください。
カスタム コントロール パターンの実装例
このセクションには、カスタム コントロール パターンのクライアント ラッパー オブジェクトとパターン ハンドラー オブジェクトを実装する方法を示すコード例が含まれています。 この例では、 Value コントロール パターンに基づくカスタム コントロール パターンを実装しています。
// Step 1: Define the public provider and client interfaces using IDL. Interface
// definitions are in C here to simplify the example.
// Define the provider interface.
interface __declspec(uuid("9f5266dd-f0ab-4562-8175-c383abb2569e"))
IMyValueProvider : public IUnknown
{
STDMETHOD (get_Value)(BSTR * pValue) = 0;
STDMETHOD (get_IsReadOnly)(BOOL * pIsReadOnly) = 0;
STDMETHOD (SetValue)(LPCWSTR pNewValue) = 0;
STDMETHOD (Reset)() = 0;
};
// Define the client interface.
interface __declspec(uuid("103b8323-b04a-4180-9140-8c1e437713a3"))
IUIAutomationMyValuePattern : public IUnknown
{
STDMETHOD (get_CurrentValue)(BSTR * pValue) = 0;
STDMETHOD (get_CachedValue)(BSTR * pValue) = 0;
STDMETHOD (get_CurrentIsReadOnly)(BOOL * pIsReadOnly) = 0;
STDMETHOD (get_CachedIsReadOnly)(BOOL * pIsReadOnly) = 0;
STDMETHOD (SetValue)(LPCWSTR pNewValue) = 0;
STDMETHOD (Reset)() = 0;
};
// Enumerate the properties and methods starting from 0, and placing the
// properties first.
enum
{
MyValue_GetValue = 0,
MyValue_GetIsReadOnly = 1,
MyValue_SetValue = 2,
MyValue_Reset = 3,
};
// Step 2: Implement the client wrapper class.
class CMyValuePatternClientWrapper :
public IUIAutomationMyValuePattern
{
IUIAutomationPatternInstance * _pInstance;
public:
// Get IUIAutomationPatternInstance interface pointer.
CMyValuePatternClientWrapper(IUIAutomationPatternInstance * pInstance)
{
_pInstance = pInstance;
_pInstance->AddRef();
}
// Put standard IUnknown implementation here.
STDMETHODIMP get_CurrentValue(BSTR * pValue)
{
return _pInstance->GetProperty(MyValue_GetValue, FALSE,
UIAutomationType_String, pValue);
}
STDMETHODIMP get_CachedValue(BSTR * pValue)
{
return _pInstance->GetProperty(MyValue_GetValue, TRUE,
UIAutomationType_String, pValue);
}
STDMETHODIMP get_CurrentIsReadOnly(BOOL * pIsReadOnly)
{
return _pInstance->GetProperty(MyValue_GetIsReadOnly, FALSE,
UIAutomationType_Bool, pIsReadOnly);
}
STDMETHODIMP get_CachedIsReadOnly(BOOL * pIsReadOnly)
{
return _pInstance->GetProperty(MyValue_GetIsReadOnly, TRUE,
UIAutomationType_Bool, pIsReadOnly);
}
STDMETHODIMP SetValue(LPCWSTR pValue)
{
UIAutomationParameter SetValueParams[] =
{ UIAutomationType_String, &pValue };
return _pInstance->CallMethod(MyValue_SetValue, SetValueParams,
ARRAYSIZE(SetValueParams));
}
STDMETHODIMP Reset()
{
return _pInstance->CallMethod(MyValue_Reset, NULL, 0);
}
};
// Step 3: Implement the pattern handler class.
class CMyValuePatternHandler : public IUIAutomationPatternHandler
{
public:
// Put standard IUnknown implementation here.
STDMETHODIMP CreateClientWrapper(
IUIAutomationPatternInstance * pPatternInstance,
IUnknown ** pClientWrapper)
{
*pClientWrapper = new CMyValuePatternClientWrapper(pPatternInstance);
if (*pClientWrapper == NULL)
return E_INVALIDARG;
return S_OK;
}
STDMETHODIMP Dispatch (IUnknown * pTarget, UINT index,
const struct UIAutomationParameter *pParams,
UINT cParams)
{
switch(index)
{
case MyValue_GetValue:
return ((IMyValueProvider*)pTarget)->get_Value((BSTR*)pParams[0].pData);
case MyValue_GetIsReadOnly:
return ((IMyValueProvider*)pTarget)->get_IsReadOnly((BOOL*)pParams[0].pData);
case MyValue_SetValue:
return ((IMyValueProvider*)pTarget)->SetValue(*(LPCWSTR*)pParams[0].pData);
case MyValue_Reset:
return ((IMyValueProvider*)pTarget)->Reset();
}
return E_INVALIDARG;
}
};
CMyValuePatternHandler g_MyValuePatternHandler;
// Step 4: Declare information about the properties and methods supported
// by the custom control pattern.
// Define GUIDs for the custom control pattern and each of its properties
// and events.
static const GUID MyValue_Pattern_Guid = { 0xa49aa3c0, 0xe413, 0x4ecf,
{ 0xa1, 0xc3, 0x37, 0x42, 0xa7, 0x86, 0x67, 0x3f } };
static const GUID MyValue_Value_Property_Guid = { 0xe58f3f67, 0x22c7, 0x44f0,
{ 0x83, 0x55, 0xd8, 0x76, 0x14, 0xa1, 0x10, 0x81 } };
static const GUID MyValue_IsReadOnly_Property_Guid = { 0x480540f2, 0x9829, 0x4acd,
{ 0xb8, 0xea, 0x6e, 0x2a, 0xdc, 0xe5, 0x3a, 0xfb } };
static const GUID MyValue_Reset_Event_Guid = { 0x5b80edd3, 0x67f, 0x4a70,
{ 0xb0, 0x7, 0x4, 0x12, 0x85, 0x11, 0x1, 0x7a } };
// Declare information about the properties, in the same order as the
// previously defined "MyValue_" enumerated type.
UIAutomationPropertyInfo g_MyValueProperties[] =
{
// GUID, name, data type.
{ MyValue_Value_Property_Guid, L"MyValuePattern.Value",
UIAutomationType_String },
{ MyValue_IsReadOnly_Property_Guid, L"MyValuePattern.IsReadOnly",
UIAutomationType_Bool },
};
// Declare information about the event.
UIAutomationEventInfo g_MyValueEvents [] =
{
{ MyValue_Reset_Event_Guid, L"MyValuePattern.Reset" },
};
// Declare the data type and name of the SetValue method parameter.
UIAutomationType g_SetValueParamTypes[] = { UIAutomationType_String };
LPCWSTR g_SetValueParamNames[] = {L"pNewValue"};
// Declare information about the methods.
UIAutomationMethodInfo g_MyValueMethods[] =
{
// Name, focus flag, count of in parameters, count of out parameters, types, parameter names.
{ L"MyValuePattern.SetValue", TRUE, 1, 0, g_SetValueParamTypes, g_SetValueParamNames },
{ L"MyValuePattern.Reset", TRUE, 0, 0, NULL, NULL },
};
// Declare the custom control pattern using the previously defined information.
UIAutomationPatternInfo g_ValuePatternInfo =
{
MyValue_Pattern_Guid,
L"MyValuePattern",
__uuidof(IMyValueProvider),
__uuidof(IUIAutomationMyValuePattern),
ARRAYSIZE(g_MyValueProperties), g_MyValueProperties, // properties
ARRAYSIZE(g_MyValueMethods), g_MyValueMethods, // methods
ARRAYSIZE(g_MyValueEvents), g_MyValueEvents, // events
&g_MyValuePatternHandler
};
// Step 5: Register the custom control pattern and retrieve the control pattern and property
// identifiers.
// Control pattern, property, and event IDs.
PATTERNID g_MyValue_PatternID;
PROPERTYID g_MyValue_Value_PropertyID;
PROPERTYID g_MyValue_IsReadOnly_PropertyID;
EVENTID g_MyValueReset_EventID;
// ID used by the client to determine whether the custom control pattern is available.
PROPERTYID g_IsMyValuePatternAvailable_PropertyID;
HRESULT RegisterPattern()
{
// Create the registrar object and get the IUIAutomationRegistrar interface pointer.
IUIAutomationRegistrar * pUIARegistrar;
CoCreateInstance(CLSID_CUIAutomationRegistrar, NULL, CLSCTX_INPROC_SERVER,
IID_IUIAutomationRegistrar, (void **)&pUIARegistrar);
if (pUIARegistrar == NULL)
return E_NOINTERFACE;
PROPERTYID propIDs[2]; // Array for property IDs.
// Register the control pattern.
HRESULT hr = pUIARegistrar->RegisterPattern(
&g_ValuePatternInfo,
&g_MyValue_PatternID,
&g_IsMyValuePatternAvailable_PropertyID,
ARRAYSIZE(propIDs),
propIDs,
1,
&g_MyValueReset_EventID);
if (hr == S_OK)
{
// Copy the property IDs.
g_MyValue_Value_PropertyID = propIDs[0];
g_MyValue_IsReadOnly_PropertyID = propIDs[1];
}
pUIARegistrar->Release();
return hr;
}
関連トピック
-
概念