Openform Closeable with procedure feature

Feature Request: I wish I had the option to open a window with the red close dot disabled, but I could still close the window with a program. The current closeable option for the openform statement prevents closing the window until the database is closed, even with a procedure. The same is true for the nobuttons option. Sometimes I want to force the user to use a close button, which has a procedure to run on closing the form, which can be by-passed if the user used the red dot.

Time for another hack. I made a form called MyForm with one button. I added this code to the button’s Procedure panel:

let TransferForm=exportform("", "MyForm")
setformoptions "","MyForm","DELETE",""
importform TransferForm

I then opened the form with the close button in the title bar disabled and then clicked the button on the form with the above code. The form was deleted but immediately recreated in the View menu ready for the next use. As you can see, we export the existing form to a variable and then delete the current form and immediately import the same form back again from that variable. Everything looks exactly the same as closing the form normally.

Thanks, Gary. I put your code into a custom statement so I can just replace any closewindow statement with my custom statement.

This closes the window? I’m a bit shocked at that. I would think that a crash would be more likely. I do NOT recommend this technique.

I am assuming that your concern involves the deleting of a form used in an unclosable window and not the importing and exporting of the binary archive of the form. This deletion can also be done manually while the form is open with or without a toolbar.

With the form set to “Closeable”,“no” (note that ‘closeable’ should be spelled ‘closable’) you can click on the “Remove” lightening bolt on the right or go to Graphics Mode and do the same thing and the form and window will be removed. Without a toolbar you can still choose Go to Graphics Mode from the Window menu. Seems that if deleting an unclosable form window is problematic that there are easy ways to fall into this trap by accident.

With a lot of experimenting on this I have not had a crash but maybe I’m just lucky. :game_die:

My concern is deleting a form while it is open.

However, I have now looked at the source code, and it appears that perhaps this is acceptable. The setformoptions code that deletes a form does check to see if the form is open, and closes the window. So it was actually designed to do this, more or less.

Since the code is more-or-less already written, I should go ahead and make a statement that does this, without the need for the delete/restore trick.

I think the problem here is that the closewindow statement essentially closes the window by sort of “virtually” clicking the close box, and since there is no close box, that doesn’t work.

I have used Gary’s code many times now and once I had a problem: the code deleted but did not re-create the form. Yikes. I had to open an older version of the db to retrieve a copy.
I had another idea, but it would require some changes from Jim: add another option to the setwindowoptions statement to allow setting whether the window is closable. If it were, there would not be a need to delete the form and add it back, but just change the change the option setting and then use closewindow.

change:

let TransferForm=exportform("", "MyForm")

to:

letpermanent TransferForm=exportform("", "MyForm")

That way if the form is ever missing you only need to run the importform TransferForm code. Should the file be later saved with the form missing, the form’s binary value will still be in the permanent variable. If the file is not saved, the form should not be removed.

There are other safe guards that could be taken including running a timer that checks for the existence of the form and imports it from the permanent variable if missing. Regardless, this is still a hack of sorts and only meant to help until something else becomes available.

Thanks. Good idea. I will do that.

The problem is that the closewindow statement normally works by triggering the same code that is triggered by clicking on the red circle button. This is Apple’s approved method for closing a window, doing it this way makes sure that everything associated with the window is cleaned up properly, including closing the database if it is the last visible window in the database. The only problem is that Apple’s approved method doesn’t do anything if there is no red circle button. As far as I can see Apple didn’t really anticipate that a document window would have no close box.

However, probably you don’t want the database to close in this situation. So it turns out that Panorama X 10.2 already has a new statement for this situation – closeclonewindow. I forgot about this but it turned up in my research as I was about to write a new statement. To use this you must enable the “clone” option when opening the form window, but I think that’s probably a good idea in this situation anyway. Fortunately this suggestion will be immediately useful to everyone that has posted on this thread :wink:

As an alternative approach allowing the programer to intercept a user closing a window, would it be possible to add to PanX an additional form event - ‘formCLOSE’?

I think that is exactly what I was hoping for. Thanks for pointing that out.

Unfortunately as far as I can tell Apple has not provided a hook where this can be done, and a couple of years ago I spent quite a bit of time pouring over the documentation looking for this. However, this isn’t what Tom is looking for – what he needs is a way to make the window close, not a way to find out that it is closing. There are of course applications where it would be great to be able to intercept the close, but the Cocoa API’s simply don’t support this option.

May I suggest an addition to the openform documentation along these lines?

As setting titlebar or nobuttons options removes the window close button, the form cannot be closed manually, or procedurally with closewindow. However if the clone option is set, the window can be closed procedurally with closeclonewindow.

I have added a custom statement, which I call closeanywindow, which first tries to close a window using ‘closewindow’. If the window is still open after that, then it tries closeclonewindow. So I can use the statement for regular windows and clone windows. That gives me the capability to open a clone which cannot be closed with the red dot, and force the user to use my close button, where I can include other code to do whatever. For me, this has turned out to be a perfectly good solution.