tips:kb:openinsight_kb

OpenInsight KnowledgeBase

This is the first installment of the OpenInsight Knowledgebase. The objective of this document is to provide an addendum to the OpenInsight documentation set, detailing intermediate and advanced development tips and techniques.

This document is in draft form, the editing and formating of this document is spartan. Upon completion of this draft, this document will be available as a Windows Help file. The Help file with provide improved formatting, hypertype, and a topic index. This KnowledgeBase and all updates are available on Revelation Technologies CompuServe Forum, or through a support representative.

Disclaimer: This software and documentation are provided "as is" without warranty of any kind. Revelation Technologies further disclaims all implied warranties including without limitation any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the software and documentation remains with you.

In no event shall Revelation Technologies or its suppliers be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the software or documentation, even if Revelation Technologies has been advised of the possibility of such damages.

OpenInsight functions & commands

Window Form Design Tips

"I used to do it in Arev…"

OpenInsight Command Line Options

On the command line, you can specify:

/AP=[Application name in all caps] /UN=[User name in all caps] /DV this flag will to bring you to the Open Application Dialog box instead of the login dialog box. This is useful for those developers that have specified a starting window but might not want to execute it everytime they open OpenInsight.

Example:

C:\OINSIGHT\OINSIGHT.EXE /AP=CARPARTS /UN=CARPARTS /DV

DDE Between OI and WinWord

There are two ways to do Dynamic Data Exchange with Word for Windows (WinWord):

1. Hot DDE connection: When you enter data in an OpenInsight Editbox the connection will automatically enter the data into the WinWord document. You need to set up this connection in both OpenInsight and WinWord. The following script will walk you through this process.

In OpenInsight:

Create an Editbox named DDE_DATA. Click on the Editbox so it is highlighted. Under the main menu go under Properties - Link. Enter the following information:

Service:WinWord Topic:C:\Windows\Test.doc (the WinWord document) Item:DDE_LINK# (where # represents the link#…. discussed below.)

Link Type: Auto or Hot (either one).

In WinWord:

From the WinWord Main Menu: Alt - (I)nsert - (F)ield - (L)ink. Double click on Text.

Highlight the link object created in the document. Press Ctrl-C. Go back into OpenInsight in the Link window and for the Item hit the Paste Link button. DDE_LINK1 should be pasted into this field.

Back in WinWord, Press Alt - (E)dit-(L)inks, double click on the line that says Manual and hit the Automatic button and then the Change Link button. The application should be the same as Item in the OpenInsight Link Window, i.e. DDE_LINK1.

Bring up the OpenInsight window and test. The data typed from either the WinWord document or the OpenInsight Editbox should both be updated in either place automatically.

2. Setting up a warm DDE link:

Note: The settings used above are not used in this setup. Be sure to delete those settings if you have set them previously.

In OpenInsight:

Create an Editbox and two buttons. Name the Editbox DDE_DATA.

For the DDE_POKE (data is put into the WinWord document from OI) follow this example:

declare function get_property, set_property

Ctrl_Name = "DDE_TEST.DDE_DATA"
Stat = Set_Property(  Ctrl_Name, "DDESERVICE", "WinWord" )
Stat = Set_Property(  Ctrl_Name, "DDETOPIC","C:\WINDOWS\TEST.DOC" )
Stat = Set_Property(  Ctrl_Name, "DDEITEM","DDETEST" )
Stat = Set_Property(  Ctrl_Name, "DDELINK","WARM" )

Text_Val = Get_Property( Ctrl_Name, "TEXT" )
call msg( "", "text_val: ":text_val )

Stat = Set_Property( Ctrl_Name, "DDEDATA", TEXT_VAL )

Return 1

For the DDE_REQUEST (data is taken from the WinWord document and into OpenInsight) follow this example:

declare function get_property, set_property

Stat = Set_Property(  Ctrl_Name, "DDESERVICE", "WinWord" )
Stat = Set_Property(  Ctrl_Name, "DDETOPIC", "C:\WINDOWS\TEST.DOC" )
Stat = Set_Property(  Ctrl_Name, "DDEITEM",          "DDETEST" )
Stat = Set_Property(  Ctrl_Name, "DDELINK",       "WARM" )

In_Data   = Get_Property( Ctrl_Name, "DDEDATA" )
call msg( "", "data received: ":in_data )

Stat = Set_Property( Ctrl_Name, "TEXT", In_Data )

Return 1

In WinWord:

Place the cursor where you want the data to be put into on the document from OpenInsight. Hit Alt-(I)nsert-Book(M)ark. Create a new book mark of the name of DDE_TEST.

Test run your OpenInsight Window.

Deleting stored procedures and stored inserts

The DELETE_PROC System Stored Procedure will delete (destroy) a stored procedure, object and debug tables with repository synchronization. A DESTROY message to these entities will also delete them. A TDESTROY to the STPROCEXE will destroy the executable, source and debug components but remember - it will also destroy anything that they call!

Calling DLL's from within OpenInsight

OpenInsight can use any DLL and DLL function. The following is an example of setting up the functions necessary to gain access to a fonts' pixel attributes.

To call a DLL you will first need to create a function prototype - This prototype is a record in the SYSPROCS table. In this example, the name of this record will be DLL_GDI; after setting up this prototype run the command: RUN DECLARE_FCNS "DLL_GDI" in the system editor. This procedure will "catalog" the DLL in OpenInsight. The function prototype would look similar to:

Row1: GDI_DLL Row2: SHORT PASCAL CREATECOMPATIBLEDC(SHORT) Row3: SHORT PASCAL CREATEFONT(SHORT,SHORT,SHORT,SHORT,SHORT,BYTE,BYTE,BYTE,BYTE,BYTE,BYTE, BYTE,BYTE,LPCHAR) Row4: VOID PASCAL SELECTOBJECT(SHORT,SHORT) Row5: LONG PASCAL GETTEXTEXTENT(SHORT,LPCHAR,SHORT) Row6: VOID PASCAL DELETEDC(SHORT)

