tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板 [ツリー表示へ]   [Home]
一括表示(VB6.0)
タイトルvbModeless と vbModal
記事No15047
投稿日: 2010/11/30(Tue) 11:46
投稿者ichiro
環境:VB6.0 SP6
VB歴:1年

お世話になります。
データ収集アプリですが、コード作成者に聞くことができない状況なので
質問させていただきました。

アプリの概要
・複数のロガーと1台のPCを接続し、ロガーからデータをサンプリングしデータ保存する
・サンプリング間隔などを設定画面にて行う

メイン画面に張り付けたボタンをクリックすることで、
設定画面を表示します。
この設定画面表示中にもデータのサンプリングは可としています。

Private Sub settingFormOpen()

    frmMain.Enabled = False

    isFormOpen = True                
    settingForm.Show vbModeless
    
    While isFormOpen = True
        DoEvents
        Sleep 10
    Wend

    frmMain.Enabled = True            
    frmMain.SetFocus
    
End Sub


質問は、
・vbModeless ではなく、vbModalでは違う動きになってしまうのか?
 vbModelessを使用した意図を知りたい、ということです。

メインの画面にはその他、いくつかのボタンがあります。
whileの中に、DoEventsとSleep10を書くことで、ユーザが他のボタンのクリックが可能になるように
していると思いましたが、frmmain.Enabled = False でメイン画面をロックしているため、
ボタンを操作することはできなくなります。
よって、vbModalと結果的には同じになるのでは?
と考えています。

vbModelessを vbModalに変えた場合、プログラムの動作でここが違ってくるのでは?
という点があればご教授いただけないでしょうか。

[ツリー表示へ]
タイトルRe: vbModeless と vbModal
記事No15048
投稿日: 2010/11/30(Tue) 12:17
投稿者花ちゃん
> vbModelessを vbModalに変えた場合、プログラムの動作でここが違ってくるのでは?
> という点があればご教授いただけないでしょうか。

質問するより、vbModalに変えて試した方が早いですよ。


>vbModelessを使用した意図を知りたい、ということです。

そのプログラムを作成した人にしか真意は解らないかと。
(そのコードだけでは、そのソフトの使用目的とかユーザの要望までは解りません)
他人が、多分、settingForm 内でisFormOpen = False に設定するまでは、frmMain を
触られたくないとか言っても想像にしか過ぎないし。

[ツリー表示へ]
タイトルRe: vbModeless と vbModal
記事No15049
投稿日: 2010/11/30(Tue) 13:32
投稿者GOD
> vbModelessを vbModalに変えた場合、プログラムの動作でここが違ってくるのでは?
>
モーダルウィンドウ表示中にモードレスウィンドウが表示できない。

> whileの中に、DoEventsとSleep10を書くことで、ユーザが他のボタンのクリックが可能
> になるように
>
ではなく、設定中もサンプリングできるようにしたかったのでは?
(タイマーイベントの処理?)

bbs.wankuma.com/index.cgi?mode=al2&namber=55290
↑みたいな勘違いがあったとか?(推測ですが)

[ツリー表示へ]
タイトルRe^2: vbModeless と vbModal
記事No15050
投稿日: 2010/11/30(Tue) 14:10
投稿者ichiro
花ちゃんさん、GODさん、返信有り難うございます。

さきほどの書き込みでは漏れてしまいましたが、vbModalでも試してみてはいますが、
見た目の動き的には変わらないと感じています。
なので、なぜvbModalを使わず、whileを使用して回りくどい書き方をしているのか、と
疑問に思った次第です。
呼び出されたフォーム側もプログラムを見直してみます。


>モーダルウィンドウ表示中にモードレスウィンドウが表示できない。
本アプリは設定画面上にもボタンが配置されており、別のフォームを表示する仕様になっています。
そこで以下のような簡単なサンプルプログラムで確認してみましたが、問題はありませんでした。

メイン画面 
 ↓
 ↓vbModalでオープン
 ↓
フォーム1
 ↓
 ↓vbModal、vbModelessの両方で試したが、どちらも問題なくオープンできた
 ↓
フォーム2


>ではなく、設定中もサンプリングできるようにしたかったのでは?
>(タイマーイベントの処理?)
私も最初そのように思ったのですが、vbModalの場合でもサンプリングは問題なくできてます。
Timer1は別スレッドではないにしろ、vbModal,vbModelessに関係なく動くようです。

[ツリー表示へ]
タイトルRe^3: vbModeless と vbModal
記事No15051
投稿日: 2010/11/30(Tue) 15:24
投稿者GOD
> >モーダルウィンドウ表示中にモードレスウィンドウが表示できない。
> 本アプリは設定画面上にもボタンが配置されており、別のフォームを表示する仕様になっています。
> そこで以下のような簡単なサンプルプログラムで確認してみましたが、問題はありませんでした。
>
失礼しました。
昔と動作が変わってしまったんですかね。
昔は、
donnk.com/Fudi/VBtips/VBtips16.html
↑のようになっていました。
因みに私の環境でも同じようにエラーが出ました。何が違うんだろう?

