End_Dialog and End_Window, a Cautionary Tale
Belated Happy New Year to everyone. Project demands for SRP ramped up significantly at the end of 2013 and has carried over to 2014, which is why we are late in contributing to our blog as well as getting our next newsletter out. There are some very interesting product updates that we are excited about. Therefore, we hope to refocus on our publications shortly.
In the meantime, we wanted to share a quick reminder about the potentially unwanted, or unexpected, behavior of the End_Window and End_Dialog system stored procedures. We ran into this during a recent project wherein we have been retrofitting a 15-year old OpenInsight application with the latest version of SRP FrameWorks. One of our standard features is to add the caption of an MDI Child form to a clickable list of names (aka Open Windows) along the left side our our MDI Frame:
The purpose of this list is to help end users remember which forms are already running and to give them an easy way to bring forward the form they wish to work on. Naturally, we automate all of this through promoted event handlers, specifically CREATE (to add the caption to the list) and CLOSE (to remove the caption from the list.)
During our recent upgrade project, we began to notice that several of captions remained in the list of Open Windows despite the fact that we dismissed the forms. It didn’t take long to realize that it made a difference in the way we dismissed the forms. Specifically, if we used the form’s system menu close button then everything worked as expected. The problem only occurred when we clicked on the form’s push button which was intended to close the form. Further investigation led to the discovery that the CLICK event handler for these buttons used the End_Window function.
End_Window is a perfectly acceptable way to close a form. It even provides a convenient argument to direct focus to another form and control after the form is closed. So why would this have an impact on our Open Window list management? The simple explanation is that End_Window (and End_Dialog) do not close forms using the CLOSE event handler chain. Rather, they utilize the DESTROY service. Consequently, any CLOSE event handlers (including scripts) are bypassed, thus ignoring any form specific or application wide logic that is required when closing the form.
Of course, the developer might actually want to bypass the CLOSE event handler. Barring that, the natural question is, “How do I resolve this?” That will depend on the nature of the application and each form. End_Window itself can generally be replaced with a Post_Event call:
End_Dialog, however, is the recommended method to close a form launched with the Dialog_Box or Create_Dialog functions. In these situations it might be best to directly call any logic that would otherwise be handled by the CLOSE event handler. This, of course, makes a strong argument for writing code that is modular and loosely tied to any specific event handler. As in our situation, the logic that maintains the Open Windows list is stored within a callable routine rather than directly embedded in our respective promoted CREATE and CLOSE event handlers. We can call this routine at will whenever the situation requires it.