Menu manager question

43 views
Skip to first unread message

Kevin Toppenberg

unread,
Jul 26, 2022, 8:45:10 AM7/26/22
to Hardhats
The menu manager has several API's for manipulating menus.   Here is a URL showing these: https://hardhats.org/kernel/html/category_frm1.html#menu_manager

I have a very simple desire to drop into a menu location programmatically.  But I can't find such an API.  Can anyone point me in the right direction?

I know that sometimes it is expected that a user will have gotten to menu B by first going through menu A, and thus having proper setup via code executed during execution.  But all that aside, it doesn't stop me from picking any arbitrary menu when I enter via ^XUP.

If no one knows right off, I'll debug through this and I suspect it will be easy to figure out.  I was just wondering why an entry API wasn't listed on the website above.

Thanks
Kevin

Thurber, Joseph H

unread,
Jul 26, 2022, 8:50:42 AM7/26/22
to hard...@googlegroups.com

You may already know about this one, but just in case:

 

NUMBER: 423                             NAME: XT-OPTION TEST

  MENU TEXT: Test an option not in your menu                                    TYPE: action

  CREATOR: WVEHR,PATCH INSTALLER        LOCK: XUMGR                             E ACTION PRESENT: YES

  X ACTION PRESENT: YES

DESCRIPTION:   This is for in-house testing of options only.  It allows the selection of an option

from the OPTION file and then executes it.  No security checks are performed, therefore, this option

should only be given to programmers.

  ENTRY ACTION: S DIC=19,DIC(0)="AEMQZ",DIC("A")="Option entry to test: ",DIC("S")="I $P(^(0),U)'[""XU

PROG""" D ^DIC K DIC I Y>0 S XQY=+Y,XQUR=$P(Y,U,2),XQDIC="U",XQY0=^DIC(19,XQY,0),^("T")=^XUTL("XQ",$J,

"T")-1 G M0^XQ                          TIMESTAMP: 53824,50375

  TIMESTAMP OF PRIMARY MENU: 62746,48746

  UPPERCASE MENU TEXT: TEST AN OPTION NOT IN YOUR MEN

  TS AS DATE (c): MAY 13,1988@13:59:35  TS OF PMENU AS DATE (c): OCT 16,2012@13:32:26

 

From: hard...@googlegroups.com <hard...@googlegroups.com> On Behalf Of Kevin Toppenberg
Sent: Tuesday, July 26, 2022 8:45 AM
To: Hardhats <hard...@googlegroups.com>
Subject: [External] [Hardhats] Menu manager question

 

CAUTION: External email. Do not click links or open attachments unless you verify. Send all suspicious email as an attachment to Report Spam.

 

--
--
http://groups.google.com/group/Hardhats
To unsubscribe, send email to Hardhats+u...@googlegroups.com

---
You received this message because you are subscribed to the Google Groups "Hardhats" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hardhats+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/hardhats/e3d41e1d-1b06-43e2-8237-8a08abe1fa43n%40googlegroups.com.




Email correspondence to and from this address is subject to the North Carolina Public Records Law and may be disclosed to third parties by an authorized State official. Unauthorized disclosure of juvenile, health, legally privileged, or otherwise confidential information, including confidential information relating to an ongoing State procurement effort, is prohibited by law. If you have received this email in error, please notify the sender immediately and delete all records of this email.

Nancy Anthracite

unread,
Jul 26, 2022, 9:14:06 AM7/26/22
to hard...@googlegroups.com, Kevin Toppenberg

I doubt you don't know this or that I am answering your question, but did you Fileman to look at the options to see what routine a particular menu calls?

 

--

Nancy Anthracite

David Whitten

unread,
Jul 26, 2022, 9:56:52 AM7/26/22
to hard...@googlegroups.com
I agree with Joe that the code in the option "NAME: XT-OPTION TEST" could be used.

Note that you will have to change the code listed to not ask for the OPTION to run, and
set the variable X to be the name of the option you want to use.

Something like this:

S X="EVE" 

S DIC=19,DIC(0)="MZ",DIC("A")="Option entry to test: ",DIC("S")="I $P(^(0),U)'[""XUPROG""" 

D ^DIC K DIC 

I Y>0 S XQY=+Y,XQUR=$P(Y,U,2),XQDIC="U",XQY0=^DIC(19,XQY,0),^("T")=^XUTL("XQ",$J,"T")-1 G M0^XQ 


I checked the Integration Agreements page at https://foia-vista.worldvista.org/VistA_Integration_Agreement/2022_July_11_IA_Listing_Descriptions.txt
and did not see the entry point "M0^XQ" mentioned, but the option won't work if they change it.


The code from the most recent FoIA is Routine: XQ (worldvista.org)  or https://vivian.worldvista.org/dox/Routine_XQ_source.html#M0 

has the M0 entrypoint, so it should work.


Best Wishes,

Dave Whitten

713-870-3834


Kevin Toppenberg

