How can I get the ENUM field name from an d2d effect property by using the GetValueByName method

74 Views Asked by At

I would like to display the current enum[field].name for any given effect that has an enum property. My code results in hr = 0x88990029, the specified property does not exist. Is my property full name string incorrect or is it that the enum names were never entered into the system? I've tried using these name formats: Property.Fields.N and Property.N.Fields as the full property name but none of these name formats work. Consequently, Property.Fields.N.Index format does not work as a good property name either.

Example for the Gausian Blur, the property 1, Optimimization, is of type enum.

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
}
1

There are 1 best solutions below

0
Sempai-Dami1 On

As Simon pointed out, drilling down the subproperty level works fine.

ID2DEffect *effect1; // initialized as Gausian Blur (ENUM's starts at value 0)
ID2DEffect *effect2; // initialized as Sepia (ENUM starts at value 1)
 
// This is designed to list the enum values and names 

bool List_All_Enum_Names(HWND listbox_hwnd, ID2D1Properties *arg_d2d_property, UINT32 arg_prop_index)
{

// ASSERT(listbox_hwnd)
// ASSERT(arg_d2d_property);

// validate the prorperty is of type enum
if (arg_d2d_property->GetType(arg_prop_index) != D2D1_PROPERTY_ENUM) { return false; }

HRESULT hr = S_OK;

UINT32 enum_fields_value = 0;

WCHAR enum_fields_name[256] = {0};

WCHAR enum_fields_name_decorated[256] = {0};

CComPtr<ID2D1Properties> ccptr_sub_property;

CComPtr<ID2D1Properties> ccptr_enum_fields_names;

// Reset_ListBox_Contents(listbox_hwnd);    

// Level 1: sub property 
hr = arg_d2d_property->GetSubProperty(arg_prop_index, &ccptr_sub_property);

if (FAILED(hr)) { /* Get ccptr_sub_property FAILED */; return false; }

// Level 2: enum_fields_names interface
hr = ccptr_sub_property->GetSubProperty(D2D1_SUBPROPERTY_FIELDS, &ccptr_enum_fields_names);

if (FAILED(hr)) { /* Get ccptr_enum_fields_names FAILED */; return false; }

// Generic zero based index range 0-100
for (UINT32 zb_index = 0; zb_index <= 100; ++zb_index)
{
    { // scope the enum_fields_value interface
      
      // Level 3: enum_fields_value
      CComPtr<ID2D1Properties> ccptr_enum_fields_value;
      
      hr = ccptr_enum_fields_names->GetSubProperty(zb_index, &ccptr_enum_fields_value);

      // non-critical since the max index is unknown
      if (FAILED(hr)) { break; }

      hr = ccptr_enum_fields_value->GetValue(0, &enum_fields_value);

      if (FAILED(hr)) { /* GetValue(0) FAILED */; return false; }
     
    } // ccptr_enum_fields_value is out of scope and destroyed

    ZeroMemory(enum_fields_name, sizeof(enum_fields_name));

    ZeroMemory(enum_fields_name_decorated, sizeof(enum_fields_name_decorated));

    hr = ccptr_enum_fields_name->GetPropertyName
    (
        zb_index, 
        enum_fields_name, 
        ARRAYSIZE(enum_fields_name)
    );

    if (FAILED(hr)) { /* GetPropertyName(zb_index) FAILED */; return false; }

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

    // Send_Name_To_ListBox(listbox_hwnd, enum_fields_name_decorated, enum_fields_value);

    } // for loop

    return true;
}