This collection of code snippets used to be hosted on www.global-shared.com.
It is an old collection: it all began in 1996 or 1997, when Progress 8 was new and many of us were still using Windows 3.1 !!
Unlike wine or paintings, program code doesn't get better when it ages. You can find fragments that can be improved because Microsoft continuously expands their API, or are outdated because Progress has added features to the ABL so we don't need to use the WIN32 API anymore.
This example reads the toggle states of the three most commonly used toggle keys: Capslock, Numlock and Insert. The example also changes these three toggle states: you will see the LED's on your keyboard change.
The GetKeyboardState procedure fetches the keystates of 256 keys at once. There's also a GetKeyState procedure to fetch the state for 1 particular key, but there is no SetKeyState procedure for one key so if you need to change a keystate you will have to use SetKeyboadState and set them all.
{windows.i} DEFINE VARIABLE CapsLockToggle AS LOGICAL. DEFINE VARIABLE NumLockToggle AS LOGICAL.
by Stuart Morris
Usefull when that process really should not be interupted. Note: It can cripple the PC
&GLOBAL-DEFINE A A &GLOBAL-DEFINE SPI_SCREENSAVERRUNNING 97 DEFINE VARIABLE retVal AS INTEGER NO-UNDO. DEFINE VARIABLE lv-dummy AS INTEGER NO-UNDO. PROCEDURE SystemParametersInfo{&A} EXTERNAL "USER32.DLL":U : DEFINE INPUT PARAMETER uAction AS LONG NO-UNDO. DEFINE INPUT PARAMETER uParam AS LONG NO-UNDO. DEFINE INPUT PARAMETER lpvParam AS LONG NO-UNDO. DEFINE INPUT PARAMETER fuWinIni AS LONG NO-UNDO. DEFINE OUTPUT PARAMETER retVal AS LONG NO-UNDO.
The Tapi (Telephony API) can be used to dial a telephone number or pager.
This source is from Johann van der Merwe.
His introduction says:
This is an example of what we use. The code is not cleaned up. We also
use our own dialing properties (for instance a outside line). Hope this
helps. Use MSDN to look up tapiRequestMakeCall for parameter info.
DEFI: DO ON ERROR UNDO, RETURN "ERROR-DEFI":U: DEFINE INPUT PARAMETER TelNoStr AS CHARACTER NO-UNDO. DEFINE VARIABLE GetLine AS CHARACTER NO-UNDO. DEFINE VARIABLE TelNo AS MEMPTR NO-UNDO. DEFINE VARIABLE i AS INTEGER NO-UNDO.
By Johann van der Merwe.
PROCEDURE MapiReturnCode : INPUT PARAMETER ResultInt AS INTEGER. /* result from MAPISendMail */ DEFINE VARIABLE RESULT AS CHARACTER NO-UNDO. IF ResultInt <> 0 THEN DO: /* 0 = Success */ CASE ResultInt: WHEN 1 THEN RESULT = "User Abort". WHEN 2 THEN RESULT = "Failure". WHEN 3 THEN RESULT = "Login Failure". WHEN 4 THEN RESULT = "Disk Full". WHEN 5 THEN RESULT = "Insufficient Memory". WHEN 6 THEN RESULT = "Blk Too Small". WHEN 8 THEN RESULT = "Too Many Sessions". WHEN 9 THEN RESULT = "Too Many Files".
There are many ways to send email, smtpmail.p from freeframework.org is known to be very good.
In the past there have been many quesions about Outlook. Here is one code snippet, seen on Peg in an email from John Lubenow (I hope we have permission to use this, if not just delete this topic and let me know please)
/** Send Outlook Mail **/ DEFINE INPUT PARAMETER mailto AS CHARACTER FORMAT "x(30)". DEFINE INPUT PARAMETER mailcc AS CHARACTER FORMAT "x(30)". DEFINE INPUT PARAMETER subject AS CHARACTER FORMAT "x(50)". DEFINE INPUT PARAMETER body AS CHARACTER FORMAT "x(255)". DEFINE VARIABLE chOutlook AS COM-HANDLE NO-UNDO.
There are different kinds of solutions for using Email from Progress. For example, there are several ActiveX components, there is a Progress 7+8 product with source made by Ketil Parow (you can download a trial version at http:www.sn.no/~ketilp/misc/mapi.zip), you can use the MAPI OLE automation server (there is a document about that on the ActiveX pages on www.dotr.com) or you can use the MAPI through its native API. On this site we'll only discuss the API kind of solutions.
The next sourcecode example was posted by Jeff Ledbetter and was earlier found in Profiles. I ported it to 32-bit.
This solution is made by Johann van der Merwe.
It allows one attachment.
{windows.i} RUN mapi ( "you@work.com", "yourwife@home.com", "late for dinner", "something came up..", "c:\images\flowers.bmp" ). /* ========================================================================== */ PROCEDURE MAPI : DEFINE INPUT PARAMETER OriginName AS CHARACTER. DEFINE INPUT PARAMETER RecipName AS CHARACTER. DEFINE INPUT PARAMETER Subject AS CHARACTER. DEFINE INPUT PARAMETER Bodytext AS CHARACTER. DEFINE INPUT PARAMETER FilePathName AS CHARACTER.
Some articles about how to send, or read e-mail from within Progress
Suppose there is a registry key
HKEY_LOCAL_MACHINE\Software\Nerdware\Test
and suppose it contains a DWORD value, named "count".
This source example will read the value of "count", identifies the datatype, and increment the value of "count" by one.
{windows.i} /* March 28, 1998 or later */ DEFINE VARIABLE key-hdl AS INTEGER NO-UNDO. DEFINE VARIABLE lpBuffer AS MEMPTR NO-UNDO. DEFINE VARIABLE lth AS INTEGER NO-UNDO. DEFINE VARIABLE reslt AS INTEGER NO-UNDO. DEFINE VARIABLE datatype AS INTEGER NO-UNDO. DEFINE VARIABLE icount AS INTEGER NO-UNDO.
This example enumerates all values in a given registry key.
In this case, it will return a list of all installed printers (with their names and ports), so it actually does the same as the EnumPrinters function.
As explained in the registry introduction you should prefer to use the EnumPrinters function instead of this RegEnumA stuff, because Microsoft may decide to store the printers info elsewhere in the future, while the EnumPrinters API will be maintained.
{windows.i} /* March 28, 1998 or later */ DEFINE VARIABLE hKey AS INTEGER NO-UNDO. DEFINE VARIABLE hPrinterkey AS INTEGER NO-UNDO.
Function RegCreateKeyEx creates a registry key and opens it. If the key already exists, the function will just open it.
{windows.i} &SCOPED-DEFINE KEY_ALL_ACCESS 983103 &SCOPED-DEFINE REG_OPTION_NON_VOLATILE 0 &SCOPED-DEFINE REG_OPTION_VOLATILE 1 &SCOPED-DEFINE REG_CREATED_NEW_KEY 1 &SCOPED-DEFINE REG_OPENED_EXISTING_KEY 2 PROCEDURE RegCreateKeyEx{&A} EXTERNAL {&ADVAPI} : DEFINE INPUT PARAMETER hkey AS LONG. DEFINE INPUT PARAMETER lpszSubKey AS CHARACTER. DEFINE INPUT PARAMETER dwReserved AS LONG.
There are P4GL functions for setting and getting registry information. I am not familiar with those P4GL functions so it may be silly to use Windows functions instead.
One thing the P4GL can not do is accessing (hexa)decimal data.
Before you try to access the registry directly you should try to find some specialized API call for the requested information type.
For example:
You can read a list of available printers from the registry, but you can also use the EnumPrinters API function for this task. It is generally speaking better to use the API function, because these are documented while the exact registry-locations are not. The EnumPrinters example is only one example. I don't know, but I guess there are documented functions for everything in the registry.
The 'name' field (in a login dialog) can be initialized with the name by which the user is known in Windows.
You can try to find this name in the registry but you better let Windows do it for you, using the GetUserName function.
{windows.i} DEFINE VARIABLE NAME AS CHARACTER NO-UNDO. RUN WinUserName(OUTPUT NAME). fill-in_name:SCREEN-VALUE = NAME. PROCEDURE WinUserName : DEFINE OUTPUT PARAMETER NAME AS CHARACTER. DEFINE VARIABLE nr AS INTEGER NO-UNDO INITIAL 100. DEFINE VARIABLE ReturnValue AS INTEGER NO-UNDO. NAME = FILL(" ", nr). RUN GetUserName{&A} IN hpApi (INPUT-OUTPUT NAME,