> >ではなく、設定中もサンプリングできるようにしたかったのでは?
> >(タイマーイベントの処理?)
> 私も最初そのように思ったのですが、vbModalの場合でもサンプリングは問題なくできてます。
> Timer1は別スレッドではないにしろ、vbModal,vbModelessに関係なく動くようです。
>
VB6ではスレッドは使用できないと考えた方がよいです。頑張ればできるけど保障されてい
ない。
先ほどのURLは午後からアクセスできなくなっているみたい。(キャッシュなら見れる
けど)
「isformopen」でググってタイトルが「Show()とShowDialog()」のものが非常によく似て
いる。同じ人が作ったのではと疑いたくなるほどに。

「Show()とShowDialog()」の質問者みたいにモーダルでサンプリングできないと勘違いしている人が作ったのなら
「モードレスに変更→ボタンは押させたくない→Enabled=false→Enabled=trueのタイミングが掴めない→ループ処理で終了を待つ」
なのかと思っていた。

[ツリー表示へ]
タイトルRe^4: vbModeless と vbModal
記事No15056
投稿日: 2010/11/30(Tue) 17:43
投稿者ichiro
> 失礼しました。
> 昔と動作が変わってしまったんですかね。
> 昔は、
> donnk.com/Fudi/VBtips/VBtips16.html
> ↑のようになっていました。
> 因みに私の環境でも同じようにエラーが出ました。何が違うんだろう?

GODさん、すみません。
このサンプルプログラムの確認ついては、僕がミスしました。

フォームをShowするときのオプションを 、vbModalとするところを、
Modal としてしまっていました。
(これでコンパイルエラーでないんですね。。)

結果はGODさんのおっしゃる通りになりました。

[ツリー表示へ]
タイトルRe^5: vbModeless と vbModal
記事No15057
投稿日: 2010/12/01(Wed) 09:10
投稿者魔界の仮面弁士
> フォームをShowするときのオプションを 、vbModalとするところを、
> Modal としてしまっていました。
> (これでコンパイルエラーでないんですね。。)

Option Explicit が宣言されていない場合、
未知のキーワードは変数と見做されるため、
 Dim Modal As Variant
 Modal = Empty
となり、結果として 0 すなわち vbModeless として処理されたのでしょう。

[ツリー表示へ]
タイトルRe^3: vbModeless と vbModal
記事No15052
投稿日: 2010/11/30(Tue) 15:33
投稿者花ちゃん
> 呼び出されたフォーム側もプログラムを見直してみます。

どこかに isFormOpen = False と書いていませんでしたか?
それ以降、 frmMain.Enabled = True  が有効になるはずですが。


[ツリー表示へ]
タイトルRe^4: vbModeless と vbModal
記事No15054
投稿日: 2010/11/30(Tue) 16:33
投稿者ichiro
花ちゃんさん、GODさん、度々返信有り難うございます。

> どこかに isFormOpen = False と書いていませんでしたか?
> それ以降、 frmMain.Enabled = True  が有効になるはずですが。
描画した settingForm の_Unloadイベントハンドラ内で、isFormOpenフラグはFalseに設定されています。
それ以降は、おっしゃる通り、While isFormOpen = True のループを抜け、frmMain.Enabled = Trueが
有効になります。


>「Show()とShowDialog()」の質問者みたいにモーダルでサンプリングできないと勘違いしている人が作ったのなら
>「モードレスに変更→ボタンは押させたくない→Enabled=false→Enabled=trueのタイミングが掴めない→ループ処理で終了を待つ」
>なのかと思っていた。
確かにこの推論は無理がないように思います。
作成者が「モーダルでサンプリングできない」と勘違いしていたのかどうかを確かめれないのが残念ですが。。
(おそらく10年ぐらい前のソース)

[ツリー表示へ]
タイトルRe^3: vbModeless と vbModal
記事No15053
投稿日: 2010/11/30(Tue) 16:28
投稿者魔界の仮面弁士
> なので、なぜvbModalを使わず、whileを使用して回りくどい書き方をしているのか、と
> 疑問に思った次第です。
もしかしたら、古いソースを転用し続けてきた時の名残なのかもしれません。

作った本人にしか分からないところではありますが、かつて、
古いバージョンの VB において、モーダルフォームの扱いに問題があり、
モードレスフォームで親フォームを Enabled = False にすることで
代用するケースが稀にありました。その時の処理手順に似ています。

ただし、仮にその時代のソースなら、
 settingForm.Show vbModeless
ではなく、
 settingForm.Show 0 ', frmMain
などと書いてるだろうとは思いますけれどね。


