「Curlにて実現したい動作について」カテゴリーアーカイブ

Curlに対する要求仕様について、過去にお問い合わせの多かった事例を紹介いたします。記載日時点での状況(最新or問い合わせ時指定バージョンにおける仕様)を元に回答したものです。
 

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
}

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]の項をご参照ください。 

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]
の項をご参照ください。 

Curl外のURLを別ウインドウで開く

【ご質問】
Curl以外のURLを別ブラウザで開く際、新たに開かれるウインドウの
サイズやステータスバーの有無を制御することは可能でしょうか。

【回答】
残念ながらCurlから直接ブラウザウィンドウのサイズを制御することや
ブラウザウィンドウのステータスバー、メニューの表示などをコントロールすること不可能です。

Curlから別URLを別ウィンドウ(サイズ指定、ステータスバーの有無指定など)で開くのであれば、
Curlから一度、ウィンドウサイズ等の指定を行なうJavaScriptを含むページに遷移し、
そこから目的のページに遷移させてはどうでしょうか。

Curlアプレット(browse-urlプロシージャ使用)

JavaScriptを使用したページ(ウィンドウサイズ指定、ステータスバー指定など)

目的のページ

サンプルをご参照ください。
(JUMPボタンの処理内容、sample.html内の処理内容)

※JavaScriptを含んだページはブラウザのセキュリティ制限などによって自動的に実行されない場合があります。
  よってウインドウサイズが変わらない、自動的に遷移しないなどの挙動が見られる可能性があります。

TextDisplayフィールドの値のコピーについて

【ご質問】
TextDisplayフィールドの内容を選択し、クリップボードへコピーすることは可能でしょうか。

【回答】
残念ながらTextDisplayで表示させている値をマウスで選択して
コピーをすることは出来ません。
TextDisplayはあくまでも表示だけのコントロールであり、
表示されている文字を選択することも想定されておりません。

TextDisplayに似たような外観のTextFieldを作成して使用するのはどうでしょうか。
 TextField.editable? = false
と設定すると編集することは出来なくなりますが、選択することは可能です。

{TextField
    control-content-background = “#E0E0E0”,
    editable? = false,
    value = “This is TextField”
}

印刷用紙サイズの指定

【ご質問】
印刷時に使用する用紙サイズの変更を行いたいのですが、可能でしょうか。

【回答】
{print-graphic}プロシージャのpage-descriptionを指定することで用紙サイズの指定が可能です。

以下のサンプルを参考にして下さい。

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

{import * from CURL.GRAPHICS.PRINTER}
{value
    let pf:#PrintRootFrame
    let g:Graphic={Frame font-size = 15pt, width=1in, height=1in, background=“red”, “test”}

    ||get-page-descriptionでPrintPageDescriptionを取得する
    let ppds:#{Array-of PrintPageDescription} = {Printer.get-page-description
                                                    {if-non-null pn = {Printer.get-current-printer} then
                                                        pn else “”
                                                    }
                                                }
    ||用紙一覧を作成するためのデータモデル
    let size-model:DefaultListModel = {DefaultListModel {splice ppds}}
    ||用紙一覧を表示するリストボックス
    let list-box:ListBox = {ListBox
                               selection-policy = “single”,
                               width = 10cm,
                               height = 10cm,
                               data-model = size-model,
                               list-item-creation-proc = {proc {val:any}:ListItem
                                                             let ppd:PrintPageDescription = val asa PrintPageDescription
                                                             {return
                                                                 {ListValueItem ppd, label = ppd.description}
                                                             }
                                                         }
                           }

    let cb:CommandButton =
        {CommandButton label=“test printing”,
            {on Action do              
                set pf = {print-graphic g,
                             ||リストボックスで選択した用紙(PrintPageDescription)を設定する
                             page-description = list-box.value[0],
                             ||縦、横を設定する
                             orientation =PageOrientation.landscape                            
                         }
            }
        }
    let v:View = {View
                     {Frame width = 14cm, height = 10cm,
                         {VBox list-box, cb}
                     },
                     visibility = “normal”,
                     {on WindowClose do
                         {exit}
                     }
                 }
    {v.show}
}

尚、指定する用紙の文字列は”指定したプリンタが返す文字列”と必ず一致させる必要があることにご注意ください。
プリンタによっては、用紙の名称が半角や全角、空白を含むなど、同じ名称でも文字列が若干異なる可能性があります。
(例.”A4″(半角)と”A4”(全角))

正常に機能しない場合は、まずは印刷可能な用紙の種類や名称の文字列などの違いをご確認ください。

詳細は、APIリファレンスの
[CURL.GUI.BASE]-[print-graphic]
の項をご参照ください。

ウインドウを最前面に表示させる

【ご質問】
実行中のアプレットが他のウィンドウの下に隠れている場合でも、
一番前に表示させたいのですが可能でしょうか。

【回答】
独立型アプレット(.dcurl)であれば実現が可能です。

独立型アプレットは通常1つ以上のViewを作成する必要があります。
Viewクラスにはウィンドウを最上位に表示するためのraiseメソッドやset-topmostメソッドがあります。

Curlアプレットでイベントが実行される際にこれらのメソッドを呼びだすことで実現可能です。

詳細は、APIリファレンスの
[CURL.GUI.BASE]-[View]
の項内のメソッド[raise]及びに[set-topmost]の項をご参照ください。 

独立型アプレット呼び出し時のパラメータについて

【ご質問】
独立型アプレットを起動する際に、URLにパラメータを指定出来ますか。
また、その値をCurlアプレットから取得することは可能でしょうか。

【回答】
パラメータを指定して独立型アプレットを起動することは可能です。

また、Appletクラスのurlフィールドを使用することで起動時のURLを取得可能です。
{get-the-applet}.urlで起動するUrlオブジェクトが取得できます。

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

1.以下のコードを記載した独立型アプレット(start.dcurl)を作成してWebサーバ上に配置して下さい。

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

{View
    {VBox
        {CommandButton
            label = “URL表示”,
            {on Action do
                let str = {get-the-applet}.url
                {popup-message str}
            }
        }
    },
    visibility = “normal”,
    {on WindowClose do
        {exit}
    }
}

2.以下のコードを記載したCurlアプレット(.curlファイル)を作成して実行して下さい。

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

{CommandButton
    label = “dcurl起動”,
    {on Action do
        {browse-url target = “_blank”,
            {url “curl://launch/http://[Webサーバのアドレス]/start.dcurl?foo=bar”}
        }
    }
}

3.「dcurl起動」ボタンを押すとstart.dcurlが起動します。
  start.dcurl上の「URL表示」ボタンを押すとパラメータ部分を含むURLが取得出来ていることが分かります。
379-2010-10-18-05-36-23.png