ファイル選択ダイアログ †
ファイル選択ダイアログを出すにはdialog命令を使います。
書式は以下のようになっています。
dialog "extension" , style , "type"
extension : 拡張子を表す文字列を指定します。
ここに指定した拡張子のファイルがダイアログボックスに表示されます。
style : ダイアログのスタイルを指定します。
16でファイル選択ダイアログ、17でファイル保存ダイアログを表示します。
type : extensionに対するファイルの種類を表す名前を指定します。
ここに指定した名前が[ファイルの種類]コンボボックスに反映します。
では実際の使用例を示します。
1
2
3
4
5
6
|
| 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
|
| 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の式を理解している人は上の式の意味は分かると思います。
選択可能な拡張子は「;」で拡張子を区切ればいいと分かりました。
しかし場合によっては「画像ファイル」「音楽ファイル」「テキストファイル」などと複数のファイルの種類に区分けしたい場合もあると思いますが、それはHSP標準命令では出来ません。
何故出来ないのかは後で説明するとしてファイルの種類を増やすにはWin32APIのGetOpenFileName?()関数を呼び出します。(HSPのdialog命令も内部でこれを呼んでいる。)
ここではAPIの説明は省き、実際に呼び出してみることにします。APIの呼び出しにはllmodを使用しています。
引越し前より読みやすく編集しました。
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
|
-
|
!
| #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 ofn.1 = bmscr.13 ofn.2 = bmscr.14 getptr ofn.3 , aplFilter getptr ofn.4 , usrFilter ofn.5 = FILTERSIZE ofn.6 = 1 getptr ofn.7 , filename ofn.8 = BUFSIZE ofn.9 = 0 ofn.10 = 0 ofn.11 = 0 ofn.12 = 0 ofn.13 = OFN_FILEMUSTEXIST
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構造体のフィルターメンバに渡されるはずですね?
では実際に出来るかどうかテストしましょう。
v2try_dialog[sp].as
どうでした?思い通りにならなかったですね・・・。「画像ファイル (*.bmp;*.mag;*.jpg) (*.txt)」という変な表示になってしまいました。
分かっていても思い通り失敗してくれたので僕的には笑えましたけど^^;
理由は文字列操作ページの文字列連結を読んでください。
2010/11/8
ファイルの種類を増やす方法が見つかりました。
画像ファイルと文書ファイルを選択したい時は、
1
|
| dialog "bmp"+"\ntxt",16,"画像ファイル"+"\n文書ファイル"
|
とすると、"文書ファイル(*.txt)"が次の行に移っているはずです。
ここが猫太さんの予約場所^^;
分からないことはコメント欄に書いてください。
多分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 ofn.1 = bmscr.13 ofn.2 = bmscr.14 ofn.3=varptr(aplFilter) ofn.4=varptr(usrFilter) ofn.5 = FILTERSIZE ofn.6 = 1 ofn.7=varptr(filename) ofn.8 = BUFSIZE ofn.9 = 0 ofn.10 = 0 ofn.11 = 0 ofn.12 = 0 ofn.13 = OFN_FILEMUSTEXIST
prm=varptr(ofn)
GetOpenFileName prm
if stat = 0{
dialog "失敗" , 0 , "終了確認" : end
}
title filename
stop
|
順番的には上で猫太さんがHSP3に移植してくれているハズなので移植が終わったら次にやることは複数ファイルを選択してみることです。(HSP2BBSからネタ拾い)
しかし・・・今書くと猫太さんの移植が・・・。
とりあえず回答の出ていない今のうちにパクリでないことを示すために簡単に。
フラグにOFN_ALLOWMULTISELECTを指定する。ただしこれだけだとテンプレートからダイアログが作られるので、
エクスプローラー風のものを使用するときは、OFN_EXPLORERも一緒に指定する。
これでよしっと^^;
予約。
- はい、GetOpenFileName?()のフィルター文字列を説明しようとしましたが、すでにちょくとさんのところに詳細な情報があるのでここで説明してもしかたないので(ぁ)APIや構造体やフィルターの意味を知りたい人はちょくとさんのページで調べてください。 -- kz3
- ちょくとさんのページはリンクフリー(トップページだよね)ということなので、まずこっち側でリンクを貼っておいて、これからちょくとさんの掲示板で「リンク貼らせていただきました、相互リンクお願いしますm_ _m」と掲示板に書き込んできます^^; -- kz3
- バナーなどがあるため、この辺りはCharlotteさんじゃないと分からないのでお願いしにいくのはちょっとお休み。 -- kz3
- で、猫太さんへの移植に関する説明です。今回必要なことを列挙してみましたよ〜。意味はちょくとさんのところで。
- GetOpenFileName?()のプロトタイプ(引数)と関数のあるDLL(引数はOPENFILENAME構造体へのポインタでcomdlg32.dllに関数あり)
- OPENFILENAME構造体とそのメンバ(構造体サイズは88バイト)
- ポインタ(ポインタとは参照元が自分自身を指し示す矢印)
- HSPでヌル文字はリラテル内で展開されない(ヌル文字の代わりになる文字に置き換えておいて)
- なので自分でヌル文字を書き込まなくてはいけない(置き換えた文字を検索してヌル文字を書き込む)
- HSP2とHSP3の違い
HSP2 | HSP3 |
---|
lmodを使ってDLL関数を呼び出す。 | #uselibと#funcで使用するDLLと関数を指定(宣言)する。 |
getptrでポインタを取得する。 | varptrでポインタを取得する。 |
instr命令 | instr()関数 |
文字列変数は自前で確保 | 文字列変数は代入による自動確保が効く ただしそれはHSPが自分の資源を使う時だけで、外部に依頼する場合はそこまで面倒を見てくれない |
- または、ちょくとさんのページを読んで分からなかったことを書くのも○
説明できるものは説明します^^; -- kz3
- ファイルの種類を増やすの説明が下手ですみません;; -- kz3
- 複数のファイルの選択についてはhsp2bbsに回答がでてますね。multiopenでできるようです。私も出来ないと思い込んでたんで目からうろこです。ちなみにヘルプブラウザのサンプルはllmod.asとmultiopen.asをincludeしないと動作しない。ヘルプブラウザのヘルプはたまにこういう部分があって困る。 -- GENKI?
- 出てたの気づいてましたー!知らない命令がまだまだあるものです・・・。
あぁ・・・必要ファイルも含めたサンプルを載せて欲しいってことですねぇ。 -- kz3
- しかしOPENFILENAME構造体にはいろいろ便利なメンバがあるのでここでは直接APIをいじっていきます!`ゝ´)フォー! -- kz3
- HG?! -- GENKI?
- HGって何ですか??^^; -- kz3
- 猫太さん来ないかなぁ・・・帰っちゃったかなぁ・・・トボトボ;´;ω;`) -- kz3
- HG?これでつ。だってフォーって… -- GENKI?
- 良く分からなかったですがそれは`_ゝ´)フゥー!!じゃないですか?^^; -- kz3
- 分かりましたよ・・・やっと。本日発売のFLASHという雑誌に載ってました・・・。普段はラジオだけ(それもフランスのネットラジオです。)しか聞いてないのでまったく(日本の)TV事情、芸能事情は分かりません・・・。(フランスのネットラジオも分かりません。汗) -- kz3
- 猫太さんが移植してくれるまで私kz3は移植版を書きません!2.61で書き続けます!ε=`ム´プンスカ(ギャグですよ?)
せっかくHSP2とHSP3の違いも書いたのに・・・列挙もしたのに・・・;ω;グスン
白じゃなくて灰色にしておこうかな。(謎) -- kz3
- kz3さんすっかりここの存在を忘れてましたm(__)mさっきHSP3化が完了したんですけど、どうすれば・・・。 -- 猫太?
- 「HSP3に移植する」の鉛筆アイコンをクリックしてコメント部分にペーストするか、ファイルを「添付」より添付するかしたら僕がペーストしておきますよ^^ 忘れちゃダメですよー! -- kz3
- 貼り付けましたぞ!! -- 猫太?
- は〜い、お疲れ様です!移植一色です。(謎 -- kz3
- 選択可能なファイルの種類を増やす の項目で、『"txt"+"\nexe"』と書けばテキストファイルと実行ファイルを分けれることが判明 -- 検討して?
ここは話の流れを残しておくという意味で残してあります。お話は「コメント」の方にお願いします。
- 上の仕組みをAPIを使って直に操作するとこうなります。
つまり、dialogはAPIにフィルター文字列を渡すのにp1とp3を単純に連結してワイルドカードを先頭につけているだけだと分かると思います。
- いや本当にbsaveの新規作成/上書きモードは自分の為になった。^^; -- kz3
- さっき思い出したので書かせてもらいました。書くならここが一番適当かなと。<ファイルダイアログ -- GENKI?
- ところでファイルの種類のところのリストボックスに項目ふやすのは方法ってあるんでしょうか? -- GENKI?
- 無駄足じゃなかったです!!
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
- HSP標準のdialogだと出来ないっぽいです・・・。というわけでAPIを直接やるしか無い様ですが、こんな感じでいいのかなぁ。
ソースをどこに置くべきか迷ったのでとりあえずここにおきます! -- kz3
- ってなんか載ってます!!!そうか・・・道理で「as;hsp」→「*as;hsp」になってしまうわけだ・・・。単純にフィルター文字列にワイルドカードをくっつけてるだけなんだね・・・。ショボーン
自分、こんなもの書いてました;; -- kz3
- getopenfilename.asの中で「@」はヌル文字の代わりです。
Cだと文字列中で「\0」と記述するとヌル文字($00)を表すのですが、HSPだと"\0"は文字0($30)になってしまい、文字列リラテルでヌル文字を表せません・・・。 -- kz3
- 文字列+数値=文字列+数値文字になってしまうから、"\0"==""+$00=="0"という事か・・・。 -- kz3
- すいません・・・。このソースをHSP3化できますでしょうか?? -- 猫太?
- いらっしゃ〜い、猫太さん^^;
出来ますよ。 -- kz3
- どのようにやるんですか?? -- 猫太?
- どのようにやるんですか?? -- 猫太?
- まず上のソースは理解できていますか? -- kz3
- まずllmodを呼んでリストに表示する文字列を設定してCOMDLGのGetOpenFileNameAを呼んでパラメータを渡してるんだと思います。 -- 猫太?
- う、うん・・・大体そうです。とりあえず、じゃぁこうしましょう。
猫太さん、上のソースをHSP3に書き換えたものを新しいページを作ってそこに載せちゃってください^^
お話はそちらにしましょう。ちょっとここのページ長くなってきた´ロ` -- kz3
- 作ってくださいとか言いながら自分で作りました。汗。
HSP3への移植は猫太さん担当。(独断) -- kz3