The following is sample code used to obtain the pixel width of a given string in a text box named EL1:

Declare Function CreateCompatibleDC, CreateFont, GetTextExtent
Declare Subroutine SelectObject, DeleteDC

Equ Null$    to Char( 0 )

font = .EL1->Font
Convert @SVM to @FM in font
faceName       = font< 1 >
height           = font< 2 >
weight         = font< 3 >
italic          = font< 4 >
underline    = font< 5 >
width          = font< 6 >
charSet            = font< 7 >
pitchAndFamily   = font< 8 >
strikeOut               = font< 9 >
escapement        = 0
orientation            = 0
outputPrecision    = 0
clipPrecision      = 0
quality                = 0

string = .EL1->Text
strLen = Len( string )
string := Null$

hDC = CreateCompatibleDC( 0 )
hFont = CreateFont( height, width, escapement, orientation, weight,
italic, underline, strikeout, charSet, outputPrecision,
clipPrecision, quality, pitchAndFamily, faceName)
* the three lines above should be placed on the same line
 
SelectObject( hDC, hFont )
pixelLen = GetTextExtent( hDC, string, strLen )
DeleteDC( hDC )

Calling GET/SET_PROPERTY

General syntax:

OldValue = Set_Property (<ObjectNameList>, <PropertyNameList>, <ValueList>)

value = Get_Property (<ObjectNameList>, <PropertyNameList>)

where <itemList> ::= <item1> @RM <item2> …

The ability to pass a @RM delimited string for each of the arguements allow the developer to change multiple objects and their properties with one function call. Note: If <ObjectNameList> contains more items than <PropertyNameList> or <ValueList> then shortest list <ObjectNameList> will be used.

If request is not valid, then a null will be returned.

PropertyName:

- ARRAY – for EDITTABLEs

Get_Property - returns @FM , @VM (columns,rows) delimited array Set_Property - resets the entire table

- ACCESSPOS – for EDITTABLEs

Get_Property - returns col:@FM:row for internal cursor Set_Property - if value = col:@FM:row , sets internal cursor

- ACCESSDATA – for EDITTABLE

Get_Property - returns text from cell by internal cursor Set_Property - sets text into the cell by internal cursor

- BACKCOLOR – for all objects excluding PUSHBMP, CHECKBMP, RADIOBMP

Get_Property - returns background color of object (long integer) Set_Property - set background color of object (long integer)

- BITMAP – for BITMAP, PUSHBMP, CHECKBMP, RADIOBMP

Get_Property - returns path to .bmp file Set_Property - if value is path to .bmp, sets new bitmap

- CANCEL – for PUSHBUTTON and PUSHBMP

Get_Property - returns a name of CANCEL object Set_Property - set CANCEL_BUTTON property of a button

- CLIENTSIZE – for WINDOW

Get_Property - returns width:@FM:height of window's client area Set_Property - is not used

- CHECK – for CHECKBUTTON, RADIOBUTTON, CHECKBMP, RADIOBMP

Get_Property - returns 1 if object is checked, 0 otherwise Set_Property - if value <> 0 then checks an object, otherwise (for CHECKBOX and CHECKBMP only) unchecks it

- DEFAULT – for PUSHBUTTON and PUSHBMP

Get_Property - returns a name of DEFAULT object Set_Property - set DEFAULT_BUTTON property of a button

- DROPDOWN – for COMBOBOX

Get_Property - returns 1 if combobox's is dropdowned, 0 otherwise Set_Property - if value <> 0 then displays the list box, otherwise hides it

- ENABLED – for all objects that can have focus

Get_Property - returns 1 if object is enabled, 0 otherwise Set_Property - if value <> 0 then enables an object, otherwise disables it

- FOCUS – for all objects that can have focus

Get_Property - returns name of the object that has a focus Set_Property - sets focus to an object

- FONT – for all objects excluding WINDOW, ICON, PUSHBMP, CHECKBMP, RADIOBMP

Get_Property - get font structure Set_Property - set font, described by font structure, where font-structure is @SVM delimited array of:

SET_PROPERTYGET_PROPERTY
FACENAMEFACENAME
HEIGHT

positive for cell height
negative for character height
HEIGHT

always positive - cell height
WEIGHTWEIGHT
ITALICITALIC
UNDERLINEUNDERLINE
WIDTHWIDTH

average character width
CHARSETCHARSET
PITCHANDFAMILYPITCHANDFAMILY
STRIKEOUTSTRIKEOUT
OUTPRECISION<null>
CLIPPRECISION<null>
QUALITY<null>
<null>ACSENT
<null>INTERNALLEADING
<null>EXTERNALLEADING
<null>MAXCHARWIDTH

- FORECOLOR – for all objects excluding PUSHBMP, CHECKBMP, RADIOBMP

Get_Property - returns foreground color of object (long integer) Set_Property - sets foreground color of object (long integer)

- HANDLE – for all objects

Get_Property - returns integer window handle of an object Set_Property - is not used

- HPOSITION – for WINDOW, HSCROLLBAR

if object = WINDOW, this property applies to a horizontal scrollbar of given window

Get_Property - returns Pos:@FM:MinPos:@FM:MaxPos, where Pos is the current position of the thumb in a scrollbar, MinPos and MaxPos - min and max positions for a the scrollbar.

Set_Property - if Value equals Pos, set a new position of thumb; if Value equals Pos:@FM:MinPos:@FM:MaxPos - set new minimum, maximum positions for a scrollbar and a thumb position

- 'IDLEPROC' – for 'SYSTEM'

Value is a @FM delimited array:

IdleProcStructure <1> = ProcedureName IdleProcStructure <2> = Parameter IdleProcStructure <3> = Time of activating (hh:mm:ss) IdleProcStructure <4> = Day of activating (mm/dd/yy)

if Day is not set it will be equal to the current date if Time is not set - it will be as soon as OpenEngine is idle

Comments:

