C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[4]: WinCEのDialogResultのイベント順序について


(過去ログ 130 を表示中)

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■76951 / inTopicNo.1)  WinCEのDialogResultのイベント順序について
  
□投稿者/ トシ (1回)-(2015/08/31(Mon) 14:22:52)

分類:[VB.NET/VB2005 以降] 

2015/08/31(Mon) 14:48:41 編集(投稿者)
2015/08/31(Mon) 14:47:48 編集(投稿者)

動作OS
  Windows Embedded Compact 7

開発環境
  Microsoft Windows 7 SP1
  Microsoft Visual Studio 2008 (VB.netを使用)
  .Net Compact Framework 3.5

質問内容
  モーダルダイアログボックスの DialogResult と FormClosing イベントの関係について

本題
 他に質問する場所もなく、こちらにてはじめて質問させていただきます。
  どうぞよろしくお願いいたします。
 
  作成した簡易プログラム
  '--- Form1 --- Buttonコントロールを1個配置
  Public Class Form1
    Private Sub Button1_Click( sender As System.Object,  e As System.EventArgs) Handles Button1.Click
      Dim ret   As DialogResult
      Debug.WriteLine( "Form1:Click Start" )
      Using wForm As Form = New Form2
        ret = wForm.ShowDialog
      End Using
      Debug.WriteLine( "Form1:Click End" )
    End Sub
  End Class

  '--- Form2 --- Buttonコントロールを1個配置
  Public Class Form2
    Private Sub Button1_Click( sender As System.Object,  e As System.EventArgs) Handles Button1.Click
      Debug.WriteLine( "  Form2:Click Start" )
      Me.DialogResult = Windows.Forms.DialogResult.Yes      '-- テスト1 
      Me.DialogResult = Windows.Forms.DialogResult.No       '-- テスト2 2度セットしていることに意味はありません。
      Debug.WriteLine( "  Form2:Click End" )
    End Sub
    
    Private Sub Form2_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
      Debug.WriteLine( "    Form2:Closing Start" )
      Debug.WriteLine( "    Form2:Closing End" )
    End Sub
  End Class


上記テストプログラムを作成しました。
動作内容は
  @プログラムを起動
  AForm1 のボタンを押して Form2 を開く
  BForm2 のボタンを押して、Form2 を閉じる
を行っています。

この場合のログを Windows 7 SP1 と Windows Embedded Compact 7 で比較すると以下のようになります。

Windows 7 SP1
    Form1:Click Start
      Form2:Click Start
      Form2:Click End           ※注目
        Form2:Closing Start     ※注目
        Form2:Closing End       ※注目
    Form1:Click End

Windows Embedded Compact 7
    Form1:Click Start
      Form2:Click Start
        Form2:Closing Start     ※注目  DialogResult.Yes    設定タイミング
        Form2:Closing End       ※注目
        Form2:Closing Start     ※注目  DialogResult.No     設定タイミング
        Form2:Closing End       ※注目
      Form2:Click End           ※注目
    Form1:Click End

上記のように、DialogResultの設定により、FormClosingイベントの順番が違います。
なぜこのようなことが起きているのかは不明ではありますが、
どのような対応をするのが正しい(よりベスト)なのかがわかりません。
※実は、この動作によって、フォームが正しく終了していないような動作が
  発生しているようなのです。(2度めのFormClosing Endで停止)

お分かりになる方がおりましたら、アドバイスを頂ければと思います。
何卒よろしくお願いいたします。

引用返信 編集キー/
■76953 / inTopicNo.2)  Re[1]: WinCEのDialogResultのイベント順序について
□投稿者/ Hongliang (337回)-(2015/08/31(Mon) 14:59:41)
> 上記のように、DialogResultの設定により、FormClosingイベントの順番が違います。
> なぜこのようなことが起きているのかは不明ではありますが、

そういうものとしか言いようがないような。
ターゲットがWindowsとWindows CEという別のOSである以上、実装に差異があるのは当然でしょう。

> どのような対応をするのが正しい(よりベスト)なのかがわかりません。

