home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1993 #2 / Image.iso / database / pk4pak.zip / EVENTMAN.DOC < prev    next >
Text File  |  1993-01-06  |  32KB  |  687 lines

  1. EVENTMAN
  2.  
  3. A generic event manager, by Henrik Bechmann of Elect Software International Inc.
  4.  
  5. Version 1.1 (beta) December, 1992.
  6.  
  7. ============================================================================
  8.                             WHAT'S NEW ?
  9. ============================================================================
  10.  
  11.  EventMan version 1.1 introduces types. By setting 
  12.  
  13.      EventMan.SetObjectTagProc = "EventMan.SetObjectTagAndType"
  14.  
  15.  and
  16.  
  17.      EventMan.DispatchEventTagProc = "EventMan.DispatchEventTagToType"
  18.  
  19.  EventMan will check an object's type for an event handler if there isn't one
  20.  for the object itself.
  21.  
  22.  if the application doesn't set a type for the object in 
  23.  
  24.               EventMan.ObjectTypeBag[]
  25.  
  26.  then EventMan will try to provide one (in SetObjectTagAndType()) with
  27.  EventMan.GetWindowType(). The standard types are
  28.              FLOATING, CANVAS, QUERY, TABLE, FORM, FILE_EDITOR, SCRIPT, MEMO,
  29.              FORMDESIGN, REPORTDESIGN, CREATE, GRAPH, PASSWORD, RESTRUCTURE,
  30.              INDEX, SORT
  31.  
  32.  Therefore the developer can develop generalized code for each type, default
  33.  code for the application as a whole, and limit custom code for each object 
  34.  to special cases.
  35.  
  36.  For direct dispatches of messages to objects, use
  37.  
  38.         EventMan.SendMessage(ObjectTag,MessageTag)
  39.  
  40.  Since SetObjectTagAndType will set a default object name as well as object
  41.  type if none is provided for the window, EventMan 1.1 should be code 
  42.  compatible for most applications written for the original version.
  43.  
  44. =============================================================================
  45.                            EVENTMAN DESCRIPTION
  46. =============================================================================
  47.  
  48. General description:
  49. --------------------
  50. EventMan (Event Manager) is a generic event manager for use in Paradox 4.0 applications. The general organization of the scheme is as follows:
  51.  
  52. Procedures (event handlers) are associated with events and objects in a dictionary (a dynarray) in the following general form:
  53.  
  54.       EventMan.Dictionary[ObjectTag + EventTag] = ProcName
  55.  
  56. The idea is to EXECPROC ProcName based on the current object and event.
  57.  
  58. EventMan organizes programming in Paradox 4.0 into 4 phases:
  59.         1. Event collection
  60.         2. Event analysis
  61.         3. Event dispatch
  62.         4. Event handling
  63.  
  64. In Version 1.1 Type hanmdling has been added. For type handling configure EventMan as follows:
  65.  
  66.     EventMan.SetObjectTagProc = "EventMan.SetObjectTagAndType"
  67.     EventMan.DispatchEventTagProc = "EventMan.DispatchEventTagToType"
  68.  
  69. When a window is loaded, then set three values for the window, eg.:
  70.  
  71.     EventMan.WindowObjectTag[GetWindow()] = "MyObject"
  72.     EventMan.ObjectTagWindow["MyObject"] = GetWindow()
  73.     EventMan.ObjectTagType["MyObject"] = "FORM"
  74.  
  75. Then EventMan.Dictionary will be searched for an EventTag in the following order:
  76.  
  77.     EventMan.Dictionary[EventMan.ObjectTag + EventMan.EventTag]
  78.  
  79.     EventMan.Dictionary[EventMan.ObjectType + EventMan.EventTag]
  80.  
  81.     EventMan.Dictionary[EventMan.EventTag]
  82.  
  83. Event collection:
  84. -----------------
  85. Event collection can take place under either WAIT ... PROC or GETEVENT. EventMan.DoWait() and EventMan.DoGetEvent() are provided as defaults for this.
  86.  
  87. Event analysis:
  88. ---------------
  89. Event analysis involves several steps:
  90.         1. Get target window handle (placed in EventMan.TargetWindow)
  91.         2. Set object tag (placed in EventMan.ObjectTag)
  92.         3. Set event tag (placed in EventMan.EventTag)
  93.  
  94. EventMan automatically places the target window handle in
  95. EventMan.TargetWindow using EventMan.GetTargetWindow(..)).
  96.  
  97. EventMan provides a default procedure in EventMan.SetObjectTagProc (EventMan.SetWindowAsObjectTag()) for setting EventMan.ObjectTag. This procedure simply sets EventMan.ObjectTag to StrVal(EventMan.TargetWindow).
  98.  
  99. Your application can substitute a more sophisticated procedure which might, for instance, set EventMan.ObjectTag to "INVOICE" rather than a window number. EventMan.SetIndexedObjectTag() is provided for this purpose. It looks up your custom ObjectTag from a list of window numbers. With this alternative, your application must maintain the cross referencing information in the dynarrays EventMan.WindowObjectTag[] and EventMan.ObjectTagWindow[]. The advantage to this is that by avoiding the use of window handles for ObjectTags, EventMan.Dictionary[] updates are not required each time a window is loaded or unloaded.
  100.  
  101. For type handling, EventMan provides EventMan.SetObjectTagAndType() and EventMan.DispatchEventTagToType().
  102.  
  103. EventMan sets EventMan.EventTag according to some simple rules that are set out in detail below (See EventMan.SetEventTag()).
  104.  
  105. Event dispatch:
  106. ---------------
  107. Finally EventMan dispatches the event. EventMan provides a default dispatcher (EventMan.DispatchEventTag()) in EventMan.DispatchEventTagProc, although your application can substitute its own more sophisticated dispatcher (advanced applications only). The default dispatcher first looks for
  108.  
  109.       EventMan.Dictionary[EventMan.ObjectTag + EventMan.EventTag]
  110.  
  111. and then
  112.  
  113.       EventMan.Dictionary[EventMan.EventTag]
  114.  
  115. if it didn't find the first form. Therefore default behavior can be provided by your application. It EXECPROCs any entry it finds. If it finds no entry, then it simply returns EventMan.DefaultReturnCode, otherwise it returns the returned value of the EXECPROC'd procedure.
  116.  
  117. With EventMan.DispatchEventTagToType() EventMan additionaly checks to see if there is a hnadler for the type of object targeted, if not for the object itself, before checking for a default handler.
  118.  
  119. Event handling:
  120. ---------------
  121. Event handlers, the procedures that are EXECPROC'd by the event dispatcher, must be provided by your application, and must always return the values 0, 1, or 2, according to the rules provided for WAIT ... PROC commands.
  122.  
  123. Special support is provided for IDLE event processing, and for MOUSE event processing, as well as populating and de-populating EventMan.Dictionary[].
  124.  
  125. Look for event packet details in EventMan.EventBag[].
  126.  
  127. For some ideas on how to use EventMan, see EDEMO.SC.
  128.  
  129. To load EventMan into memory, do:
  130.  
  131.         Librarian.HasControl = True
  132.         Play "eventman"
  133.         Release vars Librarian.HasControl
  134.  
  135. =============================================================================
  136.                             EVENTMAN INTERFACE
  137. =============================================================================
  138. Summary of available procedures and properties:
  139.  
  140. Construction and destruction:
  141. -----------------------------
  142. EventMan.Constructor() ; execute at start of session
  143. EventMan.Destructor() ; execute at end of session
  144.  
  145. The event dictionary and idle proc queue:
  146. -----------------------------------------
  147. EventMan.SetHandlersFrom(HandlerBag)
  148. Eventman.ClearHandlersWith(HandlerBag)
  149. EventMan.RegisterIdleServer(ObjectTag,IdleProcName)
  150. EventMan.DeRegisterIdleServer(ObjectTag)
  151.  
  152. Event collectors: (use these in your code)
  153. ------------------------------------------
  154. (For Wait statements...)
  155. EventMan.CatchTrigger(EventMan.TriggerTag,EventMan.EventBag,
  156.       EventMan.TriggerCycle)
  157. (Shell (analog to wait) for EventMan.GetEventProc...)
  158. EventMan.DoGetEvent()
  159.  
  160. Event analysis:
  161. ---------------
  162. EventMan.GetTargetWindow(TriggerTag,EventBag) ; returns 0 or valid window
  163. EventMan.SetWindowAsObjectTag() ; Default EventMan.SetObjectTagProc
  164. EventMan.SetIndexedObjectTag() ; more sophisticated EventMan.SetObjectTagProc
  165. EventMan.SetObjectTagAndType() ; for type handling
  166. EventMan.SetEventTag() ; sets EventMan.EventTag from EventMan.EventBag[]
  167.  
  168. Event dispatch:
  169. ---------------
  170. EventMan.DispatchEventBag() ; used by collectors
  171. EventMan.DispatchEventTag() ; default EventMan.DispatchEventTagProc; called
  172.                             ; by DispatchEventBag
  173. EEventMan.DispatchEventTagToType() ; for type handling
  174. ventMan.DoIdleEvent()      ; execprocs next idle server
  175.  
  176. Utility procs:
  177. ---------------------
  178. EventMan.DoWait() ; default wait statement, uses EventMan.CatchTrigger()
  179. EventMan.GetEvent() ; default EventMan.GetEventProc
  180. EventMan.EnableEvent() ; returns 0
  181. EventMan.DisableEvent() ; returns 1
  182. EventMan.CompleteMouseSequence() ; call after ExecEvent EventBag
  183. EventMan.ReturnFromMouseMode() ; call after mouse down when UP is available
  184.  
  185. Properties:
  186. ------------
  187. EventMan.IsActive ; readonly, is EventMan active? (use isAssigned)
  188. EventMan.IsGetEvent ; readonly, is this a getevent event? (use isAssigned)
  189. EventMan.IsWait ; readonly, is this a wait event? (use isAssigned)
  190. EventMan.Dictionary[] ; EventMan.Dictionary[ObjectTag + EventTag] = ProcName
  191. EventMan.EventBag[] ; as collected by wait or getevent
  192. EventMan.ObjectTagWindow ; For tracking object window handles
  193. EventMan.WindowObjectTag ; For tracking window object tags
  194. EventMan.ObjectTagType   ; For tracking object types
  195. EventMan.EventType ; TRIGGER or EventMan.EventBag["Type"]
  196. EventMan.MouseModeButton ; Button pressed with last DOWN, or "NONE"
  197. EventMan.TargetWindow ; set by collectors from EventMan.GetTargetWindow(..)
  198. EventMan.ObjectTag ; string value for EventMan.Dictionary set by
  199.                    ; EventMan.SetWindowAsObjectTag() or
  200.                    ; EventMan.SetObjectTagProc
  201. EventMan.EventTag ; sometimes composite string value for
  202.                   ; EventMan.Dictionary set by EventMan.SetEventTag()
  203. EventMan.ReturnCode ; must be set by DispatchEventTagProc
  204. EventMan.DefaultReturnCode ; return code when handler search fails
  205. EventMan.GetEventProc ; getevent specs for DoGetEvent
  206. EventMan.SetObjectTagProc ; sets EventMan.ObjectTag based on
  207.                           ; Eventman.TargetWindow
  208. EventMan.DispatchEventTagProc ; dispatches event to EventMan.Dictionary
  209.  
  210. Detailed explanations:
  211.  
  212. Construction and destruction:
  213. -----------------------------
  214. EventMan.Constructor()
  215.  
  216. Syntax: EventMan.Constructor()
  217.  
  218. Returns: Nothing.
  219.  
  220. Description: Sets global variables, dynarrays and variables as required by EventMan.
  221.  
  222. Usage: Issue EventMan.Cosntructor() at the beginning of your application.
  223.  
  224. ------
  225. EventMan.Destructor()
  226.  
  227. Syntax: EventMan.Destructor()
  228.  
  229. Returns: Nothing.
  230.  
  231. Description: Removes global variables, dynarrays and variables as required by EventMan.
  232.  
  233. Usage: Issue EventMan.Destructor() at the end of your application.
  234.  
  235. The event dictionary and idle proc queue:
  236. -----------------------------------------
  237. EventMan.SetHandlersFrom()
  238.  
  239. Syntax: EventMan.SetHandlersFrom(HandlerBag)
  240.  
  241.         HandlerBag is a dynarray of the form
  242.  
  243.         HandlerBag[EventTag] = ProcName
  244.  
  245.         where EventTag and ProcName are both strings. ProcName must be an EXECPROCable procedure name which returns 0, 1, or 2 according to the rules of the WAIT ... PROC command.
  246.  
  247. Returns: Nothing.
  248.  
  249. Description: EventMan.SetHandlersFrom() provides a convenient way to populate EventMan's event handler dictionary, EventMan.Dictionary[].
  250.  
  251. Usage: declare a global dynarray for an object in your application or for default behavior for events, and assign procedure names (event handler names) to event tags. If the procedures are associated with an object, then add the dynarray Element
  252.  
  253.         HandlerBag["ObjectTag"] = ObjectTag
  254.  
  255. In the presence of an "ObjectTag" element for HandlerBag, EventMan.SetHandlersFrom() will convert the dynarray listing to the form
  256.  
  257.         EventMan.Dictionary[ObjectTag + EventTag] = ProcName.
  258.  
  259. In the absence of an "ObjectTag" element for HandlerBag, EventMan.SetHandlersFrom() will convert the dynarray listing to the form
  260.  
  261.         EventMan.Dictionary[EventTag] = ProcName
  262.  
  263. Keep HandlerBag as a global array so that it can be re-used with EventMan.ClearHandlersWith() (see below).
  264.  
  265. Example:
  266.  
  267. ; Assumes current window is table window...
  268. Proc SetClientTableHandlers()
  269.    Dynarray MyApp_ClientHandlers[]
  270.    ...
  271.    MyApp_ClientHandlers["RightDown"] = "ClientMenu"
  272.    MyApp_ClientHandlers["Close"] = "RemoveClientWindow"
  273.    ...
  274.    MyApp_ClientHandlers["ObjectTag"] = StrVal(GetWindow())
  275.    EventMan.SetHandlersWith(MyApp_ClientHandlers)
  276.    Return 1 ; in case this is called through EventMan
  277. EndProc
  278.  
  279. ------
  280. EventMan.ClearHandlersWith()
  281.  
  282. Syntax: Eventman.ClearHandlersWith(HandlerBag)
  283.  
  284.         See EventMan.SetHandlerFrom() above for description of the HandlerBag parameter.
  285.  
  286. Returns: Nothing.
  287.  
  288. Description: Removes entries from EventMan.Dictionary[]
  289.  
  290. Usage: Use EventMan.ClearHandlersWith() to remove entries to EventMan.Dictionary[] that have been set with EventMan.SetHandlersWith()
  291.  
  292. Example:
  293.  
  294. ; Assumes current window is table window...
  295. Proc ClearClientWindow()
  296.    Window Close
  297.    EventMan.ClearHandlersWith(MyApp_ClientHandlers)
  298.    Return 1
  299. EndProc
  300.  
  301. ------
  302.  
  303. EventMan.RegisterIdleServer()
  304.  
  305. Syntax: EventMan.RegisterIdleServer(ObjectTag,IdleProcName)
  306.         ObjectTag is a string that is used as an internal reference by the idle server mechanism.
  307.         IdleProcName is an EXECPROCable procedure name.
  308.  
  309. Returns: Nothing.
  310.  
  311. Description: EventMan.RegisterIdleServer() adds a procedure to a queue of procedures to be EXECPROC'd whenever an IDLE event is collected by EventMan. This procedure does not guarantee that the registered procedures will be fired in the order that they are registered.
  312.  
  313. Usage: If your application can benefit from asysnchronous events, then register procedures that execute those asynchronous events using EventMan.RegisterIdleServer(). The procedures so registered will be EXECPROC'd in sequence. EventMan keeps track of the last idle procedure which has been serviced, and starts at the beginning of the list after the last one has been serviced. To replace an object's procedure, just call EventMan.RegisterIdleServer() a second time with the same ObjectTag and a different IdleProcName.
  314.  
  315. Example:
  316.         EventMan.RegisterIdleServer("CLOCK","Clock.Tick")
  317.         ...
  318.         EventMan.RegisterIdleServer("DESKTOP","DesktopStatus")
  319.  
  320. ------
  321. EventMan.DeRegisterIdleServer()
  322.  
  323. Syntax: EventMan.DeRegisterIdleServer(ObjectTag)
  324.         ObjectTag is a string that was used to register an idle server procedure using EventMan.RegisterIdleServer() (see above).
  325.  
  326. Returns: Nothing.
  327.  
  328. Description: Removes an idle server procedure from the idle server queue.
  329.  
  330. Usage: use this procedure to remove a procedure from the idle server queue after it has been added by the EventMan.RegisterIdleServer() procedure.
  331.  
  332. Example:
  333.         Eventman.DeRegisterIdleServer("CLOCK")
  334.  
  335.  
  336. Event collectors: (use these in your code)
  337. ------------------------------------------
  338.  
  339. EventMan.CatchTrigger()
  340.  
  341. Syntax: WAIT ... PROC "EventMan.CatchTrigger" ... ENDWAIT
  342.  
  343. Like all WAIT procedures, EventMan.CatchTrigger() has three parameters, as follows: EventMan.CatchTrigger(EventMan.TriggerTag, EventMan.EventBag, EventMan.TriggerCycle). EventMan.TriggerTag is a string, EventMan.EventBag is a dynamic array, and EventMan.CycleNumber is a number. See the documenation of the WAIT command in the Paradox manuals for details about these parameters.
  344.  
  345. Returns: 0, 1, or 2
  346.  
  347. Description: EventMan.CatchTrigger() is designed to collect, analyse, and dispatch events collected with the WAIT statement.
  348.  
  349. Usage: Unless there is a very compelling reason not to do so, EventMan.CatchTrigger() should be used with all WAIT PROC statements in your application.
  350.  
  351. Example:
  352.         WAIT WORKSPACE
  353.            PROC "EventMan.CatchTrigger" All
  354.         ENDWAIT
  355.  
  356. ------
  357. EventMan.DoGetEvent()
  358.  
  359. Syntax: EventMan.DoGetEvent()
  360.  
  361. Returns: Nothing.
  362.  
  363. Description: EventMan.DoGetEvent() is designed as an alalog to WAIT ... PROC "EventMan.CatchTrigger" ... ENDWAIT. It takes the general form:
  364.  
  365.         ReturnCode = 0
  366.         While ReturnCode < 2
  367.            GetEvent ... To EventBag
  368.            <analyze event>
  369.            <dispatch event>
  370.            If ReturnCode = 0 Then
  371.               ExecEvent EventBag
  372.            Endif
  373.         EndWhile
  374.  
  375. Therefore event handling procedures that are written for the WAIT form of event handling can be used with the GETEVENT form of event handling as well. The main difference between the WAIT and GETEVENT forms of event handling is that the GETEVENT form does not collect TRIGGERS.
  376.  
  377. Usage: use EventMan.DoGetEvent() when there are no images on the workspace or when you do not want to collect TRIGGERs.
  378.  
  379. Example:
  380.         If nImages() > 0 Then
  381.            Wait Workspace
  382.               Proc "EventMan.CatchTrigger" All
  383.            EndWait
  384.         Else
  385.            EventMan.DoGetEvent()
  386.         Endif
  387.  
  388. Event analysis:
  389. ---------------
  390.  
  391. EventMan.GetTargetWindow()
  392.  
  393. Syntax: EventMan.GetTargetWindow(TriggerTag,EventBag)
  394.         TriggerTag is a string that must be "EVENT" or a valid TRIGGER name.
  395.         EventBag is a dynamic array that must be a valid event packet if TriggerTag is "EVENT".
  396.  
  397. Returns: 0 or a valid window handle.
  398.  
  399. Description: Evaluates the current event in relation to the windows on (and above) the desktop, and determines the target window for the event. If there is no window, then EventMan.GetTargetWindow() returns the window handle of the desktop (0). EventMan.GetTargetWindow() assumes ECHO NORMAL.
  400.  
  401. Usage: EventMan.GetTargetWindow() is used by EventMan to set EventMan.TargetWindow. It is not necessary to use it directly in your applications, although unlike most other procedures of EventMan, it is written as an independent procedure that can be used on its own outside of the context of EventMan.
  402.  
  403. ------
  404. EventMan.SetWindowAsObjectTag()
  405.  
  406. Syntax: EventMan.SetWindowAsObjectTag()
  407.  
  408. Returns: Nothing, but sets EventMan.ObjectTag as a side effect.
  409.  
  410. Description: "EventMan.SetWindowAsObjectTag" is the default for EventMan.SetObjectTagProc. It sets EventMan.ObjectTag to StrVal(EventMan.TargetWindow) if EventMan.TargetWindow is a valid window handle, or to blank if EventMan.TargetWindow is not a valid window handle.
  411.  
  412. Usage: There is no need to call EventMan.SetWindowAsObjectTag() directly from your applications. It is called automatically by the event collectors EventMan.CatchTrigger() and EventMan.DoGetEvent().
  413.  
  414. ------
  415. EventMan.SetIndexedObjectTag()
  416.  
  417. Syntax: EventMan.SetIndexedObjectTag()
  418.  
  419. Returns: Nothing, but sets EventMan.ObjectTag as a side effect.
  420.  
  421. Description: "EventMan.SetIndexedObjectTag" is an alternative for EventMan.SetObjectTagProc. It sets EventMan.ObjectTag to EventMan.WindowObjectTag[EventMan.TargetWindow] unless EventMan.TargetWindow is not a valid window handle, in which case EventMan.ObjectTag is set to blank.
  422.  
  423. Usage: Set EventMan.SetObjectTagProc = "EventMan.SetIndexedObjectTag".
  424. There is no need to call EventMan.SetIndexedObjectTag() directly from your applications. It will be called automatically by the event collectors EventMan.CatchTrigger() and EventMan.DoGetEvent(). However your applications will be responsible for maintaining accurate cross reference information in EventMan.ObjectTagWindow[] and Eventman.WindowObjectTag[].
  425.  
  426. Example:
  427.         EventMan.SetObjectTagProc = "EventMan.SetIndexedObjectTag"
  428.         ...
  429.         View "Customer"
  430.         EventMan.ObjectTagWindow["CustomerTable"] = GetWindow()
  431.         EventMan.WindowObjectTag[GetWindow()] = "CustomerTable"
  432.  
  433. ------
  434. EventMan.SetEventTag()
  435.  
  436. Syntax: EventMan.SetEventTag()
  437.  
  438. Returns: Nothing, but sets EventMan.EventTag And EventMan.EventType as side effects.
  439.  
  440. Description: EventMan.SetEventTag() uses EventMan.EventBag[] to create a string naming the current event. This string is intended for use in conjunction with EventMan.ObjectTag to select an event handler from EventMan.Dictionary[] by the event dispatcher. The rules for converting EventMan.EventBag[] information to string form in EventMan.EventTag are as follows:
  441.  
  442. For a KEY event type: Strval(EventMan.EventBag["Keycode"]
  443.  
  444. For a MOUSE event type:
  445.         Here is the source code:
  446.  
  447.          Action = EventMan.EventBag["Action"]
  448.          Switch
  449.             Case Action = "DOWN":
  450.                EventMan.EventTag = EventMan.EventBag["Buttons"] +
  451.                   IIf(EventMan.EventBag["DoubleClick"],"DOUBLE","") +
  452.                   Action
  453.                EventMan.MouseModeButton = EventMan.EventBag["Buttons"]
  454.             Case Action = "UP":
  455.                EventMan.EventTag =
  456.                   IIf(EventMan.EventBag["DoubleClick"],"DOUBLE","") +
  457.                   Action
  458.             Case EventMan.EventBag["Buttons"] = "NONE":
  459.                EventMan.EventTag =
  460.                    "NONE" + Action
  461.                EventMan.MouseModeButton = "NONE"
  462.             OtherWise:
  463.                EventMan.EventTag =
  464.                    EventMan.EventBag["Buttons"] + Action
  465.          EndSwitch
  466.  
  467. This provides the following possible event tags for the mouse:
  468.  
  469.         LEFTDOWN        LEFTDOUBLEDOWN
  470.         RIGHTDOWN       RIGHTDOUBLEDOWN
  471.         BOTHDOWN        BOTHDOUBLEDOWN
  472.         UP              DOUBLEUP
  473.         NONEMOVE
  474.         NONEAUTO
  475.         LEFTMOVE
  476.         LEFTAUTO
  477.         RIGHTMOVE
  478.         RIGHTAUTO
  479.         BOTHMOVE
  480.         BOTHAUTO
  481.  
  482. Note that EventMan.MouseModeButton is set as a side effect when the action is "DOWN", or when there are no buttons pressed.
  483.  
  484. For a MESSAGE event type:
  485.         If the message is "MENUSELECT", then EventMan.EventTag is set to a concatanation of "MenuTag:" and the value in EventMan.EventBag["MenuTag"].
  486.         If the message is "MENUKEY", then EventMan.EventTag is set to a concatanation of "MenuKey:" and the value in EventMan.EventBag["Keycode"].
  487.         Otherwise, EventMan.EventTag is set to the value in EventMan.EventBag["Message"]. Here is the source code:
  488.  
  489.          EventMan.EventTag = EventMan.EventBag["Message"]
  490.          If EventMan.EventTag = "MENUSELECT" Then
  491.             EventMan.EventTag = "MENUTAG:" + EventMan.EventBag["MenuTag"]
  492.          Endif
  493.          If EventMan.EventTag = "MENUKEY" Then
  494.             EventMan.EventTag = "MENUKEY:" + EventMan.EventBag["Keycode"]
  495.          Endif
  496.  
  497. For the IDLE event, EventMan.EventTag is set to "IDLE".
  498.  
  499. For a TRIGGER event type:
  500. Note that EventMan.CatchTrigger() sets EventMan.EventTag to EventMan.TriggerTag and EventMan.EventType to "TRIGGER" if EventMan.TriggerTag is not "EVENT".
  501.  
  502. Usage: There is normally no reason to call EventMan.SetEventTag() directly from your application.
  503.  
  504. Event dispatch:
  505. ---------------
  506.  
  507. EventMan.DispatchEventBag()
  508.  
  509. Syntax: EventMan.DispatchEventBag() ; used by collectors
  510.  
  511. Returns: Nothing, although EventMan.ReturnCode is set by its sub-calls as a side effect.
  512.  
  513. Description: EventMan.DispatchEventBag() is used by the event collectors EventMan.CatchTrigger(), EventMan.DoGetEvent() and EventMan.CompleteMouseSequence() to dispatch events. It requires a valid EventMan.EventBag[] in the environment. It then calls EventMan.SetEventBag(). If EventMan.EventTag is "IDLE" then EventMan.DispatchEventBag() calls EventMan.DoIdleEvent(). If EventMan.EventTag is not "IDLE" or if the call to EventMan.DoIdleEvent() does not EXECPROC and idle event handler, then EventMan.DispatchEventProc EXECPROC's EventMan.DispatchEventTagProc. This is the heart of EventMan.
  514.  
  515. Usage: There is normally no reason to call EventMan.DispatchEventBag() directly from your application. However advanced applications can set EventMan.EventBag[] independently, and then call EventMan.DispatchEventBag() to push that event through the event dispatch mechanism independent of the event collection mechanism that captures events from Paradox.
  516.  
  517. Example: (for advanced applications)
  518.         EventMan.ObjectTag = "CLIENT"
  519.         Dynarray EventMan.EventBag[]
  520.         EventMan.EventBag["Type"] = "KEY"
  521.         EventMan.EventBag["Keycode"] = Asc("WinClose")
  522.         EventMan.DispatchEventBag()
  523.  
  524. ------
  525. EventMan.DispatchEventTag()
  526.  
  527. Syntax: EventMan.DispatchEventTag()
  528.  
  529. Returns: Nothing, although EventMan.ReturnCode is set as a side effect.
  530.  
  531. Description: EventMan.DispatchEventTag() is the default EventMan.DispatchEventTagProc used by EventMan.DispatchEventBag() (see above). EventMan.DispatchEventTag() looks for EventMan.Dictionary[EventMan.ObjectTag + EventMan.EventTag]. If found it EXECPROC's the value and sets EventMan.ReturnCode to Retval. If not found it looks for EventMan.Dictionary[EventMan.EventTag]. If found it EXECPROC's the value and sets EventMan.ReturnCode to Retval. If not found it simply sets EventMan.ReturnCode to EventMan.DefaultReturnCode.
  532.  
  533. Usage: There is normally no reason to call EventMan.DispatchEventTag() directly from your application. However advanced applications can set EventMan.EventTag independently, and then call EventMan.DispatchEventTag() to push that event through the event dispatch mechanism independent of the event collection mechanism that captures events from Paradox.
  534.  
  535. Example: (for advanced applications)
  536.         EventMan.ObjectTag = "CLIENT"
  537.         EventMan.EventTag = "POSTRECORD"
  538.         EventMan.DispatchEventTag()
  539.  
  540. ------
  541. EventMan.DoIdleEvent()
  542.  
  543. Syntax: EventMan.DoIdleEvent()
  544.  
  545. Returns: True if an idle event has been EXECPROC'd, otherwise False. If true has been returned, then EventMan.ReturnCode has been set to 1 as a side effect.
  546.  
  547. Description: EXECPROC's procedures registered by EventMan.RegisterIdleServer() (see above) on a rotating basis.
  548.  
  549. Usage: There is normally no reason to call EventMan.DoIdleEvent() directly from your application. It is automatically called by EventMan.DispatchEventTag().
  550.  
  551. Utility procs:
  552. --------------
  553. EventMan.DoWait()
  554.  
  555. Syntax: EventMan.DoWait()
  556.  
  557. Returns: Nothing.
  558.  
  559. Description: Provides a simple default shell for EventMan.CatchTrigger(), as follows:
  560.  
  561.    Echo Normal
  562.    Wait WorkSpace
  563.       Proc "EventMan.CatchTrigger" All
  564.    EndWait
  565.  
  566. Usage: Use this as the default Wait command in your application until the event list to be captured can be refined.
  567.  
  568. ------
  569. EventMan.GetEvent()
  570.  
  571. Syntax: EventMan.GetEventProc = "EventMan.GetEvent"
  572.  
  573. Returns: Nothing, but Sets EventMan.EventBag[] as a side effect.
  574.  
  575. Description: Provides a simple GETEVENT statement to collect all events to EventMan.EventBag[], as follows:
  576.  
  577.    GetEvent All To EventMan.EventBag
  578.  
  579. Usage: Acts as the default EventMan.GetEventProc used by EventMan.DoGetEvent(). When your application can refine the events to be collected, then place the refined GETEVENT statement into a procedure and assign that procedure name to EventMan.GetEventProc.
  580.  
  581. ------
  582. EventMan.EnableEvent()
  583.  
  584. Syntax: EventMan.EnableEvent()
  585.  
  586. Returns: 0
  587.  
  588. Description: Simply returns 0.
  589.  
  590. Usage: Intended for use with EventMan.Dictionary[] to override a default returncode of 1. Since the default EventMan.DefaultReturnCode is 0, it is unlikely that EventMan.EnableEvent would be used. It is included to provide symmetry to EventMan.DisableEvent().
  591.  
  592. ------
  593. EventMan.DisableEvent()
  594.  
  595. Syntax: EventMan.DisableEvent()
  596.  
  597. Returns: 1
  598.  
  599. Description. Simply returns 1.
  600.  
  601. Usage: Can be used to disable certain events, in conjunction with EventMan.Dictionary[].
  602.  
  603. Example: The following example prevents the user from shelling out to DOS from an application:
  604.  
  605.         Dynarray DefaultHandlerProcs[]
  606.         DefaultHandlerProcs[Asc("Dos")] = "EventMan.DisableEvent"
  607.         DefaultHandlerProcs[Asc("DosBig")] = "EventMan.DisableEvent"
  608.         ...
  609.         EventMan.SetHandlersFrom(DefaultHandlerProcs)
  610.  
  611. ------
  612. EventMan.CompleteMouseSequence()
  613.  
  614. Syntax: EventMan.CompleteMouseSequence()
  615.  
  616. Returns: EventMan.ReturnCode, and also sets EventMan.ReturnCode as a side effect. It always returns a 1 or a 2.
  617.  
  618. Description: Mouse events are normally modal, beginning with a mouse DOWN event and ending with a mouse UP event. The purpose of EventMan.CompleteMouseSequence() is to ignore all events other than mouse events after a mouse DOWN event has been executed. With respect to subsequent mouse events, it treats them the same as any event collector (EventMan.CatchTrigger() and EventMan.DoGetEvent(), except that it does not set EventMan.TargetTag and EventMan.ObjectTag. Instead is uses the same EventMan.TargetTag and EventMan.ObjectTag that was set with the mouse DOWN event that is presumed to have preceded the call to EventMan.CompleteMosueSequence().
  619.  
  620. Usage: EventMan.CompleteMouseSequence() is designed to be used in a mouse DOWN handler. It should only be used where it is known that Paradox will not "eat" subsequent mouse events, otherwise it may get "stuck" waiting for EventMan.EventBag["Buttons"] = "NONE".
  621.  
  622. Example:
  623.  
  624.         Proc MouseDownHandler()
  625.            ExecEvent EventMan.EventBag
  626.            EventMan.CompleteMouseSequence()
  627.            Return EventMan.ReturnCode
  628.         EndProc
  629.         ...
  630.         MyApp_EventHandlers["LeftDown"] = "MouseDownHandler"
  631.         ...
  632.         EventMan.SetHandlersWith(MyApp_EventHandlers)
  633.  
  634. ------
  635. EventMan.ReturnFromMouseMode()
  636.  
  637. Syntax: EventMan.ReturnFromMouseMode()
  638.  
  639. Returns: EventMan.ReturnCode, and also sets EventMan.ReturnCode as a side effect. It always returns a 1.
  640.  
  641. Description: This is designed to "eat" mouse events subsequent to a mouse DOWN.
  642.  
  643. Usage: use in any situation after executing a mouse DOWN where you want to "eat" subsequent events until a mouse UP is collected.
  644.  
  645. Example:
  646.  
  647.     ExecEvent EventMan.EventBag ; execute mouse DOWN
  648.     EventMan.ReturnFromMouseMode() ; wait until user releases mouse button
  649.  
  650. Properties:
  651. ------------
  652.  
  653. The following is a summary of properties available to your application at run-time. All of these are read-only with the following exceptions:
  654.  
  655. EventMan.GetEventProc should have a GETEVENT procedure name assigned when your application is in a position to limit the events to be captured.
  656.  
  657. For advanced applications, the following properties can be assigned:
  658.         EventMan.EventBag[]
  659.         EventMan.EventTag
  660.         EventMan.ObjectTag (typically from within a custom
  661.                 EventMan.SetObjectTagProc
  662.         EventMan.DefaultReturnCode (rare!)
  663.         EventMan.ReturnCode (Set by your new EventMan.DispatchEventTagProc)
  664.         EventMan.SetObjectTagProc
  665.         EventMan.DispatchEventTagProc
  666.  
  667. EventMan.IsActive ; readonly, is EventMan active? (use isAssigned)
  668. EventMan.IsGetEvent ; readonly, is this a GETEVENT event? (use isAssigned)
  669. EventMan.IsWait ; readonly, is this a WAIT event? (use isAssigned)
  670. EventMan.Dictionary[] ; EventMan.Dictionary[ObjectTag + EventTag] = ProcName
  671. EventMan.EventBag[] ; as collected by wait or getevent
  672. EventMan.ObjectTagWindow[] ; The current window handle for your ObjectTag
  673. EventMan.WindowObjectTag[] ; The ObjectTag of the current window handle
  674. EventMan.EventType ; TRIGGER or EventMan.EventBag["Type"]
  675. EventMan.MouseModeButton ; Button pressed with last DOWN, or "NONE"
  676. EventMan.TargetWindow ; set by collectors from EventMan.GetTargetWindow(..)
  677. EventMan.ObjectTag ; string value for EventMan.Dictionary set by
  678.                    ; EventMan.SetWindowAsObjectTag() or
  679.                    ; EventMan.SetObjectTagProc
  680. EventMan.EventTag ; sometimes composite string value for
  681.                   ; EventMan.Dictionary set by EventMan.SetEventTag()
  682. EventMan.ReturnCode ; must be set by DispatchEventTagProc
  683. EventMan.DefaultReturnCode ; return code when handler search fails
  684. EventMan.GetEventProc ; getevent specs for DoGetEvent
  685. EventMan.SetObjectTagProc ; sets EventMan.ObjectTag based on
  686.                           ; Eventman.TargetWindow
  687. EventMan.DispatchEventTagProc ; dispatches event to EventMan.Dictionary