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

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

double型の値が正しく表示されない

【ご質問】
RecordGridでdouble型の値が正しく表示されません。
正しく表示させるには、どのようにしたらよいでしょうか。

【回答】
これは2進数で表現しようとした際に丸めを必要とする値に関して発生する一般的な問題です。
例えば、0.1を2進数で表現しようとすると、「0.000110011001100…」という無限小数になります。
コンピュータでは有限の桁数分しか扱えませんので、このような値を扱う場合には必ず丸め処理が発生します。
その結果、表示上元の値とは異なる近似値になってしまいます。

以下のような回避策があります。
 RecordGridColumnに”format-spec”を設定する
 ※”format-spec”を使用することで、表示する値を適当な表示にフォーマットする事が可能です。

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

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

{let num:RecordSet =
    {RecordSet
        {RecordFields
            {RecordField “Num”, domain = double}
        },
        {RecordData Num = 123456},
        {RecordData Num = 1234567},
        {RecordData Num = 12345678},
        {RecordData Num = 123456789},
        {RecordData Num = 1234567890},
        {RecordData Num = 1234567890.1}
    }
}

{let rg:RecordGrid =
    {RecordGrid
        record-source = num,
        height = 250pt,
        automatic-columns? = false,
        {RecordGridColumn “Num”}
    }
}

{value rg}

TabPaneの表示/非表示の制御をするには

◆ご質問◆
RadioButtonを変更することでタブの表示/非表示を制御することは可能でしょうか。

 

◆回答◆
TabContainer内の各タブはTabPaneというクラスで実装されており、簡単なプロパティの変更などで表示/非表示の制御を行うことは出来ません。
また、TabContainerはTab+Ctrlキーによりタブ遷移を行う事も可能ですので、この動作も制御する事が必要です。

詳細はSampleをご参照ください。

尚、TabContainer内でショートカットキーを使用するような場合は
上記のキー制御により意図しない動作をする可能性がある事をご留意下さい。

RecordGridのフィルタ制御について

【ご質問】
RecordGrid上にて右クリックした時に表示されるメニューのフィルタ関連項目について
表示/非表示の制御をすることは可能でしょうか。

【回答】
フィルタ関連項目のみの表示/非表示を制御するだけであれば、
RecordGridのローカルオプションである”filter-menu-proc”を使用することで実現可能です。

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

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

{let people:RecordSet =
    {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}
    }
}
{value
    {RecordGrid
        cells-take-focus? = false,
        column-movable? = false,
        column-resizable? = false,
        editable? = false,
        display-record-selectors? = false,
        display-navigation-panel? = false,
        record-source = people,
        height = 3cm,
        filter-menu-proc = {proc {menu-array:{Array-of MenuItem},
                                           cell:RecordGridCell}
                                       :{Array-of MenuItem}
                                       {menu-array.clear}
                                       {return menu-array}
                                   }
    }
}

トリプルクリック時に一段落を全選択するには

◆ご質問◆
トリプルクリックをした場合、TextFieldを使用すると一段落が全選択ができますが、
他のコンポーネント(TextDisplay)でも可能でしょうか?

◆回答◆
TextDisplayは文字表示に用いるAPIですので、選択には対応しておりません。

TextFlowBoxであれば、範囲選択用のイベントハンドラを追加することで実現可能です。

{curl 6.0,7.0,8.0 applet}

{define-proc {create-select-line-handler}:EventHandler
    {return
        {on e:PointerPress at grsc:GuiRangeSelectionContext do
            {if not e.consumed? and e.click-count == 3 then
                {if grsc.range-selection-ui-enabled? then
                    {if-non-null range = grsc.selection.range then
                        def start-mark = range.start-mark
                        def end-mark = range.end-mark

                        {if start-mark.graphic == end-mark.graphic then
                            def graphic = start-mark.graphic
                            def bounds = {graphic.layout.get-bounds}
                            def start-clone = {start-mark.clone}
                            def end-clone = {end-mark.clone}
                           
                            def (graphic-x, graphic-y) =
                                {transform-coordinates e.x, e.y, grsc, graphic}
                           
                            {if
                                {start-clone.move-to-point
                                    bounds.lextent, graphic-y
                                } and
                                {end-clone.move-to-point
                                    bounds.rextent – .01pt, graphic-y
                                }
                             then
                                {grsc.select start-clone, end-clone}
                            }
                        }
                    }
                   
                    {e.consume}
                }
            }
        }
    }
}

