Skip to main content
K.Daube
Community Expert
Community Expert
January 27, 2018
Answered

app.Displaying considered unreliable

  • January 27, 2018
  • 1 reply
  • 1122 views

Der friends,

The white document hits again... ( see https://forums.adobe.com/thread/2276988) and I tracked it down to failing app.Displaying. The script requests function SetDisplay (bWanted) 17 times successful, but the 18. call does not switch the display any more. The routine is that simple:

function SetDisplay (bWanted) { //=== Set display to on or off ====================================
// Arguments bWanted: true => set display ON; false => display OFF
// Commment  This function does not work reliably. See https://forums.adobe.com/thread/2276988
// Reference Rick Quattro
    Console ("    current:" + app.Displaying + " => wanted: " + bWanted);
  if (app.Displaying != bWanted) {
    app.Displaying = bWanted;
    Console ("    set ? " + app.Displaying);
  }
} //--- end SetDisplay

Just after the following log the document gets white:

....SetDisplay(true)
    current:0 => wanted: true
    set ? 0

That is, app.Displaying was not performed and hence the document is not visible.

The white document appears within a routine which collects variables from the document. Since this function switches between pages and even page types I want to avoid flicker - which is really annoying here.

Do you spot something dubious in this routine?

function CollectVarsInDoc (oDoc, aDocVars) { //=== Collect variables in the 'natural' order =======
// Arguments oDoc:        current document
//           aDocVars:    array to be filled with var objects
// Called by xxx
// Calling   GetFindParameters, SetDisplay, SaveCurrentLocation, RestoreLocation
// Comment   Variables are found on all page types (Body, Master, Reference).
//           Starting points must be oDoc.FirstBodyPageInDoc, .FirstMasterPageInDoc, .FirstRefPageInDoc
var aVarsRange = [], bIsSystem, findParams, jFound = 0, jPageType, iVrLen, oFirst, oPage, oPara,
    oSavedLoc, oTextItem,  oTR = new TextRange(), oVar, sVarName, sValue,
    aPages = [oDoc.FirstBodyPageInDoc, oDoc.FirstMasterPageInDoc, oDoc.FirstRefPageInDoc];

  SetDisplay (false);
  oSavedLoc = SaveCurrentLocation (oDoc);
  aDocVars.length = 0;                            // clear array for refill
  if (oDoc == null) {                             // emergency bailing out   
    SetDisplay (true);
    return;
  }              
  for (jPageType = 0; jPageType < 3; jPageType++) { // for all page types
    oFirst = aPages[jPageType];
    if (oFirst.id == 0 && jPageType != 1) {continue}; // only master page(s) exist
    oDoc.CurrentPage = oFirst;
    oPage = oDoc.CurrentPage;
    oPara = oPage.PageFrame.FirstGraphicInFrame.FirstPgf;
    while (oPara == undefined) {                  // can happen on ref pages
      oPage = oPage.PageNext;
      if (oPage.id == 0) {
        goFMv.nDocVars = aDocVars.length;
        RestoreLocation (oDoc, oSavedLoc);
        SetDisplay (true);
        return;}                                  // no next page available
      oPara = oPage.PageFrame.FirstGraphicInFrame.FirstPgf;
    }
    oTR   = oDoc.TextSelection;
    oTR.beg.obj =  oTR.end.obj = oPara;
    oDoc.TextSelection = oTR;
    oTR.beg.offset = oTR.end.offset = 0;

    findParams = GetFindParameters (2, null);     // finding any variable, no wrap
    InitFA_errno ();                              // reset - it is write protected
    oTR = oDoc.Find(oTR.beg, findParams);         // and do an initial find to get started.

    while(FA_errno === Constants.FE_Success) {
      jFound += 1;
      oDoc.TextSelection = oTR;                   // set up the text range
      aVarsRange = oDoc.GetTextForRange (oTR, Constants.FTI_VarBegin);  // this is an array
      iVrLen = aVarsRange.length;                 // have not found anything other than 1 to be correct
      if (iVrLen === 0) {                         // Hickup ?
        InitFA_errno ();                          // track the progress
        oTR = oDoc.Find(oTR.beg, findParams);     // prepare for next find
        continue;                                 // while
      }
      oTextItem = aVarsRange[0];                  // have not found anything other than 1 to be correct
      oVar = oTextItem.obj;
      sVarName = oVar.VarFmt.Name;                // name of the variable
      sValue   = oVar.VarFmt.Fmt;                 // contents of variable
      oTR      = oVar.TextRange;                  // the text range of the variable
      bIsSystem= (oVar.VarFmt.SystemVar !== Constants.FV_VAR_USER_VARIABLE);
      aDocVars.push (new oVariable (sVarName, sValue, oVar, bIsSystem, oTR));
      InitFA_errno ();                            // track the progress
      oTR = oDoc.Find(oTR.beg, findParams);       // prepare for next find
    }
  }
  goFMv.nDocVars = goFMv.aoDocVars.length;
  RestoreLocation (oDoc, oSavedLoc);
  SetDisplay (true);
} //--- end CollectVarsInDoc

From a more detailed trace I know that the statement on line 66 is in charge.

This topic has been closed for replies.
Correct answer frameexpert

Somewhere along the line, Adobe changed the Displaying property from a toggle (on or off) to a stack-based property. So the problem comes when Displaying is set to the same value more than once. I don't remember the details, but the solution is simple:

// Make sure Displaying is on before you turn it off.

if (app.Displaying === 1) {

    app.Displaying = 0;

}

...

// Make sure Displaying is off before you turn it on.

if (app.Displaying === 0) {

    app.Displaying = 1;

}

1 reply

frameexpert
Community Expert
frameexpertCommunity ExpertCorrect answer
Community Expert
January 27, 2018

Somewhere along the line, Adobe changed the Displaying property from a toggle (on or off) to a stack-based property. So the problem comes when Displaying is set to the same value more than once. I don't remember the details, but the solution is simple:

// Make sure Displaying is on before you turn it off.

if (app.Displaying === 1) {

    app.Displaying = 0;

}

...

// Make sure Displaying is off before you turn it on.

if (app.Displaying === 0) {

    app.Displaying = 1;

}

K.Daube
Community Expert
K.DaubeCommunity ExpertAuthor
Community Expert
January 28, 2018

Thanks Rick, but isn't my code observing the basic rule: avoid to set the current setting again?

function SetDisplay (bWanted) { //=== Set display to on or off ====================================
// Arguments bWanted: true => set display ON; false => display OFF
var bCurrent = app.Displaying;
  if (bCurrent != bWanted) {                      // if current setting not the wanted one
    app.Displaying = bWanted;                     // set to the wanted one
  }
} //--- end SetDisplay

bCurrentbWantedActiom
truetrueif is bypassed
truefalseapp.Displaying = false
falsetrueapp.Displaying = true
falsefalseif is bypassed

IMHO my code is correct - but my logic might be wrong!

Klaus

frameexpert
Community Expert
Community Expert
January 28, 2018

Hi Klaus. After looking at your SetDisplay function, it looks like your logic is correct. I am sorry for not reading more carefully and following the thread you mentioned.

I would not worry about setting Displaying inside of a function like this. I always do it in my main function, usually "processDoc". I am not sure, but maybe there is a problem when calling it too many times.

main ();

function main () {

    // Test for active doc or book, etc.

    // and call processDoc or processBook.

    processDoc (app.ActiveDoc);

}

function processDoc (doc) {

    // Do any required tests here. Return if necessary.

    // Now worry about the display.

    if (app.Displaying === 1) {

        app.Displaying = 0;

    }

    // Call my various functions, etc.

    abc (doc);

    xyz (doc);

    // Restore the display.

    if (app.Displaying === 0) {

        app.Displaying = 1;

    }

}

function processBook (book) {

    // For each book component, open it and call processDoc.

    processDoc (doc);

}

function xyz (doc) {

}

function abc (doc) {

}