OPL Tips

Whilst I'm developing OPL programs for EPOC based machines I will keep note of any useful tips I discover and make them available on this page.

Contents

Starting out

The OPL programming manual

There should be a copy of the OPL manual on the CD that came with your machine; try looking in the EXTRAS folder. If you would like a copy in EPOC Word format then see my OPL Manual page. You can also download a useful help file for use on an EPOC machine from EPOC World.

It is a good idea to read all of the manual, though probably in small chunks :o) Even though a lot of it may not sink in on first reading, at least when you want to do something new you may have a vague recollection of some useful in a certain chapter and be able to find it again.

First steps

For an excellent introduction to OPL programming see Steve Litchfields Programming features

Newsgroup for programmers

The UseNet newsgroup for EPOC programmers is comp.sys.psion.programmer You may want to read this regularly to see if you can pick up some tips from what other people are talking about.

You can post questions there asking for help, but please make sure first that the answer is not in the manual. :o)

Also; it's good form to prefix the subject line of a posting with something like "[EPOC OPL]", this means that people who don't program for EPOC or in OPL can quickly skip the post. It also means you are more likely to get an relevant answer to your query.

Style guide for EPOC programs.

There is a style guide for EPOC programs. This is produced by Symbian and is used by both Symbian employees and external developers to help give all programs the same look and feel. It is a good idea to follow these style suggestions where possible so that any user of the programs that you write will have a familiar way of interacting with it.

Unfortunately, this style guide no longer appears to be available on the EpocWorld web site, however it is contained in the documentation which comes with the various SDKs available.

Making MBM picture files on an EPOC machine.

You can produce graphics files for use in OPL programs by exporting a picture from sketch as an 'EPOC Picture'. This will produce a Multiple BitMap (MBM) file that contains a single picture. If you want to produce files on your EPOC machine which contain more than one picture then Lieuwe de Vrie has produced an excellent program called MBMView which lets you view and edit MBM files. Check out his web site.

Smoother screen updates.

Use gUPDATE OFF at the start of any code that draws several items to the screen. This will queue up all the graphics commands until you use gUPDATE ON, when they will all be processed together. Note: if your program spends a lot of time between a pair of gUPDATE OFF and gUPDATE ONs then you may need to use IOYIELD occasionally. (See the OPL manual.) This allows the operating system time to process events such as key presses.

Using CaptureKey&

If you use CaptureKey& then you will need to set the compute mode up correctly so that a program can react immediately to a key press. The following code will ensure this by making a program run at full speed even whilst it is in the background.

  REM Give program a high priority

  SetComputeMode:(KComputeModeOff&)

  REM Prevent program from changing to low priority
  REM when it gets sent to the background

  SetComputeMode:(KComputeModeDisabled&)

If you use the above then it is important that your program gives up time to the CPU to process other tasks. This is usually done with IOWait or GetEvent32 which suspend a program until it receives an event. If you don't then your program will significantly slow down the foreground program that the user is trying to use.

Making programs work on different EPOC machines.

Introduction.

There are several different screen sizes used by various EPOC devices and no doubt more variations will appear in the future. Therefore a program should not assume anything about the screen size. E.g. if a program were to be written assuming a 640x480 sized Series 5 screen, then part the program's display wouldn't be visible on a Revo and it would only use half the available screen space on a Series 7. Neither of these looks very professional.

There are also other differences which need to be considered, including toolbars and screen colours available.

Screen sizes.

It is possible to write a one-size-fits-all program and the first step in achieving this is for the program to determine what size screen is available to it. Fortunately when an OPL program is run it is given a default window to use which is the full size of the screen. Therefore some code like the following can be used at the start of a program.

  GLOBAL ScreenWidth%,ScreenHeight%

  ScreenWidth% = gWIDTH
  ScreenHeight% = gHEIGHT

This provides two global variables that a program can use as a basis to calculate all screen positions and window sizes.

If the program uses a toolbar then it can be initialised so that it always appears at the right-hand edge of the screen by:

  TBarInit:("Program Name",ScreenWidth%,ScreenHeight%)

As the toolbar may also have a different size on different machines the total size of screen available to a program should be calculated using the TBWidth% variable and not a fixed number. E.g.

  IF MyToolbarIsVisible
    MyMainWindowWidth% = ScreenWidth%-TBWidth%
  ELSE
    MyMainWindowWidth% = ScreenWidth%
  ENDIF
  MyMainWindowHeight% = ScreenHeight%

