Saturday, October 3, 2009

How can you disable mouse-wheel scroll in TextArea component - AS3.0

Recently had a requirement to disable mouseWheel scroll in textArea component in Flash CS4.0 using AS3.0.

It does not get disable by using below statement :

myTxt.textField.mouseWheelEnabled = false;

You also need to stop propagation of that event.

myTxt.addEventListener(MouseEvent.MOUSE_WHEEL, disableMouseHandler, true);

function disableMouseHandler(event:MouseEvent):void {
event.stopPropagation();
}

You need to add both the above codes together to disable mouseWheel.

Click Here to get source files.

Thursday, September 10, 2009

getDefinitionByName - Example in AS3.0



getDefinitionByName is a method in Actionscript 3.0 with the help of which you can access any class @ runtime. For better understanding of this method I have created this small app. In this example user can select any class from the combobox and we can dynamically add it on stage.

We need to create certain objects in library which we would be adding in the combobox. On selection from the combobox we will use getDefinitionByName(ClassName).

Document Class - DocMainCls.as - Download Here



package {

import flash.events.MouseEvent;

import flash.display.Sprite;

import flash.display.MovieClip;

import flash.text.TextField;

import com.GetDefinitionByName_example;


public class DocMainCls extends MovieClip{



private var objGetDefinitionByName_example:GetDefinitionByName_example = new GetDefinitionByName_example();

private var objsAddedOnStage:Array = new Array();

private var objCounter:uint = 0;



public function DocMainCls(){

init();

}

private function init(){

attachToStageBtn.addEventListener(MouseEvent.MOUSE_DOWN, attachBtnPressFunction);

}

private function attachBtnPressFunction(e:MouseEvent):void{

if(objToAddDropDown.selectedItem.data < 0)

{

msgBox.text = "Select Object To Add..."

}

else

{

objGetDefinitionByName_example.objToAddName = objToAddDropDown.selectedItem.data;

objsAddedOnStage.push(objGetDefinitionByName_example.getClipToAddOnStage());

myStage.addChild(objsAddedOnStage[objCounter]);

objsAddedOnStage[objCounter].objId = "StageObj"+objCounter;


objsAddedOnStage[objCounter].addEventListener(MouseEvent.MOUSE_DOWN, stageObjectDragFunction);

objsAddedOnStage[objCounter].addEventListener(MouseEvent.MOUSE_UP, stageObjectDropFunction);

msgBox.text = "Object on stage "+objGetDefinitionByName_example.objToAddName

objCounter++;

}

}


private function stageObjectDragFunction(e:MouseEvent):void{

e.target.startDrag();

}

private function stageObjectDropFunction(e:MouseEvent):void{

e.target.stopDrag();

}

}

}



The important method in above class is "attachBtnPressFunction". It is an event method. In this method

objGetDefinitionByName_example.objToAddName = objToAddDropDown.selectedItem.data;
objsAddedOnStage.push(objGetDefinitionByName_example.getClipToAddOnStage());
myStage.addChild(objsAddedOnStage[objCounter]);


The first line in above is setting a value for the object to be added. It is assiging class name from the combobox dropdown to the GetDefinitionByName_example class below.

GetDefinitionByName_example Class - GetDefinitionByName_example.as - Download Here

package com{

import flash.display.MovieClip;

import flash.utils.getDefinitionByName;



public class GetDefinitionByName_example{

private var _objToAddStage:String;

private var _objType:Class;

private var _objTypeInstance:MovieClip;



public function GetDefinitionByName_example(){

trace("Class -> GetDefinitionByName_example::::: constructor initiated...")

}

public function set objToAddName(_setVal:String):void

{

_objToAddStage = _setVal;

trace("Class -> GetDefinitionByName_example:::Method -> objToAddName::::"+ _objToAddStage)

}

public function getClipToAddOnStage():MovieClip

{

_objType = getDefinitionByName(_objToAddStage) as Class;

_objTypeInstance = new _objType as MovieClip

return _objTypeInstance;

}

public function get objToAddName():String

{

return _objToAddStage;

}

}

}

In the above class "objToAddName" It is a getter setter method which basically sets the class which the getDefinitionByName will access. We set the comboxBox dropdown values to be passed to this method.
The other most important method of this class is "getClipToAddOnStage()" this basically fetches the class and returns its
movieclip object which is further processed to add on stage.

This method is very important when we create dynamic attachment on stage or whenever we have requirement to access the
classes dynamically.

You can download the complete source files here

-Nitin

Sunday, July 19, 2009

AS3.0 and VisualBasic communication using ExternalInterface

This example deals with the communication between flash and Visual Studio 6. In this example a flash9 swf is placed on a VB form in shockwave wrapper. The requirement is reading any directory of windows OS with the help of Flash as frontend and VB as Backend.

To start of lets create one flash file. The file has to be simple just carrying one select directory button and a movieclip with textbox inside it, which will display the directory name. You can also create dynamic movie clips to deal all these but here i have placed them in library.

This is the link to the fla file if you don't want to create it. You can download it from below link.


I am using a document class here named as "main.as". I am using external interface to communicate to the VB which reads
the directory and sends us the values. Lets check the document class below.


package {
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.external.ExternalInterface;
import flash.text.TextField;
import flash.net.navigateToURL;
import flash.net.URLRequest;
import flash.net.URLLoader;
import flash.display.Loader;

public class main extends Sprite
{
private var _directoryPath:String;
private var _directoryList:XML;
private var _sampleXML:XML;
private var _parserData:directoryParser;
private var _linkObjects:Array = new Array();
public function main()
{
_directoryPath = "C:\\Documents and Settings\\nitins\\Desktop\\Reading_Directory_Content\\data"
selectFolder.addEventListener(MouseEvent.MOUSE_DOWN, selectDirectoryInvoked);

ExternalInterface.addCallback("sendToActionScript",callFromVB);
}
private function callFromVB(_myParam)
{
_directoryList = XML(_myParam);
_parserData = new directoryParser(_directoryList);
generateTree(_parserData.returnXML());
}

public function selectDirectoryInvoked(event:MouseEvent)
{
ExternalInterface.call("selectFolder",_directoryPath);
}

public function generateTree(givenList:XML)
{
var loopLen:Number = givenList.filename.length();
var strtY:Number = 50;
for(var i=0;i<loopLen;i++)
{
var tempHold = givenList.filename[i].split(".")
var req:String = tempHold(tempHold.length-1)+".jpg"
var iconLoader:Loader = new Loader();
iconLoader.load(new URLRequest(req));
_linkObjects[i] = new ListBox();
_linkObjects[i].txt.text = givenList.filename[i];
_linkObjects[i].openFileName = givenList.filename[i];
_linkObjects[i].addEventListener(MouseEvent.MOUSE_DOWN, clikedLink);
_linkObjects[i].y = strtY
addChild(_linkObjects[i]);
strtY += _linkObjects[i].height+10;
}
}

public function clikedLink(e:MouseEvent):void
{
var _passPath:String = _directoryPath+"\\"+e.currentTarget.openFileName
ExternalInterface.call("openFile",_passPath);
}
}
}

As you can notice above - the method "selectDirectoryInvoked" is the one which gets called when the select directory button is clicked from the interface. Basically it just makes a call to VB function "selectFolder" and passes a parameter as the path of the directory. One more function you can notice above is the "callFromVB" it is the method that is registered to External Interface in the constructor of the "main" class.

/*------------------------------------------------------------*/
private function callFromVB(_myParam)
{
_directoryList = XML(_myParam);
_parserData = new directoryParser(_directoryList);
generateTree(_parserData.returnXML());
}
/*-------------------------------------------------------------*/

Above method is reading "_myParam" which is a dynamically generated XML from VB App.
Few very important things which we must keep in mind doing this communication is that the entire communication is XML oriented. From making the External interface call to reading it, all this happens in a perticular XML node format which is something like this :


