Nei giorni scorsi stavo tentando si sviluppare un controllo flash da utilizzare all’interno di una Windows Form e mi sono di conseguenza scontrato con varie problematiche inerenti la comunicazione e il passaggio di dati fra le due tecnologie. Di seguito vi riporto brevemente alcune annotazioni. Gli snippets di codice riportati sono in ActionScript e C++/CLI, ma possono facilmente essere convertiti in qualunque linguaggio che giri sotto il .Net Framework.
Comunicazione da .Net a Flash:
Permette di settare il valore di una variabile ActionScript. Il problema ÃÂè che SetVariable prende come parametri due stringhe, quindi non posso passare altri tipi di dato.
flashObj->SetVariable( nome, valore );
Permette di richiamare una funzione definita in ActionScript passando eventuali parametri. Permette di passare come parametro booleani, stringhe, array e oggetti;
In actionscript bisogna ricordarsi di importare ExternalInterface:
import flash.external.ExternalInterface;
e di definire un CallBack per ogni funziona che si vuole richiamare da C++:
ExternalInterface.addCallback("setVisible", null, setVisible);
- Invoca la funzione resetAll (definita in actionscript) senza passare alcun parametro.
String^ command = "<invoke name=\"resetAll\" returntype=\"xml\"><arguments></arguments></invoke>";
flashObj->CallFunction(command);
- Invoca la funzione setVisible (definita in actionscript) e le passa un booleano a true.
command = "<invoke name=\"setVisible\" returntype=\"xml\"><arguments><true/></arguments></invoke>";
X maggiori info:
http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/
html/wwhelp.htm?context=LiveDocs_Parts&file=00000344.html
Comunicazione da Flash a .Net:
Permette di scatenare un evento FSCommand che verrÃÂàcatturato dal container del Ocx Flash. Anche in questo caso vi ÃÂè la limitazione che fscommand permette di restituire solo stringhe(che poi andranno quindi convertite nel formato appropriato).
Da C++ quindi dobbiamo andare a gestire lâ≢evento FSCommand.
void MyUserCtrl::flashObj_FSCommand(System::Object^ sender, AxShockwaveFlashObjects::_IShockwaveFlashEvents_FSCommandEvent^ e)
{
if(e->command == "Start")
{
switch(Int32::Parse(e->args))
{
case 1:
MessageBox::Show(ââ¬Ã
ÂStart 1ââ¬ÃÂ);
break;
case 2:
MessageBox::Show (ââ¬Ã
ÂStart 2ââ¬ÃÂ);
break;
}
}
else if(e->command == "stop")
{
MessageBox::Show(ââ¬Ã
ÂStopââ¬ÃÂ);
}
}
Da ActionScript la sintassi da usare sarÃÂÃÂ la seguente:
fscommand(ââ¬Ã
ÂStartââ¬ÃÂ, ââ¬Ã
Â1ââ¬ÃÂ);
fscommand(ââ¬Ã
ÂStopââ¬ÃÂ, ââ¬Ã
Âââ¬ÃÂ);
Permette di eseguire un metodo presente nel contenitore del controllo Flash. Richiede almeno un parametro che ÃÂè il nome della funzione da richiamare. Gli eventuali altri parametri verranno poi passati alla funziona richiamata. Inoltre anche in questo caso ÃÂè necessario importare la classe ExternalInterface.
var num1:Number = 5;
var num2:Number = 2;
var result:uint = ExternalInterface.call("somma", num1, num2 );
Gli argomenti passati da actionscript si potranno ricevere attraverso la proprietÃÂàrequest dellâ≢evento e avranno una struttura simile alla seguente:
<invoke name="somma" returntype="xml">
<arguments>
<number>5</number>
<number>2</number>
</arguments>
</invoke>
Quindi in C++ il gestore dellâ≢evento FlashCall sarÃÂàil seguente:
void MyUserCtrl:: flashObj _FlashCall(System::Object^ sender, AxShockwaveFlashObjects::_IShockwaveFlashEvents_FlashCallEvent^ e)
{
XmlDocument^ document = gcnew XmlDocument();
document->LoadXml(e->request);
XmlNodeList^ list = document->GetElementsByTagName("arguments");
somma( Convert::ToInt32( list[0]->FirstChild->InnerText ), Convert::ToInt32(list[0]->ChildNodes[1]->InnerText) );
}
void MyUserCtrl::somma( int num1, int num2 )
{
MessageBox::Show( (num1 + num2).ToString() );
}