Liberty Basic is develeopped by Carl Gundel
Original Newsletter compiled by Alyce Watson and Brosco
Translation to HTML: Raymond Roumeas

The Liberty Basic Newsletter - Issue #60 - JAN 2000

© 1999, Cliff Bros and Alyce Watson - All Rights Reserved

In this issue:

  1. A look at the future...
  2. Writing an editor for Liberty BASIC - Part Three Tooltips!

In future issues:

  1. Writing an editor for Liberty BASIC - more??
  2. Installers for our Liberty BASIC programs.
  3. Variables and arrays.


1.A LOOK AT THE FUTURE...

have received so many messages regarding the series on writing an editor for Liberty BASIC, that we will certainly continue with it. Each newsletter that adds to our open source editor should be of interest to everyone - even to those who do not want to write an editor!

The methods and routines involved will be applicable to many other types of programs, so please take the time to read the articles!

Some planned additions to the editor include a wav previewer, a bitmap previewer, access to branch labels font change for the texteditor, and... suggestions are always welcome.

Some clever people have sent me their own modifications of this open source editor. All I can say is, "WOW!" I hope everyone will share his modifications with the community at large. As we have seen so many times, our creativity and knowledge base expand tremendously when we work together.


WHAT ARE TOOLTIPS?

Tooltips are small text messages that appear when the user moves his mouse over a control such as a button, and hovers there for a moment. The messages describe the function of the control. Tooltips do not appear instantly, but only become visible when the mouse cursor hovers over the control for a moment. They do not stay onscreen indefinitely, either. They disappear when the user moves his mouse, or they time-out when they have been visible for a few seconds.

CAN WE MAKE TOOLTIPS IN LIBERTY BASIC?

You bet. Over the years, people have come up with numerous ways to simulate Windows tooltips. It can be done with graphic text, or even with graphicboxes that are displayed and hidden at the proper times. Doing it right takes quite a bit of coding, including timing functions and checking for mouse location.

2.REAL WINDOWS TOOLTIPS!

Brent Thorn has discovered the way to make real Windows tooltips work in Liberty BASIC. It requires the help of commctrl.dll. It takes a bit of code to set them up, but once the setup is accomplished, WINDOWS takes care of everything else! Windows itself detects when the mouse is over the button and shows the tooltip after a short delay. Windows removes the tooltip after a few seconds. The tooltip will display slightly to the right and below the mouse cursor. Its background will match the user's system colors.

******* NOTE *******

This will work for Win95+ and for later versions of Win3.1 that have Win32s installed. If you are not sure if you have Win32s, search your Windows directory for it.

******* NOTE *******

Let's put them into our editor!
TOOTIP SETUP

Windows must have access to the information in the commctrl.dll to make tooltips. To give this access, we open the DLL and initialize it:

open "commctrl.dll" for dll as #cctl
calldll #cctl, "InitCommonControls", re as void

In our [exit] routine, we'll close #cctl. Tooltip creation requires that we have the instance handle to the window. We get this with the function GetWindowWord. We pass the window's handle as the first parameter, then the Windows constant for retrieving the instance handle, which is GWW_HINSTANCE, and the function returns the instance handle, which we'll use later.

Since the value for GWW_HINSTANCE is a negative number, we must put it together with 0 using the bitwise OR operator. (See nl #57 for more on bitwise operations.)

GWW = _GWW_HINSTANCE or 0
calldll #user, "GetWindowWord", h as word,_
GWW as word, hInstance as word

We'll need values for some Windows constants in order to make the API function call to create the tooltips. Here are the values we will need. For more information on using Windows constants in API calls, please see nl #57.

CW.USEDEFAULT   = hexdec("8000")
TTF.IDISHWND    = hexdec("0001")
TTF.SUBCLASS    = hexdec("0010")
TTM.ADDTOOL     = _WM_USER+4

All Windows controls are actually "Child Windows" of the window upon which they appear, and most controls are created with a call to CreateWindow. Here is a generic CreateWindow call.

calldll #user, "CreateWindow", _
classname$ as ptr, _
windowname$ as ptr, _
style as long, _
Xorigin as word, _
Yorigin as word, _
width as word, _
height as word, _
handleParent as word, _
Menu as word, _
handleInstance as word, _
null$ as ptr, _
handleTooltipWindow as word

The classname$ param sets the type of control to be created. It can be "BUTTON", "COMBOBOX", &etc. The classname$ we need here is "tooltips_class". We are used to seeing our controls on the parent window. We will not see our tooltip control; it is not something that can be clicked by our program's user.

Rather, it is a control that functions in the background to handle ALL tooltips we add to a window's visible controls. It is essential that commctrl.dll has been initialized, or Windows will not recognize the "tooltips_class". The DLL will probably be initialized when Windows starts up, but we will initialize ourselves, just to be sure.

calldll #cctl, "InitCommonControls", re as void

The next param in the CreateWindow function is the windowname$. For a window, this would be the text on the titlebar. For a button, it would be the button caption. For static text, it would be the text displayed on the control. A tooltip control does not have a windowname$, so we make it null.

The next param is the style flag. For a tooltip control, this is set to 0.

style = 0

The next params set the x origin, y origin, width and height of the control. These don't really apply to our tooltip control, so we'll let Windows manage these by making them have a value of _CW_USEDEFAULT. (See newsletter #57 for a discussion of Windows constants.)

The next parameter is essential. It is the handle of the window that is parent to the tooltip control. We pass our window handle, which is retrieved with LB's HWND function:

handleParent as word, _

The next parameter is not used, since it designates the menu to use for the control, and tooltip controls do not use menus.

Menu as word, _

The next parameter is also essential. It is the instance handle of our window, which we obtained earlier with a call to GetWindowWord.

handleInstance as word, _

The next parameter is not used:

null$ as ptr, _

The CreateWindow call returns the handle of the control we have created, if it is successful:

handleTooltipWindow as word

And here is the function call from the program:

    calldll #user, "CreateWindow", _
        "tooltips_class" as ptr, _
        "" as ptr, _
        style as long, _
        CW.USEDEFAULT as word, _
        CW.USEDEFAULT as word, _
        CW.USEDEFAULT as word, _
        CW.USEDEFAULT as word, _
        h as word, _
        0 as word, _
        hInstance as word, _
        "" as ptr, _
        hwndTT as word
 

We now have a tooltip control for our program window. It won't DO anything for us, though! We need to take three steps for EACH control that is to have a tooltip. We must set up a struct, fill the struct with the proper values, then add the tooltip to the tooltip control.


MAKE A TOOLTIP STRUCT

We must make a separate struct for each control that is to display a tooltip. Each struct must have a unique name.

    struct toolinfo1,_
    ........
    struct toolinfo2,_
    ........
    struct toolinfo3,_
    ........
    &etc.

The struct contains the following fields:

    cbSize as word,_      'size of struct
    uFlags as word,_      'flags for tooltip type
    hwnd as word,_        'parent window handle
    uId as word,_         'handle of control
    x as word,_           'x origin of control
    y as word,_           'y origin of control
    w as word,_           'width of control
    h as word, _          'height of control
    hInst as word,_       'window instance handle
    lpstrText$ as ptr     'text to display on tooltip

Our program will have tooltips for all 15 buttons, so we must set up 15 separate structs, each with a unique name:

'** MAKE A STRUCT FOR EACH TOOL
    struct toolinfo1, cbSize as word, uFlags as word,_
        hwnd as word, uId as word, x as word, y as word,_
        w as word, h as word, _
        hInst as word, lpstrText$ as ptr
 
    struct toolinfo2, cbSize as word, uFlags as word,_
        hwnd as word, uId as word, x as word, y as word,_
        w as word, h as word, _
        hInst as word, lpstrText$ as ptr
 
&etc. &etc.

Sure, its a bit of code, but it will actually save many lines of code compared with the pseudo tooltips we have used in the past. It will also function much better!


FILL A TOOLTIP STRUCT

The first struct item to fill is the size. Our struct is 22 bytes long, so:

    toolinfo1.cbSize.struct = 22

Now, we set up the type of tooltip. We will use these flags:

    toolinfo1.uFlags.struct = TTF.IDISHWND or TTF.SUBCLASS

The hwnd item requires the parant window handle:

    toolinfo1.hwnd.struct = h

Earlier, we used the TTF_IDISHWND flag. It might make more sense to break that up: ID IS HWND. This tells Windows that the uID item in the struct is the HWND of the control. With the TTF_IDISHWND flag set, then we must place the control's handle into this part of the struct:

    toolinfo1.uId.struct = hwnd(#1.new)

The next four parameters do NOT need to be filled, because we have used the TTF_IDISHWND flag:

    x as word,_           'x origin of control
    y as word,_           'y origin of control
    w as word,_           'width of control
    h as word, _          'height of control
 

We do not need these values, because Windows has the handle of the control, and computes the values for us. We need to place the instance handle we obtained with GetWindowWord into the struct.

    toolinfo1.hInst.struct = hInstance

The last parameter we need to fill is the caption, or text that will be displayed on the tooltip when it is activated:

    toolinfo1.lpstrText$.struct = "New File"	

We must fill ALL 15 structs for the 15 buttons that will use tooltips in our program:

    toolinfo1.cbSize.struct = 22
    toolinfo1.uFlags.struct = TTF.IDISHWND or TTF.SUBCLASS
    toolinfo1.hwnd.struct = h
    toolinfo1.uId.struct = hwnd(#1.new)
    toolinfo1.hInst.struct = hInstance
    toolinfo1.lpstrText$.struct = "New File"
 
    toolinfo2.cbSize.struct = 22
    toolinfo2.uFlags.struct = TTF.IDISHWND or TTF.SUBCLASS
    toolinfo2.hwnd.struct = h
    toolinfo2.uId.struct = hwnd(#1.open)
    toolinfo2.hInst.struct = hInstance
    toolinfo2.lpstrText$.struct = "Open File"
 
&etc. for the other 13!

That seems like a lot of code, but it is easy stuff to addmore tooltips, once we understand the form and syntax. We are still not finished! After setting up the structs and filling them, we must add each tooltip to the tooltip control. We do this with the SendMessage API call. The message is sent to our tooltip control, so we pass that handle as the first param. The message is TTM_ADDTOOL,so we pass that as the next param. The word param is not used here, so it is 0. The long param contains theaddress (in Liberty BASIC this is the name of...) the tooltip struct.

 
    calldll #user, "SendMessage",_
    hwndTT as word,_            'tooltip control handle
    TTM.ADDTOOL as word, _      'flag to add a tip
    0 as word,_                 'not used
    toolinfoX as struct,_       'struct for tip info
    re as long

Again we must send this message 15 times, once for EACH control that will display a tooltip:

    calldll #user, "SendMessage", hwndTT as word, TTM.ADDTOOL as word, _
    0 as word, toolinfo1 as struct, re as long
 
    calldll #user, "SendMessage", hwndTT as word, TTM.ADDTOOL as word, _
    0 as word, toolinfo2 as struct, re as long
 
    calldll #user, "SendMessage", hwndTT as word, TTM.ADDTOOL as word, _
    0 as word, toolinfo3 as struct, re as long
 
&etc. for all 15 tooltips!

We are now done! Windows now knows which controls should display tooltips, and Windows will detect mouse movement over these controls, and manage the display/hiding of the tooltips, using the text we have specifed for each one.

Here is the complete code:


'** Liberty BASIC Newsletter
'** Open Source Editor
'** Please add your name to
'** the list of authors:
'**
'** Authors:
'**
'** Alyce Watson
'**
nomainwin
    open "user" for dll as #user
    dim info$(10,10)                'for file exist check
 
'** NEW **
    open "commctrl.dll" for dll as #cctl
cursor hourglass
 
'variables:
'file$              name of file to open
'title$             titlebar caption
'h                  is window handle
'modflag$           is answer to modified query
'answer$            receiver variable for confirm messages
'tempfilename$      name to use when running and debugging code
'rowVar,columnVar   location of texteditor origin
'fileindex          used for counter in path/file separation
'filelength         used for counter in path/file separation
'shortFile$         just filename without path
'filePath$          path without filename
'saveit$            receiver for input from texteditor
'libertyexe$        path to Liberty.exe for running/tokenizing/debugging
'tknfile$           name of tkn to run
'red                red value
'green              green value
'blue               blue value
'menuColor          system menu color
 
'** NEW **
'hInstance          window instance handle
'
'for tooltips:
    GWW = _GWW_HINSTANCE or 0
    style           = 0
    CW.USEDEFAULT   = hexdec("8000")
    TTF.IDISHWND    = hexdec("0001")
    TTF.SUBCLASS    = hexdec("0010")
    TTM.ADDTOOL     = _WM_USER+4
 
menu #1, "&File",_
    "&New",[new],_
    "&Open",[open],_
    "&Save",[save],_
    "Save &As",[saveas],|,_
    "&Print",[print],_
    "E&xit",[quit]
 
menu #1, "&Edit" 'LB supplies the Edit Menu
 
menu #1, "&Run",_
    "Ru&n", [run],_
    "&Debug",[debug],_
    "&Make TKN",[maketkn],_
    "Run &TKN",[runtkn]
 
menu #1, "E&xternals",_
    "&Paintbrush",[paint],_
    "&File Manager",[winfile],_
    "&Notepad",[notepad],_
    "&Calculator",[calculator]
 
menu #1, "&Help",_
    "&Liberty BASIC Help",[help],_
    "LB &Tutorial",[tutorial]
 
    texteditor #1.t, 0,40,600,400  'edit window
 
    graphicbox #1.g, -1,-1,800,21  'toolbar
    button #1.new,     "New",   [new],       UL,3,2,30,15
    button #1.open,    "Open",  [open],      UL,34,2,30,15
    button #1.save,    "Save",  [save],      UL,65,2,30,15
    button #1.saveas,  "..As",  [saveas],    UL,96,2,30,15
    button #1.print,   "Print", [print],     UL,127,2,30,15
 
    button #1.run,     "Run",   [run],       UL,167,2,30,15
    button #1.debug,   "Debug", [debug],     UL,198,2,30,15
    button #1.token,   "TKN",   [maketkn],   UL,229,2,30,15
    button #1.runtkn,  "R tkn", [runtkn],    UL,260,2,30,15
 
    button #1.paint,   "Paint", [paint],     UL,300,2,30,15
    button #1.file,    "F Mgr", [winfile],   UL,331,2,30,15
    button #1.note,    "Note",  [notepad],   UL,362,2,30,15
    button #1.calc,    "Calc",  [calculator],UL,393,2,30,15
 
    button #1.help,    "Help",  [help],      UL,433,2,30,15
    button #1.tutor,   "Tutor", [tutorial],  UL,464,2,30,15
 
open "Open Source LB Editor" for window as #1
 
    h=HWND(#1)
    print #1, "trapclose [quit]"
    print #1, "resizehandler [resize]"
 
    calldll #user, "ShowWindow",h as word,_SW_MAXIMIZE as ushort,result As
word
 
    print #1.new,     "!font arial 0 12"
    print #1.open,    "!font arial 0 12"
    print #1.save,    "!font arial 0 12"
    print #1.saveas,  "!font arial 0 12"
    print #1.print,   "!font arial 0 12"
    print #1.run,     "!font arial 0 12"
    print #1.debug,   "!font arial 0 12"
    print #1.token,   "!font arial 0 12"
    print #1.runtkn,  "!font arial 0 12"
    print #1.paint,   "!font arial 0 12"
    print #1.file,    "!font arial 0 12"
    print #1.note,    "!font arial 0 12"
    print #1.calc,    "!font arial 0 12"
    print #1.help,    "!font arial 0 12"
    print #1.tutor,   "!font arial 0 12"
 
    print #1.t, "!setfocus";
    gosub [colorToolbar]
 
'** NEW **
    gosub [addTooltips]
    cursor normal
 
[loop]
    input a$
 
[quit]
    gosub [isModified]
    close #user: close #1 : close #cctl
    if tempfilename$<>"" then kill tempfilename$ 
    END
 
[isModified]'** CHECK TO SEE IF FILE HAS BEEN MODIFIED
    print #1.t, "!modified?":input #1.t, modflag$
    if modflag$="true" then
        confirm "This file has been modified.  Save?";answer$
        if answer$="yes" then gosub [savesub]
    end if
    RETURN
 
[resize]'** LOCATE TEXT EDITOR
    '** LOCATE TEXTEDITOR 20 PIXELS FROM TOP OF CLIENT AREA
    print #1.t, "!locate 0 20 ";WindowWidth-1;" ";WindowHeight-21
    print #1.t, "!origin?";
    input #1.t, rowVar,columnVar
 
    '** LOCATE GRAPHICBOX - WindowWidth+2 WIDE, 21 PIXELS HIGH
    print #1.g, "locate -1 -1 ";WindowWidth+2;" 21"
 
    '** UPDATE WINDOW
    print #1, "refresh"
    print #1.t, "!origin ";rowVar;" ";columnVar;"";
    goto [loop]
 
[new]'** CLEAR EDITOR CONTENTS, RESET VARIABLES
    gosub [isModified]
    print #1.t, "!cls"
    file$="untitled.bas"
    filePath$=""
    gosub [settext]
    goto [loop]
 
[open]
    gosub [isModified]
    filedialog "Open file..",filePath$+"*.bas",file$ 
    if file$="" then [loop]
 
    fileindex=len(file$)  'separate path and filename
    filelength=len(file$)
        while mid$(file$, fileindex,1)<>"\"
            fileindex=fileindex-1
        wend
 
'** USE FILES STATEMENT TO CHECK FOR FILE'S EXISTENCE
    shortFile$=right$(file$,filelength-fileindex)
    filePath$=left$(file$,fileindex)
    files filePath$,shortFile$,info$(
    if val(info$(0,0))<1 then
        notice "Error"+chr$(13)+"File does not exist."
        goto [loop]
    end if
 
[loadFile]'** OPEN FILE AND LOAD INTO TEXTEDITOR
    cursor hourglass
    open file$ for input as #file
    print #1.t, "!contents #file"
    close #file
    gosub [settext]
    print #1.t, "!origin 1 1";
    cursor normal
    goto [loop]
 
[settext]'** ADD FILENAME TO TITLEBAR
    title$="Open Source LB Editor "+file$
    calldll #user, "SetWindowText", h as word, title$ as ptr, result as void
    return
 
[saveas]'** SAVES CONTENTS AS file$
    filedialog "Save file as..",filePath$+"*.bas",file$ 
      if file$="" then
        notice "You must choose a file name."
        goto [loop]
      end if
    gosub [settext]
 
[save]'** SAVES CURRENT FILE
    gosub [savesub]
    goto [loop]
 
[savesub]
    cursor hourglass
    print #1.t, "!contents?";
    input #1.t, saveit$
 
'** IF THERE IS NO CURRENT FILENAME, ASK USER FOR ONE
    if (right$(file$,12)="untitled.bas") or (file$="") then
        filedialog "Save file as...",filePath$+"*.bas",file$ 
          if file$="" then
            notice "You must choose a file name."
            RETURN
          end if
    end if
 
    open file$ for output as #file
    print #file, saveit$
    close #file
 
    cursor normal
    notice "File saved as "+ file$
    RETURN
 
[print]
    cursor hourglass
    print #1.t, "!origin?";
    input #1.t, rowVar,columnVar
    print #1.t, "!contents?";
    input #1.t, saveit$ 
    lprint saveit$
    dump
    print #1.t, "!origin ";rowVar;" ";columnVar;"";
    cursor normal
    goto [loop]
 
[readyRun]'** MAKE A TEMP FILE TO RUN IN LIBERTY BASIC
'** GET CURRENT TEXTEDIT ORIGIN
    print #1.t, "!origin?";
    input #1.t, rowVar,columnVar
 
'** GET CONTENTS OF TEXTEDITOR AND SAVE TO TEMPFILE
    if tempfilename$<>"" then kill tempfilename$
    print #1.t, "!contents?"
    input #1.t, saveit$ 
    tempfilename$=filePath$+"tempfile.bas"
    open tempfilename$ for output as #temp
    print #temp, saveit$
    close #temp
 
    if libertyexe$="" then gosub [findLiberty]
    RETURN
 
[findLiberty]'** FIND LIBERTY.EXE
    filedialog "Find Liberty.exe","liberty.exe",libertyexe$ 
    RETURN
 
[run]
    gosub [readyRun]
    run libertyexe$+" -R -A -M "+tempfilename$ 
    print #1.t, "!origin ";rowVar;" ";columnVar;"";
    goto [loop]
 
[debug]
    gosub [readyRun]
    run libertyexe$+" -D -A -M "+tempfilename$
    print #1.t, "!origin ";rowVar;" ";columnVar;"";
    goto [loop]
 
[runtkn]
    filedialog "Choose TKN..","*.TKN",tknfile$
    run tknfile$
    goto [loop]
 
[maketkn]
    gosub [readyRun]
    run libertyexe$+" -T "+tempfilename$
    print #1.t, "!origin ";rowVar;" ";columnVar;"";
    goto [loop]
 
[paint]
    run "pbrush.exe",SHOWNORMAL
    goto [loop]
 
[notepad]
    run "notepad.exe",SHOWNORMAL
    goto [loop]
 
[winfile]
    run "winfile.exe",SHOWNORMAL
    goto [loop]
 
[calculator]
    run "calc.exe" ,SHOWNORMAL
    goto [loop]
 
[help]
    run "winhelp liberty.hlp"
    goto [loop]
 
[tutorial]
    run "winhelp tutorial.hlp"
    goto [loop]
 
[colorToolbar]
    '** GET SYSTEM MENU COLOR VALUE
    calldll #user,  "GetSysColor",_
        _COLOR_MENU as word,_
        menuColor as long
 
    '** RETRIEVE VALUES FOR red, green, blue
    blue = int(menuColor / (256 * 256))
    green = int((menuColor - blue *256*256) / 256)
    red = menuColor - blue *256 * 256 - green * 256
 
    '** FILL TOOLBAR WITH THIS COLOR
    print #1.g, "down;size 50; color ";red;" ";green;" ";blue
    print #1.g, "line 0 20 1200 20"
    print #1.g, "flush"
    RETURN
 
'** NEW **
[addTooltips]
    calldll #cctl, "InitCommonControls", re as void
    calldll #user, "GetWindowWord", h as word,_
        GWW as word, hInstance as word
 
    calldll #user, "CreateWindow", _
        "tooltips_class" as ptr, _
        "" as ptr, _
        style as long, _
        CW.USEDEFAULT as word, _
        CW.USEDEFAULT as word, _
        CW.USEDEFAULT as word, _
        CW.USEDEFAULT as word, _
        h as word, _
        0 as word, _
        hInstance as word, _
        "" as ptr, _
        hwndTT as word
 
'** MAKE A STRUCT FOR EACH TOOL
    struct toolinfo1, cbSize as word, uFlags as word,_
        hwnd as word, uId as word, x as word, y as word,_
        w as word, h as word, _
        hInst as word, lpstrText$ as ptr
 
    struct toolinfo2, cbSize as word, uFlags as word,_
        hwnd as word, uId as word, x as word, y as word,_
        w as word, h as word, _
        hInst as word, lpstrText$ as ptr
 
    struct toolinfo3, cbSize as word, uFlags as word,_
        hwnd as word, uId as word, x as word, y as word,_
        w as word, h as word, _
        hInst as word, lpstrText$ as ptr
 
    struct toolinfo4, cbSize as word, uFlags as word,_
        hwnd as word, uId as word, x as word, y as word,_
        w as word, h as word, _
        hInst as word, lpstrText$ as ptr
 
    struct toolinfo5, cbSize as word, uFlags as word,_
        hwnd as word, uId as word, x as word, y as word,_
        w as word, h as word, _
        hInst as word, lpstrText$ as ptr
 
    struct toolinfo6, cbSize as word, uFlags as word,_
        hwnd as word, uId as word, x as word, y as word,_
        w as word, h as word, _
        hInst as word, lpstrText$ as ptr
 
    struct toolinfo7, cbSize as word, uFlags as word,_
        hwnd as word, uId as word, x as word, y as word,_
        w as word, h as word, _
        hInst as word, lpstrText$ as ptr
 
    struct toolinfo8, cbSize as word, uFlags as word,_
        hwnd as word, uId as word, x as word, y as word,_
        w as word, h as word, _
        hInst as word, lpstrText$ as ptr
 
    struct toolinfo9, cbSize as word, uFlags as word,_
        hwnd as word, uId as word, x as word, y as word,_
        w as word, h as word, _
        hInst as word, lpstrText$ as ptr
 
    struct toolinfo10, cbSize as word, uFlags as word,_
        hwnd as word, uId as word, x as word, y as word,_
        w as word, h as word, _
        hInst as word, lpstrText$ as ptr
 
    struct toolinfo11, cbSize as word, uFlags as word,_
        hwnd as word, uId as word, x as word, y as word,_
        w as word, h as word, _
        hInst as word, lpstrText$ as ptr
 
    struct toolinfo12, cbSize as word, uFlags as word,_
        hwnd as word, uId as word, x as word, y as word,_
        w as word, h as word, _
        hInst as word, lpstrText$ as ptr
 
    struct toolinfo13, cbSize as word, uFlags as word,_
        hwnd as word, uId as word, x as word, y as word,_
        w as word, h as word, _
        hInst as word, lpstrText$ as ptr
 
    struct toolinfo14, cbSize as word, uFlags as word,_
        hwnd as word, uId as word, x as word, y as word,_
        w as word, h as word, _
        hInst as word, lpstrText$ as ptr
 
    struct toolinfo15, cbSize as word, uFlags as word,_
        hwnd as word, uId as word, x as word, y as word,_
        w as word, h as word, _
        hInst as word, lpstrText$ as ptr
 
    toolinfo1.cbSize.struct = 22
    toolinfo1.uFlags.struct = TTF.IDISHWND or TTF.SUBCLASS
    toolinfo1.hwnd.struct = h
    toolinfo1.uId.struct = hwnd(#1.new)
    toolinfo1.hInst.struct = hInstance
    toolinfo1.lpstrText$.struct = "New File"
    calldll #user, "SendMessage", hwndTT as word, TTM.ADDTOOL as word, _
    0 as word, toolinfo1 as struct, re as long
 
    toolinfo2.cbSize.struct = 22
    toolinfo2.uFlags.struct = TTF.IDISHWND or TTF.SUBCLASS
    toolinfo2.hwnd.struct = h
    toolinfo2.uId.struct = hwnd(#1.open)
    toolinfo2.hInst.struct = hInstance
    toolinfo2.lpstrText$.struct = "Open File"
    calldll #user, "SendMessage", hwndTT as word, TTM.ADDTOOL as word, _
    0 as word, toolinfo2 as struct, re as long
 
    toolinfo3.cbSize.struct = 22
    toolinfo3.uFlags.struct = TTF.IDISHWND or TTF.SUBCLASS
    toolinfo3.hwnd.struct = h
    toolinfo3.uId.struct = hwnd(#1.save)
    toolinfo3.hInst.struct = hInstance
    toolinfo3.lpstrText$.struct = "Save File"
    calldll #user, "SendMessage", hwndTT as word, TTM.ADDTOOL as word, _
    0 as word, toolinfo3 as struct, re as long
 
    toolinfo4.cbSize.struct = 22
    toolinfo4.uFlags.struct = TTF.IDISHWND or TTF.SUBCLASS
    toolinfo4.hwnd.struct = h
    toolinfo4.uId.struct = hwnd(#1.saveas)
    toolinfo4.hInst.struct = hInstance
    toolinfo4.lpstrText$.struct = "Save File As..."
    calldll #user, "SendMessage", hwndTT as word, TTM.ADDTOOL as word, _
    0 as word, toolinfo4 as struct, re as long
 
    toolinfo5.cbSize.struct = 22
    toolinfo5.uFlags.struct = TTF.IDISHWND or TTF.SUBCLASS
    toolinfo5.hwnd.struct = h
    toolinfo5.uId.struct = hwnd(#1.print)
    toolinfo5.hInst.struct = hInstance
    toolinfo5.lpstrText$.struct = "Print File"
    calldll #user, "SendMessage", hwndTT as word, TTM.ADDTOOL as word, _
    0 as word, toolinfo5 as struct, re as long
 
    toolinfo6.cbSize.struct = 22
    toolinfo6.uFlags.struct = TTF.IDISHWND or TTF.SUBCLASS
    toolinfo6.hwnd.struct = h
    toolinfo6.uId.struct = hwnd(#1.run)
    toolinfo6.hInst.struct = hInstance
    toolinfo6.lpstrText$.struct = "Run Program"
    calldll #user, "SendMessage", hwndTT as word, TTM.ADDTOOL as word, _
    0 as word, toolinfo6 as struct, re as long
 
    toolinfo7.cbSize.struct = 22
    toolinfo7.uFlags.struct = TTF.IDISHWND or TTF.SUBCLASS
    toolinfo7.hwnd.struct = h
    toolinfo7.uId.struct = hwnd(#1.debug)
    toolinfo7.hInst.struct = hInstance
    toolinfo7.lpstrText$.struct = "Debug Program"
    calldll #user, "SendMessage", hwndTT as word, TTM.ADDTOOL as word, _
    0 as word, toolinfo7 as struct, re as long
 
    toolinfo8.cbSize.struct = 22
    toolinfo8.uFlags.struct = TTF.IDISHWND or TTF.SUBCLASS
    toolinfo8.hwnd.struct = h
    toolinfo8.uId.struct = hwnd(#1.token)
    toolinfo8.hInst.struct = hInstance
    toolinfo8.lpstrText$.struct = "Tokenize Program"
    calldll #user, "SendMessage", hwndTT as word, TTM.ADDTOOL as word, _
    0 as word, toolinfo8 as struct, re as long
 
    toolinfo9.cbSize.struct = 22
    toolinfo9.uFlags.struct = TTF.IDISHWND or TTF.SUBCLASS
    toolinfo9.hwnd.struct = h
    toolinfo9.uId.struct = hwnd(#1.runtkn)
    toolinfo9.hInst.struct = hInstance
    toolinfo9.lpstrText$.struct = "Run an existing TKN"
    calldll #user, "SendMessage", hwndTT as word, TTM.ADDTOOL as word, _
    0 as word, toolinfo9 as struct, re as long
 
    toolinfo10.cbSize.struct = 22
    toolinfo10.uFlags.struct = TTF.IDISHWND or TTF.SUBCLASS
    toolinfo10.hwnd.struct = h
    toolinfo10.uId.struct = hwnd(#1.paint)
    toolinfo10.hInst.struct = hInstance
    toolinfo10.lpstrText$.struct = "Run Windows Paintbrush"
    calldll #user, "SendMessage", hwndTT as word, TTM.ADDTOOL as word, _
    0 as word, toolinfo10 as struct, re as long
 
    toolinfo11.cbSize.struct = 22
    toolinfo11.uFlags.struct = TTF.IDISHWND or TTF.SUBCLASS
    toolinfo11.hwnd.struct = h
    toolinfo11.uId.struct = hwnd(#1.file)
    toolinfo11.hInst.struct = hInstance
    toolinfo11.lpstrText$.struct = "Run File Manager"
    calldll #user, "SendMessage", hwndTT as word, TTM.ADDTOOL as word, _
    0 as word, toolinfo11 as struct, re as long
 
    toolinfo12.cbSize.struct = 22
    toolinfo12.uFlags.struct = TTF.IDISHWND or TTF.SUBCLASS
    toolinfo12.hwnd.struct = h
    toolinfo12.uId.struct = hwnd(#1.note)
    toolinfo12.hInst.struct = hInstance
    toolinfo12.lpstrText$.struct = "Run Notepad"
    calldll #user, "SendMessage", hwndTT as word, TTM.ADDTOOL as word, _
    0 as word, toolinfo12 as struct, re as long
 
    toolinfo13.cbSize.struct = 22
    toolinfo13.uFlags.struct = TTF.IDISHWND or TTF.SUBCLASS
    toolinfo13.hwnd.struct = h
    toolinfo13.uId.struct = hwnd(#1.calc)
    toolinfo13.hInst.struct = hInstance
    toolinfo13.lpstrText$.struct = "Run Windows Calculator"
    calldll #user, "SendMessage", hwndTT as word, TTM.ADDTOOL as word, _
    0 as word, toolinfo13 as struct, re as long
 
    toolinfo14.cbSize.struct = 22
    toolinfo14.uFlags.struct = TTF.IDISHWND or TTF.SUBCLASS
    toolinfo14.hwnd.struct = h
    toolinfo14.uId.struct = hwnd(#1.help)
    toolinfo14.hInst.struct = hInstance
    toolinfo14.lpstrText$.struct = "Liberty BASIC Help"
    calldll #user, "SendMessage", hwndTT as word, TTM.ADDTOOL as word, _
    0 as word, toolinfo14 as struct, re as long
 
    toolinfo15.cbSize.struct = 22
    toolinfo15.uFlags.struct = TTF.IDISHWND or TTF.SUBCLASS
    toolinfo15.hwnd.struct = h
    toolinfo15.uId.struct = hwnd(#1.tutor)
    toolinfo15.hInst.struct = hInstance
    toolinfo15.lpstrText$.struct = "Liberty BASIC Tutorial"
    calldll #user, "SendMessage", hwndTT as word, TTM.ADDTOOL as word, _
    0 as word, toolinfo15 as struct, re as long
 
    RETURN
Newsletter compiled and edited by: Brosco and Alyce. Comments, requests or corrections: Hit 'REPLY' now! mailto:brosc-@orac.net.au or mailto:awatso-@wctc.net