[nvda-addons] Re: Developing Addons - The best way to get started?

  • From: James Scholes <james@xxxxxxxxxxxxx>
  • To: nvda-addons@xxxxxxxxxxxxx
  • Date: Fri, 15 Apr 2016 20:05:12 +0100

Plenty of replies inline.

Damien Sykes-Pendleton wrote:

1. When you say "accessing various objects in code," which objects do
you mean?

I mean accessing the object tree hierarchically programatically, the
same way object navigation allows you to do in NVDA itself. To be honest
I thought there may have been some helper functions that allow you to
find controls based on certain information, rather than having to try
and find the object manually. Especially given that it could be in
different places depending on the information that the summary shows.

There are some helper functions which can help with this.  For example,
in the api module, you'll find functions to obtain the current focus,
foreground, mouse and desktop objects, as well as a few others which
I'll leave it up to you to investigate.  If you don't have a copy of the
NVDA source code, you can open the NVDA Python console and use:

import api
dir(api)

This will show a list (or array if you like) of objects defined in the
api module.  Most, if not all, should be functions.  You can request the
help information, if any,  associated with a function by typing:

help(function_name)

For example:

help(api.getDesktopObject)

Personally, I find it easier to just read the source code of
source\api.py.  You don't need to understand the code inside the body of
the functions, but you can read the names and docstrings.

There are also functions like windowUtils.findDescendantWindow, which
will let you find a control given a parent to start from.  It takes the
following arguments:

parent (int): The handle (HWND) of the parent window to search within.
This can be obtained using something like:
api.getForegroundObject().windowHandle
But you'll need to experiment to make sure that you're passing a handle
to an appropriate window.  While focussed in the list box of your
application, open the NVDA Python console with NVDA+Ctrl+Z (not the menu
option) and type:
fg.name
It should return the name of your application's window.
fg.windowHandle will contain the HWND of that window.

visible (bool): Whether the window should be visible, should probably be
set to True.

controlID (int): The control ID of the control you want to find.  This
can be obtained from the log viewer.
className (str): The class name of the control you want to find, see above.

The function will either return the HWND of the located control, or
raise a LookupError if no control can be found.  Once you have the HWND,
you can retrieve the associated NVDA object with:

obj = getNVDAObjectFromEvent(hwnd, winUser.OBJID_CLIENT, 0)

2. Do you understand how event handlers work, and the fact that they
receive the object on which the event was fired as an argument?

I wasn't sure about that, but now you mention it, it makes sense. I'm
guessing that's why you have to check various things about the object,
because it could be anything that has triggered the event. Is that why
it beeped pretty much on every control change when I did the example
gain focus event in the dev guide?

Exactly.  You must filter for the subset of controls you're interestted
in inside your event handler.

3. Do you understand that, from within an event handler function, you
can find other objects using the object delivered to your function as a
starting point?

You wrote that as part of the same question, but to me that is something
totally different. I didn't know that at all. How can one object let you
access all others?

Because object navigation is recursive.  Every object, apart from the
desktop object, has a parent.  And every object has the possibility to
have siblings or children.

If you use object nav to keep going up and up and up, you will
eventually reach the desktop.  If you're focussed in a text field inside
Notepad, you can use object nav to read a web page in Firefox, without
the focus on screen changing at all and without switching windows.  All
objects belong to the same tree, with desktop as the top-level parent,
or the root node, of that tree.  Try it out.

4. Do you understand what methods and attributes objects have to help you
find other objects around them, e.g. simpleNext, simplePrevious,
children, etc?

I'm guessing that's what my biggest problem is. I know nothing about these.

See section 3.7 of the developer guide for more information about an
object's various properties.

5. Have you tried using the NVDA Python console to navigate around an
application you're familiar with to get a feel for how all of this works?

No, because again I wouldn't know what to put in there. What I did do is
try to get the focus information in the console, but it didn't show me
any of the variables it had created for me. Even if it had, I'd have no
idea how to make something actually happen as I know nothing of the NVDA
source code, all I know how to do is make it beep.

For an accurate snapshot to be taken, I believe you have to activate the
console using the keystroke NVDA+Ctrl+Z, rather than opening it from the
menu.

6. Have you ran the Python built-in function dir on an object to see
what properties and methods it exposes?  Object introspection at runtime
is one of Python's biggest bonuses, and you're probably going to need it.

No, because again I knew nothing of the existence of this function.

You do now.

7. Have you downloaded the code of some other app modules contributed by
the community to see if you can figure out how they work?

I wouldn't even know what to start looking at, as most of them are a lot
more complex than what I am trying to do. I do use several addons
(GoldWave, NVDA Remote, System Tray list etc) but to me they just sound
way, way too advanced for me to start looking at their code at the moment.

This very well might be the case, but it's certainly an exercise you
should try.  Everything I've written in this email has come from
learning Python, reading the NVDA developer guide, and reading the
source code of other add-ons.  If there are tons of concepts you don't
understand, perhaps add them to a list for investigation.

8. Some of the app modules that ship with NVDA itself, if you check out
the source code, are not overly complicated.

A lot of the apps NVDA supports (such as Microsoft Office) I don't
actually have, so I can't compare the code to what it might be trying to
do with the object.

Maybe not, but there are app modules for a lot of freely available apps
that you could install.  And the same point as above stands.  Keep in
mind that NVDA core's app modules were, for the most part, written by
the core NVDA developers themselves, so they are a good source of high
quality code, and a good place to find out how to do things the right way.
-- 
James Scholes
http://twitter.com/JamesScholes
----------------------------------------------------------------
NVDA add-ons: A list to discuss add-on code enhancements and for reporting 
bugs. 

Community addons are available from: http://addons.nvda-project.org
To send a message to the list: nvda-addons@xxxxxxxxxxxxx
To change your list settings/unsubscribe: 
//www.freelists.org/list/nvda-addons
To contact list moderators: nvda-addons-moderators@xxxxxxxxxxxxx

Other related posts: