Progress Indicator Widget and OCX Replacement¶
The 4GL doesn't offer a progress bar control out of the box. As a workaround slider widget can be used as a replacement. Another solution we have seen at our customers was the use of OCX controls. The commonly used ones is Microsoft's ProgressBar from the Windows Common Control library.
PROGRESS-BAR¶
To simplify the modernization of applications that use OCX components, which are bound to the Windows OS and can't be easily moved in the web, we implemented a PROGRESS-BAR widget as an extension to the 4GL language. The widget can be used as any other 4GL widget, see below for an example.
DEFINE VARIABLE hProgBar AS HANDLE NO-UNDO. CREATE PROGRESS-BAR hProgBar ASSIGN FRAME = FRAME F:HANDLE ROW = 3.62 COLUMN = 5 HEIGHT = 1.2 WIDTH = 104 VISIBLE = TRUE. /* PROGRESS-BAR methods and attributes */ hProgBar:OLE-DROP-MODE = 1. hProgBar:PB-APPEARANCE = 1. hProgBar:PB-BORDER-STYLE = 0. hProgBar:PB-ORIENTATION = 0. hProgBar:PB-SCROLLING = 1. hProgBar:PB-MAX = 100. hProgBar:PB-MIN = 0. hProgBar:PB-VALUE = 30. hProgBar:PB-MOUSE-POINTER = 3. hProgBar:OLE-DRAG(). hProgBar:PB-REFRESH(). /* PROGRESS-BAR mouse events */ ON "MOUSE-CLICK" OF hProgBar DO: MESSAGE "Click!". END.
The extension only exists in FWD, it doesn't work in OpenEdge. The API of the PROGRESS-BAR widget is compliant with Microsoft ProgressBar OCX (VB 6.0 common control). This make the conversion process more straightforward.
Attributes¶
Attribute Name | OCX Name | Handle Type | Return Type | Read Only | Default | Description |
---|---|---|---|---|---|---|
PB-APPEARANCE | Appearance | PROGRESS-BAR | INTEGER | N | 0 | Returns/sets whether or not controls, Forms or an MDIForm are painted at runtime with 3-D effects. AppearanceConstants: cc3D=1 ccFlat=0 |
PB-BORDER-STYLE | BorderStyle | PROGRESS-BAR | INTEGER | N | 0 | Returns/sets border style for an object. BorderStyleConstants - ccFixedSingle=1 ccNone=0 |
PB-ENABLED | Enabled | PROGRESS-BAR | LOGICAL | N | FALSE | Returns/sets a value that determines whether the control can respond to user-generated events. |
PB-MIN | Min | PROGRESS-BAR | DECIMAL | N | 0.0 | Returns/sets a control's minimum value. |
PB-MAX | Max | PROGRESS-BAR | DECIMAL | N | 100.0 | Returns/sets a control's maximum value. |
PB-VALUE | Value | PROGRESS-BAR | DECIMAL | N | 0.0 | Returns or sets a control's current Value property |
PB-MOUSE-ICON | MouseIcon | PROGRESS-BAR | CHARACTER | N | UNKNOWN | Sets a custom mouse icon. |
PB-MOUSE-POINTER | MousePointer | PROGRESS-BAR | INTEGER | N | 0 | Returns/sets the type of mouse pointer displayed when over part of an object. MousePointerConstants - ccArrow=1 ccArrowHourglass=13 ccArrowQuestion=14 ccCross=2 ccCustom=99 ccDefault=0 ccHourglass=11 ccIBeam=3 ccIcon=4 ccNoDrop=12 ccSize=5 ccSizeAll=15 ccSizeEW=9 ccSizeNESW=6 ccSizeNS=7 ccSizeNWSE=8 ccUpArrow=10 |
OLE-DROP-MODE | OLEDropMode | PROGRESS-BAR | INTEGER | N | 0 | Returns/Sets whether this control can act as an OLE drop target. OLEDropConstants - ccOLEDropManual=1 ccOLEDropNone=0 |
PB-ORIENTATION | Orientation | PROGRESS-BAR | INTEGER | N | 0 | Returns/sets a value that determines whether the Progress Bar is displayed vertically or horizontally. OrientationConstants - ccOrientationHorizontal=0 ccOrientationVertical=1 |
PB-SCROLLING | Scrolling | PROGRESS-BAR | INTEGER | N | 0 | Returns/sets a value that determines whether the control displays progress with a standard segmented bar or a smooth bar. ScrollingConstants - ccScrollingSmooth=1 ccScrollingStandard=0 |
Methods¶
Method Name | OCX Name | Handle Type | Return Type | Parameters | Description |
---|---|---|---|---|---|
OLE-DRAG | OLEDrag | PROGRESS-BAR | NO-RETURN-VALUE | N/A | Start an OLE drag/drop event with the given control as the source. |
PB-REFRESH | Refresh | PROGRESS-BAR | NO-RETURN-VALUE | N/A | Refresh control. |
Mouse events¶
Event Name | OCX Name | Affected Widget | Description |
---|---|---|---|
MOUSE-CLICK | Click | PROGRESS-BAR | Triggered when mouse is clicked |
MOUSE-DOWN | MouseDown | PROGRESS-BAR | Triggered when one of the mouse button is down. |
MOUSE-MOVE | MouseMove | PROGRESS-BAR | Triggered when mouse pointer is moved over control area. |
MOUSE-UP | MouseUp | PROGRESS-BAR | Triggered when one of the mouse button is up. |
The OCX procedures to handle mouse events looks like:
PROCEDURE <event-proc-prefix>.Click : END PROCEDURE. PROCEDURE <event-proc-prefix>.MouseDown : DEFINE INPUT PARAMETER Button AS INTEGER. DEFINE INPUT PARAMETER Shift AS INTEGER. DEFINE INPUT PARAMETER x AS INTEGER. DEFINE INPUT PARAMETER y AS INTEGER. END PROCEDURE. PROCEDURE <event-proc-prefix>.MouseMove : DEFINE INPUT PARAMETER Button AS INTEGER. DEFINE INPUT PARAMETER Shift AS INTEGER. DEFINE INPUT PARAMETER x AS INTEGER. DEFINE INPUT PARAMETER y AS INTEGER. END PROCEDURE. PROCEDURE <event-proc-prefix>.MouseUp : DEFINE INPUT PARAMETER Button AS INTEGER. DEFINE INPUT PARAMETER Shift AS INTEGER. DEFINE INPUT PARAMETER x AS INTEGER. DEFINE INPUT PARAMETER y AS INTEGER. END PROCEDURE.
OCX mouse events procedures parameters:
Attribute Name | OCX Name | Handle Type | Return Type | Read Only | Description |
---|---|---|---|---|---|
OCX-MOUSE-BUTTON | Button | PROGRESS-BAR | INTEGER | Y | Returns which, if any, of the mouse buttons has changed state. |
OCX-SHIFT | Shift | PROGRESS-BAR | INTEGER | Y | Returns state of all modal keys, such as ALT, CTRL, META, and the mouse buttons just after the event occurred. |
OCX-MOUSE-X | x | PROGRESS-BAR | INTEGER | Y | Returns the horizontal x position of the event relative to the source component. |
OCX-MOUSE-Y | y | PROGRESS-BAR | INTEGER | Y | Returns the vertical y position of the event relative to the source component. |
When PROGRESS-BAR is used like a 4gl extension widget a typical definition of mouse events triggers looks like:
on "mouse-click" of progBar do: message "Click!". end. on "mouse-down" of progBar do: define variable Button as integer. define variable Shift as integer. define variable x as integer. define variable y as integer. Button = progBar:ocx-mouse-Button. Shift = progBar:ocx-mouse-Shift. x = progBar:ocx-mouse-x. y = progBar:ocx-mouse-y. message "MouseDown!" x y Button Shift. end. on "mouse-move" of progBar do: define variable Button as integer. define variable Shift as integer. define variable x as integer. define variable y as integer. Button = progBar:ocx-mouse-Button. Shift = progBar:ocx-mouse-Shift. x = progBar:ocx-mouse-x. y = progBar:ocx-mouse-y. message "MouseMove!" x y Button Shift. end. on "mouse-up" of progBar do: define variable Button as integer. define variable Shift as integer. define variable x as integer. define variable y as integer. Button = progBar:ocx-mouse-Button. Shift = progBar:ocx-mouse-Shift. x = progBar:ocx-mouse-x. y = progBar:ocx-mouse-y. message "MouseUp!" x y Button Shift. end.
OLE Drag & Drop events¶
Event Name | OCX Name | Affected Widget | Description |
---|---|---|---|
OLE-START-DRAG | OLEStartDrag | PROGRESS-BAR | Occurs when an OLE drag-drop operation is initiated either manually or automatically. This event is initiated as soon as the control's OLEDrag() method is invoked. If a value is not assigned to the Data parameter then the GetData method of the DataObject initiates the OLESetData event to obtain the data. |
OLE-SET-DATA | OLESetData | PROGRESS-BAR | Occurs at the drag-drop source control when the drop target requests data that was not provided to the DataObject. This event is initiated when the target control requests data and the DataObject does not have data for that format because delayed rendering was used in the OLEStartDrag event. |
OLE-DRAG-OVER | OLEDragOver | PROGRESS-BAR | Occurs when the mouse is moved over the target control during an OLE drag-drop operation. OLEDropMode property must be set to 1 (OLEDropModeManual) for the OLEDragOver event to occur. The Effect parameter is passed to this event from the OLEDragOver event (target control). Note: If the State parameter is set to 2 (Leave), indicating the pointer is outside of the control, then the X and Y parameters will be set to zero. |
OLE-GIVE-FEEDBACK | OLEGiveFedback | PROGRESS-BAR | Provides visual feedback through the pointer, by the source control for a drag-drop operation. If the DefaultCursors parameter is set to False, use the MousePointer property of the Screen object to specify the customized pointer. Fired after every OLEDragOver event to allow the source component to provide visual feedback to the user. |
OLE-DRAG-DROP | OLEDragDrop | PROGRESS-BAR | Occurs when data is dropped onto the control. The OLEDropMode property must be set to 1 (OLEDropModeManual) for the OLEDragOver event to occur. The OLEDragOver event occurs at the target control when the mouse button is released. After this event occurs, call the GetFormat method of the DataObject to query whether or not the desired format is available, then call the GetData method of the DataObject to retrieve the data. The Effect parameters are passed to this event from the OLEStartDrag event (source control). |
OLE-COMPLETE-DRAG | OLECompleteDrag | PROGRESS-BAR | Occurs at the source control after an OLE drag-drop operation has been completed or canceled. This is the last event to occur in an OLE drag-drop operation. The Effect parameter value is passed in from the target control's OLEDragDrop event. If the Effect parameter contains a value of 0, the drag-drop operation did not complete successfully. |
The OCX procedures to handle OLE events looks like:
PROCEDURE <event-proc-prefix>.OLECompleteDrag : DEFINE INPUT-OUTPUT PARAMETER Effect AS INTEGER. END PROCEDURE. PROCEDURE <event-proc-prefix>.OLEDragDrop : DEFINE INPUT-OUTPUT PARAMETER Data AS COM-HANDLE. /* IVBDataObject */ DEFINE INPUT-OUTPUT PARAMETER Effect AS INTEGER. DEFINE INPUT-OUTPUT PARAMETER Button AS INTEGER. DEFINE INPUT-OUTPUT PARAMETER Shift AS INTEGER. DEFINE INPUT-OUTPUT PARAMETER x AS DECIMAL. DEFINE INPUT-OUTPUT PARAMETER y AS DECIMAL. END PROCEDURE. PROCEDURE <event-proc-prefix>.OLEDragOver : DEFINE INPUT-OUTPUT PARAMETER Data AS COM-HANDLE. /* IVBDataObject */ DEFINE INPUT-OUTPUT PARAMETER Effect AS INTEGER. DEFINE INPUT-OUTPUT PARAMETER Button AS INTEGER. DEFINE INPUT-OUTPUT PARAMETER Shift AS INTEGER. DEFINE INPUT-OUTPUT PARAMETER x AS DECIMAL. DEFINE INPUT-OUTPUT PARAMETER y AS DECIMAL. DEFINE INPUT-OUTPUT PARAMETER State AS INTEGER. END PROCEDURE. PROCEDURE <event-proc-prefix>.OLEGiveFeedback : DEFINE INPUT-OUTPUT PARAMETER Effect AS INTEGER. DEFINE INPUT-OUTPUT PARAMETER DefaultCursors AS LOGICAL. END PROCEDURE. PROCEDURE <event-proc-prefix>.OLESetData : DEFINE INPUT-OUTPUT PARAMETER Data AS COM-HANDLE. /* IVBDataObject */ DEFINE INPUT-OUTPUT PARAMETER DataFormat AS INTEGER. END PROCEDURE. PROCEDURE <event-proc-prefix>.OLEStartDrag : DEFINE INPUT-OUTPUT PARAMETER Data AS COM-HANDLE. /* IVBDataObject */ DEFINE INPUT-OUTPUT PARAMETER AllowedEffects AS INTEGER. END PROCEDURE.
OCX OLE events procedures parameters:
Attribute Name | OCX Name | Handle Type | Return Type | Read Only | Description |
---|---|---|---|---|---|
COM-DATA | Data | PROGRESS-BAR | COM-HANDLE | Y | Returns DataObject and instance of IVBDataObject COM interface |
OCX-MOUSE-BUTTON | Button | PROGRESS-BAR | INTEGER | Y | Returns which, if any, of the mouse buttons has changed state. |
OCX-SHIFT | Shift | PROGRESS-BAR | INTEGER | Y | Returns state of all modal keys, such as ALT, CTRL, META, and the mouse buttons just after the event occurred. |
OLE-X | x | PROGRESS-BAR | DECIMAL | Y | Returns the horizontal x position of the event relative to the source component. |
OLE-Y | y | PROGRESS-BAR | DECIMAL | Y | Returns the vertical y position of the event relative to the source component. |
OLE-EFFECT | Effect | PROGRESS-BAR | INTEGER | N | Returns drop Effect OLEDropEffectNone = 0 OLEDropEffectCopy = 1 OLEDropEffectMove = 2 OLEDropEffectScroll = -2147483648 |
OLE-STATE | State | PROGRESS-BAR | INTEGER | N | Returns OLE state. Enter = 0 Leave = 1 Over = 2 |
OLE-DEFAULT-CURSORS | DefaultCursors | PROGRESS-BAR | LOGICAL | N | If the DefaultCursors parameter is set to False, use the MousePointer property of the Screen object to specify the customized pointer. |
OLE-ALLOWED-EFFECTS | AllowedEffects | PROGRESS-BAR | INTEGER | N | Gets which drag-and-drop operations are allowed by the originator (or source) of the drag event. One of the Effects values. |
OLE-DATA-FORMAT | DataFormat | PROGRESS-BAR | INTEGER | N | Clipboard format. CFText = 1 CFBitmap = 2 CFMetafile = 3 CFDIB = 8 CFPalette = 9 CFEMetafile = 14 CFFiles = 15 CFRTF = -16639 |
DataObject is an instance of IVBDataObject COM iterface. Actually two COM interfaces are used in a drag-drop operation, IVBDataObject and IVBDataObjectFiles.
IVBDataObject properties and methods:
NO-RETURN-VALUE <com-handle>: Clear ( ) Property Get: [ Com-Handle-Var = ] <com-handle>:Files. /* Returns IVBDataObjectFiles COM interface */ [ <anytype>-Var = ] <com-handle>: GetData (Integer-sFormat AS SHORT ). [ Logical-Var = ] <com-handle>: GetFormat (Integer-sFormat AS SHORT ). NO-RETURN-VALUE <com-handle>: SetData (<anytype>-vValue, <anytype>-vFormat ).
IVBDataObjectFiles properties and methods:
NO-RETURN-VALUE <com-handle>: Add (Character-bstrFilename, <anytype>-vIndex ). NO-RETURN-VALUE <com-handle>: Clear ( ). Property Get: [ Integer-Var = ] <com-handle>:Count. Property Get: [ Character-Var = ] <com-handle>:Item ( Integer-lIndex ). NO-RETURN-VALUE <com-handle>: Remove ( <anytype>-vIndex ).
When PROGRESS-BAR is used like a 4gl extension widget a typical definitions of OLE events triggers looks like:
on "ole-complete-drag" of progBar do: define variable Effect as integer. effect = progBar:ole-effect. message "OLECompleteDrag" Effect. end. on "ole-drag-drop" of progBar do: define variable Data as component-handle. define variable Effect as integer. define variable Button as integer. define variable Shift as integer. define variable x as decimal. define variable y as decimal. data = progBar:com-data. effect = progBar:ole-effect. Button = progBar:ocx-mouse-Button. Shift = progBar:ocx-mouse-Shift. x = progBar:ole-x. y = progBar:ole-y. message "OLEDragDrop" Button Shift Effect x y. end. on "ole-drag-over" of progBar do: define variable Data as component-handle. define variable Effect as integer. define variable Button as integer. define variable Shift as integer. define variable x as decimal. define variable y as decimal. define variable State as integer. data = progBar:com-data. effect = progBar:ole-effect. Button = progBar:ocx-mouse-Button. Shift = progBar:ocx-mouse-Shift. x = progBar:ole-x. y = progBar:ole-y. state = progBar:ole-state. message "OLEDragOver" Button Shift Effect x y State. end. on "ole-give-feedback" of progBar do: define variable Effect as integer. define variable DefaultCursors as logical. effect = progBar:ole-effect. DefaultCursors = progBar:ole-default-cursors. message "OLEGiveFeedback" Effect DefaultCursors. end. on "ole-set-data" of progBar do: define variable Data as component-handle. define variable DataFormat as integer. data = progBar:com-data. dataFormat = progBar:ole-data-format. message "OLESetData" DataFormat. Data:Clear(). end. on "ole-start-drag" of progBar do: define variable Data as component-handle. define variable AllowedEffects as integer. data = progBar:com-data. AllowedEffects = progBar:ole-allowed-effects. message "OLEStartDrag" AllowedEffects. Data:GetData(15). Data:Files. Data:Item(0). end.
Standard 4GL members¶
Besides the members introduced in FWD, the widget also supports the following standard 4GL members. Please consult the official OpenEdge documentation.
BGCOLOR COLUMN FGCOLOR FONT FRAME FRAME-COL FRAME-ROW FRAME-X FRAME-Y HEIGHT-CHARS HEIGHT-PIXELS HELP HIDDEN INSTANTIATING-PROCEDURE LABEL LABEL-FONT LOAD-MOUSE-POINTER MENU-KEY MENU-MOUSE MOUSE-POINTER MOVE-AFTER-TAB MOVE-TO-BOTTOM MOVE-TO-TOP NAME NEXT-SIBLING NEXT-TAB-ITEM PARENT POPUP-MENU PREV-SIBLING PREV-TAB-ITEM PRIVATE-DATA ROW SCREEN-VALUE SENSITIVE SIDE-LABEL-HANDLE TAB-POSITION TAB-STOP TYPE VISIBLE WIDGET-ID WIDTH WIDTH-CHARS WIDTH-PIXELS WINDOW X Y
Conversion¶
FWD is capable to automatically convert the usages of Microsoft's progress bar control from the Windows Common Controls library.
To enable the conversion create the file <procedurefile.p>.ext-hints with the following structure.
<extension> <ocx control-frame="CtrlFrame" control-frame-handle="chCtrlFrame" com-handle="chCtrlFrame:ProgressBar" target-handle="hProgressBar" target-widget="progress-bar" /> <drop-procedure name="control_load" /> </extension>
The xml element ocx defines the CONTROL-FRAME hosting the progress bar control (control-frame), the com handle (control-frame-handle) of the control frame,
com handle property (com-handle) for referencing the progress bar in the control frame and the handle (target-handle) for the converted progress bar widget.
The xml element drop-procedure defines all the functions and internal procedures declared in <procedure.p> file that contain the OCX initialization code.
To give an example, the following code sample will convert with the xml configuration given above.
define variable CtrlFrame as widget-handle no-undo. define variable chCtrlFrame as component-handle no-undo. procedure control_load : define variable UIB_S as logical no-undo. define variable OCXFile as character no-undo. OCXFile = search( "progbar.wrx":U ). assign chCtrlFrame = CtrlFrame:com-handle UIB_S = chCtrlFrame:LoadControls( OCXFile, "ProgressBar":U). end procedure. run control_load. chCtrlFrame:ProgressBar:Value = 45. procedure CtrlFrame.ProgressBar.Click : ... end procedure.
Examples¶
Create PROGRESS-BAR widget¶
create progress-bar progBar assign frame = frame f:handle row = 3.62 column = 5 height = 1.2 width = 104 visible = true.
Set properties¶
progBar:ole-Drop-Mode = 1. progBar:pb-Appearance = 1. progBar:pb-Border-Style = 0. progBar:pb-Orientation = 0. progBar:pb-Scrolling = 1. progBar:pb-Max = 100. progBar:pb-Min = 0. progBar:pb-Value = 30. progBar:pb-Mouse-Pointer = 3.
Test progress indicator¶
procedure test_progress : define variable icount as integer no-undo. do iCount = 1 to progBar:pb-Max : progBar:pb-Value = iCount. progBar:pb-Refresh( ). end. end procedure.
Mouse DOWN trigger¶
on "mouse-down" of progBar do: define variable Button as integer. define variable Shift as integer. define variable x as integer. define variable y as integer. Button = progBar:ocx-mouse-Button. Shift = progBar:ocx-mouse-Shift. x = progBar:ocx-mouse-x. y = progBar:ocx-mouse-y. message "MouseDown!" x y Button Shift. end.
Complex example¶
© 2019 Golden Code Development Corporation. ALL RIGHTS RESERVED.