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


HSPTV!掲示板


未解決 解決 停止 削除要請

2019
1122
たかWindows8での(combox・listboxの選択監視処理に関する?)ランタイムエラー10解決


たか

リンク

2019/11/22(Fri) 01:07:43|NO.88900

DB検索などの機能を含めたシステムをつくり,2名の他者(PC:Windows8)に提供していました。しかし,
機能更新を加え,バージョンアップを重ねていく途中で,「下記のようなランタイムエラーがダイアログで提示
されて,実行ファイルが強制終了してしまうという事態が発生する」という報告を受けるようになってしまい
ました。
ーーーーーーーーーーーーーーーーーーーーーーーーーー
Microsoft Visual C++ Runtime Library(ここはウィンドウタイトル)
ーーーーーーーーーーーーーーーーーーーーーーーーー
Runtime Error!(以下,ウィンドウでの表記内容)
Program: [実行ファイルのディレクトリ]
abnormal program termination
ーーーーーーーーーーーーーーーーーーーーーーーーーー

または

ーーーーーーーーーーーーーーーーーーーーーーーーーー
Microsoft Visual C++ Runtime Library(ここはウィンドウタイトル)
ーーーーーーーーーーーーーーーーーーーーーーーーー
Runtime Error!(以下,ウィンドウでの表記内容)
Program: [実行ファイルのディレクトリ]
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
ーーーーーーーーーーーーーーーーーーーーーーーーーー

エラー報告をしてくれた両者の共通点は,Windows8のPC使用であるということです。Windows7および
Windows10でも同じシステムを試用してみましたが,ランタイムエラーは発生しませんでした。提供先は,
諸事情により,Windows8からOSを変更することは厳しい状況にあります。

機能更新前の旧バージョンアップでは,上記エラーが発生していなかったことから,追加機能を確認したところ,
下記サンプルプログラムを参考にcomboxおよびlistboxの自動監視・判別処理を追加したことが原因では
ないかと考えました。該当箇所をコメントアウトし,comboxまたはlistboxで項目選択後,buttonで選択項目
判別処理を行う仕様(旧バージョンの処理方法)にしたところ,エラーは発生しませんでした。
■以下,comboxでの項目選択に関する自動監視・判別処理

// コンボボックス監視サンプル (by Kpan) #define ctype HIWORD(%1) (%1 >> 16 & $FFFF) ; WM_COMMAND oncmd gosub *command, $111 objsize 100 combox a, 60, "胡瓜\n林檎\n人参\n葡萄\n茄子\n南瓜\n玉葱" hCombox = objinfo(stat, 2) stop *command ; lparamにはオブジェクトのウィンドウハンドルが返る if lparam = hCombox { ; wparamの上位ワードに通知コードが返る ; 通知コード1の場合は選択状態変化 (LBN_SELCHANGE) if HIWORD(wparam) = 1 { ; 現在選択中のインデックス番号取得 title "インデックス番号: "+a;comboxはlistboxと異なり,変数でインデックスを取得できる return } return } return

■以下,listboxでの項目選択に関する自動監視・判別処理

// リストボックス監視サンプル (by Kpan) #define ctype HIWORD(%1) (%1 >> 16 & $FFFF) ; WM_COMMAND oncmd gosub *command, $111 objsize 100 listbox a, 60, "胡瓜\n林檎\n人参\n葡萄\n茄子\n南瓜\n玉葱" hListbox = objinfo(stat, 2) stop *command ; lparamにはオブジェクトのウィンドウハンドルが返る if lparam = hListbox { ; wparamの上位ワードに通知コードが返る ; 通知コード1の場合は選択状態変化 (LBN_SELCHANGE) if HIWORD(wparam) = 1 { ; 現在選択中のインデックス番号取得 (LB_GETCURSEL) ; (変数aは利用しません) sendmsg hListbox, $188 title "インデックス番号: "+stat return } return } return

上記の機能を無くしてしまうという選択肢も最悪ありますが,効率が落ちたり,操作ミスが増えたりすることを
防ぎたいため,上記機能を組み込みたく,解決方法を探っている最中であります。Windows8の環境が手元
に無く,色々と試験的にエラー原因を追及することができておりません。提供先との関係上,いくつかβ版を
供給して試験的にエラー原因を追及することも厳しい状況です。

他の同様の処理を行うサンプルを拝見したところ,LBS_NOTIFYが入っていましたが,こちらの処理が必要
なのでしょうか??
http://hsp.tv/play/pforum.php?mode=pastwch&num=56566

