Microsoft KB Archive/35898

From BetaArchive Wiki
Knowledge Base


Complete QuickBASIC Program to Browse & Expand Get Info.. Help

Article ID: 35898

Article Last Modified on 10/23/2003



APPLIES TO

  • Microsoft QuickBasic Compiler for Macintosh 1.0
  • Microsoft QuickBasic Compiler for Macintosh 1.0
  • Microsoft QuickBasic Compiler for Macintosh 1.0



This article was previously published under Q35898

SUMMARY

The "Help Edit" program further below lets you browse or modify the help information available in the Macintosh QuickBASIC version 1.00, 1.00a, or 1.00b environment. Unlike the Set Info... feature in the Search menu in QuickBASIC, this program lets you embed carriage returns and Cut and Paste in the help box for a keyword. It also lets you conveniently add help information for all keywords at once. This program works either interpreted or compiled.

This article was previously PSSONLY because it exceeded the now-defunct 200- line practical limit for online services.

This information applies to Microsoft QuickBASIC versions 1.00, 1.00a, and 1.00b for Apple Macintosh Systems.

MORE INFORMATION

This program, called "Help Edit", is a good demonstration of the following:

  1. Resource management
  2. Text editing
  3. Writing for both interpreted and compiled environments
  4. Handling refresh events

To use the help feature of Macintosh QuickBASIC, position the insertion pointer on any keyword in the List window and press COMMAND+I (or select the Get Info... option on the Search menu). COMMAND+I (or Get Info...) gives you the proper syntax for any selected QuickBASIC statement or Toolbox call.

The Set Info... option on QuickBASIC's Search menu allows you to add additional help information for a Macintosh QuickBASIC statement. However, Set Info... will not allow you to embed carriage returns, it only wraps to the next line after you have typed a complete line.

The "Help Edit" program lets you easily expand QuickBASIC's help information for any BASIC statement, Toolbox call, or user-defined keyword. The "Help Edit" program lets you embed carriage returns in the help text. In "Help Edit", you may open Microsoft QuickBASIC (b) or (d) (binary or decimal). The program lets you browse or modify the help information stored in the MBKI and MBTI resources in QuickBASIC.

The "Help Edit" program also lets you open a source file, if you have previously used Set Info... from the Search menu in QuickBASIC to define help information for a user-defined keyword in a particular source file. In other words, the program lets you browse or modify the help information stored in MBUI resources (if any) stored in the source file.

The following is the "Help Edit" program:

'----------------------------------------------------------------
'    Help Edit
'    Copyright 1988 Microsoft Corp.
'
'    Microsoft does not make any warranty or claims for the
'    performance of this program. This program is for personal
'    use only, and may not be distributed in any form, electronic
'    or mechanical, for any purpose without the written permission
'    of Microsoft.
'
'    WARNING:
'    This program may make changes to the resource fork of the
'    QuickBASIC application. Use strictly at your own risk. Make
'    backups of your originals before using this program.
'
'----------------------------------------------------------------
'
'    Help Edit is useful to browse the available online help, as
'    well as make changes Set Info... (in Search menu) does not allow.
'
'    Open, or COMMAND+O from the File menu allows you to open the
'    other QuickBASIC or a QuickBASIC source file so you can edit user
'    information.
'
'    A simple addition to make would be a Print option to print the
'    contents of a particular help item, or all the online help.
'
'----------------------------------------------------------------
ToolBox "i"

'    Global variables
DIM SHARED ref%     'current file reference number (usually QuickBASIC)
DIM SHARED info$(300,1),ids%(300)    'info name,text & resource id
DIM SHARED r%(3)    'scratch rectangle
DIM SHARED max%     'number of info resources
DIM SHARED hit%     'selected info resource
DIM SHARED curType$ 'current res type, one of MBKI,MBTI,or MBUI
DIM SHARED sb%(3,1),sh&    'scrolling rectangles and scrollbar handle

