Feeds:
文章
迴響

Archive for 2007 年 03 月

MSN SpaceGoogle DocGoogle Blog
Chui-Wen Chiu(Arick)
2007.03.30 建立

今天發現Mike Chambers[1]的文章談到 HTML 中使用 Apollo 功能,將上次寫的 Apollo 使用 Windows 的檔案視窗 改成HTML來測試看看。測試程式如下:
 

application.xml

<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://ns.adobe.com/apollo/application/1.0.M3&quot;
    appId="com.adobe.mesh.HTMLFileExample" version=".4">  
   
      <properties>
            <name>Browse Example</name>
            <description>Browse Example Description</description>
            <publisher>Chui-Wen Chiu</publisher>
            <copyright>http://chuiwenchiu.spaces.live.com</copyright&gt;
      </properties>
      <!– 定義啟始網頁 –>
      <rootContent systemChrome="standard" transparent="false" visible="true">
          fileexample.html
      </rootContent>

</application>

flleexample.html

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>Browse Example</title>
    <script type="text/javascript" src="fileexample.js"></script>
</head>

<body onload="onLoad()" style =’background:#222222′>
    <input type="button" value="Load" onClick="onLoadFileClick();"><br />   
    <input type="button" value="Save" onClick="onSaveFileClick();"><br />   
</body>
</html>

fileexample.js

var apollo = window.runtime;

// 網頁載入完成後觸發該事件
function onLoad(){
    // 設定應用程式視窗尺寸
    window.resizeTo(400,300);
}

// 開啟檔案
function onSaveFileClick(){
    // 取得 File Object,請起始位置為桌面
    var f = apollo.flash.filesystem.File.desktopDirectory;

    // 監聽選取事件
    f.addEventListener(apollo.flash.events.Event.SELECT, onSaveFile);
   
    // 開啟視窗
    f.download(new apollo.flash.net.URLRequest("http://localhost/&quot;), "Untitle.txt");
}

function onSaveFile(e){
    var file = e.target;
    // 只是用來選取檔案而非實際下載,所以直接 Cancel 下載
    file.cancel();

    // 回傳  "file://檔案完整路徑"
    alert( file.url );

    // 回傳檔案名稱
    alert( file.name );
}

// 開啟檔案
function onLoadFileClick(){
    // 取得 File Object,請起始位置為桌面
    var f = apollo.flash.filesystem.File.desktopDirectory;

    // 監聽選取事件
    f.addEventListener(apollo.flash.events.Event.SELECT, onLoadFile);
   
    // 開啟視窗
    f.browse();
}

function onLoadFile(e){
    var file = e.target;

    // 回傳  "file://檔案完整路徑"
    alert( file.url );

    // 回傳檔案名稱
    alert( file.name );

    // 回傳檔案名稱
    alert( file.name );
}

執行結果


 

參考資料:
廣告

Read Full Post »

 
新增/編輯文章時,使用下方的 Embed videos 或內嵌視訊,填上類似下面的語法
<embed src="http://sisimi.pchome.googlepages.com/ClockAnalog.swf"
 quality="high"
 width="412" height="362"
 wmode="transparent"
 type="application/x-shockwave-flash"
 pluginspage="http://macromedia.com/go/getflashplayer"
 flashvars="c=v&v=cfcc053e-cefc-4ae0-a293-680a45141581" >
</embed>

 

Read Full Post »

MSN SpaceGoogle DocGoogle Blog
Chui-Wen Chiu(Arick)
2007.03.29 建立

Apollo 提供的 File 類別可以使用原生的檔案對話視窗來選取檔案,簡單的說就是 File.browse 和 File.download 分別呼叫""和""。測試程式如下:
 
<?xml version="1.0" encoding="utf-8"?>
<mx:ApolloApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
 title="Browse Example"
 backgroundColor="0x222222">
 <mx:Script>
  <![CDATA[
   import mx.controls.Alert;
   import mx.events.IndexChangedEvent;
   import mx.events.DragEvent;
   import mx.containers.Canvas;
   import flash.filesystem.*;
   
   private var file:File;
   public function save():void {
    // 設定起始目錄為桌面
    file = File.desktopDirectory;
    // 監聽選取檔案動作
    file.addEventListener(Event.SELECT, onFileSave);
    // 儲存檔案視窗
    file.download(new URLRequest("http://localhost/"), "Untitle.txt");
   }
   public function onFileSave(e:Event):void {
        // 只是用來選取檔案而非實際下載,所以直接 Cancel 下載
        file.cancel();

        // file.url 回傳  "file://檔案完整路徑"
        mx.controls.Alert.show( file.url );

        // 取得檔名
        mx.controls.Alert.show(file.name);
   }

   public function load():void {
    // 設定起始目錄為桌面
    file = File.desktopDirectory;
     
    // 監聽選取檔案動作
    file.addEventListener(Event.SELECT, onFileLoad);
    // 開啟檔案視窗
    file.browse([new FileFilter("All Files", "*.*")]);
   }
   // 檔案選取的事件處理函數
   private function onFileLoad(e:Event):void {
    // file.url 回傳  "file://檔案完整路徑"
    mx.controls.Alert.show( file.url );

   }

  ]]>
 </mx:Script>
 <mx:VBox left="5" top="5" bottom="5" right="5" horizontalAlign="center">
  <mx:HBox width="100%"  horizontalAlign="center">
   <mx:Button label="Load…" click="load()"  />
   <mx:Button label="Save…" click="save()"  />
  </mx:HBox>
 </mx:VBox>
</mx:ApolloApplication>
執行結果


 

參考資料:

Read Full Post »

Delphi For PHP 初探

Chui-Wen Chiu(Arick)
MSN SpaceGoogle DocGoogle Blog
2007.03.27

測試環境:
1. Windows XP Pro + SP2
2. Delphi For PHP 1.0
3. MySQL 3.23.58

  • Application 架構
    • <?php
              //Includes
              require_once("vcl/vcl.inc.php"); // VCL 底層實作函數庫
              use_unit("forms.inc.php"); // 應用程式基本架構:Application, Frame, Page, Window, …
              use_unit("extctrls.inc.php"); // 延伸 VCL 控制項:Image, FlashObject, GroupBox, Timer, Shape, ….
              use_unit("stdctrls.inc.php"); // 標準 VCL 控制項:Button, CheckBox, Label, Edit, ListBox, …

              //Class definition
              class Unit1 extends Page // 每一頁面都需要繼承 Page
              {
              }

              global $application; // 在 forms.inc.php 中產生  

              global $Unit1;

              //Creates the form
              $Unit1=new Unit1($application); // 將自訂 Page 加入 Application

              //Read from resource file
              $Unit1->loadResource(__FILE__);// Page 讀取 UI 設定 XML 檔, unit.xml.php, 定義在 Component

              //Shows the form
              $Unit1->show(); // 顯示頁面內容,定義在 Control

      ?>

    • 類別階層
      • + Object (system.inc.php)
            + Persistent (classes.inc.php)
                + Component (classes.inc.php)
                    + Control (controls.inc.php)
                    |   + FocusControl (controls.inc.php)
                    |       + ScrollingControl (controls.inc.php)
                    |           + CustomPage (controls.inc.php)
                    |               + Page (forms.inc.php)
                    + Application (controls.inc.php)
  • 顯示資料庫
  • 使用 Data Explorer
    • 透過 UI 設定資料庫連線,如果連線成功將可看到資料庫的所有 Table
    • 將 Table 拉到 Form 上即可,自動產生 Database, Table, DataSource 和 DBGrid
  • 手動使用 Database, Query, Datasource. DBGrid 完成資料庫呈現  
    • 基本上就是將上面方式改成手動設定,Query 取代 Table 元件,透過 Query 元件可以指定查詢條件

  • 在控制項事件中使用 Javascript
  • 透過 Delphi For PHP 開發環境的 Object Inspector | Javascript 設定對應的 Event Handler
  • 此時,Delphi For PHP 會在 *.xml.php 中產生對應的 <property> 如: <property name="jsOnClick">JSClick</property>
  • Code Editor 也會產生對應的區塊,如:
    function JSClick($sender, $params)
    {
    ?>      
            //Add your javascript code here  
            alert( document.getElementById(‘MyButton1’).value);
    <?php
    }

    

  • 前端產生的結果如下:
    function JSClick(event)
    {
    var event = event || window.event;
    var params=null;
            //Add your javascript code here
                   alert( document.getElementById(‘MyButton1’).value);
           
    }
  • 補充:想要透過 Javascript 取得 VCL 元件,透過 document.getElementById 即可取得,Id 即 VCL 的 name。

  • 自訂 VCL假設元件檔案名稱為 unit1.inc.php, unit1.package.php)
    • 建立自訂元件
      1. 選擇 Component | New Component

                    2. Ancestor Type 選擇你要從那一個類別繼承
                    3. Classname 給予一個你的元件名稱
                    4. Palette Page 指定元件放置在那一個分類中
                    5. 將 *.inc.php 複製到 C:Program FilesCodeGearDelphi for PHP1.0vcl
                    6. *.package.php 可以隨意放置
                     

      • 補充:預設 use_unit 會到 C:Program FilesCodeGearDelphi for PHP1.0vcl 搜尋指定的 *.inc.php。如果想要變更目錄,必須修改 unit1.package.php 的 registerComponents("Additional",array("MyButton"),"cwc/unit1.inc.php");,如此, use_unit 就會到 vcl/cwc 下尋找該元件。

    • 建立非視覺化元件
      • 繼承 Component 系列的元件,而不要繼承 Control 系列的元件即可。

    • 新增 Server 端事件
      function FireMyEvent(){
          // 呼叫 Server 端事件,定義在 Component
          $this->callEvent(‘onmyevent’, array($this, 1, 2, 3));
      }

      // 宣告一個事件
      protected $_onmyevent = null;
      function getOnMyEvent()       { return $this->_onmyevent; }
      function setOnMyEvent($value) { $this->_onmyevent = $value; }
      function defaultOnMyEvent()   { return ""; }

    •  新增屬性
  • 將游標移到元件需要加入屬性程式片段的地方,選擇 "Edit | Add New Property "
  • 自行加入 getXXX, setXXX 對應的函數,VCL 會自動產生 XXX 屬性,如下: (此寫法可以讓屬性再屬性視窗中進行設定)
    class MyButton extends Button{
       protected $_v;
       function getXXX(){ return $this->_v;}
       function setXXX($v){ $this->_v = $v; };
    }
  • 屬性的類型
    • 簡單:數值、字串… 等,使用者能夠直接編輯的皆屬此類
    • 列舉:透過下拉選單選擇
    • 物件:表單上得另一個物件
    • 子屬性:一個物件的多個屬性,如:Font.Case, Font.Color, Font.Align, …
    • 陣列:使用特定的編輯器

    • 加入訂定圖示
      • 準備一張 16×16 24BPP 的 BMP 圖檔
      • 將圖檔命名和元件名稱一樣,如:MyButton 類別對應的圖檔為 MyButton.bmp
      • 將圖檔案放置在 unit1.package.php 的 setIconPath() 所指定路徑
      • 安裝 package 即可看到該圖示

   

    • 新增多個元件到已經存在的 Package 中
      • 只需要在 unit1.package.php 多加幾行 registerComponents 即可,如下:
          registerComponents("Additional",array("MyButton"),"unit1.inc.php");
          registerComponents("Additional",array("ArickButton"),"unit2.inc.php");
      • 重新安裝 Package

    • 設定 Package 名稱
      • 修改 unit1.package.php 的 setPackageTitle("System VCL for PHP Components");

    • 新增/移除 Package
      • 使用 Component | Package

   

  • 國際化
    • Delphi For PHP 提供 Internationalization Wizard 來讓你對不同的國家自訂語系,且程式會依據國家的不同將轉換成自訂的語系。Internationalization Wizard 負責的工作有
      a. 收集專案中使用的檔案
      b. 選擇應用程式要針對哪些國家建立對應語系檔
      c. 掃描所有的原始檔並產生相對應的語系檔

      當完成 Internationalization Wizard 的動作後,在專案的目錄下會產生 local 目錄,這個目錄包含各語系檔案。假如你希望元件能夠取用語系檔的文字,必須使用 gettext() 或 _() 取得語系對應文字,如:
      $this->Button=_("Localize this string");

  • 快速鍵
    • Ctrl+J  程式樣板列表
    • F5 新增/移除中斷點
    • F6/Shift+F6 往前/往後移動 Code Editor Tab
    • F9 啟用除錯器執行程式
    • Shift+F9 不啟用除錯器執行程式

已知缺點:
1. 採用類似 ASP.NET 的 Server-Side Control 概念,所有元件的 Event 處理都是 Form Submit 到 Server 端處理後在重新呈現新頁面。
2. 每一次畫面的呈現似乎都需要解析畫面配置的 XML
3. 每一次的元件修改都需要重新安裝 Package
4. 透過 DBGrid 顯示 Big5 的中文資料會亂碼

Read Full Post »

之前一直嘗試想以 meta-programming 的思維寫程式,今天終於想到如何寫了^^
下面是我的 Fibonacci 範例
// VC8
#include <iostream>
template<int n>
struct fac{
 enum{ value= fac<n-1>::value+fac<n-2>::value};
};
 
template<>
struct fac<0>{
 enum {value=1};
};
 
template<>
struct fac<1>{
 enum{value=1};
};
 
int main(){
 std::cout << fac<40>::value << std::endl;  
 return 0;
}

Read Full Post »

MSN SpaceGoogle DocGoogle Blog
Chui-Wen Chiu(Arick)
2007.03.26

摘至 [1] 的問題 1-3,問題描述如下:
以兩個整數陣列 f[] 與 g[],他們的元素經自小到大排列好,而且兩個陣列元素各自不相同;譬如說,f[] 中可能有 1,3, 4, 7, 9,而 f[] 有 3, 5, 7, 8, 10。請寫程式,算出這兩個陣列彼此之間有多少組相同資料。就以上例而言,f[2], g[1] 為3是第一組;f[4], g[3] 為8是第二組。

說明:
我並不期望你用下面的方式來寫作程式
a. 固定 f[i]
b. 對於 f[i] 而言,檢查 g[]中有沒有與 f[i] 相同的元素
c. 處理下一個 f[i],即 f[i+1]

因為 f[] 與 g[] 都以經由小到大排序好,你應該活用這一個很強的特性;好程式員絕對不會用上面的本拙方式寫程式的,因為做了太多無意義的事。
為什麼呢?因為 g[] 的元素都相異,對於 f[i] 而言,最多只會只找一個與他相同的元素,但在會壞的情況下,你得把 g[] 全部查完才曉得這一回事,如果 g[] 有 n  個元素,你得查 n 次,但是若在 f[] 中也有 n 個元素,所以你得把 g[] 查 n 遍,一共做了 n2 個比較才能找出結果。

請試試看能夠找出方法,把 f[] 與 g[] 各查一次就可以找到答案。請記住,活用 f[] 與 g[] 已經自小到大排序好的特性。

我的解法-版本#1


#include <iostream>

template<int len1, int len2, typename T>
int eq_count(T f[], T g[]){
    int count = 0;
    int i = 0;
    int j = 0;
    while(i < len1 && j < len2){
        if (f[i] == g[j]){
            ++count;
            i<len1-1?++i:++j;

            continue;
        }

        if (f[i] < g[j]){
            i<len1-1?++i:++j;       
            continue;
        }

        if (f[i] > g[j]){
            j < len2-1?++j:++i;           
        }
    }

    return count;
}

int main(){
    int f[] = {1, 3, 4, 7, 8, 9, 11, 99, 101};
    int g[] = {1, 3, 5, 7, 8, 10};

    std::cout << eq_count<9, 6>(f, g) << std::endl;
    return 0;
}

參考資料
[1] C 名題精選百則 技巧篇

Read Full Post »

MSN SpaceGoogle DocGoogle Blog
Chui-Wen Chiu(Arick)
2007.03.26

摘至 [1] 的問題 1-2,問題描述如下:
已知f[]與g[]兩個整數陣列,元素都已經至小到大排序好,請寫一個程式算出 f[] 中比 g[] 中元素大的對數。換句話說,f[0] 比 g[]中多少個元素來的大,f[1] 比 g[]中多少個元素來的大等等,這些值得總和就是我們要求答案。

舉個例子,如果 f[] 中有 1,3,5,7,9 而 g[] 中有 2,3,4,7,8。因此比 g[0] 大的有 f[1] 到[4],比g[1]大的有f[2]到f[4],比g[2]大的有f[2]到f[4],比g[3]大的有f[4],比g[4]大的有f[4],所以答案為 4+3+3+1+1 = 13。

我的解法-版本#1

#include <iostream>

template<int len1, int len2, typename T1, typename T2>
int gt_count(T1 f[], T2 g[]){
    int count = 0;
    int pos = 0;
    for(int i = 0; i<len2; ++i){
        for(int j = pos; j<len1; ++j){
            if (g[i] < f[j]){
                count += len1-j;
                pos = j;
                break;
            }
        }
    }

    return count;
}

int main(){
    int f[] = {1, 3, 5, 7, 9};
    int g[] = {2, 3, 4, 7, 8};
   
    std::cout << gt_count<5, 5>(f, g) << std::endl;
    return 0;
}

參考資料
[1] C 名題精選百則 技巧篇

Read Full Post »

Older Posts »