DialogResultを一度きりしか設定しないようにすれば良いんじゃないでしょうか。
不正終了する動作は.NET Compact Frameworkのバグかもしれませんが、
それをMSに報告したところで今更.NET Compact Framework 3.5を修正するとも思えませんし。
引用返信 編集キー/
■76954 / inTopicNo.3)  Re[2]: WinCEのDialogResultのイベント順序について
□投稿者/ kiku (56回)-(2015/08/31(Mon) 15:15:51)

環境はWindows Embedded Compact 7ではなく
WindowsCE6.0ですが、
同じ現象を確認しました。

仕様として受け入れるしかなさそうです。

引用返信 編集キー/
■76955 / inTopicNo.4)  Re[3]: WinCEのDialogResultのイベント順序について
□投稿者/ トシ (2回)-(2015/08/31(Mon) 15:36:07)
No76954 (kiku さん) に返信
> 
> 環境はWindows Embedded Compact 7ではなく
> WindowsCE6.0ですが、
> 同じ現象を確認しました。
> 
> 仕様として受け入れるしかなさそうです。


HongLiang様 kiku様
ご返信ありがとうございます。

kiku様に至っては、確認までしていただきありがとうございます。
お二人とも
「仕様として受け入れるしかない」
という意見で、私もその通りだとは思っています。
上司が理由を知りたがるので、何かご存知または、ベストな情報をお持ちかと思い質問させていただきました。

今回は

    Private ResultCode      As DialogResult = Windows.Forms.DialogResult.None

    Private Sub Button1_Click( sender As System.Object,  e As System.EventArgs) Handles Button1.Click
        Debug.WriteLine( "  Form2:Click Start" )
        ResultCode = Windows.Forms.DialogResult.Yes
        ResultCode = Windows.Forms.DialogResult.No
        Debug.WriteLine( "  Form2:Click End" )
        Me.Close
    End Sub
    
    Private Sub Form2_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        Debug.WriteLine( "    Form2:Closing Start" )
        Me.DialogResult = ResultCode
        Debug.WriteLine( "    Form2:Closing End" )
    End Sub

Microsoftの情報 https://msdn.microsoft.com/ja-jp/library/system.windows.forms.form.dialogresult(v=VS.100).aspx より
 〜 ユーザーが閉じるボタンをクリックしたときに DialogResult プロパティに割り当てられる値をオーバーライドするには、 〜
 〜 フォームの Closing イベントのイベント ハンドラーで DialogResult プロパティを設定します。            〜
から、Closingイベントで設定することは認められていると判断し

上記ソースのように、いったんプライベート変数に格納後、
自分でクローズを行い、Closing イベント内で設定を行うこととします。

ちなみに、この場合のログは
 Form1:Click Start
   Form2:Click Start
     Form2:Closing Start
     Form2:Closing End
   Form2:Click End
 Form1:Click End

となります。
※Closingイベント内で設定する事で、Closingイベントが無限ループしそうで怖かったですが、
 発生しなかったので、何かしら対策されているものだと思います。

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

解決済み
引用返信 編集キー/
■76956 / inTopicNo.5)  Re[1]: WinCEのDialogResultのイベント順序について
□投稿者/ 魔界の仮面弁士 (475回)-(2015/08/31(Mon) 15:39:18)
2015/08/31(Mon) 16:13:21 編集(投稿者)

No76951 (トシ さん) に返信
> '--- Form2 --- Buttonコントロールを1個配置
> Public Class Form1
Form1 クラスなのに Form2…?


> この場合のログを Windows 7 SP1 と Windows Embedded Compact 7 で比較すると以下のようになります。
.NET Compact Framework に Form.FormClosing イベントは無いはずです。
(Form.Closing イベントなら、.NET / .NET Comapact の両方にあります)
https://msdn.microsoft.com/ja-jp/library/system.windows.forms.form_events%28vs.90%29.aspx



> 上記のように、DialogResultの設定により、FormClosingイベントの順番が違います。
> なぜこのようなことが起きているのかは不明ではありますが、
> どのような対応をするのが正しい(よりベスト)なのかがわかりません。

DialogResult プロパティをセットしたときにフォームが閉じられるのは仕様です。
(モーダルなら非表示になり、モードレスなら破棄されます)
この点は、.NET Compact Framework でも .NET Framework でも同様です。

違うのは、いつ閉じられるのかという「タイミング」の問題です。



