Getting bitmap of a window

Ed Leafe wrote:

    I'm wondering if there is a way to capture the image of what a control would look like if it were visible. In other words, I'd like to create, say, a wx.Button, and then either move it to (-500, -500) or make it invisible with Show(False), so that it isn't available for the user to click on or to receive mouse events. But I'd like to then create a panel to serve as a proxy to the button, and somehow capture the image of what the button would look like if it were visible, and then use a DC to draw it on the panel. The user would interact with the panel, which is only used for design purposes, and which should never get focus or respond to clicks, etc.

    Am I being clear? And if so, is what I'm describing possible?

I've tried doing things like this and also other tricks but nothing works as slick as what I wanted.

* When the widget is not visible (hidden or moved to a nonvisible location) then blitting from a wxWindowDC only gives you a blank rectangle because the widget is not actually mapped to the display so there is nothing to Blit from.

* On Windows there is a (undocumented I think) trick that is supposed to cause a widget to paint itself to an arbitrary DC using the WM_PRINT message. I tried adding support of this to wxWidgets and although I could easily make it work well for non-native things like Panels or custom controls it only worked perfectly for about half of the native widgets and didn't do anything at all for some of the rest. When I later tried it on XP with comctl32 v6 (XP Themable controls) active then none of the native widgets worked better than just getting part of the widget copied. Although something like this is certainly possible on OSX and *might* be possible with GTK2, I gave up when I saw how bad it was on Windows.

I think that given the current state of things that the way to do it is like Roger suggested but taken one step further. Make a class that has two states: 1) it draws a bitmap of the real control on itself while the real control is hidden, and 2) shows the real control which completely covers this window. When you change properties of the widget in the design tool you can then change them on the real widget, show it, take a snapshot using a wxWindowDC --> wxBitmap, and then hide the real widget letting the bitmap show. If you're careful about when and the order that these things are done then you can probably do this without very much flicker.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

I understand why blitting doesn't work, but I wonder if there is a way to 'trick' the control into drawing itself. IOW, imagine it was located at (0,0) of the form, Visible was True, and no other control was in the way: the control would 'know' how to tell the OS to draw itself. Can't we fake that somehow? Can't we tap into the control somehow to extract this information?

      ___/
     /
    __/
   /
  ____/
  Ed Leafe
  http://leafe.com/
  http://dabodev.com/

···

On Jan 3, 2005, at 9:11 PM, Robin Dunn wrote:

* When the widget is not visible (hidden or moved to a nonvisible location) then blitting from a wxWindowDC only gives you a blank rectangle because the widget is not actually mapped to the display so there is nothing to Blit from.

Ed Leafe wrote:

···

On Jan 3, 2005, at 9:11 PM, Robin Dunn wrote:

* When the widget is not visible (hidden or moved to a nonvisible location) then blitting from a wxWindowDC only gives you a blank rectangle because the widget is not actually mapped to the display so there is nothing to Blit from.

    I understand why blitting doesn't work, but I wonder if there is a way to 'trick' the control into drawing itself. IOW, imagine it was located at (0,0) of the form, Visible was True, and no other control was in the way: the control would 'know' how to tell the OS to draw itself. Can't we fake that somehow? Can't we tap into the control somehow to extract this information?

That's what the WM_PRINT (or using the PrintWindow API on XP) trick on Windows was supposed to do. Even if a normal Paint event is forced the window creates it's own (inaccessible) DC to draw to and since it isn't visible everything will be clipped and nothing drawn.

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

OK, I understand. I was simply hoping it was possible, since it would make creating the Dabo Designer (our visual UI tool) a lot simpler.

      ___/
     /
    __/
   /
  ____/
  Ed Leafe
  http://leafe.com/
  http://dabodev.com/

···

On Jan 4, 2005, at 4:46 PM, Robin Dunn wrote:

That's what the WM_PRINT (or using the PrintWindow API on XP) trick on Windows was supposed to do. Even if a normal Paint event is forced the window creates it's own (inaccessible) DC to draw to and since it isn't visible everything will be clipped and nothing drawn.