There is a temporary restriction - LEN( IdleProcStucture ) ⇐ 60 As soon as the indicated procedure is activated the 'IDLEPROC' property is reset to <NULL>

- ICON – for WINDOW and ICON

Get_Property - returns path to .ico file Set_Property - creates new icon for all objects of the same class with this object (value = .ico file path)

- LABEL – for EDITTABLEs

Get_Property - returns @FM delimited list of heading labels Set_Property - sets new heading labels (Value = @FM delimited list)

- LIMIT – for LISTBOX, COMBOBOX, EDITTABLE

Get_Property - returns count of items in an object (colCount :@FM: rowCount for EDITTABLE) Set_Property - is not used

- LIST – for LISTBOX, COMBOBOX, EDITTABLE

Get_Property - returns @FM delimited list (@FM , @VM (rows,columns) for EDITTABLE) Set_Property - resets the entire list

- MDBA – for all objects (obsolete)

Get_Property - returns Map of Database Attributes Set_Property - saves Map of Database Attributes

- MISC – for all objects

Get_Property - returns string of satellite data Set_Property - saves string of satellite data

- MODIFIED – for EDITFIELD, EDITBOX, COMBOBOX

Get_Property - returns current value of the modify flag Set_Property - sets the modify flag for a given object

- NEXT – for all objects that can have focus

Get_Property - returns next object in a Tab-chain Set_Property - set next object for this object

- PARENT – for all objects

Get_Property - returns parent's name Set_Property - is not used

- PREVIOUS – for all objects that can have focus

Get_Property - returns previous object in a Tab-chain Set_Property - set previous object for this object

- PREVSELPOS – for EDITTABLE

GetProperty - returns col :@FM: row for the cell that previously had a focus SetProperty - is not used

- REPOS_TYPE – for WINDOW objects

Get_Property - returns Repository Type value Set_Property - is not used

- SIZE – for all objects

Get_Property - returns x:@FM:y:@FM:w:@FM:h Set_Property - sets size of an object (value = x:@FM:y:@FM:w:@FM:h) if some of params equal to (2 POW 15) - does not change this characteristic of the object;if object was hidden - shows it normal

- SELECTION – for EDITFIELD, EDITBOX, COMBOBOX, EDITTABLE

Get_Property - returns p:@FM:l, where p - starting position and l - length of the current selection (highlighted text) Set_Property - if Value = p:@FM:l - selects (highlights) all characters in the current text starting from position p with length l (1 :@FM: 32767 selects the entire text)

- SELPOS (or SHOWPOS)– for EDITTABLE, LISTBOX, COMBOBOX

Get_Property - returns col:@FM:row for active cell in EDITTABLE or selected row(s) for LIST and COMBOBOX (@FM-delimited list for multiple-selection listbox) Set_Property - sets active cell for EDITTABLE (value = col:@FM:row), or select row(s) for LIST and COMBOBOX (invert current state for multiple-selection listbox)

- STYLE (STYLE_EX) - for all objects

GetProperty - returns Windows SDK style (extended style) for an object in hexadecimal format SetProperty - sets Windows SDK style (extended style) for an object

- TEXT – for all objects

Get_Property - returns text value of object (highlighted item(s) for LISTBOX, active cell for EDITTABLE) Set_Property - sets text value of object (highlights indicated item(s) for LISTBOX, active cell for EDITTABLE)

- TYPE – for all objects

Get_Property - returns object type ('WINDOW', 'PUSHBUTTON' …) Set_Property - is not used

- TABSTOPS - for EDITBOX, LISTBOX

Get_Property - is not used Set_Property - if value is @FM delimited array of numbers (in pixels) sets tabstops according to this array (see Windows SDK description for EM_SETTABSTOPS and LB_SETTABSTOPS messages)

- VISIBLE – for all objects

Get_Property - returns 0 if object is invisible, 2 if object is minimized, 3 if object is maximized, 1 otherwise Set_Property - if value <> 0 then shows an object, otherwise hides it

- VALUE - for RADIOGROUP

Get_Property - returns a value of selected RADIOBUTTON from this group Set_Property - checks a RADIOBUTTON with an indicated value in this group

- VPOSITION – for WINDOW, VSCROLLBAR

if object = WINDOW this property applies to a vertical scrollbar of given window

Get_Property - returns Pos:@FM:MinPos:@FM:MaxPos, where Pos - current position of thumb in a scrollbar, MinPos and MaxPos - min and max positions for a scrollbar Set_Property - if Value = Pos - set a new position of thumb; if Value = Pos:@FM:MinPos:@FM:MaxPos - set new minimum, maximum positions for a scrollbar and a thumb position

**Get/Set_Property supports custom properties - any property name that begins with @-sign is treated as a free format satellite data register that is stored as far as an object exists.

System maintained controls can also be manipulated with Get & Set_Property

MENUITEM has properties:

CHECK

ENABLED

TEXT

SYSTEM object has properties:

FOCUS

IDLEPROC

SIZE

VERSION

CLIPBOARD object has property:

TEXT

Calling the UTILITY function

General syntax:

