hinekure.net が http://hspdev-wiki.net/ から自動クローリングした結果を表示しています。画像やリソースなどのリンクが切れています。予めご了承ください。
小ワザ/ファイル選択ダイアログ - HSP開発wiki
トップ    編集凍結 差分バックアップ添付複製名前変更リロード   新規一覧単語検索最終更新   最終更新のRSS

ファイル入出力|ファイル保存ダイアログ

HSP2.61 HSP3.0

ファイル選択ダイアログ

ファイル選択ダイアログを出すにはdialog命令を使います。
書式は以下のようになっています。

dialog "extension" , style , "type"
extension : 拡張子を表す文字列を指定します。
            ここに指定した拡張子のファイルがダイアログボックスに表示されます。
style     : ダイアログのスタイルを指定します。
            16でファイル選択ダイアログ、17でファイル保存ダイアログを表示します。
type      : extensionに対するファイルの種類を表す名前を指定します。
            ここに指定した名前が[ファイルの種類]コンボボックスに反映します。

では実際の使用例を示します。

  1
  2
  3
  4
  5
  6
 
 
 
 
 
 
    ; < HSP2.61 > <HSP3.0a>
    dialog "as" , 16 , "えいちえすぴいすくりぷと"
 
    if stat = 0 : end
    mes refstr
    stop

ダイアログの[ファイルの種類]コンボボックスに注目してください。
「えいちえすぴいすくりぷと (*.as)」となっていると思います。
そしてディレクトリをいろいろ移動してasファイルだけ(実際は移動のためにフォルダも表示されますが。)がリストビューに表示していることも確認してください。
このいろんな拡張子の中からas拡張子だけを取り出す(抽出)する役割の"extension"パラメータをここでは「フィルター」と呼ぶことにします。

選択可能な拡張子を増やす

ファイルダイアログはフルパスファイル名を取得することが出来ます。
マニュアルでは1種のファイルしか対応しないとの記述になっていますが、複数のファイル形式を指定することもできます。

複数の拡張子を表示させる場合は「;(セミコロン)」で区切って記述します。
次の例はbmp,mag,jpgファイルの3つを選択可能にします。

  1
  2
  3
  4
  5
  6
 
 
 
 
 
 
    ; < HSP2.61 > < HSP3.0a>
    dialog "bmp;*.mag;*.jpg" , 16 , "画像ファイル"
    if stat = 0 : end
    title refstr
    picload refstr
    stop

今度は[ファイルの種類]コンボボックスの内容が「画像ファイル (*.bmp;*.mag;*.jpg)」になりましたね?
そしてリストビューには指定した3つの拡張子のファイルが表示されるようになったと思います。
HSPでは"extension"に指定した文字列と"type"に指定した文字列を次のように連結しているだけなんですね。

dialog "extension" , style , "type"

-> type + " (*." + extension + ")"

HSPの式を理解している人は上の式の意味は分かると思います。

written by GENKI?さん
editor : kz3

選択可能なファイルの種類を増やす

選択可能な拡張子は「;」で拡張子を区切ればいいと分かりました。
しかし場合によっては「画像ファイル」「音楽ファイル」「テキストファイル」などと複数のファイルの種類に区分けしたい場合もあると思いますが、それはHSP標準命令では出来ません。
何故出来ないのかは後で説明するとしてファイルの種類を増やすにはWin32APIのGetOpenFileName?()関数を呼び出します。(HSPのdialog命令も内部でこれを呼んでいる。)
ここではAPIの説明は省き、実際に呼び出してみることにします。APIの呼び出しにはllmodを使用しています。