unread,
Jul 26, 2022, 6:31:08 PM7/26/22
to Hardhats
This is turning out to be much more difficult than I had hoped. Before  I got answers above, we traced through and found, when starting via DO ^XUP,  that the following code gets called in XQ1

XQ1    ; SEA/MJM - DRIVER FOR MENUMAN (PART 2) ;08/28/08  13:20
    ;;8.0;KERNEL;**1,15,59,67,46,151,170,242,446**;Jul 10, 1995;Build 36
    ;Per VHA Directive 2004-038, this routine should not be modified.
    S DIC=19,DIC(0)="AEQM" D ^DIC Q:Y<0  S (XQDIC,XQY)=+Y K DIC,XQUR,Y,^VA(200,DUZ,202.1)
    D INIT^XQ12
    G M^XQ


We reformulated this into this code, which we put in TMGXQ1.m

ENTER(OPT)  ;
  ;"Purpose: Enter Menu Manager
  ;"Input:   OPT -- either a name of OPTION to enter, or IEN of OPTION
  ;"Result: none
  ;"Routine is copied and modified from /r/XQ1.m
  ;
  SET OPT=$GET(OPT)
  NEW IEN SET IEN=+OPT
  IF +OPT'=OPT,OPT'="" DO
  . SET DIC=19,DIC(0)="M",X=OPT DO ^DIC
  . IF Y'<0 SET IEN=+Y
  IF +IEN'>0 QUIT
  SET (XQDIC,XQY)=+IEN
  KILL DIC,XQUR,Y,^VA(200,DUZ,202.1)
  DO INIT^XQ12
  GOTO M^XQ
  ;
   
And this will indeed allow me to view and interact with menus.  HOWEVER, when I attempt to leave MenuMan, it halts all the way out of mumps, back to a linux prompt.

I next tried using the code that Joe and David recommended, from XT-OPTION TEST.  Here it is below slightly modified.  

E2  
  SET X="EVE"
  SET DIC=19,DIC(0)="MZ" D ^DIC K DIC
  IF Y'>0 QUIT
  SET XQY=+Y
  SET XQUR=$P(Y,U,2)
  SET XQDIC="U"
  SET XQY0=^DIC(19,XQY,0),^("T")=^XUTL("XQ",$J,"T")-1
  G M0^XQ

However, this code crashes when ^XUTL("XQ",$J,"T") is empty, which occurs when some obscure setup doesn't occur.  I got the code to run once, I think, but now I can't replicate it.

I have brought up 2 debugging windows side-by-side, one running my ENTER^TMGXQ1("EVE"), which goes into XQ*.m code, and the other running from DO ^XUP, after EVE is selected.  Both work exactly the same, except for when it comes time to quit out of the code.  My code ends up with a HALT somehow, whereas the other doesn't.  I have run this several times, and the is some slight difference in state that I can't quite figure out. So suddenly the execution path will alter between the two windows, and I can't tell why (yet).

Frustrating.

This seems like a fairly basic functionality, being able to launch MenuMan programatically, and then have execution return to one's own code when it is done.  Has this not been solved before??


Thanks
Kevin

Kevin Toppenberg

unread,
Jul 26, 2022, 6:32:22 PM7/26/22
to Hardhats
Nancy,

Thanks for your reply.  I can bypass MenuMan and perform the menu options myself. But I would like to reuse MenuMan functionality if I can.  However, after struggling with this for too long, I may have to just do it myself.  Thanks again

Kevin

Kevin Toppenberg

unread,
Jul 26, 2022, 7:20:25 PM7/26/22
to Hardhats
Well, I have it running without HALTing out to the Linux prompt.   The highlighted line had to be added below.

I figured this out by copying all the XUP code into my TMGXQ1 file, demonstrating to myself that it worked, and then slowly commenting out lines until it broke.  By this I found that the XQXFLG set was required.

I have tried putting other values, such as "XXX" or "TMGXQ1" in place of "XUP", but they don't work.  Appears to have to be "XUP".  I have searched for all uses of XQXFLG in the XQ*.m, and I can't find anywhere that it is compared to "XUP", so I don't understand how this test is occurring.  Regardless, it works as below. 

Next, I want to figure out how to avoid "logging out" when leaving the MenuMan.  It seems to close all files, etc etc, as if the user is leaving VistA.  I need to figure out how to avoid all that.

Kevin



ENTER(OPT)  ;
  ;"Purpose: Enter Menu Manager
  ;"Input:   OPT -- either a name of OPTION to enter, or IEN of OPTION
  ;"Result: none
  ;"Routine is copied and modified from /r/XQ1.m
  ;
  SET OPT=$GET(OPT)
  NEW IEN SET IEN=+OPT
  IF +OPT'=OPT,OPT'="" DO
  . SET DIC=19,DIC(0)="M",X=OPT DO ^DIC
  . IF Y'<0 SET IEN=+Y
  IF +IEN'>0 QUIT
  SET (XQDIC,XQY)=+IEN
  KILL DIC,XQUR,Y,^VA(200,DUZ,202.1)  
  SET $P(XQXFLG,U,3)="XUP"
  DO INIT^XQ12
  DO
  . GOTO M^XQ
  WRITE !,"BACK!",!
  QUIT
  ;
 