'    Main level variables
DIM h&    'scratch resource handle
'    variables for hit testing: point, font info, and flag
DIM mousePt%(1),fi%(3),inRect%
MENU 1,0,1,"File"
MENU 1,1,1,"Open" :CmdKey 1,1,"O"
MENU 1,2,0,"-"
MENU 1,3,1,"Quit" :CmdKey 1,3,"Q"

IF SYSTEM(4) THEN
    '    compiled, so get user to find QuickBASIC
    GetFile ff$, "APPL", "Please find QuickBASIC for me"
    IF ff$ = "" THEN BEEP : END
    '    Use ToolBox OpenResFile to enable us to open another
    '    application, something the library OpenResFile forbids
    '    to protect programs from CODE resource conflicts.
    ToolBox "WQ", &H997, f$, ref%
ELSE
    '    we're in the interpreter, so get CurApRefNum global
    ref% = PEEKW(&H900)
END IF

h% = 220 :w% = 400
l% = (SYSTEM(5)-w%)\2 :t% = (SYSTEM(6)-h%)\3
WINDOW 1,"QuickBASIC Help Editor",(l%,t%)-(l%+w%,t%+h%),5
TEXTSIZE 9 :TEXTFONT 4 :GetFontInfo fi%(0)

r% = 32 * fi%(2)    'allow room for 32 char name
SetRect sb%(0,0),10,10,r%,h%-10
SetRect sb%(0,1),sb%(3,0)-1,sb%(0,0),sb%(3,0)+15,sb%(2,0)
l% = r%+25

BUTTON 1,1,"Keyword Info",(l%,15)-(l%+110,30),3
BUTTON 2,1,"Toolbox Info",(l%,35)-(l%+110,50),3
BUTTON 3,1,"User Info",(l%,55)-(l%+110,70),3
BUTTON 4,0,"Edit",(l%,h%-30)-(l%+100,h%-10),1
BUTTON 6,1,"Quit",(w%-75,h%-30)-(w%-15,h%-10),1

'    turn on dialog and menu event trapping
ON DIALOG GOSUB doDialog :DIALOG ON
ON MENU GOSUB doMenu :MENU ON

NewScroll sh&,sb%(0,1),1,1,max%,0
FRAMERECT VARPTR(sb%(0,0))
top%=0
WHILE 1
    m% = MOUSE(0) :IF m% THEN GOSUB doMouse
    ScrollText sh&,sb%(0,0),info$(1,0),top%,max%,hit%,0,0
WEND

'----------------------------------------------------------------
Quit:
    WINDOW CLOSE 1
    DisposeScroll sh&    'always clean up heap entries
    '    Make sure just the right resource forks are closed
    '    before we quit--very important in the environment.
    IF ref%<>SYSTEM(7) AND ref%<>PEEKW(&H900) THEN CloseResFile ref%
    END

'----------------------------------------------------------------
doMenu:
    IF MENU(0) = 1 THEN
        SELECT CASE MENU(1)
        CASE 1    'Open
            f$ = FILES$(1,"TEXTMSBBMSBCAPPL")
            IF f$ <> "" THEN
                '    if current resource file not the currently
                '    running program, close it
                IF ref% <> SYSTEM(7) AND ref% <> PEEKW(&H900) THEN
                    CloseResFile ref%
                END IF
                '    Use ToolBox OpenResFile so we can open APPLs.
                ToolBox "WQ", &H997, f$, ref%
                IF curType$ <> "" THEN LoadInfo curType$
            END IF
        CASE 3    'Quit
            GOTO Quit
        CASE ELSE :BEEP
        END SELECT
    END IF
    MENU
    RETURN

'----------------------------------------------------------------
'    doMouse
'    Mouse click handler
'
doMouse:
    '    handle only single or double click
    IF m% = 1 OR m% = 2 THEN
        GetMouse mousePt%(0)
        PtInRect mousePt%(0),sb%(0,0),inRect%    'in text area?
        IF inRect% THEN
            '    calculate clicked row
            hit% = (mousePt%(0)-sb%(0,0))\(fi%(0)+fi%(1)) + top%
            IF hit% > max% THEN hit% = max%    'check if past end
            top% = 0     'force redraw at next ScrollText
            BUTTON 4,1   'enable "Edit" button
        END IF
        IF m% = 2 THEN CALL EditInfo    'Edit info if double clicked
    END IF
    RETURN