もう一つの可能性としては、
 Option Explicit
 Private Sub Command1_Click()
  MsgBox "TEST"
 End Sub
 Private Sub Timer1_Timer()
  Caption = Timer
 End Sub
のようなコードを書いた場合において、メッセージボックスの表示中は
 「EXE ならば Timer イベントが動作するが、
  開発環境では Timer イベントが発生しない」
という状況になるので、この MsgBox の動作を、モーダルフォームにおいても
同じような動きになると勘違いしていたという可能性もあるかも知れません。


> Timer1は別スレッドではないにしろ、vbModal,vbModelessに関係なく動くようです。
いずれにせよ、Sleep の利用は避けた方が良いと思います。

モーダルなら待機ループは不要ですし、仮に
モードレスにするにしても、VB4 以降ではイベントベースで
 Private WithEvents child As Form
 Private Sub settingFormOpen()
  frmMain.Enabled = False
  Set child = settingForm
  child.Show vbModeless, frmMain
 End Sub
 Private Sub child_Unload(Cancel As Integer)
  frmMain.Enabled = True
  frmMain.SetFocus
  Set child = Nothing
 End Sub
のように書けば、無駄な待機ループは不要です。

[ツリー表示へ]
タイトルRe^4: vbModeless と vbModal
記事No15055
投稿日: 2010/11/30(Tue) 17:03
投稿者ichiro
魔界の仮面弁士さま、返信ありがとうございます。

>もしかしたら、古いソースを転用し続けてきた時の名残なのかもしれません。
>    ・
>    ・
ソースコードが古いので、可能性が十分にありそうです。
当時のVBのバージョンも古いはずです。

この情報も最初に書き込んでおかなければいけなかったかもしれません。
花ちゃんさん、GODさん すみませんでした。


> 「EXE ならば Timer イベントが動作するが、
>  開発環境では Timer イベントが発生しない」
知りませんでした!!
これは現在のバージョンでもそうなのか、一度試してみます。
勉強になります。


>モーダルなら待機ループは不要ですし、仮に
>モードレスにするにしても、VB4 以降ではイベントベースで
> Private WithEvents child As Form
> Private Sub settingFormOpen()
>  frmMain.Enabled = False
>  Set child = settingForm
>  child.Show vbModeless, frmMain
> End Sub
> Private Sub child_Unload(Cancel As Integer)
>  frmMain.Enabled = True
>  frmMain.SetFocus
>  Set child = Nothing
> End Sub
>のように書けば、無駄な待機ループは不要です
この書き方はまだ実力不足なためピンとこないので、これから勉強します。

ありがとうございました。

[ツリー表示へ]
タイトル本題から外れて年表を書いてみる
記事No15058
投稿日: 2010/12/01(Wed) 10:38
投稿者魔界の仮面弁士
> ソースコードが古いので、可能性が十分にありそうです。
私が書いた「古いバージョンの VB」というのは、16bit 時代のことです。
VB2〜VB3、あるいは VB4 といった頃でしょうかね。


> 当時のVBのバージョンも古いはずです。

先の、No.15054 の投稿において、
>> (おそらく10年ぐらい前のソース)
とおっしゃっていましたが、10 年前の VB といえば、VB6 がメインです。
その当時に、古いバージョンの VB を使っているとは考えにくい気もします。

本当に古いバージョンを使っていたのなら、10年どころでは無いでしょう。


1997年12月 … VB5/VS97 SP3 リリース
1998年 9月 … VS6 リリース
1998年11月 … VB6 SP1 リリース
1999年 2月 … VB6 SP2 リリース
1999年 5月 … VB6 SP3 リリース
1999年 7月 … VBCE6.0 リリース(Windows CE Toolkit for Visual Basic 6.0)
1999年12月 … VB6 Plus Pack リリース
2000年 6月 … VB6 SP4 リリース
2000年 6月 … Forum 2000 で、ビルゲイツ氏が Microsoft.NET のビジョンを紹介
2000年10月 … eVB3 日本語版リリース(eMbedded Visual Basic 3.0)
2000年12月 … ★10年前というとこのあたり★
2001年 1月 … VS.NET β1 リリース
2001年 2月 … VB6 SP5 リリース
2001年 7月 … VS.NET β2 リリース
2002年 3月 … VS.NET リリース
2003年 4月 … VS.NET 2003 リリース
2004年 3月 … VB6 SP6 リリース
2005年 3月 … VB6 サポート期間終了
2005年12月 … VS2005 リリース
2007年12月 … VS2008 リリース
2008年 4月 … VB6 延長サポート期間終了
2010年 4月 … VS2010 リリース

[ツリー表示へ]
タイトルRe: 本題から外れて年表を書いてみる
記事No15059
投稿日: 2010/12/01(Wed) 13:50
投稿者ichiro
魔界の仮面弁士さん
返信ありがとうございました。

VB6のサポート終了の次期など、この表で初めて知りました。
参考になりました。
ありがとうございます。

[ツリー表示へ]