- PR -

終了処理について

投稿者投稿内容
pon
会議室デビュー日: 2007/04/04
投稿数: 5
投稿日時: 2007-04-04 11:00
ME.Closeでアプリケーションを終了することができません

具体的には Activated や Click イベントで

--------------------
MsgBox("OK")
Me.Close()
MsgBox("NG")
--------------------

と記述して実行したところ
MsgBox("NG")が実行されてしまいます
さらにプロセスも終了しません

--------------------
MsgBox("OK")
End
MsgBox("NG")
--------------------

とすれば表示はされないのですが

ME.Closeで終了しない理由と
Endでよいのかの2点が知りたいです

やりたいことは

処理1(エラーの場合はメッセージを出して終了)
処理2(エラーの場合はメッセージを出して終了)



です

長文すみませんでした

開発環境:VB.NET 2003
プロジェクト:Windowsアプリケーション
mio
ぬし
会議室デビュー日: 2005/08/25
投稿数: 734
お住まい・勤務地: 神奈川県
投稿日時: 2007-04-04 11:15
Closeは「ウィンドウを閉じる」であって「終了」ではないから、でしょう。
完全に終了したいならEndで良いのでは。
ぽぴ王子
ぬし
会議室デビュー日: 2006/03/24
投稿数: 475
お住まい・勤務地: お住まい:城・勤務地:城
投稿日時: 2007-04-04 11:27
引用:

具体的には Activated や Click イベントで

--------------------
MsgBox("OK")
Me.Close()
MsgBox("NG")
--------------------

と記述して実行したところ
MsgBox("NG")が実行されてしまいます
さらにプロセスも終了しません


ウィンドウのクローズ=アプリケーションの終了 ではないからです。
プログラムが走るときに「アプリケーション メッセージ ループ」というものが
実行されます。
一般的にはこのメッセージループからメインとなるフォームを開き、その中
で処理を行うような形になると思います(VB では意識しなくても良いようで
すが、そのようなものが裏で動いていると思ってください)。

イベント中に Me.Close() を実行しても、実際にプロセスが終了するのは
イベントプロシージャの処理が終了した後で、「メインフォームがクローズし
ている」ことをメッセージループが確認して自主的にアプリケーションを終了
します。

引用:

--------------------
MsgBox("OK")
End
MsgBox("NG")
--------------------

とすれば表示はされないのですが


End ステートメントは従来の Visual Basic、と言うよりも BASIC との互
換性のために残されていると思った方が良いでしょう。
MSDN の End ステートメントのページにも

引用:

End の使用はできる限り控えて、すぐに停止する必要がある場合にのみ使用してください。


と記されています。
上記のアプリケーション メッセージ ループを使用する場合は、終了時のい
ろいろな処理を行うタイミングがわかっている(メッセージループを抜けたと
きということがわかる)わけですが、End ステートメントを使うとそういった
処理を無視して即時終了してしまいます。これはいけません。

メッセージを出して終了(ウィンドウをクローズ)したい場合は、クローズして
からその後の処理を実行させなければよいのです。たとえば以下のように
なると思います。

コード:

Private Sub Button1_Click(
        ByVal sender As System.Object,
        ByVal e As System.EventArgs) Handles Button1.Click
    〜なんらかの処理〜
    If ダメな条件 Then
        MsgBox("NG")
        Me.Close()
        Exit Sub
    End If
    MsgBox("OK")
End Sub



ちなみに Load イベントなどではウィンドウをクローズしない方が良かった
りします。
_________________
ぽぴ王子@わんくま同盟
ぽぴ王子の人生プログラミング中 / ぽぴンち。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2007-04-04 11:32
引用:

ponさんの書き込み (2007-04-04 11:00) より:
具体的には Activated や Click イベントで

--------------------
MsgBox("OK")
Me.Close()
MsgBox("NG")
--------------------

と記述して実行したところ
MsgBox("NG")が実行されてしまいます
さらにプロセスも終了しません


VB/VB.NET に限らず、どの言語でも基本的に同じですが、Close などのメソッド呼び出しは、単にそういう名前のメソッドを呼ぶというだけの意味しかありません。「Activated や Click イベント」用のコールバックメソッド内のコードの実行が、その中で Close メソッドを呼んだということで、勝手に中断することは基本的にありません。
ただ、呼んだメソッドの中で End 相当のことをしていれば中断するわけですが、たまたま Close にはそういうことは盛り込まれていません。私としてはこのほう(盛り込んでいないほう)が自然だと思います。(とはいえ、古い例ですが、たとえば、ASP の Response.End はその中で中断のようなことをしているようです。)