answer = Utility (<Utility_name> [, <Object> [,<Value>])
Utility_nameParameters
BEEP<Object> - integer value (see Windows SDK 3.1 MessageBeep)
Makes a beep
CREATECreates objects (<Object> = @FM:@VM:@SVM delimited list of object-records)
See structure defined in the row PS_EQUATES, in the SYSPROCS table.
CURSORif <Object> = 'A' or 'I' or 'H' or 'C' or 'V' then sets cursor shape to arrow or I-beam or hourglass or cross or uparrow
CHOOSECOLORcalls common dialog (from Windows SDK 3.1)
<Object> = Owner window
if Value = RGB color value then init this dialog by indicated color
return value = selected color
CHOOSEFONTcalls common dialog (from Windows SDK 3.1)
<Object> = Owner window
if Value = FaceName:@TM: Height:@TM: Bold:@TM: Italic:@TM: Underline:@TM: Weight:@TM: Width:@TM: Set:@TM PitchAndFamily:@TM: StrikeOut (any number of arguments can be skipped) then init this dialog by indicated parameters
return value has the same structure
CHOOSEFILEcalls common dialog (from Windows SDK 3.1)
<Object> = Owner window
Value = should be @FM delimeted array:
Value <1> = <mode> ( 0 = Open Dialog; 1 = Save dialog )
Value <2> = Filter buffer
Value <3> = Filter index
Value <4> = Init name
Value <5> = Flags
only first field (mode) is required
return value - full path of selected file (NULL if operation was canceled)
DESTROYDestroys an Object
DRAWif Object = <Window name> and Value = <Mode> then switches this window in a special drawing mode
GET_EVENTreturns description for a next event is to be processed
FLUSHRemoves all queued events from the event queue (useful during an unsuccesful validation on a LOSTFOCUS)
PRINTSETUPCommon dialog (Windows SDK 3.1)
RUNPasses Object as a command line string to the System monitor window
RUNHELPPasses Objectname as a help file name to the WinHelp () function (see Windows SDK)
Value (optional) is a @FM delimited array:
Value <1> = Owner window name
Value <2> = command (second param for WinHelp)
Value <3> = extraParam (polymorphic third param for WinHelp)
RUNWINPasses Object as a command line string to WinExec function (see Windows SDK)
Value (optional) is a @FM delimited array:
Value <1> = Mode to be passed to WinExec function
Value <2> = Name of callback function to be called when an activated now application has been terminated
Value <3> = Parameter to be passed to the callback function
Note: total length of Value array should not exceed 60 bytes
Return value is @FM delimeted array of hexadecimal numbers for instance handle, module handle and task handle for the activated task.
TEXTRECTDetermines the size of the rectangle with a text.
Object - any object or NULL
Value - @FM delimited array:
<Text> - any text (lines delimited by \0D0A\)
<Flags> - see Windows SDK DrawText() (fuFormat parameter)
<width> - width of rectangle for DT_WORDBREAK flag set (only if object doesn't exist)
<font> - logfont structure (SVM delimited) (only if object doesn't exist)
returns (<width> FM <height>) of rectangle to fit the text

Algorithm: (see Windows SDK, DrawText() function for detail)
if object exists then
width = width of client area of the object
font = current font of the object
DrawText (hDC, text, len (text), &rect, flag | DT_CALCRECT)

Returns (rect.right : @FM: rect.bottom)
WINCOUNTReturns number of currently running OpenInsight windows

Calling the SEND_MESSAGE function

General syntax:

answer = SEND_MESSAGE (<Object>, <Message> [,<Param_N>]*)

(up to 4 parameters)

Messages:

- COLCHARS – for EDITTABLE Set or retrieve max number of characters for a column in EDITTABLE Param1 - column number (0 for all) Param2 - if is set - new value(s) (@fm delimeted array of values) return value - actual value(s) (Note: if value is changed - text data should be rewritten)

- COLSTYLE – for EDITTABLE Set or retrieve style of column(s) in EDITTABLE Param1 - column number (0 for all) Param2 - if is set - new style(s) (@fm delimeted array of values) return value - actual style(s)

- COLWIDTH – for EDITTABLE Set or retrieve width of column(s) in EDITTABLE Param1 - column number (0 for all) Param2 - if is set - new width (@fm delimeted array of values) return value - actual value(s)

- DELETE – for COMBOBOX, LISTBOX, EDITTABLE Deletes row. Param1 - index of row to delete (1 - first; -1 - last) return value - text of deleted item

- INSERT – for COMBOBOX, LISTBOX, EDITTABLE, EDITBOX, EDITLINE

Inserts new row (for EDITBOX, EDITLINE - replace selection). Param1 - index of row (for EDITBOX, EDITLINE - is not used) before which to insert (-1 after the last) Param2 - text to insert return value - actual position of inserted row

- MOVE_ROW – for EDITTABLE Moves row Param1 to row Param2

- POS_BY_TEXT – for COMBOBOX, LISTBOX

Returns position of text. Param1 - text to find (prefix or full text) Param2 - position of item before the first item to be searched (-1 - through the whole list) Param3 - flag of exact matching (optional, default=0)

- SCROLL if Object = <Window name> and Param1 = <X_Shift>; Param2 = <Y_Shift> then scrolls this window accordingly

- TEXT_BY_POS – for COMBOBOX, LISTBOX, EDITTABLE

Return text by position or by (column, row) coordinates Param1 - position of item for COMBOBOX, LISTBOX; column for EDITTABLE Param2 - row for EDITTABLE

Comments for EDITTABLE: if colum <> 0 and row <> 0 then return value is a cell if column = 0 and row <> 0 then return value is a row (@VM delimited) if column <> 0 and row = 0 then return value is a column (@FM delimited) if column = 0 and row = 0 then return value is a LIST property

if in any case Param3 is indicated it's used to change either cell or row or column or the whole list

- UNDO – for EDITFIELD, EDITBOX Undoes the last change

- UPDATE – for LISTBOX, COMBOBOX, EDITTABLE

for LISTBOX or COMBOBOX that has OWNERDRAWFIXED SDK-style set then changes an image to the image number Param2 in a row Param1

for EDITTABLE changes a row Param1 with data in Param2 (@VM delimited array)

System Monitor internal commands

The internal commands are:

1) STOP stops all running projects and frees all resources.

2) STOP <main-window-of-project name> stops the project with given main window

3) EXEC <project description> a) According to <project description> receives object list from Start_Project() SSP ; b) if main window already exists tries to close it c) if main window does not exist creates all objects from the list, activates main window and generates CREATE event for it

4) ACTIVATE (or APPEND) <project description>

a) According to <project description> receives object list from Start_Project() SSP ; b) if main window already exists activates it else creates all objects from the list, activates main window and generates CREATE event for main window

PS passed <project description> directly to START_PROJECT() SSP.

5) QUIT - shuts down PS (stand-alone PS only)

Window Dialog mechanism

