Progress
External Program
Interfaces


Examples

The following procedure uses the Progress MESSAGE statement to display a message in an alert box. It then calls the MessageBoxA routine from user32.dll to display the same message in an identical alert box:

e-dllex1.p
/* e-dllex1.p */

DEFINE VARIABLE result AS INTEGER
  MESSAGE "   It’s a whole new world!"
  VIEW-AS
    ALERT-BOX MESSAGE
    BUTTONS OK
    TITLE "Progress DLL Access".

RUN MessageBoxA (0, "   It’s A Whole New World!",
  "Progress DLL Access - from the DLL!", 0, OUTPUT result).

PROCEDURE MessageBoxA EXTERNAL "user32.dll":
    DEFINE INPUT PARAMETER hwnd AS LONG.
    DEFINE INPUT PARAMETER mbtext AS CHARACTER.
    DEFINE INPUT PARAMETER mbtitle AS CHARACTER.
    DEFINE INPUT PARAMETER style AS LONG.
    DEFINE RETURN PARAMETER result AS LONG.
END. 

The following procedure uses the sndPlaySoundA routine from winmm.dll. The procedure allows the user to select a sound to play and then invokes the DLL routine to play the sound. The DLL routine takes two input parameters and returns a status code:

e-dllex2.p
DEFINE VARIABLE wave-name AS CHARACTER INITIAL ? NO-UNDO.
DEFINE VARIABLE play-status AS INTEGER.

SYSTEM-DIALOG GET-FILE wave-name
  TITLE "Choose the Sound"
  FILTERS "Wave Files (*.wav)" "*.wav"
  MUST-EXIST USE-FILENAME.

RUN sndPlaySoundA (INPUT wave-name, INPUT 2,
                 OUTPUT play-status).

PROCEDURE sndPlaySoundA EXTERNAL "winmm.dll":
  DEFINE INPUT PARAMETER ic AS CHARACTER.
  DEFINE INPUT PARAMETER ish AS LONG.
  DEFINE RETURN PARAMETER osh AS LONG.
END PROCEDURE. 

NOTE: You must have a sound driver installed on your machine to play sounds.

The following code sample demonstrates calling the C library function “atoi” to get the value of the character form of an integer. The declaration of the C function being called looks like this: int atoi(const char *str):

PROCEDURE atoi EXTERNAL "/usr/lib/libc.so.1" :
   DEFINE INPUT PARAMETER b AS MEMPTR.
   DEFINE OUTPUT PARAMETER ret-val AS SHORT.
END PROCEDURE.

DEFINE VARIABLE in-string AS MEMPTR.
DEFINE VARIABLE out-int AS INTEGER INITIAL 0.

SET-SIZE(in-string) = 10.
PUT-STRING(in-string, 1) = "150".

RUN ATOI( INPUT in-string, OUTPUT out-int).

MESSAGE "ATOI RESULT: " out-int VIEW-AS ALERT-BOX. 

The following procedure defines and displays a shaded ellipse in the current window using DLL functions from the Windows graphics library. This requires initialization of a small structure (ElipRegion).

Note that Progress has no knowledge of any graphics that you create using DLLs. You must ensure that Progress does not refresh the window you are using while the graphics are displayed. Otherwise, the graphics disappear during a window system refresh. (You can help to mitigate this by providing a graphics refresh option within your Progress application.) This procedure displays a preparatory message (“Preparing drawing”), and pauses to realize the current window before calling the DLL routines that display the filled ellipse. The procedure pauses by default before it terminates, allowing the ellipse to remain on the display:

e-dllex3.p
/* DLL routine to create an elliptic region */

PROCEDURE CreateEllipticRgnIndirect EXTERNAL "gdi32.dll":
  DEFINE RETURN PARAMETER RegionHandle AS LONG.
  DEFINE INPUT PARAMETER RegionSpec AS MEMPTR.
END PROCEDURE.

/* DLL routine to get drawing object */