本当に,上記機能が原因なのかは,定かではありませんが,どなたか修正方法をご示唆いただけると幸いです。
(冗長な文章となり,申し訳ありません。)
(開発環境:HSP3.5.1,Windows10)



この記事に返信する


(^_^)v

リンク

2019/11/22(Fri) 01:29:52|NO.88901

*commandのサブルーチンに当たる部分でobjprmやclsなどオブジェクトを削除するような処理は無いでしょうか

>下記サンプルプログラムを参考にcomboxおよびlistboxの自動監視・判別処理を追加したことが原因
この場合、サンプルプログラムではなくいじった方で不要な部分を削ったソースが必要です。
質問をするために最小限ソースを用意する段階で気づくこともあります。



MillkeyStars

リンク

2019/11/22(Fri) 08:30:55|NO.88902

これ、連動リストボックスとか使ってるんじゃ・・・
リストボックス.A が変更されると連動してリストボックス.B の内容が変化するやつ。



Drip

リンク

2019/11/23(Sat) 22:20:57|NO.88913

たかさん、こんにちは。

掲示板スレッドをunusual wayで検索すると何件かヒットするのですが、
私も最近同様の不具合を報告させていただいております。
http://hsp.tv/play/pforum.php?mode=all&num=87482

ツール作品ですと割り込み処理が多様に発生するためデバッグが大変ですよね。
私の報告したケースではgosubのonexitとgotoのbuttonがバグのトリガーになっています。
このランタイムエラーはHSPのネストが深く関与しているようです。
gosubのbuttonとgotoのbuttonが同時に存在していたり、
gotoのonclickとgosubのoncmdが混在していたりすると同じような問題が起こり易いかもしれません。
注意してデバッグしてみてください。

私もこの不具合はウォッチしているので再現手順など何かわかりましたら貼っていただければ検証したいと思います。



たか

リンク

2019/11/24(Sun) 18:04:36|NO.88919

皆様,ご助言ありがとうございます。
私のcomboxおよびlistboxの使用概要は,下記のプログラムです。かなり不要部分は,省略してあります。

// combox&listbox監視サンプル #define ctype HIWORD(%1) (%1 >> 16 & $FFFF) ; WM_COMMAND oncmd gosub *command, $111 *combox_window cls a=-1 objsize 100 combox a, 60, "胡瓜\n林檎\n人参\n葡萄\n茄子\n南瓜\n玉葱" hCombox = objinfo(stat, 2) id=stat stop *listbox_window cls a=-1 objsize 100 listbox a, 60, "胡瓜\n林檎\n人参\n葡萄\n茄子\n南瓜\n玉葱" hListbox = objinfo(stat, 2) id=stat mes "ひとつ画面を(*combox_windowへ)戻る" button "Back",*combox_window stop *last_window cls mes "最初に戻る(*combox_window)" button "Yes",*combox_window mes "ひとつ画面を(*listbox_windowへ)戻る" button "Back",*listbox_window stop *command ; lparamにはオブジェクトのウィンドウハンドルが返る if lparam = hCombox { ; wparamの上位ワードに通知コードが返る ; 通知コード1の場合は選択状態変化 (LBN_SELCHANGE) if HIWORD(wparam) = 1 { ; 現在選択中のインデックス番号取得 dialog "インデックス番号: "+a+" よろしいでしょうか?",2 if stat=6 { goto *listbox_window } else { a=-1 objprm id,a return } } return } if lparam = hListbox { ; wparamの上位ワードに通知コードが返る ; 通知コード1の場合は選択状態変化 (LBN_SELCHANGE) if HIWORD(wparam) = 1 { ; 現在選択中のインデックス番号取得 ; (変数aは利用しません) sendmsg hListbox, $188 dialog "インデックス番号: "+stat+" よろしいでしょうか?",2 if stat=6 { goto *last_window } else { a=-1 objprm id,a return } } return } return
comboxおよびlistboxは,別画面(別ラベル)で使用したいと考えています。

(^_^)v様にご指摘いただいた「*commandのサブルーチンに当たる部分でobjprmやclsなどオブジェクトを削除するような処理は無いでしょうか」につきましては,確かにその様な処理を組み込んでおります。これは,よろしくない処理なのでしょうか?



たか

リンク

2019/11/29(Fri) 00:06:54|NO.88941

