我想显示具有枚举属性的任何给定效果的当前枚举[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
}
正如 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
}