<invoke name="functionName" returntype="xml">
<arguments>
... (individual argument values)
</arguments>
</invoke>
Communication between ActionScript and an application hosting the Shockwave  Flash ActiveX 
control uses a specific XML format to encode function calls and  values. There are two parts to the 
XML format used by the external API. One format is used to represent function  calls. Another 
format is used to represent individual values; this format is  used for parameters in functions 
as well as function return values. The XML  format for function calls is used for calls to and 
from ActionScript. For a  function call from ActionScript, Flash Player passes the XML to the container;  
for a call from the container, Flash Player expects the container application to  pass it an XML string 
in this format. - (From Adobe Docs)

This is the reason i have casted the parameter from VB to XML. One more thing to notice 
in the above method is 
_parserData = new directoryParser(_directoryList);
Here i also have created one class which parses the VB returned XML to flash. Lets take a look
at this class.
directoryParser.as
package {
import flash.display.Sprite;
public class directoryParser
{
private var _returnData:XML;
private var _maxLen:Number;
private var _typeArray:Array;
public function directoryParser(dataToParse:XML)
{
_maxLen = dataToParse.filename.length();
_typeArray = new Array();
var temp:Array;
for(var i=0;i<_maxLen;i++)
{
temp = dataToParse.filename[i].split(".")
dataToParse.filename[i].@type = temp[1];
_typeArray.pushUnique(temp[1]);
}
_typeArray.sort();

generateSortedXML(dataToParse);
}
private function generateSortedXML(inputXML:XML)
{
var myTempXML:XML = <rootNode></rootNode>;
for(var i=0;i<_typeArray.length;i++)
{
for(var k=0;k<inputXML.filename.length();k++)
{
if(inputXML.filename[k].@type == _typeArray[i])
{
myTempXML.appendChild(inputXML.filename[k].toXMLString());
}
}
}
_returnData = myTempXML
}
public function returnXML():XML
{
return _returnData;
}

Array.prototype.pushUnique = function( a )
{
var l:Number = this.length;
var exists:Boolean = false;
for( var i=0; i<l; i++ ) if( this[i] == a ) exists = true;
if( !exists ) this.push( a );
};
}
}

This class is basically sorting the list given from VB to file types and showing the display. The public method within this class "returnXML()" is used to fetch the sorted XML which our document class "main" processes. It generated a list of files using "generateTree()" method.
You can use the same method to do any application handling using ExternalInteface.

Link to this class below :


Now lets take a look @ the VB interface and its code, what things we should keep in mind. Look @ below image.

In the above image the two red boxes are important, mySWF is the name of the shockwave object. AllowScriptAccess you need to make it "always" if you want your application to work.
Lets take a look @ the VB Code and its methods.


Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _

(ByVal hwnd As Long, ByVal lpOperation As String, _

ByVal lpFile As String, ByVal lpParameters As String, _

ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long

Dim directoryPath As String

Private Sub mySWF_FlashCall(ByVal request As String)

Dim objXML As MSXML2.DOMDocument

Dim strXML As String

Set objXML = New MSXML2.DOMDocument

strXML = request

If Not objXML.loadXML(strXML) Then

Err.Raise objXML.parseError.errorCode, , objXML.parseError.reason

End If

Dim objElem As MSXML2.IXMLDOMElement

Set objElem = objXML.selectSingleNode("//invoke")

If objElem.getAttribute("name") = "selectFolder" Then

Dim xmlElem As IXMLDOMElement

Set xmlElem = objXML.selectSingleNode("invoke/arguments/string")

directoryPath = xmlElem.Text

Dim fso As FileSystemObject

Dim fso_folder As Folder

Dim txt As String

Dim fso_file As File

Dim i As Long

Dim file_names() As String

' Make a new File System object.

Set fso = New FileSystemObject

' Get the FSO Folder (directory) object.

MsgBox directoryPath + "\"

Set fso_folder = fso.GetFolder(directoryPath + "\")

' Make the list of names.

ReDim file_names(1 To fso_folder.Files.Count)

i = 1

For Each fso_file In fso_folder.Files

file_names(i) = fso_file.Name

i = i + 1

Next fso_file

'MsgBox file_names(1)

Dim postString As String

postString = "<rootNode>"

For k = 1 To UBound(file_names)

postString = postString + "<filename>" + file_names(k) + "</filename>"

Next k

postString = postString + "</rootNode>"



mySWF.CallFunction ("<invoke name='sendToActionScript' returntype='xml'><arguments><string>" + postString + "</string></arguments></invoke>")

End If

If objElem.getAttribute("name") = "openFile" Then

Dim xmlElem1 As IXMLDOMElement

Set xmlElem1 = objXML.selectSingleNode("invoke/arguments/string")

MsgBox xmlElem1.Text

temp1 = Split(xmlElem1.Text, "\")



For i = 1 To UBound(temp1) - 1

finalPath = finalPath + temp1(i) + "\"

Next i

Dim ret As Long

Dim lErr As Long

ret = ShellExecute(Me.hwnd, vbNullString, xmlElem1.Text, vbNullString, finalPath, 1)

If (ret < 0) Or (ret > 32) Then

'ShellEx = True

Else

Select Case ret

Case 0

lErr = 7: sErr = "Out of memory"

Case ERROR_FILE_NOT_FOUND

lErr = 53: sErr = "File not found"

Case ERROR_PATH_NOT_FOUND

lErr = 76: sErr = "Path not found"

Case ERROR_BAD_FORMAT

sErr = "The executable file is invalid or corrupt"

Case SE_ERR_ACCESSDENIED

lErr = 75: sErr = "Path/file access error"

Case SE_ERR_ASSOCINCOMPLETE

sErr = "This file type does not have a valid file association."

Case SE_ERR_DDEBUSY

lErr = 285: sErr = "The file could not be opened because the target application is busy. Please try again in a moment."

Case SE_ERR_DDEFAIL

lErr = 285: sErr = "The file could not be opened because the DDE transaction failed. Please try again in a moment."

Case SE_ERR_DDETIMEOUT
lErr = 286: sErr = "The file could not be opened due to time out. Please try again in a moment."
Case SE_ERR_DLLNOTFOUND
lErr = 48: sErr = "The specified dynamic-link library was not found."
Case SE_ERR_FNF
lErr = 53: sErr = "File not found"
Case SE_ERR_NOASSOC
sErr = "No application is associated with this file type."
Case SE_ERR_OOM
lErr = 7: sErr = "Out of memory"
Case SE_ERR_PNF
lErr = 76: sErr = "Path not found"
Case SE_ERR_SHARE
lErr = 75: sErr = "A sharing violation occurred."
Case Else
sErr = "File could not be opened due to invalid application"
End Select
'Err.Raise lErr, , App.EXEName & "", sErr
MsgBox sErr
End If
End If
End Sub

Lets take a look at VB code.

"Private Sub mySWF_FlashCall(ByVal request As String)" Its very important to keep the function name in same way like with the shockwave object and adding the "_FlashCall" to let your application work. "request" is the variable as in XML format with arguement as shown and explained above in the tag.

With this code

postString = "<rootNode>"
For k = 1 To UBound(file_names)
postString = postString + "<filename>" + file_names(k) + "</filename>"
Next k
postString = postString + "</rootNode>"

I am creating one Dynamic XML String which we are sending to flash function "callFromVB".

This is the line which is sending the data to AS3.0 method.

mySWF.CallFunction ("<invoke name='sendToActionScript' returntype='xml'><arguments><string>" + postString + "</string></arguments></invoke>")

The other code is for opening a perticular file with the associated application as in case of my requirement it was required. I have put in a check to see if the file is working or not corrupt and if its fine i am launching it.

You can download entire application @ below link :


A special thanks to my manager Manotosh Roy who helped me in doing this stuff :o)

I hope you find it useful.

-Nitin

Friday, June 19, 2009

Build Flash Online - AS3.0 online compiler

This is very interesting stuff that you can explore. If you don't have programming resources for coding in AS3.0 then don't worry. You just need to go to


It really awsome. It has also support for many AS3.0 Libraries like as3corelib, tweener etc.

So you can do some great stuff here without much requirement of resource. Just logon and start coding :)

I will take you through one small example. Lets take a look @ the interface. Its too simple.



You just need to click the red pointed area shown above to start coding.



Doing coding is as simple as putting up some text line in notepad. The only disadvantage or advantage whatever u consider is that you don't get code hints. Lets go with a simple example. All I am trying to do is to create a simple circle and move it through Left and Right arrow.

The thing which i got to know while coding on wonderfl is that all the classes needs to be declared on the same screen - the package, classes etc. So, I need a circle shape which i am simple taking it through a class "snakeNode". This is just an example you can try with your own code.

  1. import flash.display.Sprite;
  2. import flash.geom.Rectangle;
  3. import flash.display.Shape;
  4. import flash.display.DisplayObject;
  5. class snakeNode extends Sprite{
  6. private var child:Shape = new Shape();
  7. public function snakeNode()
  8. {
  9. child.graphics.beginFill(0xFFCC00);
  10. child.graphics.lineStyle(0, 0x666666);
  11. child.graphics.drawCircle(5, 5, 5);
  12. child.graphics.endFill();
  13. addChild(child);
  14. }
  15. }

It goes something like above. Now the main document class where we would use this code.

  1. package {
  2. import flash.display.Sprite;
  3. import flash.events.KeyboardEvent;
  4. import flash.events.MouseEvent;
  5. public class sampleHitTest extends Sprite {
  6. private var mysNode:snakeNode;
  7. public function sampleHitTest() {
  8. init()
  9. }
  10. public function init():void
  11. {
  12. mysNode = new snakeNode();
  13. mysNode.x = 100;
  14. mysNode.y = 200;
  15. addChild(mysNode);
  16. stage.addEventListener(KeyboardEvent.KEY_DOWN,mouseDown);
  17. }
  18. public function mouseDown(event:KeyboardEvent):void
  19. {
  20. if(event.keyCode == 37)
  21. {
  22. mysNode.x-=15;
  23. }
  24. else if(event.keyCode == 39)
  25. {
  26. mysNode.x+=15;
  27. }
  28. }
  29. }
  30. }

In this way you can write your code. It compiles automatically as an when you are writing a code at the bottom.




Here is the complete code how it looks.

  1. package {
  2. import flash.display.Sprite;
  3. import flash.events.KeyboardEvent;
  4. import flash.events.MouseEvent;
  5. public class sampleHitTest extends Sprite {
  6. private var mysNode:snakeNode;
  7. public function sampleHitTest() {
  8. init()
  9. }
  10. public function init():void
  11. {
  12. mysNode = new snakeNode();
  13. mysNode.x = 100;
  14. mysNode.y = 200;
  15. addChild(mysNode);
  16. stage.addEventListener(KeyboardEvent.KEY_DOWN,mouseDown);
  17. }
  18. public function mouseDown(event:KeyboardEvent):void
  19. {
  20. if(event.keyCode == 37)
  21. {
  22. mysNode.x-=15;
  23. }
  24. else if(event.keyCode == 39)
  25. {
  26. mysNode.x+=15;
  27. }
  28. }
  29. }
  30. }
  31. import flash.display.Sprite;
  32. import flash.geom.Rectangle;
  33. import flash.display.Shape;
  34. import flash.display.DisplayObject;
  35. class snakeNode extends Sprite{
  36. private var child:Shape = new Shape();
  37. public function snakeNode()
  38. {
  39. child.graphics.beginFill(0xFFCC00);
  40. child.graphics.lineStyle(0, 0x666666);
  41. child.graphics.drawCircle(5, 5, 5);
  42. child.graphics.endFill();
  43. addChild(child);
  44. }
  45. }

You can also download this script in form of *.as file to use it anywhere you like. Its a great stuff and very useful. Cheers !!!

Nitin :o)

Using FormBuilder, Validators & FormGroup in Angular 2 to post data to Node server (node.js)

This blog explains usage of  FormBuilder , Validators , FormGroup classes in Angular 2 projects. In this post we will create HTML form a...