A Dialog is window that is created on a fly by the request from event-handler as a child (owned) window of some existing WINDOW object and which can be used by different applications under OpenInsight.

The window that is parent of a Dialog stores three parameters of Dialog:

- InitParameter - is used to pass data from calling application to a Dialog

- OwnParameter - is used to store some dialog-specific data

- OutParameter - is used to pass data from a Dialog to calling application

There are five SSPs that allow you to create and use dialog boxes in Basic+. 1)function DIALOG_BOX (DialogDescription, ParentName, InitParameter )

where DialogDescription = <FileName> :" ": <MainDialogWindowName> ParentName = <ParentOfDialog> InitParameter = Data is to be passed to dialog box

2)function CREATE_DIALOG (DialogDescription, ParentName, ModalMode, InitParameter)

where DialogDescription = <FileName> :" ": <MainDialogWindowName> ParentName = <ParentOfDialog> ModalMode = 0 - if Parent window has to be disabled 1 - if Parent window has to stay enabled InitParameter = Data is to be passed to dialog box

3)END_DIALOG (MainDialogWindowName, OutParameter)

For Modal Dialogs, OutParameter is the return value; for modeless - it is stored and can be retrieved by GET_DIALOG_PARAMS

4)function GET_DIALOG_PARAMS (MainDialogWindowName [, ParentName])

(ParentName has to be used to retrieve dialog-specific data when the Dialog does not exist anymore)

this function returns @FM delimited array of parameters

5)function SET_DIALOG_PARAMS (MainDialogWindowName, Parameters, [, ParentName])

(ParentName has to be used to set dialog-specific data when PS-Dialog does not exist anymore)

this function stores @FM delimited Parameters array and returns previous value of @FM delimited parameters array.

Columnar Reporting in Basic+ (ORPRV, ORPRTF, OR_VIEW functions)

ORPRV is the previewer window called by the Report Builder. One can call it with the following parameters:

[Report name], ['RLIST statement']

The two are mutually exlusive. You can print to file directly using the ORPRTF window with these parameters.

[Report name], ['RLIST statement'], 'PATH'

It is possible to call any of the report builder's windows including ORMAIN. You need to call a subroutine to call the windows. An Example:

/*
     Syntax:
     or_view( [ReportEntID], [Rlist_Statement] )
    or_prtf(    [ReportEntID], [Rlist_Statement], 'PATH' )

     The square brackets mean optional.  
     Explanation follows:
*/
Declare subroutine or_view, or_prtf

rlist_st  = 'LIST CAR_PARTS'  ;* A valid RList statement (no ' ,1' necessary)
rep1 = 'REPORT_1'        ;* A report saved in report builder
or_view('', rlist_st )       ;* first argument is null
or_prtf( rep1, '','c:\reports\rep1.doc'  )  ;* Second argument is null
                                            ;* Relative path is also allowed

Return 0

How to force a control to gain focus

       stat = SET_PROPERTY("windowname.controlname","FOCUS","1")

or shorthand:

       windowname.controlname->focus=1

This syntax allows you to move the cursor to any control in a window and force it to have focus. Please note: This will also flush the event queue. To force focus without flushing the event queue:

       stat = SET_PROPERTY("SYSTEM","FOCUS","windowname.controlname")

or shorthand:

       
       system->focus="windowname.controlname"

To get the name of the control with focus, do:

       controlname = GET_PROPERTY("SYSTEM","FOCUS")

or shorthand

       
       controlname=system->focus

How to manipulate Radio button groups and menu controls

There are two controls that are not as simple as the others. MENUs and RADIOBUTTONGROUPs. Radiobuttons and menus are named dynamically, and have a name of the form

WINDOWNAME.MENU[.MENUNAME[…]].MENUITEM

Where [MENUNAME] are submenus that occur recursively (explaining the […].)

If you look at the window template record found in SYSREPOSWINEXES, you will see the structure of a radiobutton group. There is a RADIOGROUP control as well as a separate RADIOBUTTON control for each button in the group. The parent of each RADIOBUTTON is the RADIOGROUP. This relationship is also seen in the control name. It is of the form:

WINDOWNAME.RADIOGROUPNAME.BUTTONNAME

BUTTONNAME is derived from the TEXT property, not the VALUE property - and spaces are converted to underscores.

An example that shows how one would disable 'choice 2' inside a radiogroup called RADIO_1.

+——————+

* choice 1
* choice 2
* choice 3

+——————+

EQU false$ TO 0
.radio_1.choice_2->enabled = false$
return 0

How do you specify the qualified control name of the menu command in a Set_Property call when you want to enable the pushbutton and menu command?

  x = Set_Property( "WINDOWNAME.MENU.EDIT.TITLES...",  "ENABLED",  1 )

or shorthand:

  .MENU.EDIT.TITLES...->ENABLED = 1

Note that the three dots (…) MUST be specified as part of the control name or the Set_Property call doesn't change the property.

The control name and the text property do not need to be the same. It is true that the menu does base its control name on the text associated with it (using the Menu Builder). The name of a MENU control is of the form

WINDOWNAME.MENU.FULLMENUPATH

where FULLMENUPATH in this case would be EDIT.TITLES…

Thus, to enable the menu use

x = Set_Property( "WINDOWNAME.MENU.EDIT.TITLES…", "ENABLED", 1 )

How to scroll an editbox based on the position in the text

You can find text using INDEX and select it using SELECTION. See below for syntax and explanation.

/*

SYNTAX:

set_property( CtrlEntID, 'SELECTION', SelectionPos )
            get_property( CtrlEntID, 'SELECTION' )

            CtrlEntID is the name of the control.
                It can be an EDITBOX, EDITFIELD, EDITTABLE,COMBOBOX

           SELECTION is the property (similar to SELPOS

             SelectionPos is StartPos:@FM:Length
             StartPos of -1 is end
             StartPos of 1 with Length of 32767 is entire text

             SEE ALSO:
             SELECTION, SELPOS   == TRM
             INDEX
             */

 DECLARE function set_property, get_property