引越し前より読みやすく編集しました。
filev2api_GetOFN[sp].as
Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
-
|
!
 
 
 
 
    ; <HSP2.61>
    #include "llmod.as"
 
    #define BUFSIZE     260
    #define FILTERSIZE  512
 
    #define ALLTYPE     "ALL files (*.*)@*.*@"
    #define PICTURE     "画像ファイル (*.bmp;*.mag;*.jpg)@*.bmp;*.mag;*.jpg@"
    #define SOUND       "音楽ファイル (*.mid;*.mp3;*.wav)@*.mid;*.mp3;*.wav@"
    #define DOCUMENT    "文書ファイル (*.txt)@*.txt@"
 
    #define OFN_FILEMUSTEXIST   $00001000
 
    mref bmscr , 67
    
    dim  ofn       , 22
    sdim aplFilter , FILTERSIZE+1
    sdim usrFilter , FILTERSIZE+1
    sdim filename  , BUFSIZE+1
 
    aplFilter  = PICTURE + SOUND + DOCUMENT + ALLTYPE + "@"
    usrFilter  = "ユーザ選択フィルタ (*.*)@*.*@" + "@"
 
    repeat
        await 0
        instr mutch , aplFilter , "@" , start
        if mutch = -1 : break
        poke aplFilter , start + mutch , $00
        start += mutch + 1
    loop
    start = 0
    repeat
        await 0
        instr mutch  ,usrFilter , "@" , start
        if mutch = -1 : break
        poke usrFilter , start + mutch , $00
        start += mutch + 1
    loop
 
        ofn.0   = 88                ; lStructSize
        ofn.1   = bmscr.13          ; hwndOwner
        ofn.2   = bmscr.14          ; hInstance
getptr  ofn.3   , aplFilter         ; lpstrFilter
getptr  ofn.4   , usrFilter         ; lpstrCustomFilter
        ofn.5   = FILTERSIZE        ; nMaxCustFilter
        ofn.6   = 1                 ; nFilterIndex
getptr  ofn.7   , filename          ; lpstrFile
        ofn.8   = BUFSIZE           ; nMaxFile
        ofn.9   = 0                 ; lpstrFileTitle
        ofn.10  = 0                 ; nMaxFileTitle
        ofn.11  = 0                 ; lpstrInitialDir
        ofn.12  = 0                 ; lpstrTitle
        ofn.13  = OFN_FILEMUSTEXIST ; Flags
 
getptr  prm     , ofn
 
    dllproc "GetOpenFileNameA" , prm , 1 , D_COMDLG
    if dllret = 0{
        dialog "失敗" , 0 , "終了確認" : end
    }
 
    title filename
 
    stop

