[jawsscripts] Re: A last-gasp attempt at this 3270 problem of mine

  • From: "Geoff Chapman" <gch@xxxxxxxxxxxxxxxx>
  • To: <jawsscripts@xxxxxxxxxxxxx>
  • Date: Fri, 15 Jun 2012 15:24:25 +1000

So but Steve, are you saying this is kind of a done deal now? and that you 
can no longer access the system to work on it for this potential employee?
Does this mean the person is just not gunna get the job though? not because 
it can't be done, but because it can't be done in one day?
Far out though! That just seems all wrong to me!
What about the jolly blind employee!

In case you can submit a report indicating that it can be actually done, and 
encourage your bean counters to spill forth with the funds in order to 
permit this employee a useable and eficient playing field, if given 
sufficient time to put it together, then here is the adendum to my post I 
promised you yesterday, complete with code fragments which might help.

Ok so I'll just try and explain a bit of this before pasting.

The first function, VirtualizePriorityInfoCustomerHistoryNarrative,  is just 
a simple example of the method I used to grab data from various custom 
defined rectangles on the screen, without first defining them as frames, and 
adding them to the userBuffer, along with manually inserted text String 
labels for each one, then immediately virtualizing that info for user to 
traverse.
Of course I'd done the checking as to whether I was on the correct screen, 
previously, firstly using NewTextEvent, to watch for a whole range of 
possible screen identifiers that I'd found denoted each screen, then 
scheduling little ScreenCheck functions if it saw that text come in, to then 
check if that text was in it's expected place on given screens.  Then based 
on that outcome I'd set a giWhichScreen Global integer variable, to a 
certain number.
Then, Although I know seasoned scripters warn to be jolly careful not to 
clutter up both NewTextEvent and KeyPressedEvent, because of just how often 
the jolly things run, and I totally understood that,
i ended up utilizing KeyPressedEvent pretty extensively, and I've had no 
complaints from the employees using it, in jaws8, on machines 5 years old 
now in performance,
To enable me to do exactly what you were wanting to do. I.e. use the same 
set of control+GraveAccent through Number keys, to grab different data/do 
different things, on their relevant screens etc.

I'll paste in a rather lengthy yet fairly repetitious fragment of my 
KeyPressedEvent usage, just to show how it ended up working, along with 
fairly extensive commentary.
I hope it may help.

in basic form, in case you don't reeeeally need to read the code to get the 
jist,
the logic of the KeyPressedEvent usage was,
First run a SaveKeyHistory Function at the front end,
(Which facilitates some necessary usage of an overRiding IsSameScript 
function, the necessity of which escapes me for the moment,)
then,
if I'm on screen1, Blah Blah screen, then,
 if nKey is Blah, then,
if KeyboardHelp is enabled, then,
if IsSameScript DoublePressed in Keyboard help then,
 run the doublePress code,
else Single Press Keyboard Help for that key.
EndIf Keyboard Help active check,
then
run the function to grab the relevant data you wanna either hear, or 
virtualize, for that key, on that particular screen.

Oh By the way, in case anyone is wondering, I didn't come up with this cool 
logic/idea myself.
but it worked a treat for me, and x years out the people are still using it 
successfully under jaws 8.

ok here we go then. code time.

The kind of code I used, to grab things from the screen and shove them into 
the UserBuffer, with manual field labels alongside each bit of data, looked 
something like this:

Function VirtualizePriorityInfoCustomerHistoryNarrative () ; assigned to 
control+GraveAccent on Customer History Narrative Screen

; immediately Virtualizes the 5 most relevant components, Order date, 
narrative record type code, description, UserID, and LastChangedTime, from 
customer history narrative screen.

; as opposed to speaking them on a singleKeyPress and virtualizing them upon 
a doublePress, because will always be too much info to take in, in one 
announcement shot.





var

string sOrderDate,

String sNarrativeRecordTypeCode,

String sDescription,

String sUserID,

string sLastChangedTime



; let user no i'ts virtualizing on a single keyPress.

SayUsingVoice (VCTX_JAWSCURSOR, "virtual", OT_String)



; first check userBuffer isn't already active and give time to dismiss for 
screen to settle if so. Delay is long but it had to be for stability in this 
setup.



If UserBufferIsActive () then

UserBufferDeactivate ()

UserBufferClear ()

SayUsingVoice (VCTX_JAWSCURSOR, "Please wait", Ot_String)