Ctrl      = 'WINDOW.EDITBOX_1

CurrentSelection    = get_property(ctrl, 'SELECTION')

* using the new notation gives
*
*  CurrentSelection = @ctrl->selection
*
Length         = CurrentSelection<2>    ;* Do not change startpos
Length         *= 2           ;* Double length of selected text
NewSelection   = CurrentSelection<1>:@FM:Length

OldSel         = set_property( Ctrl, 'SELECTION', NewSelection )

* using the new notation gives
*
  @ctrl->selection = NewSelection
*
return 0

How to return selected rows of a control.

Example Program:

function GetTableSel(charstr ctrlentid)
/*
function:GetTableSel


By editing the SYSREPOSWINS and adding 512 (200h) to the style field
of an edit table control, you can make it select multiple rows.
there is not yet an intrinsic property for returning multiply-
selected rows, though, so this function returns a dynamic array
(@vm delimited) of row numbers that have been selected. You can
use this array to parse up the LIST property and get
selected values.

parameters:ctrlentid - the fully qualified control id
returns  :@vm delimited list of selected row numbers


*/

declare function get_property, set_property, sendmessage

EQU WM_USER TO 1024

EQU DTM_GETROWSELCOUNT TO WM_USER+62
EQU DTM_GETROWSELFIRST TO WM_USER+64
EQU DTM_GETROWSELNEXT  TO WM_USER+65

retlist = ""

hWndEditTable = Get_Property(ctrlentid, 'HANDLE')
selcount=SendMessage(hWndEditTable,DTM_GETROWSELCOUNT,0,0)
if (selcount>0) then
currsel=SendMessage(hWndEditTable,DTM_GETROWSELFIRST,0,0)
retlist=currsel+1
for i=2 to selcount
currsel=SendMessage(hWndEditTable,DTM_GETROWSELNEXT,0,currsel)
retlist:=@VM:currsel+1
next i
end

return retlist

How to count lines in an EditBox

Sample Program

Compile Function CountLines ( CtrlEntID )

/*

 PURPOSE    : Counting lines in an editbox.  With soft returns
 
 PROCEDURES : 
 
 WARNINGS   : All hard returns will become soft returns.
 
 THEORY OF OPERATION :
 
1.  Convert soft returns to hard returns.
2.  Count carriage return linefeeds.
3.  Return to normal.
4.  See EM_FMTLINES in the Windows SDK for more details.
5.  Did not use EM_GETLINECOUNT because it scrolls the editbox.
         

begin condition
    pre:
    post:
end condition

/* ----------------------------------------------------------------------- */
/* Insert Records */

/* ----------------------------------------------------------------------- */
/* EQUATEs */
EQU TRUE$ TO 1
EQU FALSE$    TO 0
EQU YES$        TO 1
EQU NO$          TO 0
EQU OTHERWISE$  TO 1
EQU NULL$       TO ""
EQU SPACE$    TO \20\

EQUEM_FMTLINES TO 1048

/* Declares */

Declare function SendMessage, get_property
    
/* =============================================================== */



crlf= char(13) : char(10)
hCtrl= get_property( CtrlEntID, 'HANDLE')

bOk = SendMessage( hCtrl, EM_FMTLINES, true$, 0 )

Text= Get_Property( CtrlEntID, 'TEXT' )

LineCnt= Count( Text, crlf ) + 1
bOk = SendMessage( hCtrl, EM_FMTLINES, false$, 0 )

return LineCnt

Setting EditTable Colors

An example program to manipulate EditTable colors.

Compile function test_cellcolor ( CtrlEntID, CellPos )

BEGIN CONDITION
PRE:
POST:
END CONDITION

/*
Date:Modification:

Description:This subroutine takes an edit control and sets the Colors of a Cell
A column or row can also be set using different messages.

*/

DECLARE FUNCTION SendMessage, Get_Property, Set_Property

EQUDTM_SETROWCOLOR TO 1024 + 98;*  different messages FROM datatbl.h
EQUDTM_SETCOLCOLORTO 1024 + 99
EQUDTM_SETCELLCOLORTO 1024 +100

*Lower BYTE goes first when creating color structure

BkGrnd= \FF000000\;* Red
Text= \00FF0000\;* Green
SelBkGrnd= \0000FF00\;* Blue
SelText= \FFFFFF00\;* Black

dtColStruct= BkGrnd:Text:SelBkGrnd:SelText;* Order is important

* Set Cell position to affect

CtrlEntID= ' WINDOW.TABLECTL' ;* remove these two lines when not testing
CellPos= 2:@FM:2 ;* This is theY,X position
 
OldPos= Set_Property(CtrlEntID, 'ACCESSPOS', CellPos)
 * SELPOS can be used (see accessMode)

* Set variables to send to EditTable control

hCtrl= Get_Property(CtrlEntID, 'HANDLE') ;* handle to editTable
message= DTM_SETCELLCOLOR     ;* Scope of cell(s) to affect
accessMode= 0      ;* Use a 1 here if using SELPOS
lp= getPointer( dtColStruct )      ;* Get LONG pointer

bOk= SendMessage( hCtrl, message, accessMode, lp )

Return bOk

Setting EditMode 'on' in an EditTable

Example Program:

Compile function ef2 ( CtrlEntID )

declare function SendMessage, Get_Property

BEGIN CONDITION
PRE:
POST:
END CONDITION


/*Date:Modification:

Description:This Function is used to set the editmode ON 
programmatically in an edittable.  In GOTFOCUS and 
POSCHANGED event forward the event and call 
this function.

The F2 key will accomplish the same behavior while
in an edittable cell (Not F4 as some of you might 
have thought).

*/

EQU DT_BEGINEDITTO 1
EQU DT_ENDEDITTO 2
EQU DT_ABORTEDITTO 3

EQU WM_USER TO 1024
EQU DTM_EDITCURRCELLTO WM_USER + 95

