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

another 'object FORMNAME is not found' problem 2

Status
Not open for further replies.

dexterdg

Programmer
Jan 6, 2013
85
PH
hi to all

i made a vfp project that contains a log in and an mdi form

problem:
after running login and after log in---
*codes to redirect*
*!* filter codes here
loginform.release()
do form mdiform

everything works perfectly except:
when i click the menu on my mdi parent its shows the error
"object FORMNAME is not found"

but when i run mdiform* (w/ loging in)
it works just fine

also after the log in, it shows the called mdiform but its like at the *send to back mode* so i have to switch tab to it.

thanks for taking time helping!

 
oh and FORMNAME in my problem is the name of my mdiform
*FORMNAME == mdiform
 
You can't address a form merely by it's name. You need a form reference inside a variable and adress the form via the variable name.

You can also address the active form with code like _Screen.ActiveForm.Caption = 'My App', but there is a pitfall: _Screen.ActiveForm is no usable reference, if there is no form running and active.

So, if you create your MDI form in the main.prg by DO FORM mdiform, instead do the following:

poMDIForm = .NULL.
DO FORM mdiform NAME poMDIForm LINKED

The NAME clause does NOT change the name of the form, but puts a form reference into the variable name poMDIForm, the LINKED clause makes the form vanish, when you RELEASE poMDIForm, that is when you release the variable. Such variables have VARTYPE "O" for object, meaning object reference. They mainly contain the memory address of the main object, but never tell you the interger address value, they address the object. Welcome to object oriented programming.

Now you can address the form via poMDIForm, also in menu items, if the form is generated and kept open throughout the application session, o if closing the form closes the application, which would be the case for MDI main forms. Eg poMDIForm.Caption = 'Your App' now would change the caption, even if the form is not active.

Bye, Olaf.
 
Just to add a word to Olaf's answer:

You need to keep poMDIForm in scope for as long as you want the form to be open. If you don't explicitly declare its scope, it will be a local variable. That means that, if you issue the DO FORM in a method or a function, the variable will cease to exist when the method or function exits, at which point the form will close.

To avoid that situation, declare poMDIForm either as a private or a public. If you're not sure what those mean, or what the implications are, read the VFP Help for PUBLIC, PRIVATE (and also LOCAL).

Mikw

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
Mike, if you define it as that in main.prg (as I suggested) it will be almost the same as public, because it's private (not local) and private to the main.prg, it's scope will only end, when the main.prg ends. And as main.prg also is, where you have your READ EVENTs, that would mean it stays in scope throughout the application session.

Bye, Olaf.
 
I see, Mike, OK.

Chris also points to a good overall solution, to handle forms via a form handler. The concept of handlers is also good for other things. I would base a form handler on the collection class, today, but the approach to use oForms = CreateObject([Empty]) && VFP 8.0/9.0 or oForms = CreateObject([Custom]) && < VFP 8.0 as a root object to add all further form references also is good.

If you go for object orientation and create form classes, the concept is even forcing you to create such form references, as CREATEOBJECT() then is the main function to create instances and you create a form by oFORM = CREATEOIBJECT("formclass") and then oFORM.Show(). instead of DO FORM, so this way you're simply forced to put an object reference into a variable.

Things are much more consistent, if you don't just move from legacy screens to SCX, but to classes.

Bye, Olaf.
 
In fact, I published a complete form manager class in FoxPro Advisor some years back. I wish I could re-publish it here, but unfortunately I no longer have access to the electronic versions of the material.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
is the problem really is how i called the mdiFrom?
redirecting to mdiForm seems like it doesnt have a problem
functionality of mdiForm after called does.
problem occurs when im in mdiForm already, and i tried your
suggestions i learned something new from you guys but
program error still persists

*!*for better view of my coding
*!*--[[log-in.scx]] form object: cmdOk Procedure: Click
If *!*filter
Else
*!*check on db if acc exist
If Found()
thisform.Release()
DO FORM mdiForm
Else
*!*error catcher
ENDIF
ENDIF
*!*---[[mdiForm.scx]] object: form Procedure: Init
WITH THISFORM
DO menu.mpr WITH THIS, .t.
ENDWIH
*!*---[[menu.mpr]]
*!*vfp generated codes for menu
*!*i added selection action at the bottom to trigger action when menu is clicked
ON SELECTION BAR 1 OF file mdiForm.filefunc1()
*!*filefunc1()->contains the action [in this case just a messagebox]
*!*and repeated ON SELECTION BAR 2...n OF [other menu] mdiForm.[other predefined method]

thanks, Dexter
im online @ gmt+8: 8:00am - 1:00pm
hope we could converse in other medium/s
 
also sir olaf, why with the "LINKED" if it will vanish my mdiform?
 
i think i kinda found the solution.
its the ON SELECTION BAR
error refers to the method
so i put codes there directly
e.g. ON SELECTION BAR 1 of file DO FORM employeeForm.scx
but i have new problems so please help me
in my new problem
thanks for the new learnings! stars for you!
 
1. ON SELECTION BAR 1 OF file mdiForm.filefunc1()
Yes, this is a problem, because a form can't be addressed by it's name, only by an object reference. Only few commands really need the form name as a clause, eg HIDE WINDOW mdiForm wold do, but you can't call a method of the form via form name, you need a form reference.

2. LINKED
You can also go without LINKED, but you missunderstood it vanishes your form, in the first place it does not, it just enables you to easily close the form finally by releasing the variable, but as I put it in the sample code I gave you earlier, that variable would stay in scope and exist and keep the form existing, until you RELEASE the variable. You don't do that of course, unless you want to release the form, eg at the end of the application.

Again explained:
DO FORM mdiform NAME poMDIForm LINKED will put a reference to the form into the variable poMDIForm, and you can use that variable in your menu code:
ON SELECTION BAR 1 OF file poMDIForm.filefunc1()

And AGAIN said: This does NOT rename the form, the NAME clause is there to specify a VARIABLE name, not the FORM name. So you don't rename the form and the form name doesn't matter at all. In fact poMDIForm.Name will be the form name and most probably will be "Form1" and neither mdiform nor poMDIForm, you have to stop thinking in form/window names, this is legacy code and thinking and doesn't work anymore, with the object oriented way of adressing forms. Witout the name caluse of DO FORM, there is nothing, that will hold a reference to the form and so you can't address the form in menu code or any other code outside of the form. Only code inside a form could then address itself via THISFORM, which you already know. But outside of form you need more than just the name of the form. It's useless but for a few legacy WINDOW commands. But it doesn't help you in calling for example a form method, like you want to do.

Bye, Olaf.
 
you are a life saver sir olaf!
gonna try it again and update this thread for what is to happen
 
poMDIForm = .null. ; DO FORM mdiForm NAME poMDIForm is up and running so i can now reference my methods with poMDIForm.[methodname], thanks again sir olaf. saved me a lot of coding lines. !

how do i put this thread to solved??
thanks
Dexter
 
You don't need to close a thread. If you want, you may thank for single posts, with the link "Thank ... and star this post".

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top