Can we manage the Close (X) button found at the top right corner of every form?
If I would like a display a dialog box when the Close button is pressed, how can I do so?
Please help. Thank you!
Printable View
Can we manage the Close (X) button found at the top right corner of every form?
If I would like a display a dialog box when the Close button is pressed, how can I do so?
Please help. Thank you!
VB Code:
Private Sub myForm_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing MessageBox.Show("Close") End Sub
This shows a message box when the form is closing.
But not essentially when X button clicked.Quote:
This shows a message box when the form is closing.
If you need to know the reason the form is closing then try this:
VB Code:
Public Enum QueryUnloadModes SystemShutdown TaskManager MenuClose CodeCall Unknown End Enum Public Function QueryUnloadMode() As QueryUnloadModes 'PURPOSE: This function provides the same functionality that the QueryUnloadMode 'parameter did when closing a form in VB6. It returns the reason the form is closing. 'It has not been tested when run outside of the Closing event but does work as 'expected when called from the Closing event of a form. 'SOURCE: Most of the code found here is a variant of the following two sources: ' [url]http://www.gotdotnet.com/Community/MessageBoard/Thread.aspx?id=42556[/url] ' [url]http://www.gotdotnet.com/community/messageboard/Thread.aspx?id=40651[/url] Dim st As New System.Diagnostics.StackTrace(True) If st.FrameCount >= 15 Then If st.GetFrame(15).GetMethod.Name <> "WmSysCommand" Then Return QueryUnloadModes.SystemShutdown End If End If Dim O As New System.Diagnostics.StackTrace(True) Dim F As System.Diagnostics.StackFrame F = O.GetFrame(8) Select Case F.GetMethod.Name.ToString Case "SendMessage" 'Closing because of call in code Return QueryUnloadModes.CodeCall Case "CallWindowProc" 'Closing because of system menu click Return QueryUnloadModes.MenuClose Case "DispatchMessageW" 'Closing because of Task Manager Return QueryUnloadModes.TaskManager Case Else 'Don't Know why I'm closing!!?? Return QueryUnloadModes.Unknown End Select End Function
Then just call it from the closing event of the form and it will return the enum value for the reason.
VB Code:
Dim ret As QueryUnloadModes = QueryUnloadMode() If ret <> QueryUnloadModes.SystemShutdown Then e.Cancel = True Me.Hide() End If
It can also be put in a dll and used from there.
Edneeis,
I appreciate your reply.
But understand nothing of what you had explained.
Can you please explain to me in more details?
Thank you.
Well if you programmed in VB6 you'd be familiar with UnloadMode which was an argument that was in the QueryUnload event of a form which told you why the form was closing (i.e because of code, system shut down, close button..). In .NET there is no suck argument so this provides basically the samething. I'm not sure its what you were looking for but I had just read your post and used the class and thought someone might find it useful as well.
If all you need to do is capture when a form is closing then you don't need it, you can just use the Closing event as previously mentioned. This code is intended to be used in the Closing event IF you need to know WHY the form is closing not WHEN.
It seems to me that QueryUnloadMode doesn't trap for specifically when the X button is pushed?
Do you mean in VB6?
I think the original poster was asking about .NET (I'm curious too).
I think I was confused for a second you were asking about the QueryUnloadMode code I posted right? I thought you were asking about QueryUnload in VB6.
It should trap for the X close button and return MenuClose. I haven't tested on multiple OSs but it worked on Windows 2000 and XP.
Just run this in the closing event:
VB Code:
Msgbox(QueryUnloadMode.ToString)
Yeah that's what I thought it did - but MenuClose is also returned from Menu -> Close (presumably Form.Close)?
I mean in VB .NET.
Yes the code posted is for VB.NET sorry about the confusing. I brought up VB6 because it mirrors something already available in VB6.
Slow_Learner, I don't understand your question, what else would Menu->Close return?
SystemShutdown - Returned when the request to close the application or form is caused by Windows shutting down.
TaskManager - Returned when the application process is closed via the TaskManager.
MenuClose - Returned when the close button of the form, the little X in the corner, causes the form or application to close.
CodeCall - Returned when the form or application is closed due to a request from code (i.e. Me.Close).
Unknown - Returned when it was not able to determine the reason the form or application is closing.
There may be trouble with it returning SystemShutdown instead of Code on XP machines. I'm looking into this.
//Slow_Learner, I don't understand your question, what else would Menu->Close return?
This is kind of a tangent from what the original poster wanted to know - what I was curious about was how you could discriminate between a form closing by pressing the X button, and any other method. Guess you'd use Form.MouseDown and look for where the top right corner of the form is. Never mind, I was over-curious :)
Fixed the trouble with Shutdown instead of CodeCall:
VB Code:
Public Enum QueryUnloadModes SystemShutdown TaskManager MenuClose CodeCall Unknown End Enum Public Function QueryUnloadMode() As QueryUnloadModes 'PURPOSE: This function provides the same functionality that the QueryUnloadMode 'parameter did when closing a form in VB6. It returns the reason the form is closing. 'It has not been tested when run outside of the Closing event but does work as 'expected when called from the Closing event of a form. 'SOURCE: Most of the code found here is a variant of the following two sources: ' [url]http://www.gotdotnet.com/Community/...d.aspx?id=42556[/url] ' [url]http://www.gotdotnet.com/community/...d.aspx?id=40651[/url] Dim st As New StackTrace(True) Dim O As New System.Diagnostics.StackTrace(True) Dim F As System.Diagnostics.StackFrame F = O.GetFrame(8) Select Case F.GetMethod.Name.ToString Case "SendMessage" 'Closing because of call in code Return QueryUnloadModes.CodeCall Case "CallWindowProc" Try If st.GetFrame(15).GetMethod.Name = "WmSysCommand" Then 'Closing because of system menu click Return QueryUnloadModes.MenuClose Else 'Closing because of system shut down Return QueryUnloadModes.SystemShutdown End If Catch 'Don't Know why I'm closing!!?? Return QueryUnloadModes.Unknown End Try Case "DispatchMessageW" 'Closing because of Task Manager Return QueryUnloadModes.TaskManager Case Else 'Don't Know why I'm closing!!?? Return QueryUnloadModes.Unknown End Select End Function
Maybe the phrase MenuClose is not appropriate since it isn't from a MainMenu or MenuItem. MenuClose is returned from the X of the from otherwise something else is returned. Slow_Learner this code does exactly what you are talking about. Here try this example to understand. It is a tangent from the original posters request, but I posted it anyway.
I meant the control menu in the top left (alt + space menu), which does seem to return the same thing as the X button in the top right. Thanks for the example.
Yes I believe that is the context menu of the buttons in the corner so I'm afraid it does the samething as pressing the x, sorry.
No problem at all, I was just over-curious :)