Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Visual FoxPro 9 formset question

Posted on 2009-12-22
10
Medium Priority
?
3,134 Views
Last Modified: 2013-11-14
I have a VFP 9 application that utilizes a form set consisting of only two forms.  The main form (form1) loads data into a grid on the form based upon an SQL query from data entered into a text box either by the user or a barcode scanner.  The second form (form2) is hidden during the initial load of form1.

If the end user determines the data in the grid needs to be edited I have a command button that will make form2 visible and show form2. The second form queries and inventory master and displays the results of a cursor into a combo box. During testing of the application within VFP everything works perfectly.

However I now am ready to distribute the application via a setup program using InstallSheild.  During the init method of form1 I have the following command: application.visible = .f. to turn off the main Visual Fox Pro window.  I have the form1.showwindow property set to a top level form and form2.showwindow property set to: in top level form, I also have form2.alwaysontop property set to .T.  My problem is if I distribute the application and call form2 from form1 it is not visible...I do not get an error, I just can't see form2.  However if modify form1.init event and set application.visible = .t. when I call form2 it loads but it loads behind form1 into my task bar and I have to click on the task bar to bring the form to the forefront.

My goal is to obviously set application.visible = .f. and be able to load form2 into the top level form1.  What I am missing?  Any help would be greatly appreciated.
0
Comment
Question by:Patmac951
  • 5
  • 4
10 Comments
 
LVL 14

Expert Comment

by:tusharkanvinde
ID: 26110609
Maybe you need _screen.visible=.f. instead

I have never used formsets. They are also not recommended. You could try setting AlwaysOnTop for form2 to .T.
0
 
LVL 43

Expert Comment

by:pcelba
ID: 26111598
Forms in a formset are moreless independent and they cannot be displayed one inside the other.

If you want ShowWindow to work as you need then you need one Main form having ShowWindow property set to "As top level form" and all other forms which should be displayed inside this Main form must be initialized from this Main form by DO FORM command or created by CREATEOBJECT(). These "child" forms must have ShowWindow property set to "In top level form" and they don't need to be On top. If you would like to move these child forms outside the Main form, set its Desktop property to .T.

I am just not sure if it is possible to remove some form from the formset without its deletion. Probably not... So, you have to create a new form outside the formset, copy all controls and code from the form created in formset and then you may remove the form from formset...

BTW, I am also not using application.visible  but _screen.visible.
0
 
LVL 43

Expert Comment

by:pcelba
ID: 26113686
I have to correct myself: Forms in a formset CAN be displayed one inside the other but I did not find a way how to do it in design mode... But it should be possible because it is allowed in run-time.

So, if you really need a formset having one Top level form and the second form In Top level form, create the second form by Formset's AddObject method:

THISFORMSET.AddObject('newForm','FormInTopLevelForm')
THISFORMSET.NewForm.Visible = .T.

The class FormInTopLevelForm is your second form having ShowWindow property set to "In top level form".

The question is: Do you really need Formset? Sometimes it would be useful to have some container for app forms but I don't think it is necessary in many cases.
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 11

Author Comment

by:Patmac951
ID: 26114120
pcelba,

Thanks for the response.  The reason I created a formset was because form2 in my scenario stores a value selected from a combo box to a variable when a command buttoned has been clicked.  Also within the command button of form2 I have the following code
thisformset.form1.command7.setfocus( )
thisformset.form1.command7.click
These commands allow me to update the grid on form1 using a cursor in the command7.click event with the value of the variable from form2.
I initially tried not using a formset but having 2 separate forms and in the command button of form2 I tried this code
form1.command7.setfocus( )
form1.command7.click
however when using separate forms...when I attempt to click the command button in question on form 2 it says "Object Form1 not found"  ?? The forms are in the same project and in the same folder.  The init event in form1 has a set default to 'c:\projectfolder'

Is there a way to accomplish this using separate forms or since I already have everthing coded for a formset should I try the thisformset.addobject you mentioned above?
0
 
LVL 43

Accepted Solution

by:
pcelba earned 2000 total points
ID: 26114563
If you use thisformset.addobject then you can leave the code in Form2 unchanged but you have to define separate class from it (means to remove Form2 from formset and save it as class).

If you need to access Form1 methods from "independent" Form2 then you cannot use the form name but you have to provide the form object reference of Form1 to Form2. You could find the Form1 object reference from _screen.forms or you can pass this reference as parameter:

