HotSoupProcessorの記録 -4ページ目

HotSoupProcessorの記録

コンピューター言語 HotSoupProcessor の練習記録です

できると何かと便利な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のないタグがあるとダメです。
最終的に、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。