The menu I am referring to is not VFP menu but downloaded from here: https://github.com/VFPX/OOPMenu. There are a lot of logic be programmed such as the menu item will be enabled when user has the privilege. Now, how do I substitute such as menu? Change back to VFP menu?
You need to modify code in sfMenu.vcx
to replace any menu command by a call to wMenu()
(modify command awPublic.prg
)
eg.
&& replace
define popup (.cPopupNameThis) margin relative shadow color scheme 4
&& by
wMenu(textmerge([define popup <<.cPopupNameThis>> margin relative shadow color scheme 4]))
Here is a sample menu program generated from a *.mnx
by home(1) + "tools\ab\awMenuGen.prg"
Here is the full documentation:
To adapt any menu command or function to LAN (desktop) mode and Web mode, pass it as a character string to wMenu()
;
(FoxInCloud Adaptation Assistant adapts all your menu instructions that way)
DEFI POPU myPopup MARGIN RELA SHADOW COLOR W+/B* && command before adaptation
wMenu('DEFI POPU myPopup MARGIN RELA SHADOW COLOR W+/B* ') && command after adaptation
&& note: wMenu() expands standard abbreviated Visual FoxPro keywords and parses any number of spaces or tabs around clauses
Except ON SELECTION
commands and SKIP FOR
expressions, expressions inside clauses must be expressed as literals;
To convert expressions to literals, simply place your instruction in Textmerge()
and enclose expressions within "<<>>"
lcPrompt = "Display contents of myFile"
DEFINE BAR 2 OF myPopup PROMPT m.lcPrompt SKIP FOR !FILE("myFile.ext") && command before adaptation
wMenu(Textmerge('DEFINE BAR 2 OF myPopup PROMPT "<<m.lcPrompt>>" SKIP FOR !FILE("myFile.ext")')) && command after adaptation
To make it even more simple, you can use the FoxInCloud cLitteral()
function (aliased as cL
);
cLitteral()
[alias cL()] supports expressions of any type:
liBar = 2
lcPrompt = "Display contents of myFile"
DEFINE BAR m.liBar OF myPopup PROMPT m.lcPrompt SKIP FOR !FILE("myFile.ext") && command before adaptation
wMenu(Textmerge('DEFINE BAR <<cL(m.liBar)>> OF myPopup PROMPT <<cL(m.lcPrompt)>> SKIP FOR !FILE("myFile.ext")')) && command after adaptation
To control whether menu command execution is OK, you can chain your wMenu() command calls with .AND.
;
If any error occurs, execution chain will stop on the offending instruction, and the second parameter passed by reference will hold the error message:
local success, result
success = .T.;
and wMenu('DEFI POPU myPopup MARGIN RELATIVE SHADOW COLOR W+/B*', @m.result);
and wMenu('ON SELECTION BAR 2 OF myPopup loMyForm.myMethod(m.myValue)', @m.result)
assert m.success message m.result
if m.success
...
endif
Just before executing ACTIVATE commands such as:
wMenu('ACTIVATE MENU|POPUP ...', @m.result)
wMenu('ON PAD|BAR ... ACTIVATE MENU|POPUP xxx', @m.result)
for a MENU or POPUP having SKIP FOR
and/or ON SELECTION
clauses relying on variables, e.g.
wMenu('ON SELECTION BAR 2 OF myPopup loMyForm.myMethod(m.myValue)', @m.result);
wMenu('DEFINE PAD|BAR ... SKIP FOR myFunction(m.myValue)', @m.result)
(keywords such as this
and thisform
can't be used in ON SELECTION and SKIP FOR clauses as they execute outside of the form's context)
... Make sure to pass by reference an object as second parameter [@m.result], with properties holding any variable required for SKIP FOR
and ON SELECTION
clauses
local success, result
success = .T.;
and wMenu('DEFI POPU myPopup MARGIN RELATIVE SHADOW COLOR W+/B*', @m.result);
and wMenu('DEFINE BAR 2 OF myPopup PROMPT "xx" SKIP FOR m.myBoolean', @m.result);
and wMenu('ON SELECTION BAR 2 OF myPopup loMyForm.myMethod(m.myValue)', @m.result);
;
and varSet(@m.result, CreateObject('Empty')); && you create an object which defines the parameters that are required for your ON SELECTION commands and SKIP FOR expressions
and AddProperty(m.result, 'loMyForm', thisForm);
and AddProperty(m.result, 'myValue', m.myValue);
and AddProperty(m.result, 'myBoolean', m.myBoolean);
and wMenu('ACTIVATE POPUP myPopup ... NOWAIT', @m.result) && m.result contains: - on call, the 'parameter object' - on return, error message if any, else .null.
assert m.success message m.result
Please note that, for parameters of type Object, ONLY references to form or form members are supported. e.g. if you need a reference to an object, make sure that this object is added to any container within the form, or the form itself:
local loMyObject, success, result
thisForm.AddObject('oObject', 'myCustom', InitParm)
loMyObject = thisForm.oObject
success = .T.;
and wMenu('DEFI POPU myPopup MARGIN RELATIVE SHADOW COLOR W+/B*', @m.result);
and wMenu('ON SELECTION BAR 2 OF myPopup loMyObject.myMethod(m.myValue)', @m.result);
and varSet(@m.result, CreateObject('Empty')); && you create an object which defines the parameters that are required for your ON SELECTION commands and SKIP FOR expressions
and AddProperty(m.result, 'loMyObject', m.loMyObject); && loMyObject is needed to evaluate some SKIP FOR expression or execute some ON SELECTION command
and AddProperty(m.result, 'myValue', m.myValue);
and wMenu('ACTIVATE POPUP myPopup ... NOWAIT', @m.result)
assert m.success message m.result
if you:
- use the ACTIVATE MENU|POPUP without the NOWAIT clause,
- expect some code to execute after MENU|POPUP gets DEACTIVATEd,
Make sure to:
- move the code located after the ACTIVATE MENU|POPUP command to another method (AKA
call-back
method) - this code move is similar to what you already do for code processing the response of a modal form - add 2 properties to the above-mentioned parameter object:
.
woCallBack
: reference to the form member holding the call-back method, = this typically .wcCallBack
: name of the call-back method, = 'wFormCallBack*' typically
Important:
- if either
.woCallBack
or.wcCallBack
is not passed or do not match a valid object and public method, the code you currently have afterACTIVATE MENU|POPUP
WILL NOT EXECUTE in Web mode. - the call-back object (
.woCallBack
) MUST BE a form or a form member. - make sure not to use
woCallBack
orwcCallBack
as variable names as defined above.
local loMyObject, success, result
thisForm.AddObject('oObject', 'myCustom', InitParm)
loMyObject = thisForm.oObject
success = .T.;
and wMenu('DEFI POPU myPopup MARGIN RELATIVE SHADOW COLOR W+/B*', @m.result);
and wMenu('ON SELECTION BAR 2 OF myPopup loMyObject.myMethod(m.myValue)', @m.result);
and varSet(@m.result, CreateObject('Empty')); && you create an object which defines the parameters that are required for your ON SELECTION commands and SKIP FOR expressions
and AddProperty(m.result, 'loMyObject', m.loMyObject); && loMyObject is needed to evaluate some SKIP FOR expression or execute some ON SELECTION command
and AddProperty(m.result, 'myValue', m.myValue);
and AddProperty(m.result, 'woCallBack', m.this);
and AddProperty(m.result, 'wcCallBack', 'wFormCallBack'); && this.wFormCallBack() will execute when myPopup deactivates
and wMenu('ACTIVATE POPUP myPopup ...', @m.result)
assert m.success message m.result
wMenu()
also executes menu functions:
&& function call before adaptation:
? Prmba( "myPopup", 2 )
&& function call after adaptation:
? wMenu('Prmba( "myPopup", 2 )', @m.result)
If an error occurs, wMenu('menuFunction()', @m.result)
returns .null.
(In logical tests such as IF
, Iif()
, case
, etc., VFP coerces .null.
to .F.
)
local lcPrmBar, success
lcPrmBar = wMenu('Prmba( "myPopup", 2 )', @m.result)
success = not IsNull(m.lcPrmBar)
assert m.success message m.result
if m.success
do something with m.lcPrmBar
endif