> この場合のログを Windows 7 SP1 と Windows Embedded Compact 7 で比較すると以下のようになります。

当方の実験結果:

【.NET Compact Framework 3.5 App on Windows 7 Pro SP1 /w CLR 2.0】

Form1:Click Start
 Form2:Click Start
 Form2:Click End
 Form2:Closing Start
 Form2:Closing End
Form1:Click End

【.NET Compact Framework 3.5 on Pocket PC 2003 SE エミュレータ】

Form1:Click Start
 Form2:Click Start
 Form2:Closing Start
 Form2:Closing End
 Form2:Closing Start
 Form2:Closing End
 Form2:Click End
Form1:Click End


今度は、【.NET Framework 3.5 on Windows 7 Pro SP1】 で実験。
ついでに、Application.Idle イベントが発生した時にもログを残しています。

(Application.Idle)
Form1:Click Start
(Application.Idle)
 Form2:Click Start
 Form2:Click End
(Application.Idle)
 Form2:Closing Start
 Form2:Closing End
Form1:Click End
(Application.Idle)


Form1 の Button1_Click にせよ
Form2 の Button1_Click にせよ
Form2 の Form2_Closing にせよ、
それらが開始されるのは、Application.Idle が呼ばれた後ということが分かります。

また、Appliation.Idle になるのは、End Sub 通過後(あるいは、ShgowDialog 時)に
限られます。これは、他の多くのイベントにおいても同じ動きです。


デスクトップ OS においては、イベント処理が終わってアイドル時にならないと、
Windows Message は基本的に処理されません。(実際に反映されるのは「End Subの後」です)
引用返信 編集キー/
■76957 / inTopicNo.6)  Re[2]: WinCEのDialogResultのイベント順序について
□投稿者/ トシ (3回)-(2015/08/31(Mon) 15:51:15)
No76956 (魔界の仮面弁士 さん) に返信

魔界の仮面弁士様
ご返答ありがとうございます。
よくお名前を拝見するので、いろいろ参考にさせていただいております。

> ■No76951 (トシ さん) に返信
>> '--- Form2 --- Buttonコントロールを1個配置
>> Public Class Form1
> Form1 クラスなのに Form2…?

これについては申し訳ありません。
後から気付いて修正いたしましたが、私の誤記です。



>>この場合のログを Windows 7 SP1 と Windows Embedded Compact 7 で比較すると以下のようになります。
> .NET Compact Framework に Form.FormClosing イベントは無いはずです。
> (Form.Closing イベントなら、.NET / .NET Comapact の両方にあります)
> https://msdn.microsoft.com/ja-jp/library/system.windows.forms.form_events%28vs.90%29.aspx

おっしゃる通り、Form.Closingが正しいです。


>>上記のように、DialogResultの設定により、FormClosingイベントの順番が違います。
>>なぜこのようなことが起きているのかは不明ではありますが、
>>どのような対応をするのが正しい(よりベスト)なのかがわかりません。
>
> DialogResult プロパティをセットしたときにフォームが閉じられるのは仕様です。
> (モーダルなら非表示になり、モードレスなら破棄されます)
> この点は、.NET Compact Framework でも .NET Framework でも同様です。

こちらの件につきましては、私のほうでもマイクロソフト社のページで拝見いたしました。
当初、VB6の癖から Closeメソッド も書いてしまい、フォームクローズイベントが大量発生しました・・・
※今思えば、この時から後記していただいている「タイミング」による問題が発生していたことになります。