hTbl= Get_Property( CtrlEntID, 'HANDLE')
message = DTM_EDITCURRCELL
EditMode= DT_BEGINEDIT


bOk = SendMessage( hTbl, message, EditMode,'')

Return bOk

The above code will put a cell in editmode allowing the user to use the mouse directly and not necessarilly overwrite the current text. Currently the F2 key already does this. The way to use my program would be in the GOTFOCUS and POSCHANGED events of the edittable.

Function PosChanged( CtrlEntID, OtherParams )

Declare function f2

Call Forward_Event( CtrlEntID )

bOk= f2( CtrlEntID )

return 0

Emulating INPUT.CHAR

Question: What is the variable which contains the buffered mouse or keyboard inputs? i.e. if a procedure is running and the user clicks on a button, where is this input stored, or how can the procedure detect that this or any other input has occurred?

In OpenInsight you use the CHAR event to trap characters from the keyboard. If you look at the top of the event editor in the CHAR event you can see everything that is trapped. To trap a click you need to use the BUTTONDOWN event in the window. You have position as well which button and some other info available in the header.

The user will be in an event procedure when he needs to detect the input. The input would be the trigger to finish the loop in this procedure that it is running. The other events are not ran until control is given back to the window.

Is there an equivalent to input.char 1,-1?

What you can use is the YIELD subroutine. What yield does is allow Windows to simulate a bit of multitasking. Thus, in your loop you could put up a window with a Cancel button on it. At the beginnning of each loop you would yield and check if the window is still visible. Cancel would either close the window or ask you to continue in a dialog_box (which halts your program for yield does not end execution by itself).

We suggest trapping a click because it is standard but if you have an edit control, you can trap any character.

Here is sample code for the yield function. It sets up a running clock in an editline for a window. This code should be put into the CREATE event of a window. It checks to see if the currently displayed time is the same as the internal clock time, if not then it updates the displayed time in the editline. It does this so that the display does not blink based on the half second, etc. The Set_Property in the beginning of the code sets up a user defined variable for use by the window. This variable will stay in effect until the window is closed.

Call Set_Property(CtrlEntID, '@STOP', '0')

LOOP
      vTime = oconv(time(), 'MTHS')
            IF vTime NE .Status2->Text THEN
.Status2->Text = vTime
      END
      vStop = Get_Property(CtrlEntID, '@STOP')
     Call Yield()
            UNTIL vStop = '1'
REPEAT

Call Send_Event(CtrlEntID, 'CLOSE')

The following should be placed on a control, such as a click of a pushbutton. This code sets the user defined Window variable @STOP, which is made for the window by the Set_Property in the CREATE event, to 1 (one) which tells the loop to stop processing.

Call Set_Property(CtrlEntID[1, '.'], '@STOP', '1')

RETURN 0

Emulating a browse list

The QBFLIST property of the window can be loaded with an @vm delimited list of keys. That's how non-procedurally called popups, for example are intended to return key lists for browsing. The developer should then set the data entry windows QBFLIST property to the list of ids passed. Here is an example of issuing an Rlist select and passing the information in QBFLIST.

parent = CtrlEntID[1, '.']

stmt = "SELECT TABLE WITH COLUMN = 'Value'"

rlist(stmt, TARGET_SAVELIST$, 'QUERY_METHOD', '', '')
            * RLIST is documented latter in the doc - see table of contents
list = xlate('SYSLISTS', 'QUERY_METHOD', '', 'X')
call set_property(parent, 'QBFLIST', list)

Managing SELECT lists

Use the RLIST() system stored procedure, the parameters are:

RLIST(statement, target, targetName,userarg, debugflag)

1.0 RLIST arguments

Parameter 1 statementcharstr

R/LIST "LIST" or "SELECT" statement, for the most part the same as Advanced Revelation syntax except that inline formulas and inline "( )" options are not supported as such. Relevant in-line options may be supported by protocols with other arguments.

Parameter 2 targetinteger If statement is a LIST statement, target is TARGET_PRINTER by default. If statement is a SELECT statement, target is TARGET_SAVELIST by default.

TARGET_PRINTER$ 0Send output to printer (currently only LIST) TARGET_CLIENT$ 1Send output directly to the client (currently only LIST) no header/footer TARGET_UNUSED$ 2Not currently used TARGET_CALLBACK$ 3Call the specified callback function (see targetName). (Currently only LIST ). callback function receives text normally sent to printer. Header, footer and column header data included. TARGET_SAVELIST$ 4(SELECT only) - Saves list to name specified in targetName and/or to rotating queue of 10 last SELECT queries not left active or latent. TARGET_ACTIVELIST$ 5Resolve the list but do not save it to a named or default list. When RLIST returns, the list remains active. This is only useful when RLIST is called procedurally from another SSP. TARGET_LATENTLIST$ 6Do not resolve the list unless absolutely necessary and do not save it to a named or default list. When RLIST returns, the list remains active. This is only useful when RLIST is called procedurally from another SSP. TARGET_CHECKSYNTAX$ 7 Check the syntax of the statement and return status information but do not execute. For use by tools that allow users to enter query specifications.

Parameter 3 targetNamecharstr If Target is TARGET_CALLBACK then targetName is the name of the callback function. If targetName is NULL or invalid, a loading error will occur.

If Target is TARGET_SAVELIST then targetName is the name to save the list to in the SYSLIST table.

Parameter 4 userArgcharstr If Target is TARGET_CALLBACK then userArg accepts a string argument which will be passed to the callback function. See the section on callback function arguments and protocol. If RLIST is called procedurally from another SSP, userArg will return with the last value set by the callback function.

If Target is TARGET_SAVELIST then userArg accepts a description string to be saved into the header of the saved list.

Parameter 5 debugFlaginteger If set, the RLIST output program will be saved to disk as RLIST_OUT in SYSOBJ. This should probably be changed to save it to SYSPROCS under a name optionally specified by the user. If debugFlag is TRUE then the query is not executed.

2.0 Callback Function Arguments and Protocol