Delay (6)

EndIf ; is UserBuffer Active check

; now populate the variables with the data info we want, using GetTextInRect 
functions instead of GetTextInFrames, coz I found it easier in the end.

; also precede each line with it's field label manually, inserting space 
before closing quote after the colon, for nicer reading, plus ability to 
controlRightArrow to the data if needs to step through char by char.

let sLastChangedTime = GetTextInRect (861, 561, 921, 584)

let sNarrativeRecordTypeCode = GetTextInRect (369, 197, 873, 220)

let sDescription = GetTextInRect (369, 223, 969, 246)

let sUserID = GetTextInRect (369, 249, 489, 272)

let sOrderDate = GetTextInRect (369, 171, 489, 194)



; now compile the userBuffer and virtualize info

UserBufferDeactivate ()

UserBufferClear ()

UserBufferAddText ("LastChangedTime: " + sLastChangedTime)

UserBufferAddText ("NarrativeRecordType: " + sNarrativeRecordTypeCode)

UserBufferAddText ("Description: " + sDescription)

UserBufferAddText ("UserID: " + sUserID)

UserBufferAddText ("Date: " + sOrderDate)

UserBufferActivate ()

JawsTopOfFile ()

SayLine ()

EndFunction




And before demonstrating usage of KeyPressedEvent, here's the bits of 
supporting code that were in place for it to work.

void function SaveKeyHistory (string keyName)
; call this function from the first line of KeyPressedEvent
;SayString ("beep")
Let strPreviousKey = strLastKey
Let strLastKey = keyname
ScheduleFunction ("KeyboardTimeout", 5)
EndFunction

Void Function KeyboardTimeOut ()
Let strLastKey = ""
;Pause ()
Let strPreviousKey = "..."
EndFunction

Int Function IsSameScript ()
if (strLastKey == strPreviousKey) then
 return(1)
else
 return(0)
EndIf
EndFunction

 Function KeyPressedEvent (int nKey, string strKeyName, int nIsBrailleKey, 
int nIsScriptKey)
;  to learn what the NKey Variable integers are as I press them
; SayInteger (NKey)

/*
 as an alternative to swapping jkm files in and out of memory to alter the 
behaviour of certain keys dependent on screen context,
 as is currently being done with frame files for the same purpose,
 I'm going to experiment with using KeyPressedEvent logic to handle this, to 
see which gives better endUser results/performance.
 so either this code, or swapping jkm code, should be left active, but not 
both.
 test code to see whether KeyPressedEvent logic will be best to handle 
varying reading jobs on various screens.
 ok. this first line is placed here to enable a special SaveKey History 
function to record each key being pressed,
 to enable implementation of a special IsSameScript function overriding the 
builtIn,
 which facilitates the same keys being assigned diferent functions on 
different screens,
 to hopefully make things simpler for the user who may wish to just grab the 
most useful information from a group of say 5 sameKey keystrokes,
 rather than having to remember a bunch of keystrokes across several screens 
which in many cases may be glancing at very similar data in each case.
*/
; this is the function which acts as a kind of scrolling buffer of keys, 
which facilitates the IsSameScript emulation in KeyPressedEvent multiple key 
screen Assignment idea.
SaveKeyHistory (strKeyName)

