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 TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Mulitple Forms acting independently of each other

Status
Not open for further replies.

Theresajn

IS-IT--Management
Jan 12, 2021
6
US
I am not sure if this can be done and was hoping someone could point me in the right direction. I am using VFP 9 with service pack 2.

I have a program with a toolbar at the top where users can go through a menu and choose what form they need. The form opens, they edit or add a record, then close the form so they can open a different form and so on.

2023-10-13_14_05_10-PicSmart_v1.1.476_Current_User__Theresa_Niemet_-_Developer_pkaoqf.png


I want to be able to have another option in the menu for a To-Do list, a form that could be open all the time if needed regardless of other forms being open. I want it to work independently from any other form. At the moment, the to-do list form opens up but if I open another form, I can't access the to-do list. How could I accomplish a form to be open and act independently of any other form but still access if other forms are open? My forms are modal but I made the to-do list form a modeless form.

I have tried searching for some help on this but I really can't find anything or I am using the wrong search term.

Any help would be appreciated.
 
Well, to use forms in parallel, they all need to be non-modal. Since all your old forms are modal, they restrict access to any other form, no matter if other forms are modal or not. In other words, you step onto your own feet. NOw you made the first form, which is "cooperative" - the to-do list form - but that's not making all forms cooperate, every form that is modal is hindering to use other forms in parallel.

So the solution to an application with multiple form usage is making all forms non-modal, i.e. cooperative for parallel usage. Is there any reason you made all forms modal? In an application that is as complex as having many forms, it seems very useful to open up multiple forms at the same time, even before you introduce a form you absolutely want to be usable in parallel to everything else. It's a bad design to work with modal forms all the time, modality should only be used for a short period where the focus has to be on that one modal form.

Chriss
 
Thank you Chriss. I will have to change my plan now.
 
It shouldn't be too difficult. One reason you might have your forms made to use one after the other is no need for that parallelism of usage. Fine, but now simply set all forms to use private datasessions and be on modal and you should be fine. That's not much to do. Not what I'd call "change plans", you just fix an architectural flaw and get over with it.

Chriss
 
Yes, making the forms non-modal will fix this. However, it will introduce a new issue.

If a user picks a form, and then picks that same form again while the first form is still open, you will get two instances of the form. That might be what you want. For example, you might want to allow the user to work on two different orders at the same time.

But if that's not what you want, you will need to write code to explicitly deal with that situation. Your code will need to test to see if the form is already open, and, if it is, to bring that form to the front rather than opening it again.

To check to see if the form is already open, you can use _SCREEN.Forms, which contains an array of all the open forms. Each entry in the array is a Form object, so you can check its name, caption, etc. and call its Show method to activate it.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mike, that's a valid point, but once you set the data session of all forms private (with exceptions where you definitely want a popup form to work in the same data session) this should become no problem. I'd make it the decision of a user whether a second instance of the same form is useful to him or not.

If you have reasons to control this, I'd take into account the current application architecture to start forms from a menu. It's possible to define the menu item with a SKIP FOR clause that uses a function or expression to control whether to start the form there is enabled or disabled. The expression just needs to return whether the form already is started yet, which will disable the item once the form is started and also automatically reactivates the menu item, when the form is closed again.

This function/expression should have a way to determine that, which can be done as Mike suggests using the _Screen.Forms collection and finding the one form of interest in there, or you make form starts a matter of a form handler that maintains the knowledge whether a form is already started or not.

In the simplest case, you already have a form handler. If not, the simplest form handler is a passive one, just a collection added to goApp or _screen. Like [tt]_screen.addobject('colForms','Collection')[/tt] in main.prg and in the load or init of a form just needs to do _screen.colFoms.add(This,'formname')

The menu item to start the form will need the [tt]SKIP FOR[/tt] clause to be [tt]_screen.colForms.getKey('formname')>0[/tt] and that's disabling those menu items as long as the form is in the collection. You don't need any code in the unload/destroy/release of the form, as a form released will automatically be removed from the collection.

You only need to define the menu item SKIP FOR and the form load or init code line for the forms you don't want to allow multiple instances of. Other forms don't need to be in the collection and don't need a code modification.

In comparison, if not using your own forms collection, to find out whether a specific scx is within _Screen.forms you need a loop and check all form objects name or scx file names, so that's not doable in a simple expression.

Chriss
 
Chris, I have over 250 forms that I would have to change to non-modal. I am updating a program someone else created who is not around anymore so I am looking for the most efficient way to get this done.

I think I will just make a screen that the user could open any time they needed it but will have to close it before working on another form. This is not ideal but will have to work. I use SQL has a backend and not FoxPro tables. I have not worked with setting data sessions before so not sure that is the route I want to take. Also, I don't want the user to be able the same screen multiple times.

The forms work like this.

Top level menu item is Orders. If the user clicks on that menu item, they get a form with a list of orders. From that form, the user can click on an order and open it and edit it if need be. But, they can't open another order until they close the one they are working on. So they need to close the order they are working on and then they will be back at the form with the list of orders.
 
You have _vfp.projects.files to iterate through all project files and you can programmatically turn all forms to be non-modal.
Likewise, you can programatically add SKIP FOR clauses to menu items.

Anything can be programmed.

Chances are pretty high for some forms it makes sense to have them modal anyway, as said one such situation is if they are actually popup forms that are started from a form and not from the menu, such forms then usually provide something that has to do with a current item of a main form or even returns a result to the calling form. So you'd need to find out those forms that actually don't need to be modal by finding out which of them are in menu items that DO FORM.

You can programmatically list all the menu items that start a form and get a list from there, no matter if you have a menu table or the menu code generated by genmenu, because in the first case you can scan the menu table, in the second you can read in the mpr program code and find the menu items starting forms.

It's okay, if you decide against such a plan, it takes a bit of experimenting before you get there. If you would want to go that route, it's advisable to first make a copy of the whole project.

Another doable solution would be making that todo list a form that is displayed by a parallel running EXE, so it's a window of another process, to and from which you can switch. It just becomes harder if picking something from the todo list should start a corresponding form/item in the process of the main application but you can use thing like interprocess communication, a DBF with some meta data to be processed by a timer in the main process, DDE commands, just to give 3 possible ideas.

Chriss
 
You say you would have to change 250 forms to non-modal. I suspect I already know the answer to my next question: Are all the forms based on a single base class (or, at least, a small number of different base classes)? If so, you would only need to change those classes to non-modal, and the individual forms would then automatically inherit that property.

If that's not an option, you might want to look at Rick Schummer's HackCX product ( which might well do the job for you. The professional version is definitely worth having, but there is also a free version, albeit with fewer features.

That said, if you do manage to convert the forms to modeless, keep in mind what I said above about having multiple copies open at the same time.

I can understand why you would prefer to stay with your existing modal architecture. This was the usual way that applications worked back in the days of Foxbase and Clipper and MS-DOS, and many developers from that era never made the transition to the more modern event-driven environment. But it's a terrible system from the user's point of view. (Just imagine you are browsing a website, and you need to look up something on another site, and the only way to do that was to come out of the first site, navigate to the second, then close the second and navigate back to the first. That is what a modal system does.)

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top