Re: Next couple of questions relating to retrieving an object based on controlID, performing actions, typing in text automatically and event binding


Travis Roth
 

Hi Jacob,

Correct, it’d depend on the application.

Control IDs are not as reliable as they used to be if they exist at all. Many modern applications either use the same one or randomize them or set everything to 0 essentially not having them.

Travis

 

From: nvda-addons@nvda-addons.groups.io <nvda-addons@nvda-addons.groups.io> On Behalf Of Jacob Kruger
Sent: Wednesday, January 13, 2021 11:01 AM
To: nvda-addons@nvda-addons.groups.io
Subject: Re: [nvda-addons] Next couple of questions relating to retrieving an object based on controlID, performing actions, typing in text automatically and event binding

 

Travis, in terms of #1 if I, for example, try using that in notepad - purely as a test, with the controlID value being passed as the controlID have literally just pulled from the file menu, I am still getting the following error message in the log:

LookupError: No matching descendant window found

 

And, I tried switching over from api.getForegroundObject() to api.getDesktopObject() just in case, but, no difference.

 

Also 'see' that the controlID value is different each time, so, this would not really be feasible as such - would need to rather look into a form of object-tree traversing, comparing values and types if wanted to look for a GUI element like this.

 

Not the end of the world - will work with mouse coordinates, etc., for now.

 

And, in terms of #2, I was just asking for confirmation that obj.doAction() would just choose a form of default activity per element - as in focus on a text field, click on a button, etc, but, this is also less relevant if cannot figure out a way to get references to instances of the GUI elements.

 

In terms of #3 agree with you fully with regard to clipboard hijacking, so was thinking that typing one character at a time would be more suitable.

 

Let me sort of rephrase #4 - I presume there's no way to bind keystrokes to script blocks at runtime? As in, no way to manipulate the contents of __gestures at runtime? But, the original question related to being able to read forms of monitoring instructions in from the text file loading the queued command sets - as in, read an entry from that text file that instructed me to notify the user actively if some specific element fired an event, but, without having hard-coded the event binding in before-hand.

 

Let me, lastly, explain why I am working with this text file entries approach at the moment as well - the specific piece of software they're asking me to develop an add-on for is the goldmine CRM package, but, an older version, and, I have no experience with it, and, don't think it's general interface is in any case all that usable out-of-the-box from an accessibility perspective, so, the idea is to let the sighted training instructor work via my text file input mode, to compile interaction command sets, which I can then, later on, hard-code into the actual python code, etc., but anyway - they're not really experienced with NVDA at all, and, they'll be popping round tomorrow for me to explain all sorts of things to them... 😉

 

The one advantage is have been meaning to look into working on real NVDA add-on code for quite a while, and this is both an excuse as well as a launching platform from my perspective, since have been working with python code for quite a few years now, but, mainly using it to handle data transformation, command line utilities, etc., with only a little bit of actual wx GUI experience in the past.

 

Thanks for all your efforts


Jacob Kruger
+2782 413 4791
Skype: BlindZA
"...resistance is futile...but, acceptance is versatile..."

On 2021-01-13 04:21 PM, Travis Roth wrote:

Hi Jacob,

 

As for your questions:

  1. myObj = NVDAObjects.IAccessible.getNVDAObjectFromEvent(

        windowUtils.findDescendantWindow(api.getForegroundObject().windowHandle, controlID=xxx),

                winUser.OBJID_CLIENT, 0)

where xxx is the desired control id. (As posted by Jamie some years ago.)

 

  1. Sorry I don’t understand that question.
  2. I suspect this comes down a lot to your needs, purpose and preference. The one annoying thing about applications that use the clipboard is they overwrite things I already had on the clipboard, and if I don’t realize this is how they operate, poof there goes my last clipboard entry.
  3. I think you’re looking for chooseNVDAObjectOverlayClasses and then you’ll need to make a custom class that defines your event. See the addons developer guide, it explains a lot better than I ever could.

Travis

From: nvda-addons@nvda-addons.groups.io <nvda-addons@nvda-addons.groups.io> On Behalf Of Jacob Kruger
Sent: Wednesday, January 13, 2021 3:20 AM
To: NVDA-Addons <nvda-addons@nvda-addons.groups.io>
Subject: [nvda-addons] Next couple of questions relating to retrieving an object based on controlID, performing actions, typing in text automatically and event binding

 

Me, again - few different questions, and, will number them for reference.

 

1. Ok, firstly, if I have the controlID for a GUI element on record - presume these stay the same across sessions, most of the time - then, how would I retrieve an instance of an NVDA object based on this controlID?

 

As in, is this doable?

 

What I mean is, could I use the controlID value to retrieve an object similar to what gets retrieved by api.getNavigatorObject() an api.getFocusObject(), or is there some other preferred method for retrieving instances of specific objects?

 

2. Secondly, presume that depending on the type of element, the obj.doAction() function will do something like perform a mouse-click on a button/menu item, or open up a drop-down, and, obj.setFocus() would, obviously, do something like set focus to a text entry field?

 

3. If I want to automate forms of text entry, I can use something like api.copyToClip(), followed by emulating a ctrl+V keystroke, but, would it be better to rather do something like the following, for example, to type in a single character, almost as if the user was doing it themselves?

 

gesture = keyboardHandler.KeyboardInputGesture.fromName("a")

inputCore.manager.emulateGesture(gesture)

 

As in, the above two lines of code do seem to enter the letter a into a text field, but, if a menu had focus, would it then more or less perform the keypress of the letter a, to then possibly activate a sub-menu, or menu item bound to the letter a?

 

If I then used something like the above two lines of code to enter a single character, but, wanted to enter a whole string, would this then still be the best way to handle it, using a form of loop through the whole string to be entered, or should I then use a different method/means, or use the clipboard approach?

 

4. How simple is it to, at run time, bind an event to a specific element, again based on something like a controlID, or would this need to be included in code before-hand, and if so, what's the specific syntax for that?  As in, do I perform a check against controlID or name before then executing code, based on the event_ syntax - purely a sample here:

def event_gainFocus(self, obj, nextHandler):

  if obj.windowControlID=="1234567890":

    #do something here

 

Thanks for any feedback

Jacob Kruger
+2782 413 4791
Skype: BlindZA
"...resistance is futile...but, acceptance is versatile..."

Join nvda-addons@nvda-addons.groups.io to automatically receive all group messages.