Well, nothing much can go wrong with a call to addElement, provided:
a) You make the call on a class that _has_ the addElement method
b) You call it with something that is a valid IVisualElement
For b), you say that the call works when you use FlexGlobals.topLevelApplication.addElement(); so (although you haven't provided source) I can be confident that MyPrintView is a valid IVisualElement. So b) is not the problem. Calling FlexGlobals.topLevelApplication.addElement(); works because the application is an IVisualElementContainer and so has the addElement method defined.
Therefore, I conclude that you have defined this method on something other than the display class that you are printing.
You have either defined the method on a class that is not an IVisualElementContainer (for example, did you build this as an extension of Sprite, outside of Flex? or did you create a separate print manager class?) or created an anonymous function within the display class that cannot resolve "this" to the container.
Check where and what you have set your print job method up on. If you are using Flex, then it can just be a method of the containing s:Group or s:View or whatever. If it is a Sprite in a pure Flash app, then you can replace addElement with addChild instead.
Many thanks for your insights. What 'this' means is always something that seems to fool me. Because of my programming background I tend to split code from UI by putting code into a separate .as file that I then include, using <fx:Script source="xyz.as"/>, into the mxml file. So, my public function doPrint() is declared inside the .as file rather than inside an fx:Script block in the mxml file.
I understand that if I declared doPrint() in a script block in the mxml file then 'this' would refer to the containing s:window (in my case). But, moving the code out into the .as file, despite it being included back into the mxml file with <fs:Script source="xyz.as">, clearly leaves 'this' refering to something else, something else that isn't based on IVisualElementContainer.
So, using your insight, I simply created a new function, print2(), inside the mxml file (and that has no problem with addElement) then just called print2 from the original doPrint() function in the .as file, passing in the necessary data to output. No errors and no gray overlay!
Thank you for helping me to understand the issue better and thereby come up with a solution. Maybe I shouldn't be so keen to move code out of the mxml file.
Separating out logical code from display code is nothing to be ashamed of, but there are better ways of doing it... Remember, you are in an OOP environment, so you can organise things to share functionality across a wide range of things without getting tied up in global function hell.
For example, I could do this:
public class PGroupBase extends Group
I can then add custom properties to that class, or create subclasses of that class, or quite a lot of other things. I can implement interfaces and I can use static properties to provide global links between every instance and so on and so forth.
And, from a design perspective, in my display code, I still end up with the very simple and familiar:
<whatever:PGroupBase width="100%" height="100%"
That doesn't stop you from separating out purely abstract code into purely abstract classes - for example, I have a singleton pattern OrientationManager class that provides me with full control over stage rotation etc for anything that cares to use it in just a couple of lines - but it does mean that you can leverage the full might of Flex IVisualElement and IUIComponent power without tieing yourself up in knots.