使用GetValueByName获取D2D特效枚举字段名遇0x88990029错误求助
问题:获取D2D特效枚举属性名称失败(错误码0x88990029)
我想要获取任意带有枚举属性的D2D特效当前枚举字段的.name,但运行代码时返回错误码hr=0x88990029(提示指定属性不存在)。试过Property.Fields.N、Property.N.Fields、Property.Fields.N.Index等格式都无法生效,不确定是属性全名格式错误,还是枚举名称未被系统录入。
以高斯模糊特效为例,其Optimization属性为枚举类型,以下是我的代码:
WCHAR prop_base_name[256] = {0}; WCHAR prop_full_name[256] = {0}; WCHAR enum_fields_name[256] = {0}; ID2DEffect *effect1; // initialized as Gaussian 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_based_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 }
解决方案
错误核心是对D2D枚举属性的访问逻辑理解有误,枚举字段的名称不能通过直接拼接路径的方式获取,正确的做法是通过子属性层级逐层访问:
关键修正逻辑
- 不要硬编码属性索引(比如代码中的
1),改用属性名称获取索引,避免不同特效属性顺序不一致的问题。 - 枚举的
Fields是字段数量属性,而非可直接索引的集合入口,每个枚举字段是独立的子属性,包含Name(名称)和Value(对应值)两个子属性。 - 先获取当前枚举值,再遍历所有枚举字段匹配值,进而获取对应的名称。
修正后的代码示例
bool Get_Current_Enum_Name(ID2D1Properties* arg_d2d_property) { HRESULT hr = S_OK; WCHAR enum_field_name[256] = {0}; // 1. 通过属性名称获取Optimization的索引(比硬编码索引更可靠) UINT32 opt_prop_index = 0; hr = arg_d2d_property->GetPropertyIndex(L"Optimization", &opt_prop_index); if (FAILED(hr)) return false; // 2. 获取Optimization枚举的子属性集合 CComPtr<ID2D1Properties> enum_sub_props; hr = arg_d2d_property->GetSubProperties(opt_prop_index, &enum_sub_props); if (FAILED(hr)) return false; // 3. 获取当前特效的Optimization枚举值 UINT32 current_enum_value = 0; hr = arg_d2d_property->GetValue(opt_prop_index, ¤t_enum_value); if (FAILED(hr)) return false; // 4. 获取枚举的字段总数 UINT32 field_count = 0; hr = enum_sub_props->GetValueByName(L"Fields", &field_count); if (FAILED(hr)) return false; // 5. 遍历所有枚举字段,匹配当前值并获取名称 for (UINT32 i = 0; i < field_count; ++i) { CComPtr<ID2D1Properties> field_sub_prop; hr = enum_sub_props->GetSubProperties(i, &field_sub_prop); if (FAILED(hr)) continue; // 获取当前字段的枚举值 UINT32 field_value = 0; hr = field_sub_prop->GetValueByName(L"Value", &field_value); if (FAILED(hr)) continue; // 匹配成功则获取字段名称 if (field_value == current_enum_value) { hr = field_sub_prop->GetValueByName(L"Name", enum_field_name, ARRAYSIZE(enum_field_name)); if (SUCCEEDED(hr)) { // enum_field_name即为当前枚举的名称 return true; } } } return false; }
内容的提问来源于stack exchange,提问作者Sempai-Dami1
相关产品推荐
相关产品推荐

