HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2012
0325
centrisoncmd gosub の動作について8解決


centris

リンク

2012/3/25(Sun) 00:58:50|NO.45577

ドラッグ&ドロップのプログラムをシンプルに扱うために
色々なアプローチを試したのですが解決できなくて
最終的に oncmd gosub の動作が理不尽で暗礁にのりあげております。

[問題点]

通常の gosub の場合サブルーチンを呼び出した後は
直下の行を実行します。

しかし oncmd gosub はサブルーチン内でreturnしても
直下の行を実行してくれません。
しかも動作的にはreturnと記述しているが実質STOP命令のような
素振りを見せます。
(スキル的にHELPを見ても理解できませんでした…)


言葉だけでは説明しにくいと思うのでスクリプトを書いておきます
ドロップされた時だけ実行するようにしたいのです。

HSP3.3添付のサンプルに手を加えています

#uselib "shell32.dll"
#func DragAcceptFiles "DragAcceptFiles" int,int
#func DragQueryFile "DragQueryFileA" int,int,int,int
#func DragQueryPoint "DragQueryPoint" int,int
#func DragFinish "DragFinish" int

#define WM_DROPFILES 0x0233

title "ウィンドウにファイルをドロップしてください"
DragAcceptFiles hwnd, 1

oncmd gosub *OnDropFiles, WM_DROPFILES

//999が返された場合ドロップされたと判断する

mes "stat "+stat :if stat != 999 :stop

//▲疋蹈奪廚気譴浸だけ実行する 

mes "ドロップされました"

stop

*OnDropFiles
hdrop = wParam
DragQueryFile hdrop, -1, 0, 0
ndrop = stat

syscolor 5 : boxf
syscolor 8 : pos 0,0

sdim filename, 260
repeat ndrop
DragQueryFile hdrop, cnt, varptr(filename), 260
mes filename
loop

DragFinish hdrop
//ここの戻り値の扱いも不明。便宜上値を999にしています
return 999

現状では oncmd goto で return の代わりに goto で△鉾瑤
又はサブルーチン内で処理を行う。
どちらもシンプルでないので汎用性に欠けます。

何か解決方法はありませんでしょうか。



この記事に返信する


てれてれ

リンク

2012/3/25(Sun) 01:25:31|NO.45578

理不尽なのはoncmd gosubではなくあなたの方です。

oncmdの動作を誤解されているようですが、
この場合*OnDropFilesからのreturnで返ってくる先は、
oncmdの真下の行ではなく、処理を待機しているstopの行です。

そもそもoncmdに返り値を設定することはほとんど無意味だと思いますけど・・・

単純にこうしてしまうと何か問題が起きるんですか?

#uselib "shell32.dll" #func DragAcceptFiles "DragAcceptFiles" int,int #func DragQueryFile "DragQueryFileA" int,int,int,int #func DragQueryPoint "DragQueryPoint" int,int #func DragFinish "DragFinish" int #define WM_DROPFILES 0x0233 title "ウィンドウにファイルをドロップしてください" DragAcceptFiles hwnd, 1 oncmd gosub *OnDropFiles, WM_DROPFILES stop *OnDropFiles hdrop = wParam DragQueryFile hdrop, -1, 0, 0 ndrop = stat syscolor 5 : boxf syscolor 8 : pos 0,0 sdim filename, 260 repeat ndrop DragQueryFile hdrop, cnt, varptr(filename), 260 mes filename loop DragFinish hdrop //ここの戻り値の扱いも不明。便宜上値を999にしています mes "ドロップされました" return 999



Cookies

リンク

2012/3/25(Sun) 09:02:54|NO.45579

MSDN http://msdn.microsoft.com/en-us/library/windows/desktop/bb774303(v=vs.85).aspxより。

Return value
An application should return zero if it processes this message.
アプリケーションは0を返すべき、もしメッセージを処理したならば。



centris

リンク

2012/3/25(Sun) 23:41:57|NO.45587

てれてれさん

早速お返事いただきありがとうございます。

oncmd の動作はご指摘で理解できました。

言葉が解らないのでアセンブリ言語風に言うと
'PC'が既にSTOPの位置に移動しているので'RET'しても
oncmdの直下に飛ばないデスヨネ。


記述いただいたスクリプトはすでに検証していました。
>又はサブルーチン内で処理を行う。
(最後の5行が尻切れトンボ状態の文章なので無用なスクリプトを
書かせてすみません。)
私はサブルーチンを一種のライブラリと考えています。
プログラムをコーディングする際にライブラリを書き換えるのは
抵抗があります。ある程度成熟したライブラリを変更する行為は
バグの温床となりかねないため極力タッチを避けたいからです。


単純にする理由は単にoncmdを1行入れるだけでイベントが
発生すると直下の行が実行されたらスマートかなと思ったからです。

実際のところoncmd gotoで記述すれば2行追加で実現できるのですが
高級言語でgotoを使うのは少し抵抗があります。
(もっともgosub方式でも2行以上になるので矛盾しているのですが…)


理不尽だと思ったのは同じgosubなのでステートメントが実行されると
直下に戻ってくるものだと思い込んでいた為です。


私自身、昔のBASICと昔のアセンブラしか知らないので頭固くてすみません。

----------------
Cookiesさん

レスありがとうございます。

残念ながら
>(スキル的にHELPを見ても理解できませんでした…)
上記のレベルなので、全く理解できませんでした。
returnの補足をしてくださったと思うのですが
できれば解説して頂けると助かります。

----------------
一応プログラムは問題なく動作しているのですが
記述的に好ましくなく納得できずに使っていました。
きっとスマートな方法があるはずと思い投稿しました。
基本的にoncmd命令では期待する動作は望めないのは理解しましたが
もしかすると"こんな手法があるヨ"的なアドバイスを頂けないかと期待して
ご意見をお待ちしております。
しばらくお付き合い頂ければ幸いです。



KA

リンク

2012/3/26(Mon) 00:23:38|NO.45588

hspをどう使うのかは個人の自由ですが、コンセプト的に
余り高い所は望めない言語だということは承知ください。

ライブラリ的に使いたいのなら、モジュールで定義したり
、別ファイルで作ってインクルード等はどうでしょうか。



てれてれ

リンク

2012/3/26(Mon) 00:35:46|NO.45589

なるほど。わかりました。
自分はライブラリとして利用したい汎用性の高いスクリプトは
#deffuncや#defcfuncを使ってモジュールとして使っていたため、
「サブルーチンをライブラリと捉える」という考えが思いつきませんでした。

Cookiesさんが仰っていることは単純に、
「oncmdからのreturnは0を指定するべきだ」ってことだと思いますよ。
HSPではシステム変数statが固有のものなので、
割り込み処理の返り値を下手に指定してしまうと他の命令に干渉してしまう危険もありますし。



HK2

リンク

2012/3/26(Mon) 06:48:19|NO.45592

oncmdによるサブルーチンジャンプからreturnを使って戻るときの引数は、
メッセージに応じてする必要があります。

例えば、Windowsがシャットダウンしようとした時、
WM_QUERYENDSESSIONが送信されますが、ここで0を指定すると、
シャットダウンは中止されます。



HK2

リンク

2012/3/26(Mon) 06:57:59|NO.45593

追記

WM_NCPAINTメッセージを受信した場合は、戻り値として0を返さなければなりませんが、
HSPでは省略する必要があります。
それはHSPではoncmdのサブルーチンからのreturnで引数が省略されると、
標準の処理がされますが、何らかの引数を与えると、HSPは何もしません。

WM_MOUSEMOVEメッセージを受信して、その戻り値をわざわざ0を指定すれば、
HSPは標準の処理をしないので、
mousex,mouseyが更新されません。
戻り値を省略すれば、きちんと更新されます。



centris

リンク

2012/3/27(Tue) 23:26:11|NO.45608

KAさん

アドバイスありがとうございます。

私もHSPに過度の期待は抱いておらず並行で他の言語も勉強中です。
(20,000件程のテキストファイルを正規表現で処理するのに
2時間ぐらい掛かってしまい実感しています。)
HSPは簡単な記述でプログラムが書けるので利用させていただいております。


てれてれさん
HK2さん

解説ありがとうございます。

returnってstatが単純に戻ってくるだけだと思っていました。


half-toneさん

サンプルありがとうございます。

現段階で私が欲していたもの100%の回答でした。


実はすぐにお返事を書くべきなのですが、
お恥ずかしい話ですが頂いたサンプルが理解できずマニュアルを
読み返していたため遅くなりました。
"*@"って見たことあるな〜だけど[F1]押しても出てこないし??(理解できました)



皆様、ご助言ありがとうございました。



ONION software Copyright 1997-2021(c) All rights reserved.