2007年1月26日 星期五

Flash 8 ExternalInterface.addCallback Bug   [+/-]

Ticore's Blog

Flash 8 新增的 ExternalInterface Class
專門用來與外部環境溝通
比以前的 fscommand、GetProperty、....等好用得多
不過有一個 Bug 可能會讓瀏覽器,或是其它嵌入 Flash Movie 的應用程式當掉

執行環境與條件:

Flash Player main version:8, 9
SWF version:8, 9
ActionScript version:1.0, 2.0
Player type:ActiveX, Plugin
OS:Windows XP, Windows VISTA, Linux
Browser:Firefox, IE6, IE7

在一個 MovieClip Frame Action 或是 onClipEvent 上
呼叫 ExternalInterface.addCallback 註冊 callback function
然後將該 MovieClip 加到 _root timeline frame 1
在 _root timeline 建立關鍵影格 frame 2 並加上 frame action : stop();
於 frame 2 移除該 MovieClip

這樣 Flash Movie 便會停在 frame 2
此時外部環境 JavaScript 呼叫先前註冊過的 function
便會讓瀏覽器或是應用程式當掉

ActionScript 1.0 ExternalInterface Bug Demo Code:

onClipEvent (load) {
 import flash.external.*;
 var callByJs = function () {
  trace("callByJs");
 };
 ExternalInterface.addCallback("callByJs",null,callByJs);
}

JavaScript Code:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ExternalInterface Crash Demo</title>
<script type="text/javascript">

var isInternetExplorer = navigator.appName.indexOf("Microsoft") != -1;

function doCallAS() {
 var crashMovie = isInternetExplorer ? document.all.crashMovie : document.crashMovie;
 crashMovie.callByJs();
}

</script>
</head>
<body>
<p>
  <input type="submit" name="button" id="button" value="JS call AS" onClick="doCallAS();" />
</p>
<p>
  <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
      codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,28,0"
      width="300" height="200" id="crashMovie">
    <param name="movie" value="ExternalCrashDemo.swf" />
    <param name="allowScriptAccess" value="always" />
    <embed src="ExternalCrashDemo.swf" width="300" height="200"
      pluginspage="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash"
      type="application/x-shockwave-flash" name="crashMovie"
      allowscriptaccess="always"></embed>
  </object>
</p>
</body>
</html>

ExternalInterface Crash Bug Demo Page

以上的 Bug 至少會在以下 Flash Player 版本發生:
Flash Player 8.0.33.0
Flash Player 9.0.115.0
Flash Player 9.0.124.0
Flash Player 10.0.12.10
Flash Player 10.0.22.87

Read more...

2007年1月21日 星期日

ActionScript BitmapData.draw TextField Bug   [+/-]

Ticore's Blog

問題描述:

使用 BitmapData.draw 繪制 TextField 點陣圖資料
該 TextField 使用非嵌入字體
且 draw 方法的 blendMode 參數非為 "normal"

同時使用者用滑鼠拖動應用程式視窗
或是打開應用程式控制選單(application control menu)
或是調整視窗大小
會造成該 Flash Movie 所在執行應用程式 (Flash Player、Browser、Flash IDE)
執行發生錯誤而終止

 

執行環境與條件:

ActionScript Version:1、2、3
SWF Version:8、9
Flash Player Version:8、9
Player Mode:StandAlone、Plugin、ActiveX、External
Browser:IE、Firefox
OS:Windows XP SP2 cht

 

ActionScript 2 Bug Demo:

import flash.display.*;
import flash.geom.*;

var root:MovieClip = this;
var txt:TextField = root.createTextField("txt", root.getNextHighestDepth(), 100, 50, 100, 100);

var bmp:BitmapData = new BitmapData(txt._width, txt._height, true, 0);
root.attachBitmap(bmp, root.getNextHighestDepth());

root.onEnterFrame = function() {
 bmp.draw(txt, new Matrix(1, 0, 0, 1), null, "add");
}; 

ActionScript 3 Bug Demo:

package {
 import flash.display.*;
 import flash.text.*;
 import flash.utils.*;
 import flash.geom.*;
 public class Main extends MovieClip {
  public var txt:TextField;
  public var bmp:BitmapData;
  public function Main () {
   txt = new TextField();
   txt.x = 100;
   txt.y = 50;
   txt.width = 100;
   txt.height = 100;
   bmp = new BitmapData(txt.width, txt.height, true, 0);
   setInterval(doDraw, 100);
  }
  public function doDraw () {
   bmp.draw(txt, new Matrix(1, 0, 0, 1), null, "add");
  }
 }
}
// Ticore's Blog - http://ticore.blogspot.com/

該 Bug 在以下版本 Windows Flash Player 測試會發生
Flash Player 9.0.15.0
Flash Player 9.0.16.0
Flash Player 9.0.28.0
Flash Player 9.0.45.0
Flash Player 9.0.47.0
Flash Player 9.0.60.120
Flash Player 9.0.60.235
Flash Player 9.0.64.0
Flash Player 9.0.115.0
Flash Player 9.0.124.0
Flash Player 9.0.159.0

相關連結:
Flash Player TextField Render Bug

Read more...

2007年1月19日 星期五

Adobe Flash Media Encoder 測試版出來了   [+/-]

Ticore's Blog

Adobe Flash Media Encoder 測試版出來了!

支援 VP6 Codec Live Encoding
可以擷取 Camera 視訊來源
發佈到 Flash Media Server 或是存成 *.flv
Read more...

2007年1月14日 星期日

Flex 2 Bindable Metadata Tag 背後實際作用   [+/-]

Ticore's Blog

Flex 有一個很方便的功能 - Data Bind
很容易可以做到資料綁定的功能

對於 AS3 Class 加上 [Bindable] metadata tag
便可以對該 Class 資料成員賦予 Data Bind 能力

以下利用 flash.utils.describeType 觀察 Bindable 對 Class 實際的影響

加上 [Bindable] 之前:

package idv.ticore {
 public class MyClass {
  public var name:String;
 }
}
// Ticore's Blog - http://ticore.blogspot.com/

describeType(MyClass) output:

<type name="idv.ticore::MyClass" base="Class" isDynamic="true" isFinal="true" isStatic="true">
  <extendsClass type="Class"/>
  <extendsClass type="Object"/>
  <accessor name="prototype" access="readonly" type="*" declaredBy="Class"/>
  <factory type="idv.ticore::MyClass">
    <extendsClass type="Object"/>
    <variable name="name" type="String"/>
  </factory>
</type>

加上 [Bindable] 之後:

package idv.ticore {
 [Bindable]
 public class MyClass {
  public var name:String;
 }
}

describeType(MyClass) output:

<type name="idv.ticore::MyClass" base="Class" isDynamic="true" isFinal="true" isStatic="true">
  <extendsClass type="Class"/>
  <extendsClass type="Object"/>
  <accessor name="prototype" access="readonly" type="*" declaredBy="Class"/>
  <factory type="idv.ticore::MyClass">
    <extendsClass type="Object"/>
    <implementsInterface type="flash.events::IEventDispatcher"/>
    <accessor name="name" access="readwrite" type="String" declaredBy="idv.ticore::MyClass">
      <metadata name="Bindable">
        <arg key="event" value="propertyChange"/>
      </metadata>
    </accessor>
    <method name="addEventListener" declaredBy="idv.ticore::MyClass" returnType="void">
      <parameter index="1" type="String" optional="false"/>
      <parameter index="2" type="Function" optional="false"/>
      <parameter index="3" type="Boolean" optional="true"/>
      <parameter index="4" type="int" optional="true"/>
      <parameter index="5" type="Boolean" optional="true"/>
    </method>
    <method name="hasEventListener" declaredBy="idv.ticore::MyClass" returnType="Boolean">
      <parameter index="1" type="String" optional="false"/>
    </method>
    <method name="willTrigger" declaredBy="idv.ticore::MyClass" returnType="Boolean">
      <parameter index="1" type="String" optional="false"/>
    </method>
    <method name="dispatchEvent" declaredBy="idv.ticore::MyClass" returnType="Boolean">
      <parameter index="1" type="flash.events::Event" optional="false"/>
    </method>
    <method name="removeEventListener" declaredBy="idv.ticore::MyClass" returnType="void">
      <parameter index="1" type="String" optional="false"/>
      <parameter index="2" type="Function" optional="false"/>
      <parameter index="3" type="Boolean" optional="true"/>
    </method>
  </factory>
</type>

可以發現在編譯過程中,MyClass 自動實做了 flash.events::IEventDispatcher 介面
加入了四個與事件有關的方法
原本簡單的資料成員的宣告方式
也被改成 getter、setter 的寫法
是用來處理發布屬性改變的事件

假如在一般 ActionScript3 Project 下使用 [Bindable]
則會出現錯誤訊息

Severity and Description Path Resource Location Creation Time Id

  1172: Definition mx.binding:BindingManager could not be found. BindableTest/idv/ticore MyClass.as line 1 1168754444078 138
  1172: Definition mx.binding:BindingManager could not be found. BindableTest/idv/ticore MyClass.as line 1 1168754444078 143
  1172: Definition mx.core:IPropertyChangeNotifier could not be found. BindableTest/idv/ticore MyClass.as line 1 1168754444078 137
  1172: Definition mx.core:IPropertyChangeNotifier could not be found. BindableTest/idv/ticore MyClass.as line 1 1168754444078 142
  1172: Definition mx.events:PropertyChangeEvent could not be found. BindableTest/idv/ticore MyClass.as line 1 1168754444078 139
  1172: Definition mx.events:PropertyChangeEvent could not be found. BindableTest/idv/ticore MyClass.as line 1 1168754444078 144
  1172: Definition mx.utils:ObjectProxy could not be found. BindableTest/idv/ticore MyClass.as line 1 1168754444078 136
  1172: Definition mx.utils:ObjectProxy could not be found. BindableTest/idv/ticore MyClass.as line 1 1168754444078 141
  1172: Definition mx.utils:UIDUtil could not be found. BindableTest/idv/ticore MyClass.as line 1 1168754444062 135
  1172: Definition mx.utils:UIDUtil could not be found. BindableTest/idv/ticore MyClass.as line 1 1168754444078 140
  1202: Access of undefined property PropertyChangeEvent in package mx.events. BindableTest/idv/ticore MyClass.as line 4 1168754444078 145

因為缺少 Data Bind 中需要用到的 Class

只要加入 framework library 即可
framework 路徑:${FRAMEWORKS}libsframework.swc

Flex 線上文件:
Using static properties as the source for data binding

相關連結:
Flex 4 Gumbo 雙向資料繫結測試
Flex 技巧 - 將資料綁定封裝起來
Flex - 純手工設定 DataBinding 的方式
Flex 技巧 - BindingManager 使用方式
Flex 技巧 - 觀察 Data Binding 資料變化
Flex Tip - 在 Data Binding 內使用 [...] 運算子
Flex 2.0 - 以 ActionScript 3.0 動態設置 Data Binding

Read more...

2007年1月3日 星期三

Flash 獨立播放器中文路徑問題   [+/-]

Ticore's Blog

Flash 獨立播放器中文路徑問題由來已久
從我開始學 Flash 5 時便存在這問題
最簡單的解決方式,就是不要將檔案放在含有中文路徑的資料夾下
這對於習慣中文命名資料夾的 CD Title 開發人員實在不方便測試

不過我已經很久沒有將 Flash fla 發布獨立播放器(projector)了
最近又拿起來測試,發現新的收穫~~

首先,定義一下獨立播放器的執行方式

執行方式:

  1. 發佈為 *.swf 檔案,透過滑鼠左鍵雙擊檔案,用作業系統內安裝好的 SAFlashPlayer.exe 來執行
  2. 發佈為 *.exe 獨立播放器來執行
  3. 發佈為 *.swf 檔案,透過 dos 命令啟動 SAFlashPlayer.exe 帶入 swf 檔名參數
    e.g. c:> start SAFlashPlayer.exe /中文資料夾/test.swf


雖然 Player Mode 都是 StandAlone,可是其中卻有很大的差異存在

分別用三種方式來測試 ActionScript _url 輸出字串

1.

2.

3.

 

很明顯看得出來,執行方式 2 遇到中文路徑會有問題
可以利用之前提到的方式 Flash Player for Firefox Plugin 本機路徑 Bug
將路徑字串編碼轉回來
但是缺乏判斷是否需要轉換編碼的依據
這方法並不實用

另外一個差異則是根目錄所在位置
執行方式 1、2 都是認定根目錄為所在磁碟根目錄
而執行方式 3 則是認定批次檔所在目錄為根目錄

根據以上結果
執行方式 3,不會遇到中文路徑的問題
同時又可以模擬根目錄的執行環境
頗適合用來作 CD Title 開發測試

假如在 CD Title 內也想用中文資料夾怎麼辦? (不建議這樣做)

很簡單~
將空白的 SAFlashPlayer.exe 複製一份到 CD 內

檔案結構:

┬AUTORUN.INF
├AUTORUN.bat
├SAFlashPlayer.exe
└中文資料夾
└主檔案.swf

AUTORUN.INF:

[autorun]
open=SAFlashPlayer.exe /中文資料夾/主檔案.swf

AUTORUN.bat:

start SAFlashPlayer.exe /中文資料夾/主檔案.swf

測試的時候,執行 AUTORUN.bat 即可

Read more...