カテゴリー別アーカイブ: その他

非同期ホストプロセス呼び出しAPI

※v8.0からサポートされました。

非同期ホストプロセス呼び出しAPI が追加されました。
ホスト固有のコマンドまたはシェルコマンドを子プロセスで起動し、
コマンドまたはシェルの起動や終了をイベントで検出することが
できるようになります(特権アプレットのみ)。

async-spawn-host-process
プロシージャが追加されました。
指定されたホスト固有のコマンドを子プロセスで起動し、バックグラウンドプロセスにハンドルを返す既存プロシージャ spawn-host-process の非同期バージョンです。
引数は以下のように定義されています。

||子プロセスで起動される実行可能ファイル。実行可能ファイルは、ローカル ファイル システムの Url として、またはローカル ファイル名を含んでいる String として指定される可能性があります。
executable
||コマンドのパラメータが格納されます。パラメータは、StringArray に格納された 0 個以上の引数として指定されます。
args
||HostProcessEvent を受け取る EventHandler で、少なくとも一つは指定する必要があります。イベントの HostProcessCreatedEvent と HostProcessExitedEvent を参照してください。
event-handler…
||このパラメータが null でない場合、このパラメータには、コマンドの明示的なホスト環境が含まれていなければなりません。このパラメータが NULL の場合は、子プロセスが既存のホスト環境を継承します。
host-environment
||このパラメータが true に設定されている場合は、リターンされた HostProcess から子プロセスの標準入力を取得できます。
write-stdin?
||この引数が true に設定されている場合は、リターンされた HostProcess から子プロセスの標準出力を取得できます。
read-stdout?
||この引数が true に設定されている場合は、リターンされた HostProcess から子プロセスの標準エラーを取得できます。
read-stderr?
||この引数を true に設定した場合、コンソール モードが実行可能であっても生成される HostProcess はコンソール ウィンドウなしで実行されます。
suppress-console-window?

戻り値: 子プロセスとのやりとりに使用される可能性がある HostProcessを返します。

async-spawn-host-shell プロシージャが追加されました。
指定されたホスト固有のシェルコマンドを子プロセスで起動し、バックグラウンドプロセスにハンドルを返す既存プロシージャ spawn-host-shell の非同期バージョンです。
引数は以下のように定義されています。

||1つの String として引数を含む、実行対象のコマンド。
command
||HostProcessEvent を受け取る EventHandler で、少なくとも一つは指定する必要があります。
event-handler
||このパラメータが null でない場合、このパラメータには、コマンドの明示的なホスト環境が含まれていなければなりません。このパラメータが NULL の場合は、子プロセスが既存のホスト環境を継承します。
host-environment
||このパラメータが true に設定されている場合は、リターンされた HostProcess から子プロセスの標準入力を取得できます。
write-stdin?
||この引数が true に設定されている場合は、リターンされた HostProcess から子プロセスの標準出力を取得できます。
read-stdout?
||この引数が true に設定されている場合は、リターンされた HostProcess から子プロセスの標準エラーを取得できます。
read-stderr?
||この引数を true に設定した場合、コンソール モードが実行可能であっても生成される HostProcess はコンソール ウィンドウなしで実行されます。
suppress-console-window?

戻り値: 非同期ホストプロセスを制御することができる AsyncHostProcessWorker を返します。

async-spawn-host-shell, async-spawn-host-processに、以下のイベントを処理するイベントハンドラを渡し、起動や終了を検出して処理を記述することができます。

||ホストプロセスの生成に失敗すると exceptionアクセサ からnull以外の値が戻ります。
HostProcessCreatedEvent:
||終了コードをexit-statusアクセサから取得できます。
HostProcessExitedEvent:

以下は、Windowsのverコマンドを、同期プロシージャと非同期プロシージャのそれぞれで五回連続して呼び出すサンプルです。

http://developers.curlap.com/curl/v8/async-host-procsee.curl

Curl RTEの主な新機能(v8.0.0)

Curl RTEの主な新機能(v8.0.0)を紹介致します。

Decimal型サポート

SimpleDateTimeAxis のサポート

AppletDataを用いたデバッグ

Activeドキュメントコンテナ

SHA-2を用いたメッセージダイジェスト出力

マルチタッチとジェスチャーAPI

IPv6

HTTP only cookie

・印刷機能の強化

PDF 出力

システム起動時の Curl RTE スタートアップ

国際化ドメイン名

truncate/floor/ceiling/round

非同期ホストプロセス呼び出しAPI

truncate/floor/ceiling/round

 ※v8.0からサポートされました。

truncate および floor に、符号なし整数(uint32 と uint64)を指定することが可能となりました。

 

{curl 8.0 applet}
{curl-file-attributes character-encoding = “utf8”}

{let u32:uint32 = 4294967295}
{let u64:uint64 = 18446744073709551615}

{value
    {VBox
        {truncate u32 ,2},
        {truncate u64 ,2}
    }
}

 

 http://developers.curlap.com/curl/v8/trunc_floor.curl

 

システム起動時の Curl RTE スタートアップ

 ※v8.0からサポートされました。

システム起動時に Curl RTE がスタートアップするようになりました。これはCurl コントロールパネルで切りかえることができます。

また、従来のバージョンではアプレットが実行されていない場合はRTEを自動でシャットダウンされていましたが、このオプションを利用することで手動でシャットダウンするまでRTEが実行されます。

startup2.jpg

国際化ドメイン名

 ※v8.0からサポートされました。 

国際化ドメイン名 (IDN) をサポートするプロシージャが追加されました。

 

ソース

{curl 8.0 applet}
{curl-file-attributes character-encoding = “utf8”}

{let asi:String =  “idn-hostname-to-ascii   日本語.jp          result is :” & {idn-hostname-to-ascii “日本語.jp”}}
{let uni:String =  “idn-hostname-to-unicode xn--wgv71a119e.jp result is :” & {idn-hostname-to-unicode “xn--wgv71a119e.jp”}}
{let vb:VBox = {VBox asi,uni}}
{value
    vb
}

実行結果idn.jpg

 

 


サンプル

 http://developers.curlap.com/curl/v8/idn2.curl

 

 

VLE機能拡張:オートコンプリート

Advanced UIで提供されているオートコンプリートのAPIを利用して、VLEで利用できるようにしました。

まずは以下のファイルをダウンロードしてください。

vle-auto-complete.zip

ファイルを適当な場所に配置して解凍すると、以下のファイルが格納されています。

  •  autocomplete.gif
  •  autocomplete_blue.gif
  •  autocomplete_red.gif
  •  autocomplete_s.gif
  •  autocomplete_s_blue.gif
  •  autocomplete_s_red.gif
  •  AUTOCOMPLETE.scurl
  •  vle-auto-complete.scurl

次にCurl IDEを起動し、「ツール」から「ビジュアル レイアウト エディタ」を選択します。するとVLEが起動しますので、「表示」⇒「パレット機能拡張」を選択してください。すると「パレット機能拡張」というダイアログが表示されますので、『新規』ボタンを押下して、上記のvle-auto-complete.scurlを選択します。選択すると、以下のように一覧にファイルが追加されます。

vle-autocomplete-1.jpg

 

 

 

 

 

 

 

 

 

 

この状態でVLEでファイルの新規作成を行うと、以下のように「Developer Center」のタブが追加され、オートコンプリートの機能を持つ3種類のAPIがアイコンとして表示されます。

vle-autocomplete-2.jpg

 

 

 

 

 

 

 

 

 

 

これらの部品の機能は、以下の通りです。

AutoCompleteTextField

入力補完の機能を持つテキストフィールドです。入力候補となる文字列は自分で指定することが出来ます。

AutoCompleteComboBox

入力補完の機能を持つコンボボックスです。基本的な機能はAutoCompleteTextFieldと同様ですが、右側のプルダウンより入力候補を選択することが出来ます。

ReminderAutoCompleteTextField

入力履歴を記憶し、入力候補として表示するテキストフィールドです。テキストフィールドに名前をつけることにより、入力欄を識別することが可能です。

これらの部品を画面上に配置するとこれらの部品をパッケージに含むAUTOCOMPLETE.scurlがプロジェクトにコピーされ、追加されます。

注意

一度VLEにファイルを追加した後、vle-auto-complete.scurlとAUTOCOMPLETE.scurlのファイルを削除しないでください。また、VLE拡張機能はCurl Pro/IDEでのみ使用することができます。

 

アプレット終了時の処理

 

アプレット終了時もしくは一時停止時になんからの処理を行いたい場合、register-exit-proc(終了時)もしくはregister-suspend-proc(一時停止時)というプロシージャを利用します。

このプロシージャは、終了時に実行させたい処理(プロシージャ)を登録することができます。アプレット終了時に複数の処理が登録されている場合は、登録時とは逆の順番で実行されます。

以下はサンプルです。

{curl 6.0 applet}

{value
    def p =
        {proc {}:void
            {output “終了!”}        
        }
    {register-exit-proc p}
   
    {HBox background = “red”}
}

実行し、×ボタンなどで終了させますと、コンソールに”終了!”という文字が表示され、終了します。

逆に登録したものを削除する場合は、unregister-exit-procもしくはunregister-suspend-procプロシージャを利用します。

APIリファレンス

 

Curlランタイムの起動と停止

surge-doというコマンドで、Curlのラインタイムの起動や停止などいろいろ操作することができます。そこでsurge-doコマンドのオプションの一部を紹介したいと思います。

Curlランタイム起動

> surge-do –start

Curlランタイムの停止

> surge-do –quit

Curlランタイムの強制終了

> surge-do –quit-force

コントロールパネルの表示

> surge-do –show-manager

コンソールにデータ出力(以下の例ではコンソールにABCと出力されます。)

> surge-do –output ABC

ブラウザの起動及びサイト表示 

> surge-do –browse http://www.curlap.com

ブラウザの起動及びサイト表示 (新しいブラウザ)

> surge-do –browse-new http://www.curlap.com

 

 

 

 

 

emacsでCurl

Curlをemacsで利用する方法を記載します。

Curl IDEをインストールしますと、Curlインストールディレクトリに標準でelファイルがインストールされます。(無料IDEでも存在します。)

(Windowsの場合)
…./Curl Corporation/Surge/7/ide/share/emacs/site-lisp/curl.el

このファイルをロードしますとemacsでCurlが利用することができるようになります。

 

Curlでスクリプトの作成

Curlでは、dcurlやcurlのようなアプレット以外に、スクリプトと作成して実行することができます。これにはcurl.exeを利用して、コマンドラインからスクリプトを実行します。以下にサンプルを紹介します。

{curl 6.0 script}

{do
    let v:int = 0
    {for arg in script-args do
        set v = v + {arg.to-int}
    }
    {output v}
}

スクリプトとして作成するにはヘラルドにappletではなくscriptと記載し、ファイル名の拡張子を.xcurlとします。(ここではrun.xcurlで保存しています。)

また、コマンドラインの引数をCurlで受け取るにはscript-args変数で受け取ることができます。上記サンプルでは引数で指定した値をすべて加算するものです。例えば、以下のように実行します。 

“c:\Program Files\Curl Corporation\Surge\7\bin\curl.exe” run.xcurl 1 2 3 4

実行結果

10

 

よく出るエラーの種類と回避方法

ここでは、Curlを利用し始めた時に経験しがちなエラーとその解決方法を説明します。


メッセージ

コンテンツが、システムにインストールされていない Curl API の次のバー ジョンの 1 つを必要としています。このコンテンツを表示するには、バー ジョンのサポートに必要なコンポーネントをダウンロードし、インストールする必要があります:

原因と解決策

実行使用としたCurlアプレットに対応するCurlRTE(ランタイム)がインストールされていないことによります。対応するCurlRTEを入手しインストールしてください。


メッセージ

アプレット’http://****’をロードできませんでした。SyntaxError’http://****’規定のマニフェストをインポートできません。
SecurityException:非特権状態のアプレットは、ローカルファイル’http://****’を読み取ることは出来ません。このメッセージはアプレット内のエラーによるものです。

原因と解決策

ローカルファイルの読み込みという”特権”設定が必要な操作を行おうとしています。アプレットを信用する場合は、Curlコントロールパネルから”セキュリティタブ”を選択し、当該アプレットのホストを追加してください。


メッセージ

Error: ‘http://xxx/start.curl’
アプレットはライセンス キーを取得できません。 HttpMissingFileException:
‘http://xxx/curl-license-4.dat’ を開いている間のステータスは 404 です。

原因と解決策

Curlサーバーライセンスが正しく配置されていません。ライセンスファイルを配置してください。その後IEのキャッシュファイルをクリアし、CurlRTEが起動している場合は終了した後に、アプレットを再度実行してください。

 


 

症状

アプレットを実行するとブラウザにCurlのソースコードが表示されてしまう。

原因と解決策

原因は二つ考えられます。

  1. WebサーバーにcurlのMIMEタイプが登録されていない。
  2. CurlRTE(もしくはIDE)をインストールした後に、ブラウザをインストールした。

1の場合は、Webサーバーのマニュアルを参照してMIMEを設定してください。詳細は、Curl開発者ガイドの「Webサーバーの構成」の「CurlファイルソースのMIMEタイプ」をご覧ください。

2の場合は、再度CurlRTE(もしくはIDE)をインストールし直すことで解決します。


メッセージ

SyntaxError:xxx/yyy/start.curl規定のマニフェストをインポートできません
アプレットはライセンスキーを取得できない
HTTP Permisshon Denied File exceptionHTTP://xxx/curl-licence-5.datを開いてる間のステータスは403です。
HTTP Permisshon Denied Fileexception
HTTP://xxx/curl-licence-5.datを開いてる間のステータスは403です。

原因と解決策

ライセンスファイル(curl-licence-5.dat)に対してアクセス許可が与えられていません。アクセス権を変更してください。


メッセージ

Error: ‘any’ から暗黙的キャストは禁止(または不正使用)されています。 この作業を行う場合は、このコードを ‘{with-compiler-directives allow-implicit-any-casts? = true do <ユーザーコード>}’ でラップし、コンパイラのディレクティブをオーバーライドする必要があります。

原因と解決策

start.curlやload.scurl等のアプレット宣言部分に下記のように{compiler-directives careful? = true}が宣言されており、
{applet manifest = “manifest.mcurl”,
{compiler-directives careful? = true}
}

かつ、変数の宣言時に let aaa = xxxxのように型を宣言していないことが原因だと思われます。

対応としては、
・ アプレット宣言部分を次のように変更する: {applet manifest = “manifest.mcurl”} (compiler-directives careful? = true をはずす。)
・ let  で宣言している部分には必ず型を指定する。
・ def で宣言する

 

Ajax連携(JavascriptからCurlのメソッドをコール)

Curl6.0からAjax相互運用性という機能が追加されました。これはJavascriptからCurlのメソッドをコールしたり、またはその逆でCurlからJavascriptの関数をコールすることができます。この機能を用いれば、GoogleMapのAPIをコールしてGoogleMapと組み合わせたアプリケーションなどを作成することができます。この機能をサンプルコードを元に説明していきます。

JavascriptからCurlのメソッドをコールする

Javascriptから、sharp.curlというCurlアプレットの中にあるMySharpクラスのchange-colorメソッドを実行するという例を紹介していきます。

まずは、Curl側のサンプルコード(sharp.curl)から説明していきます。以下のサンプルは、単純にRectangleSharpクラスを継承して四角形の図を表示するMySharpクラスを作っています。そのMySharpクラスの中に色を変更するchange-colorメソッドを作成し、このメソッドを後述するJavascriptから呼び出すこととします。

また、このオブジェクトを生成した後、Javascriptから実行可能なオブジェクトとして登録するために、自アプレットのハンドラとして登録する必要があります。これにはregister-applet-invoke-handlerメソッドを利用します。この行が存在しませんとJavascriptから実行することはできません。

{curl 6.0 applet}

{import * from CURL.GUI.SHAPES}

{define-class MyShape
  {inherits RectangleShape}
 
  {constructor {default …}
    {construct-super …}
  }
 
  {method public {change-color color:String}:#String
    set self.color = color
    {return “changed-color”}
  }
}
 
{value
    let shape =
        {MyShape
            {GRect 1cm, 1cm, 1cm, 1cm},
            color = “orange”,
            border-color = “silver”,
            border-width = 5px
        }
   
    {{get-the-applet}.register-applet-invoke-handler
        {Applet.applet-invoke-handler-for-object shape},
        || Allow ANY page to host this applet and send it commands.
        verifier = {proc {}:bool {return true}}
    }
   
    shape
}

次にHTML側を説明します。まずは、CurlのアプレットをHTML内に埋め込む場合は、objectタグを利用します。objectタグをサポートしていないブラウザの場合は、embedを利用します。

<object id=”shape” type=”text/vnd.curl”
  data=”sharp.curl” height=”200″ width=”200″>
</object>

このJavascriptオブジェクトのapplet_invoke関数を使って先ほど登録したCurlオブジェクトのメソッドを呼びます。 

var shape = document.getElementById(“shape“);
shape.applet_invoke(“change-color”, color);

また、その他に用意されているJavascriptオブジェクトの関数・フィールドとして、Curlアプレットの呼び出し準備が整っているか否かをチェックするためのapplet_invoke_readyフィールドと、アプレットの呼び出し準備が整った際に実行されるapplet_invoke_ready_callback関数があります。具体的な使い方を見せるためにすべてのコードを以下に載せておきます。

<html><head><title>Javascript sample</title>

<script type=”text/javascript”>

// change color
function changeColor(color) {
  var shape = document.getElementById(“shape”);
  if (shape.applet_invoke_ready)
  {
    alert(shape.applet_invoke(“change-color”, color) + ‘ to ‘ + color);
  }
  else
  {
    alert(“not ready”);
  }
}

function onLoad()
{
  var shape = document.getElementById(“shape”);
  shape.applet_invoke_ready_callback =
      function() {
          if (!shape.applet_invoke_ready)
          {
              alert(“not ready!”);
          }
      };
};

</script></head>
<body onload=”setTimeout(‘onLoad()’, 0)”
  onpageshow=”if (event.persisted) setTimeout(‘onLoad()’, 0);”>
<object id=”shape” type=”text/vnd.curl”
  data=”sharp.curl” height=”200″ width=”200″>
</object>

<p>
Color
<select id=”color” onchange=”changeColor(value)”>
  <option value=”red”>red</option>
  <option value=”orange” selected=”selected”>orange</option>
  <option value=”yellow”>yellow</option>
  <option value=”pink”>pink</option>
  <option value=”lightsalmon”>lightsalmon</option>
  <option value=”orchid”>gray</option>
</select>
</p><p>

</p></body></html>

CurlからJavascript関数をコールする

CurlからJavascriptの関数を呼び出す場合、AppletDataクラスのapplet-invoke-asyncメソッドを実行します。以下に呼び出し方のサンプルコードを載せておきます。

let ad:AppletData = {AppletData …}
{ad.applet-invoke-async
    finish-proc =
        {proc {ex:#Exception, result:any}:void
             || 終了処理
        },
    “change-color”,  || 呼び出すjavascriptの関数
    “green”         || 呼び出すJavascriptの関数の引数
}

 

関連サンプル

GoogleMapと組み合わせたサンプルはCurlをインストールすると、以下のディレクトリに提供されます。(等サンプルはLinuxやMAC版も同様にも含まれています。)

C:\Program Files\Curl Corporation\Surge\7\docs\default\examples\dguide\subapplets.zip

 

バックグラウンドでアプレットを実行

表示されている画面(アプレット)とは別にバックグラウンドで動くアプレットの作成方法をここでは紹介していきます。これにはCurlのサブアプレット機能を利用します。ここでは、バックグラウンドでタイマーを使い定期的に何か処理をするプログラムの起動・停止例を紹介します。

まずは、呼び出し側(ここではparent.curl)とバックグラウンド実行する側(ここではchild.curl)との2つの.curlファイルを用意します。child.curlの中には、以下のように通常のクラスを用意します。

{define-class public Child

  field displayed-string:String
  field private timer:Timer

  {constructor public {default}
    set self.displayed-string = “child”
    set self.timer =
        {Timer
            enabled? = false,
            interval = 1s,
            {on TimerEvent do
                {output self.displayed-string}
            }
        }
  }

  {method public {start}:void
    {self.timer.enable}
  }

  {method public {change-displayed-string str:String}:void
    set self.displayed-string = str
  }

  {method public {stop}:void
    {self.timer.disable}
  }
}

このファイルの中で、上記クラスのオブジェクト(Child)を以下のようにregister-applet-invoke-handlerを登録することで、親側から子供側のメソッドを呼び出すことができます。

{{get-the-applet}.register-applet-invoke-handler
    {Applet.applet-invoke-handler-for-object {Child}},
    verifier = {proc {}:bool {return true}}
}

次にparent.curlでは、AppletDataを継承したクラスを作成し、child.curlを引数に指定して、そのクラスのオブジェクトを生成します。このオブジェクト(child)に対して、child.curl内のChildクラスのメソッドを実行します。メソッドを実行する際には、applet-invokeもしくはapplet-invoke-asyncを利用します。ここではバックグラウンドで実行させておきたいので、applet-invoke-asyncを利用します。 

{child.applet-invoke-async
    finish-proc = {proc {ex:#Exception, result:any}:void},
    “start” || startメソッドで、タイマー開始
}

実行結果

child
child
child

サポートバージョン

RTE 6.0以上

サンプルコード

画面なしサブアプレットのサンプル

 

コマンド実行

Curlでコマンドを実行する方法を説明します。Curlでコマンドを実行するには、spawn-host-processもしくはspawn-host-shellプロシージャを利用します。ここではpingコマンドを実行する例を紹介します。

{curl 6.0 applet}

{import * from CURL.RUNTIME.HOST-PROCESS}

{value
    def host-process =
        {spawn-host-process 
            read-stdout? = true,
            read-stderr? = true,
            “ping”,
            {StringArray “www.curlap.com“}
        }
    {with-open-streams stream = {host-process.read-open-stdout} do
        {while not stream.end-of-stream? do
            {output {stream.read-line}}
        }
    }
}

spawn-host-processプロシージャの引数にコマンド名(もしくはコマンドのURL)をセットし、引数をStringArrayで渡します。結果はHostProcessクラスのread-open-stdoutメソッドにて標準出力をTextInputStreamにて受け取ることができます。

実行結果

Reply from xxx.xxx.xxx.xxx: bytes=32 time=9ms TTL=48

Reply from xxx.xxx.xxx.xxx: bytes=32 time=9ms TTL=48

Reply from xxx.xxx.xxx.xxx: bytes=32 time=9ms TTL=48

Reply from xxx.xxx.xxx.xxx: bytes=32 time=9ms TTL=48

Ping statistics for xxx.xxx.xxx.xxx:

    Packets: Sent = 4, Received = 3, Lost = 1 (25% loss),

Approximate round trip times in milli-seconds:

    Minimum = 9ms, Maximum = 9ms, Average = 9m

 

OS環境変数の値取得

端末の環境変数を取得するためには、clone-host-environmentプロシージャを利用します。以下にサンプルを紹介します。

{curl 6.0 applet}

{import * from CURL.RUNTIME.HOST-ENVIRONMENT}
{value
    let table:Table = {Table columns = 2}
    {for v key k:String in {clone-host-environment} do
        {table.add k}
        {table.add v}
    }
    table
}

 

実行結果

windir  C:\WINDOWS
ALLUSERSPROFILE  C:\Documents and Settings\All Users
HOMEPATH  \Documents and Settings\XXXXXX
OS  Windows_NT
PROCESSOR_IDENTIFIER  x86 Family 15 Model 75 Stepping 2, AuthenticAMD
ProgramFiles  C:\Program Files
LOGONSERVER  xxxxx
NUMBER_OF_PROCESSORS  2

….

 

Curl RTEのバージョン情報取得

端末にインストールされているRTEのバージョン情報を取得するには、get-installed-api-versionsというプロシージャを利用します。

{curl 6.0 applet}

{import * from CURL.LANGUAGE.COMPONENT}
{value
    {spaced-vbox
        {splice {get-installed-api-versions}}
    }
}

実行結果

6.0.0
5.0.4
4.0.6

 

オフライン実行(OCC)

随時接続コンピューティングとはリモート環境下においてクライアントPCがネットワークから切り離されていても、ユーザはあたかもネットワークに接続しているかのようにローカルにあるファイルにアクセスし、通常通りにWeb業務アプリケーションを使用できる機能です。

occ00.gif

OCCを利用するアプレットの作り方

*事前準備:
・Apache(IIS等でも可)を起動して、http://localhost が動いていることを確認してください。
・インストール先ディレクトリ\Curl Corporation\Surge\7\ide\etc\localhost-proの中のcurl-license-5.datファイルを localhost のルートに置いてください。(また、この動作を検証するためにはCurl/Proの機能を必要とします。)
・localhostに特権が与えられているか確認してください。(ローカルフォルダにアプレットを置くため、特権が必要になります。)

1.任意のディレクトリに新規プロジェクトを作成します。
OCCの機能を実現するために、 occ-install-or-update プロシージャを使います。その引数として、occ-root-installer というプロシージャを使います。この occ-root-installer が機能するには、サーバ上のアプレットの curl-root に特別な curl-timestamp.txt ファイルと特別な curl-archive.car ファイルが存在する必要があります。

2.コードを記述します。ハイライトしてある箇所を記述します。

{curl 6.0 applet}
{curl-file-attributes character-encoding = “shift-jis”}
{applet manifest = “manifest.mcurl”,
curl-root = “.”
}
{do {occ-install-or-update occ-root-installer}}

これでOCCの機能が使えるようになります。たったこれだけです。

3.[ツールバー]→[プロジェクト]→[OCC用のディプロイメント]を実行します。
“deploy-default”という名前のフォルダが、1で作成したプロジェクトと同じ階層に作成されます。
フォルダの中に、curl-archive.car, curl-timestamp.txt, manifest.mcurl, start.curl の4つのファイルが作成されていることを確認してください。

4.deploy-defaultフォルダをlocalhostのルートディレクトリに配置します。
*今回は便宜上、全てルートディレクトリで行います。

5.IEを立ち上げ、アドレスバーに以下のアドレスを入力します。

curl://occ/http://localhost/deploy-default/start.curl
*OCCの機能を使用するためにはアドレスの前に curl://occ/というプレフィックスが必要となります。これは独立型アプレットと似ていますね(curl://launch/URL)。

6.結果の確認(オンライン)
Apacheを起動して立ち上げるとアドレスが以下のようになっていると思います。

http://localhost/deploy-default/start.curl

7.結果の確認(オフライン)
次に、サーバを停止して、5を実行してみます。すると、Curlランタイムがオフラインであることを検知してローカルにコピーしたアプリにリダイレクトします。(*うまくいかない場合は物理的にケーブルをPCから抜いてください)

どうでしょうか、これが最もシンプルなOCCの機能の紹介です。ポイントは
・ オンライン、オフラインで記述するコードは変更されないこと
です。

8.色々な確認
[1]で作成したフォルダの中の start.curl に対して以下のコードをコピー&ペーストし、[2-7]までの手順を実行してください。

{curl 6.0 applet}
{curl-file-attributes character-encoding = “shift-jis”}
{applet curl-root = “.”}

実際のアプレットのURLは… ‘{value {get-the-applet}.url}’.

curl-rootは… ‘{process-get-curl-root}’.

有効なルートは… ‘{process-get-effective-root}’.

有効なアプレットURLは… ‘{value {get-the-applet}.effective-url}’.

‘curl://local-data’ のロケーションは… ‘{{url “curl://local-data”}.canonicalize}’.

ローカルに保存するコピーの更新を行います…
{{get-the-applet}.flush}

{let (permission?:bool, network?:bool,
allowed?:bool, updated?:bool)
=
{occ-install-or-update occ-root-installer}
}

{if updated? then
“ローカルへのコピーが更新されました。”
elseif allowed? then
“ローカルのコピーは既に最新です。”
elseif network? then
“今回はローカルのコピーを更新できませんでした。”
elseif permission? then
“現在ローカルにコピーされたアプレットが実行されています。”
else
“ユーザによりローカルへのコピーは禁止されています。”
}

9.OCCのリンクを示すためのcurlファイルを作ります。

{curl 6.0 applet}
{curl-file-attributes character-encoding = “shift-jis”}
{value
{link href={url “curl://occ/http://localhost/deploy-default/start.curl”},
“OCC機能を使ったアプリへのリンク”}
}

*ただのリンクを表示するファイルなので、HTMLで作成していただいてもかまいません。

上手く動作しないときは・・・

・ 物理的にも切断されるように、PCからケーブルを抜いてみてください。
・ サーバが完全に停止していないかもしれません。停止させてから少し時間を置いてアプリを実行してみてください
・ ブラウザのキャッシュが影響しているかもしれません。IEの場合は[プロパティ]→[全般]タブから一時ファイルの削除を行ってから再度実行してみてください。
・ localhostに特権を与えていないことが問題かもしれません。[コントロールパネル]→[セキュリティ]→[ホストの追加]から localhostを追加してください。

外部ライブラリコール

Curlは外部ライブラリにアクセスすることができます。これによりC言語等で作成されたライブラリをコールし、結果を取得することができます。以下にサンプルをもとにして説明していきます。(ちなみにこのサンプルはWindowsのみで動きます。UNIX用のライブラリであれば、UNIX上でも実行することができます。)

当サンプルは、user32.dllに格納されているMessageBox 関数へのインターフェースを使用します。MessageBox は、単にメッセージ ボックスを表示します。インターフェースは以下のようになっています。

int MessageBox(
  HWND hWnd;
  LPCTSTR lpText;
  LPCTSTR lpCaption;
  UINT uType;
):int

パラメータには以下のような意味があります。
hWnd
メッセージボックスの上位ウィンドウへのハンドル。NULL の場合、このウィンドウにオーナーはありません。

lpText
表示されるテキスト。

lpCaption
ダイアログ ボックスのタイトルに表示されるテキスト。NULL の場合、既定のタイトルとしてエラーが使用されます。

uType
指定されたフラグに応じて、ダイアログ ボックスの内容と動作を変更します。フラグの種類は多数ありますが、この例で紹介しているのは、その一部です。

ライブラリをコールするクラスは、define-dll-classマクロを使って定義します。以下のようにサンプルでは、このコンストラクタ内で、SharedLibraryクラスを用いて対象DLL(user32.dll)をロードしています。construct-superでスーパークラスのコンストラクタを呼び出していますが、このスーパークラスはDLLInterfaceクラスです。 

{define-dll-class public WinMessageBox
  {defaults
    calling-convention = stdcall,
    string-rep = CStringUTF16
  }
 
  {constructor public {default}
    {construct-super {SharedLibrary “user32”}}
  } 

次にdll-methodで対象となる関数を定義することとなります。{defaults …} 句により、クラスに含まれた dll-method に直接、いくつかの既定値を設定できるようになります。これらの既定は、このクラスのサブクラスには適用されません。詳細はCurlのAPIリファレンスdefine-dll-classマクロを参照してください。

対象となる関数の定義については、同様の関数名をdll-methodのメソッド名としてセットするか、任意の名前を振り、括弧()で関数名を記載します。このサンプルでは後者の方法で定義しており、関数名はMessageBoxA、Curl内でのメソッドへのアクセスはshow-ascii-messageとなります。

{dll-method public {show-ascii-message (“MessageBoxA”)
                       hwin:CPointer = null,
                       text:StringInterface (rep = CString),
                       title:#StringInterface = null (rep = CString),
                       button-code:int = WinMessageBox.button-ok
                     }:int
}

…. 省略 ….

let box:WinMessageBox = {WinMessageBox}
let result:int =
    {box.show-message
        “Would you like a cookie?”,
         button-code =
             {bit-or
                 WinMessageBox.button-yes-no,
                 WinMessageBox.icon-question
             }
    }

実行結果 

 

 

コードサンプルのダウンロード

外部DLLコールのコードサンプル