{define-proc {find-grsc g:Graphic}:#GuiRangeSelectionContext
    {type-switch g
     case g:GuiRangeSelectionContext do
        {return g}
    }

    {if-non-null parent = g.parent then
        {return {find-grsc parent}}
    }

    {return null}
}

{define-proc {install-handler g:Graphic}:void
    {if-non-null grsc = {find-grsc g} then
        {grsc.add-event-handler {create-select-line-handler}}
    }
}

{value
    def tfb =
        {TextFlowBox background={Color.from-string “#9099ff”},
            width=2in,

            {text First text fragment.},
            {paragraph
                Second text fragment. Quite a bit
                longer than the first. May wrap.},
            “Text in quotes. Here, text is expressed “ &
            “as two concatenated Strings.”
        }
    {after 0s do {install-handler tfb}}
    tfb
}

ExcelのハイパーリンクからCurl起動をするとエラーになる

◆ご質問◆
ExcelのハイパーリンクからCurlアプレットにアクセスすると、エラーが発生します。
Curlはハイパーリンクからのアクセスには対応しているのでしょうか。

◆回答◆
Excelのハイパーリンクをクリックしての起動は、webサーバからではなく”ブラウザのキャッシュ”から起動されます。
つまり、Excelのハイパーリンクをクリック時に、一度そのリンク先のファイルをブラウザのキャッシュに保存し、
そこから起動しようとします。

これは、Curlの問題というよりExcelの挙動になります。
回避策は以下の通りです。

[回避策]
Excelのリンク先を通常のHTMLファイルにし、このファイルからCurlアプレットにリンクするように変更する。
(Excelのハイパーリンク→HTMLファイル→Curlアプレット)

PanedWindowサイズ変更時のイベント取得

【ご質問】
PanedWindowのサイズ変更のイベントを取得することは可能でしょうか。

【回答】
PanedWindowクラスのSashオブジェクトに対してドラッグ、ドロップの
イベントハンドラを追加する事でサイズ変更のイベントを取得する事が可能です。

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

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

{define-class MyFrame {inherits Frame}
  {constructor {default …}
    {construct-super
        …}
  }
}

{value
    def p = {PanedWindow
                   width = 50mm,
                   height = 50mm,
                   background = “red”
               }
    def p1 = {MyFrame
                     background = “blue”,
                     width = {add-stretch},
                     height = {add-stretch}
                 }
    def p2 = {MyFrame
                     background = “yellow”,
                     width = {add-stretch},
                     height = {add-stretch}
                 }
    {p.add-pane {Pane p1, p}}
    {p.add-pane {Pane p2, p}}
    {for i:int = 0 below {p.pane-count} do
        {{p.get i}.add-event-handler
            {on AttachEvent at mf:Pane do
                {{mf.get-view}.add-event-handler
                    {on vre:ViewResizeEvent do
                        {output “Viewのサイズ変更中”}
                    }
                }
            }
        }
    }

    let pro = {proc {g:any}:void
                     {for g:Graphic in g.graphical-children do
                         {if g isa Sash then
                             let sash:Sash = g asa Sash
                             {sash.add-event-handler
                                 {on DragStarted  do
                                     {dump “サイズ変更開始”}
                                 }
                             }
                             {sash.add-event-handler
                                 {on GrabRelease do
                                     {dump “サイズ変更終了”}
                                 }
                             }
                             {break}
                         else
                             {pro g}
                      }
                  }
              }
    {pro p}
    p
}

また、APIリファレンスの
[CURL.GUI.BASE]-[PanedWindow]・[Sash]
の項をご参照ください。 

ファイルダイアログの表示ディレクトリについて

◆ご質問◆
choose-fileにより表示されるファイルダイアログですが、前回選択時のディレクトリが表示されます。
(※default-location は設定していません)

この「前回選択時」のディレクトリ情報はいつまで保持されるのでしょうか。
時間経過または何らかのキャッシュを削除することによってクリアされるのでしょうか。

◆回答◆
choose-fileプロシージャのdefault-locationがnullの場合は、プラットフォームに依存します。
つまり、ダイアログの過去の選択した履歴などはOSによって管理されており、Curlでは何も管理しておりません。

ディレクトリの履歴は
“HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\ComDlg32\OpenSaveMRU”
に格納されており、このレジストリ情報をクリアすることで過去の履歴が削除されるかと思われます。

四捨五入について

【ご質問】
double型の数値に対してround関数を用いて四捨五入を行いましたが
四捨五入されない場合があります。
正確に四捨五入を行わせるにはどのようにすればよいでしょうか。

 ・確認を行ったロジック
  {for x:double=1.0 to 10 step 0.1 do
    {output {round x}}
  }

【回答】
正確に四捨五入を行わせるためには、{floor x + 0.5f}をお使いください。

詳細は、APIリファレンスの
[CURL.LANGUAGE.COMPILER]-[round]
の項をご参照ください。 

RecordGridのソート制御

【ご質問】
RecordGridにて、ソートを無効にするにはどうしたらよいか。

【回答】
RecordGrid.sort-spec (オプション)をnullに設定することで、
ソートが実行されないようにすることができます。

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

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

{let records:RecordSet =
    {RecordSet
        {RecordFields
            {RecordField
                “id”, caption = “User ID”, domain = int,
                index-type = RecordFieldIndexType.unique
            },
            {RecordField “Last”, domain = String},
            {RecordField “First”, domain = String},
            {RecordField “City”, domain = String}

        },
        {RecordData id = 1, Last = “Smith”, First = “Gene”, City = “Boston”},
        {RecordData id = 2, Last = “Smith”, First = “Fred”, City = “Cambridge”},
        {RecordData id = 3, Last = “Smith”, First = “Mike”, City = “Keene”},
        {RecordData id = 4, Last = “Smith”, First = “Ben”, City = “New Haven”},
        {RecordData id = 5, Last = “Abrams”, First = “Ben”, City = “Boston”},
        {RecordData id = 6, Last = “Jones”, First = “Sam”, City = “Storrs”},
        {RecordData id = 7, Last = “Stevens”, First = “Nigel”, City = “Hartford”},
        {RecordData id = 8, Last = “Stevens”, First = “Bert”, City = “Cambridge”},
        {RecordData id = 9, Last = “Linden”, First = “Pat”, City = “Hartford”},
        {RecordData id = 10, Last = “Abrams”, First = “Mat”, City = “Boston”}
    }
}

{View
    {RecordGrid
        record-source = records,
        height = 10cm,
        width = 13cm,
        sort-spec = null
    },
    visibility = “normal”,
    {on WindowClose do
        {exit}
    }
}

また、APIリファレンスの
[CURL.GUI.CONTROL-LOGICAL]-[RecordGridOptions]
の項内のプロパティ[sort-spec]の項をご参照ください。 

ActiveXObject使用時にExcelのプロセスが残る

◆ご質問◆
ActiveXObjectを使用し、Excelファイルを操作すると、
Curlのブラウザを閉じるまでExcelのプロセスが消去されない。

Curlのブラウザを閉じずにExcelのプロセスを消去するにはどうしたらよいか。

◆回答◆
Excelのプロセスを消去するためには以下の操作などを実行する必要があります。
なお、この現象はCurlに限らず他のアプリケーションからExcelを呼出す場合にも発生します。

  1.Applicationオブジェクトは必ず Quitする。
  2.WorkBookオブジェクトは必ず Close する。
  3.宣言以外の場所で Excel. と書かない。
  4.参照は必ず宣言しているオブジェクトから書き始める。
  5.プロシージャ外で宣言しているオブジェクトは必ずNothingを使って破棄する。

アプレットの中で上記のような処理を正しく行っているか確認をお願いします。

SurfaceTooLargeExceptionについて

◆ご質問◆
処理の重いExcelを立ち上げているときに、
Curlのアプリケーションを実行すると”SurfaceTooLargeException”が発生する。
Exceptionの発生原因および対策はどのようなことが考えられるか。

◆回答◆
“SurfaceTooLargeException”はレンダリングに使用するグラフィックメモリが不足した場合に発生します。

対策としては以下のことが挙げられます。
 ・極力、必要最小限のメモリを使用する
 ・不要となったオブジェクトは適宜破棄するようなロジックにする

OSのバージョン取得

【ご質問】
CurlからOSのバージョンを取得することは可能でしょうか。

【回答】
Curlの標準APIではOSのバージョンまで詳細に取得する方法はありません。

しかし、spawn-host-shellプロシージャを利用してシェルコマンドを呼び出し、
シェルコマンドの’ver’を実行することで情報を取得することが可能です。

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

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

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

{value
    {CommandButton
        {on Action do
            let hp:HostProcess =
                {spawn-host-shell
                    read-stdout? = true,
                    “ver”
                }
            let tis:TextInputStream = {hp.read-open-stdout}
            let str:StringBuf = {tis.read-one-string}
            {tis.close}
            {popup-message str}
        }
    }
}

また、以下のことを行うことでOSのバージョンをレジストリより取得することも可能です。
 1.レジストリよりOSのバージョンを取得するようなVBScript等を作成する。
 2.CurlよりActiveXコントロールを使用して、対象VBScriptを起動させる。

以下のページも同内容のFAQです。参考にしてください。
http://developers.curlap.com/faq/48-faq-specification/853-curlosie.html

RecordGridのソート順序について

◆ご質問◆
RecordGridのソート順序を決定する文字コードは何でしょうか。
また、RecordGridのソート順を「エクセルと同じShift-JISによるソート順」にすることは可能でしょうか。

◆回答◆
CurlはUnicode順にソートされます。

Excelは厳密にはShift-JISの順にソートされておらず、独自の規定に沿ってソート順が決定されております。
このため、CurlのアプレットでExcelのソート順と同じにする事は困難です。

なお、RecordGridのソート順をShift-JIS順にする事は可能です。
詳細はサンプルをご参照ください。

プリンタ選択時のイベントを取得する方法について

◆ご質問◆
非特権アプレットで1ページ印刷の際に、プリンタの選択でユーザーがキャンセルしたことを知ることは可能でしょうか。

◆回答1◆
print-graphicプロシージャの処理範囲は印刷ダイアログをポップアップさせるところまでになっており、
印刷ダイアログ上で印刷ボタンやキャンセルボタンが押下された際の処理はWindowsが担っております。
このため、プリンタの選択の際にキャンセルされた事をCurl側から検出する事は出来ません。

ただし、プリンタの印刷ダイアログをCurlで独自に作成すれば印刷がキャンセルされた事を検出する事は可能です。
この場合、ダイアログ内でshow-printer-dialog? = falseオプションを設定してprint-graphicプロシージャを呼出す事になります。

※独自に印刷ダイアログを作成した場合、印刷時のプロパティはCurlで設定できるもののみとなります。

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

RecordGridのスクロール位置の取得

◆ご質問◆
RecordGridを上下2つ並べ、一方のGridで横スクロールされるともう一方も連動して移動させることは可能でしょうか。

◆回答◆
二つのRecordGridを連動させるためにはRecordGridのスクロールバーを取得しなければなりませんが、
残念ながら用意されているAPIからRecordGrid内のスクロールバーに簡単にアクセスする方法はありません。

グラフィック階層を辿ることでスクロールバーを取得することは可能ですが、
将来バージョンアップを行った場合にそのバージョンにてグラフィック階層の構造が変更されている可能性があります。
その際にエラーが発生するもしくは正常に動作しない可能性がありますので、ご利用には十分ご注意ください。

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

小文字入力を不可にしたい

【ご質問】
TextFieldにて小文字入力を制御することは可能でしょうか。

【回答】
TextField.replace-selection-with-string (メソッド)を改変することで実現可能です。

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

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

{define-class public open MyTextField {inherits TextField}
  {constructor public {default …}
    {construct-super …}
  }

  {method public open {replace-selection-with-string
                                     text:StringInterface
                                 }:void

    set text = {text.to-upper-clone}
    {super.replace-selection-with-string text}
  }
}

{let text1:TextField = {MyTextField
                                    width = 3cm
                                }
}

{let text2:TextField = {TextField
                                   width = 3cm
                                }
}

{HBox
    {VBox
        “↓小文字入力不可”,
        text1
    },
    {Fill width = 0.5cm},
    {VBox
        “↓小文字入力可”,
        text2
    }
}

また、APIリファレンスの
[CURL.LANGUAGE.STRINGS]-[StringInterface]
の項内のメソッド[to-upper-clone]の項をご参照ください。 

また以下のFAQをご参照ください。
http://developers.curlap.com/faq/48-faq-specification/706-combobox.html

ドラッグ&ドロップによるBoxの伸縮

【ご質問】
ドラッグ&ドロップでBoxオブジェクトのサイズ変更することは可能でしょうか。

【回答】
PointerPress、PointerMotion、PointerReleaseのイベントを使用することで実現可能です。

サイズを変えたいオブジェクト上でPointerPressイベントが発生したタイミングで
PointerMotionイベントを貼り付けます。
そのPointerMotionイベントではマウスの動きに合わせてオブジェクトのサイズを変更します。
そして、PointerReleaseイベントで貼り付けたPointerMotionイベントを取り除きます。

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

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

{value
    let frame:#Frame
    let start-x:Distance
    let start-width :Distance
   
    let p-mo:EventHandler = {on e:PointerMotion at canvas:Canvas do
                                             set frame.width = start-width + (e.x – start-x)
                                         }
    let canvas:Canvas = {Canvas width = 15cm, height = 10cm,
                                      background = “silver”,
                                     {on e:PointerRelease at canvas:Canvas do
                                         {try
                                             {canvas.remove-event-handler p-mo}
                                          catch e:Exception do
                                             ||do nothing
                                         }
                                     }
                                 }
    set frame = {Frame width = 3cm, height = 3cm, background = “#D4D0C8”,
                          border-width = 1pt, border-color = “black”,
                          {VBox {Fill},
                              {HBox {Fill},
                                  {Frame width = 10pt, height = 10pt, background = “red”,
                                      {on e:PointerPress at f:Frame do
                                          let (canvas-x:Distance, canvas-y:Distance) =
                                               {frame.get-origin-in-graphical-ancestor canvas}
                                          set start-x = canvas-x + e.x
                                   
                                          set start-width = f.width
                                          {canvas.add-event-handler p-mo}
                                          {e.continue-implicit-pointer-grab canvas}
                                     }
                                 }
                             }
                         }
                     }

    {canvas.add frame, x = 4cm, y = 4cm}
    canvas
}

アプレット起動時に表示されるスクロールバーの制御

【ご質問】
ブラウザ上で実行するアプレット(.curl)ではデフォルトで縦スクロールバーが表示されます。
縦スクロールバーを非表示にすることは可能でしょうか。

【回答】
document-styleをPlainDocumentにしてはいかがでしょうか。
デフォルトのDefaultDocumentではスクロールバーが表示されますが、
PainDocumentにすればスクロールバーなしとなります。
画面に収まりきらないコンテンツがある場合は、ScrollBoxを
利用してスクロールさせる画面にすればよいのではないでしょうか。

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

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

{document-style PlainDocument}

{value
    {ScrollBox width = {make-elastic}, height = {make-elastic},
        {Frame width = 20cm, height = 20cm, background = “aliceblue”,
            valign = “top”,
            {VBox
                {TextDisplay
                    width = 5cm,
                    value = “This is TextDisplay”},
                {TextField
                    width = 5cm,
                    value = “This is TextField”},
                {Fill height = 10pt},
                {TextArea width = 5cm, height = 5cm},

                {Fill height = 20pt}
            }
        }
    }
}

また、APIリファレンスの
[CURL.ENGINE.APPLET]-[document-style]
の項をご参照ください。