If you will call Form2 from Form1 by
DO FORM Form2 WITH THISFORM
then the calling form reference is passed to Form2.Init method as a parameter and you may use this parameter value to access Form1 methods and properties. Remember the parameter is just variable having some scope - when the Init event code exits then this variable disappears so you have to store its value into some form property:

Form2.Init:
LPARAMETER loCallingForm
*-- Some Init code
*-- Store the calling object reference
THISFORM.CallingFormReference = loCallingForm  && CallingFormReference is property of Form2
*-- etc.
RETURN

When referencing Form1 use simple:
THISFORM.CallingFormReference.command7.setfocus( )
THISFORM.CallingFormReference.command7.click

This approach is valid but not so correct in OO environment. Form2 should not know about all Form1 controls and their properties. You should call just some public method from calling form and this method should do the work.

Same rules are valid if the form is in a formset. In such case you should call mehods from the formset only and formset should propagate such call to its child forms. The concept is "Object encapsulation" and you should communicate via some public interface only.

I know, programs must be delivered sometimes...
0
 
LVL 11

Author Comment

by:Patmac951
ID: 26116632
pcelba,

Sorry for the delay I have been out of the office.  I have removed the formset and now have two independent forms.  I am having no luck with _screen.forms to find the object reference for form1.  It allways tells me form not found.  What is the exact syntax of that command?  I must be missing something.
I would like to use your example:

DO FORM Form2 WITH THISFORM
Form2.Init:
LPARAMETER loCallingForm
*-- Some Init code
*-- Store the calling object reference
THISFORM.CallingFormReference = loCallingForm  && CallingFormReference is property of Form2
*-- etc.
RETURN

When referencing Form1 use simple:
THISFORM.CallingFormReference.command7.setfocus( )
THISFORM.CallingFormReference.command7.click

Thanks again for your help....you are definitely a FoxPro Guru

0
 
LVL 43

Expert Comment

by:pcelba
ID: 26116722
If you will call Form2 from Form1 by DO FORM Form2 WITH THISFORM command then you don't need to elaborate with _screen.Forms.

References to all instantiated forms are in the array
_screen.Forms[n]
number of forms is in
_screen.FormCount
The problematic part could be to find out the right form from above collection... So it is easier to use the parameter.

If you execute your code to display forms and then invoke debug command you may simply look at it.

Possible code to find the reference is here:
loFormRef = null

FOR lnI = 1 TO _screen.FormCount
  IF _screen.Forms[lnI].Name = 'Form1' AND _screen.Forms[lnI].Caption = "< Form title here >"
    loFormRef = _screen.Forms[lnI].
  ENDIF
NEXT

Open in new window

0
 
LVL 11

Author Comment

by:Patmac951
ID: 26116783
Ok that's what I would like to do just call form2 from form1 by using your recomendation:

DO FORM form2 WITH THISFORM

I thought I did exactly what you said
DO FORM Form2 WITH THISFORM
Form2.Init:
LPARAMETER loCallingForm
*-- Some Init code
*-- Store the calling object reference
THISFORM.CallingFormReference = loCallingForm  && CallingFormReference is property of Form2
*-- etc.
RETURN

When referencing Form1 use simple:
THISFORM.CallingFormReference.command7.setfocus( )
THISFORM.CallingFormReference.command7.click

I have stored the variable in the load property of the form.  However when I call form2 from form1 it says Parameter statement not found?  I am sorry if I seem like and idiot today....but I replaced an Oracle server last night for one of my clients and I am running on almost no sleep.  But I have to have this Foxpro project delivered by tomorrow and this is the only thing holding me up at this point...thanks again for  your help.
0
 
LVL 11

Author Closing Comment

by:Patmac951
ID: 31669687
Pcelba,
Thanks again.  Disregard my last post.  I forgot to add the new property to form2....as I mentioned I have not slept for over 40 hours. Once I added the custom property to the form your solution worked like a charm!  Greatly appreciated.
0
 
LVL 43

Expert Comment

by:pcelba
ID: 26121939
Great it is working now. And happy Holidays!
0

Featured Post

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Microsoft Visual FoxPro (short VFP) is a programming language with it’s own IDE and database, ranking somewhat between Access and VB.NET + SQL Server (Express). Product Description: http://msdn.microsoft.com/en-us/vfoxpro/default.aspx (http://msd…
If you don't know how to downgrade, my instructions below should be helpful.
Screencast - Getting to Know the Pipeline
How can you see what you are working on when you want to see it while you to save a copy? Add a "Save As" icon to the Quick Access Toolbar, or QAT. That way, when you save a copy of a query, form, report, or other object you are modifying, you…
Suggested Courses

577 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question