VB.NET - Code after Me.Close is executed - vb.net

Update: Solution by #Mark Hall:
Using Exit Sub after the Me.Close to prevent further execution of the sub while the Closing event is going on..
I'm trying to open up a popup window on closing a form where the user can decide if he really wants to close the form.
Therefore I wrote:
Private Sub Form1_FormClosing_1(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
e.Cancel = True 'Fenster wird nicht geschlossen
Dim DialogExit As DialogResult
DialogExit = MsgBox("Do you want to exit the setup process?", vbQuestion Or MsgBoxStyle.OkCancel, "Exit Setup?")
Select Case DialogExit
Case Windows.Forms.DialogResult.OK
Me._Result_ThisForm = Result_Form.Yes
e.Cancel = False
Case Else
'Just no exit
End Select
End Sub
But when I call Me.Close from somewhere in the code, the form just doesn't close but it executes further code!
Like in (somewhere in the code):
If bErr = False Then
Me._Result_ThisForm = Result_Form.Goto_Next ' Just an additional info Enum
Me.Close()
End If
MsgBox("This should not pop up if bErr = false")
-> The "Exit Setup?" MsgBox pops up correctly but the user presses "ok" to exit the programm, the MessageBox from after the "Me.Close()" suddenly appers an then the program closes.
What causes this behavior?
Thank you for your help!

Related

Have to Click Form To Give Focus

I have a main form with buttons that open a custom message box form. It works fine if it's just a message and the user just needs to click OK. But if the answer to that message box is important, like "Are you sure you want to delete this file?" I use a while loop to wait for the user to respond and once they do then a flag is set from false to true and the response is recorded.
For some reason any response that uses a while loop to wait is causing the message box form to not have focus after being called. Requiring the user to first click on the form, and then click on OK.
So far I've tried using form.Activate() instead of form.Show(), as well as calling Application.DoEvents() inside the while loop since I believed the while loop was taking focus away from the message form immediately after being called. Neither solved the issue.
Code from a message box that works as intended:
If cmbLoadProgram.SelectedItem = "" Then
frmMessageBox.lblHeader.Text = "Set-Up"
frmMessageBox.lblMessageText.Text = "No Program Selected!"
frmMessageBox.Show()
Exit Sub
End If
Code from a message box that needs to be clicked twice:
If btnGetHexStart.Visible = False And cmbStartCondition.SelectedItem = "Pixel" Then
frmMessageBox.lblHeader.Text = "Hex Set-Up"
frmMessageBox.lblMessageText.Text = "Reset Hex Code Data?"
frmMessageBox.Show()
Me.Hide()
While Flag = False
If frmMain.OKCancel = "OK" Then
btnGetHexStart.Visible = True
btnGetHexStart.Enabled = True
btnGetHexStart.PerformClick()
Flag = True
End If
frmMain.delay(20)
End While
End If
I'm wanting both options to only need to be clicked once in order to confirm or cancel the action. Instead of the while loop questions needing to be clicked twice.
This just an idea from me, just how to open msgboxform, here we need MessageForm and one module1, for example:
Public Class MessageForm
'You can assign any variable to show any data in messageform display
Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click
theResult = MsgBoxResult.Ok
Me.Close()
Me.Dispose()
End Sub
Private Sub bttcancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bttcancel.Click
theResult = MsgBoxResult.Cancel
Me.Close()
Me.Dispose()
End Sub
End Class
Module Module1
Public theResult As MsgBoxResult
'You can add some parameter here to submit to MessageForm
Public Function myMessageBox() As MsgBoxResult
myMessageBox = MsgBoxResult.Cancel
MessageForm.ShowDialog()
myMessageBox = theResult
End Function
End Module
and then you can call the myMessageBox anywhere like this:
'if myMessageBox procedure have parameter, apply the paramters too
dim myRslt = myMessageBox()
You don't need to create a form,You can use DialogResult and MessageBox.Show, code:
Dim Result As DialogResult = MessageBox.Show("Set-Up" & vbCrLf & "No Program Selected!", "Warning", MessageBoxButtons.OKCancel)
If Result = DialogResult.OK Then
ElseIf Result = DialogResult.Cancel Then
End If

InputSimulator works while debugging but not when program is built

In my project im using inputsimulator and it works great when visual studio is ran as an administrator, but when i build it into a .exe it doesn't work even when i run it as administrator. here's my code
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
AutoSaveTimer.Enabled = True
Try
System.Threading.Thread.Sleep(50)
GameConnection.SendKeyTo(Keys.OemSemicolon)
System.Threading.Thread.Sleep(2000)
GameConnection.SendKeyTo(Keys.K)
System.Threading.Thread.Sleep(50)
GameConnection.SendKeyTo(Keys.Enter)
Catch AutoSaveExeption As GameException
If AutoSaveExeption.GameErrorCode = GameError.GAME_ERR_SENDMSG Then
' Send message error - connection to Game lost.
'
MessageBox.Show("cant make a connection.... can't autosave sadly", AppTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
SimConnectionBar.BackColor = Color.Red
End If
End Try
End Sub
it does send focus to the window i specify but it doesn't send the keystrokes
Try using SetForegroundWindow before sending any input to ensure your game does in fact have focus.The call to SetForegroundWindow should be made in your method just before sending the input.
<DllImport("user32.dll")> _
Public Shared Function SetForegroundWindow(hWnd As IntPtr) As Boolean
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click `
AutoSaveTimer.Enabled = True
Try
'Find the handle to the game. This can do it by searching for the process.
Dim p As System.Diagnostics.Process() = System.Diagnostics.Process.GetProcessesByName("notepad")
'search for process notepad
If p.Length > 0 Then
'check if window was found
'bring notepad to foreground
SetForegroundWindow(p(0).MainWindowHandle)
End If
System.Threading.Thread.Sleep(50)
GameConnection.SendKeyTo(Keys.OemSemicolon)
System.Threading.Thread.Sleep(2000)
GameConnection.SendKeyTo(Keys.K)
System.Threading.Thread.Sleep(50)
GameConnection.SendKeyTo(Keys.Enter)
Catch AutoSaveExeption As GameException
If AutoSaveExeption.GameErrorCode = GameError.GAME_ERR_SENDMSG Then
' Send message error - connection to Game lost.
'
MessageBox.Show("cant make a connection.... can't autosave sadly", AppTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
SimConnectionBar.BackColor = Color.Red
End If
End Try
end sub

Log Out message box appear twice when click on logout button

So I would like to perform a confirmation before i close the application or logout the application by clicking the logout button or just click to close the application. If i directly close the application then the message box just appear once. However when i use the logout button then the message box appear twice.
So the coding is basically look like this:
Private Sub btnLogOut_Click(sender As Object, e As EventArgs) Handles btnLogOut.Click
If logOut() Then
Me.Dispose()
frmLogIn.Show()
End If
End Sub
Private Sub frmHome_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
If logOut() Then
Me.Dispose()
frmLogIn.Show()
Else
e.Cancel = True
End If
End Sub
Public Function logOut() As Boolean
Dim respond = MessageBox.Show("Are you sure you want to log out?", "Log Out", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
If respond = DialogResult.Yes Then
blnResult = True
Else
blnResult = False
End If
logOut = blnResult
End Function
So anyone could help?
In your logout button event click
If logOut() Then //first line
Me.Dispose()//second line
frmLogIn.Show()//third line
End If//fourth line
in your second line which is Me.Dispose, you disposing the form, in other term you CLOSING it. So that, Your form_close event will be trigger because you dispose your form. That's why the message box pop up twice.

What is the best way to detect all ways of closing a form?

I have a form that i close using End several times in my code. I want to do a command to save settings when I do this called VarsToIni() which takes some public variables and saves them in an INI file. I have tried putting it in the main window's FormClosing (which stays open throughout) and this only works when you close from pressing the X button not from my End statement.
Add a new Sub and replace calls to End with calls to your new Sub:
Sub EndMe()
VarsToIni()
Application.Exit()
End Sub
Edit:
As Dan points out, End() is a bad way to close the application, Application.Exit() is preferred.
Consider using Application.Exit() instead of End. This allows FormClosing to be called no matter what (and you can handle it based on how it is being closed).
Private Sub frmMain_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
Select Case e.CloseReason
Case CloseReason.ApplicationExitCall
' This is the result of Application.Exit()
e.Cancel = False
Case CloseReason.UserClosing
' This is the result of clicking the red X
Select Case MessageBox.Show("Are you sure you wish to exit?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
Case DialogResult.Yes
e.Cancel = False
Case DialogResult.No
e.Cancel = True
End Select
Case Else
e.Cancel = False
End Select
If Not e.Cancel Then
VarsToIni()
End If
End Sub
I am quite confused by your question, nonetheless:
This will close all your forms
For each x as Form in My.Application.OpenForms
'You can then put your VarsToIni() here
x.Close()
Next
Note: Add this to your import
Imports System.Windows.Forms

Application.Exit() and FormClosing event in Vb.net

I have a single windows form application that is running in system tray icon.If the user press X button of the windows form a messagebox is displayed with Yes and No ( Yes ->close the form---No->keep the form running in system tray icon).
I was thinking to prevent the scenario when the user open another instance of the application when there is already an instance running so i have used this code :
If Process.GetProcessesByName(Process.GetCurrentProcess.ProcessName).Length> 1 Then
MessageBox.Show("Another instance is running", "Error Window", MessageBoxButtons.OK,
MessageBoxIcon.Exclamation)
Application.Exit()
End If
The problem is that when i want to test this the message is displayed but after i press ok, a new messagebox appears (that one from Private Sub Form_FormClosing ).If i choose NO i will have to instance running!
I have read that Application.Exit fires the Form_FormClosing event.
Is there any possibility to cancel the triggering of the Form_FormClosing event,or am i doing something wrong?
'this is the formclosing procedure
Private Sub Form_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
Try
Dim response As MsgBoxResult
response = MsgBox("Are you sure you want to exit", CType(MsgBoxStyle.Question + MsgBoxStyle.YesNo, MsgBoxStyle), "Confirm")
'If the user press Yes the application wil close
'because the application remains in taskmanager after closing i decide to kill the current process
If response = MsgBoxResult.Yes Then
Process.GetCurrentProcess().Kill()
ElseIf response = MsgBoxResult.No Then
e.Cancel = True
Me.WindowState = FormWindowState.Minimized
Me.Hide()
NotifyIcon1.Visible = True
End If
PS: I am not a programmer so please don't be to harsh with me:)
You don't need to Kill the current process or use the End Statement. If you have to use these then there is something amiss with your application.
When you want to end your application use Me.Close. This will fire the FormClosing event:
Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
Select Case MessageBox.Show("Are you sure you want to exit?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
Case Windows.Forms.DialogResult.Yes
'nothing to do here the form is already closing
Case Windows.Forms.DialogResult.No
e.Cancel = True 'cancel the form closing event
'minimize to tray/hide etc here
End Select
End Sub
To stop more than one copy of your application from running use the option to Make Single Instance Application
In the situation where you are just starting your application and are testing for previous instances I have used the VB End Statement to terminate the application.
The End statement stops code execution abruptly, and does not invoke
the Dispose or Finalize method, or any other Visual Basic code. Object
references held by other programs are invalidated. If an End statement
is encountered within a Try or Catch block, control does not pass to
the corresponding Finally block.
If Process.GetProcessesByName(Process.GetCurrentProcess.ProcessName).Length> 1 Then
MessageBox.Show("Another instance is running", "Error Window", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End
End If
Private Sub main_master_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
If e.CloseReason = CloseReason.UserClosing Then
'Put you desired Code inside this!
Msgbox("Application Closing from Taskbar")
End If
End Sub
It will Close the exe from Taskbar or kill Process. If user Close the
Application from taskbar.
CloseReason.UserClosing
event will close the application if it is closed by User from
Taskber