The main point is, I may have more than one concrete implementation of the abstract factory/product set. So, let's say I have:
This post you made (first half) nails the whole idea between abstract factory correctly. Abstract factory is specifically for this exact special case, where there are multiple sets of classes that work with each other, and only each other, but other families of classes that have the same pattern. Such as if you had the touch / keyboard interface you describe, or my standard answer, the OpenGL and DirectX widget implementations. Obviously for these types of situations the OUTSIDE user wants to use JUST the interfaces (in other words the GAME doesn't care about OpenGL vs DirectX, so it uses the IControl, and IWindows interfaces EXCLUSIVELY). However of course, as you are aware the classes themselves, internally, DO care. An OpenGL control only consumes OpenGL textures and draws in OpenGL windows. So the key here is that the INTERNAL logic is more complex than the EXTERNAL logic.
Understand that Abstract Factory isn't telling you about how to make the OpenGL family talk to each other, its telling you how to make it so the outside world instantiates a factory once (and only once) and uses that ONE factory to create all of its widgets, so that it can be completely ignorant of what type of widget they are. Kinda like saying, as long as you are in a Verizon store, any phones you buy will work on the Verizon network. So once you decided which store to walk into, you can remain ignorant of the compatibility issue.
So, will you need down-casts for this case ... probably (although there are some techniques and languages that do not require it). However realize that your example of such a need is very flawed.
An OpenGL window should not be running around casting OpenGL controls to a long list of all possible children types, that is just madness. That is an unmanageable, unextendable non-oo design. However each OpenGL control can and likely will cast the IWindow to an IOpenGL window (fully expecting it to be one, since the whole assumption is the creation of everything from exactly 1 factory instance, so that a mismatch would be impossible. Also, an OpenGL window would keep a list of IOpenGL controls, and cast each control on add from IControl to IOpenGL control ... because the open gl family is going to be implemented internally to receive, associate with and use only other open gl family controls. The base interfaces are just used as the lesser API for externally facing interfaces.
So seeing the logical equivalent of:
is totally normal for this type pattern.
would NOT be normal. The difference? In the first case you are downcasting from some interface, to its FAMILY SPECIFIC SPECIALIZATION (of which there can only be 1), which has the exact same PURPOSE within the family as the base interface, but just adds necessary family specific details to allow proper operation. In the second case you are trying to downcast from some general interface to another interface, which has a more specialized purpose - of what use is a window having a list of control, if the window has to know what type they are to use them ... this is the opposite of polymorphic
Another example - if would be like - instead of letting a class (Teacher) walk through a list of children (Students) asking them to perform the same operation (AreYouReadyForTheFeildTrip?) - which each student determine using different methods. Your flawed example would be like the teacher deciding what to ask the student based on first identifying who they are (Tommy or Jane?) and then if Tommy, doing the Tommy specific code, and if Jane doing the Jane specific code. When the whole point of polymorphic is to let Tommy, Jane and Ivan's creator (programmer / parents) make each one unique as they should be - but their Teacher no longer has to understand these differences to interact with them.