Dear all,
Usually end users can close a FORM either by ...
1. Clicking on the close button(cross icon) on the system menu
2. Using the keyboard short cut ALT-F4
=> For these both cases the WM_CLOSE notification is raised
3. Clicking on a specific "Close" button (if there is one) on the form
In this case the function FORM1_CLOSE_BN_CLICKED is used to manage the close event.
In many cases the source codes are usually the same for the WM_CLOSE function and the CLOSE_BN_CLICKED function; so to avoid duplicating the source code I simulate a click on the "Close" button inside the WM_CLOSE notification function :
'--------------------------------------------------------------------------------
Function FORM1_WM_CLOSE ( _
hWndForm As Dword _ ' handle of Form
) As Long
' simulate a click on the Close button
SendMessage hWndForm, %WM_COMMAND, MakLng(IDC_FORM1_CLOSE,%BN_CLICKED), HWND_FORM1_CLOSE
' to cancel the WM_CLOSE notification
Function = -1
End Function
And then write the code to close (or not) the FORM inside the FORM1_CLOSE_BN_CLICKED function:
'--------------------------------------------------------------------------------
Function FORM1_CLOSE_BN_CLICKED ( _
ControlIndex As Long, _ ' index in Control Array
hWndForm As Dword, _ ' handle of Form
hWndControl As Dword, _ ' handle of Control
idButtonControl As Long _ ' identifier of button
) As Long
Local lResult As Long
' to ask for a confirmation
lResult = MessageBox(hWndForm, "Leave the form ?" & $CrLf, "Close Form", %MB_YESNO Or %MB_DEFBUTTON2 Or %MB_ICONQUESTION Or %MB_APPLMODAL)
' if the user decides to stay on the form
If lResult = %IDNO Then Exit Function
' close the current form
FF_CloseForm (hWndForm)
End Function
I would like to know if it is a good practice (or not) to do that ? Is-there any other way to achieve the same thing ? I don't remember if this subject was already discussed in the past in the FF forum.
PS: In this sample project, there are not a lot of common source codes; but in a real project, we have to check fields, to update databases, etc ...
Thanks.
Jean-Pierre
Jean-Pierre,
I would do it the other way around because it seems simpler to me:
Function FORM1_WM_CLOSE ( _
hWndForm As Dword _ ' handle of Form
) As Long
Local i As Long
i = MsgBox("Close this form?", %MB_YESNO Or %MB_DEFBUTTON2 Or %MB_TASKMODAL Or %MB_ICONQUESTION, "????")
If i = %IDNO Then
'Don't close this form
Function = 1
Else
'Close this form
Function = 0
End If
End Function
A Close/Exit button must generate a WM_CLOSE message (see the below code) because FF_CloseForm() does not send a WM_CLOSE message to the form (only a WM_DESTROY):
Function FORM1_CMDCLOSEFORM_BN_CLICKED ( _
ControlIndex As Long, _ ' index in Control Array
hWndForm As Dword, _ ' handle of Form
hWndControl As Dword, _ ' handle of Control
idButtonControl As Long _ ' identifier of button
) As Long
'FF_CloseForm hWndForm, %TRUE 'But FF_CloseForm does not send a WM_CLOSE message to the form (only a WM_DESTROY),
SendMessage hWndForm, %WM_CLOSE, 0, 0
End Function
Kind regards
Eddy
Jean-pierre,
I would create a function that contains the common code and just call it from each of the two FF functions you mentioned.
But, I don't see anything wrong with the way you or Eddy are doing it. There's more than one way to skin a cat (kind of a morbid old saying).
David
Jean-Pierre,
An improvement to my original post:
Probably FF likes it better when FF_CloseForm is called:
Function FORM1_WM_CLOSE ( _
hWndForm As Dword _ ' handle of Form
) As Long
Local i As Long
i = MsgBox("Close this form?", %MB_YESNO Or %MB_DEFBUTTON2 Or %MB_TASKMODAL Or %MB_ICONQUESTION, "????")
If i = %IDYES Then
'Close this form
FF_CloseForm hWndForm, %TRUE
End If
Function = 1
End Function
Eddy, Kenny,
Thanks I appreciate your answers.
Eddy,
Yes you're right it is clearly more elegant and simpler to do it the other way around.
NB: Regarding the call to the FF_CloseForm function inside the WM_CLOSE handler function I don't know if it is mandatory, optionnal, recommanded or useless; I think that Paul can help us here on this question.
Regards,
Jean-Pierre
Quote from: Jean-pierre Leroy on January 06, 2014, 07:51:14 AM
Regarding the call to the FF_CloseForm function inside the WM_CLOSE handler function I don't know if it is mandatory, optionnal, recommanded or useless; I think that Paul can help us here on this question.
The use of FF_CloseForm is probably 'highly recommended' in most cases because it does some cleaning up for us.
Here's what it (currently) does:
Sub FF_CloseForm( ByVal hwndForm As Dword, _
Optional ByVal ReturnValue As Long )
If IsWindow( hWndForm ) = %FALSE Then Exit Sub
Local hWndParent As DWord
Local ff As FLY_DATA Ptr
ff = GetProp(hwndForm, "FLY_PTR")
If ff Then
If @ff.IsModal Then
' Reset the focus back to the parent of the modal form.
' Enable Mouse and keyboard input for the Parent Form
hWndParent = GetWindowLong( hWndForm, %GWL_HWNDPARENT )
If IsWindow(hWndParent) then
EnableWindow hWndParent, %TRUE
SetActiveWindow hWndParent
End If
End If
End If
'Destroy the window. This will delete any font objects and release
'the memory held by the type structure.
DestroyWindow hWndForm
'Set the value that will be returned to the calling program.
App.ReturnValue = ReturnValue
End Sub