[ファイルの種類]コンボボックスに画像、音楽、文書、ALLという種類に分けられました。
ここではフィルターがどういう構造になっているかを説明します。(ちょくとさんとこにもあったかな?ありました。)
ということで説明は省きます。(ぇ

とりあえず、どうしてdialogだけではファイルの種類を増やせないのかを説明。dialog命令では、"extension"と"type"を

type + " (*." + extension + ")"

というように連結するといいました。そして[ファイルの種類]の内部文字列は、

type + " (*." + extension + ")" + $00 + extension + $00 + ... + "すべてのファイル (*.*)" + $00 + "*.*" + $00 + $00

というようになっています。
「すべてのファイル (*.*)」はHSPが付加します。もしかしたら「すべての(略)」はカスタムフィルター(lpstrCustomFilter?メンバ)として設定されており、dialogで指定する文字列はアプリケーション定義のフィルター(lpstrFilterメンバ)に指定しているのかも知れません。
いや後者の方が強いかな。というわけで[ファイルの種類]の内部文字列を修正して

type + " (*." + extension + ")" + $00 + extension + $00 + $00

となっているとします。

ここで[ファイルの種類]は上記のtypeとextensionを1組の種類として


type + " (*." + extension + ")" + $00 + extension + $00 ・・・ T
T@@1@@ + T@@2@@ + T@@3@@ + ... + T@@n@@ + $00

というようになっています。そしてTの集合をTYPEと考えると次のように考えられそうですよね?


type + " (*." + extension + ")" + $00 + extension + $00 ・・・ T
T@@1@@ + T@@2@@ ・・・ TYPE

TYPE + type + " (*." + extension + ")" + $00 + extension + $00 + $00

アンダーバー部分は文字列の連結と考えれば

TYPE + type ・・・ type よって
type + " (*." + extension + ")" + $00 + extension + $00 + $00

最初の式に戻りましたね?つまりtypeに内部書式文字列を設定してしまえばdialog命令でも出来るのではないか?ということです。
この考えをもとに擬似コーディングしてみると[ファイルの種類]の文字列設定部分は次のようになると思います。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
    #define FILTERSIZE  512
    #define PICTURE     "画像ファイル (*.bmp;*.mag;*.jpg)@*.bmp;*.mag;*.jpg@"
    #define SOUND       "音楽ファイル (*.wav;*.mp3;*.mid)@*.wav;*.mp3;*.mid@"
 
    sdim type , FILTERSIZE+1
 
    type = PICTURE + SOUND + "文書ファイル"
 
    repeat
        instr mutch , type , "@" , start
        if mutch = -1 : break
        poke type , start + mutch , $00
        start += mutch + 1
    loop
 
    dialog "txt" , 16 , type

このようにすると、dialog命令実行時点でのtypeの中身は、

"画像ファイル (*.bmp;*.mag;*.jpg)" + $00 +"*.bmp;*.mag;*.jpg" + $00 + 音楽ファイル (*.wav;*.mp3;*.mid)" + $00 + "*.wav;*.mp3;*.mid" + $00 + "文書ファイル"

となっているのは分かりますね?これにextensionを以下のように連結するので、

type + " (*." + extension + ")" + $00 + "*." + extension + $00 + $00

"画像ファイル (*.bmp;*.mag;*.jpg)" + $00 +"*.bmp;*.mag;*.jpg" + $00 + 音楽ファイル (*.wav;*.mp3;*.mid)" + $00 + "*.wav;*.mp3;*.mid" + $00 + "文書ファイル (*.txt)" + $00 + "*.txt" + $00 + $00

という文字列がOPENFILENAME構造体のフィルターメンバに渡されるはずですね?
では実際に出来るかどうかテストしましょう。 filev2try_dialog[sp].as

どうでした?思い通りにならなかったですね・・・。「画像ファイル (*.bmp;*.mag;*.jpg) (*.txt)」という変な表示になってしまいました。
分かっていても思い通り失敗してくれたので僕的には笑えましたけど^^;
理由は文字列操作ページの文字列連結を読んでください。

2010/11/8
ファイルの種類を増やす方法が見つかりました。 画像ファイルと文書ファイルを選択したい時は、

  1
 
     dialog "bmp"+"\ntxt",16,"画像ファイル"+"\n文書ファイル"

とすると、"文書ファイル(*.txt)"が次の行に移っているはずです。

HSP3に移植する

ここが猫太さんの予約場所^^;
分からないことはコメント欄に書いてください。 多分wikiの編集の仕方も分からないと思う。
とりあえずソースを載せる雛形だけ作っておこう。
wikiの編集はページ上の[編集]というのをクリック。そしてこのページのソースを直接みてください。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
-
|
!
 
 
#uselib "Comdlg32.DLL"
#func GetOpenFileName "GetOpenFileNameA" int
 
#define BUFSIZE     260
#define FILTERSIZE  512
#define ALLTYPE                "ALL files (*.*)@*.*@"
#define PICTURE                "画像ファイル (*.bmp;*.mag;*.jpg)@*.bmp;*.mag;*.jpg@"
#define SOUND                "音楽ファイル (*.mid;*.mp3;*.wav)@*.mid;*.mp3;*.wav@"
#define DOCUMENT            "文書ファイル (*.txt)@*.txt@"
#define OFN_FILEMUSTEXIST    $00001000
 
    mref bmscr , 67
    
    dim  ofn  , 22
    sdim aplFilter , FILTERSIZE+1
    sdim usrFilter , FILTERSIZE+1
    sdim filename  , BUFSIZE+1
 
    aplFilter  = PICTURE + SOUND + DOCUMENT + ALLTYPE + "@"
    usrFilter  = "ユーザ選択フィルタ (*.*)@*.*@" + "@"
 
    repeat
        await 0
        mutch=instr(aplFilter,start,"@")
        if mutch = -1 : break
        poke aplFilter , start + mutch , $00
        start += mutch + 1
    loop
    start = 0
    repeat
        await 0
        mutch=instr(usrFilter,start,"@")
        if mutch = -1 : break
        poke usrFilter , start + mutch , $00
        start += mutch + 1
    loop
    
        ofn.0    = 88                ; lStructSize
        ofn.1    = bmscr.13          ; hwndOwner
        ofn.2    = bmscr.14          ; hInstance
        ofn.3=varptr(aplFilter)         ; lpstrFilter
        ofn.4=varptr(usrFilter)         ; lpstrCustomFilter
        ofn.5    = FILTERSIZE        ; nMaxCustFilter
        ofn.6    = 1                  ; nFilterIndex
        ofn.7=varptr(filename)          ; lpstrFile
        ofn.8    = BUFSIZE           ; nMaxFile
        ofn.9    = 0                  ; lpstrFileTitle
        ofn.10  = 0                  ; nMaxFileTitle
        ofn.11  = 0                  ; lpstrInitialDir
        ofn.12  = 0                  ; lpstrTitle
        ofn.13  = OFN_FILEMUSTEXIST ; Flags
        
        prm=varptr(ofn)
 
        GetOpenFileName prm
        if stat = 0{
            dialog "失敗" , 0 , "終了確認" : end
        }
    title filename
    stop

複数ファイルを選択する

順番的には上で猫太さんがHSP3に移植してくれているハズなので移植が終わったら次にやることは複数ファイルを選択してみることです。(HSP2BBSからネタ拾い)
しかし・・・今書くと猫太さんの移植が・・・。
とりあえず回答の出ていない今のうちにパクリでないことを示すために簡単に。

フラグにOFN_ALLOWMULTISELECTを指定する。ただしこれだけだとテンプレートからダイアログが作られるので、 エクスプローラー風のものを使用するときは、OFN_EXPLORERも一緒に指定する。

これでよしっと^^;

初期ディレクトリを指定する

予約。

コメント

  • はい、GetOpenFileName?()のフィルター文字列を説明しようとしましたが、すでにちょくとさんのところに詳細な情報があるのでここで説明してもしかたないので(ぁ)APIや構造体やフィルターの意味を知りたい人はちょくとさんのページで調べてください。 -- kz3 2005-10-01 11:43:47 (土)
  • ちょくとさんのページはリンクフリー(トップページだよね)ということなので、まずこっち側でリンクを貼っておいて、これからちょくとさんの掲示板で「リンク貼らせていただきました、相互リンクお願いしますm_ _m」と掲示板に書き込んできます^^; -- kz3 2005-10-01 11:45:13 (土)
  • バナーなどがあるため、この辺りはCharlotteさんじゃないと分からないのでお願いしにいくのはちょっとお休み。 -- kz3 2005-10-01 12:13:44 (土)
  • で、猫太さんへの移植に関する説明です。今回必要なことを列挙してみましたよ〜。意味はちょくとさんのところで。
    • GetOpenFileName?()のプロトタイプ(引数)と関数のあるDLL(引数はOPENFILENAME構造体へのポインタでcomdlg32.dllに関数あり)
    • OPENFILENAME構造体とそのメンバ(構造体サイズは88バイト)
    • ポインタ(ポインタとは参照元が自分自身を指し示す矢印)
    • HSPでヌル文字はリラテル内で展開されない(ヌル文字の代わりになる文字に置き換えておいて)
      • なので自分でヌル文字を書き込まなくてはいけない(置き換えた文字を検索してヌル文字を書き込む)
  • HSP2とHSP3の違い
    HSP2HSP3
    lmodを使ってDLL関数を呼び出す。#uselibと#funcで使用するDLLと関数を指定(宣言)する。
    getptrでポインタを取得する。varptrでポインタを取得する。
    instr命令instr()関数
    文字列変数は自前で確保文字列変数は代入による自動確保が効く
    ただしそれはHSPが自分の資源を使う時だけで、外部に依頼する場合はそこまで面倒を見てくれない
  • または、ちょくとさんのページを読んで分からなかったことを書くのも○
    説明できるものは説明します^^; -- kz3 2005-10-01 16:07:29 (土)
  • ファイルの種類を増やすの説明が下手ですみません;; -- kz3 2005-10-02 09:15:18 (日)
  • 複数のファイルの選択についてはhsp2bbsに回答がでてますね。multiopenでできるようです。私も出来ないと思い込んでたんで目からうろこです。ちなみにヘルプブラウザのサンプルはllmod.asとmultiopen.asをincludeしないと動作しない。ヘルプブラウザのヘルプはたまにこういう部分があって困る。 -- GENKI? 2005-10-02 22:30:33 (日)
  • 出てたの気づいてましたー!知らない命令がまだまだあるものです・・・。
    あぁ・・・必要ファイルも含めたサンプルを載せて欲しいってことですねぇ。 -- kz3 2005-10-02 23:32:50 (日)
  • しかしOPENFILENAME構造体にはいろいろ便利なメンバがあるのでここでは直接APIをいじっていきます!`ゝ´)フォー! -- kz3 2005-10-02 23:33:47 (日)
  • HG?! -- GENKI? 2005-10-03 00:15:23 (月)
  • HGって何ですか??^^; -- kz3 2005-10-03 08:36:01 (月)
  • 猫太さん来ないかなぁ・・・帰っちゃったかなぁ・・・トボトボ;´;ω;`) -- kz3 2005-10-03 11:13:13 (月)
  • HG?これでつ。だってフォーって… -- GENKI? 2005-10-03 23:12:07 (月)
  • 良く分からなかったですがそれは`_ゝ´)フゥー!!じゃないですか?^^; -- kz3 2005-10-03 23:21:08 (月)
  • 分かりましたよ・・・やっと。本日発売のFLASHという雑誌に載ってました・・・。普段はラジオだけ(それもフランスのネットラジオです。)しか聞いてないのでまったく(日本の)TV事情、芸能事情は分かりません・・・。(フランスのネットラジオも分かりません。汗) -- kz3 2005-10-04 09:01:29 (火)
  • 猫太さんが移植してくれるまで私kz3は移植版を書きません!2.61で書き続けます!ε=`ム´プンスカ(ギャグですよ?)
    せっかくHSP2とHSP3の違いも書いたのに・・・列挙もしたのに・・・;ω;グスン
    白じゃなくて灰色にしておこうかな。(謎) -- kz3 2005-10-04 09:15:32 (火)
  • kz3さんすっかりここの存在を忘れてましたm(__)mさっきHSP3化が完了したんですけど、どうすれば・・・。 -- 猫太? 2005-11-13 (日) 17:04:45
  • 「HSP3に移植する」の鉛筆アイコンをクリックしてコメント部分にペーストするか、ファイルを「添付」より添付するかしたら僕がペーストしておきますよ^^ 忘れちゃダメですよー! -- kz3 2005-11-13 (日) 23:13:14
  • 貼り付けましたぞ!! -- 猫太? 2005-11-15 (火) 01:50:50
  • は〜い、お疲れ様です!移植一色です。(謎 -- kz3 2005-11-15 (火) 10:34:15
  • 選択可能なファイルの種類を増やす の項目で、『"txt"+"\nexe"』と書けばテキストファイルと実行ファイルを分けれることが判明 -- 検討して? 2010-11-08 (月) 18:18:18

URL B I U SIZE Black Maroon Green Olive Navy Purple Teal Gray Silver Red Lime Yellow Blue Fuchsia Aqua White

引越し前のお話

ここは話の流れを残しておくという意味で残してあります。お話は「コメント」の方にお願いします。
  • 上の仕組みをAPIを使って直に操作するとこうなります。
    つまり、dialogはAPIにフィルター文字列を渡すのにp1とp3を単純に連結してワイルドカードを先頭につけているだけだと分かると思います。
    • 無駄足だったね・・・。 -- kz3 2005-08-08 22:49:22 (月)
  • いや本当にbsaveの新規作成/上書きモードは自分の為になった。^^; -- kz3 2005-07-08 14:16:06 (金)
  • さっき思い出したので書かせてもらいました。書くならここが一番適当かなと。<ファイルダイアログ -- GENKI? 2005-08-08 21:02:24 (月)
  • ところでファイルの種類のところのリストボックスに項目ふやすのは方法ってあるんでしょうか? -- GENKI? 2005-08-08 21:02:24 (月)
    • 無駄足じゃなかったです!!
      dialog p1,p2,p3の記述でAPIには"p3@*.p1@@"というフィルター文字列に加工されて渡されるようです。
      ※「@」は$00と思ってください。
      ファイルの種類は、「種類名1$00ワイルドカード1$00種類名2$00ワイルドカード2$00種類名3$00ワイルドカード3$00...ワイルドカードn$00$00」 という書式なので、dialogだけでは無理そうです。 -- kz3 2005-08-08 23:07:11 (月)
  • HSP標準のdialogだと出来ないっぽいです・・・。というわけでAPIを直接やるしか無い様ですが、こんな感じでいいのかなぁ。
    ソースをどこに置くべきか迷ったのでとりあえずここにおきます! -- kz3 2005-08-08 22:42:38 (月)
  • ってなんか載ってます!!!そうか・・・道理で「as;hsp」→「*as;hsp」になってしまうわけだ・・・。単純にフィルター文字列にワイルドカードをくっつけてるだけなんだね・・・。ショボーン
    自分、こんなもの書いてました;; -- kz3 2005-08-08 22:45:11 (月)
  • getopenfilename.asの中で「@」はヌル文字の代わりです。
    Cだと文字列中で「\0」と記述するとヌル文字($00)を表すのですが、HSPだと"\0"は文字0($30)になってしまい、文字列リラテルでヌル文字を表せません・・・。 -- kz3 2005-08-08 22:53:22 (月)
  • 文字列+数値=文字列+数値文字になってしまうから、"\0"==""+$00=="0"という事か・・・。 -- kz3 2005-08-08 22:56:37 (月)
  • すいません・・・。このソースをHSP3化できますでしょうか?? -- 猫太? 2005-09-29 21:36:38 (木)
  • いらっしゃ〜い、猫太さん^^;
    出来ますよ。 -- kz3 2005-09-29 21:48:32 (木)
  • どのようにやるんですか?? -- 猫太? 2005-09-30 00:29:51 (金)
  • どのようにやるんですか?? -- 猫太? 2005-09-30 00:30:50 (金)
  • まず上のソースは理解できていますか? -- kz3 2005-09-30 05:23:28 (金)
  • まずllmodを呼んでリストに表示する文字列を設定してCOMDLGのGetOpenFileNameAを呼んでパラメータを渡してるんだと思います。 -- 猫太? 2005-09-30 17:32:42 (金)
  • う、うん・・・大体そうです。とりあえず、じゃぁこうしましょう。
    猫太さん、上のソースをHSP3に書き換えたものを新しいページを作ってそこに載せちゃってください^^
    お話はそちらにしましょう。ちょっとここのページ長くなってきた´ロ` -- kz3 2005-10-01 08:56:46 (土)
  • 作ってくださいとか言いながら自分で作りました。汗。
    HSP3への移植は猫太さん担当。(独断) -- kz3 2005-10-01 08:59:32 (土)

添付ファイル:
filev2try_dialog[sp].as
479件 [詳細]
filev2api_GetOFN[sp].as
494件 [詳細]
トップ    編集凍結 差分バックアップ添付複製名前変更リロード   新規一覧単語検索最終更新   最終更新のRSS
Last-modified: 2010-11-08 (月) 19:17:13 (1125d)