調べていたら下記ページを見つけました。
https://predator.hateblo.jp/entry/2014/07/13/133928
ここで示されていたように,
oncmd gosub *command, $111
に関するサブルーチン処理に問題があるのでしょうか?
上記(NO.88919)で提示させていただいたプログラムにつきまして,「gosub => return => gosub => return」になっておりません。 また,提示プログラムはかなり簡略化してありますが,本来の私の制作プログラムでは,
goto *listbox_window

goto *last_window

の先で,更にサブルーチン処理を数階層に渡って行っております。 これらの問題がWindows8環境では,VC++ランタイムエラーとして吐き出されているのでしょうか? ご示唆いただけると幸いです。よろしくお願いいたします。



沢渡

リンク

2019/11/29(Fri) 12:37:07|NO.88943

まず最初に、「gosubで飛んだら必ずreturnで戻る」というのは大鉄則です。
gosubのネストが深くなりすぎるとエラーになりますし、
特にoncmd gosubでの割り込みの場合、returnされたタイミングで
システム内部で「割り込み処理の後に必要な後始末」が行われますので、
returnを行わないと不味いことになります。

次に、WM_COMMANDによる割り込みはHSPのシステム自身も使用していますので、
処理が複雑になると、予期せぬ不具合が発生することになります。
たとえば、clsでオブジェクトを消した時等にも割り込みは発生するようで、
このせいでなぜ発生したのかよくわからないようなエラーや不具合が
発生してしまうようです。

したがって、clsでオブジェクトを削除するのをやめ、
最初にオブジェクトをすべて作成し、
場面に応じてShowWindowで隠したり表示したりする方法をとってみました。

#include "user32.as" #define ctype HIWORD(%1) (%1 >> 16 & $FFFF) //ShowWindow p1,p2 //p1はオブジェクトのハンドル。 //p2を0にするとオブジェクトを隠す。4にするとオブジェクトを表示する。 //参考:http://chokuto.ifdef.jp/urawaza/api/ShowWindow.html //オブジェクトの用意 objsize 100,30 com_item=-1 pos 0,0 : combox com_item, 60, "胡瓜\n林檎\n人参\n葡萄\n茄子\n南瓜\n玉葱" com_id=stat : com_h=objinfo(com_id,2) lis_item=-1 pos 0,0 : listbox lis_item, 60, "胡瓜\n林檎\n人参\n葡萄\n茄子\n南瓜\n玉葱" lis_id=stat : lis_h=objinfo(lis_id,2) pos 0,100 : button gosub "Back",*combox_window but1_id=stat : but1_h=objinfo(but1_id,2) pos 0,20 : button gosub "Yes",*combox_window but2_id=stat : but2_h=objinfo(but2_id,2) pos 0,80 : button gosub "Back",*listbox_window but3_id=stat : but3_h=objinfo(but3_id,2) gosub *combox_window ; WM_COMMAND oncmd gosub *command, $111 onexit *exit stop *hide_all //全てのオブジェクトを隠す ShowWindow com_h,0 ShowWindow lis_h,0 ShowWindow but1_h,0 ShowWindow but2_h,0 ShowWindow but3_h,0 return *combox_window color 255,255,255 : boxf : color 0,0,0 gosub *hide_all objprm com_id,-1 ShowWindow com_h,4 return *listbox_window color 255,255,255 : boxf : color 0,0,0 gosub *hide_all pos 0,80 : mes "ひとつ画面を(*combox_windowへ)戻る" objprm lis_id,-1 ShowWindow lis_h,4 ShowWindow but1_h,4 return *last_window color 255,255,255 : boxf : color 0,0,0 gosub *hide_all pos 0,0 : mes "最初に戻る(*combox_window)" ShowWindow but2_h,4 pos 0,50 : mes "ひとつ画面を(*listbox_windowへ)戻る" ShowWindow but3_h,4 return *command ; lparamにはオブジェクトのウィンドウハンドルが返る if lparam = com_h { ; wparamの上位ワードに通知コードが返る ; 通知コード1の場合は選択状態変化 (LBN_SELCHANGE) if HIWORD(wparam) = 1 { ; 現在選択中のインデックス番号取得 sendmsg com_h, $147 dialog "インデックス番号: "+stat+" よろしいでしょうか?",2 if stat=6 { gosub *listbox_window } else { objprm com_id,-1 return } } return } if lparam = lis_h { ; wparamの上位ワードに通知コードが返る ; 通知コード1の場合は選択状態変化 (LBN_SELCHANGE) if HIWORD(wparam) = 1 { ; 現在選択中のインデックス番号取得 sendmsg lis_h, $188 dialog "インデックス番号: "+stat+" よろしいでしょうか?",2 if stat=6 { gosub *last_window } else { objprm lis_id,-1 return } } return } return *exit //終了時にプロセスが残ってしまうのを防ぐため、終了前にoncmd割り込みを無効にする //http://mclab.uunyan.com/lab/hspneta/neta004.htm oncmd 0 clrobj end



