INTELLIGENT WORK FORUMS FOR COMPUTER PROFESSIONALS
Come Join Us!
Are you a Computer / IT professional? Join Tek-Tips now!
- Talk With Other Members
- Be Notified Of Responses
To Your Posts
- Keyword Search
- One-Click Access To Your
Favorite Forums
- Automated Signatures
On Your Posts
- Best Of All, It's Free!
*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.
Partner With Us!
"Best Of Breed" Forums Add Stickiness To Your Site

(Download This Button Today!)
Feedback
"...If I'd only had resource like eng-tips when I was just getting started! I might have dazzled them with my brilliance instead of my BS..."
Geography
Where in the world do Tek-Tips members come from?
|
Acess form's custom properties from menu? (4)
|
|
|
Paco75 (Programmer) |
12 Apr 12 14:24 |
Hi, I have a standalone form with a menu and i want to acess my custom properties i put in the form but i can`t manage to do a call like CODEthisform.myProperty = "TEST" So i need to pass a variable from menu to standalone form! anyone know how to? except than putting the property as public variable :( |
|
You need to create a local variable, and use it to store an object reference to the form. Do that in the code that creates the menu. I know you are using the menu designer to create your menu, so you might have to hand-modify the menu code, or create the entire menu in code, using the generated code as a guide. Something like this: CODELOCAL loForm loForm = THISFORM
DEFINE BAR 1 .... ON SELECTION BAR 1 OF ... loForm.SomeMethod If you want to access a property in a clause of the DEFINE BAR (such as the SKIP FOR clause), you need to make the variable PRIVATE: CODEPRIVATE poFom poForm = THISFORM
DEFINE BAR 1 ... SKIP FOR poForm.NotAvailable Does that give you the general idea? Mike __________________________________ Mike Lewis (Edinburgh, Scotland)
Visual FoxPro articles, tips, training, consultancy |
|
|
Paco75 (Programmer) |
12 Apr 12 15:16 |
|
Menu code exists "outside" the form object so you can't use "thisform". Only code that's inside an object can make reference to itself.
You can create a variable just for the purpose as Mike suggests. Or your menu code can reference _Screen.Activeform instead of Thisform. The caveat is that you need to make sure the menu won't ever make that reference when Activeform is empty.
(You can creatively use SKIP FOR to disable menu options when there isn't an Activeform, for example.) |
|
|
Paco75 (Programmer) |
12 Apr 12 15:45 |
i get the error "Thisform can only be used within a method" |
|
|
Paco75 (Programmer) |
12 Apr 12 16:16 |
i also tried _Screen.Activeform but i dont have access to form. here is my .mpr file CODELPARAMETERS oFormRef, getMenuName, lUniquePopups, parm4, parm5, parm6, parm7, parm8, parm9 LOCAL cMenuName, nTotPops, a_menupops, cTypeParm2, cSaveFormName IF TYPE("m.oFormRef") # "O" OR ; LOWER(m.oFormRef.BaseClass) # 'form' OR ; m.oFormRef.ShowWindow # 2 MESSAGEBOX([This menu can only be called from a Top-Level form. Ensure that your form's ShowWindow property is set to 2. Read the header section of the menu's MPR file for more details.]) RETURN ENDIF m.cTypeParm2 = TYPE("m.getMenuName") m.cMenuName = SYS(2015) m.cSaveFormName = m.oFormRef.Name IF m.cTypeParm2 = "C" OR (m.cTypeParm2 = "L" AND m.getMenuName) m.oFormRef.Name = m.cMenuName ENDIF IF m.cTypeParm2 = "C" AND !EMPTY(m.getMenuName) m.cMenuName = m.getMenuName ENDIF DIMENSION a_menupops[1] IF TYPE("m.lUniquePopups")="L" AND m.lUniquePopups FOR nTotPops = 1 TO ALEN(a_menupops) a_menupops[m.nTotPops]= SYS(2015) ENDFOR ELSE a_menupops[1]="newitem" ENDIF
* ********************************************************* * * * * Menu Definition * * * ********************************************************* *
DEFINE MENU (m.cMenuName) IN (m.oFormRef.Name) BAR
DEFINE PAD _3h70uffqt OF (m.cMenuName) PROMPT "\<Fichier" COLOR SCHEME 3 ; KEY ALT+F, "ALT+F" ON PAD _3h70uffqt OF (m.cMenuName) ACTIVATE POPUP (a_menupops[1])
DEFINE POPUP (a_menupops[1]) MARGIN RELATIVE SHADOW COLOR SCHEME 4 DEFINE BAR 1 OF (a_menupops[1]) PROMPT "Ouvrir \<Estime" ; KEY CTRL+E, "CTRL+E" DEFINE BAR 2 OF (a_menupops[1]) PROMPT "Ouvrir \<Bon de Commande" ; KEY CTRL+C, "CTRL+C" DEFINE BAR 3 OF (a_menupops[1]) PROMPT "Ouvrir \<Bon de Production" ; KEY CTRL+P, "CTRL+P" ON SELECTION BAR 1 OF (a_menupops[1]) ; DO _3h70uffqu ; IN LOCFILE("VISUALINSPECTOR\MENUPRINCIPAL" ,"MPX;MPR|FXP;PRG" ,"WHERE is MENUPRINCIPAL?") ON SELECTION BAR 2 OF (a_menupops[1]) ; DO _3h70uffqv ; IN LOCFILE("VISUALINSPECTOR\MENUPRINCIPAL" ,"MPX;MPR|FXP;PRG" ,"WHERE is MENUPRINCIPAL?") ON SELECTION BAR 3 OF (a_menupops[1]) ; DO _3h70uffqw ; IN LOCFILE("VISUALINSPECTOR\MENUPRINCIPAL" ,"MPX;MPR|FXP;PRG" ,"WHERE is MENUPRINCIPAL?")
ACTIVATE MENU (m.cMenuName) NOWAIT
IF m.cTypeParm2 = "C" m.getMenuName = m.cMenuName m.oFormRef.Name = m.cSaveFormName ENDIF
*************************************************** PROCEDURE _3h70uffqu
LOCAL loForm loForm = _Screen.Activeform DO FORM frmOpenEstimate loForm.lblEstimateNo.caption = "Test" In the last procedure you can see what im trying to do. |
|
1. Do not attempt to use _Screen.Activeform when there isn't any form. I thought I said that. 2. You have removed from your generated code the standard comments for using your top-level menu with a form. I'll paste them here: CODE* To attach this menu to your Top-Level form, * call it from the Init event of the form:
* Syntax: DO <mprname> WITH <oFormRef> [,<cMenuname>|<lRename>][<lUniquePopups>]
* oFormRef - form object reference (THIS) * cMenuname - name for menu (this is required for Append menus - see below) * lRename - renames Name property of your form * lUniquePopups - determines whether to generate unique ids for popup names * example:
* PROCEDURE Init * DO mymenu.mpr WITH THIS,.T. * ENDPROC
* Use the optional 2nd parameter if you plan on running multiple instances * of your Top-Level form. The preferred method is to create an empty string * variable and pass it by reference so you can receive the form name after * the MPR file is run. You can later use this reference to destroy the menu. |
|
Paco, To use the code I gave you, you will need to create the menu in a method of the form. I know from your other question that the menu is part of your top-level form, so there should be nothing to prevent you from creating the menu in the Load or Init of that form, in which case you won't get the "Thisform can only be used within a method" error. Mike __________________________________ Mike Lewis (Edinburgh, Scotland)
Visual FoxPro articles, tips, training, consultancy |
|
LOCAL loForm loForm = _Screen.Activeform <- trying to access a form here DO FORM frmOpenEstimate <- while you create it here
Does this make sense?
Turn the command order arund: 1. create a form 2. set it's properties
You can't set properties of something not existing yet, can you?
Bye, Olaf. |
|
Besides I would suggest the form should set it's caption itself. Play by the rules of OOP, encapsulation is important, a class, and also a standard SCX form, shold be self contained, mostly.
Why do you need to set the form caption from the menu?
Bye, Olaf. |
|
|
Paco75 (Programmer) |
17 Apr 12 15:48 |
I did like Mike suggested and created the menu in a method of the top level form. I choosed form.Activate here is the code. CODECLEAR SET SYSMENU SAVE SET SYSMENU TO ON KEY LABEL ESC KEYBOARD CHR(13) DEFINE MENU mainMenu BAR in window frmMain DEFINE PAD padFile OF mainMenu PROMPT '\<File' COLOR SCHEME 3 KEY ALT+F, '' ON PAD padFile OF mainMenu ACTIVATE POPUP popFile DEFINE POPUP popFile MARGIN RELATIVE SHADOW COLOR SCHEME 4 DEFINE BAR 1 OF popFile PROMPT "Open \<Estimate" KEY CTRL+E, "CTRL+E" DEFINE BAR 2 OF popFile PROMPT "Ouvrir \<Purchase Order" KEY CTRL+O, "CTRL+O" DEFINE BAR 3 OF popFile PROMPT "Ouvrir \<Production Order" KEY CTRL+P, "CTRL+P" ON SELECTION BAR 1 OF popFile ; thisform.openEstimate ON SELECTION BAR 2 OF popFile ; thisform.openPurchOrd ON SELECTION BAR 3 OF popFile ; thisform.openProdOrd ACTIVATE MENU mainMenu nowait and on form unload of top level form CODEDEACTIVATE MENU mainMenu RELEASE MENU mainMenu EXTENDED SET SYSMENU TO DEFAULT But the menu still work as before... thisform (the toplevel form) is not accessible from menu. Im not sure im explaining myself clearly... When user press File->Open estimate it pops a small window to ask user the estimate number. Then i want to return that value to the top level form so i could fill the form's objects (textfields, combobox,... etc) to do this i must have acces to top level form. The menu is loaded in the top level form and the form is visible and active (otherwise i would not see the menu that is loaded in) so logically i should be able to access the components of the form that contains the menu! |
|
You're never going to be able to use ThisForm in menu code. What both Mike and Olaf were suggesting were ways to get a reference to the form inside the menu, so you don't need ThisForm.
My experience is that I can almost always use _Screen.ActiveForm rather than ThisForm in menu code.
Tamar |
|
|
Paco75 (Programmer) |
17 Apr 12 16:27 |
Thanks it worked with _Screen.ActiveForm directly in replacement of thisform. CODECLEAR SET SYSMENU SAVE SET SYSMENU TO ON KEY LABEL ESC KEYBOARD CHR(13) DEFINE MENU mainMenu BAR in window frmMain DEFINE PAD padFile OF mainMenu PROMPT '\<File' COLOR SCHEME 3 KEY ALT+F, '' ON PAD padFile OF mainMenu ACTIVATE POPUP popFile DEFINE POPUP popFile MARGIN RELATIVE SHADOW COLOR SCHEME 4 DEFINE BAR 1 OF popFile PROMPT "Open \<Estimate" KEY CTRL+E, "CTRL+E" DEFINE BAR 2 OF popFile PROMPT "Ouvrir \<Purchase Order" KEY CTRL+O, "CTRL+O" DEFINE BAR 3 OF popFile PROMPT "Ouvrir \<Production Order" KEY CTRL+P, "CTRL+P" ON SELECTION BAR 1 OF popFile ; _Screen.ActiveForm.openEstimate ON SELECTION BAR 2 OF popFile ; _Screen.ActiveForm.openPurchOrd ON SELECTION BAR 3 OF popFile ; _Screen.ActiveForm.openProdOrd ACTIVATE MENU mainMenu nowait |
|
Paco, Quote (dan): Menu code exists "outside" the form object so you can't use "thisform"
Dan said this 25 minutes before your post Quote (Paco): i get the error "Thisform can only be used within a method"
So in the end you start a top level form and a menu, that you want to make calls into this top level form from the menu, right? And this top level form is your main form and it will only be started once, right? But you also start new forms, don't you? Then _screen.Activeform will not always adress the main top level form. If you want (some or most of your) menu to control the top level form, then rather think about a way to always adress that form, eg like this: In your top level form init() add this line: CODE* top level form init * ... _screen.AddProperty("oMainForm",This) * ... Then change all your _screen.ActiveForm references in the menu items, that should always address the mainform to _screen.oMainform And going back to your initial question, you then can also do things like: CODE_screen.oMainform.myProperty = "TEST" _screen.activeform must be used cautious for something, any form of your app will support, only, and also if closing your main form does not close the app, _screen.Activeform can get NULL, which makes code using it fail. That may not be the case, but still _screen.activeform will address the active form, no matter what it is, that's not what you want. In regard of the other case, where you start a form and then set it's properties (or actually tried it the other way around), the normal way to go about this, is to add an LPARAMETERS to the form init and to call the form with parameters passed to the init, for example: CODE* Form.Init() code: LPARAMETERS tcCaption
This.Caption = EVL(tcCaption,"Default Caption")
* Call of the form Do Form yourform WITH "Non Default Caption" Bye, Olaf. |
|
One other point, Paco .... Your code includes this line: CODEON KEY LABEL ESC KEYBOARD CHR(13) You should be aware that this comand has a global scope. In other words, you will be changing the behaviour of the ESC key throughout the application. I'm not sure why you have this command in this particular place, but you need to change it back as soon as it is no longer needed. Mike __________________________________ Mike Lewis (Edinburgh, Scotland)
Visual FoxPro articles, tips, training, consultancy |
|
|
Paco75 (Programmer) |
18 Apr 12 7:22 |
@Olaf Thanks for the tip i did not knew i could set properties to _screen. I tried it and it works #1. My application has more than one screen but except the top one the others are dialogs so i think it might have worked without setting a _screen property. The top level form also close the application completely. @Mike The line CODEON KEY LABEL ESC KEYBOARD CHR(13) is a remnant of the .mpr generated file... i kept it because he was here. I removed it since it is now useless. Thanks |
|
Quote: but except the top one the others are dialogs so i think it might have worked without setting a _screen property.
If you want to say with "dialogs" they are modal forms like messageboxes, meaning you can not choose menu items, while they are active, only while the top level form is the active one, yes, then _screen.activeform would be sufficient in the menu. Bye, Olaf. |
|
|
 |
|