Page 1 of 1

SNDPGMMSG in Genie

Posted: Wed Sep 03, 2014 4:29 pm
by AjFromADS
I have to change some old code to work with the GUI system. The CL uses quite a bit of SNDPGMMSG. Where does that end up in a Genie session? And how does one go about getting it to work? Thanks.

Re: SNDPGMMSG in Genie

Posted: Wed Sep 03, 2014 5:27 pm
by Scott Klement
I'm not sure that I understand the question.

SNDPGMMSG is a feature of the operating system that sends a message to a program's call-level message queue. It doesn't really have anything to do with Genie at all. Messages go to the message queue you direct them to.

There are some instances, such as message subfiles, where a message will appear on the display. But, again, this works the same in Genie (or a Rich Display for that matter) as it does in other environments.

Likewise, an *ESCAPE message sent with SNDPGMMSG can be used to indicate a program error -- this, if not monitored for, can cause the "Display Program Messages" screen to come up and it might show the message (or a function check) to the user on the display. But, again, this is the same in Genie as it would be in green-screen or anywhere else.

Can you tell us how you're using SNDPGMMSG, and what sort of issues you're having in the Genie session? I think that would help me understand.

Re: SNDPGMMSG in Genie

Posted: Wed Sep 03, 2014 5:47 pm
by AjFromADS
This is what the CL looks like.

SNDRCVF RCDFMT(UB0440A)

IF (&IN12 = '1') THEN(+
DO)
SNDPGMMSG MSG('G/L Monthly Transaction Summary was +
Cancelled.')
GOTO END
ENDDO
IF (&SPRINT = ' ' *AND &SXFER = ' ' *OR &SPRINT = 'X' +
*AND &SXFER = 'X') THEN(CHGVAR &IN31 '1')
ELSE CHGVAR &IN31 '0'
IF (&IN31 = '1' *OR &IN03 = '0') THEN(GOTO GETCHOICE)

IF (&SXFER = 'X') THEN(+
DO)
SNDPGMMSG MSGID(CPF9897) MSGF(QCPFMSG) +
MSGDTA('Saving files as Backup...') +
TOPGMQ(*EXT) MSGTYPE(*STATUS)
SAVOBJ OBJ(UBGLTRPF) LIB(UBDTA) DEV(*SAVF) +
OBJTYPE(*FILE) SAVF(UBDTA/UBGLSV) +
CLEAR(*ALL) SAVACT(*SYSDFN)
SAVOBJ OBJ(PBTHPF PBTDPF) LIB(HWDTA) DEV(*SAVF) +
OBJTYPE(*FILE) SAVF(UBDTA/UBGLPBSV) +
CLEAR(*ALL) SAVACT(*SYSDFN)
SNDPGMMSG MSGID(CPF9897) MSGF(QCPFMSG) +
MSGDTA('Save Complete. Transfering G/L +
Transactions...') TOPGMQ(*EXT) MSGTYPE(*STATUS)
ENDDO

Re: SNDPGMMSG in Genie

Posted: Wed Sep 03, 2014 6:04 pm
by Scott Klement
Okay, thanks for posting that... that helps a lot.

Looks like you are using SNDPGMMSG two different ways in this example. Here's the first one:

Code: Select all

SNDPGMMSG MSG('G/L Monthly Transaction Summary was +
Cancelled.') 
This should work exactly the same in Genie as it does in green-screen. What it does is send an *INFO message to the caller's message queue. If this is called from the command-line or a menu, that will result in the message being displayed at the bottom of the screen. (Should be exactly the same in Genie.)

Here's the other way you are using SNDPGMMSG:

Code: Select all

SNDPGMMSG MSGID(CPF9897) MSGF(QCPFMSG) +
MSGDTA('Saving files as Backup...') +
TOPGMQ(*EXT) MSGTYPE(*STATUS) 
This sends a status message to the job's external (*EXT) message queue. In this instance, Genie will behave a little bit differently than a typical green-screen because Genie is running in a web browser. Normally, when a status message is sent to the external message queue in an interactive job (it's different in a batch job) the OS will print the message at the bottom of the 5250 window. The way it works is that the OS sends a signal to the 5250 emulator to stop displaying the screen that it's currently displaying, and then tells it to re-display the screen with the message on it.

However, in a web browser, we have a bit of a problem. The only time a web server can tell a browser to display a screen is when the browser asks for it. So if a browser says to a server "I want to display the web page at (insert URL here)" the server sends it the proper data, and the browser displays it, and all is well. So that's what happens when the user hits enter or a function key (etc) inside Genie, the browser asks the srever for the next screen to display, and all is well. However, it's not possible for the server to change what's on the browser's display without the browser asking for it. (Imagine if any web server in the world could display something on your screen without you having to first ask to see their web site... that'd be horrible!)

In the case of a status message, though, that's exactly what it'd need to do. The user hasn't clicked anything... so the browser isn't going to ask the server to re-display with the message. It doesn't know that the CL program has sent a status message... only the server knows that, and the server can't initiate the screen display.

So what Genie does is "remember" what the status message is. The next time the user asks for a new screen, Genie will send that message across (unless that part of the screen has been blanked out in the mean time.) But there's no way for Genie to redraw the screen until the user asks for it.

Sorry for the long winded reply... hope it makes sense.

Re: SNDPGMMSG in Genie

Posted: Thu Sep 11, 2014 1:03 pm
by SDeanD
Scott,

We have been testing Profoundui to Upgrade or Legacy application to GUI.

We have some RPG programs that are "Monitor" programs that we currently refresh the display on a timer with new orders. that have not been migrated or tested. I assume we would have to change them to use some Jscript on the page to do the refresh? as the continuous write from RPG would not refresh as the client or browser has not requested them? we are not using Genie. just RPG-OA.

Same would hold true for CL Job Streams that have Displays or Messages that are shown but do not require user input we use the DDS keyword INVITE. This is just to keep the user updated on job progress. I guess again we could use Jscript to auto press enter to continue?

Thanks,
Dean

Re: SNDPGMMSG in Genie

Posted: Thu Sep 11, 2014 1:30 pm
by Scott Klement
Yes, you could use JavaScript code to refresh the screen in either Genie or in a Rich Display.

For example, to automatically "press enter" after 5 seconds, you could do this in your record format's onload event:

Code: Select all

window.saveTimer = setTimeout(function() {
  saveTimer = null;
  pui.click();
}, 5000);
And in the same format's onsubmit event:

Code: Select all

    if (saveTimer != null) {
      clearTimeout(saveTimer);
      saveTimer = null;
    }
The idea is that the browser will run some JavaScript code automatically after a "timeout" has elapsed. In this case, the timeout is set to 5 seconds (5000 is used because intervals are measured in 1/1000 of a second.) When that happens, the pui.click() API will perform the equivalent of the user pressing enter on a Rich Display. (For 5250 displays in Genie, replace pui.click() with pressKey("Enter") -- otherwise Genie is the same.)

You want to cancel that timeout if the user submits the screen before the 5 seconds is up. So that's what the "onsubmit" event does.

If you would prefer to click a button (so you can turn on an indicator to tell the RPG program that it timed out) you can put a button on the display (and optionally hide it, if you don't want the user to click it) and change the pui,click() to pui.click("id-of-the-button") so that it clicks the button and turns on it's response indicator.

Hope that helps. Let me know if there's anything about this that I can explain better.