Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

_Screen 'X' button does not change immediately after Modal form is opened or closed.

Status
Not open for further replies.

steve4king

IS-IT--Management
Feb 6, 2007
154
US
I see this issue all over this forum, but no definitive solutions.
Hoping someone has learned something since then, or clues from my scenario will aid in finding a better solution.

This is an old app I'm working with, but currently building with VFP9 sp1.
I launch a small procedure from a _screen menu bar item which does nothing but call a form using "do form &name".

The form is Modal, has nothing custom in the activate, or show methods. Also, nothing stands out in Init or Load. Yet it does not immediately disable _screen's close button as a modal child form should. Switching to another application and back or minimizing then maximizing _screen disables it. After the click method in this form, _screen's close button changes to disabled. But when the form closes.. it remains disabled. (Until switching apps, min>maximizing, or displaying a messagebox from _screen)

_Screen.closable is .T. and _screen.lockscreen is .F.

This appears to be a refresh issue, though neither _screen.refresh nor DOEVENTS work to update it.
Is there a setting that would affect _Screen's titlebar refresh or is there a different command that will work?
(I moved a messagebox from the unload of my form to the calling procedure as a quick fix)

-Stephen
 
I'm not sure what a messagebox has to do with any of this.

But let me pose a philosophical question to you: why should a modal form make the _Screen not closeable? (I actually consider it a bug that leaving the app and coming back does so.)

There are several flavors of modal: form, application, and system.

A modal form should affect the form, not the application or the system, no?
 
Stephen,

You say:

Yet it does not immediately disable _screen's close button as a modal child form should.

That's where you are going wrong. There is nothing in the native behaviour of a modal form that says it should disable the Close button. I agree that it is highly desirable to disable that button, but VFP doesn't do that for you. You have to take steps to make it happen.

The usual approach is to set _SCREEN.Closable to .F. in the form's Activate, and to set it to .T. in the Destroy. That will give the desired behaviour, including cases where a child form is called from a parent modal form. If you put that code in your base modal form class (which is recommended), be sure not to override it in sub-classes and instances.

Mike





__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
I try to reproduce.

1. started VFP.
=> command window is active and it's close button is red, _screen close button is title bar colored, but enabled.
2. in command window I did
Code:
o = createobject("form")
o.Show(1)
=> form got the red, enabled close button, _screen instantly changed it's close button to disabled.
3. closing the modal form
=> _screen's close button immediatle does change to enabled, but the command window close button gets red, of course, not the _Screen close button.

This also does not change when useing a modal form and DO FORM.

I'll test further, because either the menu or the runtime situation without a command window should change the behaviour, of course. But so far I don't see a problem.

Maybe your modal form does not fully release, because of any reference on it.

In the end, even if I can finally reproduce something, a modal form is something to prevent in the first place. A good application design does not need modal forms and thereby never has any locking situation. I agree with Dan in that philosophical perspective. And if you overcome this, there is no need for a fix.

So far what helps but causes a visual hickup is _screen.WindowState=0 followed by _Screen.WindowState=2, but if your command window is open, this even makes both _screen and command window have red, enabled close buttons.

There may be a flow in there, but I'd rather address windows, the title bar and border of all VFP forms including _screen is Winforms, VFP only superimposes another class/object structure, but it's drawing is OS specific, only the innner canvas is 100% pure VFP, unless you use ActiveX controls.

Finally, you know there are some Aero flaws with forms and the drawing of their borders, which only are fixed with VFP9 SP2. Only the final version is the one best suited for Vista or later Windows versions.

Bye, Olaf.
 
Now I also did a small EXE version

1. Created a pjx
2. Created a simple modal form modalform.scx, nothing on it, only changed WindowType to modal.
3. With the menu designer created a quick menu (which includes many sysmenu items).
4. In the \<Window Submenu added a menu item with a procedure, with nothing more than DO FORM MODALFORM.SCX in it.
5. In the \<File Menu changed the E\<xit menu item from Bar# to command and put CLEAR EVENTS as the command.
6. created a main.prg with no more than the two lines DO MENU1.MPR and READ EVENTS. Built an exe from this project. (The build process uses _genmenu to compile the menu1.mnx to the menu1.mpr I call in main.prg)

Running the exe starting the modal form from the Windows menu, The _screen close button immediately get's disabled and closing the modal form, the _screen close button also immediately is back enabled.

So maybe this is a difference between SP1 and SP2, but you may follow my steps to create a similar EXE and try if that also works as wanted in VFP9 SP1.

Bye, Olaf.


 
Just tried Olaf's test (in VFP 9.0 SP1). The behaviour seems to be different in the development environment, compared to running from an executable.

In development, it's like I said: the Close button doesn't automatically get disabled. But running from an EXE, the button does get disabled, as Olaf's test showed.

I did this test very quickly, so it might not exactly reproduce Stephen's behaviour.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Sorry, I didn't catch my typo. I'm building from vfp9sp2, not sp1.

Dan, I actually wouldn't mind that the modal form didn't disable the _screen's close button. I check for any open forms before allowing that close button to do anything anyway. The problem is that during the click routine (which opens child forms, and displays a messagebox) The close button does get disabled.. then when the top level form closes it doesn't re-enable in _Screen.

Leaving the app and returning just refreshes the form, setting the close button to the correct state. It doesn't disable _screen's close button unless there is a modal child form. Conversely, leaving/returning enables the close button if it should be enabled.(eg. Modal form open, messagebox opens closes which disables the close button, modal form closes) So, as I see it, the bug isn't that leaving/returning does something.. but that the something should have changed before leaving/returning. _screen didn't have a visible change when it should have.

What the messagebox does, is refresh _screen. When a messagebox is opened and closed, _screen is updated. Just like leaving/returning or _screen.WindowState=0 followed by _Screen.WindowState=2 as Olaf suggested. When Messagebox is called, it immediately disables screen's close button. When the messagebox is destroyed, _screen's close button status is updated. It stays disabled if I have another modal form, it enables if I do not.

Mike, Your best practice suggestion was actually the best solution! Setting closable=.T. on destroy didn't work until I also set closable=.F. on load. Apparently setting closable=.T. doesn't trigger a refresh if it is already closable.

-Stephen
 
As said I don't see the _Screen Close button staying disabled, from my test.exe it get's both disabled when the modal form runs and is reenabled, when the modal form Closes.

There has to be something else in your code making the Screen not refresh.

Bye, Olaf.
 
Mike, Your best practice suggestion was actually the best solution! Setting closable=.T. on destroy didn't work until I also set closable=.F. on load. Apparently setting closable=.T. doesn't trigger a refresh if it is already closable.

No, you don't want to set to .F. in the Load. You need to do that in the Activate.

The reason is simple. If the modal form (call it Form A) calls a second modal form (Form B), then when Form B closes, its Destroy will fire, and this will set Closable to .T. So far, so good. But Form A then becomes active again. At this point, Closable is still .T., which is not what you want.

If you put your _SCREEN.Closable = .F. in the Activate rather than the Load, then that solves the problem. When Form B closes, Form A's Activate will fire, and the button will remain disabled. When Form A eventually closes, its own Destroy will fire, setting Closable to .T. again.

I didn't catch my typo. I'm building from vfp9sp2, not sp1.

That makes no difference at all. There is nothing here that has changed between SP1 and SP2.

Mike



__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Olaf said:
There has to be something else in your code making the Screen not refresh.
Exactly. But I'm not sure what that might be.

Mike, thanks. I had actually put it in activate rather than load, but hadn't really thought through the reason for it. Makes perfect sense, thank you!


-Stephen
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top