General XMetaL Discussion

XMetaL Community Forum General XMetaL Discussion Read Flash (SWF) dimensions

  • 4fingers

    Read Flash (SWF) dimensions

    Participants 8
    Replies 9
    Last Activity 11 years, 4 months ago

    Hi,

    We have a flash tag where you can specify a SWF file but you then have to manually add in the widths and height. It should ideally work in the same way as images where the width and height are automatically populated.

    It looks like I could place some logic inside the “On_Before_Set_Attribute_From_AI” event macro but retrieving the actual dimensions would be the hard part.

    However retrieving the dimensions does look possible in JavaScript via the TGetProperty Flash method:
    [url=http://blog.codefidelity.com/?p=14]Detect Flash Dimensions (Width & Height) via Javascript[/url]

    Anyone have any ideas if such a thing would be possible in XMetaL 6.0 EE

    Thanks

    Reply

    Derek Read

    Reply to: Read Flash (SWF) dimensions

    See the attached sample called swfExample.zip

    I've made a self-contained customization that is as simple as possible to answer just this one question. You will ultimately take just those few relevent lines of code and adapt them to fit your own customization.

    Legal:
    * Licensed Materials - Property of JustSystems, Canada, Inc.
    *
    * (c) Copyright JustSystems Canada, Inc. 2011
    * All rights reserved.
    *
    *-------------------------------------------------------------------
    * The sample contained herein is provided to you "AS IS".
    *
    * It is furnished by JustSystems Corporation as a simple example and has not been
    * thoroughly tested under all conditions. JustSystems Canada, Inc., therefore, cannot
    * guarantee its reliability, serviceability or functionality.
    *
    * This sample may include the names of individuals, companies, brands and products
    * in order to illustrate concepts as completely as possible. All of these names are
    * fictitious and any similarity to the names and addresses used by actual persons or
    * business enterprises is entirely coincidental.
    *---------------------------------------------------------------------

    Running the Demo:
    1. Save the zip file (attached) and unzip it to an empty folder.
    2. Confirm that you have the Adobe ShockWaveFlash ActiveX control installed on your system. This should be the case if you have installed the plug-in for Internet Explorer or perhaps other browsers. You need to obtain and install it if it is not installed already.
    3. Launch XMetaL Author Enterprise or Essential and open test.xml. The file “lorem.swf” (generated from a sample included with Corel R.A.V.E.) should be rendered within the element. An alert dialog should also be displayed telling you what the width and height are. Further information is contained within test.xml

    More Info:
    Essentially what needs to be done is to integrate the two method calls discussed on http://blog.codefidelity.com/?p=14 into your own script(s). Provided you have access to the ActiveX control (as in this example) you should be able to access all of its properties and methods (for details on what those are refer to Adobe's documentation).

    The most relevent portion of the demo is the event macro that calls the method TGetProperty (shown in blue) as follows:

     var IPC = Application.ActiveInPlaceControl;
     if (IPC != null) {
       var domnode = IPC.Node;
       // Tell ShockWave to open file from swf @href value, noting that it needs an absolute filepath
       attrnode = domnode.attributes.getNamedItem("href");
       if (attrnode != null) {
         var swfPath = "";
         swfPath = swfPath + IPC.Document.LocalPath;
         swfPath = swfPath + "\" + attrnode.value;
         var ShockWaveFlash = IPC.Control;
         if (ShockWaveFlash != null) {
           ShockWaveFlash.Movie = swfPath;
           ShockWaveFlash.Play();
           var msg = "Internal dimensions of " + swfPath +" (as reported by the ShockWaveFlash control) are: ";
            var w = ShockWaveFlash.TGetProperty("/", 8);
            var h = ShockWaveFlash.TGetProperty("/", 9);

           msg += "nnwidth:" + w + "nheight:" + h;
           Application.Alert(msg);
         } else {
           Application.Alert("Unable to load ShockWaveFlash ActiveX control.","swf_OnInitialize Macro Error");
         }
       }
     }
    ]]>

    Reply

    4fingers

    Reply to: Read Flash (SWF) dimensions

    Thanks Derek that example was a great help

    However after adapting the example I seem to have run into a severe “bug” and a graphical “glitch”.

    First of all here are the following changes I made; the first includes changes to the DTD to use default width and height values:
    ...
       href CDATA #IMPLIED
       width CDATA  "800"
       height CDATA  "600"
       align (left,center,right) #IMPLIED
    >

    Then adding a section of code into the macro that would update the width and height attributes if they didn’t exist or were set to the defaults:
    ...
    msg += "nnwidth:" + w + "nheight:" + h;
    w = Math.round(w);
    h = Math.round(h);
    var widthAttribute = domnode.attributes.getNamedItem("width");
    var heightAttribute = domnode.attributes.getNamedItem("height");

    if(widthAttribute != null && widthAttribute.value == "" || widthAttribute.value == 800){
      widthAttribute.value = w;    
    }      
    if(heightAttribute != null && heightAttribute.value == "" || heightAttribute.value == 600){
       heightAttribute.value = h;
    }
    Application.Alert(msg);
    ...

    Upon opening the test.xml file I am greeted with three alerts. I am guessing one for the initialising then two more for each attribute change. After the document has opened the width and height values have been successfully updated and are no longer set to 800 by 600.

    The trouble comes when I create a new “swf” element beside the current “swf” element e.g.
    ...
     width="478" height="174"/>

    ..

    As soon as I press enter after typing “lorem.swf” into the new and empty “href” attribute field I get two Alert messages before XMetaL 6.0 just closes without any error message. Attempting to run the exact same process via XMetaL Developer results in the same behaviour with the following output from the console:

    Warning: Cannot debug script code. Incorrect function.

    ———————– DEBUG STARTED —————————–
    Command : C:Program FilesXMetaL 6.0Authorxmetal60.exe
    Command Arguments :
    Working Directory : C:Program FilesXMetaL 6.0Author
    ———————– END OF DEBUG SESSION ———————-
    The thread 0xdd8 has exited with code 0 (0x0).
    The program '[3300] xmetal60.exe: Script program' has exited with code 0 (0x0).

    The only way round this issue would be to edit the width and height values to something else before adding in a file name to the href attribute.

    The second issue is more of a visual glitch and can be recreated at my end via the following steps:

    • Open text.xml
    • Crate a second “swf” element beside previous one just like before.
    • To avoid XMetaL crashing change the default width and height to 801 by 601.
    • Type “lorem.swf” into the “href” attribute.
    • Now go ahead and delete the height or width value, giving the macro a chance to populated it with the actual width and height values from the “swf” file
    • You should now see a total of thee “swf” elements on the page instead of two.

    The final effect can be seen in the attached zip file which includes a screenshot (lorem_glitch.png) of this issue. Although with this issue it can be remedied by simply changing views or updating an attribute.

    Any ideas why its doing these things?

    Thanks

    EDIT: It might be handy to know I am using Windows XP SP2, IE7 and Flash ActiveX version 10.2.152.32

    Reply

    Derek Read

    Reply to: Read Flash (SWF) dimensions

    Seems you didn't include an updated zip file. However, I have made your changes to the MCR and I can reproduce a crash. The crash is most likely because you should not be modifying the document in ***_OnInitialize. If the document needs to be modified then you should do that elsewhere, possibly in ***_OnSynchronize.

    I'm assuming you basically want this:

    1. If @width and @height are not set in the XML (either the attribute is missing or the value is an empty string) then read them from the SWF file and populate them automatically.
    2. Draw the control at the size specified by @width and @height.

    The second one is easily done in OnInitialize. It is the first one that is going to be difficult.

    It is also possible that this control has some issues that make it incompatible for use this way (it was designed for use with IE and so may not have been tested when embedded in other ActiveX hosts), or perhaps this particular version has issues. If that appears to be the case it may be worth trying an older version (if one is available). The issue you have seen with multiple copies of the SWF appearing when there should only be one makes me wonder. That could be our issue as well (in either case I still cannot reproduce this).

    Alternatively, you may wish to embed the IE WebBrowser control instead and interact with it. To do that you would specify Shell.Explorer as the progid in the CTM file. The trick then would be to figure out how to tunnel down to the ShockWave control that IE would load to extract these values. You may need to create an HTML page that loads the SWF file in order to do that, in which case the issue becomes even more complex to interact with the ShockWave control as you would likely need to make calls something like this from within the XMetaL script: IPC.Control.Document.parentWindow.yourcustomfunction(IPC.domnode), where yourcustomfunction() is defined inside the HTML.

    If none of these things appear to work we might need to pass this on to our development team to see if they can add or extend our APIs to support this usecase (assuming this ActiveX control does not have any issues as that would be out of our control).

    Reply

    Derek Read

    Reply to: Read Flash (SWF) dimensions

    Depending on the desired workflow it might also be possible to call up this control without rendering it, or if that is not possible to call up IE and render it invisibly (that is possible) then query the value there, or maybe you don't mind rendering it (if a dialog is involved).

    I'm thinking about a custom dialog (XFT) that would be similar to a standard “Browse for Image” dialog but that would call the ShockWave control (or actually embed it), at which point you could query the width and height, then when the control is dismissed it would populate the @width and @height.

    To provide similar behavior (to force the user to select a file so that such an element never gets into the document without the width and height set) you could trigger the same dialog from an block inside the CTM file (see the journalist.ctm demo for a simple example).

    Reply

    4fingers

    Reply to: Read Flash (SWF) dimensions

    Hi Derek,

    Seems you didn't include an updated zip file.

    Woops sorry about that, I made sure I included the updated version this time.

    The crash is most likely because you should not be modifying the document in ***_OnInitialize. If the document needs to be modified then you should do that elsewhere, possibly in ***_OnSynchronize.

    I went ahead and placed the logic inside ***_OnSynchronize but it still resulted in a crash, the only difference being I received an Application Error:

    ---------------------------
    xmetal60.exe - Application Error
    ---------------------------
    The instruction at "0x00000000" referenced memory at "0x00000000". The memory could not be "read".

    Click on OK to terminate the program
    Click on CANCEL to debug the program
    ---------------------------
    OK  Cancel 
    ---------------------------

    However, after tiding up the macro code, including a mini template for the swf element and converting the width and height attribute back to #IMPLIED the crashing issue seems to have been resolved. The updated Macro, CTM and DTD file should be viewable in the attached zip file.

    The issue with graphical glitches is still present; if it helps I managed to simplify the test case:

    • Open text.xml
    • Select the swf element and delete one of the width or height attributes.

    For me this results in the duplication of the swf element, the updated screenshot should show this.

    It is also possible that this control has some issues that make it incompatible for use this way (it was designed for use with IE and so may not have been tested when embedded in other ActiveX hosts), or perhaps this particular version has issues. If that appears to be the case it may be worth trying an older version (if one is available). The issue you have seen with multiple copies of the SWF appearing when there should only be one makes me wonder. That could be our issue as well (in either case I still cannot reproduce this).

    Adobe provides archived versions of the the Flash ActiveX player here: [url=http://kb2.adobe.com/cps/142/tn_14266.html]Archived Flash Player versions[/url]
    From there I was able to install version 9.0.280.0, I could go back further but so far no improvement over version 10.

    It does appear that XMetaL is recreating the swf element entirely. For example the swf tags are also created and highlightable, even the Flash right mouse button context menu works.

    Furthermore if I remove the ***_OnInitialize macro from the updated MCR file and follow the above steps, then when I open the test.xml file, as expected the Flash doesn't load. When I go and delete the width or height then a duplicate swf element still appears, even when the source xml says there is only one. Like before switching views removes the clone. I attached another screenshot (lorem_glitch_no_flash.png) to show this.

    Depending on the desired workflow it might also be possible to call up this control without rendering it, or if that is not possible to call up IE and render it invisibly (that is possible) then query the value there, or maybe you don't mind rendering it (if a dialog is involved).

    Although rendering the Flash is nice, retrieving the width and height is more important. I could certainly look into creating a custom dialog that does all this in the background and I will try looking into examples in the journalist.ctm demo before I ask any further questions on this approach.

    Thanks

    Reply

    Derek Read

    Reply to: Read Flash (SWF) dimensions

    I think this example (attached as example2.zip) may get you closer to what you want.

    1. Unzip all files to a new empty folder.
    2. Open test.xml
    3. See that an SWF is rendered (the same lorem.swf as before).

    In Tags On view you can click just inside an opening or closing tag to trigger a custom form called swfBrowser.xft to launch (it needs to be just inside, but not on the control itself because Shockwave eats clicks that hit it directly).

    The same form is launched when you insert an element using the Element List (in either Tags On view or Normal view).

    I think the form does the logical thing. It tries to keep the @width and @height from the XML if the selection is already inside an element that has href/width/height set, but if you browse for a new file it uses the TGetProperty() method to extract the width and height from the SWF itself, which you can then alter if you like before clicking the OK button to either update an existing or insert a new one.

    It also tries to do some fancy stuff like display the full path to the SWF file in the dialog for the user but fix that up to be relative in the XML source.

    I am seeing the odd rendering behaviors with the other stuff we've tried (as you described previously) but not with this example. The MCR has been simplified in example2.zip. It seems that merely calling TGetProperty() in the MCR triggers the odd behaviors though I'm not sure and I don't know why that would be but also when I embed IE (instead of embedding the control directly as before) these issues seem to go away (so it could also be that Shockwave really wants to be inside IE which is likely the only place it is ever tested by Adobe).

    Reply

    4fingers

    Reply to: Read Flash (SWF) dimensions

    I think this example (attached as example2.zip) may get you closer to what you want.

    Thanks Derek! That example proved to be very useful indeed.

    In Tags On view you can click just inside an opening or closing tag to trigger a custom form called swfBrowser.xft to launch (it needs to be just inside, but not on the control itself because Shockwave eats clicks that hit it directly).

    This was the only feature that our authors may not have been too keen about. The main issue was with affordance and usability where the area to click on might be too small for it to be truly helpful.

    To get round this issue I removed the XFtreplacements element and added in an On_Before_Set_Attributes_From_AI macro which contained the same logic in the OnInsertElement macro. It was then customised further so the custom form would only appear if the href attribute was deleted.

    It also tries to do some fancy stuff like display the full path to the SWF file in the dialog for the user but fix that up to be relative in the XML source.

    I did come across a bug where if the file was not saved then the absolute path created by the swfBrowser.xft was somehow incorrect. For example the following error would appear after clicking OK when I tried to insert a new swf element when the document wasn't saved:

    ---------------------------
    Windows Internet Explorer
    ---------------------------
    Cannot find 'file:///C:/file:///C:/Documents%20and%20Settings/Administrator/Desktop/shapes.swf'. Make sure the path or Internet address is correct.
    ---------------------------
    OK  
    ---------------------------

    This was simply fixed by including an extra check before the form was opened that would ensure the document was indeed saved before it went further e.g:

    if(ActiveDocument.FullName==""){
     Application.Alert("Please save the document before adding Flash/ShockWave");
    }

    To keep things organised I also wanted to place the swfBrowser.xft file in the Forms folder so I decided to include an extra check that if it couldn’t find it relative to the schema then it would look in the current Application.Path Form directory.

    After a few tweaks we now have a perfect solution to a problem I didn’t think was solvable in XMetaL

    Thanks again

    Reply

    Derek Read

    Reply to: Read Flash (SWF) dimensions

    That's great news. Thanks.

    Reply

    4fingers

    Reply to: Read Flash (SWF) dimensions

    Just thought I would share the problem we ran into when authors tried to open XML documents that contained Flash files on a network drive. Files would load fine on the local C: drive but placing them else where meant they were restricted by IE's security features and as a result the following error message would appear:

    Internet Explorer Script Error
    Line: 2
    Char: 1
    Error: Invalid character
    Code: 0

    There is more information on this issue via a Microsoft Support Article:
    [url=http://support.microsoft.com/kb/934366]Error message when you try to open an ActiveX control-based MIME handler in Windows Internet Explorer 7: “Invalid character”[/url]

    The easiest way round this for us was to create the following REG file which ran after the customisations were installed and ensured XMetaL had the rights to access HTML pages and scripts:

    Windows Registry Editor Version 5.00

    [HKEY_LOCAL_MACHINESOFTWAREMicrosoftInternet ExplorerMainFeatureControlFEATURE_BLOCK_LMZ_SCRIPT]
    "xmetal60.exe"=dword:00000000

    Hopeful someone will find this useful.

    Reply

  • You must be logged in to reply to this topic.

Lost Your Password?

Products
Downloads
Support