| **Navigation:**  [[abc library reference.htm|ABC Library Reference]] > ToolbarClass >====== ToolbarClass Overview {{c6h0009.jpg|C6H0009.jpg}} ====== | [[toolbarclass.htm|{{btn_prev_n.gif|Previous page}}]][[abc library reference.htm|{{btn_home_n.gif|Return to chapter overview}}]][[toolbarclass methods.htm|{{btn_next_n.gif|Next page}}]] | | || ToolbarClass and ToolbarTarget objects work together to reliably "convert" an event associated with a toolbar button into an appropriate event associated with a specific control or window. ToolbarClass objects communicate with zero or more ToolbarTarget objects. Each ToolbarTarget object is associated with a specific entity, such as a browse list, relation tree,or update form. The ToolbarClass object forwards events and method calls to the //active //ToolbarTarget object. Only one target is active at a time. This lets you use a single toolbar to drive a variety of targets, such as update forms, browse lists, relation tree lists, etc. A single toolbar can even drive multiple targets (two or more BrowseBoxes) in a single procedure. **ToolbarClass Concepts** Within an MDI application, the ToolbarClass and ToolbarTarget work together to reliably interpret and pass an event (EVENT:Accepted) associated with a toolbar button into an event associated with a specific control or window. For example, the end user CLICKS on a toolbar button (say the "Insert" button) on the MDI application frame. The frame procedure forwards the event to the active thread (**POST(EVENT:Accepted,ACCEPTED(),SYSTEM{Prop:Active})**). The active thread (procedure) manages a window that displays two LIST controls, and one of the LISTs has focus. This procedure has a ToolbarClass object plus a ToolbarTarget object for each LIST control. The ToolbarClass object takes the event (ToolbarClass.TakeEvent)1 and forwards the event to the //active //ToolbarTarget object (the target that represents the LIST with focus). The ToolbarTarget object takes the event (ToolbarListBoxClass.TakeEvent) and handles it by posting an appropriate event to a specific control or to the window, for example: **POST(EVENT:ACCEPTED,SELF.InsertButton) !insert a record** **POST(EVENT:PageDown,SELF.Control)      !scroll a LIST** **POST(EVENT:Completed)                  !complete an update form** **POST(EVENT:CloseWindow)                !select a record** **!    'etc.** If the procedure has a WindowManager object, the WindowManager object takes the event (WindowManager.TakeEvent) and forwards it to the ToolbarClass object (WindowManager.TakeAccepted). **ToolbarClass Relationship to Other Application Builder Classes** **ToolbarTarget** The ToolbarClass object keeps a list of ToolbarTarget objects so it can forward events and method calls to a particular target. Each ToolbarTarget object is associated with a specific entity, such as a browse list, relation tree,or update form. At present, the ABC Library has three classes derived from the ToolbarTarget: | ToolbarListboxClass | BrowseClass toolbar target | | ToolbarReltreeClass | Reltree control toolbar target | | ToolbarUpdateClass | Form procedure toolbar target | These ToolbarTarget objects implement the event handling specific to the associated entity. There may be zero or more ToolbarTarget objects within a procedure; however, //only one is active// at a time. The SetTarget method sets the active ToolbarTarget object. **BrowseClass and WindowManager** The WindowManager optionally uses the ToolbarClass, as does the BrowseClass. Therefore, if your program uses a WindowManager or BrowseClass object, it may also need the ToolbarClass. Much of this is automatic when you INCLUDE the WindowManager or BrowseClass headers (ABWINDOW.INC and ABBROWSE.INC) in your program's data section. See the [[toolbarclass overview.htm#ld4mqq|Conceptual Example]]. **ToolbarClass ABC Template Implementation** The ABC procedure templates instantiate a ToolbarClass object called Toolbar within each procedure containing a template that asks for global toolbar control--that is, the BrowseBox template, the FormVCRControls template, and the RelationTree template. The templates generate code to instantiate the ToolbarClass object and to register the ToolbarClass object with the WindowManager object. You may see code such as the following in your template-generated procedures. **Toolbar    ToolbarClass      !declare Toolbar object** ** CODE** ** !** **ThisWindow.Init PROCEDURE** ** SELF.AddItem(Toolbar)         !register Toolbar with WindowManager** ** BRW1.AddToolbarTarget(Toolbar)   !register BrowseClass as target** ** Toolbar.AddTarget(REL1::Toolbar,?RelTree) !register RelTree as target** ** SELF.AddItem(ToolbarForm)      !register update form as target** The WindowManager and BrowseClass are both programmed to use ToolbarClass objects. Therefore most of the interaction between these objects is encapsulated within the Application Builder Class code, and is only minimally reflected in the ABC Template generated code. **Toolbar Class Source Files** The ToolbarClass source code is installed by default to the Clarion \LIBSRC folder. The ToolbarClass source code and its respective components are contained in: | ABTOOLBA.INC | ToolbarClass declarations | | ABTOOLBA.CLW | ToolbarClass method definitions | **ToolbarClass Conceptual Example** The following example shows a typical sequence of statements to declare, instantiate, initialize, use, and terminate a ToolbarClass object and related ToolbarTarget objects. This example uses the ToolbarClass to allow a global toolbar to drive two separate but related LISTs within a single MDI procedure. The primary LIST shows client information and the related LIST shows phone numbers for the selected client. The toolbar drives whichever list has focus. The program POSTs toolbar events to the active MDI window using the SYSTEM{Prop:Active} property. Then the local ToolbarClass object calls on the active ToolbarTarget object to handle the event. ** PROGRAM** ** INCLUDE('ABBROWSE.INC')         !declare BrowseClass** ** INCLUDE('ABTOOLBA.INC')         !declare Toolbar classes** ** INCLUDE('ABWINDOW.INC')         !declare WindowManager** ** CODE** ** !program code** **Main PROCEDURE               !contains global toolbar** **AppFrame APPLICATION('Toolbars'),AT(,,275,175),SYSTEM,MAX,RESIZE,IMM** **      MENUBAR** **       ITEM('Browse Customers'),USE(?BrowseCustomer)** **      END** **      TOOLBAR,AT(0,0,400,22)        !must use ABTOOLBA.INC EQUATES:** ** BUTTON,AT(4,2),USE(?Top,Toolbar:Top),DISABLE,ICON('VCRFIRST.ICO'),FLAT** ** BUTTON,AT(16,2),USE(?PageUp,Toolbar:PageUp),DISABLE,ICON('VCRPRIOR.ICO'),FLAT** ** BUTTON,AT(28,2),USE(?Up,Toolbar:Up),DISABLE,ICON('VCRUP.ICO'),FLAT** ** BUTTON,AT(40,2),USE(?Down,Toolbar:Down),DISABLE,ICON('VCRDOWN.ICO'),FLAT** ** BUTTON,AT(52,2),USE(?PageDown,Toolbar:PageDown),DISABLE,ICON('VCRNEXT.ICO'),FLAT** ** BUTTON,AT(64,2),USE(?Bottom,Toolbar:Bottom),DISABLE,ICON('VCRLAST.ICO'),FLAT** **      END** **     END** **Frame    CLASS(WindowManager)** **Init      PROCEDURE(),BYTE,PROC,VIRTUAL** **TakeAccepted PROCEDURE(),BYTE,PROC,VIRTUAL** **       END** **Toolbar   ToolbarClass             !declare Toolbar object** ** CODE** ** Frame.Run()** **Frame.Init  PROCEDURE()** **ReturnValue  BYTE,AUTO** ** CODE** ** ReturnValue = PARENT.Init()** ** SELF.VCRRequest &= VCRRequest** ** SELF.Errors &= GlobalErrors** ** SELF.AddItem(Toolbar)              !register Toolbar with WindowManager** ** OPEN(AppFrame)** ** SELF.Opened=True** ** SELF.SetAlerts()** ** RETURN ReturnValue** **Frame.TakeAccepted PROCEDURE()** **ReturnValue     BYTE,AUTO** **Looped       BYTE** ** CODE** ** LOOP** **  IF Looped THEN RETURN Level:Notify ELSE Looped=1.** **  CASE ACCEPTED()** **  OF Toolbar:First TO Toolbar:Last               !for EVENT:Accepted on toolbar** **   POST(EVENT:Accepted,ACCEPTED(),SYSTEM{Prop:Active}) !transfer it to active thread** **   CYCLE                           ! and stop** **  END** **  ReturnValue = PARENT.TakeAccepted()** **  IF ACCEPTED() = ?BrowseCustomer** **   START(BrowseCustomer,050000)** **  END** **  RETURN ReturnValue** ** END** **BrowseCustomer PROCEDURE             !contains local Toolbar and targets** **CusView   VIEW(Customer)** **       END** **CusQ     QUEUE** **CUS:CUSTNO  LIKE(CUS:CUSTNO)** **CUS:NAME    LIKE(CUS:NAME)** **ViewPosition STRING(512)** **       END** **PhView    VIEW(Phones)** **       END** **PhQ      QUEUE** **PH:NUMBER   LIKE(PH:NUMBER)** **PH:ID     LIKE(PH:ID)** **ViewPosition STRING(512) ** **       END** **CusWindow WINDOW('Browse Customers'),AT(,,246,131),IMM,SYSTEM,GRAY,MDI** **       LIST,AT(8,7,160,100),USE(?CusList),IMM,HVSCROLL,FROM(CusQ),|** **        FORMAT('51R(2)|M~CUSTNO~C(0)@n-14@80L(2)|M~NAME~@s30@')** **       BUTTON('&Insert'),AT(17,111,45,14),USE(?InsertCus),SKIP** **       BUTTON('&Change'),AT(66,111,45,14),USE(?ChangeCus),SKIP,DEFAULT** **       BUTTON('&Delete'),AT(115,111,45,14),USE(?DeleteCus),SKIP** **       LIST,AT(176,7,65,100),USE(?PhList),IMM,FROM(PhQ),FORMAT('80L~Phones~L(1)')** **       BUTTON('&Insert'),AT(187,41,42,12),USE(?InsertPh),HIDE** **       BUTTON('&Change'),AT(187,54,42,12),USE(?ChangePh),HIDE** **       BUTTON('&Delete'),AT(187,67,42,12),USE(?DeletePh),HIDE** **      END** **ThisWindow CLASS(WindowManager)         !declare ThisWindow object** **Init      PROCEDURE(),BYTE,PROC,VIRTUAL** **Kill      PROCEDURE(),BYTE,PROC,VIRTUAL** **TakeSelected PROCEDURE(),BYTE,PROC,VIRTUAL** **       END** **Toolbar   ToolbarClass             !declare Toolbar object to receive** **                           ! and process toolbar events from Main** **CusBrowse  CLASS(BrowseClass)          !declare CusBrowse object** **Q        &CusQ            ** **       END** **PhBrowse   CLASS(BrowseClass)          !declare PhBrowse object** **Q        &PhQ                 ** **       END** ** CODE** ** ThisWindow.Run()** **ThisWindow.Init PROCEDURE()** **ReturnValue    BYTE,AUTO** ** CODE** ** ReturnValue = PARENT.Init()** ** SELF.FirstField = ?CusList            !CusList gets initial focus** ** SELF.VCRRequest &= VCRRequest** ** SELF.Errors &= GlobalErrors** ** SELF.AddItem(Toolbar)               !register Toolbar with WindowManager** ** Relate:Customer.Open** ** CusBrowse.Init(?CusList,CusQ.ViewPosition,CusView,CusQ,Relate:Customer,SELF)** ** PhBrowse.Init(?PhList,PhQ.ViewPosition,PhView,PhQ,Relate:Phones,SELF)** ** OPEN(CusWindow)** ** SELF.Opened=True** ** CusBrowse.Q &= CusQ** ** CusBrowse.AddSortOrder(,CUS:BYNUMBER)** ** CusBrowse.AddField(CUS:CUSTNO,CusBrowse.Q.CUS:CUSTNO)** ** CusBrowse.AddField(CUS:NAME,CusBrowse.Q.CUS:NAME)** ** PhBrowse.Q &= PhQ** ** PhBrowse.AddSortOrder(,PH:IDKEY)** ** PhBrowse.AddRange(PH:ID,Relate:Phones,Relate:Customer)** ** PhBrowse.AddField(PH:NUMBER,PhBrowse.Q.PH:NUMBER)** ** PhBrowse.AddField(PH:ID,PhBrowse.Q.PH:ID)** ** CusBrowse.InsertControl=?InsertCus** ** CusBrowse.ChangeControl=?ChangeCus** ** CusBrowse.DeleteControl=?DeleteCus** ** CusBrowse.AddToolbarTarget(Toolbar)       !Make CusBrowse a toolbar target** ** PhBrowse.InsertControl=?InsertPh** ** PhBrowse.ChangeControl=?ChangePh** ** PhBrowse.DeleteControl=?DeletePh** ** PhBrowse.AddToolbarTarget(Toolbar)        !Make PhBrowse a toolbar target** ** SELF.SetAlerts()** ** RETURN ReturnValue** **ThisWindow.Kill  PROCEDURE()** **ReturnValue    BYTE,AUTO** ** CODE** ** ReturnValue = PARENT.Kill()** ** Relate:Customer.Close** ** RETURN ReturnValue** **ThisWindow.TakeSelected  PROCEDURE()** **ReturnValue          BYTE,AUTO** **Looped             BYTE** ** CODE** ** LOOP** ** IF Looped THEN RETURN Level:Notify ELSE Looped=1.** **  ReturnValue = PARENT.TakeSelected()** **  CASE FIELD()** **   OF ?CusList                  !if selected,** **    Toolbar.SetTarget(?CusList)       ! make ?CusList the active target** **   OF ?PhList                  !if selected** **    IF RECORDS(PhBrowse.Q) > 1        !and contains more than one record,** **     Toolbar.SetTarget(?PhList)       ! make ?PhList the active target** **    END** **  END** **  RETURN ReturnValue** ** END**