2010-06-15 3 views
0

Donc j'essaye de construire un outil qui me permettra, ainsi qu'aux autres utilisateurs, d'ouvrir le même fichier .swf, et ensuite je serai capable d'interagir avec le mien alors qu'ils verront tous mes mouvements de souris et clics de boutons etc. sur le leur. J'utilise BlazeDS pour gérer cela et je reçois des données envoyées en arrière et en avant etc - pas de difficultés là-bas. Le problème que je rencontre est le suivant:Flash: comment envoyer un événement click en haut d'un .swf chargé?

Dans une instance "Admin", je clique sur un bouton. Je capture ce X et Y, puis dis à Blaze de dire à mes clients d'envoyer un événement Click à ce X et Y. Du côté de mon client, j'obtiens ces données et envoie un événement Click à ce X et Y - mais le clic est effectivement pris au niveau de la scène. Le clic sur mon côté client a lieu sous tous mes boutons et autres contenus - donc tout échoue.

Est-ce que cela a du sens? Y at-il un moyen de lui dire de commencer l'événement de clic en haut?

Répondre

1

Si vous ne parvenez pas à architecturer les swf chargés pour utiliser une meilleure architecture, vous pouvez essayer quelque chose d'un peu plus hackish pour que les boutons fonctionnent. Regardez les méthodes getObjectsUnderPoint et areInaccessibleObjectsUnderPoint de DisplayObjectContainer. Combiné avec hasEventListener vous devriez pouvoir émuler ce que vous voulez.

Voici quelques pseudo-code non testé:

function detectClick(pt:Point):void 
{ 
    var objsUnderPoint:Array = containerStage.getObjectsUnderPoint(pt); 
    var clickable:Array = []; 
    for each(dispObj:DisplayObject in objsUnderPoint) 
    { 
     if(dispObj.hasEventListener(MouseEvent.CLICK)) 
     { 
      clickable.push(dispObj); 
     } 
    } 

    if(clickable.length) 
    { 
     // sort on depth here 
     // that might be tricky since you'll be looking at grandchildren 
     // and not just children but it is doable. 
     var topMostClickable:DisplayObject = ??? 
     topMostClickable.dispatchEvent(new MouseEvent(MouseEvent.CLICK, true, false)); 
    } 
} 

areInaccessibleObjectsUnderPoint est important si vous pensez peut-être leur restrictions de sécurité (par exemple, des questions inter-domaines) afin que vous puissiez déboguer si les choses tournent mal.

Notez également que vous pouvez (ou doivent) remplir plus de détails sur la MouseEvent (comme la cible appropriée, localX, localyY etc.)

+0

Je pense que c'est exactement ce dont j'ai besoin. Laissez-moi câbler et voir comment ça se passe, merci! – Myk

+0

Encore un peu difficile à mettre en œuvre de manière cohérente, mais cette réponse était sur place. Merci, accepté. – Myk

0

Il semble que vous ayez besoin de régler le focus sur la position la plus élevée des positions x et y avant d'envoyer l'événement click. Cela dit, je me demande quel est le cas d'utilisation pour quelque chose comme ceci; plutôt que d'utiliser un outil de partage d'écran tel que Connect.

+0

Il est un outil interne avec les exigences spécifiques. Que voulez-vous dire définir le focus? J'essaye de faire myLoadedSWF.dispatchEvent() etc - êtes-vous en train de dire que je devrais introspecter le fichier .swf chargé et envoyer l'événement sur le bouton réel, etc Je voudrais l'intercepter? – Myk

+0

Je ne sais pas comment expliquer le focus. L'élément avec focus est celui qui est actif. Vous devriez essayer de mettre l'accent en utilisant le FocusManager http://livedocs.adobe.com/flex/3/langref/mx/managers/FocusManager.html, puis envoyer l'événement approprié sur l'objet focalisé. – JeffryHouser

+0

Ouais, ce n'est pas ce dont j'ai besoin. La mise au point est excellente pour le tabulation, mais j'ai besoin d'une duplication de l'événement souris 1: 1 entre l'administrateur et le client. – Myk

0

Cela semble être une mauvaise façon d'implémenter ce que vous essayez de faire. Si vous "cliquez" dans l'outil d'administration, vous êtes probablement en réalité déclenchant un événement. Pourquoi ne pas déclencher cet événement au lieu d'envoyer le clic de souris? Je voudrais juste garder une carte d'actions et puis quand quelque chose se passe dans l'interface d'administration envoyer la clé à l'action.

par exemple.

Dans l'administration:

myButton.addEventListener(MouseEvent.CLICK, handleClickButton); 

function handleClickButton(event:MouseEvent):void 
{ 
    doSomeAction(); 
    sendTriggerToClient(MyActions.SOME_TRIGGER); 
} 

Dans le client:

var actionMap:Object = {}; 
actionMap[MyActions.SOME_TRIGGER] = doSomeAction; 

function receiveTriggerFromAdmin(trigger:String):void 
{ 
    var responseFunc:Function = actionMap[trigger]; 
    responseFunc(); 
} 

J'espère que pseudo-code est logique. Juste résumé ce qui se passe à la suite d'un clic dans une fonction distincte (doSomeAction), puis demandez à l'administrateur d'envoyer un message avant d'appeler cette fonction. Dans le client attendez tout déclencheur qui traverse et mappez-le à la même fonction.

+0

Si cela ne tenait qu'à moi, nous aurions une intégration MVC complète sur tous les actifs chargés dans cet outil - alors nous avons simplement synchroniser le modèle à un serveur central, lier l'état à ce modèle et autoriser seulement l'administrateur à écrire des mises à jour il. Malheureusement, cet outil doit prendre en charge une vaste étendue de fichiers .swf déjà écrits. Je voudrais éviter d'entrer et de rééquiper tout leur contenu existant pour une bonne architecture. Ceci est destiné à être un outil qui permet à quelqu'un de démo l'une de leurs applications à un certain nombre de clients à la fois. Donc, oui - bonne pensée, mais malheureusement, ne résout pas ce problème. – Myk

+0

Pour être plus précis - le client et l'administrateur sont effectivement la même application. J'ai juste un drapeau "admin" que je déclenche dans celui que je veux utiliser pour diffuser. Je dois être capable de l'utiliser pour charger n'importe quel fichier .swf. Cela a-t-il du sens? – Myk

Questions connexes