|
 |
|
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)

| |
|
2019/11/22(Fri) 01:29:52|NO.88901
*commandのサブルーチンに当たる部分でobjprmやclsなどオブジェクトを削除するような処理は無いでしょうか
>下記サンプルプログラムを参考にcomboxおよびlistboxの自動監視・判別処理を追加したことが原因
この場合、サンプルプログラムではなくいじった方で不要な部分を削ったソースが必要です。
質問をするために最小限ソースを用意する段階で気づくこともあります。
|
|
2019/11/22(Fri) 08:30:55|NO.88902
これ、連動リストボックスとか使ってるんじゃ・・・
リストボックス.A が変更されると連動してリストボックス.B の内容が変化するやつ。
|
|
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++のランタイムエラーが発生せず,適切に動作することができました。
丁寧なご提言,ありがとうございました。
|
|