OpenEdge - Progress ABL: How to open a web browser inside a dialog window - progress-4gl

For the moment i have a code that allow me to open a web browser directly from my Progress application.
DEFINE VARIABLE cProgramName AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPageAddress AS CHARACTER NO-UNDO.
DEFINE VARIABLE iReturnResult AS INTEGER NO-UNDO.
ASSIGN
cProgramName = "C:\Program Files\Internet Explorer\iexplore.exe"
cPageAddress = "http://www.progress.com".
RUN WinExec (INPUT cProgramName + CHR(32) + cPageAddress , INPUT 1, OUTPUT iReturnResult).
PROCEDURE WinExec EXTERNAL "KERNEL32.DLL":
DEFINE INPUT PARAMETER ProgramName AS CHARACTER.
DEFINE INPUT PARAMETER VisualStyle AS LONG.
DEFINE RETURN PARAMETER StatusCode AS LONG.
END PROCEDURE.
Now i want to open the browser inside a dialogue box, pop-up window or a frame. I can't find any code to help me with that !

In AppBuilder, choose "OCX" from the palette. Then drag the "Microsoft Web Browser" Active X Control on your frame.
To navigate to a certain web-page use:
chCtrlFrame:WebBrowser:Navigate ("http://www.progress.com").

Related

Why did my code turn into another language..?

Basically, I touched something in visual studio code that made my .js script turn into a SQL script but the script name is main.js and not main.sql
This is how the file looks:
And this is how the code editor looks:
Also, there is a file name data with a SQL file in it that file is normal I was just practicing SQL was also trying to see if i can store data with SQL for a discord bot
There are multiple ways to fix this:
Firstly you can change the language mode by clicking on the bottom where it says the language mode:
You will then be prompted to change your language mode
You can also do this in the command pallete
Press ctrl + shift + p (by default) and the command prompt will pop up, type change language mode and the option will then appear.
You can also press ctrl + m and then k by default, where you have the ability to change the language mode there

How to change primary command in Edit

I want to add some shortcuts in ISPF Edit.
For instance, I'd like to type T for "TOP" and B for "BOT". How can I do this? I tried to enter
define t alias top
in the command line, but it didn't work: I have "COMMAND TOP NOT FOUND" if I use the shortcut.
How can I achieve this? And how to have this shortcut available each time I open Edit?
A flexible solution would be to create an initial edit macro that does double duty. On first invocation as the initial edit macro, it defines commands such as T and B as aliases to itself. These commands then cause ISPF to invoke the same macro and perform the appropriate action. For this, use the ISPF variable ZEDTMCMD as the main logic driver; it is set by the editor with the command that invoked the macro.
Here is a very general REXX solution called MYMACRO:
/* REXX */
address 'ISREDIT'
parse source . . s3 .
'MACRO' /* You can specify optional arguments if you want */
/* Easier to work with upper case and no leading or trailing blanks */
address 'ISPEXEC' 'VGET (ZEDTMCMD)'
invoke_cmd = translate(strip(zedtmcmd))
select
when invoke_cmd == s3 then do /* first time call */
'DEFINE T ALIAS' s3
'DEFINE B ALIAS' s3
end
when invoke_cmd == 'T' then 'UP MAX'
when invoke_cmd == 'B' then 'DOWN MAX'
otherwise nop
end
exit 0
Next, specify MYMACRO as a initial edit macro. This can be specified in several places, but the easiest is on the main edit panel (option 2).
Note that your macro needs to be in the standard lookup (DD SYSEXEC, SYSPROC, or DD SYSUEXEC or SYSUPROC if ALTLIB is active, or ISPCLIB) to be found.
If you decide to write a program, it is a little bit more complicated. You have to:
prefix the name in the initial edit macro field with an exclamation point ! so ISPF knows to invoke it as a program rather than a script (this means 7 characters maximum for the name);
remove the leading exclamation point before executing the SELECT;
and add 'DEFINE MYMACRO MACRO PGM' as the first line in the first time call logic, so ISPF knows that it is a program, not a script.
In this scenario, when executed as the initial edit macro, ZEDTMCMD will have the leading exclamation point.
By creating one macro, you can make it easier to add new commands in the future.
The ISPF installation SAMPLIB (usually named ISP.SISPSAMP, but it may be different at your installation) has several example macros, all beginning with ISR*. There are REXX scripts, CLISTs, COBOL, and PL/I examples. (No assembler, but creating one is a trivial exercise.)
TOP and BOTTOM are commands in the ISPF command table. They are not EDIT commands. They are ALIAS's for UP MAX and DOWN MAX. An ISPF command must be at least 2 bytes in length, so you can not create a new ALIAS in the command table for UP MAX using a 1 byte character.
You can define an Edit macro called T. The macro could do something like
/* REXX */
address ISREDIT "MACRO"
address ISREDIT "LOCATE 0"
exit(0)
B for BOTTOM could be
/* REXX */
address ISREDIT "MACRO"
address ISREDIT "LOCATE .ZLAST"
exit(0)
Note that B would put you on the last line and not the last full page like BOTTOM actually does. For TOP and BOTTOM I would personally just use PF7 or PF8 with M on the command line to do the max scroll. Its just 1 character with a PFKEY as opposed to the enter key.

