Writing Derived ABC Classes for APPs

When I hear people who want to generate the same code into every instance of a WindowManager, I find myself thinking why not change the base class for ThisWindow and write the code just once.

To get the new behavior that appears in MyWindowManagerType

! change this ---v 
ThisWindow CLASS(WindowManager)  
!     to this ---v
ThisWindow CLASS(MyWindowManagerType)

Steps to replace WIndowManager with MyWindowMangerType

  1. write MyWindowManagerType (some technical details below)
  2. place MyWindowManagerType.inc in a folder that ScanABC knows about
    FYI: ScanABC is a list of folders where the IDE looks when you click on Refresh Classes.
    The list of folders is set in:
    • IDE > Tools > Options > Clarion > Clarion For Windows > Version > list of “Directories scanned for ABC Classes”
  3. Refresh Classes
    • In your APP > Global Properties > Actions > Tab[ Classes ] >
      press button: Refresh Application Builder Class Information
  4. Select the new Class
    • In your APP > Global Properties > Actions > Tab[ Classes ] >
      press button: General
      Select new Class for Window Manager
  5. Regenerate
  6. Compile

I wish there were embed points to create the derived class, but there are not as I write this.

There are embed points for some global objects, but those are instances, vs types.

For the ,TYPEs like the MyWindowManagerType above,
I think it would be great if we had something like:

  1. Use the embeds in one APP to derive WindowManager (or other classes)

  2. Generate the inc/clw into a special folder,
    the folder is listed as a ScanABC
    the folder appears in the .RED

  3. Then for other APPs, in Global Properties > Actions > Tab[ classes ] > select the derived class as you can now (after a Refresh Classes).

But since we don’t currently have this imagined system for using embeds
It’s up to programmers to write these classes by hand.
Which honestly isn’t that hard once you’ve done it once.


Now even if you’re already comfortable writing clarion classes, there are a few extra technical challenges to writing a class that can be used as a global class type in an APP

  1. you MUST have an ABCIncludeFile magic comment in the .INC
    the comment MUST be at the top of the file ( before any compliable code )
    and it MUST start in 1st column ( I don’t believe this is documented )

!ABCIncludeFile
!ABCIncludeFile(familyclass)

  • note: the family class, names the * for _*LinkMode_ and _*DLLMode_
    when absent, it defaults to ABC
  1. the .INC MUST appear in a ScanABC folder
    while the extension of .INC is just
    convention as far as the compiler is concerned
    it’s a requirement for APPs

  2. you MUST refresh classes before you can select it


Here’s an example of an .INC file for a derived WindowManager

!ABCIncludeFile

    INCLUDE('ABWindow.inc'),ONCE

MyWindowMangerType CLASS(WindowManager),TYPE,MODULE('MyWindowMangerType.clw'),LINK('MyWindowMangerType.clw',_ABCLinkMode_),DLL(_ABCDllMode_) 
TakeAccepted          PROCEDURE,DERIVED,BYTE,PROC
OnButtonAccepted      PROCEDURE,VIRTUAL
                   END

and it’s matching .CLW

  MEMBER()
  INCLUDE('MyWindowMangerType.inc'),ONCE
  MAP
  END 

MyWindowMangerType.TakeAccepted            PROCEDURE() !,DERIVED,BYTE,PROC
  CODE
  IF ACCEPTED(){PROP:Type} = CREATE:Button
     SELF.OnButtonAccepted()
  END 
  RETURN Parent.TakeAccepted()

MyWindowMangerType.OnButtonAccepted() PROCEDURE!,VIRTUAL
  CODE 
  ! do something like play a sound
6 Likes

Here’s a (22 year old) example of deriving an ABC Browse. Still works. http://www.jssoftware.com/jssoftware/downloads/free_stuff/jsbrowsec55.zip