If Statement contains a LIST statement and Target is TARGET_CALLBACK then the module specified in TargetName will be called for every line of output with the following arguments.

code Code contains an integer value indicating the nature of the data passed in the Line argument.

CALLCODE_DATA$1 Regular textual data CALLCODE_INFO$2 Informational text lines supplied by the system. e.g. "10 lines printed…" CALLCODE_ERR$3 Error lines supplied by the system - e.g. file I/O errors CALLCODE_HEADER$4Page Header Text CALLCODE_COLHEAD$5Column Header Text CALLCODE_FOOTER$6Page Footer Text. Page footer text is not preceeded by pad lines necessary to fill out the page length. Footer may be blank if a footer is not specified, indicating a page change.

line (integer)One line of text output by the list processor module.

userArg (charstr) The first time the callback is called, this value is what is passed in the userArg argument of RLIST. The callback function may modify this value and it will be maintain and returned to subsequent invocations of the callback function. Finally, after the last call to the callback function, this value will be returned to RLIST and returned in the userArg argument of that stored procedure.

If the callback function returns FALSE (0 or NULL) then processing will be terminated in the LIST output processor and control will return to RLIST.

3.0 Saved List Queue Protocol

If RLIST Target is TARGET_SAVELIST then the resolved results of the query will be saved to a rotating queue of 10 "slots" numbers 0 for the most recent query to 9 for the oldest saved query. If a targetName is specified then the list will also be saved to the specified name. Queries older than the 9th query are deleted from the system. Named saved queries are not automatically deleted from the system. Every different user on every different machine has their own saved queue list which is private to them. Named saved lists are shared across users logged into the same database/application. There is no security on named saved lists. A queue header row in SYSLISTS maintains the list of the last 10 saved SELECTS for a user. The queue list header row key structure is:

"Q*" : @station : "*" : @username

The key structure for lists maintained by the queue list mechanism is as follows:

"W*" : @station : "*" : @username : "*" : <internal_date/time> [ "*" list_part_number ]

The first row of a saved list does not have a part number attached to it or a trailing "*". If there are multiple rows then subsequent rows have the part number appended, with "*" as a separator character. Numbering starts at "1" for the first overflow row and is incremented by one for each subsequent overflow row.

Note: key conventions for Temporary external lists (starting with "T*" are different than for queue working lists ("W*") or for saved lists ("S*"). The first row of Temporary external lists begin with a part number of "1" and increment from there. "W" and "S" lists begin with "0" implicitly, (but not actually appended to the key), and increment by one from there.

Each list entry in the queue is stored in a field and contains the following information

SELQ_LISTKEY$1 The root key of the working queue list SELQ_SELSTMT$2 The statement that generated the select list SELQ_RECCNT$3 The number of keys in the list

The fourth key part of the working list key root is the internal date/time it was created.

4.0 Named Save List Header Structure

Named saved select lists and queue working select lists have an optional header structure which is filled by RLIST. If a user creates "hand built" select lists which do not contain this header all subsequent use of that list by support SSPs should work correctly though they will lack certain information. A list informational header may be placed in the first field of a list by making the first character a text mark (@TM). The first line will be discarded by list activating processes. The header structure is text mark delimited and contains the following information:

SAVSEL_TIMEDATE$2 internal Date/time of creation SAVSEL_USER$3 User who created the saved select SAVSEL_RECCOUNT$4 Number of keys in the list SAVSEL_COMMENTS$5 User comments or notes about the saved select

5.0 Support System Stored Procedures

5.1 LIST_SAVE_SELECT

LIST_SAVE_SELECT lists to the client all named saved selects in SYSLISTS without regard to the originator (user).

Arguments:

noConvert (integer) FALSE$convert date/time of creation into external format before returning. TRUE$do not convert date/time of creation.

Returns:

One row per named saved select:

Col1:Name of list Col2:Date/Time of creation Col3:User who created the list Col4:Number of keys in list Col5:Comments/notes about list

5.2 GET_SAVE_SELECT

Return to the client all of the keys in a queued or named saved select, one key per row.

Arguments: listName (charstr) The identifier of the saved select to return.

0 - Most recently saved select 1 - Second most recently saved select … 9 - Last queued saved select Key of any othe named saved select.

Returns: multiple rows of one column, one key per row.

5.3 ACTIVATE_SAVE_SELECT

Creates an active select list from queued or named saved select. This is useful primarily when called from another SSP. All active selects are cleared when the top-level SSP returns control to the system.

Arguments: listName (charstr) 0 - Most recently saved select 1 - Second most recently saved select … 9 - Last queued saved select Key of any othe named saved select.

Returns: Active resolved select list.

5.4 DELETE_SAVE_SELECT

Deletes a queued or named saved select. If the entry is a queued saved select then the entry is removed from the queue header.

Arguments: listName (charstr) 0 - Most recently saved select 1 - Second most recently saved select … 9 - Last queued saved select Key of any othe named saved select.

5.5 LIST_SELECT_QUEUE

List information about the queries saved in the select queue.

Arguments:

userName (charstr) Name of "owner" of list. (default - self)

noConvert (integer) FALSE$convert date/time of creation into external format before returning. TRUE$do not convert date/time of creation.

Returns: One row per queued saved select: Col1: Date/Time of creation Col2: Statement that generated list Col3: Number of keys in list Col4: Comments/notes about list

5.6 CLEAR_SELECT_QUEUE

Delete all queued saved selects in the current users queue.

Arguments:None Returns:None

Emulating Window Common variables and Window Registers

You can specify your own variable space in any control by doing the following:

stat = Set_Property( cntrlEntID, '@YourVarNameHere', 'a value here' )

or shorthand:

cntrlEntId.@yourVarNameHere->'a value here'

This creates a storage variable property for the control which is named @YourVarNameHere. This variable is active during the runtime life of the parent window and can replace Label Common blocks to store counters, static text, or other satilite data.

  • tips/kb/openinsight_kb.txt
  • Last modified: 2023/08/10 07:09
  • (external edit)