English 中文(简体)
如何在Flash表单中停止复制/粘贴
原标题:
  • 时间:2009-01-27 20:23:53
  •  标签:

我在一家医学转录公司工作,我们向申请人进行的医学转录测试是一个较旧的flash格式应用程序,当您进入表单时,它会停止复制和粘贴通过清空剪贴板。这在IE 7中运行得很好,但最近我注意到它在Firefox中效果不佳。或许这是flash的版本问题,因为flash应该是与浏览器无关的。我绝对不是flash开发人员,事实上我在这方面很糟糕。因此,我需要知道如何使用action script停止复制和粘贴。

根据评论,显然需要一些额外的信息。测试实际上做的是播放一个声音文件(基本的MP3),他们需要在听时将其转录。当他们的转录员朋友已经参加过测试,并将其电邮给他们的朋友以便跳过它时,复制和粘贴问题就出现了。

最佳回答

You might not be able to "disable paste" as such (without hosting the Flash control somehow yourself, say, in a Windows app, or in a browser extension of some sort), but you can certainly make a pretty good guess about the way someone s using the app with a little timer-based math. Here s a (super-)rough example of a Flex app illustrating what I mean:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:local="*" creationComplete="this_creationComplete(event)">

    <mx:Script>
        <![CDATA[

            private var timer:Timer;
            import flash.events.Event;

            private function this_creationComplete(event:Event):void
            {
                timer = new Timer(1000);
                timer.addEventListener(TimerEvent.TIMER, timer_tick);
                timer.start();
            }

            private function timer_tick(event:TimerEvent):void  
            {
                var elapsedTimeInMinutes:Number = timer.currentCount / 60;
                var averageWordLength:Number = 4;
                var humanlyPossible:Number = 200;

                var thisPersonsSpeed:Number = (txtTest.text.length / averageWordLength) / elapsedTimeInMinutes;

                if (thisPersonsSpeed > humanlyPossible)
                {
                    txtSpeed.text = "Wait, " + Math.floor(thisPersonsSpeed).toString() +  " words per minute?  This clown is probably cheating.";
                    txtTest.enabled = false;
                    timer.stop();
                }
                else
                {
                    txtSpeed.text = "Currently typing " + Math.floor(thisPersonsSpeed).toString() + " wpm.  Hurry up!  Faster!";
                }
            }

        ]]>
    </mx:Script>    

    <mx:VBox>
        <mx:TextArea id="txtTest" width="600" height="300" />
        <mx:Text id="txtSpeed" />
    </mx:VBox>

</mx:Application>

Essentially, it s just a timer that calculates words per minute; if that number exceeds a certain threshold, the timer stops, and the form disables.

Sure, it s not iron-clad, and if I were implementing it myself, I d layer in some additional timing-oriented safeguards (e.g., stopping the timer after periods of inactivity, etc.), but it should illustrate the point. I m sure there are other solutions, but something simple like this may work out well-enough for you.


Update: A couple of folks have mentioned Event.PASTE, which would work, but doesn t exist in ActionScript 2 / Flash Player 9. Provided you were able to ensure Flash Player 10 and could script in ActionScript 3, that d be another option.

问题回答

I assume since this is a trascription test, you re displaying some source document side by side with a form you want the user to fill in based on said source document. Instead of emptying the clipboard, wouldn t it be easier to prevent them from copying the source document? If the source document is also under the control of your flash object, it should be simple to set it as readonly and unselectable. This has the added benefit of allowing them to copy between form fields, as that may be their normal usage during transcription and allow them to test faster.

Note that no solution like this is ever going to stop someone who is determined and has a little bit of time -- if you re trying to do anything beyond preventing them from cheating on this test, you re getting into DRM territory, which is both very difficult and very futile.

Recently Flash updates have made it tougher to access the clipboard. As a general rule of thumb, programmatic clipboard accesses will often fail to work when not initiated by the user. So, clipboard-clearing code is more likely to work if you place it inside a button call. This really doesn t help you, but it does tell you what is wrong, and why the the thing you are trying to fix cannot be fixed. I d suggest making use of rmeador s suggestion.

If that is not practical, take a screenshot of the text and use a graphic for the text. Someone stubborn could still copy and paste with a bit of effort, but this is a rather simple way to stop it from being done casually without using a flash form.

Internally to flash, you might want to look into a paste event handler.

Couldn t you register an event handle to capture the past event on the textfield?

function onPasteMessage(event:Event){ ... }

...

myTextField.addEventListener(Event.PASTE, onPasteMessage)

onPasteMessage could either be a simple alert to the user that past is not allowed or something that undoes the paste action depending on when the event is fired and when/how the textfield is modified. Chances are if you capture the event at this level you ll prevent the default eventHandler from copying the text from the clipboard to the textfield.

In the absence of event.paste in earlier versions of flash you could probably set up something like an onKeyUp listener that checked for pressing the V key with the control/command key pressed. I guess it would go something like:

var listening_object = new Object();
Key.addListener(listening_object);
listening_object.onKeyUp(){
  if ( Key.getCode() == whatevercodeforVis && Key.isDown(Key.CONTROL)){
    freakout();
  }
}

Where freakout() did something like clear out the text field or pop up a warning dialog. It wouldn t help for right-click pasting, but you might be able to disable the context menu - you can for most parts of flash but whether it works in text-fields I am uncertain.

Is it completely out of scope to prepare a number of slightly different readings that get randomised at runtime to catch out people who might be inclined to cheat?

 package {  
     import flash.desktop.Clipboard;  
     import flash.desktop.ClipboardFormats;  
     import flash.display.MovieClip;  
     import flash.display.Sprite;  
     import flash.events.Event;  
     import flash.ui.ContextMenu;    
     public class PasteExample extends MovieClip {  

         public function PasteExample():void {  
             //make a movie
             var pasteTarget:Sprite = addChild(new Sprite()) as Sprite;  
             pasteTarget.graphics.beginFill(0);  
             pasteTarget.graphics.drawRect(0, 0, 100, 100); 
             pasteTarget.endFill();

             var contextMenu:ContextMenu = new ContextMenu();  
             contextMenu.clipboardMenu = true;
             contextMenu.clipboardItems.paste = true;  
             pasteTarget.contextMenu = contextMenu;  

             pasteTarget.addEventListener(Event.PASTE,pasteHandler)  
         }  

         private function pasteHandler(e:Event):void {  
             var clipboadStr:String =  Clipboard.generalClipboard.getData(ClipboardFormats.TEXT_FORMAT) as String;  
             trace(clipboadStr)  
         }     
     } 




相关问题
热门标签