Visual FoxPro: How to call back to a form from a popup menu

Popup menus are a useful way to provide users with context-based shortcuts to frequently used actions. In Visual FoxPro, popup menus are commonly invoked from the right-click event code of a control on a form, while the code you want to execute from a bar on the menu may be contained in a custom method of the form.

The challenge is, how do you get a popup menu to run a method of the form that invoked it? You can't reference 'thisform' within the menu, because 'thisform' is out of scope when the menu is active. And it's bad design to reference the calling form with a specific object name, because then the menu is tightly coupled to a particular named instance of the form.

The solution is to pass an object reference to the form as a parameter to the menu. This enables the menu to call back to the form using the parameter as the object reference.

For example, say you have a form with a grid to display rows of data, and another form to edit the data for any given row. The main form has a method named Edit() that does whatever's necessary to launch the editing form, perhaps passing it the primary key of the record for the currently selected grid row. You want the user to be able to right-click on the grid and choose 'Edit' from the popup menu, which in turn should call the form's Edit() method. Here's how to do this:

In the right-click method of a control(s) in the grid, put

DO myPopup.mpr WITH thisform

This passes an object reference to the form as a parameter to the popup menu. In the Setup code of myPopup menu, put


Use PARAMETERS instead of LPARAMETERS so oCaller is PRIVATE rather than LOCAL. As a private variable, oCaller is visible to and can be referenced by any other code in myPopup.mpr. So in the code for the Edit bar of myPopup, you can write


This runs the Edit() method of the calling form, regardless of what the calling form's object name is.

You can extend this concept even further by passing an object reference to the individual control as a second parameter. For example, put

DO myPopup.mpr WITH thisform, this

in the right-click method, and put the corresponding

PARAMETERS oCaller, oControl

in the menu's Setup code. Within the menu, you now have fine-grained access both to the calling form and to the specific control from which the menu was launched.

Technorati Tags: ,


Craig said...

Why not just use _SCREEN.Activform.SomeMethod()

Rick Borup said...

> Craig said...
> Why not just use
> _SCREEN.Activform.SomeMethod()

Because you don't necessarily have any control over which form is going to be the ActiveForm when that code runs.

RejVar76 said...

I tried putting the
PARAMETERS oCaller in the MENU.MPR file but it gets overwritten whenever I compile. I am using the VFP Menu Designer. Is there a way to get around this

Rick Borup said...

Any changes made directly in an MPR file are overwritten when the menu is recompiled from the MNX. Instead, make the changes in the menu designer. Open the menu in the menu designer, click View | General Options on the VFP main menu, click the Setup check box in the Menu Code section of the dialog, then click OK. Now the Setup code is open in the VFP code editor and you can enter the 'Parameters oCaller' code there.

RejVar76 said...

Thanks, it helped