できると何かと便利なDrag&Drop。
きっとできるだろうと思ってヘルプ見てみたらやっぱりありました。
けど、サンプルどおりだと動かなくて、
ちょっと手直ししました。
------------
; ドラッグ&ドロップ
#include "llmod3/llmod3.hsp"
#include "llmod3/dragdrop.hsp"
;ドラッグ&ドロップされたファイル名を入れる変数
alloc strDropFilePaths, 1024*64
dd_accept strDropFilePaths, nDropNum
*DDLoop
wait 10
if nDropNum {
cls
pos 0,0
mes "ドラッグ&ドロップされたファイル数:" + nDropNum
mes strDropFilePaths
; nDropNumをリセット
nDropNum = 0
}
goto *DDLoop
------------
dd_acceptで受け入れ開始して、
あとは、Numのリセットを忘れなければいいだけっぽいです。
簡単。
ちなみにdd_rejectで受け入れ停止(D&Dできないようにする)ができるので、
取得した後にdd_rejectするっていうケースもありそうです。
わたくし、XMLというものは知っており、
書けといわれればテキストファイルで書くことはできるレベルです。
そこから先の、
・COMを使って読むとか、
・HTMLを作る的なの(←よく知らない)とか、・・etc
は、ほんとわからない。
なので、今回のプログラムは個人的には力作ですw
1行1行が試行錯誤で、結構大変でした。
やってることは、MSXMLを使って、ファイルを読んでるだけです。
知ってる人にとっては、HSP+COMのところだけがポイントなのかな。
あ、関数の呼び方が結構特殊かも?
---------------
; XMLパーサを使って、XMLファイルを読む
; COMでMSXMLを使う
; 参考1:MSDN1
; 参考2:MSDN2
newcom oDom, "Microsoft.XMLDOM"
oDom("async") = "FALSE"
oDom->"load" "sample.xml"
; root要素を取得
oRoot = oDom("documentElement")
; ルートタグが、であることを確認
if( oRoot("tagName") = "jobs" ){
mes "OK!"
}else{
mes "NG!" + oRoot("tagName")
stop
}
;のノードを取得
nodes_Jobs = oRoot("childNodes")
nJobsNodeNum = nodes_Jobs("length") ; ノードの数
;のノードから、を検索
for i, 0, nJobsNodeNum
mes "item[" + i + "]"
;内のノードリストから、i番目のノードを取得
node_Jobs = nodes_Jobs("item", i)
nodeType = node_Jobs("nodeType")
if( nodeType = 1 ){ ; タグ
if( node_Jobs("tagName") = "job" ){
mes "発見!"
;の属性idの値を取得
atrs_Job = node_Jobs("attributes") ; attribute map
atr_Id = atrs_Job("getNamedItem","ids") ; id
mes "id=" + atr_Id("nodeValue") ; idの値
}else{
; 別のタグ処理
}
}else{
; 別の要素処理
}
next
stop
-----------
使用したsample.xml
<?xml version="1.0" encoding="Shift_JIS"?>
<jobs>
abc
<job id="j11" />
<job id="j12" />
<job id="j13" />
</jobs>
-----------
関数の呼び方といったのは、
;内のノードリストから、i番目のノードを取得
node_Jobs = nodes_Jobs("item", i)
こういうの。
自分で発想することはありえない呼び方です。
そういうお作法的なことがわかれば、
あとはなんとかなるかな~。
あと実際に使用するときは、
MSXMLの関数呼ぶたびに、正常に取得できたか確認しないと、
エラーケースでHSPが落ちるので注意です。
今回の例では、<job />とかidのないタグがあるとダメです。
書けといわれればテキストファイルで書くことはできるレベルです。
そこから先の、
・COMを使って読むとか、
・HTMLを作る的なの(←よく知らない)とか、・・etc
は、ほんとわからない。
なので、今回のプログラムは個人的には力作ですw
1行1行が試行錯誤で、結構大変でした。
やってることは、MSXMLを使って、ファイルを読んでるだけです。
知ってる人にとっては、HSP+COMのところだけがポイントなのかな。
あ、関数の呼び方が結構特殊かも?
---------------
; XMLパーサを使って、XMLファイルを読む
; COMでMSXMLを使う
; 参考1:MSDN1
; 参考2:MSDN2
newcom oDom, "Microsoft.XMLDOM"
oDom("async") = "FALSE"
oDom->"load" "sample.xml"
; root要素を取得
oRoot = oDom("documentElement")
; ルートタグが、
if( oRoot("tagName") = "jobs" ){
mes "
}else{
mes "
stop
}
;
nodes_Jobs = oRoot("childNodes")
nJobsNodeNum = nodes_Jobs("length") ; ノードの数
;
for i, 0, nJobsNodeNum
mes "item[" + i + "]"
;
node_Jobs = nodes_Jobs("item", i)
nodeType = node_Jobs("nodeType")
if( nodeType = 1 ){ ; タグ
if( node_Jobs("tagName") = "job" ){
mes "
;
atrs_Job = node_Jobs("attributes") ; attribute map
atr_Id = atrs_Job("getNamedItem","ids") ; id
mes "id=" + atr_Id("nodeValue") ; idの値
}else{
; 別のタグ処理
}
}else{
; 別の要素処理
}
next
stop
-----------
使用したsample.xml
<?xml version="1.0" encoding="Shift_JIS"?>
<jobs>
abc
<job id="j11" />
<job id="j12" />
<job id="j13" />
</jobs>
-----------
関数の呼び方といったのは、
;
node_Jobs = nodes_Jobs("item", i)
こういうの。
自分で発想することはありえない呼び方です。
そういうお作法的なことがわかれば、
あとはなんとかなるかな~。
あと実際に使用するときは、
MSXMLの関数呼ぶたびに、正常に取得できたか確認しないと、
エラーケースでHSPが落ちるので注意です。
今回の例では、<job />とかidのないタグがあるとダメです。
最終的に、JP1みたいなものを作りたいので、
外部ファイル(ここではバッチファイル)を実行する練習をしてみました。
バッチファイルは、echo とかしてるだけです。
単純に動かしたいだけなら、exec関数、
終わったのかまだ続いてるのか、様子を見たいなら、pipeexec関数を使用します。
exec関数だけだとあっさり終わってしまうので
合わせて載せます。
------
; バッチプログラムを動かす
#include "hspext.as"
button gosub "exec", *ExecBat
button gosub "pipeexec", *PipeExecBat
stop
; 通常の実行
*ExecBat
exec "test.bat"
retVal = stat
mes stat
return
; パイプ付き実行
*PipeExecBat
sdim buf, 32000
pipeexec buf, "test.bat"
repeat
pipeget buf
if stat=0 : break
// mes buf
wait 50
// pipeput 1
loop
pos 100, 100
mes "終わり"
return
----
execでも、pipeexecでも、同期実行というのはナシみたいです。
(Version3より前はあったみたい)
なので、蹴っ飛ばして戻ってくる感じですね。
蹴っ飛ばした先が重い処理の場合でも、
HSPへコントロールが戻ってくる。
それはそれでいいのだけども、
その先を見ていたいのです。
終わったのか、まだやってるのか。
なので、execだけでは物足りず、pipeexecを使うことになりそうです。
さてpipeexec。
そもそもpipeと言うのは何かと言うと、
HSPが蹴っ飛ばした外部ファイル(ここではバッチプログラム)が
別プロセスで動いていて、
そこの様子を見るために、通信用のパイプをつなげるという意味です。(たぶん)
イメージは・・・潜水艦(プログラム)同士をゴムホース(パイプ)でつないで声を通す・・みたいな!?
pipeexec実行時に、パイプを指定し、実行します。
そうすると、走り始めます。
HSPからは、ちょっとしてから、pipegetで様子を伺います。
終わったよとか、まだやってるよとかのステータスを得ます。
終わってたら、repeatを抜けて終了。
コメントアウトしてあるのは実験コード。
bufには、標準出力が入ってました。
pipeoutは、標準入力です。
さらに実験
①バッチファイルでpauseして、その状態でタスクマネージャーからcmd.exeを殺してみた
stat=0になって、"終わり"が出た
⇒ 強制終了等で死んでも見失わず(?)終了と判断できる。OK。
②バッチファイルでpauseして、その状態でHSPのダイアログを閉じてみた
タスクマネージャー上のcmd.exeも死んだ
⇒ 子プロセスの掃除をしてる。OK。
外部ファイル(ここではバッチファイル)を実行する練習をしてみました。
バッチファイルは、echo とかしてるだけです。
単純に動かしたいだけなら、exec関数、
終わったのかまだ続いてるのか、様子を見たいなら、pipeexec関数を使用します。
exec関数だけだとあっさり終わってしまうので
合わせて載せます。
------
; バッチプログラムを動かす
#include "hspext.as"
button gosub "exec", *ExecBat
button gosub "pipeexec", *PipeExecBat
stop
; 通常の実行
*ExecBat
exec "test.bat"
retVal = stat
mes stat
return
; パイプ付き実行
*PipeExecBat
sdim buf, 32000
pipeexec buf, "test.bat"
repeat
pipeget buf
if stat=0 : break
// mes buf
wait 50
// pipeput 1
loop
pos 100, 100
mes "終わり"
return
----
execでも、pipeexecでも、同期実行というのはナシみたいです。
(Version3より前はあったみたい)
なので、蹴っ飛ばして戻ってくる感じですね。
蹴っ飛ばした先が重い処理の場合でも、
HSPへコントロールが戻ってくる。
それはそれでいいのだけども、
その先を見ていたいのです。
終わったのか、まだやってるのか。
なので、execだけでは物足りず、pipeexecを使うことになりそうです。
さてpipeexec。
そもそもpipeと言うのは何かと言うと、
HSPが蹴っ飛ばした外部ファイル(ここではバッチプログラム)が
別プロセスで動いていて、
そこの様子を見るために、通信用のパイプをつなげるという意味です。(たぶん)
イメージは・・・潜水艦(プログラム)同士をゴムホース(パイプ)でつないで声を通す・・みたいな!?
pipeexec実行時に、パイプを指定し、実行します。
そうすると、走り始めます。
HSPからは、ちょっとしてから、pipegetで様子を伺います。
終わったよとか、まだやってるよとかのステータスを得ます。
終わってたら、repeatを抜けて終了。
コメントアウトしてあるのは実験コード。
bufには、標準出力が入ってました。
pipeoutは、標準入力です。
さらに実験
①バッチファイルでpauseして、その状態でタスクマネージャーからcmd.exeを殺してみた
stat=0になって、"終わり"が出た
⇒ 強制終了等で死んでも見失わず(?)終了と判断できる。OK。
②バッチファイルでpauseして、その状態でHSPのダイアログを閉じてみた
タスクマネージャー上のcmd.exeも死んだ
⇒ 子プロセスの掃除をしてる。OK。