沢渡

リンク

2019/11/29(Fri) 12:41:54|NO.88944

追記ですが、もしWM_COMMAND絡みの不具合が多発するようなら、
oncmdでの割り込みをやめて、無限ループを作ってコンボボックスやリストボックスの選択内容が
変化しているかどうかを監視する手法をとるのも、一つの手です。


#include "user32.as" #define ctype HIWORD(%1) (%1 >> 16 & $FFFF) //ShowWindow p1,p2 //p1はオブジェクトのハンドル。 //p2を0にするとオブジェクトを隠す。4にするとオブジェクトを表示する。 //参考:http://chokuto.ifdef.jp/urawaza/api/ShowWindow.html //オブジェクトの用意 objsize 100,30 com_item=-1 : com_item_old=-1 pos 0,0 : combox com_item, 60, "胡瓜\n林檎\n人参\n葡萄\n茄子\n南瓜\n玉葱" com_id=stat : com_h=objinfo(com_id,2) lis_item=-1 : lis_item_old=-1 pos 0,0 : listbox lis_item, 60, "胡瓜\n林檎\n人参\n葡萄\n茄子\n南瓜\n玉葱" lis_id=stat : lis_h=objinfo(lis_id,2) pos 0,100 : button gosub "Back",*combox_window but1_id=stat : but1_h=objinfo(but1_id,2) pos 0,20 : button gosub "Yes",*combox_window but2_id=stat : but2_h=objinfo(but2_id,2) pos 0,80 : button gosub "Back",*listbox_window but3_id=stat : but3_h=objinfo(but3_id,2) gosub *combox_window exit_flag=0 //この値を0以外にすれば無限ループから脱出する(無限ループから脱出する場合は必ずbreakで脱出すること) repeat if exit_flag : break if com_item!=com_item_old { //コンボボックスに変化があった場合 dialog "インデックス番号: "+com_item+" よろしいでしょうか?",2 if stat=6 { gosub *listbox_window com_item_old=com_item } else { gosub *combox_reset } } if lis_item!=lis_item_old { //リストボックスに変化があった場合 dialog "インデックス番号: "+lis_item+" よろしいでしょうか?",2 if stat=6 { gosub *last_window lis_item_old=lis_item } else { gosub *lisbox_reset } } await 100 loop stop *hide_all //全てのオブジェクトを隠す ShowWindow com_h,0 ShowWindow lis_h,0 ShowWindow but1_h,0 ShowWindow but2_h,0 ShowWindow but3_h,0 return *combox_reset com_item=-1 : com_item_old=-1 objprm com_id,-1 return *combox_window color 255,255,255 : boxf : color 0,0,0 gosub *hide_all gosub *combox_reset ShowWindow com_h,4 return *lisbox_reset lis_item=-1 : lis_item_old=-1 objprm lis_id,-1 return *listbox_window color 255,255,255 : boxf : color 0,0,0 gosub *hide_all pos 0,80 : mes "ひとつ画面を(*combox_windowへ)戻る" gosub *lisbox_reset ShowWindow lis_h,4 ShowWindow but1_h,4 return *last_window color 255,255,255 : boxf : color 0,0,0 gosub *hide_all pos 0,0 : mes "最初に戻る(*combox_window)" ShowWindow but2_h,4 pos 0,50 : mes "ひとつ画面を(*listbox_windowへ)戻る" ShowWindow but3_h,4 return



沢渡

リンク

2019/11/29(Fri) 12:45:03|NO.88945

すみません、「予期せぬ不具合が発生することになります」は
「予期せぬ不具合に繋がる可能性も高まります」に読み替えてください。



たか

リンク

2019/12/1(Sun) 18:35:44|NO.88967

沢渡様,ありがとうございます。
ご指摘いただいたことを踏まえ,プログラムに組み込んでみます。

Windows8にて,改善プログラムにより問題が解決されたら,解決チェックを付けたいと思います。



たか

リンク

2019/12/9(Mon) 16:23:33|NO.89028

沢渡様にご指摘いただいた点に留意してプログラムを改良した結果,Windows8にてVC++のランタイムエラーが発生せず,適切に動作することができました。
丁寧なご提言,ありがとうございました。



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