Then use a sheet window
In a CancelClose event, you can close all the other windows, so each show a sheet window (not blocking the UI).
Drawback: this won’t work with Windows or Linux…
Or, do it otherwise:
In the first occurring CancelClose event, show the “Would you like to save changes for this window?” dialog. Wait for the user to answer.
In a property of the window (e.g. UserAnswer As MessageDialogButton), store the answer of the dialog, close the next window and return true.
The second window then shows the same message box (and so on for all windows).
Once all windows have asked to save changes (you know that by checking if UserAnswer is nil or not), close again each window (now, every window knows the user’s choice and can save or not).
A slightly different method, common on Mac, would be to first show a global message: “Do you want to save changes to all windows before closing?” with buttons {“Save all”, “Review one by one” and “Cancel”}.
“Review one by one” would then ask for each window; the user may choose “Save all” only once to be not bothered by many dialogs.
@Arnaud_N I am using a sheet window to ask about closing. However, Xojo only performs one CancelClose at a time. It doesn’t move on to the next one until the first returns, that way it can check for a user Cancel not do the rest of the Windows.
I’ve taken your idea and worked up something that works very well.
The following in the App.CancelClose method. I’ve created my own AskCancelClose method which asks the standard Don’t save, Cancel, Save message. It checks that they didn’t respond with a Cancel before looping around to the next form. Each window remembers the response provided and if Close is called uses it as the response to the true CancelClose event.
Function CancelClose() Handles CancelClose as Boolean
Var nWindow As Integer
Var nWindows As Integer = App.WindowCount
Var aWindows() As CSW
Var NoneChanged As Boolean = True
For nWindow = 0 To nWindows - 1
If App.Window( nWindow ) IsA CSW Then
aWindows.Add CSW( App.Window( nWindow ) )
If App.Window( nWindow ).Changed Then
NoneChanged = False
End If
End If
Next
' If none of the windows needed saving or there where no CSW windows open
If NoneChanged Or aWindows.LastIndex = -1 Then
' Then just let the application Quit In the normal way
Return False
Else
' Now ask each window what it wants to do about closing. If any return cancel cancel out of the CancelClose event without action
For nWindow = 0 To aWindows.LastIndex
aWindows( nWindow ).AskCancelClose
If aWindows( nWindow ).AskCancelCloseResponse = CloseCancelDialog.Cancel Then
'
' Clear all the windows we've done so far, so they actually ask when the window is next closed
'
For nWin As Integer = 0 To nWindow
aWindows( nWindow ).AskCancelCloseResponse = -1
Next
Return True
End If
Next
Return False
End If
End Function
The true Window.CancelClose event as follows:
#Pragma Unused appQuitting
If Changed Then
If AskCancelCloseResponse = -1 Then
Var oDialog As New CloseCancelDialog
Select Case oDialog.ShowModalWithin( Self )
Case CloseCancelDialog.Cancel
' They pressed Cancel on the Closing dirty window dialog
Return True
Case CloseCancelDialog.Save
' They pressed save on the Closeing dirty window dialog
If SaveTable( False, True, True ) Then
Return False
Else
' They pressed the cancel button on the SaveAs Dialog so we're done with Quitting
Return True
End If
Case CloseCancelDialog.DontSave
' They pressed don't save, continue to close and quit if that's whats happening
Return False
End Select
Else
If AskCancelCloseResponse = CloseCancelDialog.Save Then
' They pressed save on the Closeing dirty window dialog
If SaveTable( False, True, True ) Then
Return False
Else
Return True
End If
Else
Return False
End If
End If
Else
Return False
End If
AskCancelClose method:
If Changed Then
Var oDialog As New CloseCancelDialog
AskCancelCloseResponse = oDialog.ShowModalWithin( Self )
Else
AskCancelCloseResponse = CloseCancelDialog.DontSave
End If
with AskCancelCloseResponse being a property of the window.
All the windows ask right away, one by one. The App.CancelClose then returns False in the standard way closing all the windows, responding without asking from th prior answers.