programmatically press an enter key after starting .exe file in Matlab

In Matlab I can start external .exe files that sometime have a pop up that requires an enter key pressed. For example:
system('C:\Program Files (x86)\WinZip\WINZIP32.EXE')
will start Winzip, and then in order to use it you need to pass the "buy now" pop up window by pressing enter.
Now my problem is not with winzip, I only gave it as an example (i use winrar anyway :).
How can I programmatically press an enter key in Matlab in such cases ? (I use win 7)
Can an event listener be used to solve that?
EDIT: The java.awt.Robot class indeed works on explorer, but not on any software that has a pop up window with an OK button that needs to be pressed. I don't know why it doesn't work for that. I gave the winzip example because I assume everybody has winzip/winrar installed in their machine. The actual software I have is different and irrelevant for the question.
There is a way using Java from Matlab, specifically the java.awt.Robot class. See here.
Apparently there are two types of programs, regarding the way they work when called from Matlab with system('...'):
For some programs, Matlab waits until the program has finished before running the next statement. This happens for example with WinRAR (at least in my Windows 7 machine).
For other programs this doesn't happen, and Matlab proceeds with the next statement right after the external program has been started. An example of this type is explorer (the standard Windows file explorer).
Now, it is possible to return execution to Matlab immediately even for type 1 programs: just add & at the end of the string passed to system. This is standard in Linux Bash shell, and it also works in Windows, as discussed here.
So, you would proceed as follows:
robot = java.awt.Robot;
command = '"C:\Program Files (x86)\WinRAR\WinRAR"'; %// external program; full path
system([command ' &']); %// note: ' &' at the end
pause(5) %// allow some time for the external program to start
robot.keyPress (java.awt.event.KeyEvent.VK_ENTER); %// press "enter" key
robot.keyRelease (java.awt.event.KeyEvent.VK_ENTER); %// release "enter" key
If your applications are only on Windows platform, you can try using .net objects.
The SendWait method of the SendKeys objects allows to send virtually any key, or key combination, to the application which has the focus, including the "modifier" keys like Alt, Shift, Ctrl etc ...
The first thing to do is to import the .net library, then the full syntax to send the ENTER key would be:
NET.addAssembly('System.Windows.Forms');
System.Windows.Forms.SendKeys.SendWait('{ENTER}'); %// send the key "ENTER"
If you only do it once the full syntax is OK. If you plan to make extensive use of the command, you can help yourself with an anonymous helper function.
A little example with notepad
%% // import the .NET assembly and define helper function
NET.addAssembly('System.Windows.Forms');
sendkey = #(strkey) System.Windows.Forms.SendKeys.SendWait(strkey) ;
%% // prepare a few things to send to the notepad
str1 = 'Hello World' ;
str2 = 'OMG ... my notepad is alive' ;
file2save = [pwd '\SelfSaveTest.txt'] ;
if exist(file2save,'file')==2 ; delete(file2save) ; end %// this is just in case you run the test multiple times.
%% // go for it
%// write a few things, save the file then close it.
system('notepad &') ; %// Start notepad, without matlab waiting for the return value
sendkey(str1) %// send a full string to the notepad
sendkey('{ENTER}'); %// send the {ENTER} key
sendkey(str2) %// send another full string to the notepad
sendkey('{! 3}'); %// note how you can REPEAT a key send instruction
sendkey('%(FA)'); %// Send key combination to open the "save as..." dialog
pause(1) %// little pause to make sure your hard drive is ready before continuing
sendkey(file2save); %// Send the name (full path) of the file to save to the dialog
sendkey('{ENTER}'); %// validate
pause(3) %// just wait a bit so you can see you file is now saved (check the titlebar of the notepad)
sendkey('%(FX)'); %// Bye bye ... close the Notepad
As explained in the Microsoft documentation the SendKeys class may have some timing issues sometimes so if you want to do complex manipulations (like Tab multiple times to change the button you actually want to press), you may have to introduce a pause in your Matlab calls to SendKeys.
Try without first, but don't forget you are managing a process from another without any synchronization between them, so timing all that can require a bit of trial and error before you get it right, at least for complex sequences (simple one should be straightforward).
In my case above for example I am running all my data from an external hard drive with an ECO function which puts it into standby, so when I called the "save as..." dialog, it takes time for it to display because the HDD has to wake up. If I didn't introduce the pause(1), sometimes the file path would be imcomplete (the first part of the path was send before the dialog had the focus).
Also, do not forget the & character when you execute the external program. All credit to Luis Mendo for highlighting it. (I tend to forget how important it is because I use it by default. I only omit it if I have to specifically wait for a return value from the program, otherwise I let it run on its own)
The special characters have a special code. Here are a few:
Shift +
Control (Ctrl) ^
Alt %
Tab {TAB}
Backspace {BACKSPACE}, {BS}, or {BKSP}
Validation {ENTER} or ~ (a tilde)
Ins Or Insert {INSERT} or {INS}
Delete {DELETE} or {DEL}
Text Navigation {HOME} {END} {PGDN} {PGUP}
Arrow Keys {UP} {RIGHT} {DOWN} {LEFT}
Escape {ESC}
Function Keys {F1} ... {F16}
Print Screen {PRTSC}
Break {BREAK}
The full list from Microsoft can be found here
There is a small javascript utility that simulates keystrokes like this on the Windows javascript interpreter.
Just create a js file with following code:
var WshShell = WScript.CreateObject("WScript.Shell");
WshShell.SendKeys(WScript.Arguments(0));
then call it from Matlab after the necessary timeout like this:
system('c:\my\js\file\script.js {Enter}');
Can't test here now, but I think this should work...
If you need to run a console-only program in a context that permits full DOS redirection, you can create a file called, say, CR.txt containing a carriage return and use the '<' notation to pipe the value into the program.
This only works if you can provide all the keyboard input can be recorded in the file. It fails dismally if the input has to vary based on responses.
An alternative is to duplicate the input (and possibly output) stream(s) for the program and then pipe data into and out of the program. This is more robust and can permit dynamic responses to the data, but will also likely require substantial effort to implement a robot user to the application.
Rog-O-Matic is an example of a large application completely controlled by a program that monitors screen output and simulates keyboard input to play an early (1980s) ASCII graphic adventure game.
The other responses will be required for GUI-based applications.
Python package pywinauto can wait any dialog and click buttons automatically. But it's capable for native and some .NET applications only. You may have problems with pressing WPF button (maybe QT button is clickable - not checked), but in such case code like app.DialogTitle.wait('ready').set_focus(); app.DialogTitle.type_keys('{ENTER}') may help. Your case is quite simple and probably some tricks with pywinauto are enough. Is your "app with popup" 64-bit or 32-bit?
wait and wait_not functions have timeout parameter. But if you need precisely listener with potentially infinite loop awaiting popups, good direction is global Windows hooks (pyHook can listen mouse and keybd events, but cannot listen dialog opening). I'll try to find my prototype that can detect new windows. It uses UI Automation API event handlers... and... ops... it requires IronPython. I still don't know how to set UI Automation handler with COM interface from standard CPython.
EDIT (2019, January): new module win32hooks was implemented in pywinauto a while ago. Example of usage is here: examples/hook_and_listen.py.

