Tips_gui   >   Misc   >   Misc (All Contents)
Various window objects allow you to show a vertical and/or horizontal scrollbar. The properties associated with this capability are $horzscroll and $vertscroll. Setting them to kTrue or kFalse shows or hides the particular scrollbar.
If the user scrolls the object an evHScroll or evVScroll $event message is sent to the object.
The $hscroll and $vscroll properties return an integer value telling you how far the user has scrolled. The integer value is a ratio of 1:8 pixel units. To convert the $hscroll or $vscroll property to pixels use the following calculation:
Calculate Pixels as 8*(ScrollableObjRef.$hscroll-1)
Calculate Pixels as 8*(ScrollableObjRef.$vscroll-1)
If you look in the System Classes folder of any libary you will see a #STYLES class and a series of #W*FONTS and #M*FONTS classes.
The Omnis Studio help states that #STYLES supercedes #W*FONTS, #M*FONTS. #STYLES is better because it not only allows you to specify different fonts for different platforms, but it also gives you full control over font size, font style, etc.
Once a style is declared and used in your library, any text which is assigned $fieldstyle is mapped to the row # in the #STYLES table, not the style name! If you change a style name in the table, the style name of all the text in your library which is mapped to that row will immediately change its $fieldstyle name to match the #STYLES style name. (Try it, it's harmless to do, just be sure to change it back.)
If a text related object with a $fieldstyle is copied into your library, Omnis Studio tries to match its name to the existing styles in the #STYLES table, if it finds a match, the $fieldstyle is then mapped to that row. If it doesn't find a matching style, Omnis Studio automatically adds the new style to the next available line in the #STYLES table.
If you don't have any styles in your library, your styles table will be built in the order that you drag components in. For example if you have an empty #STYLES tables in Library A and B. In Libary A and you first drag in a button object, #STYLES row 1 will be CtrlPushButton. In Library B you drag in an entry field first, row 1 will be CtrlEditText. As you can see, that can get messy if you decide later decide you want the same #STYLES table in all your libraries and you drag a brand new #STYLES class table into your library. If you drag #STYLES from Library A to Library B, the field styles which were mapped to #STYLE row 1, will still be mapped to #STYLE row 1. The $fieldstyles in your library are mapped to the row #, not the name!
To set up custom field styles:
For each style you can control the properties for All platforms, kMSWindow, kMacintosh (OS9), kUnix (Linux), and kMacOSX.
For any $has... property you set to kTrue in All platforms, the specified property can not be changed at the field level. If the styles says the $textcolor is kBlue and the $hastextcolor setting is set to kTrue, you won't be able to change the $textcolor property for that $fieldstyle at the field level. Change $hastextcolor to kFalse in the #STYLES class for the style, will allow you to change the default $textcolor at the field level.
I recommend that you create your own field styles in the #STYLES class for any special text you want to consistent cross-platform control of the font size and style. Here are some hints when you are doing this:
Here are some field styles to consider for reports:
Getting a window to reopen in the same position with multiple monitors on the Mac platforms is a bit tricky.
$modes.$width and $modes.$height returns the width and height of the main monitor (the one with the applications menu bar), ignoring additional monitors.
$modes.$height is the height not including the 22 pixels used by the applications menu bar. For a monitor set to 1200 pixels high, $modes.$height is 1178 pixels.
sys(104) and sys(105) return the overall total width and overall height of all the monitors provided that the main monitor is the left most monitor in your window and the tops of the extra monitors are not above the top of the main monitor.
If a monitor is located to the left of the main monitor is will not be included in the sys(104) width calculation.
If a monitor goes higher than the top of the main monitor the portion above the main monitor will not be included in the sys(105) height calculation.
You can move the applications menu bar from one monitor to another by dragging it to the other monitor in
If the resolution is different on the 2 monitors (one is 1200 pixels high, the other is 1024 pixels high) it becomes a bit of a guessing game outside of the main monitor where the top and bottom of the additional monitor really is.
If you have a dual monitor setup you can click the $modes.$width, $modes.$height, sys(104), and sys(105), for your current monitor arrangement. Move the window to each of the monitors. The demo will also tell you the top, left, bottom, and right pixel location of the window.
button in the window to find out the currentIn my applications I store the last size and position of each window instance for each user when they close the window. The next time they open the same window instance I restore it to the last size and position. If the user is on a different work station or goes from a multiple monitor setup to a single monitor the window instance may need to be resized and repositioned to fit on the available monitor space.
The sample code that follows checks the size and location of a window instance to make sure the window instance fits within the available monitor(s) and if not, resizes and repositions the window to fit within the available space. You are free to copy the code to your own application.The checkSizeAndFit method simply has a switch/case that checks the platform and call the respective checkSizeAndFit submethod.
; Parameter 1: prWinInst - Item Reference - reference to the window instance.
; Check and Size to the window to fit the available screen area.
Switch sys(6)
Case 'M','X'
Do method checkSizeAndFit_MacOS (prWinInst) Returns FlagOK
Default
Do method checkSizeAndFit_Default (prWinInst) Returns FlagOK
End Switch
Quit method FlagOK
The checkSizeAndFit_Default method is used for non-Mac platforms. For non-Mac platforms all Omnis window instances exist within the Omnis application space ($modes) so the method does not need to worry about the size and location of multiple monitors.
; Parameter 1: prWinInst - Item Reference - reference to the window instance.
; On Windows and Linux the Omnis application window is the max space.
Calculate AvailWidth as $modes.$width
Calculate AvailHeight as $modes.$height
Set reference rTopLevelFrame to prWinInst.$toplevelhwnd.$ref
; Adjust window size if it doesn't fit the available space.
If rTopLevelFrame.$width>AvailWidth
Calculate rTopLevelFrame.$width as AvailWidth
End If
If rTopLevelFrame.$height>AvailHeight
Calculate rTopLevelFrame.$height as AvailHeight
End If
; Reposition window if it is outside the available width.
If rTopLevelFrame.$left+rTopLevelFrame.$width>AvailWidth
Calculate rTopLevelFrame.$left as AvailWidth-rTopLevelFrame.$width
End If
; If the window is below the available height, move it up.
If rTopLevelFrame.$top+rTopLevelFrame.$height>AvailHeight
Calculate rTopLevelFrame.$top as AvailHeight-rTopLevelFrame.$height
End If
; Check to make sure the window is not off the top of the main monitor window.
If rTopLevelFrame.$top<0
Calculate rTopLevelFrame.$top as 0
End If
; Check to make sure the window is not off the left of the main monitor window.
If rTopLevelFrame.$left<0
Calculate rTopLevelFrame.$left as 0
End If
Quit method kTrue
The checkSizeAndFit_MacOS method is used for the Mac platform. On the Mac platform the Omnis window instances can exist outside of $modes space so the method needs to find out the size and location of external monitors using AppleScript then size and locate the window instance accordinly.
; Parameter 1: prWinInst - Item Reference - reference to the window instance.
; Overall Omnis application space on the Mac platform
; includes extra monitors to the left of the main monitor.
Calculate Width_MainMonitor as $modes.$width
; Note : main monitor height excludes the system bar (53 pixels)
Calculate Height_MainMonitor as $modes.$height
; Get the right bounds of the screen. May not be the whole deal if external on the left !
Calculate AScript as con('tell Application ',chr(34),'Finder',chr(34),chr(13),' set screensize to bounds of window of desktop',chr(13),' set returnval to item 3 of screensize',chr(13),' result',chr(13),'end tell')
Do $runapplescript(AScript,ScriptResult)
Calculate Width_Overall as ScriptResult
; Get the leftmost coordinate. Tells us if the external monitor is on the left (if negative).
Calculate AScript as con('tell Application ',chr(34),'Finder',chr(34),chr(13),' set screensize to bounds of window of desktop',chr(13),' set returnval to item 1 of screensize',chr(13),' result',chr(13),'end tell')
Do $runapplescript(AScript,ScriptResult)
; This takes account of having an external monitor on the left - if it is on the right then leftmost value is 0
Calculate Width_Overall as Width_Overall-ScriptResult
; If the main monitor width is the same as the overall width, we have no external monitor or its
; the same width and exactly on top or underneath - otherwise calculate the left of the external
Calculate ExternalMonitor_Left as pick(Width_MainMonitor<>Width_Overall,0,pick(ScriptResult=0,ScriptResult,Width_MainMonitor+1))
Calculate ExternalMonitor_Width as pick(Width_MainMonitor<>Width_Overall,Width_MainMonitor,pick(ScriptResult=0,-ScriptResult,Width_Overall-Width_MainMonitor))
; Get the height bounds of the screen.
Calculate AScript as con('tell Application ',chr(34),'Finder',chr(34),chr(13),' set screensize to bounds of window of desktop',chr(13),' set returnval to item 4 of screensize',chr(13),' result',chr(13),'end tell')
Do $runapplescript(AScript,ScriptResult)
; Note : if the external monitor is lower then this gives overall height, if higher then this is only the main mon height.
Calculate Height_Overall as ScriptResult
Calculate AScript as con('tell Application ',chr(34),'Finder',chr(34),chr(13),' set screensize to bounds of window of desktop',chr(13),' set returnval to item 2 of screensize',chr(13),' result',chr(13),'end tell')
Do $runapplescript(AScript,ScriptResult)
; Note : we have no way of knowing if the external monitor opens lower down than the main monitor, only if higher (so top is negative).
Calculate ExternalMonitor_Top as pick(Height_MainMonitor<>Height_Overall,0,ScriptResult)
; Note Omnis takes 53 off any value less than 0 but if we are on an external monitor we can put it back as we don't have the system bar!!
If ExternalMonitor_Top<0
; This corrects the height_overall where external is higher than main monitor
Calculate Height_Overall as Height_Overall-ExternalMonitor_Top
Calculate ExternalMonitor_Top as ExternalMonitor_Top-53
End If
; Note - we have no way of knowing if the external monitor is less height than the main monitor - only if it is taller
Calculate ExternalMonitor_Height as pick(Height_MainMonitor<>Height_Overall,Height_MainMonitor,Height_Overall)
; Note : the toolbar can be relevant to either main monitor.
Set reference rTopLevelFrame to prWinInst.$toplevelhwnd.$ref
; Make sure that the window's width is no greater than the overal monitor width
If rTopLevelFrame.$width>Width_Overall
Calculate rTopLevelFrame.$width as Width_Overall
End If
; Make sure that the window's height is no greater than the overal monitor height less the toolbar
If rTopLevelFrame.$height>Height_Overall-Toolbar_Height
Calculate rTopLevelFrame.$height as Width_Overall
End If
; If the window's left edge is inside the main monitor, use the main monitor as the available height.
If rTopLevelFrame.$left<=Width_MainMonitor&rTopLevelFrame.$left=0
; Note : the toolbar can be relevant to either main monitor.
If rTopLevelFrame.$height>Height_MainMonitor
Calculate rTopLevelFrame.$height as Height_MainMonitor
End If
; Make sure the top of the window is not off the top of the main window.
If rTopLevelFrame.$top<Toolbar_Height
Calculate rTopLevelFrame.$top as Toolbar_Height
End If
; Make sure the bottom of the window is not past the bottom edge of the main monitor.
If rTopLevelFrame.$top+rTopLevelFrame.$height>Height_MainMonitor-Toolbar_Height
If Height_MainMonitor-Toolbar_Height>rTopLevelFrame.$height
Calculate rTopLevelFrame.$top as Height_MainMonitor-Toolbar_Height-rTopLevelFrame.$height
Else
Calculate rTopLevelFrame.$top as Toolbar_Height
Calculate rTopLevelFrame.$height as Height_MainMonitor-Toolbar_Height
End If
End If
Else
; The window's left edge is outside of the main monitor, use ExternalMonitor_Height as the available height.
If rTopLevelFrame.$height>ExternalMonitor_Height
Calculate rTopLevelFrame.$height as ExternalMonitor_Height
End If
; Make sure the top of the window is not off the top of the external window.
If rTopLevelFrame.$top<ExternalMonitor_Top+Toolbar_Height
Calculate rTopLevelFrame.$top as ExternalMonitor_Top+Toolbar_Height
End If
; Make sure the bottom of the window is not off the bottom edge of the available space.
If rTopLevelFrame.$top+rTopLevelFrame.$height>ExternalMonitor_Height
If rTopLevelFrame.$height<(ExternalMonitor_Height-Toolbar_Height)
Calculate rTopLevelFrame.$top as ExternalMonitor_Height-rTopLevelFrame.$height
Else
; The window is larger than the available space, size it to fit.
Calculate rTopLevelFrame.$top as Toolbar_Height
Calculate rTopLevelFrame.$height as ExternalMonitor_Height-Toolbar_Height
End If
; If the extra monitor is smaller than the main monitor it could still be off the bottom of the extra monitor
End If
End If
; Make sure the right edge of the window is within the overall width.
Calculate Right as rTopLevelFrame.$left+rTopLevelFrame.$width
; If rTopLevelFrame.$left+rTopLevelFrame.$width>pick(ExternalMonitor_Left<0,Width_Overall,Width_MainMonitor)
If rTopLevelFrame.$left+rTopLevelFrame.$width>pick(ExternalMonitor_Left<0,Width_Overall,Width_MainMonitor)
Calculate rTopLevelFrame.$left as pick(ExternalMonitor_Left<0,Width_Overall,Width_MainMonitor)-rTopLevelFrame.$width
End If
; Make sure the left of the window is not off the left edge of the available space.
; ExternalMonitor_Left can be less than zero - if it is greater than 0 then 0 is our low point
If rTopLevelFrame.$left<min(0,ExternalMonitor_Left)
Calculate rTopLevelFrame.$left as min(0,ExternalMonitor_Left)
End If
Quit method kTrue
String tables can be used to support multiple languages. String tables are a good discipline to follow, even if you are supporting only one language.
Books on GUI recommend that developers use some sort of a common phrase dictionary for all the labels, titles, prompts, and messages throughout the application. By using a centralized phrase dictionary you are better assured that the same terminology is used for the same things throughout your application. This is especially critical for applications being developed by multiple programmers. The user becomes confused when in one window you refer to the a certain menu as the
and in another window you refer to it as .String tables could also be used for operating system sensitive terminlogy.
e.g. Mac vs. Win vs. Unix. Ctrl-Click vs. Right-Click
At the time of writing this section in StudioTips, finding the information on www.omnis.net/develop/resources/notes/technotes.html
took some effort. Eventually I found a Tech Note on the Omnis web site at:You can also download two string table demo libraries from Omnis: strtest.lbs and Table.lbs
This section of StudioTips goes through the information provided in the Tech Note giving demos and suggestion of how to implement . Each function is listed and explained.The
is a window interface which Omnis has created to assist developers in creating, editting, and saving String Tables.To open the
look under the menu > > ... Look through the and menus. Hold your mouse of the toolbar buttons to review all the functions that Omnis has provided for you to use.When you
a string table, Omnis sorts the table on the ID column just prior to saving it. This is done to speed lookups when the string table is being used.For editing an existing string table, you have the option of exporting it, editing it in Excel and then importing it. You might find it easier to create your string table in
and then import it.If you aren't happy with the
you can roll your own. Click the button in the to open the StudioTips custom String Table Editor.So, how do you go about using string tables in your own application? Well, as usual there are many ways. Some developers choose to create and store the string tables as lists which are stored in the data file, rather than using actual string table files stored on disk. In that case you would use $loadtablefromlist instead of $loadstringtable.
My own preference at this stage is to save and load the string tables as files.
To keep your string tables manageable, it is recommended that you have separate string tables for various categories. For example you can have separate string tables for:
You should store all the string table files in a separate directory below the main library of your application. For StudioTips I created a string_tables folder located inside the demos folder.
Even if you are currently only developing your application in one language, the use of string tables can be a good discipline for keeping your terminology consistent throughout your application.As I was adding labels to the entry fields on a window the idea occurred to me to create a string table for each server table and to use the server table column name as the string table ID column. Every colum in my database would be mapped to a unique string table row.
I have embarked on a mission to create a string table for every SQL table that has data which is displayed on a window or report.
For example, a server table column name of ChequeNumber in the en-US (English-US) column will say Check Number and in the en-GB (English-British) column will say Cheque Number.
In your windows and report instead of entering the actual field label text, you can use a kText field and put the following square bracket notation:
[StringTable.$gettext('SQLTable.ColumnName')]
No further thinking or coding is required! When the window opens the labels will display the correct label text for the language column that was set when the library was opened. If I or my client want to change the label for the server table column LastName from Last Name to Surname ... no problem. Change it in the string table and every place LastName is displayed will be changed from Last Name to Surname.
To speed up creation of string tables which match existing schema classes, I created a
StudioTips includes the custom String Tables Editor with the which allows you to select a schema class and then using a context menu call a method which builds a string table list with the ID and 1st language column already filled in. You can then edit and save the string table as a file. feature. Click the button in the to open the StudioTips custom .Omnis provides a handy
external component which works well with string tables. You will find the in the under .The String Table Label has a property $rowid under the tab where you enter TableName.ID
One alternative is to use "text" background objects and enclose the $gettext function in [square brackets].If you are using string tables for supporting various languages, you may want to use the same language abbreviations used by the web browsers. Why bother figuring out codes for the various languages, when there is already a standard being used.
To find out the code, open the
in your web brower and click on the preferences setting. Click on the button, and you will be prompted with a list of languages and their abbreviations.Don't include parenthesis () in your string table column names ... the brackets will mess up your notation.
The headed list $columnnames property doesn't evaluate [] square bracket $gettext notation. One workaround is to build the $columnnames string in the $construct method of the headed list.
Click to see how this can be done.Do StringTable.$colcnt([TableName])
Returns the column count for TableName.Do StringTable.$getcolumnname(TableName)
Gets the column name for the current column.Do StringTable.$getcolumnnumber(TableName)
Gets the column number for the current column.Do StringTable.$gettext('[TableName.]ID') Returns Text
Gets the text in the current column of the specified String Table for the row matching ID.
You can use square brackets in a kText label:
[StringTable.$gettext('TableName.ID')]Do StringTable.$loadcolumn(ColumnName,TableName,Path)
Creates a string table file using a single column of an existing string table.Do StringTable.$loadlistfromtable(TableName) Returns List
Loads a string table already in memory to a list variable.Do StringTable.$loadstringtable(TableName,Path)
Loads an existing string table into memory from an existing string table file.
Note: If the string table has already been loaded, you must first $unloadstringtable. Trying to load the same string table will result in an error.Do StringTable.$loadtablefromlist(TableName,Path,List) Returns ErrCode
Creates a string table from a list variable. It should be noted that the table is created in memory at this point. To save the table, use $savestringtable.
Although this command requires a path, it doesn't actually create the file until you issue the $savestringtable.
If the String Table has already been loaded, you must first $unloadstringtable. Trying to load the same string table will result in an error.Do StringTable.$redraw(WindowInstanceRef.$hwnd)
Redraws the string table labels on an entire window.
Not including the .$hwnd will cause Omnis Studio to crash. (I know from experience!)
Redraw all windows after selecting a new string table.
This is not a string table function. This is a method you can create/use for redrawing all the string table labels in all the open windows.Do StringTable.$removestringtable(Path)
Deletes a string table stored on disk.
This function really does delete the string table file!
Do StringTable.$rowcnt([TableName])
Returns the row count for TableName.Do StringTable.$savestringtable(TableName)
Saves a string table which has been previously created.
Note: A path name is not required when saving. Pathnames are only specified when creating string tables.
If you had a new string table in a list, the process of creating the new string table file on disk would be as follows:
; Saving a string table to disk.
; First unload the String Table if it has already been loaded.
Do StringTable.$unloadstringtable(TableName)
; Load the list and path into the String Table to be held in memory.
Do StringTable.$loadtablefromlist(TableName,Path,List)
; The path was loaded into the String Table, so it's already there when you $savestringtable().
Do StringTable.$savestringtable(TableName)
Do StringTable.$setcolumn([StringTableName.]ColumnName)
Sets the current column to ColumnName. This may be either a name or a number.
Note: ColumnName is case sensitive. If multiple string tables are being used then the format needs to be TableName.ColumnName
Do StringTable.$setcolumn("Table1.French")
or
Do StringTable.$setcolumn("Table1.3")Do StringTable.$unloadall()
Unloads all string tables from memory.
This function is optional, as all String Tables are automatically unloaded when Omnis quits.Do StringTable.$unloadstringtable(TableName)
Unloads a string table from memory.
This function is optional, as all string tables are automatically unloaded when Omnis quits.