如何使用 GetValueByName 方法从 d2d 效果属性中获取 ENUM 字段名称

问题描述 投票:0回答:1

我想显示具有枚举属性的任何给定效果的当前枚举[field].name。我的代码结果为 hr = 0x88990029,指定的属性不存在。我的属性全名字符串是否不正确,或者枚举名称从未输入到系统中?我尝试使用这些名称格式:Property.Fields.N 和 Property.N.Fields 作为完整的属性名称,但这些名称格式都不起作用。因此,Property.Fields.N.Index 格式也不能作为一个好的属性名称。

高斯模糊示例,属性 1(优化)是枚举类型。

WCHAR prop_base_name[256] = {0};

WCHAR prop_full_name[256] = {0};

WCHAR enum_fields_name[256] = {0};

ID2DEffect *effect1; // initialized as Gausian Blur

bool Get_Current_Enum_Name(ID2D1Properties *arg_d2d_property)
{

// Get the zero based index that corresponds to the current enum value
// If the enum is zero based and consecutive then the index is the same as the enum value

// ASSERT(arg_d2d_property);

HRESULT hr = S_OK;

UINT32 zero_based_index = 0;

CComPtr<ID2D1Properties> ccptr_sub_property;

hr = arg_d2d_property->GetSubProperties(1, &ccptr_sub_property);

if (FAILED(hr)) { /* err msg */  return false;}

hr = ccptr_sub_property->GetValue(D2D1_SUBPROPERTY_INDEX, &zero_based_index);

hr = arg_d2d_property->GetPropertyName(1, prop_base_name, ARRAYSIZE(prop_base_name));

// Create the full name: using this format Property.Fields.N
StringCbPrintfW
(
    prop_full_name,
    sizeof(prop_full_name),
    L"%s.Fields.%i",
    prop_base_name,
    zero_base_index
);

UINT32 enum_max_fields = 0;

// This works fine: the result is 3 enum fields
hr = arg_d2d_property->GetValueByName(L"Optimization.Fields", (LPBYTE)&enum_max_fields, sizeof(enum_max_fields));

 UINT32 enum_default = 0;

// This works fine: the result is 1
hr = arg_d2d_property->GetValueByName(L"Optimization.Default", (LPBYTE)&enum_default, sizeof(enum_default));

// derived from
// https://learn.microsoft.com/en-us/windows/win32/api/d2d1_1/nn-d2d1_1-id2d1properties

// actual code
// hr = arg_d2d_property->GetValueByName(prop_full_name, (LPBYTE)enum_fields_name, sizeof(enum_fields_name));

// I will use the literal string for simplicity
// fails with hr = 0x88990029 code This Property Does Not Exist
hr = arg_d2d_property->GetValueByName(L"Optimization.Fields.0", (LPBYTE)enum_fields_name, sizeof(enum_fields_name));

 if (hr == S_OK) { return true; }

// fails with hr = 0x88990029 code This Property Does Not Exist
hr = ccptr_sub_property->GetValueByName(L"Optimization.Fields.0", (LPBYTE)enum_fields_name, sizeof(enum_fields_name));

 if (hr == S_OK) { return true; }

  return false;
}

// somewhere in the app

if (Get_Current_Enum_Name(effect1)) 
{ 
  // display the enum value:name
}
else
{
  // display the enum value
}
c++ properties com effects direct2d
1个回答
0
投票

正如 Simmon 指出的那样,深入到子属性级别效果很好。

WCHAR enum_fields_name[256] = {0};

WCHAR enum_fields_name_decorated[256] = {0};

ID2DEffect *effect1; // initialized as Gausian Blur
    
// This is designed to dive into the root property for the name associated with the current enum value
bool Get_Current_Enum_Name(ID2D1Properties *arg_d2d_property, UINT32 arg_prop_index)
{

// ASSERT(arg_d2d_property);

ZeroMemory(enum_fields_name, sizeof(enum_fields_name));

ZeroMemory(enum_fields_name_decorated, sizeof(enum_fields_name_decorated));

if (arg_d2d_property->GetPropertyType(arg_prop_index) != D2D1_PROPERTY_ENUM) 
{
    // this is designed for property type enum 
    
    return false;
}

HRESULT hr = S_OK;

UINT32 enum_value = 0;

UINT32 zero_based_index = 0;

CComPtr<ID2D1Properties> ccptr_sub_property;

CComPtr<ID2D1Properties> ccptr_fields_property;

hr = arg_d2d_property->GetValue(arg_prop_index, (LPBYTE)&enum_value, sizeof(enum_value));

// Level 1 subproperty
hr = arg_d2d_property->GetSubProperties(arg_prop_index, &ccptr_sub_property);

if (FAILED(hr)) { /* err msg */  return false;}

// Level 2 subproperty
hr = ccptr_sub_property->GetSubProperties(D2D1_SUBPROPERTY_FIELDS, &ccptr_fields_property);

if (FAILED(hr)) { /* err msg */  return false;}

// this assumes that the enum is zero_based and incremental by 1
// if these conditions dont apply then more code is required to match the enum
// value with the enum field index

// avoid using the GetValue(...) templates or change zero_based_index to DWORD
hr = arg_d2d_property->GetValue(arg_d2d_index, (LPBYTE)&zero_based_index, sizeof(zero_based_index));

hr = ccptr_fields_property->GetPropertyName
(
    zero_based_index, 
    enum_fields_name, 
    ARRAYSIZE(enum_fields_name)
);

// Decorated Name is value:Name
StringCbPrintfW
(
    enum_fields_name_decorated,
    sizeof(enum_fields_name_decorated),
    L"%i:%s",
    enum_value,
    enum_fields_name
);

  return true;
}

// somewhere in the app

// Display: Optimization
if (Get_Current_Enum_Name(effect1, 1)) 
{ 
  // display Optimization:value:name
}
else
{
  // display Optimization:value
}

// Display: BorderMode
if (Get_Current_Enum_Name(effect1, 2)) 
{ 
  // display BorderMode:value:name
}
else
{
  // display BorderMode:value
}
© www.soinside.com 2019 - 2024. All rights reserved.