How can I run a Perl script through an ActiveX Control within Excel?

I want to run a Perl script at the click of a button inside an Excel spreadsheet.
As the button is assigned to execute a VB macro, the macro should effectively execute the program.
As my first ever VB script, this is what I came up with, which throws up an irritating Run-time error '424': Object required error.
Sub RunPerlScript()
System.Diagnostics.process.Start ("perlscript.pl")
End Sub
How can I get this script to do what I want it to do?
I didn't write this snippet, but it would seem to be a good answer to your question.
From the article "How to execute a perl script from VBA":
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Sub RunPerl()
MsgBox ("Start of macro")
Dim oWsc As Object
Set oWsc = CreateObject("WScript.Shell")
Dim oExec As Object
Set oExec = oWsc.Exec("perl C:\temp\myperl.pl StartParam")
While oExec.Status <> 1 ' Wait for process
Sleep 1000
Wend
MsgBox ("STDOUT" + oExec.StdOut.ReadAll())
MsgBox ("STDERR" + oExec.StdErr.ReadAll())
Set oWsc = Nothing
MsgBox ("End of macro")
End Sub
You might need to install ActivePerl first
You cannot use .NET classes in a VBA macro.
Use the VBA Shell function.
Shell "p:\ath\to\perlscript.pl"
The documentation:
Shell Function
Runs an executable program and returns
a Variant (Double) representing the
program's task ID if successful,
otherwise it returns zero.
Syntax
Shell(pathname[,windowstyle])
The Shell function syntax has these
named arguments:
Part Description pathname Required;
Variant (String). Name of the program
to execute and any required arguments
or command-line switches; may include
directory or folder and drive. On the
Macintosh, you can use the MacID
function to specify an application's
signature instead of its name. The
following example uses the signature
for Microsoft Word: Shell
MacID("MSWD") windowstyle Optional.
Variant (Integer) corresponding to the
style of the window in which the
program is to be run. If windowstyle
is omitted, the program is started
minimized with focus. On the Macintosh
(System 7.0 or later), windowstyle
only determines whether or not the
application gets the focus when it is
run.
The windowstyle named argument has
these values:
Constant Value Description vbHide 0
Window is hidden and focus is passed
to the hidden window. The vbHide
constant is not applicable on
Macintosh platforms. vbNormalFocus 1
Window has focus and is restored to
its original size and position.
vbMinimizedFocus 2 Window is displayed
as an icon with focus.
vbMaximizedFocus 3 Window is maximized
with focus. vbNormalNoFocus 4 Window
is restored to its most recent size
and position. The currently active
window remains active.
vbMinimizedNoFocus 6 Window is
displayed as an icon. The currently
active window remains active.
ActiveState's PDK has PerlCtrl which lets you package a perl script as an ActiveX control. It gathers up your script and all dependencies into a tidy DLL.

