sbcobjプラグイン †
sbcobj( SubclassObject )プラグインは、HSP3.0標準命令oncmdでは出来ないコントロール( 以下、オブジェクト )に対するメッセージの横取り( サブクラス化 )を実現する為のHSP3.0専用の拡張プラグインです。
sbcobj ver 1.6( sbcobj.as ) に _oncmd マクロを追加しました。
注意事項、著作権、インストール方法などはブリーフケース内の説明書を読んでください。
sbcobjプラグインを利用した方で動作環境の収集に協力頂ける方は追加をお願いします。
- Windows XP HomeEdition? SP2 + hsp3.0
- Windows 98se : HSP 3.0a , HSP 3.1b
(コンパイル環境 : Windows 98se : 'Borland C++ 5.5.1' + 'HSPSDK 3.0a')
+
| | ... |
- 近日β版公開となります。 -- kz3
- 「オブジェクトのサブクラス化」ってぴんとこないんですが、(サンプルプログラムに示したもの以外で)具体的にどんなことが出来るんですか? -- GENKI?
- あとはmesboxのスクロールメッセージを受け取れたりします。大抵はコントロールから通知メッセージが送られてきますが、送られてこないメッセージ=コントロールがメッセージを消化してしまうものを捕まえることができます^^ -- kz3
- 何かファイルのUPミス、「この説明はこう書いたほうがいい」などあったら指摘してくださいm(u_u)m -- kz3
- このプラグインを使ってほしい人が実は居ます。
猫太さん見てますか〜?これでエディタのルーラーのスクロール実現できるはずです。 -- kz3
- オーナードローを扱った時に既に「オブジェクトのサブクラス化」という想いはあったので、これでより独自のコントロールをHSPで実装できる・・・そう考えています。>naznyarkさん^^; -- kz3
- スタティックコントロールもサブクラス化できています。 -- kz3
- リリース版UPです。ファイルを上書きして再度コンパイルお願いします。具体的に変わったのはプロシージャのファイルだけのハズですが念のため・・・。 -- kz3
- HSPに関するwikiだからHSPの紹介は要らないかな・・・でもドキュメントには・・・。単品で配布するわけじゃないから要らないかな@@ -- kz3
- まず動作確認報告。以下の私の環境では特に問題なく動作しました。
とても良いです。コントロールで突っ込んだことをするのがかなり楽になりそうです。
なんとなく作ったサンプル2本。
さらに要望、というかあっても良いかなと思った機能。(考えていそうですが)
- サブクラス化の解除
- 特定あるいは全てのメッセージの処理の中止・一時停止
- メッセージ処理先の多重登録(処理先1での処理→(メッセージ処理中断でなければ)処理先2での処理→...) -- naznyark?
- naznyarkさん、ありがとうございます。(u_u)
サブクラス化の解除はoncmd 0相当の命令ということですよね、正常に動作していないとかなんとか、の。
表面的にはパラメータか命令を増やして、内部的にはSBCINFO構造体とMSGINFO構造体に有効/無効メンバを持たせるか、有効/無効を別のリストで管理するとか考えられますね。
後者は無効な要素を探索対象から外せるので速度UP( 微々 )に繋がるかも知れません。
が実装すると前者は常に有効/常に無効関係なく、使用メモリは登録数に比例して大きくなります。
後者の場合は無効ROOTを追加するだけで構造体は変更しなくて済みそうですね。
ただ仮に有効/無効機能があってもスクリプトでどのオブジェクト・メッセージを現在無効にしているのか、といった事を管理するにも変数を使うことになると思うので、2箇所で管理するのは( スクリプトの )バグの原因になるのが少し心配です。
ましてHSPは全てグローバル変数ですから・・・^^; -- kz3
- 処理先の多重登録ですかーこれはちょっと複雑ですね・・・。
飛び先のラベル内でgosubによって別ルーチンに飛んで帰って、の方がHSPらしいといえばらしいですが・・・。
いろいろと検討してみます^^( 検討好き.特にデータ構造 )貴重なご意見ありがとうございます! -- kz3
- statにハンドルが入れられる点についてですが、頻繁に利用されるstatがたかだかハンドルの為だけに元の値を上書きしてしまうのはどうかと考えたりしてます( 実際にサンプル書いた感想 )。参照コマンドsbcobj( プラグイン名と同名だと混乱する? )で取得するようにしようかな〜と思ったりです。 -- kz3
- 動作環境とサンプルをそれぞれの場所に追記したのでコメントの重複個所を編集してもいいでしょうか?>naznyarkさん
あとオブジェクトの移動とか私も書いてました^^; -- kz3
- なぬ!?ルーラーがこれでできると!?しばらく開発停止状態だったので、これで続行できるかも! -- 猫太?
- どうにもコンパイルができんとですorz 構文エラーとかいろんなのが下のウィンドウに表示されます。 -- 猫太?
- makefileを覗いてbcc32 の書いてある行を下から実行してみてください。か、もしくは「make -fmakefileのフルパス」ではどうでしょ? -- kz3
- そうだよね・・・コンパイルできなきゃサンプル意味ないのよね^^; -- kz3
- エラー E2209 sbc_init.cpp 5: インクルードファイル 'hsp3plugin.h' をオープンできないってありますが、何か他に入れるものがあるんですかね?HSP3のSDKとか -- 猫太?
- 必要ファイルにも書いてある通り、表の右側のSDKのファイルが必要になります。SDK(hsp3.1b1)はオフィシャルページのβテスト版のリンクから入手できます。猫太さんにもサブクラス化の魅力を知ってほしいので出来るまで付き合いますよ。 -- kz3
- ありがとうです!よく見たら上に書いてありましたね(^_^;)んで、色々放り込んで、一応全てmakeしました。そのあとはどうすればいいのでしょう? -- 猫太?
- hpiファイルが出きていればコンパイル・リンク完了です。あとはインストールの内容に従うだけです。 -- kz3
- 個人的にプラグインのヘッダ(*.as)が多くなるとCommonフォルダが汚くなるのでプラグイン名( 私はCommon/sbc/sbcobj.as )など一段フォルダを作ると管理しやすいと思います。 -- kz3
- どうしてもTDSファイルとOBJファイルしか出力されませんorz init.cpp>manager.cpp>proc.cpp>hsp3plugin.cppの順に実行のmakeを行いました。 -- 猫太?
- まだ一番上の「bcc32」の行が残っていますよorz -- kz3
- その4つの手順は1つのcppソースと対のモジュール(オブジェクト)を生成したわけです。これらのモジュールを1つにまとめる(リンク)ことで実行ファイルが作成されますです。 -- kz3
- sbcobj.hpi: sbc_init.obj sbc_manager.obj sbc_proc.obj hsp3plugin.obj ですか? -- 猫太?
- そーの下ですね。その行は「sbcobj.hpi(目的のファイル)はsbc_init.obj, sbc_manager.obj, sbc_proc.obj, hsp3plugin.obj に依存している」というmakeに与える情報です。依存関係の下に実際のコンパイラへのコマンドが書かれています。これが作成(make)手順を記したファイル、だからmakefileって呼ばれます。(自論) -- kz3
- bcc32 -esbcobj.hpi -WD sbc_init.obj sbc_manager.obj sbc_proc.obj hsp3plugin.objですよね?sbc_init.obj sbc_manager.obj sbc_proc.obj hsp3plugin.objをmakeすればいいんですか? -- 猫太?
- そうですそうです。で、最後のmakeはlinkね^^; -- kz3
- link?それはどこにありますか?CPad Ver 2.31を使ってます。 -- 猫太?
- 余計なことを言ってしまったか・・・。4つのobjが無事出来たらmakefileの上から二行目のコマンドをコマンドラインに打ち込めばばっちグーのはずです。 -- kz3
- やっとできました!!長かった・・・。kz3さんありがとうございますm(__)m -- 猫太?
- 早速サンプルをお試しあれ! -- kz3
- サンプル実行してみました!どれも今までのHSPとは思えない機能っぷりですね〜 オブジェクトのD&Dがすごかったです! -- 猫太?
- demo, -- 猫太?
- ミスりました(^_^;)これでルーラースクロールができるそうですが、どういったことなんでしょうか? -- 猫太?
- エディットボックスのスクロールバーの両端のボタンを押すと親ウィンドウにWM_COMMANDという通知メッセージが送られてきます。まずこれは普通にoncmdで処理できます。HSPのウィンドウに通知メッセージが送られますから。
このメッセージはEN_HSCROLL,ENVSCROLLという通知コードを含んでいるので、これを処理することによりルーラーの位置もコントロールできます。 -- kz3
- エディットボックスのスクロールバーのスライダをスライドさせると、WM_HSCROLL,WM_VSCROLLというメッセージが親ウィンドウに送られます、がこの時の親はHSPウィンドウではないのです。メッセージボックスに送られます。これはこのスクロールバーがメッセージボックスの一部だからですね。というわけで、メッセージボックスに送られてくるメッセージはサブクラス化の出番です。 -- kz3
- そしてそのウィンドウのスクロールバーの情報はGetScrollInfo?()で取得できます。 -- kz3
- なるほど!これはいけそうですな!!でも、一つ問題点がありました。 -- 猫太?
- winobjで作ったオブジェクトのハンドルを取得するにはhEdit=objinfo(stat,2)ってやってるんですが、objcmd hEdit, $00000114, *sってやると、横取りができません。仕様でしょうか? -- 猫太?
- 使い方を良く読んでくださいー。ハンドル指定できたらoncmd用済みです・・・(sbcobjが勝るとかじゃなくて) -- kz3
- 出来ますがあえてHSPの"簡便さ"を残してID指定にしているんですね〜^^; -- kz3
- さらにコメント。ハンドル指定にすると1とか777がハンドルなのかの区別が出来ないわけなのです。 -- kz3
- なるほど〜 把握しました! なんか色々お世話になりましたm(__)m ちょっと研究してみますね!引き続き開発、がんばってくださいませ〜 -- 猫太?
- 猫太さんも頑張ってください〜、って上で説明した方法はまだ自分で試していないので自分でもやってみるつもりです。(ォィォィ。あと、猫太さんよかったら動作環境追加お願いします。既に載っていたら大丈夫です^^; -- kz3
- 動作環境は Windows XP HomeEdition? SP2 + hsp3.0 コンパイル環境 : Windows XP HomeEdition? SP2 : 'Borland C++ 5.5.1' + 'HSPSDK 3.1b'です。今現在、2つのmesboxの横スクロール連動を製作してるんですが、どうにもうまくいかない状態です(^_^;) -- 猫太?
- > コメントの重複個所を編集
全く問題ないですよ。 > 処理先の多重登録
できないほうが HSP らしい(?)ような気はするのですが、これができると複数モジュールと本体部分での同一オブジェクトの同一メッセ−ジに対しての objcmd の多重使用による問題が軽減されるんですよね。
まあ本質的ではないことの考えすぎですが。
それと不具合ありました。バグレポートのほうに書いておきます。 -- naznyark?
- naznyarkさん報告ありがとうございます_(.._)
多重登録の件は納得しました。オーナードローの時にも挙がった問題ですね。登録メッセージの有効/無効の方はルート管理ですぐさま実装できます、あれ?「サブクラス化の解除」というのはオブジェクトに対して指定された全メッセージの無効化という風に受け取っていいでしょうか?
ラベルの多重登録ではラベルを提供するモジュールの優先順位(?)が問題になりそうです。
たとえば3つとも登録したラベルの処理が3つともプロシージャの戻り値を返したくても、実際実行されるのは登録順番次第だと思います。
処理1から処理2、処理2から処理3に"継続"したとしてもメッセージの流れに沿わない場合はその処理はプロシージャに無視されてしまうと思いますがどうでしょう?もう少し仕様を固めてからですね^^; -- kz3
- うーん、終了時のオブジェクトの削除関数ですがー、HSPがただオブジェクトだけを削除してるだけなら問題ないですが、「ただオブジェクトを削除しているだけ」と決めてかかってデフォルトの削除関数を呼ばなくても良いのかどうか・・・( 本当はダメ ) -- kz3
- むしろ終了時に削除関数が呼ばれているなら終了受け取りファンクションでのマネージャの解放は要らないような・・・。オブジェクトの削除と同時にsbcオブジェクトも削除しているので...
ということはプロシージャを戻すだけでいいかな。-- kz3
- やはり多重登録、及びメッセージの横流し( 同じメッセージ対して登録してある別ラベルに処理を渡す )はoncmdに合わせてラベルの上書きのままでいく考えです。( ラベル変数が実装されればスクリプトで融通が利きそうな予感です。 )
オブジェクトのサブクラス化・メッセージ処理の有効/無効化はオブジェクト毎・メッセージ毎にオプションで指定できるようにする考えです。オブジェクト毎でなくスクリプト全体に対する無効化は入れるとしたら命令追加ですね。 あとはオブジェクトの破棄の根本的解決法を思いついたので試行錯誤してみます。むふふ -- kz3
- naznyarkさん、お時間空いたときにでも再度、98seでの終了時のページ違反についてv1.2で改善されたかどうかご検証よろしくお願いしますm(u_um -- kz3
- 2つのmesboxのスクロール連動は片方(両方も可)をサブクラス化して片方に同じメッセージを同じパラメータでメッセージを送ればできますよー>猫太さん -- kz3
- 助言ありがとうございます!とりあえず、GetScrollInfo?とSetScrollInfo?を使ってスクロールバーのつまみだけの連動はできました。あとは、mesboxの中身の連動です。 -- 猫太?
- この書き込み時点でアップされている sbcobj.as に sbcobj の登録がありません。
#cmd sbcobj $01
でいいんですよね?。それはおいといて、
sbcobj ver 1.2、Win 98se での SAMPLE4 のページ違反エラー、出なくなりました。
もちろん他のサンプルプログラムも問題ありません。-- naznyark?
- UPミス失礼しました・・・配布ファイル7つ再UPしなおしました。sbcobjの宣言はそれでOKです。
改善の検証ありがとうございますm(u_um -- kz3
- sbcobj ver 1.2にして、SAMPLE4を実行したら、チェックボックスが強調表示されたままになります。XP SP2、HSP Ver3.00 -- 猫太?
- あれーっ;;猫太さんと私、同じ環境なはずなのに・・・具体的な発生状況を教えていただけませんか?あ、過去のサンプルファイルはハンドルをstatから取得していますが、v1.2からはsbcobjから取得するようになりますので、最新のサンプルファイルで確認してみてください。 -- kz3
- SAMPLE4ってどういう動作になれば正常なんでしょうか?チェックボックスにカーソルを当てると、XPのLunaですとオレンジ色になって、カーソルを外すと元の色に戻りますよね?でも、1.2でSAMPLE4を実行してカーソルを当てたらオレンジ色になったままチェックボックスの色が戻らないんです。このSAMPLEではこれが正常なんでしょうか?? -- 猫太?
- Luna・・・環境違いましたね、私はクラシックでしたorz症状を把握しておきたいので、お手数かけますがSSと猫太さんの持ってるSAMPLE4をnekosample4などにリネームしてUPしていただけますか? -- kz3
- カーソルの下にあるチェックボックスが強調され、以前の強調表示はクリアされるハズです。あと要所要所にdialogを入れてTrackMouseEvent?()が実行されているか、その戻り値は正常か、WM_MOUSELEAVE内の処理は実行されているか、なども教えていただけると嬉しいです。 -- kz3
- とりあえず、ファイルのUPをしておきました!全てオレンジ色(強調表示)になってるはずです。 -- 猫太?
- 今、いろいろ調べてLunaスタイルに出来たところです!!(目が痛い・・・ -- kz3
- Lunaスタイルでのチェックボックスのオレンジ表示が残る症状確認できました。Lunaスタイル初のため、原因究明に時間かかるかも知れませんが調べてみます。 -- kz3
- 一応、各ラベルにはちゃんとジャンプしてるようです。原因は変数sbcobjが常にゼロになってるからのようです。 -- 猫太?
- Lunaスタイルだと標準でチェックボックスが強調表示のようですね・・・それは置いとき、WM_MOUSELEAVEでデフォルトプロシージャに処理を渡す( return で値を指定しない )と無事(?)灰色表示で強調されました。 -- kz3
- Lunaスタイルだとサブクラス化しなくても強調表示されるんですねぇ。SAMPLE4はLuna以外でも類似したインターフェースにしたい場合に有効ですね。 -- kz3
- sbcobjが0なのは定義ファイルのUPミスです;;sbcobj.asをダウンロードしなおしてください。 -- kz3
- sbcobj v1.3 にあわせて sbcobj_sample_mod_omd を更新しました。
その際に不具合を発見しましたがプラグインというより HSP 本体側の仕様(不具合?)によるもののようです。
HSP 3.0 での return 命令の仕様。
- return (引数なし)
HSPCTX->retval_level : 値の変更なし(その時点の値のまま。return 命令ではクリアされないようです)
- return (引数あり)
HSPCTX->retval_level : 値が変更される
引数なしの return 命令では HSPCTX->retval_level の値がクリアされないので、
return 0
..(略)..
return
と実行した場合 retval_level の値では 2度目の return も引数ありと判定される場合があるようです。 -- naznyark?
- naznyarkさんありがとうございます〜;;一個だけでのテストで判断していましたが、ネストなどさせてみると現象を確認できました。
retval_levelの内容をよくよく観察してみるとネストレベル0のジャンプ元を深さ0とした時の「最終的に値を返したreturnの深さ」ということが分かりました。
ただこの最終的にというのは、サブルーチンレベルが0になったところで0にクリアして欲しかったり・・・
というわけで、修正してみましたが、割込みラベルに割込み以外でgosubさせる人はいないと思うのでプロシージャでジャンプする前に( ジャンプ元だから )0にして・・・一応元の値に戻すようにしました。( 微妙 ) -- kz3
- あ、そうか・・・割込み以外のgosubならプロシージャに戻ってくるわけじゃないので、プラグイン内でラベルジャンプする前に0にして、値は戻さなくてもいいのか・・・。 -- kz3
+
| | sublev と retval_level の関係
|
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
|
| font msgothic, 14
mref ctx, 68
dup retval_level, ctx.211
*lb0
gosub *lb1
mes retval_level
mes "----"
gosub *lb2
mes retval_level
mes "----"
gosub *lb3
mes retval_level
mes "----"
stop
*lb1
mes "lb1 : sublev = "+sublev
gosub *lb2
mes "lb1 : retval_level = "+retval_level
gosub *lb3
mes "lb1 : retval_level = "+retval_level
return
*lb2
mes "lb2 : sublev = "+sublev+"*" gosub *lb3 mes "lb2 : retval_level = "+retval_level return 1 *lb3
mes "lb3 : sublev = "+sublev
return
|
上2つのコメントは言葉になってないですねorz -- kz3
|
- バージョンアップが激しくてすいません こちらもあっぷあっぷです( ) -- kz3
- なにかおかしいようですよ。
説明がうまくまとまらないのでとりあえず修正してみたソースとテスト用のプログラムを。 -- naznyark?
- ん・・・頭がこんがらがってしまいますね・・・
「retval_levelの内容をよくよく観察してみるとネストレベル0のジャンプ元を深さ0とした時の「最終的に値を返したreturnの深さ」ではなくて・・・
「retval_levelはreturnで値を返したサブルーチンレベル( sublev )を表す」ということでした。
相対レベルを返すと思っていましたが、そうではなくて絶対レベルを返すということが分かったのでnaznyarkさんの修正コードで正しくなりますorz。
テストまでしていただき本当にありがとうございます && すみません^^;
少し手を加えてUPしなおします( 早; -- kz3
- 「retval_levelにはreturnで値を返した時点のsublevの値が格納される」と一言にまとめると、こう言える。 -- kz3
- 重複部分を削除です〜。naznyarkさんのサンプルだけになってしまいました^^; -- kz3
- hsp3.1b3のreturn code絡みでb3対応を検討中に挙動不審発見。原因調べて修正と同時に探索アルゴリズムをワンランク上げます〜。ただ原因調べるのに長くかかりそうです。 -- kz3
- sbcobjは割込み先でretval_levelを一時的に0にしていますが、b3のoncmdは割込み先でもretval_levelが維持されているので、そこも揃える予定です。その前にまずは挙動不審を失くすところです。はい... -- kz3
- hsp31b3で修正されたretval_level絡みの挙動ですが、sbcobj同様割込み発生時にretval_levelを一時的に0クリアしていると考えて良さそうですね。oncmdret.hspsublevの値が偶数=パラメータ無しreturn/奇数=パラメータ付きreturnでテストしました。 -- kz3
- naznyarkさんが言ったことを理解したかも...。飛び先ラベルの多重登録。ラベルに名前空間があるように、メッセージIDにも名前空間を持たせれば、割込みが発生した空間に合わせた処理が出来そう...同一メッセージの処理の継続とは少し違うけど...( ソレより今はddwです ) -- kz3
|
+
| | ... |
- サブクラス化されたオブジェクト( sbcオブジェクト )は処理すべきメッセージの有無に関わらず、プロシージャがメッセージを受け取るとサブクラスマネージャへオブジェクトのハンドルを問合せます。
ここでオブジェクトのハンドルが得られると、更にメッセージを問合せます。
よってアルゴリズムのオーダーで支配的な部分はオブジェクトのハンドルの探索が半数以上を占めます。
今後バージョンアップするとすれば探索アルゴリズムの見直しがメインと考えられます。
現段階においては実装面から線形探索で行っています。
またメッセージは同一オブジェクトに対して連続的に発生することが多いと考えられる為MRU法を適用して線形探索のコストを軽減しています。 -- kz3
|
+
| | ... |
- β版からの変更点
@ プロシージャ内で処理すべきメッセージがあった際、sbcオブジェクトをサブクラスマネージャの先頭に移動して探索コストを軽減するようにしました。 -- kz3
- ver 1.0 からの変更点
@ ジャンプ先でメッセージを受け取ったハンドルを取得するのにシステム変数statから、プラグイン変数(?)sbcobjに変更しました。
@ naznyarkさんに指摘されたバグ「オブジェクトテーブルの再配置によるアドレスの変動」を修正しました。 -- kz3
- ver 1.1 からの変更点
@ 終了時などサブクラスマネージャを解放する際、上記で指摘された問題について、根本的解決を図り、終了時にオブジェクトテーブルを改めて取得し書き換えることにより、終了時にはサブクラス化する前の削除関数がきちんと呼ばれるようにしました。 -- kz3
- ver 1.2 からの変更点
@ onsbc命令の追加。
@ ちょっとだけメモリの使用効率を良くした。
@ デフォルトの削除関数が用意されていると決め付けていたが、NULLチェックをして呼び出すように修正。 -- kz3
- ver 1.3 からの変更点
@ 割込みジャンプした先でプロシージャの戻り値を返すreturnについて、以前の戻り値の指定が残ってしまう不具合の修正。 -- kz3
- ver 1.4 からの変更点
@ 前回の修正ではリターンンコードを強制変更したまま、適切な値にしませんでしたが、ちゃんと戻すようにしました。 -- kz3
- ver 1.5 からの変更点
@ 前回の修正で元に戻したと思っていたretval_levelの値が戻っていなかったのを修正( naznyarkさん修正&ref(): File not found: "ojigi.png" at page "pic";、kz3確認 ) -- kz3
- ver 1.6 に追加された機能
@ sbcobjプラグイン使用時に標準命令oncmdとのパラメータの順序の違いによるデバッグ・コードの見栄えを考慮して、マクロ_oncmdをプラグイン定義ファイルに追加。 -- kz3
|
+
| | ... |
- 不具合報告。
98se + HSP3.0a で sbcSAMPLE4 実行後プログラム終了時にページ違反のエラー発生。
9x系の環境依存かなと思いつつ条件切り分けのため色々試していたら見当がついたのでソースを眺めていると問題点らしき所が見つかりました。
sbc_manager.cpp 内の
sbcinf->hspfunc = &objinf->func_delete; // func_delete へのポインタ
ここと
*sbcinf->hspfunc = sbcinf->delfunc; // オブジェクト削除関数を元に戻す
ここです。
OBJINFO 構造体の格納領域はオブジェクト作成ごとに再配置され得るので(オブジェクトの数だけ連続して確保されている必要がありますから。) objcmd 実行時に有効だったアドレスがプログラム終了時に有効という保証はないです。-- naznyark?
|