剪贴板数据格式

Flash Player 10 和更高版本,Adobe AIR 1.0 和更高版本

剪贴板格式描述了 Clipboard 对象中放置的数据。Flash Player 或 AIR 可在 ActionScript 数据类型和系统剪贴板格式之间自动进行标准数据格式的转换。此外,使用应用程序定义的格式可以在基于 ActionScript 的应用程序内或这些应用程序之间传输应用程序对象。

Clipboard 对象可以包含采用不同格式的同一信息的多种表示形式。例如,表示 Sprite 的 Clipboard 对象可以包括在同一应用程序中使用的引用格式、由在 Flash Player 或 AIR 中运行的另一应用程序使用的序列化格式、由图像编辑器使用的位图格式以及文件列表格式,还可能具有延迟呈示功能以对 PNG 文件进行编码,以便将 Sprite 的表示形式复制或拖动到文件系统。

标准数据格式

ClipboardFormats 类中提供了用于定义标准格式名称的常量:

常量

说明

TEXT_FORMAT

文本格式数据与 ActionScript String 类之间的转换。

HTML_FORMAT

带有 HTML 标记的文本。

RICH_TEXT_FORMAT

RTF 格式数据与 ActionScript ByteArray 类之间的转换。不会以任何方式对 RTF 标记进行解释或转换。

BITMAP_FORMAT

(仅限 AIR)位图格式数据与 ActionScript BitmapData 类之间的转换。

FILE_LIST_FORMAT

(仅限 AIR)文件列表格式数据与 ActionScript File 对象数组之间的转换。

URL_FORMAT

(仅限 AIR)URL 格式数据与 ActionScript String 类之间的转换。

因响应 HTML 内容(在 AIR 应用程序中承载的)中的 copy cut paste 事件而复制和粘贴数据时,必须使用 MIME 类型而不是 ClipboardFormat 字符串。有效的数据 MIME 类型为:

MIME 类型

说明

文本

"text/plain"

URL

"text/uri-list"

位图

"image/x-vnd.adobe.air.bitmap"

文件列表

"application/x-vnd.adobe.air.file-list"

注: 如果事件对象是因为 HTML 内容中的 paste 事件而被调度,则无法从该事件对象的 clipboardData 属性中获得 RTF 格式数据。

自定义数据格式

您可以使用应用程序定义的自定义格式将对象作为引用或序列化副本传输。参考只在同一应用程序中有效。序列化对象可以在应用程序之间传输,但只能用于序列化和取消序列化后仍然有效的对象。如果对象的属性为简单类型或可序列化对象,则通常可以将该对象序列化。

若要将序列化对象添加到 Clipboard 对象,请在调用 Clipboard.setData() 方法时将 可序列化 参数设置为 true 。格式名称可以是标准格式中的某一种或由应用程序定义的任意字符串。

传输模式

使用自定义数据格式将对象写入剪贴板后,可以从剪贴板中将对象数据作为引用读取,也可以将其作为原始对象的序列化副本读取。共有四种传输模式,这些模式确定了对象是以引用还是以序列化副本的形式传输:

传输模式

说明

ClipboardTransferModes.ORIGINAL_ONLY

仅返回引用。如果没有引用,则返回 null 值。

ClipboardTransferModes.ORIGINAL_PREFFERED

如果存在引用,将返回引用。否则返回序列化副本。

ClipboardTransferModes.CLONE_ONLY

仅返回序列化副本。如果没有可用的序列化副本,则返回 null 值。

ClipboardTransferModes.CLONE_PREFFERED

如果存在序列化副本,将返回序列化副本。否则返回引用。

读取和写入自定义数据格式

将对象写入剪贴板时,可将任何不以保留前缀 air: flash: 开头的字符串用于 格式 参数。请使用相同字符串作为读取对象的格式。下面的示例说明了如何从剪贴板读取对象和向其中写入对象:

public function createClipboardObject(object:Object):Clipboard{ 
    var transfer:Clipboard = Clipboard.generalClipboard; 
    transfer.setData("object", object, true); 
} 
function createClipboardObject(object){ 
    var transfer = new air.Clipboard(); 
    transfer.setData("object", object, true); 
}

若要从 Clipboard 对象中提取序列化对象(放置或粘贴操作之后),请使用相同格式名称和 CLONE_ONLY CLONE_PREFFERED 传输模式。

var transfer:Object = clipboard.getData("object", ClipboardTransferMode.CLONE_ONLY); 
var transfer = clipboard.getData("object", air.ClipboardTransferMode.CLONE_ONLY);

此时将始终向 Clipboard 对象添加一个引用。若要从 Clipboard 对象中提取引用(放置或粘贴操作之后)而不是提取序列化副本,请使用 ORIGINAL_ONLY 或 ORIGINAL_PREFFERED 传输模式:

var transferredObject:Object =  
    clipboard.getData("object", ClipboardTransferMode.ORIGINAL_ONLY); 
var transferredObject =  
    clipboard.getData("object", air.ClipboardTransferMode.ORIGINAL_ONLY);

仅当 Clipboard 对象是源自当前应用程序中时,引用才有效。当引用可用时,可使用 ORIGINAL_PREFFERED 传输模式访问该引用;当引用不可用时,则可使用该模式访问序列化副本。

延迟呈现

如果创建数据格式的计算成本高昂,则可以通过提供按需提供数据的函数来使用延迟呈现。仅当放置或粘贴操作的接收方请求延迟格式的数据时才会调用此函数。

