I am doing OpenOffice automation using C++ with OLE Bridge.
But i cannot find, how to read value of UNO enums through OLE.
For example how to get value of com.sun.star.awt.FontSlant.ITALIC?
For structures exist Bridge_GetStruct method - exist something like "Bridge_GetEnumValue" for enums?
Or is somewhere documented what concrete value enum items have?
And is concrete values of enums used in UNO guaranted to not change in future?
[Solved] How to read enum values through OLE with C++?
[Solved] How to read enum values through OLE with C++?
Last edited by Hagar Delest on Mon May 05, 2014 9:28 pm, edited 1 time in total.
Reason: tagged [Solved].
Reason: tagged [Solved].
OpenOffice 4.0.1 on Windows 7
- MrProgrammer
- Moderator
- Posts: 4908
- Joined: Fri Jun 04, 2010 7:57 pm
- Location: Wisconsin, USA
Re: How to read enum values through OLE with C++?
Enumerate enumeration nameslostinai wrote:But i cannot find, how to read value of UNO enums through OLE.
I am not a developer, but I would guess that the set of enumeration values could be expanded. However, one would expect existing members of the set will not be deleted, though they might become deprecated.lostinai wrote:And is concrete values of enums used in UNO guaranted to not change in future?
If this answered your question please go to your first post use the Edit button and add [Solved] to the start of the title. You can select the green checkmark icon at the same time.
Mr. Programmer
AOO 4.1.7 Build 9800, MacOS 13.6.3, iMac Intel. The locale for any menus or Calc formulas in my posts is English (USA).
AOO 4.1.7 Build 9800, MacOS 13.6.3, iMac Intel. The locale for any menus or Calc formulas in my posts is English (USA).
Re: How to read enum values through OLE with C++?
@MrProgrammer:
Thank you. I tried the approach from your link, but there is some problem, it does not work for me. I correctly created instance of com.sun.star.reflection.TypeDescriptionManager but when i call getByHierarchicalName i am getting NoSuchElementException for any input parameter i tried. I dont understand whats wrong, there are some indicies of bug in OpenOffice internals, but i don't know if its's relevant to my problem. So finaly i downloaded OpenOffice source and simply searched enum definition and i am using hard-boiled numerical values now. Hope it will be Ok.
Thank you. I tried the approach from your link, but there is some problem, it does not work for me. I correctly created instance of com.sun.star.reflection.TypeDescriptionManager but when i call getByHierarchicalName i am getting NoSuchElementException for any input parameter i tried. I dont understand whats wrong, there are some indicies of bug in OpenOffice internals, but i don't know if its's relevant to my problem. So finaly i downloaded OpenOffice source and simply searched enum definition and i am using hard-boiled numerical values now. Hope it will be Ok.
OpenOffice 4.0.1 on Windows 7
- Charlie Young
- Volunteer
- Posts: 1559
- Joined: Fri May 14, 2010 1:07 am
Re: How to read enum values through OLE with C++?
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.
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
Since in c++ one will also generally have a ServiceManager handy, we can do (assuming all the appropriate header files are included)
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.
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]);
}
}
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
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);
}
}
Apache OpenOffice 4.1.1
Windows XP
Windows XP
Re: How to read enum values through OLE with C++?
@Charlie Young: Nice reply. But I am crazy man. I am trying to automate OpenOffice from external C++ application through OLE Bridge. I have no comfort of headers from OpenOffice SDK - i am not using UNO directly. Yes, its not ideal, but thats my choice
I dont understand UNO and its OLE Bridge deep enough to find whats wrong, but workaround with direct usage of numerical values of enum items works. And this is curently good enough solution for my purposes without needs of investing more time to this concrete problem. Therefore this question is solved for me. Thanks.
I dont understand UNO and its OLE Bridge deep enough to find whats wrong, but workaround with direct usage of numerical values of enum items works. And this is curently good enough solution for my purposes without needs of investing more time to this concrete problem. Therefore this question is solved for me. Thanks.
OpenOffice 4.0.1 on Windows 7
-
- Posts: 1
- Joined: Wed Jul 09, 2014 2:57 pm
Re: [Solved] How to read enum values through OLE with C++?
@Charlie Young: Thanks for your solutions. Your tip of using CoreReflection worked for me with Python.
Apache OpenOffice 4.1.0 - Windows 8.1