Kevin

Kevin Toppenberg

unread,
Jul 26, 2022, 8:14:28 PM7/26/22
to Hardhats

For the sake of documentation, it appears that MenuMan maintains part of it's state in ^XUTL("XQ",$JOB,*).  For example, see below.  Here $JOB=156653

^XUTL("XQ",156653,0)="3220726.192631^Jul 26, 2022 7:26:31 pm"
^XUTL("XQ",156653,1)="10974P10974^TMG ADAM^Adam^^M^168^^^^^^^212^y"
^XUTL("XQ",156653,2)="10927P10974^TMG VPE MENU^VPE Menu Options^^M^^^^^^^^212^y^"
^XUTL("XQ",156653,3)="11398P10974^TMG VPE UTILITY^TMG VPE UTILITY^^M^^^^^^^^212^y"
^XUTL("XQ",156653,"DUZ")=168
^XUTL("XQ",156653,"T")=2
^XUTL("XQ",156653,"XQM")=10974
^XUTL("XQ",156653,"XQW")=""

Above is after I navigated between menu options ADAM-> TMG VPE MENU -> TMG VPE UTILITY, and then back to TMG VPE MENU

Notice that ^XUTL("XQ",156653,"T")=2 is the current index on the stack, and ^XUTL("XQ",$J,#) are the stack entries.  

When backing up a level in the menus, the "T" node is decreased.  When it reaches 0, then H^XUS is called, which code comments state as " ;Exit point for all applications"

This code is at M3+1^XQ, shown in expanded form.

+72       SET %=^XUTL("XQ",$JOB,"T")-1
           SET ^("T")=%
           IF (%'>0)
               GOTO H^XUS
           SET %=^XUTL("XQ",$JOB,%)
           SET XQY0=$PIECE(%,U,2,999)
           SET XQPSM=$PIECE(%,U,1)
           SET XQY=+XQPSM
           SET XQPSM=$PIECE(XQPSM,XQY,2,99)
           SET XQM3=""
           IF +XQY<0
               DO RBX^XQ73


H^XUS simply just does a GOTO ^XUSCLEAN

At +25^XUSCLEAN, is the following line

I ($D(XQNOHALT)#2)!($D(ZTQUEUED)#2)!($P(XQXFLG,U,3)="XUP") K XQNOHALT,XQXFLG Q ;Return to REST^XQ12, ^XUP or Taskman.

And this explains my prior confusion about why "XUP" was required in XQXFLG.   This caused the code to QUIT, rather than continue and HALT.

However, this check occurs after lots of logging out, shutting down devices etc.  So I am going to modify my XUSCLEAN ad H+1 to add this line:

IF $DATA(TMGXUSCNOHALT) QUIT ;"//kt 7/26/22

which will allow quitting out of MenuMan without unwanted shutdown stuff. 


Next, I didn't want it to ask "DO YOU REALLY WANT TO QUIT" when backing out of the top level of MenuMan, so I modified XPRMP^XQ12 as follows

XPRMP    ;"//kt start mod --------------------
    ;"//kt ORIGINAL --> D CHK^XM W !!,"Do you really want to ",$S(XQUR="REST":"restart",1:"halt"),"? YES// " R X:10 S:'$L(X) X="Y"
    D CHK^XM S X="Y" I $D(TMGXQ12QT)=0 W !!,"Do you really want to ",$S(XQUR="REST":"restart",1:"halt"),"? YES// " R X:10 S:'$L(X) X="Y"
    ;"//kt end mod --------------------


And so here is my final API

ENTER(OPT)  ;
  ;"Purpose: Enter Menu Manager
  ;"Input:   OPT -- either a name of OPTION to enter, or IEN of OPTION
  ;"Result: none
  ;"Routine is copied and modified from /r/XQ1.m
  ;
  SET OPT=$GET(OPT)
  NEW IEN SET IEN=+OPT
  IF +OPT'=OPT,OPT'="" DO
  . SET DIC=19,DIC(0)="M",X=OPT DO ^DIC
  . IF Y'<0 SET IEN=+Y
  IF +IEN'>0 QUIT
  SET (XQDIC,XQY)=+IEN
  KILL DIC,XQUR,Y,^VA(200,DUZ,202.1)  
  NEW TMGXUSCNOHALT SET TMGXUSCNOHALT=1
  NEW TMGXQ12QT SET TMGXQ12QT=1
  ;"Line below not needed if using custom XUSCLEAN and XQ12, but will leave in.
  SET $P(XQXFLG,U,3)="XUP"
  DO INIT^XQ12
  DO
  . GOTO M^XQ
  ;"WRITE !,"AND WE ARE BACK!",!
  QUIT
  ;


Kevin
Reply all
Reply to author
Forward
0 new messages