misc_bb 7 Posted July 20, 2021 I'm trying to test out this DirectOffice library but their demo project is really very limited. I need a little help. Their library file is quite big which can be found here Demo. But let me just point out some since I'm a bit confuse with the IComparable in assigning the value to the property. I'm trying to compare some C# code and convert the same code in Delphi. Consider this code (C#): MainDocumentPart mainDocumentPart = doc.AddMainDocumentPart(); mainDocumentPart.Document = new Document(); Body body = mainDocumentPart.Document.AppendChild(new Body()); Paragraph para = body.AppendChild(new Paragraph()); Run run =para.AppendChild(new Run()); RunProperties runProperties = run.AppendChild(new RunProperties()); FontSize fontSize = new FontSize(); fontSize.Val = "40"; runProperties.AppendChild(fontSize); run.AppendChild(new Text("Welcome!!!!!")); mainDocumentPart.Document.Save(); Using the DirectOffice library, it would look like this in Delphi: MainPart := WordDocument.AddMainDocumentPart; // create document Document := CoDocument.Create; MainPart.Document := Document; // create body Body := CoBody.Create; Document.AppendChild(Body as _OpenXmlElement); // create paragraph Paragraph := CoDocumentFormat_OpenXml_Wordprocessing_Paragraph.Create; Body.AppendChild(Paragraph as _OpenXmlElement); // create run Run := CoDocumentFormat_OpenXml_Wordprocessing_Run.Create; Paragraph.AppendChild(Run as _OpenXmlElement); Runproperties := CoDocumentFormat_OpenXml_Wordprocessing_RunProperties.Create; Fontsize := CoDocumentFormat_OpenXml_Wordprocessing_FontSize.Create; Fontsize.Val := '40'; //this error, Incompatible types: IComparable and string The last line is obviously a string, I'm not sure how I can convert it to iComparable type. Base on the DirectOffice.pas library, the following are the declarations. Can someone guide me perhaps in what I can look into next? _DocumentFormat_OpenXml_Wordprocessing_FontSize = interface(IDispatch) _DocumentFormat_OpenXml_Wordprocessing_FontSizeDisp = dispinterface property Val: IComparable read Get_Val write _Set_Val; Any response is appreciated. Thanks much! Share this post Link to post
Anders Melander 1815 Posted July 20, 2021 Can you show us the declaration of IComparable ? Share this post Link to post
misc_bb 7 Posted July 20, 2021 The IComparable is part of the Delphi Generics I believe, in their library they have IComparable set to any type: Base64BinaryValue = IComparable; Base64BinaryValueClass = _Base64BinaryValueClass; BooleanValue = IComparable; BooleanValueClass = _BooleanValueClass; ByteValue = IComparable; ByteValueClass = _ByteValueClass; DateTimeValue = IComparable; DateTimeValueClass = _DateTimeValueClass; DecimalValue = IComparable; DecimalValueClass = _DecimalValueClass; DoubleValue = IComparable; DoubleClass = _DoubleClass; EnumStringAttribute = _EnumStringAttribute; HexBinaryValue = IComparable; HexBinaryValueClass = _HexBinaryValueClass; Int16Value = IComparable; Int16ValueClass = _Int16ValueClass; Int32Value = IComparable; Int32ValueClass = _Int32ValueClass; Int64Value = IComparable; Then the interface declarations: _DocumentFormat_OpenXml_Wordprocessing_FontSize = interface(IDispatch) ['{7F640590-6AD6-349C-AF4F-B9BECAB016FC}'] property Val: IComparable read Get_Val write _Set_Val; _DocumentFormat_OpenXml_Wordprocessing_FontSizeDisp = dispinterface ['{7F640590-6AD6-349C-AF4F-B9BECAB016FC}'] property Val: IComparable dispid 1610743883; //class declaration CoDocumentFormat_OpenXml_Wordprocessing_FontSize = class class function Create: DocumentFormat_OpenXml_Wordprocessing_FontSize; end; class function CoDocumentFormat_OpenXml_Wordprocessing_FontSize.Create: DocumentFormat_OpenXml_Wordprocessing_FontSize; begin Result := CreateComObject(CLASS_DocumentFormat_OpenXml_Wordprocessing_FontSize) as DocumentFormat_OpenXml_Wordprocessing_FontSize; end; I've just pick them where I can find the declaration intended for the Wordprocessing_FontSize. The DirectOffice.pas is around 48mb file. That file is really big and they also have the winsoft.directOffice.dll This library is acting like a wrapper for OpenXML in Delphi. I'm not sure if I sounded right here. Instead of directly modifying/interacting directly with OpenXML (or xml files), you can utilized this library for it. And after a while, I was able to get a workaround to make it work somehow but my solution now involves updating/manipulating the XML value. I've declared an OpenXMLAttribute variable and assign some values that will set the property I want to change. I'm not sure if this is the right approach with this library though but I think this is an option since it works. Just sharing this one for anyone who might be interested working with this library. //other declarations here xmlreader : OpenXmlAttribute; begin WordDocument := CoWordprocessingDocumentClass.Create.Create('bold.docx', WordprocessingDocumentType_Document); try xmlreader._namespaceUri := 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'; xmlreader.LocalName := 'val'; xmlreader.Prefix := 'w'; xmlreader.Value := '240'; MainPart := WordDocument.AddMainDocumentPart; // create document Document := CoDocument.Create; MainPart.Document := Document; // create body Body := CoBody.Create; Document.AppendChild(Body as _OpenXmlElement); // create paragraph Paragraph := CoDocumentFormat_OpenXml_Wordprocessing_Paragraph.Create; Body.AppendChild(Paragraph as _OpenXmlElement); // create run Run := CoDocumentFormat_OpenXml_Wordprocessing_Run.Create; Paragraph.AppendChild(Run as _OpenXmlElement); Runproperties := CoDocumentFormat_OpenXml_Wordprocessing_RunProperties.Create; Run.AppendChild(Runproperties as _OpenXmlElement); Bold := CoDocumentFormat_OpenXml_Wordprocessing_Bold.Create; Runproperties.Bold := (Bold as _DocumentFormat_OpenXml_Wordprocessing_Bold); // create text Text := CoDocumentFormat_OpenXml_Wordprocessing_Text.Create; Text.Text := 'Hello, ! lets get to work!!!'; Run.AppendChild(Text as _OpenXmlElement); //2nd paragraph // create paragraph Paragraph := CoDocumentFormat_OpenXml_Wordprocessing_Paragraph.Create; Body.AppendChild(Paragraph as _OpenXmlElement); // create run Run := CoDocumentFormat_OpenXml_Wordprocessing_Run.Create; Paragraph.AppendChild(Run as _OpenXmlElement); Runproperties := CoDocumentFormat_OpenXml_Wordprocessing_RunProperties.Create; Run.AppendChild(Runproperties as _OpenXmlElement); Fontsize := CoDocumentFormat_OpenXml_Wordprocessing_FontSize.Create; fontsize.SetAttribute(xmlreader); Runproperties.FontSize := (Fontsize as _DocumentFormat_OpenXml_Wordprocessing_FontSize); // create text Text := CoDocumentFormat_OpenXml_Wordprocessing_Text.Create; Text.Text := 'This is so weird!'; Run.AppendChild(Text as _OpenXmlElement); finally WordDocument.Dispose; end; ShellExecute(Handle, 'open', 'bold.docx', nil, nil, SW_SHOWNORMAL); end; Share this post Link to post
Anders Melander 1815 Posted July 21, 2021 (edited) Okay. I thought that maybe the typelib you're using had its own declaration of IComparable. I'm guessing the IComparable stuff is a mistake made by the typelib importer. It doesn't make much sense to me otherwise. Since you're using dispatch interfaces (i.e. late binding) anyway the solution could be to simply access the properties through IDispatch and ignore the concrete interface declarations. You can do this quite easily by using the OleVariant type: var Fontsize: OleVariant; begin Fontsize := CoDocumentFormat_OpenXml_Wordprocessing_FontSize.Create; Fontsize.Val := '40'; end; This is basically the way VB does OLE automation. Edited July 21, 2021 by Anders Melander Share this post Link to post
misc_bb 7 Posted July 22, 2021 I'm not so familiar with late binding in Delphi but I'll look into it. Thank you Anders. Share this post Link to post