Posted by andrecp in SWF Studio V3 on Jan 10 2008, 12:03 pm

Hi, I'm new to SWFStudio but I'm trying to create an app that interacts with an ActiveX control. I decided using JScript would probably be the way to go, but I can't even get the basic examples working with JScript.

For example, I've tried creating a one-line script.js file with just this line:
jsCommand("Win.minimize",{});

But when I run this code in my Flex app's InitApp() function it pops up with a syntax error.

ssCore.init();
ssDefaults.synchronousCommands = true;
ssCore.Script.create({module:"module", language:"jscript"});

var r = ssCore.Script.loadCode({module:"module", path:"C:\\flashphone\\script.js"});

if (r.success == false) 
{
   ssCore.App.showMsgBox({prompt:"load failed: " + r.Error.description});
   ssCore.App.quit({});
}
   
var r = ssCore.module.main({});

if (r.success == false) 
{
   ssCore.App.showMsgBox({prompt:r.Error.code + " " + r.Error.description});
   ssCore.App.quit({});   



I'm not sure if I did something wrong, or if there's some issue using JScript with a Flex app (The only examples I've seen were for flash apps). However I did have some success with the Word ActiveX JScript example from another post, it would get past the first if block of the AS code but not the second.

I'm also wondering if there's any way to get more detail about JS syntax or runtime errors, for example the line number?

Thanks in advance.


Posted by andrecp in SWF Studio V3 on Jan 10 2008, 12:46 pm

Ok I think I fixed it by removing everything after the first if block in the as code.

Still having some issues with ActiveX though but I'll dig some more.


Posted by mbd in SWF Studio V3 on Jan 10 2008, 02:26 pm

There's a split in functionality for JScript in 3.5. AS1/AS2 projects won't change. AS3 projects will need to have the JScript code updated. The ActionScript code doesn't change.

For instance, there is no jsCommand accessible from JScript in AS3 projects. The following are the new objects/methods:

jsCore.execute
- similar syntax as ssCore. If you specify a callback the callback property MUST be a string and you MUST specify a scope. Note: there is no "this" object as the "document" object. You will need to specify a method on an object (which doesn't have to be a generic object).

With jsCore.execute the syntax is a split between jsCommand (from AS1/AS2) and ssCore on the AS side.

Usage:

var obj = new Object();
obj.onAnswer = function (return_obj, callback_obj, error_obj)
{
   if (return_obj.success)
   {
      trace(return_obj.result);
   }
   else
   {
      trace('ERROR: '+error_obj.description);
   }
}

jsCore.execute('App.showMsgBox', {prompt:'Hello'}, {callback:'onAnswer', scope:obj});


jsDefaults.synchronousCommands
- is not automatically set along with ssDefaults, so you need to enable it in JScript if you want sync commands in JScript.

jsGlobals
- all of the ssGlobals properties are available and updated when ssGlobals is updated.

Functions in JScript:

setInterval - same as previous versions

clearInterval - same as previous versions

setTimeout - matches JavaScript, not Flash. Although we're used to the Flash method, the JavaScript method is much more powerful, since you enter code that will be eval'd after the timeout, instead of just calling a function, which you can do as well.

clearTimeout - what you'd expect.

Items no longer available in JScript for AS3 projects:

jsCommand - use jsCore.execute instead. The new method allows you to execute the commands synchronously or asynchronously and specify a callback, the same as ssCore. This includes notifications!

Flash - The object and it's methods no longer exist. There will be a better way to do this. The new functionality will be much easier to follow.

For your example code, I don't imagine the compiler is too happy about the double-declaring of your "r" variable. Aside from that there should be no reason the code doesn't execute.

If you get an error you should see the error description. On loadCode and when executing a method in the module, if success is false in the return object, check the "scriptError" output parameter. That should contain the error details that the JScript engine returns, i.e. description and line number returned as one string.

If you aren't seeing the message boxes and your scripts aren't executing, make sure your application is visible before calling ssCore.App.showMsgBox. That command will return an error is the app isn't visible, since you can't display dialogs unless the app is visible.


Posted by northcode in SWF Studio V3 on Jan 10 2008, 07:45 pm

This will all be included in the V3.5 documentation, Derek's working on that now :)


Posted by andrecp in SWF Studio V3 on Jan 11 2008, 11:58 am

Thanks guys, I've gotten pretty far since I posted this yesterday, but I think I've run into the lack of Flash.excecute from my JScript code, I call it but it doesn't seem to do anything, so that functionality isn't in the current 3.5 beta?
I thought maybe I was calling to the wrong as method since I don't know if Flex methods go under _level0.

E.g, if I have a public method in my flex AS script:

public function SetStatus(status:String)
{
    MainPanel.status = status;            
}


Can I call it from JScript with:

Flash.execute({method:"_level0.SetStatus",args:[status]});?


Posted by mbd in SWF Studio V3 on Jan 11 2008, 04:44 pm

The current version doesn't have anything for you to use to access classes in ActionScript from JScript.

The trick with AS3 is that you have to know where something is in order to call it. _level0 doesn't exist so targetting a method is a little different.

The implementation will be simplified so that you setup a handler (or possibly listeners) to which calls from JScript can be executed.

I am working on this now. Any comments and/or suggestions are welcome.


Posted by AGo in SWF Studio V3 on Jan 12 2008, 05:25 am

Just wondering, if you do calls from JS to AS via an listener on the AS side, how about returning values back to JS, especially if the listener code executes another command async and you would want the result of that async. command passed back to JS?

(to clarify, by an async listener I mean the listener returns back to JS before the AS method with the data I am interested in returns)


Posted by mbd in SWF Studio V3 on Jan 12 2008, 09:16 pm

The event listener model may not work here because you might want to return data back from the call, as you suggest. Setting up a call handler on the AS side is probably the way to go.

As far as async goes, it's the same as anything else: when you return from a call that's it. If you spawn another call that will return asynchronously, then the data just won't be there, the same as making any call in Flash. If we talk strictly ActionScript, if you call a function and it calls a SWF Studio API call asynchronously, then your function won't be able to return the data immediately. You'll have to setup a call back into JS to pass the data.

The JScript module will only pause until you return from the AS function. There's no mechanism that will let you decide when to return data back to JScript. Something could be implemented but it's better that you handle this instead of us coming up with a messy set of exceptions for how data is returned.

Also, I forgot to mention (can't believe I missed it), but the calls to and from JS/AS will use JSON. That means native types are honoured across the "barrier". The implementation uses the classes freely available from the JSON.org site: Adobe's JSON classes from corelib, and the JScript JSON methods. JSON does not support custom classes so please don't ask if XML or any other type is supported - take a read at the JSON.org site for more information about what is supported. Although there will be mention in the V3 docs.

JSON has one limitation worth mentioning, besides custom classes: it cannot handle self-references. So if you have an object that references itself, or a sub-object that references a parent object you'll find yourself in an infinite loop. I had considered using my own serialization methods, which avoid this issue, but JSON is a standard and is open.

NOTE: SWF Studio will still only accept and return string values for API calls at this time. The JSON addition is really for calls to your own code. You also don't have to know squat about JSON to actually benefit from it, but it is good to know what is being used in case you need to know about the features and limitations.


Posted by andrecp in SWF Studio V3 on Feb 21 2008, 05:10 pm

Is the jsDefaults.synchronous commands property in the current beta (285)? I think it might help with my problem here, or some of the other js<->as3 functionality that's not in the current beta might fix (or help workaround) the problem I'm having.

I've been having an issue where I'm getting an empty return value for a function even though I'm returning a value and can verify it's contents with an alert is js, but once it gets back to as3 it's empty. I think it could be related to either the size of the value I'm returning (the contents of an xml file in a string), or the string contains something that throws off SWFStudio (it contains a lot of characters that might be parsed as delimiters or escape chars) and if I use the same function to get a small value or even a shorted xml string it will return properly.

Basically in my JS file I've set up a function called getProperty(obj), which returns eval(obj.property).

When I pass in an function it will execute that function (I can tell by putting an alert with the return value right before returning), but the return value I get back in AS is empty. I was thinking this may be due to the AS call not waiting for the return value from JScript.

JS

function getProperty(obj){return eval(obj.property);}

AS


var prop = "contactlist";//contactlist is a global var in my jscript file
var ret_obj = ssCore.module.getProperty({property:prop}(\


ret_obj.success will be true but ret_obj.value will be the empty string (despite my alert showing the string I return).

Just wondering if this is something that's been come across before? I will put together a sample app to reproduce this when I get the time.


Posted by mbd in SWF Studio V3 on Feb 21 2008, 08:29 pm

Are you actually looking for ret_obj.value, or is that a typo? The property that will contain your data will always be ret_obj.result.


Posted by andrecp in SWF Studio V3 on Feb 22 2008, 11:31 am

Sorry, yes that was a typo, I'm checking ret_obj.result

It's stange because I know the code works when I'm getting a small result, but when I get the full XML file (about 67kb) it does not.


Posted by mbd in SWF Studio V3 on Feb 22 2008, 11:50 am

I wouldn't consider 67kB large. When you mentioned large, I was thinking MBs.

Is the value a string representation of the XML? Can you post it as a file here so I can test it?


Posted by andrecp in SWF Studio V3 on Feb 22 2008, 12:14 pm

I PM'd the XML to you since it contains a lot of information that could be used maliciously if posted on the public forum.

I also did some more testing and I'm actually able to get the length of the returned string (non-zero), but when I try to trace it it just seems to skip those trace lines and go to a newline instead. e.g. ssDebug.trace(ret_obj.result.length) works and seems to contain the correct value, but ssDebug.trace(ret_obj.result) does not, it just skips to a new line.

Ok, scratch that...I actually am getting the XML back, it just doesn't appear in the trace, but when I right-click->Copy and then paste into notepad, the XML appears (along with the rest of what my app traces). Anyone ever see this issue before?

This brings me to something else, is there a way to link run my standalone app in a debugger? That way I could see the values I get back from jscript/activex without having to trace them all.


Posted by mbd in SWF Studio V3 on Feb 22 2008, 04:21 pm

I've been caught by that one too. If the value is too large the control in the Trace tab displays a blank line.

Copying the data out to a text editor is a good idea if you're expecting something you aren't seeing.

Debugging doesn't work as you'd expect. The debugger doesn't connect properly to your main SWF. You can see traces from ssDebug.trace or trace in the Output panel, but breakpoints won't work.