How can I ENABLE/DISABLE an AppFrame Menu item (based on a condition) from within an embed point in a different procedure?
You can make use of NOTIFY on the different procedure
NOTIFY( notifycode, AppFramethread, )
and NOTIFICATION on you AppFrame Event:Notify
OF EVENT:Notify
IF NOTIFICATION (NCode, NParam) !NOTIFY has sent a Notify Event. Get Code and Parameter
Thanks Tuz. I have looked at the help and need to figure things out.
The AppFramethread will almost always be 1 (one). If you know you Start(AppFrame) it will be different.
Full syntax is
NOTIFY(LONG NotifyCode, <LONG Thread>, <LONG Parameter>)
So you can pass 2 LONG’s (Code & Param) that you use any way you want. The Param is optional.
NOTIFY(301, 1) !301=Enable Check Printing
NOTIFY(302, 1) !302=Disable Check Printing
I sometimes program as (Subject,,Action) so
NOTIFY(401, 1, 1) !401=Post Checks, 1=Enable
NOTIFY(401, 1, -1) !401=Post Checks, -1=Disable
It’s best to setup Global Equates for the values you use.
Good to not assume 1, IMO.
If you’re going to save a Global with the Frame thread number instead you could save a &WINDOW reference and ITEM FEQ’s.
Then you can modify the Frame even if another window is open over it. The NOTIFY event will go to the open window. I sometimes will have a Settings that is not MDI so it prevents access to the frame menus.
Glo:FrameWndRef &WINDOW
Glo:FrameItem_PostChecks LONG
! -- In Frame after Open(AppFrame) --
Glo:FrameWndRef &= AppFrame
Glo:FrameItem_PostChecks = ?PayrollMenuPostChecks
!-- Procedure that wants to Disable Post Checks
Glo:FrameWndRef $ (Glo:FrameItem_PostChecks) {PROP:Disable} = True
I think that code works across threads ?
I would probably put all that Menu Disable/Enable code in one procedure that took parameters like I used above for Notify. That way it’s on one place should you decide to refactor.
Be mindful of the LIFO nature of Notification.
this has all come to be beyond my capabilities! But I do thank you all for taking the time to respond.
What version of Clarion are you using?
A simpler way don’t disable, instead setup a Global Variable to flag “cannot run” then in the Menu Item Accepted check that and show a Message then cycle.
Glo:PrintChecksCannotRun LONG !Global Data
!-- Menu Item Accepted Event --
IF Glo:PrintChecksCannotRun <> 0 THEN
Message('You cannot Print Checks when Enter Checks is open ...')
CYCLE
END
!-- At the Top of a Procedure like Enter Checks --
Glo:PrintChecksCannotRun += 1
!-- At the Bottom of above --
Glo:PrintChecksCannotRun -= 1
Instead of =True/False do +/- 1 so there can be multiple procedures that block.
I prefer having the Message() so it explains to the user why he cannot run. The Disabled Item can be a mystery as to why it cannot be used, often for tech support or the developer.
One nice way to code the +/- 1 is a local Class with Constructor / Destructor. The calls are automatic so you cannot miss.
CannotRunCls CLASS
Construct PROCEDURE
Destruct PROCEDURE
END
CannotRunCls.Construct PROCEDURE
CODE
Glo:PrintChecksCannotRun += 1
CannotRunCls.Destruct PROCEDURE
CODE
Glo:PrintChecksCannotRun -= 1
I am using C8, Legacy version
Thanks Carl, I will give this a try.