PROCEDURE GetStockObject EXTERNAL "gdi32.dll":
  DEFINE RETURN PARAMETER ObjectHandle AS LONG.
  DEFINE INPUT PARAMETER ObjectType AS LONG.
END PROCEDURE.

/* DLL routine to select region into device context */

PROCEDURE SelectObject EXTERNAL "gdi32.dll":
  DEFINE INPUT PARAMETER DeviceHandle AS LONG.
  DEFINE INPUT PARAMETER ObjectHandle AS LONG.
END PROCEDURE.

/* DLL routine to display region */

PROCEDURE PaintRgn EXTERNAL "gdi32.dll":
  DEFINE INPUT PARAMETER DeviceHandle AS LONG.
  DEFINE INPUT PARAMETER RegionHandle AS LONG.
END PROCEDURE. 
/* DLL routine to get handle of window device context */

PROCEDURE GetDC EXTERNAL "user32.exe":
  DEFINE RETURN PARAMETER DeviceHandle AS LONG.
  DEFINE INPUT PARAMETER WindowHandle AS LONG.
END PROCEDURE.

/* DLL routine to release device context handle */

PROCEDURE ReleaseDC EXTERNAL "user32.exe":
  DEFINE INPUT PARAMETER DeviceHandle AS LONG.
END PROCEDURE.

/* DLL routine to delete elliptic region */

PROCEDURE DeleteObject EXTERNAL "gdi32.dll":
  DEFINE INPUT PARAMETER RegionHandle AS LONG.
END PROCEDURE.

/* Variable Definitions */

DEFINE VARIABLE ElipRegion AS MEMPTR. /* Elliptic region structure */
DEFINE VARIABLE hDevice AS INTEGER.   /* Device context handle   */
DEFINE VARIABLE hObject AS INTEGER.   /* Drawing object handle   */
DEFINE VARIABLE hRegion AS INTEGER.   /* Elliptic region handle  */

DEFINE VARIABLE erLeft AS INTEGER INITIAL 1.    /* Elliptic   */
DEFINE VARIABLE erTop AS INTEGER INITIAL 5.    /* Coordinates */
DEFINE VARIABLE erRight AS INTEGER INITIAL 9.
DEFINE VARIABLE erBottom AS INTEGER INITIAL 13.

/* Allocate and build elliptic region structure */
/* specifying rectangular coordinates of region */

SET-SIZE(ElipRegion) = 4  /* int left   */
                     + 4  /* int top    */
                     + 4  /* int right  */
                     + 4  /* int bottom */
                       . 
PUT-LONG(ElipRegion, erLeft) = 50.
PUT-LONG(ElipRegion, erTop) = 50.
PUT-LONG(ElipRegion, erRight) = 200.
PUT-LONG(ElipRegion, erBottom) = 100.

/* Initialize current window with PAUSE */
/* and display perfunctory message      */

DISPLAY "Preparing drawing..." .
PAUSE.

/* Get device context, region, and drawing object handles */

RUN GetDC (OUTPUT hDevice, INPUT CURRENT-WINDOW:HWND).
RUN CreateEllipticRgnIndirect(OUTPUT hRegion, INPUT ElipRegion).
RUN GetStockObject(OUTPUT hObject, INPUT 4).

/* Select drawing object and region for device context, */
/* and paint region                                     */

RUN SelectObject(INPUT hDevice, INPUT hObject).
RUN SelectObject(INPUT hDevice, INPUT hRegion).
RUN PaintRgn(INPUT hDevice, INPUT hRegion).

/* Free resources */

SET-SIZE(ElipRegion) = 0.         /* Free region structure  */
RUN ReleaseDC (INPUT CURRENT-WINDOW:HWND, INPUT hDevice).
                                 /* Release device context */
RUN DeleteObject(INPUT hRegion).  /* Delete elliptic region */

/* Wait for user to close window or hit Escape */
WAIT-FOR WINDOW-CLOSE OF CURRENT-WINDOW. 


Copyright © 2004 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095