if giWhichScreen == 1 then ; ScreenCheck1 Login/Entry screen
if NKey == 297 then ; Control+` on Main Menu/Login screen
if gbKeyboardHelp then
if IsSameScript () then ; double press
SayString (GetScriptDescription ("ManualReadMainMenuEntryScreen"))
else ; single press
SayString (GetScriptSynopsis ("ManualReadMainMenuEntryScreen"))
EndIf ; doublePress IsSameScript check
Return ; done speaking hotkey help
EndIf ; keyboard Help on check.

; now run function attached to control+GraveAccent on Main Menu/Login Screen
ManualReadMainMenuEntryScreen ()
Endif ; 2, end of keys for screen1.

; nothing needed for screen 2 at this point

elif giWhichScreen == 3 ; Enquiry readOnly screen
|| GiWhichScreen == 20 then ; Edit master enquiry screen
; ScreenCheck 3 for Advanced customer master enquiryReadOnlyScreen plus 
screen 20 also.

if NKey == 258 then ; Control+1
if gbKeyboardHelp then
if IsSameScript () then ; double press
SayString (GetScriptDescription 
("CustomerNameReadReviewMasterInquiryReadOnly"))
else ; single press
SayString (GetScriptSynopsis 
("CustomerNameReadReviewMasterInquiryReadOnly"))
EndIf ; doublePress IsSameScript check
Return ; done speaking hotkey help
EndIf ; keyboard Help on check.
; now run function attached to control+1 on Master Inquiry screen
CustomerNameReadReviewMasterInquiryReadOnly ()
; That just reads if singlePressed, Virtualizes if DoublePressed.

elif NKey == 259 then ; Control+2
if gbKeyboardHelp then
if IsSameScript () then ; double press
SayString (GetScriptDescription 
("CustomerAddressReadReviewMasterInquiryReadOnly"))
else ; single press
SayString (GetScriptSynopsis 
("CustomerAddressReadReviewMasterInquiryReadOnly"))
EndIf ; IsSameScript doublePress check
Return ; done speaking hotkey help
EndIf ; keyboard Help on check.
; now run function attached to Control+2 on Master Inquiry screen
CustomerAddressReadReviewMasterInquiryReadOnly ()

elIf NKey == 260 then ; Control+3
if gbKeyboardHelp then
if IsSameScript () then ; double press
SayString (GetScriptDescription ("CommentsReadReviewMasterInquiryReadOnly"))
else ; single press
SayString (GetScriptSynopsis ("CommentsReadReviewMasterInquiryReadOnly"))
EndIf ; IsSameScript check
Return ; done speaking hotkey help
EndIf ; keyboard Help on check.
; now run function attached to Control+3 on Master Inquiry screen
CommentsReadReviewMasterInquiryReadOnly ()

elIf NKey == 261 then ; Control+4
if gbKeyboardHelp then
if IsSameScript () then ; double press
SayString (GetScriptDescription 
("InstructionsReadReviewMasterInquiryReadOnly"))
else ; single press
SayString (GetScriptSynopsis 
("InstructionsReadReviewMasterInquiryReadOnly"))
EndIf ; IsSameScript check
Return ; done speaking hotkey help
EndIf ; keyboard Help on check.
; now run function attached to Control+4 on Master Inquiry screen
InstructionsReadReviewMasterInquiryReadOnly ()

elIf NKey == 262 then ; Control+5
if gbKeyboardHelp then
if IsSameScript () then ; double press
SayString (GetScriptDescription 
("LastOrderReadReviewMasterInquiryReadOnly"))
else ; single press
SayString (GetScriptSynopsis ("LastOrderReadReviewMasterInquiryReadOnly"))
EndIf ; IsSameScript check
Return ; done speaking hotkey help
EndIf ; keyboard Help on check.
; now run function attached to Control+4 on Master Inquiry screen
LastOrderReadReviewMasterInquiryReadOnly ()

elIf NKey == 297 then ; Control+GraveAccent on master Inquiry screen
if gbKeyboardHelp then
if IsSameScript () then ; double press
SayString (GetScriptDescription 
("InstructionsReadReviewMasterInquiryReadOnly"))
else ; single press
SayString (GetScriptSynopsis 
("InstructionsReadReviewMasterInquiryReadOnly"))
EndIf ; IsSameScript check
Return ; done speaking hotkey help
EndIf ; keyboard Help on check.
; now run function attached to Control+GraveAccent on Master Inquiry screen
PerFormScript ReorderAdvancedCustomerMasterInquiryScreen ()


; ...

Etc etc.
***



----- Original Message ----- 
From: "Steve Matzura" <number6@xxxxxxxxxxxxxx>
To: <jawsscripts@xxxxxxxxxxxxx>
Sent: Friday, June 15, 2012 12:35 AM
Subject: [jawsscripts] Re: A last-gasp attempt at this 3270 problem of mine


> That was going to be another approach. I have also learned that the
> budget measured in both time and money for this project is severely
> limited, and they were hoping to have the potential employee start
> next week! This would take me at least a week to figure out, develop,
> implement, and train the user with it, and then, possibly less than a
> year from now, it would all go down the dumper when the company gets
> offa this 3270 nonsense. I wish I had the time to do this up right.
> You all have been immensely helpful with suggestions.
>
> On Tue, 12 Jun 2012 17:15:36 -0700 (PDT), you wrote:
>
>>Steve,
>>Â
>>Have you considered using Hotspot Clicker? You can control and load any 
>>number of key definition files you might need and then be able to reuse 
>>key assignments that are the same or similar. Just a thought.
>>Â
>>Tom
>>
>>________________________________
>> From: Steve Matzura <number6@xxxxxxxxxxxxxx>
>>To: jawsscripts <jawsscripts@xxxxxxxxxxxxx>
>>Sent: Tuesday, June 12, 2012 6:34 AM
>>Subject: [jawsscripts] A last-gasp attempt at this 3270 problem of mine
>>
>>Yesterday I spent a very productive three hours framing, labeling,
>>testing, triggering, and documenting a very busy screen on a
>>3270-emulation-based application. This thing was dancing on the
>>ceiling by the time I was finished with that screen. You could
>>hot-key-read any one of 35 fields on the screen, with or without field
>>names, which meant that I had to define two windows for each and every
>>field, and just in case you wanted to modify any of those fields, you
>>got a complimentary left-mouse-button click on that area of the screen
>>which would force the PC Cursor to that location so you could type
>>something in if so desired or if that area of the screen were even
>>designated as a field in the 3270 window definition back on the
>>application's home-base computer. Really neat stuff!
>>
>>Then, the second part of my day came crashing in. A summary screen
>>consisting of eleven lines of what amounted to a history view of
>>account activity in reverse chronological order, displayed in a
>>spreadsheet type layout, which needed to be broken up into its
>>individual fields, of which there were six per line, and searchable
>>and/or filterable by certain criteria within the data, such as show
>>only payments, show only bills, show only meter readings, etc.
>>Ideally, this should be available from the application itself, but it
>>isn't. If JAWS had the capability to define frames within frames, and
>>I don't mean just define another separate frame that just so happens
>>to be a sub-area of another frame, or if the ability existed to load a
>>separate set of frames and hot-key triggers for different screens all
>>with the same window name or control ID, I'd be set! Anybody remember
>>old JFD and how you could do stuf like that back then? I was also
>>thinking of trying to write a script which could navigate these eleven
>>lines of data and read only those lines where certain information was
>>displayed, like the code or text to indicate a payment, for example,
>>so the end-user could press a key and have the eleven lines filtered
>>the way they needed, but I couldn't for the life of me figure a way to
>>do this and get it coded in an hour or two! Frames are great things,
>>but they're not smart in any way, shape or form. You can't tell a
>>frame "read this if you contain certain data, keep silent otherwise."
>>At least, I don't *think* you can. The only possible way I could think
>>of to do this was if the information was color-coded in some way, but
>>it isn't. Everything on the screen is the same color except the
>>modifiable fields, of which there turned out not to be all that many.
>>
>>And I haven't even gotten to tell you about another data select screen
>>where you put a selection mark in front of a summary line, hit a
>>function key, and get one of half a dozen selectable new screens with
>>detailed information on the summary item you selected! An incredible
>>amount of data is available through this system. I've been in the
>>data-mining industry for years, but not since I worked on stuff for
>>the securities industry have I seen stuff like I saw yesterday. And
>>they want the customer rep who operates this thing to have access to
>>it all so that customers can check on any aspect of their account with
>>this company. The customer service industry has come a long way. The
>>reports this system produces must be real eye-openers!
>>
>>... but I digress ...
>>
>>Then there's the question of just how many key combinations can one
>>person be expected to remember for one little old application if I
>>were to define frames for every single field on every single screen,
>>most of which wouldn't even make sense to be used as such, not to
>>mention I'd run outa keys before I ran outa fields!
>>
>>It was for this reason that I have prepared a report, not yet
>>submitted, that states that scripting for this application will not go
>>far enough to satisfy the access requirements of a JAWS user to work
>>with it and get the job done for which the application was originally
>>written in any kind of efficient manner. However, before I submit this
>>report, I thought I'd throw it out to you all for one last-gasp effort
>>to see if there's anything I haven't tried that I should, etc. Your
>>input greatly sought and appreciated.
>>
>>__________�
>>
>>View the list's information and change your settings at
>>//www.freelists.org/list/jawsscripts
>>__________�
>>
>>View the list's information and change your settings at
>>//www.freelists.org/list/jawsscripts
>>
> __________�
>
> View the list's information and change your settings at
> //www.freelists.org/list/jawsscripts
> 

__________�

View the list's information and change your settings at 
//www.freelists.org/list/jawsscripts

Other related posts: