「FAQ」カテゴリーアーカイブ

Curlに関するFAQのページです

Curl起動時間の短縮について

◆ご質問◆
初回Curl起動時には20-40秒程度かかり、次回からは5秒程度とかなり差があります。
初回Curl起動にも5秒程度となるのを目指しています。

Curl起動時間を短縮する上で、推奨される構成や手法はあるのでしょうか。

◆回答◆
パッケージキャッシュが有効ということから、
初回起動が20-40秒、次回から5秒という差は
一般的にコンパイル処理の有無の差ということになります。

一度起動(コンパイル)したアプレットは二回目以降、再度コンパイルしなくても良い様に、
コンパイル済みのパッケージを保存し、それを利用することによって起動時間を短くしています。

この初回起動の時にコンパイル時間を0にする、つまり、初回起動時間を5秒にすることは
出来ませんが減らすことは可能な場合があります。


起動時に必要なクラス、プロシージャ等を最小限に留め、
パッケージの構成を見直すことです。起動時に不必要なクラスなどが
多く含まれている場合、その分コンパイルに時間がかかります。


起動ファイル(start.dcurl)の内容を極力短くし、
行う処理をパッケージに含めてしまいます。
パッケージに含めることでその処理がパッケージキャッシュされ、
その分のコンパイル時間が減少します。


起動ファイル自身は一般的に毎回サーバから取得されます。
(ブラウザのキャッシュから取得される場合もあります。)
この起動ファイルを短くすることは、ファイルサイズが小さくなるということですの
でサーバからの応答時間も短くなります。

Active Directory環境下でのセキュリティ引き継ぎについて

◆ご質問◆
Active Directory環境にて、ユーザが一度RTEインストールしたら、
他のPCに移動しても、CURLのセキュリティは引き継がれることは可能でしょうか?

◆回答◆
ユーザのプロファイルをローカルにもつローカルプロファイルにするのではなく、
ファイルサーバなどのネットワーク上に保存する移動プロファイルを使用することで
Curlのセキュリティ設定(特権ディレクトリやホストの設定)を別のPCでも共有することは可能です。

RecordGridのソート(昇順・降順)の判別

【ご質問】
一定の固定値に対して「昇順,降順」と切り替えた場合でも、固定値に関しては
常に同じ位置に表示したいと思っています。

RecordSortの「昇順、降順」の状態を判別するAPIは存在するのでしょうか。

【回答】
RecordSortの「昇順、降順」の状態を判別する標準APIは用意されておりません。
ただし、昇順、降順を判別するフラグを定義し、独自で実装することは可能だと思います。

詳細は以下のサンプルをご参照ください。

{curl 5.0,6.0,7.0,8.0 applet}
{curl-file-attributes character-encoding = “shift-jis”}

{let ascending?:bool = true}
{define-proc public {custom-sort rgc:RecordGridColumn}:RecordSort

    set rgc.grid.sort = {RecordSort
                                  {proc {r1:Record, r2:Record}:int
                                      let val:String = r1[“id”] asa String
                                      let val2:String = r2[“id”] asa String
                                      {if ascending? then
                                          {if (val == “”)  and (val2 == “”) then
                                              {return -1}
                                          else
                                              {return {r1.compare-field “id”, r2[“id”]}}
                                          }
                                          set ascending? = false
                                          {dump ascending?}
                                      else
                                          {if (val == “”)  or  (val2 == “”then
                                              {return 1}
                                          else
                                              {return {r1.compare-field “id”, r2[“id”]}}
                                          }
                                          set ascending? = true
                                          {dump ascending?}
                                      }
                                  }
                              }
    {if ascending? then
        set ascending? = false
        {dump ascending?}
     else
        set ascending? = true
        {dump ascending?}
    }
    {return
        rgc.grid.sort asa RecordSort
    }
}

{let rs:RecordSet = {RecordSet
                                {RecordFields
                                    {RecordField “id”, domain = String}
                                },
                                {RecordData id = “a”},
                                {RecordData id = “b”},
                                {RecordData id = “c”},
                                {RecordData id = “d”},
                                {RecordData id = “”},
                                {RecordData id = “”},
                                {RecordData id = “”},
                                {RecordData id = “e”},
                                {RecordData id = “f”},
                                {RecordData id = “g”},
                                {RecordData id = “h”},
                                {RecordData id = “i”},
                                {RecordData id = “3”},
                                {RecordData id = “2000”},
                                {RecordData id = “2000”},
                                {RecordData id = “j”}                       
                            }
}

{let rg:RecordGrid = {RecordGrid
                                 record-source = rs,
                                 automatic-columns? = false,
                                 {RecordGridColumn “id”, halign = “right”,
                                     sort-spec = custom-sort
                                 }
                             }
}

{let v:View = {View
                       width = 5in,
                       height = 5in,
                       rg
                   }
}
       
{v.show}

ブラウザからCurlへのCookieの引き継ぎについて

2022年6月15日にIEがサポート終了の予定です。ブラウザ内で実行するアプレットはEdgeのIEモードサポート終了に伴い、利用できなくなります。そのため、まだブラウザ内で実行する.curlアプレットをご利用中の場合、早めに独立型アプレットへ移行することをお勧めします。

【ご質問】
ブラウザが持っているCookieの内容は、Curl側のCookieには引き継がれるのでしょうか。

【回答】
通常セッションクッキーは、ブラウザのCookieを引き継がず、Curl独自でCookieを持つことになります。
ただし、Internet Explorer(※)に限って、有効期限を持ったCookie(つまりファイル保存されたCookie)の場合と
request-browser-resident-httpプロシージャを利用した場合はブラウザのCookieを引き継ぐことが可能です。

詳細は、Curl開発者ガイドの
[外部リソースとの対話]-[Web サイトとの対話]-[ブラウザ常駐 HTTP]
の項をご参照ください。 

クッキー情報の引継ぎについて、次のページもご参照ください。

Cookieを引き継ぐ方法

Curlが行っているHTTP通信プロセスについて

【ご質問】
ブラウザが行っているHTTP通信と
Curlアプレットが行っているHTTP通信のプロセスは
別のものとなるのでしょうか。

【回答】
基本的には、ブラウザが行っているHTTP通信と
Curlアプレットが行っているHTTP通信のプロセスは別になります。

ブラウザはiexplore.exeプロセスが持つWinInetで通信を行い、
Curlではsurge.exeプロセスが持つWinInetで通信を行います。

ただし、request-browser-resident-httpを使用している場合には
Curlもiexplore.exeプロセスが持つWinInetで通信を行います。

詳細は、APIリファレンスの
[CURL.IO.HTTP]-[request-browser-resident-http]
の項をご参照ください。

改行コードを除いてコピーをしたい

【ご質問】
テキストの文字列を選択し、「Crtl+C」を押下した際に
選択した文字列内の改行コードを除いてコピーすることは可能でしょうか?

【回答】
CopyCommandクラスを継承したクラスのexecuteメソッドに
おいて処理したい内容を記述すれば宜しいかと思います。

詳細は以下のサンプルをご参照ください。
(今回は改行コードを除去してクリップボードに設定しています。)

{curl 5.0,6.0,7.0,8.0 applet}
{curl-file-attributes character-encoding = “shift-jis”}

{import * from CURL.DESKTOP.CLIPBOARD}

{define-class public CustomCopyCommand {inherits CopyCommand}
  {constructor public {default context:SelectionContext}   
    {construct-super context}
  }
 
  {getter public open {context}:SelectionContext
    {return super.context asa SelectionContext}
  }
 
  {getter public open {enabled?}:bool
    {return true}
  }
   
  {method protected open {execute}:void 
    {if not self.enabled? then {return}}
    let constant context:SelectionContext = self.context
    let ret:StringBuf = {StringBuf}
    let str:String = {(self.context.selection asa TextSelection).get-text}
    let strs:StringArray = {str.split}
    {for str in strs do
        {ret.concat str}
    }
    {{Clipboard.get-system-clipboard}.set-string ret}
  }
}

{define-class CustomCommandTA {inherits TextArea}
  {constructor {default …}
    {construct-super
        value = null,
        prompt = null,
        max-chars = -1,
        data-model = null,
        ui-object = null,
        width = 200pt,
        height = 100pt,
        …}
  }
  {method public open {create-command name:String}:#Command
    {return
        {switch name
         case “copy” do {CustomCopyCommand {non-null self.selection-context}}
         else
            {super.create-command name}
        }
    }
  }
}

{define-class CustomCommandRTA {inherits RichTextArea}
  {constructor {default …}
    {construct-super
        value = null,
        prompt = null,
        max-chars = -1,
        data-model = null,
        ui-object = null,
        width = 200pt,
        height = 100pt,
        …}
  }
  {method public open {create-command name:String}:#Command
    {return
        {switch name
         case “copy” do {CustomCopyCommand {non-null self.selection-context}}
         else
            {super.create-command name}
        }
    }
  }
}

{let rta1:RichTextArea =  {RichTextArea width = 10cm, height = 4cm}}
{let rta2:RichTextArea =  {CustomCommandRTA width = 10cm, height = 4cm}}
{let ta1:TextArea =  {TextArea width = 10cm, height = 4cm}}
{let ta2:TextArea =  {CustomCommandTA width = 10cm, height = 4cm}}
{let ta3:TextArea = {TextArea width = 10cm, height = 5cm}}

{value
    {VBox
        “通常のRichTextArea”,
        rta1,
        “改行をコピーしないRichTextArea”,
        rta2,
        “通常のRichTextArea”,
        ta1,
        “改行をコピーしないRichTextArea”,
        ta2,
        “下のTextAreaに貼り付けて確認して下さい”,
        ta3
    }
}

[Ctrl+C]と同様の処理を行うコンテキストメニューを作成したい

◆ご質問◆
コンテキストポップアップメニューのメニューに「コピー」を追加し、
追加したメニューの「コピー」を選択した際に「Crtl+C」と同様の機能を実装することは可能でしょうか?

◆回答◆
FocusManagerが管理する標準のコマンド(コピーコマンド)を取得し、
MenuPaneを生成して、そのMenuActionに取得したコピーコマンドを割り当てることで実現可能です。

詳細はサンプルをご参照ください。

{curl  5.0,6.0 applet}
{curl-file-attributes character-encoding = “shift-jis”}

{define-class public MyTextFieldUI {inherits StandardTextFieldUI}
  {constructor public {default control:#TextField=null, …}
    {construct-super control = control, …}
  }

  {method private {make-menu-pane-for-text-field view:View}:MenuPane
    let fm:FocusManager = {non-null view.focus-manager}
    {return
        {MenuPane
            {on e:GrabRelease do
                {if self.input-method-enabled? then
                    let local?:bool = {set? self.input-method-enabled?}
                    {try
                        set self.input-method-enabled? = false
                     finally
                        {if local? then
                            set self.input-method-enabled? = true
                         else
                            {unset self.input-method-enabled?}
                        }
                    }
                }
            },
            {MenuAction
                label = {host-localize “Cut”},
                bound-command = {fm.get-command “cut”}
            },
            {MenuAction
                label = {host-localize “Copy”},
                bound-command = {fm.get-command “copy”}
            },
            {MenuAction
                label = {host-localize “Paste”},
                bound-command = {fm.get-command “paste”}
            },
            {MenuAction
                label = {host-localize “Delete”},
                bound-command = {fm.get-command “delete”}
            }
        }
    }
  }

  {method open public {on-context-menu-event e:ContextMenuEvent}:void
    {if not e.consumed? then
        {if-non-null v = {self.get-view} then
            {if-non-null
                menu-pane = {self.make-menu-pane-for-text-field v}
             then
                {e.consume}
                {menu-pane.popup self, e.x, e.y}
            }
        }
    }
  }
}

{do
    {the-standard-look-and-feel.register-ui
        TextField,
        MyTextFieldUI
    }
}

{TextField width = 100pt}

全選択する範囲をアクティブなフレーム内のみにしたい

◆ご質問◆
フレームを使用して表示している画面で「Crtl+A」を押下した場合、
画面全体が選択状態になりますが、アクティブなフレーム内のみ全選択にすることは可能でしょうか?

◆回答◆
DiscreteGraphicSelectionFrameを適切にコントロールすれば可能ではないでしょうか。

[Curl開発者ガイド]→[グラフィカルユーザーインターフェイス]→[選択]
→[個別選択]→[個別選択の概観の設定]
ここのサンプルにCtrl+Aで選択されるオブジェクトが
フレーム(DiscreteGraphicSelectionFrame)毎になっています。

アクティブなフレームというのがどのグラフィック階層のフレームであるのかを
プログラムで指定する必要があるかとは思いますが、
その指定を予め決めておけばいいのではないでしょうか。

常に行選択状態とならないRecordGridでTab遷移を行うには

【ご質問】
常に行選択状態とならないRecordGridにて、
Tabでフォーカス遷移をさせることは可能でしょうか。

【回答】
オープンコントロールを利用してStandardRecordGridUIに
処理を追加することで、Tab遷移をさせることが可能となります。

詳細はサンプルをご参照ください。
(修正箇所はstandard-record-grid-ui.scurlの2440行目から2444行目までを追加しております。)

ただし、オープンコントロールを使用しているため、
パッケージをロードする際にパフォーマンスに影響が生じる可能性がありますので、
使用時にはご注意ください。

ExcelからRecordGridにデータを貼り付けするには

【ご質問】
Excelで複数セルをコピーし、RecordGridの一つのセルを選んで貼り付けを行うと、
そのセルを基点に複数のセルにまたがって貼り付ける様にしたいのですが可能でしょうか。

【回答】
RecordGridのペーストコマンド(RecordGridPaste)を
エクセルからのペーストの機能に追従する様に改変し、
RecordGridの内部で使用されているTextFieldから呼び出すようにすることで実現出来ます。

詳細はサンプル(バージョン7・8用バージョン5・6用)をご参照ください。

RecordGridにてrecord選択時にKeyPressイベントを発生させるには

【ご質問】
Record選択時にEnterキーを押下しても、Actionイベントが発生せず、
editable?=trueのカラム上が選択範囲のときのみKeyPressイベントが発生するようでした。
画面初期表示時に、RecordGridにKeyPressイベントが発生するように
フォーカスを当てたいのですが、どのようしたら実現できるでしょうか?

【回答】
RecordGridにイベントを追加するのではなく、
SkinnableRecordGridUIクラスにKeyPressイベントを追加することで、
RecordGridにKeyPressイベントが発生させることが可能です。

また、editable?=falseのセルでもイベントが発生するようにするためには
カスタムセルを作成し、セルが持つTextFieldにKeyPressイベントを追加します。

詳細はサンプルをご参照ください。

{curl 7.0,8.0 applet}
{curl-file-attributes character-encoding = “shift-jis”}
{applet
    {compiler-directives careful? = true}
}

{define-class public EnterKeyCell {inherits StandardStringCell}

  {constructor public {default}
    {construct-super}
  }

  {method public {create-editor}:TextField

    let editor:TextField = {super.create-editor}

    ||セル上で操作するテキストフィールドに対して、
    ||Enterキーのイベントを追加する。
    {editor.add-event-handler
        {on e:KeyPress do
            {if e.value == KeyPressValue.enter then
                {popup-message “EnterKey Press Event 拾いました。”}
                {e.consume}
            }
        }
    }
    {return editor}
  }
}

{let rs-choice-grid:RecordSet =
    {RecordSet
        {RecordFields
            {RecordField
                “choice”, caption = “選択”, domain = bool
            },
            {RecordField
                “service”, caption = “サービス”, domain = String
            }
        },
        {RecordData choice = false, service = “良いサービス”},
        {RecordData choice = false, service = “普通サービス”},
        {RecordData choice = false, service = “悪いサービス”}
    }
}

{let rg:RecordGrid =
    {RecordGrid
        width = 264pt,
        height = 192pt,
        name = “sample”,
        automatic-columns? = false,
        column-selection-enabled? = false,
        record-selection-enabled? = true,
        select-current-record? = true,
        record-source = rs-choice-grid,
        {RecordGridColumn  width = 0.8cm, “choice”},
        {RecordGridColumn  width = 3.2cm, “service”, editable? = false, cell-spec = EnterKeyCell},
        ui-object = {SkinnableRecordGridUI                                       
                        {on e:KeyPress do
                            {if e.value == KeyPressValue.enter then
                                {popup-message “EnterKey Press Event 拾いました。”}
                                {e.consume}
                            }
                        }
                    }
    }
}

{Dialog rg}

{do
    {rg.request-key-focus}
}

入力メソッドがアクティブ時に文字列を取得するには

【ご質問】
入力メソッドがアクティブの時(input-method-focus-behaviorがInputMethodFocusBehavior.activateの時)の
入力キーイベントや文字列を取得することは可能でしょうか?

【回答】
“StartCompositionEvent”、”CompositionChangeEvent”、
“EndCompositionEvent”、”CompositionResultEvent”を利用することで可能です。

これらのイベントを入力コントロールのUIクラスに記述してはいかがでしょうか。

詳細は以下のサンプルをご参照ください。

{curl 7.0,8.0 applet}
{curl-file-attributes character-encoding = “shift-jis”}
{applet
    {compiler-directives careful? = true}
}

{let start:Frame = {Frame color = “blue”, font-weight = “bold”}}
{let change:Frame = {Frame font-weight = “bold” }}
{let end:Frame = {Frame color = “blue”, font-weight = “bold”}}
{let result:Frame = {Frame color = “red”, font-weight = “bold”}}

{VBox
    {TextField width = 5cm,
        input-method-focus-behavior = “activate”,
        ui-object = {SkinnableTextFieldUI
                        {on e:StartCompositionEvent do
                            {start.clear}
                            {change.clear}
                            {end.clear}
                            {result.clear}
                            {start.add replace? = true, “イベントが開始しました”}
                        },
                        {on e:CompositionChangeEvent do
                            {change.add replace? = true, e.string}
                        },
                        {on e:EndCompositionEvent do
                            {end.add replace? = true, “イベントが終了しました”}
                        },
                        {on e:CompositionResultEvent do
                            {result.add replace? = true, e.string}
                        }
                    }
    },
    {Table columns = 2,
        “イベントの開始”, start,
        “入力中の文字列”, change,
        “イベントの終了”, end,
        “入力結果”, result
    }
}

includeとdelegate-toの違いについて

【ご質問】
include と delegate-to の違いについて教えてください。

【回答】
includeとは、
include文を書いた箇所に指定したファイルの
内容をそのまま”挿入(貼り付け)”するイメージになります。

delegate-toとは、
外部のパッケージを利用するためにそのリソースを管理しているマニフェストファイルへの”参照”を行います。
このように”参照”のかたちをとることで外部パッケージの独立性を高めることができます。

includeの詳細については、Curl開発者ガイドの
[コンテンツの構成要素]-[アプレット]-[アプレットファイルのソースコード]
の項をご参照ください。 

また、delegate-toの詳細については、Curl開発者ガイドの
[コンテンツの構成要素]-[マニフェスト]-[マニフェストファイルの構造]-[マニフェストのデリゲート(委譲)]
の項をご参照ください。

MessageDisplayの検証時の背景色変更について

◆ご質問◆
MessageDisplayを使用しTextFieldコントロールの検証を行った場合に、
背景色を指定することは可能でしょうか。
TextFieldコントロールのcontrol-content-backgroundオプションと、
MessageDisplayを同時に指定した場合、control-content-backgroundの設定が反映されません。

◆回答◆
MessageDisplayのプロパティ「required-entry-background」を設定することで可能です。

詳細はCurl開発者ガイドの
「グラフィカル ユーザー インターフェイス」→「ダイアログとコントロール」
→「コントロールにおけるデータ検証」
をご参照ください。

プログレスバーの表示

◆ご質問◆
検索などで長い時間がかかる処理が走った際に、
プログレスバーで処理中であることを表現したいです。
タイマーで実現できるかと試行錯誤しましたが、どうもうまくいきませんでした。
どのように行えばよいのでしょうか?

◆回答◆
このような場合、別プロセスにてプログレスバーを表示させることが宜しいかと思います。

Curl内の処理で時間が掛かる場合、タイマーなどでは対応できません。
Curlの検索の処理に時間が掛かっている間は他の処理を行なうことができず、
止まっているような状態に見えます。

このような場合には、長い時間が掛かる処理を行なっているアプリとは
別のプログレスバーを表示するだけの別アプリを起動しし、
それを表示すれば良いかと思います。

詳細はサンプルをご参照ください。
これは、ボタンを押すと1~10000の間でとある計算を行ないます。
その間、プログレスバーを表示しています。

全てのアプレットの再同期を強制する

◆ご質問◆
resync-as-ofを設定している状況でもCurlの全般オプションタブの強制再同期設定を
「全てのアプレットの再同期を強制する」に設定しているとresync-as-ofが無視されて
毎回同期されるのでしょうか?

◆回答◆
ご推察の通り、「全てのアプレットの再同期を強制する」に設定した場合、
resync-as-ofの設定によらず毎回同期される事になります。

resync-as-ofの記述するファイルについて

◆ご質問◆
resync-as-ofの推奨される設定はstart.dcurlへ記述するとされていますが、
ライブラリ類などの場合はmanifest.mcurlへ記述することは問題ないでしょうか?
また、その場合Webサーバーへのコンテンツ有効期限の設定は必要ないでしょうか?

◆回答◆
resync-as-ofの設定はstart.dcurlのみにして頂く事を推奨致しております。
ライブラリやmanifest.mcurlファイルについてもstart.dcurlの設定が反映されますので、
これらにresync-as-ofの設定は必要ありません。

また、Webサーバのコンテンツの有効期限も同様にstart.dcurlファイルのみ
(ライブラリやmanifest.mcurlの有効期限の設定は必要ありません)に
設定することを推奨致しております。

複数バージョンのアプリ起動時におけるRTEのプロセスについて

【ご質問】
Curlはバージョンアッドとありますが、CurlRTEのプロセスは複数バージョンの
アプリケーションを起動してもRTEのプロセスは1つなのでしょうか?
それとも複数起動されるのでしょうか?

【回答】
バージョンの違うCurlアプレットが起動する場合の動作について説明します。
メインのバージョンのアプレットが動く場合はsurge.exeで処理されます。
それ以外のバージョンのアプレットが動き出すと、curl-eng.exeが起動し処理されます。

例えば、バージョン4、5、6のRTEがインストールされている場合、
6のアプレットが動くとsurge.exeで処理され、
5のアプレットが動くとcurl-eng.exeで処理されます。
また、この状態で4のアプレットが起動すると、
5で使用されているcurl-eng.exeとは別のcurl-eng.exeが使われます。

このときsurge.exe、curl-eng.exeが2つ起動していることになります。 

以下のFAQもご参照ください。
http://developers.curlap.com/faq/49-faq-operation/343-curl.html

カスタムセルのTab遷移

【ご質問】
RecordGridにTextFieldを含むカスタムセルを設定したところ、
このセルにTab移動でフォーカスを当てることができません。
RecordGridに設定したカスタムセル間をTab移動するには、どうすれば良いでしょうか。

【回答】
本来RecordGridを含むコンテナでのTabキーでの移動はセル自身にフォーカスが移動します。
TextFieldを含むカスタムセルを設定すると、セル自身にフォーカスが移動した際
TextFieldが埋め込まれているため本来の動きができません。

回避策としては、セル自身にフォーカスが当たったときに
TextFieldでTabキーが押されたときの処理を追加することなどが考えられます。

詳細は以下のサンプルをご参照ください。

{curl 6.0,7.0,8.0 applet}
{curl-file-attributes character-encoding = “shift-jis”}

{def grid =
    {RecordGrid
        record-source = {RecordSet
                            {RecordFields
                                {RecordField “First”, domain = String},
                                {RecordField “Last”, domain = String},
                                {RecordField “Age”, domain = int}
                            },
                            {RecordData First = “John”, Last = “Smith”, Age = 25},
                            {RecordData First = “Jane”, Last = “Smith”, Age = 29},
                            {RecordData First = “Jane”, Last = “Jones”, Age = 28}
                        },
        automatic-columns? = false,
        select-current-record? = true,
        editable? = true,
        display-record-selectors? = false,
        display-navigation-panel? = false,
        select-current-record? = true,
        display-filler-column? = true,
        column-resizable? = false,
        column-movable? = false,
        multiple-selection-enabled? = false,
        {on e:FocusIn at gird:RecordGrid do
            {InputCell.cell.become-active}
        },
       
        {RecordGridColumn “First”, cells-take-focus? = false,editable? = false},
        {RecordGridColumn “Last”, cells-take-focus? = false,editable? = false},
        {RecordGridColumn “Age”, halign = “right”, cell-spec = InputCell}

    }
}

{define-class public InputCell {inherits StandardRecordGridCell}

  field private _input:TextField =
      {TextField
        color = “black”,
        halign = “right”,
        max-chars = 10,
        takes-focus? = true,
        active-traversal-container = null,
        {validate-with {NumericValidator}}
      }

  let public cell:#InputCell

  {constructor public {default …}
    {self.add-internal self._input}

    {if InputCell.cell == null then
        set InputCell.cell = self
    }
   
    {self.add-event-handler
        {on e:FocusIn at cell:InputCell do
            {self._input.become-active}
        }
    }
    {self._input.add-event-handler
        {on e:KeyPress at tf:TextField do
            {if e.value == KeyPressValue.tab then
                {if (self.grid.current-index == 0  and e.shift?) or
                    (self.grid.current-index == self.grid.record-source.size – 1 and not e.shift? )
                 then
                    {self.grid.active-traversal-container.traverse forward? = (not e.shift?)}
                    {e.consume}
                    {return}
                }
                {self.active-traversal-container.traverse forward? = (not e.shift?)}
             else
                {super.on-key-press e}
            }
        }
    }
  }

  {method public {note-grid-focus-out}:void
    {self.attempt-update self._input.value}
    {super.note-grid-focus-out}
  }
 
  {method public {refresh-data}:void
    {super.refresh-data}
    let (val:any, valid?:bool) = {self.get-data}
    set self._input.value = {if val == null then “” else val & “”}
   
  }    
}

{View
    {StandardActiveTraversalContainer
        {VBox
            {TextField width = 100pt},
            grid,
            {CommandButton}
        }
    },
    visibility = “normal”,
    {on WindowClose do
        {exit}
    }
}

キャッシュの制御に関して

【ご質問】
アプリケーションサーバ上のアプリケーションを更新した際に、
クライアントPC側のキャッシュがONになっていると、
Curlコントロールパネルより、キャッシュを空にしないと
アプリケーションが正常に起動出来ないことがあります。

アプリケーションに更新があった際に、自動的にキャッシュを空にする方法
または、キャッシュのON/OFFに依存しない回避策はありますか?

【回答】
“キャッシュ”には”ブラウザのキャッシュ”と”CurlRTEのキャッシュ”の2つが関係しています。
問題を解決するためには”ブラウザのキャッシュ”、”CurlRTEのキャッシュ”の両方を
適切にコントロールする必要があります。

例えば、CurlRTEにキャッシュが残っている場合、
サーバのアプリケーションが修正されたとしてもCurlRTEのキャッシュ自身を使用して、
新しいアプリケーションに更新されない可能性があります。
また、CurlRTEのキャッシュを使用しない設定等を行なっても
ブラウザキャッシュが残っている場合には、サーバに新しいアプリケーションを
取得しに行かず、正常にアプリケーションが更新されない可能性があります。

CurlRTEのキャッシュをコントロールするには
「resync-as-of」アクセサを使用します。
これを使用すると、指定された日時より前にCurl RTEのキャッシュに
保存されたものはサーバからコンポーネントを取得しようとします。
この機能を利用してresync-as-ofで指定する日時をデプロイの日時に更新していけば
古いアプリケーションのコンポーネントをキャッシュしている端末は
resync-as-ofで指定された日時より古いキャッシュとなっているはずであるため、
新しいアプリケーションのコンポーネントを取得しようとします。

ブラウザのキャッシュをコントロールするには、クライアント側のブラウザの設定を
変更してキャッシュを行わないような設定にすることも可能です。
また、サーバ側でキャッシュされたファイルの有効期限を短く設定することも出来ます。
上記のような方法でブラウザのキャッシュに古いアプリケーションのコンポーネントが
キャッシュされないように調整を行うことで問題回避を図ることが出来ると思います。

詳細は、Curl開発者ガイドの
[コンテンツの構成要素]-[キャッシュと同期]
の項をご参照ください。