wolf@shaman.ingr.com (Wayne Wolf) (01/15/91)
I'm currently developing a Turbo Vision application and have encountered a minor stumbling point in the implementation. The application can be run with the user at hand or can be run unattended. Ideally it is desirable to produce only one set of code designed to handle the case where the user is at the terminal. To automate it would merely require a procedure that would spool a series of events (mostly keyboard presses) to the main event handler, simulating a user creating these events. The code is there already to handle this stream of events and no extra code is required to process an automated request save that to spool the events into the event queue. My dilemma is this: I do not see a mechanism that allows me to queue up these events. There exists a method for Views called PutEvent(Event) which allows me to put an event into the event queue. But, this is not helpful as it only allows ONE event to be put into the queue, and placing a group of these calls together has the net effect of only having the last call in the list place an event in the queue. I want to steer away from writing my own 'keyboard buffer inserter endall dohickey' mechanism if at all possible. Does anyone know how to sneak into the guts of the event handler and add new events to the end of the queue? Or, worst case, a pointer to some example source code that will monitor the keyboard buffer and when it drains to a sufficient level, pump in more keypresses (automated) from a user defined buffer. Ideally I'd like to be able to call a method, say PlaceEventInQueue(NextEvent), where my code would be as follows: ------ Procedure Automate; Var NextEvent: TEvent; Begin with NextEvent do begin What := evKeyDown; InfoPtr := Nil; KeyCode := kbF3; PlaceEventInQueue(NextEvent); (* simulate F3 press *) KeyCode := kbTab; PlaceEventInQueue(NextEvent); (* simulate Tab press *) KeyCode := kbEnter PlaceEventInQueue(NextEvent); (* simulate Enter press *) end; {with NextEvent} End; ------ To the application, when calling this procedure, it would appear as if the user had pressed F3, Tab, and then Enter. Any suggestions are appreciated. Thanx in advance. .. Wayne Wolf USENET : ...!uunet!ingr!wyle!shaman!wolf (try this one first) Internet: ww@beach.cis.ufl.edu
wolf@shaman.ingr.com (Wayne Wolf) (01/16/91)
Yesterday I posted to this group, a query for some help in designing functionality into a Turbo Vision application to allow inserting multiple events into the event queue. I did not receive any response, but I did find the solution after paging through the manual with more intensity. There is only a minor reference on how to accomplish this feat on page 125 under heading "Overriding GetEvent." I will include the source code I came up with to perform this event queue. The utility varies from implementing keyboard macros, to automating your application by reading a stream of commands and placing them into the event queue, to having one event cause a chain of multile events to occur. The code was written in about 30 mins and tested briefly, but appears to work. Any commentary is appreciated. I hope this will help anyone else who wants to implement this sort of functionality. Following are the new class definition you should inherit your application from, and then a sample program excerpt to show how the new class and its methods are used. Any usage questions, please send email to either of ...!uunet!ingr!wyle!shaman!wolf or ww@beach.cis.ufl.edu. --- Cut HERE ------- Unit AutoApp; {$F+,O+} (* Force far calls, allow overlaying *) Interface Uses App, Drivers; Const MaxEventQueue = 50; NullEvent : TEvent = (What:evNothing); Type EventQueueType = array[1..MaxEventQueue] of TEvent; PAutoApplication = ^TAutoApplication; TAutoApplication = object(TApplication) EventQueue : EventQueueType; QueueHead : word; QueueTail : word; Constructor Init; function EventInQueue: boolean; procedure GetEvent(var Event: TEvent); virtual; procedure GetNextEventFromQueue(var Event: TEvent); procedure InitEventQueue; procedure PutEventIntoQueue(NewEvent: TEvent); End; {TAutoApplication} Implementation (*---------------------------------------------------------------------------*) (* M E T H O D S : TAutoApplication *) (*---------------------------------------------------------------------------*) Constructor TAutoApplication.Init; Begin TApplication.Init; InitEventQueue; End; (*---------------------------------------------------------------------------*) Function TAutoApplication.EventInQueue: boolean; Begin EventInQueue := QueueHead <> QueueTail; End; (*---------------------------------------------------------------------------*) Procedure TAutoApplication.GetEvent(var Event: TEvent); Begin if EventInQueue then GetNextEventFromQueue(Event) else TApplication.GetEvent(Event); End; (*---------------------------------------------------------------------------*) Procedure TAutoApplication.GetNextEventFromQueue(var Event: TEvent); Begin Event := EventQueue[QueueHead]; EventQueue[QueueHead] := NullEvent; if QueueHead = MaxEventQueue then QueueHead := 1 else inc(QueueHead); End; (*---------------------------------------------------------------------------*) Procedure TAutoApplication.InitEventQueue; Var i : word; Begin QueueHead := 1; QueueTail := 1; for i := 1 to MaxEventQueue do EventQueue[i] := NullEvent; End; (*---------------------------------------------------------------------------*) Procedure TAutoApplication.PutEventIntoQueue(NewEvent: TEvent); Begin EventQueue[QueueTail] := NewEvent; if QueueTail = MaxEventQueue then QueueTail := 1 else inc(QueueTail); End; (*---------------------------------------------------------------------------*) END. ----------- To implement this new functionailty, your application object will inherit from TAutoApplication, instead of TApplication. Then, you could have a procedure to perform a series of events. For example, say the events to open a file called foo.pas were an OpenFile command, and then the keypresses for 'foo.pas'. The following procedure would implement this automatically. Note, the kb_xxx constants you will have defined somewhere within scope. Procedure MyApplication.AutoOpenFoo; Const NumEvents = 9; AutoEvents: array[1..NumEvents] of TEvent = ( (What:evCommand; Command: cmOpenFile), (What:evKeyDown; KeyCode: kb_f), (What:evKeyDown; KeyCode: kb_o), (What:evKeyDown; KeyCode: kb_o), (What:evKeyDown; KeyCode: kb_dot), (What:evKeyDown; KeyCode: kb_p), (What:evKeyDown; KeyCode: kb_a), (What:evKeyDown; KeyCode: kb_s), (What:evKeyDown; KeyCode: kbEnter), ); Var i : word; Begin for i := 1 to NumEvents do PutEventIntoQueue(AutoEvents[i]); End; ----------- If anyone has some $0.02 to add please do. .. Wayne Wolf USENET : ...!uunet!ingr!wyle!shaman!wolf (try this one first) Internet: ww@beach.cis.ufl.edu (forwards to shaman!wolf)