> 違うのは、いつ閉じられるのかという「タイミング」の問題です。
>
>>この場合のログを Windows 7 SP1 と Windows Embedded Compact 7 で比較すると以下のようになります。
>
> 当方の実験結果:
>
> 【.NET Compact Framework 3.5 on Windows 7 Pro SP1】
>
> Form1:Click Start
>  Form2:Click Start
>  Form2:Click End
>  Form2:Closing Start
>  Form2:Closing End
> Form1:Click End
>
> 【.NET Compact Framework 3.5 on Pocket PC 2003 SE エミュレータ】
>
> Form1:Click Start
>  Form2:Click Start
>  Form2:Closing Start
>  Form2:Closing End
>  Form2:Closing Start
>  Form2:Closing End
>  Form2:Click End
> Form1:Click End
>
> ということで、Compact Framework の仕様なのではなく、
> デスクトップ系と CE 系の OS の動作の差違だと思います。
>
> 今度は、【.NET Framework 3.5 on Windows 7 Pro SP1】 で実験。
> ついでに、Application.Idle イベントが発生した時にもログを残しています。
>
> (Application.Idle)
> Form1:Click Start
> (Application.Idle)
>  Form2:Click Start
>  Form2:Click End
> (Application.Idle)
>  Form2:Closing Start
>  Form2:Closing End
> Form1:Click End
> (Application.Idle)
>
>
> Form1 の Button1_Click にせよ
> Form2 の Button1_Click にせよ
> Form2 の Form2_Closing にせよ、
> それらが開始されるのは、Application.Idle が呼ばれた後ということが分かります。
>
> また、Appliation.Idle になるのは、End Sub 通過後(あるいは、ShgowDialog 時)に
> 限られます。これは、他の多くのイベントにおいても同じ動きです。
>
>
> デスクトップ OS においては、イベント処理が終わってアイドル時にならないと、
> Windows Message は基本的に処理されません。(実際に反映されるのは「End Subの後」です)


つまり、CE系のOSでは、アイドル状態にならなくても、順次発生するべきイベントが発生している
という認識でよろしいでしょうか?
確かに、通常のWindowsアプリケーションでは、現在処理中の処理が完了(End Sub等)されるまで、
開始されない状況であるのは認識おりました。
もし、CE系ではこの点が違うとしたら、私は大きなミスをしてしまっているのかもしれません。
全体的に見直してみる必要がありそうです・・・

魔界の仮面弁士様、大変貴重な情報ありがとうございました。

解決済み
引用返信 編集キー/
■76959 / inTopicNo.7)  Re[3]: WinCEのDialogResultのイベント順序について
□投稿者/ 魔界の仮面弁士 (476回)-(2015/08/31(Mon) 18:05:14)
No76957 (トシ さん) に返信
> つまり、CE系のOSでは、アイドル状態にならなくても、順次発生するべきイベントが発生している
> という認識でよろしいでしょうか?

あくまでも「DialogResult の場合は、即座に閉じられている」というだけですね。

CE の場合、イベントの流れが異なっているものがあるのは確かですが、
すべてのイベントがそういう動作になっているかどうかは別問題かと思います。


なお DialogResult の setter 実装 を調べてみると、
Compact では無い方の .NET Framework においては、
|
| Me.praivateな変数 = 新しいDialogResult値
|
という単純な処理しか行われていないようです。(参考: referencesource.microsoft.com )

ゆえに、DialogResult をセットしてすぐに閉じるれることはなく、
後から(アイドル時に)その変数が内部的に参照されることによって、
閉じる処理に移行するという流れになるようです。
(上記変数が None か否かが、各所でチェックされています)


肝心の .NET Compact Framework については、ソースが公開されていないので
詳しい調査はできませんが、DialogResult プロパティをセットしただけで
即座に閉じられるという事は、内部フィールドの変更だけでなく、
実際の閉じる処理まで一緒に行われるように実装されているのでしょう。多分。



No76955 (トシ さん) に返信
> ※Closingイベント内で設定する事で、Closingイベントが無限ループしそうで怖かったですが、
>  発生しなかったので、何かしら対策されているものだと思います。

対策されているかどうかが心配なら、標準の DialogResult を使うのはやめ、
同等機能を持ったプロパティを独自に作ってみるとか。
引用返信 編集キー/
■76962 / inTopicNo.8)  Re[4]: WinCEのDialogResultのイベント順序について
□投稿者/ トシ (4回)-(2015/08/31(Mon) 18:49:03)
No76959 (魔界の仮面弁士 さん) に返信
>>※Closingイベント内で設定する事で、Closingイベントが無限ループしそうで怖かったですが、
>> 発生しなかったので、何かしら対策されているものだと思います。
> 対策されているかどうかが心配なら、標準の DialogResult を使うのはやめ、
> 同等機能を持ったプロパティを独自に作ってみるとか。

あー・・・
確かに、プライベートな戻り値格納用変数用意するくらいなら
それをパブリックなプロパティに変更して利用するのもありですね・・・

ありがとうございます、参考にさせていただきます。


引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -