OLE - The OLD Softmasters Classes

We recently restarted using the old softmasters OLE classes with some updates from AI - including a new class in CPP for getting get whole ranges into queues.. more on that code later which we better put up on GIT for people. What AI did add was some character coloring…

Now i dont think these classes are up on the web these days but if anyone has the originals and the authors say so then it has some nice examples that are still useable to day.

And then we were able with AI to generate some classes for Paragraph composition which AI wrote about here…

Individual characters can be assembled and colors and then printed.. example here is single color only.

Your going to say what about Unicode.. no problem as it can access UBS CPP core and that does support unicode as it a standard data type.. Just put it in a cstring on the clarion side and since the standard interface to clarion is CSTRING well it comes with a tick on the box..

https://claude.ai/public/artifacts/002ea7e8-5963-4eb2-95e3-f130a3f3dbbd

paragraphs

Updated Classes with Interfaces added and also UBS binding for script calling support.

And here is what AI think about working with a technology like UBS where everything including what we call a computer language is just a binding not a AST like python.

And this is why AI likes UBS as it only has to learn a small subset to generate code not 5 different languages..

https://claude.ai/public/artifacts/2c149210-7f64-4995-8d4f-59f4a831f4d4

 MSExcelClass.IMSExcelOle.CellInteriorProperty      PROCEDURE(string PropertyName,? PropertyValue)  
    CODE
        
    case upper(Clip(PropertyName))    
    of 'COLOR'
    orof 'COLORINDEX'
    orof 'GRADIENT'
    orof 'PATTERN'
    orof 'PATTERNCOLOR'
    orof 'PATTERNCOLORINDEX'
    orof 'PATTERNTHEMECOLOR'
    orof 'PATTERNTINTAND SHADE'
    orof 'THEMECOLOR'
    orof 'TINTANDSHADE'    
    SELF.IMSOfficeOle.SetProperty('Selection.Interior.'&upper(Clip(PropertyName)),PropertyValue)
    END
 
MSExcelClass.IMSExcelOle.SetCharacterFormat PROCEDURE(LONG Row, LONG Column, LONG StartPos, LONG Length, LONG Color, BYTE Bold, LONG Size)
    CODE
    ! Set color
    IF Color > 0
        SELF.IMSOfficeOle.SetProperty('Cells(' & Row & ',' & Column & ').Characters(' & StartPos & ',' & Length & ').Font.Color', Color)
    END
    ! Set bold
    SELF.IMSOfficeOle.SetProperty('Cells(' & Row & ',' & Column & ').Characters(' & StartPos & ',' & Length & ').Font.Bold', Bold)
    ! Set size
    IF Size > 0
        SELF.IMSOfficeOle.SetProperty('Cells(' & Row & ',' & Column & ').Characters(' & StartPos & ',' & Length & ').Font.Size', Size)
    END
2 Likes

UBS Support to allow clarion code to be fired by CPP Binding software core..