The rest of the program should now use these new variables as the screen size available. E.g. to draw a box around the border:

  gAT 0,0
  gBOX MyMainWindowWidth%,MyMainWindowHeight%

Toolbar differences.

The smaller EPOC machines like the Psion Revo don't have enough space on the toolbar buttons for both icons and text, so it is best to not to give them an icon when initialising a button. E.g.

  IF TBWidth% >= 64   REM Toolbar wide enough for icons?
    TBarButt:("k",1,"Text label",0,Icon&,IconMask&,0)
  ELSE
    TBarButt:("k",1,"Text label",0,0,0,0)
  ENDIF

The number of toolbar buttons also varies from machine to machine; the Revo has three, the Series 5 has four and the Series 7 has six.

One option is to play safe and only specify four buttons, - the Revo is OK with this though it only displays three of them. However, it is possible to make use of the extra buttons, but first the maximum number available needs to be found. (Because trying to initialise more than are available can result in a run-time error.)

The number of toolbar buttons can be determined with the statement PEEKW(ADDR(TbBtFlags%())-2). This trick works because after Toolbar.opo has been initialised a global array called TbBtFlags% is created which has a dimension equal to the maximum number of buttons. The PEEK statement reads this dimension. Example:

  LOCAL numButtons% = PEEKW(ADDR(TbBtFlags%())-2)

  TBarButt:("a",1,"Text label 1",0,Icon1&,IconMask1&,0)
  TBarButt:("b",2,"Text label 2",0,Icon2&,IconMask2&,0)
  TBarButt:("c",3,"Text label 3",0,Icon3&,IconMask3&,0)
  TBarButt:("d",4,"Text label 4",0,Icon4&,IconMask4&,0)
  IF numButtons% >= 5
    TBarButt:("e",5,"Text label 5",0,Icon5&,IconMask5&,0)
    IF numButtons% >= 6
      TBarButt:("f",6,"Text label 6",0,Icon6&,IconMask6&,0)
    ENDIF
  ENDIF

When deciding which functions should appear on the toolbar, it is obviously a good idea to order them so that the most useful appear first, because buttons 4,5,6... wont be available on all EPOC machines.

OPL Bugs.

dFILE bug.

If dFILE is used with the System folder in the seed path then a crash will happen if the user taps the 'Folder' box in a dialog. e.g.

  file$ = "C:\System\Apps"
  ...
  dFILE file$,"File,Folder,Disk",770

To get around this I check for the System folder in the seed path and if it is present I set the path to the root folder. e.g.

  IF LEN(file$)>=10                        REM is file$ long enough
    IF UPPER$(MID$(file$,4,7))="SYSTEM\"   REM are chars 4 thru 10 = "SYSTEM\"
      file$=LEFT$(file$,3)                 REM file$ = left 3 chars e.g. "C:\"
    ENDIF
  ENDIF
  dFILE file$,"File,Folder,Disk",770

dFILE bug 2.

If the seed path you give to dFILE contains a file extension then it is not possible for the user to change this to a name without an extension. This is because dFILE will add it back in. E.g.

  path$ = "C:\ABC.XYZ"
  ...
  dFILE path$,"File,Folder,Disk",1    REM [user changes 'ABC.XYZ' to 'NAME']
  ...
  REM path$ is now "C:\NAME.XYZ" not "C:\NAME"

This may not be a bug, but it can be a very annoying feature.

To avoid this you can use SaveAsFileDialog&: or CreateFileDialog&: which are in SYSTEM.OPX. These do not suffer from this problem.

Toolbar title bug.

There is a bug in the Toolbar.opo, at least on ROM 1.00.

When you call SetToolbarTitle: it tries to do the sensible thing and print the title centred in its box if it will fit, or left aligned if it won't. However, when it calculates the size of the title, it does so before it has set the font. This can lead to some titles being clipped on the left and right.

To get around this problem, call SetToolbarTitle twice in a row. The first may get it wrong but the font will then be set, so the second call will get things right.

System.opx bugs and quirks.

MediaType&: returns flash cards in drive D: as type 'hard disk' not 'flash' as I would have expected. It also returns some very funny values for non-existent drives instead of the 'not present' code.

VolumeSpaceFree&: returns free space in kilobytes not bytes as the OPL manual says.