'----------------------------------------------------------------
'    doDialog
'    dialog event handler
'
doDialog:
    SELECT CASE DIALOG(0)
    CASE 1    'button clicked
        SELECT CASE DIALOG(1)
        CASE 1    'KeyWord Info
            BUTTON 1,2 :BUTTON 2,1 :BUTTON 3,1
            curType$ = "MBKI" :LoadInfo curType$
        CASE 2    'Toolbox Info
            BUTTON 1,1 :BUTTON 2,2 :BUTTON 3,1
            curType$ =  "MBTI" :LoadInfo curType$
        CASE 3    'User Info
            BUTTON 1,1 :BUTTON 2,1 :BUTTON 3,2
            curType$ =  "MBUI" :LoadInfo curType$
        CASE 4 :EditInfo    'Edit button
        CASE 6 :GOTO Quit   'Quit button
        END SELECT
    CASE 5    'refresh
        FRAMERECT VARPTR(sb%(0,0)) :top% = 0
    CASE ELSE
    END SELECT
    RETURN

'----------------------------------------------------------------
'    LoadInfo
'    Scan the resource file for tt$ type resources, loading the
'    names into array info$(i,0), the text of the info into
'    info$(i,1), and the resource id number into ids%(i). The number
'    of resources loaded is set in max%. LoadInfo loads COPIES of the
'    resources, not the actual resources.
'
SUB LoadInfo(tt$) STATIC
    h& = 0 :type$ = "" :max% = 0
    ChangeCursor 4
    '    load the info
    CountRes tt$, max%
    FOR i% = 1 TO max%
        GetIndRes tt$, i%, h&
        GetResInfo h&, ids%(i%), type$, info$(i%,0)
        HandleToString h&, info$(i%,1)
        ReleaseRes h&
    NEXT
    '    erase the scroll area
    InSetRect sb%(0,0),1,1
    ERASERECT VARPTR(sb%(0,0))
    InSetRect sb%(0,0),-1,-1
    '    define scroll bar with the new maximum
    DisposeScroll sh&
    NewScroll sh&, sb%(0,1), 1, 1, max%, 0
    INITCURSOR
END SUB

'----------------------------------------------------------------
'    EditInfo
'    Displays a dialog with the same dimensions as the information
'    dialog in QuickBASIC.
'
'    Unlike Set Info... in QuickBASIC's Search menu, EditInfo
'    allows carriage returns, and Cut, Copy, and Paste. EditInfo
'    does not allow you to enter more than 255 characters.
'
'    If the information has been changed, the resource is updated on
'    disk when the dialog is terminated.
'
SUB EditInfo STATIC
    wp& = 0 :pict& = 0
    DIALOG OFF
    WINDOW 2,info$(hit%,0),(41,70)-(471,282),5
    GetWindow wp&

    SetRect r%(0),41,70,471,282    'init refresh picture rect
    OpenPicture r%(0), pict& : SHOWPEN    'record refresh pict
    TEXTFONT 0
    SetRect r%(0),38,176,100,197  : TextBox "Info for",r%(0),0
    SetRect r%(0),100,176,271,197 : TextBox info$(hit%,0),r%(0),0
    LINE (8,7)-(417,169),,b
    BUTTON 1,1,"OK",(360,176)-(416,197),1
    BUTTON 2,1,"Cancel",(280,176)-(340,197),1
    ClosePicture : HIDEPEN    'stop recording refresh picture
    SetWindowPic wp&,pict&    'attach refresh picture to window

    EDIT FIELD 1,info$(hit%,1),(10,8)-(416,168),6
    ef& = WINDOW(6)    'cache edit field handle

    d% = DIALOG(0)
    WHILE d% <> 1    'wait for button click
        '    Monitor length of text:
        '    If length of text overflows a Pascal string, then cut the
        '    extra just before the insertion point.  This will be the
        '    text just typed.
        TElength% = PEEKW( PEEKL(ef&)+60 )
        IF  TElength% > 255 THEN
            BEEP
            c% = PEEKW( PEEKL(ef&)+32 )    'current Insertion Point
            TESETSELECT c%-(TElength%-255), c%, ef&    'extra text
            TEDELETE ef&    'clear extra text
        END IF

        d% =  DIALOG(0)
        IF d% = 5 THEN        'refresh
            TEUPDATE PEEKL(ef&),ef&
            LINE (8,7)-(417,169),,b
        END IF
    WEND

    IF DIALOG(1) = 1 THEN    'ok button clicked
        t$ = EDIT$(1)
        IF t$ <> info$(hit%,1) THEN    'Update info if changed
            ChangeCursor 4
            info$(hit%,1) = t$
            DeleteRes ref%, ids%(hit%), curType$
            StringToHandle t$, h&
            AddRes ref%, h&, curType$, ids%(hit%), info$(hit%,0)
            UpdateResFile ref%
            ReleaseRes h&
            INITCURSOR
        END IF
    END IF

    '    clean up refresh picture
    SetWindowPic wp&,0&
    DisposePicture pict&

    DIALOG ON
    WINDOW CLOSE 2