ClaMSOfficeService.IEXCELPInvoke.IInvoke                             procedure(Any object,Any Command,IParamsAnyList P) ! Invoke 
areturnvalue any  
    CODE
    !  message(' MSO IN INVOKE '&Clip(object) &'  '&Clip(Command))
  
     areturnvalue = ''   
    if not P &= NULL
    ! Call actual Class 

    ! message('ClaMSOfficeService EXCEL Params  IN  INVOKE '&Clip(object) &'  , '&Clip(Command))

   Case upper(Clip(object))
    of 'EXCEL'
    OROF 'MSEXCEL'
        
        ! NOTE: Properties will be in Focus in EXCEL and WORD Clases
        ! If call by passes Invokmember , Parameter in focus will need to be accessed for value 
        ! as in CellFontColor
 
          
                case upper(clip(command))
                   
                OF 'EXCELVER'
                     ! Check if Excel is available before binding
                     IF self.Excel.IMSExcelOle.IsExcelAvailable()
                        ExcelVersion" = self.Excel.IMSExcelOle.GetExcelVersion()
                        areturnvalue = ExcelVersion"
                     ELSE
                           return 
                     END
                    
                of 'DISPLAY'    
                    
                 !   message('  Excel Display ')
                    
                of 'XLE'
                    if not self.EXCEL.NamedStyleEquatesref &= NULL
                       areturnvalue = self.EXCEL.NamedStyleEquatesref.IStyleEquates.GetStyleGroupName('XL',P.P(1))
                    END    
                        
                of 'WDE'    
                
                of 'CELLFONTCOLOR'      
                    
                    RowNo# = P.P(1)
                    ColNo# = P.P(2)
                    ColoName" =  P.P(3)
                    ColorNo# =  self.IMSExcelStandardColor.ColorName(ColoName")
                    Bold" = P.P(4)
                    
                    Underline# = P.P(self.EXCEL.PInfocus,5,TRUE) 
                    FontSize# =  P.P(6)   
                    self.Excel.IMSExcelOle.CellFontColor(RowNo#,ColNo# ,ColorNo# ,Bold",Underline# ,FontSize# )
                   
                    
                of 'CALCS'   ! Find Calc{ formulas with an Open.
                   
                     self.IExcelExecuteUniScripts.FindCalcExpressions(1,3,1) 
                     
                of 'CALCOPEN'    
                if P.CountItems() >= 4
        
                 self.RowIndexExpression[1] = P.P(2)  
                 self.RowIndexExpression[2] = P.P(3)  
                    
                 case P.P(4)
                    of 'ADDLOCALPATH'
                      if fileexists(P.P(1)) = TRUE  
                         self.Excel.IMSExcelOle.OpenFile(P.P(1))
                      ELSE      
                         self.Excel.IMSExcelOle.OpenFile(longpath()&'\'&P.P(1))
                      END      
                 ELSE    
                     self.Excel.IMSExcelOle.OpenFile(P.P(1))
                 END    
               END          
                    
            of 'CREATE'    
                self.IClaMSOfficeService.NewExcelInstance    
            of 'OPENNEW'
                !self.EXCEL.IMSEXCELBINDING.SingleOleWindowopen(P)
                self.Excel.IMSOfficeOle.InitNoSurface(1,1,1)
                self.Excel.IMSExcelOle.CreateWorkbook ! get the workbook back ....

             of 'OPENED'    
                if self.ExcelInit = TRUE   
                   if self.Icalcscriptref &= NULL     
                        self.Icalcscriptref.setreturnclavalue('OPENED')
                    ELSE
                        self.Icalcscriptref.setreturnclavalue('NOT OPENED') 
                   END 
                END    
                    
             of 'OPEN'
                 self.Excel.IMSOfficeOle.InitNoSurface(1,1,1)
                self.Excel.IMSExcelOle.CreateWorkbook ! get the workbook back ....

             OF 'READCELLCOMPLETE'
                  ! P.P(1) = Row, P.P(2) = Col
                  IF P.CountItems() >= 2
                     IF NOT SELF.ExcelCellstructureref &= NULL
                        free(SELF.ExcelCellstructureref)    
                        SELF.EXCEL.IMSExcelOle.ReadCellComplete(P.P(1), P.P(2))
                        END
                    ELSE
                     areturnvalue = SELF.EXCEL.IMSExcelOle.ReadWorksheetComplete('')
                 END
1 Like

AI - Claude Documents the use of the softmasters - OLE classes in clarion for use with the Paragraph classes. This code run in Clarion 11 - Demonstrating that classes written decades ago for MS Office are still used today…

https://claude.ai/public/artifacts/0cd3fd24-fc08-4135-a695-ce7057b28cf4

Hello
do you have a link for this?

Claude Code has not been set up for the Agent to run the Git HUB silo for it Yet. You will need the private version of UBS to run it.. Its been ported from Linux and Im awaiting a few fixes for Windows from the Linux team.. Im hoping to have this free version for Clarion users ready MID 2026… Im very lucky the owners of UBS have allow this to run on windows and have a win 32 compiled DLL CPP version for running in clarion.. I had to twist arms to get it…

These document and some source code are all AI generated.

https://claude.ai/public/artifacts/002ea7e8-5963-4eb2-95e3-f130a3f3dbbd

This was AI generated support for call the Paragraph generation classes in Clarion. Claude code will have to seperate out Include classes for general use as the Cla office service clw module has a fair bit of decades of junk supporting custom stuff for other apps.. Clarion developers may find this other junk off putting…also UBS for clarion will be free it is not a DLL that comes with source code. Its only 158 KB in size which means you dont have to install python or javascript.. Its a virtual binding machine ported from linux. AS AI says, you get all that normal control flow stuff classes, functions, software industry standard syntax and connectivity emulated in just 158K, not 15 megs…The way you use it may be not what clarion developers are used to nor what they feel comfortable with.. but once you make the leap… you never want to go back…


  MEMBER

OMIT('***')
 * Created with Clarion 11
 * User:  Quantum Dynamics Ltd
 * Date: 4/10/2025
 * Time: 7:14 pm
 *  include('C:\win32claclasses\ExcelParagraphscontent.inc'),once
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 ***

    MAP
 
       MODULE('ParamAnyList.clw')
         NewParameterListCAddress,proc,LONG,pascal
         NewParameterList(),*ParamAnyList
       END      

    END
 
     
    include('C:\win32claclasses\paragraphscontentcontainers.inc'),once
  
! Ai Generated  - Singletons.

ExcelParagraphscontentref             &ExcelParagraphscontent
! WordParagraphscontentref            &WordParagraphscontent


paragraphscontentcontainers.Construct           PROCEDURE
    CODE
    self.Paragraphcontainersref &= NEW QParagraphcontainers
        
    ExcelParagraphscontentref   &= new(ExcelParagraphscontent)
        
    self.Paragraphcontainersref.ParagraphName = 'EXCEL'
    self.Paragraphcontainersref.IReportParagraphsref &= ExcelParagraphscontentref.IReportParagraphs
    self.Paragraphcontainersref.IReportWordParagraphsref &= ExcelParagraphscontentref.IReportWordParagraphs
    self.Paragraphcontainersref.PCIInvokeref   &= ExcelParagraphscontentref.PCIInvoke
    self.Paragraphcontainersref.ISetPCIInvokeref &= ExcelParagraphscontentref.ISetPCIInvoke
    add(self.Paragraphcontainersref)
        
   ! AI Generated WORD Support - ADD Here. 
   
    
    ! Set up WORD by default

paragraphscontentcontainers.ISetIUbsGlobals.SetUBSGlobals   PROCEDURE(long IUniBindatypesAddress, long iUBSAddress, long GlobalBindAddress, long IGlobalBindableAddress)
  
    CODE
        
    ! BIND paragrapghs    

paragraphscontentcontainers.ISetPCIInvokeID.SetInterface     PROCEDURE(string Named,long PCIInvokeaddress)
   
    CODE
    if not self.Paragraphcontainersref &= NULL and PCIInvokeaddress > FALSE   
       self.Paragraphcontainersref.ParagraphName = upper(Clip(Named))
       get(self.Paragraphcontainersref,'ParagraphName')
        if not errorcode()
            if not self.Paragraphcontainersref.ISetPCIInvokeref &= NULL
              self.Paragraphcontainersref.ISetPCIInvokeref.setinterface(PCIInvokeaddress)   ! External Client Invoker
          END     
       END       
    END
    
paragraphscontentcontainers.Destruct             PROCEDURE
    CODE
    IF NOT self.Paragraphcontainersref &= NULL
       DISPOSE(self.Paragraphcontainersref)
    END

paragraphscontentcontainers.IUBSD.getAsInteger PROCEDURE(const *cstring BindobjectName, const *cstring objectname)
returnitem LONG
    CODE
    RETURN(returnitem)

paragraphscontentcontainers.IUBSD.getAsNumber PROCEDURE(const *cstring BindobjectName, const *cstring objectname)
returnitem REAL
    CODE
    RETURN(returnitem)

paragraphscontentcontainers.IUBSD.getAsString PROCEDURE(const *cstring BindobjectName, const *cstring objectname)
returnitem CSTRING(1000)
    CODE
    RETURN(returnitem)

paragraphscontentcontainers.IUBSD.setToInteger PROCEDURE(const *cstring BindobjectName, const *cstring objectname, LONG i)
    CODE

paragraphscontentcontainers.IUBSD.setToNumber PROCEDURE(const *cstring BindobjectName, const *cstring objectname, REAL r)
    CODE

paragraphscontentcontainers.IUBSD.setToString PROCEDURE(const *cstring BindobjectName, const *cstring objectname, const *cstring s)
    CODE

paragraphscontentcontainers.IUBSD.setToBindable PROCEDURE(const *cstring BindobjectName, const *cstring objectname, LONG b)
    CODE

paragraphscontentcontainers.IUBSD.invoke PROCEDURE(const *cstring BindobjectName, LONG boundequ, const *cstring objectname, LONG EquNumber, LONG IUbsaddrss, LONG cparamsinterfaceaddress, LONG igetsetequaddress)
returnitem LONG
ParamListRef    &ParamAnyList
areturnvalue ANY
    CODE
   ! message(' paragraphscontentcontainers invoke  '&BindobjectName&'  '&objectname)
    IF cparamsinterfaceaddress > 0
        ParamListRef &= (cparamsinterfaceaddress)
    END
    
    IF NOT ParamListRef &= NULL
         
        EXECUTE self.CommandEqu 
             BEGIN ! AddParagraph
                    IF NOT self.IReportParagraphsinfocusref &= NULL
                       self.IReportParagraphsinfocusref.AddParagraph(|
                        ParamListRef.IParamsAnyList.P(1), |
                        ParamListRef.IParamsAnyList.P(2), |
                        ParamListRef.IParamsAnyList.P(3))
                END
            END
              BEGIN ! AddFragment
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    
                 
               !  message('P(1)=' & ParamListRef.IParamsAnyList.P(1) & |
              !   ' P(2)=' & ParamListRef.IParamsAnyList.P(2) & |
              !   ' P(3)=' & ParamListRef.IParamsAnyList.P(3) & |
              !   ' P(4)=' & ParamListRef.IParamsAnyList.P(4) & |
              !   ' P(5)=' & ParamListRef.IParamsAnyList.P(5))
                    
                    self.IReportParagraphsinfocusref.AddFragment(|
                        ParamListRef.IParamsAnyList.P(1), |
                        ParamListRef.IParamsAnyList.P(2), |
                        ParamListRef.IParamsAnyList.P(3), |
                        ParamListRef.IParamsAnyList.P(4), |
                        ParamListRef.IParamsAnyList.P(5), |
                        ParamListRef.IParamsAnyList.P(6), |
                        ParamListRef.IParamsAnyList.P(7), |
                        ParamListRef.IParamsAnyList.P(8), |
                        ParamListRef.IParamsAnyList.P(9), |
                        ParamListRef.IParamsAnyList.P(10), |
                        ParamListRef.IParamsAnyList.P(11))
                END
            END
            BEGIN ! GetParagraph
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    areturnvalue = self.IReportParagraphsinfocusref.getParagraph(|
                        ParamListRef.IParamsAnyList.P(1))
                END
            END
            BEGIN ! SetParagraphFormatting
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.SetParagraphFormatting(|
                        ParamListRef.IParamsAnyList.P(1), |
                        ParamListRef.IParamsAnyList.P(2), |
                        ParamListRef.IParamsAnyList.P(3), |
                        ParamListRef.IParamsAnyList.P(4), |
                        ParamListRef.IParamsAnyList.P(5), |
                        ParamListRef.IParamsAnyList.P(6), |
                        ParamListRef.IParamsAnyList.P(7), |
                        ParamListRef.IParamsAnyList.P(8))
                END
            END
            BEGIN ! SetMultiColumn
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.SetMultiColumn(|
                        ParamListRef.IParamsAnyList.P(1), |
                        ParamListRef.IParamsAnyList.P(2))
                END
            END
            BEGIN ! SetFontName
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.SetFontName(|
                        ParamListRef.IParamsAnyList.P(1), |
                        ParamListRef.IParamsAnyList.P(2))
                END
            END
            BEGIN ! SetFontSize
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.SetFontSize(|
                        ParamListRef.IParamsAnyList.P(1), |
                        ParamListRef.IParamsAnyList.P(2))
                END
            END
            BEGIN ! SetFontColor
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.SetFontColor(|
                        ParamListRef.IParamsAnyList.P(1), |
                        ParamListRef.IParamsAnyList.P(2))
                END
            END
            BEGIN ! SetFontBold
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.SetFontBold(|
                        ParamListRef.IParamsAnyList.P(1), |
                        ParamListRef.IParamsAnyList.P(2))
                END
            END
            BEGIN ! SetUnderline
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.SetUnderline(|
                        ParamListRef.IParamsAnyList.P(1), |
                        ParamListRef.IParamsAnyList.P(2))
                END
            END
            BEGIN ! SetDoubleUnderline
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.SetDoubleUnderline(|
                        ParamListRef.IParamsAnyList.P(1), |
                        ParamListRef.IParamsAnyList.P(2))
                END
            END
            BEGIN ! SetShadow
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.SetShadow(|
                        ParamListRef.IParamsAnyList.P(1), |
                        ParamListRef.IParamsAnyList.P(2))
                END
            END
            BEGIN ! SetFragmentFontSize
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.SetFragmentFontSize(|
                        ParamListRef.IParamsAnyList.P(1), |
                        ParamListRef.IParamsAnyList.P(2), |
                        ParamListRef.IParamsAnyList.P(3))
                END
            END
            BEGIN ! SetFragmentFontColor
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.SetFragmentFontColor(|
                        ParamListRef.IParamsAnyList.P(1), |
                        ParamListRef.IParamsAnyList.P(2), |
                        ParamListRef.IParamsAnyList.P(3))
                END
            END
            BEGIN ! SetFragmentFontBold
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.SetFragmentFontBold(|
                        ParamListRef.IParamsAnyList.P(1), |
                        ParamListRef.IParamsAnyList.P(2), |
                        ParamListRef.IParamsAnyList.P(3))
                END
            END
            BEGIN ! SetFragmentUnderline
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.SetFragmentUnderline(|
                        ParamListRef.IParamsAnyList.P(1), |
                        ParamListRef.IParamsAnyList.P(2), |
                        ParamListRef.IParamsAnyList.P(3))
                END
            END
            BEGIN ! SetFragmentDoubleUnderline
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.SetFragmentDoubleUnderline(|
                        ParamListRef.IParamsAnyList.P(1), |
                        ParamListRef.IParamsAnyList.P(2), |
                        ParamListRef.IParamsAnyList.P(3))
                END
            END
            BEGIN ! SetFragmentShadow
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.SetFragmentShadow(|
                        ParamListRef.IParamsAnyList.P(1), |
                        ParamListRef.IParamsAnyList.P(2), |
                        ParamListRef.IParamsAnyList.P(3))
                END
            END
            BEGIN ! RemoveParagraph
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.RemoveParagraph(|
                        ParamListRef.IParamsAnyList.P(1))
                END
            END
            BEGIN ! CreateCombinedParagraph
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.CreateCombinedParagraph(|
                        ParamListRef.IParamsAnyList.P(1))
                END
            END
            BEGIN ! AddChildParagraph
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.AddChildParagraph(|
                        ParamListRef.IParamsAnyList.P(1), |
                        ParamListRef.IParamsAnyList.P(2))
                END
            END
            BEGIN ! GetParagraphCount
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    areturnvalue = self.IReportParagraphsinfocusref.GetParagraphCount(|
                        ParamListRef.IParamsAnyList.P(1))
                END
            END
            BEGIN ! ExecuteEvent
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.ExecuteEventParagraphs(|
                        ParamListRef.IParamsAnyList.P(1))
                END
            END
            BEGIN ! ClearParagraphs
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.ClearParagraphs()
                END
            END
            BEGIN ! GenerateParagraphsContent
               if not self.IApplicationsCentreref &= NULL
                  self.IApplicationsCentreref.ApplicationEvent(11)    ! Link to External Output Invoker for MS Office    
              END       
              IF NOT self.IReportParagraphsinfocusref &= NULL
                  self.IReportParagraphsinfocusref.GenerateParagraphsContents(|
                        ParamListRef.IParamsAnyList.P(1))
                END
            END
            BEGIN ! GenerateAllParagraphsContent
                if not self.IApplicationsCentreref &= NULL
                      self.IApplicationsCentreref.ApplicationEvent(11)    ! Link to External Output Invoker for MS Office    
                 END       
                IF NOT self.IReportParagraphsinfocusref &= NULL
                     self.IReportParagraphsinfocusref.GenerateAllParagraphsContents()
                ELSE
                END
            END
            BEGIN ! GetParagraphContent
                 IF NOT self.IReportParagraphsinfocusref &= NULL
                        areturnvalue = self.IReportParagraphsinfocusref.GetParagraphContent(|
                        ParamListRef.IParamsAnyList.P(1))
                END
            END
            BEGIN ! AddTextFormatting
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    areturnvalue = self.IReportParagraphsinfocusref.AddTextFormatting(|
                        ParamListRef.IParamsAnyList.P(1), |
                        ParamListRef.IParamsAnyList.P(2), |
                        ParamListRef.IParamsAnyList.P(3), |
                        ParamListRef.IParamsAnyList.P(4), |
                        ParamListRef.IParamsAnyList.P(5), |
                        ParamListRef.IParamsAnyList.P(6), |
                        ParamListRef.IParamsAnyList.P(7), |
                        ParamListRef.IParamsAnyList.P(8))
                END
            END
            BEGIN ! RemoveTextFormatting
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.RemoveTextFormatting(|
                        ParamListRef.IParamsAnyList.P(1))
                END
            END
            BEGIN ! GetTextFormattingByName
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    areturnvalue = self.IReportParagraphsinfocusref.GetTextFormattingByName(|
                        ParamListRef.IParamsAnyList.P(1))
                END
            END
            BEGIN ! SetFragmentCharacterRange
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.SetFragmentCharacterRange(|
                        ParamListRef.IParamsAnyList.P(1), |
                        ParamListRef.IParamsAnyList.P(2), |
                        ParamListRef.IParamsAnyList.P(3), |
                        ParamListRef.IParamsAnyList.P(4), |
                        ParamListRef.IParamsAnyList.P(5))
                END
            END
            BEGIN ! FragementWords
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.Fragementwords()
                END
            END
            BEGIN ! FragementNotwords
                IF NOT self.IReportParagraphsinfocusref &= NULL
                    self.IReportParagraphsinfocusref.FragementNotwords()
                END
            END
        END
        
        IF NOT ParamListRef &= NULL
            DISPOSE(ParamListRef)
        END
    END
    
    RETURN(returnitem)

paragraphscontentcontainers.IUBSD.selectobject PROCEDURE(const *cstring BindobjectName, LONG boundequ, const *cstring objectname, LONG EquNumber, LONG IBindableEqusaddress, LONG rtnEquMember)
    CODE
    ! NOTE : Event 10 = MSOffice OLE Bound - Equate Numeric
    ! may be renumbered at a future date.    
    !message(' paragraphscontentcontainers selectobject  '&BindobjectName&'  '&objectname)
  
    case  upper(clip(objectname))   
    of 'EXCEL'
       
    self.Paragraphcontainersref.ParagraphName = upper(Clip(objectname))
    GET(self.Paragraphcontainersref, 'ParagraphName')
   
    IF NOT ERRORCODE()
        ! Set interfaces in focus from container
        self.IReportParagraphsinfocusref &= self.Paragraphcontainersref.IReportParagraphsref
        self.IReportWordParagraphsinfocusref &= self.Paragraphcontainersref.IReportWordParagraphsref

        if self.Paragraphcontainersref.IReportParagraphsref &= NULL
          ! message(' Assign IReportParagraphsinfocusref - NULL ')
        END      
       ! message(' Assign IReportParagraphsinfocusref ')
    END
        
   ELSE     
        
        ! Map command to EQU
        CASE UPPER(CLIP(objectname))
        OF 'ADDPARAGRAPH'
            self.CommandEqu = ParaCmd:AddParagraph
        OF 'ADDFRAGMENT'
            self.CommandEqu = ParaCmd:AddFragment
        OF 'GETPARAGRAPH'
            self.CommandEqu = ParaCmd:GetParagraph
        OF 'SETPARAGRAPHFORMATTING'
            self.CommandEqu = ParaCmd:SetParagraphFormatting
        OF 'SETMULTICOLUMN'
            self.CommandEqu = ParaCmd:SetMultiColumn
        OF 'SETFONTNAME'
            self.CommandEqu = ParaCmd:SetFontName
        OF 'SETFONTSIZE'
            self.CommandEqu = ParaCmd:SetFontSize
        OF 'SETFONTCOLOR'
            self.CommandEqu = ParaCmd:SetFontColor
        OF 'SETFONTBOLD'
            self.CommandEqu = ParaCmd:SetFontBold
        OF 'SETUNDERLINE'
            self.CommandEqu = ParaCmd:SetUnderline
        OF 'SETDOUBLEUNDERLINE'
            self.CommandEqu = ParaCmd:SetDoubleUnderline
        OF 'SETSHADOW'
            self.CommandEqu = ParaCmd:SetShadow
        OF 'SETFRAGMENTFONTSIZE'
            self.CommandEqu = ParaCmd:SetFragmentFontSize
        OF 'SETFRAGMENTFONTCOLOR'
            self.CommandEqu = ParaCmd:SetFragmentFontColor
        OF 'SETFRAGMENTFONTBOLD'
            self.CommandEqu = ParaCmd:SetFragmentFontBold
        OF 'SETFRAGMENTUNDERLINE'
            self.CommandEqu = ParaCmd:SetFragmentUnderline
        OF 'SETFRAGMENTDOUBLEUNDERLINE'
            self.CommandEqu = ParaCmd:SetFragmentDoubleUnderline
        OF 'SETFRAGMENTSHADOW'
            self.CommandEqu = ParaCmd:SetFragmentShadow
        OF 'REMOVEPARAGRAPH'
            self.CommandEqu = ParaCmd:RemoveParagraph
        OF 'CREATECOMBINEDPARAGRAPH'
            self.CommandEqu = ParaCmd:CreateCombinedParagraph
        OF 'ADDCHILDPARAGRAPH'
            self.CommandEqu = ParaCmd:AddChildParagraph
        OF 'GETPARAGRAPHCOUNT'
            self.CommandEqu = ParaCmd:GetParagraphCount
        OF 'EXECUTEEVENT'
            self.CommandEqu = ParaCmd:ExecuteEvent
        OF 'CLEARPARAGRAPHS'
            self.CommandEqu = ParaCmd:ClearParagraphs
        OF 'GENERATEPARAGRAPHSCONTENT'
            self.CommandEqu = ParaCmd:GenerateParagraphsContent
        OF 'GENERATEALLPARAGRAPHSCONTENT'
            self.CommandEqu = ParaCmd:GenerateAllParagraphsContent
        OF 'GETPARAGRAPHCONTENT'
            self.CommandEqu = ParaCmd:GetParagraphContent
        OF 'ADDTEXTFORMATTING'
            self.CommandEqu = ParaCmd:AddTextFormatting
        OF 'REMOVETEXTFORMATTING'
            self.CommandEqu = ParaCmd:RemoveTextFormatting
        OF 'GETTEXTFORMATTINGBYNAME'
            self.CommandEqu = ParaCmd:GetTextFormattingByName
        OF 'SETFRAGMENTCHARACTERRANGE'
            self.CommandEqu = ParaCmd:SetFragmentCharacterRange
        OF 'FRAGEMENTWORDS'
            self.CommandEqu = ParaCmd:FragementWords
        OF 'FRAGEMENTNOTWORDS'
            self.CommandEqu = ParaCmd:FragementNotwords
        END
    END
    
    RETURN(address(self.IUBSD))

paragraphscontentcontainers.IUBSD.removeobject PROCEDURE(const *cstring BindobjectName, const *cstring objectname)
    CODE

paragraphscontentcontainers.IUBSD.existsobject PROCEDURE(const *cstring BindobjectName, const *cstring objectname)
exists LONG
    CODE
    RETURN(exists)

paragraphscontentcontainers.IUBSD.nextobjectName PROCEDURE(const *cstring BindobjectName, const *cstring objectname)
    CODE
    RETURN(0)

paragraphscontentcontainers.IUBSD.copy PROCEDURE
    CODE

paragraphscontentcontainers.IUBSD.share PROCEDURE
    CODE

paragraphscontentcontainers.IUBSD.unShare PROCEDURE
    CODE

paragraphscontentcontainers.IUBSD.getDescription PROCEDURE
description CSTRING(255)
    CODE
    description = 'ParagraphsContainer'
    RETURN(description)

paragraphscontentcontainers.IUBSD.getBinding PROCEDURE
    CODE
    RETURN(ADDRESS(self.IUBSD))

paragraphscontentcontainers.IUBSD.UbsNewParams PROCEDURE
paramAddress LONG
    CODE
    paramAddress = NewParameterListCAddress()
    RETURN(paramAddress)
   
        omit('*scriptsexamples')
        
   ! T4: 2x2 Grid with colored cells
paragraphs.excel.addparagraph('TestPara4', 1, 1)

! Cell A1: 'Cell' + 'A1' (Red)
paragraphs.excel.addfragment('TestPara4', 'Cell', 1, 12, global.xlRgbDarkRed, 0, 1, 1, 0, 0, 0)
paragraphs.excel.addfragment('TestPara4', 'A1', 0, 12, global.xlRgbDarkRed, 0, 1, 1, 0, 0, 0)

! Cell B1: 'Cell' + 'B1' (Blue)
paragraphs.excel.addfragment('TestPara4', 'Cell', 0, 12, global.xlRgbDarkBlue, 0, 1, 2, 0, 0, 0)
paragraphs.excel.addfragment('TestPara4', 'B1', 0, 12, global.xlRgbDarkBlue, 0, 1, 2, 0, 0, 0)

! Cell A2: 'Cell' + 'A2' (Green)
paragraphs.excel.addfragment('TestPara4', 'Cell', 0, 12, global.xlRgbDarkGreen, 1, 2, 1, 0, 0, 0)
paragraphs.excel.addfragment('TestPara4', 'A2', 0, 12, global.xlRgbDarkGreen, 1, 2, 1, 0, 0, 0)

! Cell B2: 'Cell' + 'B2' (Purple)
paragraphs.excel.addfragment('TestPara4', 'Cell', 1, 12, global.xlRgbHotPink, 0, 2, 2, 0, 0, 0)
paragraphs.excel.addfragment('TestPara4', 'B2', 1, 12, global.xlRgbHotPink, 0, 2, 2, 0, 0, 0)

        paragraphs.excel.generateparagraphscontent('TestPara4')  
        
 ! fragRef.TextClen = self.scriptInterface.computeIntFromString('cstrlen("' & CLIP(text) & '")')
 ! fragRef.Textaddress = self.scriptInterface.computeBindableFromString('varName')
 ! fragRef.TextType = 1      
        
        
        
     ! *scriptsexamples   

As we test more of the linux binding machine on windows using CPP and Old Clarion code we are now going to test mixing and matching where you take the OLD software master classes and run them via a generic idispatch COM container that is a client of the binding machine . In this test a range in a worksheet is populated into a queue with a simple statement feed into the Binding machine… Q = ws.getrange(‘A1:D10’,‘SalesData’) , here is where the Clarion stack hits the CPP stack and you get a safe array to populate a queue and vis versa… Here clarion is not a second class citizen but get to share its classes and data via CPP abstract interfaces classes.

https://claude.ai/public/artifacts/3b97137e-6148-4a6f-88aa-64c4b2de8b05