CmpDynamicText.DynamicTextRegisterFile usage

sgronchi
2022-02-25
2022-04-07
  • sgronchi - 2022-02-25

    I need to load at runtime a TextList, so I wandered around CmpDynamicText library and saw DynamicTextRegisterFile, DynamicTextUnregisterFile and so on.

    Is there an usage example somewhere, or at least someone who has make it work?

    Or should I replicate TextList infrastructure in IEC code instead, something like the following pseudocode?

    PROGRAM LoadTexts
    
    VAR_INPUT
        xExecute : BOOL;
        filename : STRING;
    END_VAR
    VAR_OUTPUT
        textList :ARRAY [0..255] OF WSTRING;
    END_VAR
    VAR
        i : UINT;
        _xExecute : BOOL;
        parsed :ARRAY [0..255] OF WSTRING;
        idx : STRING;
        pbyText : POINTER TO BYTE;
    END_VAR
    VAR CONSTANT
        pstTextList : STRING := 'MyTextList';
    END_VAR
    
    IF xExecute AND NOT _xExecute THEN
        // open file and parse it
        IF (* all the parsed content is valid *) THEN
            FOR i := 0 TO 255 DO
                textList[i] := parsed[i];
            END_FOR
        ELSE
            FOR i := 0 TO 255 DO
                idx := UINT_TO_STRING(idx); // or just use a table
                pbyText := VisuElems.CmpDynamicText.DynamicTextGetTextW(
                    pstTextList  := pstTextList,
                    pstTextIndex := ADR(idx)
                );[i];
                IF pbyText <> 0 AND_THEN pbyText^ <> 0 THEN
                    Stu.StrCpyW(
                        pBuffer     :=    ADR(textList[i]),
                        iBufferSize := SIZEOF(textList[i]),
                        pStr        := pbyText
                    );
                END_IF
            END_FOR
        END_IF
    END_IF
    _xExecute := xExecute
    

    Nonetheless, it would be a pity to roll a poor man's version of the already builtin infrastructure.

     

    Last edit: sgronchi 2022-02-25
  • m.prestel - 2022-02-28

    Hey,
    DynamicTextRegisterFile should do the trick I think.

    Best regards,
    Marcel

     
  • sgronchi - 2022-02-28

    Yes, but what's the right format for the file?
    Is it the same as <textlistname>.txt or the one of globaltextlist.txt?
    Should I unregister the previous file or not?</textlistname>

     
  • m.prestel - 2022-02-28

    They use the same file format, they just have additional languages depending on what you added.

    Are you using the same file? Then a reload should be enough, no need to unregister and register.

     
  • sgronchi - 2022-02-28

    Sorry, I messed up with the import file (not the globaltextlist.txt), the one that has the textlist as the first column.

    I'd like to keep the original file if something goes wrong as a fallback solution, unregistering it if the other file is valid.

     
  • sgronchi - 2022-03-04

    I cannot seem to be able to change default texts. They are NOT changed from the default file even if I unregister it. But texts with IDs not present in the default file are imported successfully.

    "outputfilename" is '/opt/data/mytl.txt'
    It has only "Id;Default" instead of "Id;Default;it;en;de" columns.

    LoadCustomFile (does not overrides default texts)

    // Current language save/restore because on text reload the language reverts to ""
    // Even without it, so in the "" CURRENTLANGUAGE case, default texts are not overridden
    size := SysFile.SysFileGetSize(szFileName := outputfilename, pResult := ADR(res));
    currentLanguage := VisuElems.CmpDynamicText.DynamicTextGetCurrentLanguage();
    IF res = CmpErrors.Errors.ERR_OK AND size > 24 THEN
    
    // Unregister returns "1" = GENERIC FAIL
    // and in PLC log appears "Could not unregister dynamic text file"
    VisuElems.CmpDynamicText.DynamicTextUnRegisterFile(szFile := '/opt/Project/PlcLogic/visu/mytl.txt');
        VisuElems.CmpDynamicText.DynamicTextRegisterFile(szFile := outputfilename);
        VisuElems.CmpDynamicText.DynamicTextLoadDefaultTexts();
        // DynamicTextReloadTexts() in place of DynamicTextLoadDefaultTexts() does not work either
        VisuElems.CmpDynamicText.DynamicTextChangeLanguage(stLanguage := currentLanguage);
        VisuGlobals.customTextlist := TRUE;
    ELSE
        VisuGlobals.customTextlist := FALSE;
    END_IF
    

    RemoveCustomFile (works and removes default texts that were only in the "override" text list but not in the system one)

    currentLanguage := VisuElems.CmpDynamicText.DynamicTextGetCurrentLanguage();
    VisuElems.CmpDynamicText.DynamicTextUnRegisterFile(szFile := outputfilename);
    SysFile.SysFileDelete(szFileName := outputfilename);
    VisuElems.CmpDynamicText.DynamicTextRegisterFile(szFile := '/opt/Project/PlcLogic/visu/mytl.txt');
    VisuElems.CmpDynamicText.DynamicTextReloadTexts();
    VisuElems.CmpDynamicText.DynamicTextChangeLanguage(stLanguage := currentLanguage);
    VisuGlobals.customTextlist := FALSE;
    

    VisuGlobals.customTextlist is used to ask for the text with DynamicTextGetDefaultTextW if TRUE (because otherwise one gets the language-specific text) and with DynamicTextGetTextW if FALSE.

     

    Last edit: sgronchi 2022-03-04
  • sgronchi - 2022-03-08

    If it is not possible to understand why unregistering the default file fails, I think it's better to go the build-from-scratch way...

     
  • m.prestel - 2022-03-15

    I think it is best to provide a small example project at this point

     
  • sgronchi - 2022-04-07

    Hi Marcel,
    here you are. Sorry for the delay.

    You'll have to adjust LoadNames.defaultfilename and LoadNames.outputfilename according to your system. I attached the custom "mytl" in the projectarchive.

    If you set a breakpoint into LoadNames.LoadCustomFile, you'll see that resUnreg is 1 (generic fail).

    To keep it short, I did not implement the logic which asks for default text if LoadNames.xCustom is true, because if unregistering fails it won't work anyway.

     

Log in to post a comment.