END SUB

'----------------------------------------------------------------
'    GetFile
'    Display a window over the standard FILES$(1) dialog
'    containing the one-line message m$.
'
'    f$ = value returned by FILES$
'    t$ = type of file to get (e.g. "TEXT")
'    m$ = one-line message displayed over FILES$ dialog.
'
SUB GetFile(f$,t$,m$) STATIC
    '    Open window offscreen first, so the size calculations
    '    don't disturb a current window.
    WINDOW 10,"",(-20001,-20001)-(-20000,-20000),3
    TEXTFONT 0
    '    window width is w% or WIDTH(m$)+10, whichever is larger
    w%=300 : x% = WIDTH(m$)
    IF x% > w%-10 THEN w% = x% + 10

    mBar%=PEEKW(&HBAA) : l%=(SYSTEM(5)-w%)\2
    WINDOW 10,"",(l%,mBar%+11)-(l%+w%,mBar%+30),2
    TEXTFONT 0 : TEXTSIZE 12
    SetRect r%(0), 2,2,w%-2,CINT(WINDOW(3)-2)
    TextBox m$, r%(0),1
    f$ = FILES$( 1, t$ )
    WINDOW CLOSE 10
END SUB

'================================================================
'        Resource Utilities
'================================================================

'----------------------------------------------------------------
'    DeleteRes
'    Delete the resource id = idn% and type restype$ from the
'    resource file with file reference number r%.
'
SUB DeleteRes( r%, idn%, resType$ ) STATIC
    h& = 0
    GetRes r%, resType$, idn%, h&
    RemoveRes r%, h&
    UpdateResFile me%
    ReleaseRes h&
END SUB

'----------------------------------------------------------------
'    HandleToString
'    Convert Pascal string in a handle to BASIC string
'
SUB HandleToString( h&, x$ ) STATIC
    size& = 0
    GetHandleSize h&, size&
    x$ = STRING$(size&,0)
    BlockMove PEEKL(h&), SADD(x$), size&
    x$ = MID$( x$, 2, ASC(x$) )    'Pascal to BASIC string
END SUB

'----------------------------------------------------------------
'    StringToHandle
'    Convert BASIC string to Pascal string in a handle.
'
SUB StringToHandle( a$, h& ) STATIC
        x$ = ""
        ReleaseRes h& :h& = 0    'make sure handle is empty
        B2PStr a$, x$
        size& = ASC(x$) + 1    'string length + length byte
        NewHandle size&, h&
        BlockMove SADD(x$), PEEKL(h&), size&
        x$ = ""
END SUB
                


Additional query words: MQuickB

Keywords: KB35898