Modify cmd.exe properties using the command prompt

Isn't that nicely recursive?
I've got a portable command prompt on my external drive, and it has a nice .bat file to configure some initial settings, but I'd like more!
Here's what I know how to set from .bat:
Colors = (color XY) where x and y are hex digits for the predefined colors
Prompt = (prompt $p$g) sets the prompt to "C:\etc\etc >" the default prompt
Title = (title "text") sets the window title to "text"
Screen Size = (mode con: cols=XX lines=YY) sets the columns and lines size of the window
Path = (SET PATH=%~d0\bin;%PATH%) sets up local path to my tools and appends the computer's path
So that's all great. But there are a few settings I can't seem to set from the bat. Like, how would I set these up wihtout using the Properties dialogue:
Buffer = not screen size, but the buffer
Options like quick edit mode and autocomplete
Popup colors
Font. And can you use a font on the portable drive, or must it be installed to work?
Command history options
Regarding setting the buffer size:
Using mode con: cols=XX lines=YY sets not only the window (screen) size, but the buffer size too.
If you specify a size allowed by your system, based on available screen size, you'll see that both window and buffer dimension are set to the same value; .e.g:
mode con: cols=100 lines=30
results in the following (values are the same):
window size: Width=160, Height=78
buffer size: Width=160, Height=78
By contrast, if you specify values that are too large based on the available screen size, you'll see that the window size changes to its maximum, but the buffer size is changed to the values as specified.
mode con: cols=1600 lines=900
With a screen resolution of 1280x1024, you'll get:
window size: Width=160, Height=78
buffer size: Width=1600, Height=900
You can set these values through a shortcut (.INK file).
I have a shortcut on my desktop with this as the target:
%windir%\system32\cmd.exe /K %userprofile%\STARTUP.CMD
The /K switch tells CMD.exe to run the batch file (which sets some variables, the prompt, etc.) and then stay open.
If you right-click on the shortcut and view its properties, you can set the window and buffer size, popup colors, starting position (x,y axis), etc. The settings will be saved in the shortcut itself and will be applied every time you open CMD.exe using that shortcut.
Regarding auto-completion:
File and Directory name completion is
NOT enabled by default. You can
enable or disable file name completion
for a particular invocation of CMD.EXE
with the /F:ON or /F:OFF switch. You
can enable or disable completion for
all invocations of CMD.EXE on a
machine and/or user logon session by
setting either or both of the
following REG_DWORD values in the
registry using REGEDT32.EXE:
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\CompletionChar
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\PathCompletionChar
and/or
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\CompletionChar
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\PathCompletionChar
with the hex value of a control
character to use for a particular
function (e.g. 0x4 is Ctrl-D and 0x6
is Ctrl-F). The user specific
settings take precedence over the
machine settings. The command line
switches take precedence over the
registry settings.
If completion is enabled with the
/F:ON switch, the two control
characters used are Ctrl-D for
directory name completion and Ctrl-F
for file name completion. To disable
a particular completion character in
the registry, use the value for space
(0x20) as it is not a valid control
character.
Couldn't find any command history options in there ( cmd /? ), and it looks like the other options you asked about are set exclusively through registry settings.
For true Buffer Size adjustment use DOSKEY /LISTSIZE=size
You can't change colors within the shell anymore since Microsoft took ANSI ESC control out of the command/cmd prompts.