呈现函数是通过使用 setDataHandler() 方法添加到 Clipboard 对象中的。该函数必须返回相应格式的数据。例如,如果您调用 setDataHandler(ClipboardFormat.TEXT_FORMAT, writeText) ,则 writeText() 函数必须返回字符串。

如果使用 setData() 方法将同一类型的数据格式添加到 Clipboard 对象,则该数据的优先级高于其延迟版本(不会调用呈示函数)。如果再次访问该同一剪贴板数据,则可能会再次调用或不调用该呈示函数。

注: 在 Mac OS X 上,延迟呈示仅适用于自定义数据格式。使用标准数据格式时,会直接调用呈示函数。

使用延迟呈现函数粘贴文本

下面的示例说明了如何实现延迟呈现函数。

当用户按下“Copy”按钮时,应用程序将清除系统剪贴板以确保不会留下上次剪贴板操作的数据。然后, setDataHandler() 方法将 renderData() 函数设置为剪贴板渲染器。

当用户从目标文本字段的上下文菜单中选择“粘贴”命令时,应用程序将访问剪贴板并设置目标文本。由于已使用函数而不是字符串设置了剪贴板上的文本数据格式,剪贴板将调用 renderData() 函数。 renderData() 函数将返回源文本中的文本,然后将其分配给目标文本。

请注意,如果按下“Paste”按钮前编辑源文本,则此编辑操作将反映到粘贴的文本中,即使按下“Paste”按钮后再进行编辑也是如此。这是因为呈现函数直到按下“Paste”按钮后才会复制源文本。(当在实际的应用程序中使用延迟呈现时,最好以某种方式存储或保护源数据以防止出现此问题。)

Flash 示例

 package {  
    import flash.desktop.Clipboard; 
    import flash.desktop.ClipboardFormats; 
    import flash.desktop.ClipboardTransferMode; 
    import flash.display.Sprite; 
    import flash.text.TextField; 
    import flash.text.TextFormat; 
    import flash.text.TextFieldType; 
    import flash.events.MouseEvent; 
    import flash.events.Event; 
    public class DeferredRenderingExample extends Sprite  
    {  
         private var sourceTextField:TextField; 
        private var destination:TextField; 
        private var copyText:TextField; 
        public function DeferredRenderingExample():void 
        { 
            sourceTextField = createTextField(10, 10, 380, 90); 
            sourceTextField.text = "Neque porro quisquam est qui dolorem " 
                + "ipsum quia dolor sit amet, consectetur, adipisci velit."; 
                 
            copyText = createTextField(10, 110, 35, 20); 
            copyText.htmlText = "<a href='#'>Copy</a>"; 
            copyText.addEventListener(MouseEvent.CLICK, onCopy); 
 
            destination = createTextField(10, 145, 380, 90); 
            destination.addEventListener(Event.PASTE, onPaste); 
        } 
        private function createTextField(x:Number, y:Number, width:Number, 
                        height:Number):TextField 
        { 
            var newTxt:TextField = new TextField(); 
            newTxt.x = x; 
            newTxt.y = y; 
            newTxt.height = height; 
            newTxt.width = width; 
            newTxt.border = true; 
            newTxt.multiline = true; 
            newTxt.wordWrap = true; 
            newTxt.type = TextFieldType.INPUT; 
            addChild(newTxt); 
            return newTxt; 
        } 
        public function onCopy(event:MouseEvent):void 
        { 
            Clipboard.generalClipboard.clear(); 
            Clipboard.generalClipboard.setDataHandler(ClipboardFormats.TEXT_FORMAT, 
                            renderData); 
        } 
        public function onPaste(event:Event):void 
        { 
            sourceTextField.text = 
            Clipboard.generalClipboard.getData(ClipboardFormats.TEXT_FORMAT).toString; 
        } 
        public function renderData():String 
        { 
            trace("Rendering data"); 
            var sourceStr:String = sourceTextField.text; 
            if (sourceTextField.selectionEndIndex > 
                     sourceTextField.selectionBeginIndex) 
            { 
                return sourceStr.substring(sourceTextField.selectionBeginIndex, 
                                    sourceTextField.selectionEndIndex); 
            } 
            else 
            { 
                return sourceStr; 
            } 
        } 
    } 
}

Flex 示例

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="326" height="330" applicationComplete="init()"> 
    <mx:Script> 
    <![CDATA[ 
    import flash.desktop.Clipboard; 
    import flash.desktop.ClipboardFormats; 
     
    public function init():void 
    { 
        destination.addEventListener("paste", doPaste); 
    } 
 
    public function doCopy():void 
    { 
        Clipboard.generalClipboard.clear(); 
        Clipboard.generalClipboard.setDataHandler(ClipboardFormats.TEXT_FORMAT, renderData); 
    } 
    public function doPaste(event:Event):void 
    { 
        destination.text = Clipboard.generalClipboard.getData(ClipboardFormats.TEXT_FORMAT).toString; 
    } 
     
    public function renderData():String{ 
        trace("Rendering data"); 
        return source.text; 
    } 
    ]]> 
    </mx:Script> 
    <mx:Label x="10" y="10" text="Source"/> 
    <mx:TextArea id="source" x="10" y="36" width="300" height="100"> 
        <mx:text>Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit.</mx:text> 
    </mx:TextArea> 
    <mx:Label x="10" y="181" text="Destination"/> 
    <mx:TextArea id="destination"  x="12" y="207" width="300" height="100"/> 
    <mx:Button click="doCopy();" x="91" y="156" label="Copy"/> 
</mx:Application>