Playing around with this. I don't find any bug, I think it's how one gets the TypeDescriptionManager that might be the problem.
Getting it via the singleton, I can do this in c++. A c++ automation program will generally have a Reference<XComponentContext> laying around somewhere (though this can be slightly tricky in a c++ add-in function), in the following it's called xComponentContext.
This just writes the names into a Calc CellRange called outRange, assumed to be at least two columns wide and to have enough rows to hold the output. Obviously there are many other things one can do with the names and values.
Code: Select all
OUString sFullName = OUString::createFromAscii("com.sun.star.awt.FontSlant");
Any oTDMA = xComponentContext->getValueByName(OUString::createFromAscii("/singletons/com.sun.star.reflection.theTypeDescriptionManager"));
Reference<XEnumTypeDescription> oTDM; //(oTDMA,UNO_QUERY);
Reference<XHierarchicalNameAccess> oTDMH(oTDMA,UNO_QUERY);
if(oTDMH->hasByHierarchicalName(sFullName)) {
Any EnumNamesA = oTDMH->getByHierarchicalName(sFullName);
oTDM = Reference<XEnumTypeDescription>(EnumNamesA,UNO_QUERY);
Sequence<OUString> EnumNames = oTDM->getEnumNames();
Sequence<long> EnumValues = oTDM->getEnumValues();
for(i = 0;i < EnumNames.getLength();i++)
{
xText = Reference<XTextRange>(outRange->getCellByPosition(0,i),UNO_QUERY);
xText->setString(EnumNames[i]);
outRange->getCellByPosition(1,i)->setValue((double) EnumValues[i]);
}
}
Getting the EnumValues isn't really necessary of course, since it is always true that EnumValues
= i.
I also wondered if there was an alternative to using the TypeDescriptionManager, and there is; we can use CoreReflection.
In Basic, this function returns an array of the Names
Code: Select all
Function getEnumNames(sFullName As String)
Dim oSM As Object
Dim oNames
Dim oFields
Dim i As Long
oSM = createUnoService("com.sun.star.reflection.CoreReflection")
If oSM.hasByHierarchicalName(sFullName) Then
oNames = oSM.getByHierarchicalName(sFullName) '.getEnumNames()
oFields = oNames.getFields()
Dim eNames(UBound(oFields)) As String
For i = 0 To UBound(oFields)
eNames(i) = oFields(i).getName()
Next i
getEnumNames = eNames
Else
getEnumNames = "Invalid Enum Name."
End If
End Function
Since in c++ one will also generally have a ServiceManager handy, we can do (assuming all the appropriate header files are included)
Code: Select all
OUString sFullName = OUString::createFromAscii("com.sun.star.awt.FontSlant");
Reference< XInterface > oTDMA = rOfficeServiceManager->createInstance(
OUString::createFromAscii( "com.sun.star.reflection.CoreReflection" ));
Reference<XIdlClass> oTDM;
Reference<XHierarchicalNameAccess> oTDMH(oTDMA,UNO_QUERY);
if(oTDMH->hasByHierarchicalName(sFullName)) {
Any EnumNamesA = oTDMH->getByHierarchicalName(sFullName);
oTDM = Reference<XIdlClass>(EnumNamesA,UNO_QUERY);
Sequence<Reference<XIdlField>> EnumNames = oTDM->getFields();
Reference<XIdlMember> xMember;
for(i = 0;i < EnumNames.getLength();i++)
{
xMember = Reference<XIdlMember> (EnumNames[i],UNO_QUERY);
xText = Reference<XTextRange>(outRange->getCellByPosition(0, i),UNO_QUERY);
xText->setString(xMember->getName());
outRange->getCellByPosition(1, i)->setValue((double) i);
}
}
I also am playing with a c++ class to get this stuff, but I'll present it later, if I haven't decided it's too baroque.