普通は、Dispose しなければならないものすべてを Dispose すればアプリケーションが勝手に終わるものですが、たまに、環境のバグやコードの間違いで Dispose し忘れがあると終わらないこともありますので、Dispose はきちんとやった上で、最後に念のため End を呼ぶのは良いことだと思います。

--
unibon {B73D0144-CD2A-11DA-8E06-0050DA15BC86}
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-04-04 11:58
引用:

mioさんの書き込み (2007-04-04 11:15) より:

Closeは「ウィンドウを閉じる」であって「終了」ではないから、でしょう。
完全に終了したいならEndで良いのでは。


End は、強制終了なのでダメですね。
System.Environment.Exit メソッド を呼び出しているのですから。

# って、ぽぴ王子さんと概ね同じ意見なのでいくつか削除... orz

--
MainForm だという前提で...

そもそも、Close メソッドの後に、そのインスタンス内で何かをすること自体が流儀に反していると思います。
また、Activated イベントで何かを判断して Form が閉じられることがあるというのは好ましい仕様ではありません。

開く前に判断するのが一般的です。
GUI が欲しいということであれば、開いた後に呼び出し元で判断して呼び出し元から閉じると良いでしょう。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
pon
会議室デビュー日: 2007/04/04
投稿数: 5
投稿日時: 2007-04-04 11:58
皆さま早速の回答ありがとうございます

例えば終了前に必ずメッセージを出して終了したい場合は

--------------------
' 共通の終了処理
Private Sub aplQuit(ByVal svMsg As String)
MsgBox(svMsg)
Me.Close()
End Sub
--------------------

ではなく
--------------------
' グローバル値
Private m_bQuitFlg As Boolean = False

' 共通の終了処理
Private Function aplQuit(ByVal svMsg As String)
MsgBox(svMsg)
Return True
End Function
--------------------

としておき

--------------------
if (m_bQuitFlg = Fale) then
処理1
endif

if (m_bQuitFlg = Fale) then
処理2
endif



if (m_bQuitFlg = True) then
Me.Close()
' 各オブジェクトの破棄
XX.Dispose



Application.Exit()
' 念のため
End
endif
--------------------

とするのが良いのでしょうか?
pon
会議室デビュー日: 2007/04/04
投稿数: 5
投稿日時: 2007-04-04 12:40
すみません
記述漏れがありました

----------
m_bQuitFlg = aplQuit("処理1")
if (m_bQuitFlg = Fale) then
処理1
endif

m_bQuitFlg = aplQuit("処理2")
if (m_bQuitFlg = Fale) then
処理2
endif


----------
ShuU
常連さん
会議室デビュー日: 2006/09/29
投稿数: 21
投稿日時: 2007-04-04 13:36
引用:

例えば終了前に必ずメッセージを出して終了したい場合は


終了時に何らかのメッセージを出すならば、"Closed"イベントに書けば良いかと。
(どっかでMe.Close()したら呼ばれる)

引用:

やりたいことは

処理1(エラーの場合はメッセージを出して終了)
処理2(エラーの場合はメッセージを出して終了)



です


最初の質問に戻ると

コード:
Public Class Form1
    Private m_bQuitFlg As Boolean = False

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        m_bQuitFlg = 処理1()

        If m_bQuitFlg = False Then
            Me.Close()
        End If

        m_bQuitFlg = 処理2()

        If m_bQuitFlg = False Then
            Me.Close()
        End If

        MessageBox.Show("OK!")
    End Sub

    Private Sub Form1_FormClosed(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed
        If m_bQuitFlg = False Then
            MessageBox.Show("NG!")
        End If
    End Sub

    Private Function 処理1() As Boolean
        処理1 = True
    End Function

    Private Function 処理2() As Boolean
        処理2 = False
    End Function
End Class


上記はVB2005Expressで書いたので"FormClosed"ですが、VB.NET2003なら"Closed"だったと思います。
(ヘルプ見てくださいませ)

P.S. 念のためであろうと"End"使わないきゃ終わらないのは良くないと思います。

スキルアップ/キャリアアップ(JOB@IT)