Page 1 of 1

Curious PrintWindow_() behaviour!

Posted: Mon Mar 22, 2010 8:07 pm
by srod
Has anyone any experience with the PrintWindow_() api function?

I ask because, well, take the following for example. Run it and PrintWindow_() is used to make an image of one window which it places within the centered window. No problems. However, uncomment the commented ButtonGadget() line and, on my system, the PanelGadget no longer gets added to the image!

Code: Select all

Prototype.i ptPrintWindow(hWnd, hdc, flags)

OpenLibrary(1, "User32.dll")
PrintWindow.ptPrintWindow = GetFunction(1, "PrintWindow")

If OpenWindow(0, 0, 0, 400, 400, "ButtonGadgets", #PB_Window_SystemMenu|#PB_Window_SizeGadget)
;  ButtonGadget(0, 10, 10, 80, 20, "CLICK!")  ;Uncomment and PrintWindow_() does not work as expected!
  PanelGadget(1, 0, 40, 320, 200)
    AddGadgetItem (1, -1, "Panel 1")
      PanelGadget (2, 5, 5, 290, 166)
        AddGadgetItem(2, -1, "Sub-Panel 1")
        AddGadgetItem(2, -1, "Sub-Panel 2")
        AddGadgetItem(2, -1, "Sub-Panel 3")
      CloseGadgetList()
    AddGadgetItem (1, -1,"Panel 2")
      ButtonGadget(3, 10, 15, 80, 24,"Button 1")
      ButtonGadget(4, 95, 15, 80, 24,"Button 2")
    CloseGadgetList()
SetGadgetState(1, 1)
  
OpenWindow(1, 0, 0, 600, 600, "PrintWindow_()", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  GetWindowRect_(WindowID(0), rcWin.RECT)
  width = rcWin\right-rcWin\left
  height = rcWin\bottom-rcWin\top

  SetActiveWindow(0)
  If CreateImage(1, width, height, 24)
    hdc = StartDrawing(ImageOutput(1))
    If hdc
      Box(0, 0, width, height, #White)
      PrintWindow(WindowID(0), hdc, 0)
      StopDrawing()
    EndIf
  EndIf

  ScrollAreaGadget(20, 10, 10, 600, 600, width, height, 20, #PB_ScrollArea_BorderLess)
    ImageGadget(10, 0, 0, width, height, ImageID(1))
  CloseGadgetList()

  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Just wondering if anyone has come across this kind of thing before, and if so, can advise on a likely workaround? :)

Thanks.

Re: Curious PrintWindow_() behaviour!

Posted: Mon Mar 22, 2010 8:27 pm
by Arctic Fox
I cannot explain the PrintWindow_() behaviour, but I think #WM_PRINT may be a workaround.

This example by netmaestro seems to work
http://www.purebasic.fr/english/viewtop ... 97#p200497

Add #PRF_NONCLIENT to the lParam flags.

Code: Select all

SendMessage_(WindowID(0), #WM_PRINT, hdc, #PRF_CLIENT | #PRF_NONCLIENT | #PRF_CHILDREN | #PRF_ERASEBKGND | #PRF_CHECKVISIBLE)

Re: Curious PrintWindow_() behaviour!

Posted: Mon Mar 22, 2010 8:36 pm
by srod
Thanks for the reply, but #WM_PRINT is too unreliable for my needs. For example, try it with a themed editor gadget! :wink:

Re: Curious PrintWindow_() behaviour!

Posted: Mon Mar 22, 2010 8:49 pm
by Arctic Fox
Oh, I see :(

Re: Curious PrintWindow_() behaviour!

Posted: Mon Mar 22, 2010 10:19 pm
by Marco2007
Workaround? Using a ContainerGadget works here:

Code: Select all

Prototype.i ptPrintWindow(hWnd, hdc, flags)

OpenLibrary(1, "User32.dll")
PrintWindow.ptPrintWindow = GetFunction(1, "PrintWindow")

If OpenWindow(0, 0, 0, 400, 400, "ButtonGadgets", #PB_Window_SystemMenu|#PB_Window_SizeGadget)
  ButtonGadget(0, 10, 10, 80, 20, "CLICK!")  ;Uncomment and PrintWindow_() does not work as expected!
  ContainerGadget(90, 40, 30, 400, 400)
  PanelGadget(1, 0, 40, 320, 200)
    AddGadgetItem (1, -1, "Panel 1")
      PanelGadget (2, 5, 5, 290, 166)
        AddGadgetItem(2, -1, "Sub-Panel 1")
        AddGadgetItem(2, -1, "Sub-Panel 2")
        AddGadgetItem(2, -1, "Sub-Panel 3")
      CloseGadgetList()
    AddGadgetItem (1, -1,"Panel 2")
      ButtonGadget(3, 10, 15, 80, 24,"Button 1")
      ButtonGadget(4, 95, 15, 80, 24,"Button 2")
    CloseGadgetList()
  SetGadgetState(1, 1)
  CloseGadgetList()


OpenWindow(1, 550, 0, 600, 600, "PrintWindow_()")
  GetWindowRect_(WindowID(0), rcWin.RECT)
  width = rcWin\right-rcWin\left
  height = rcWin\bottom-rcWin\top

  SetActiveWindow(0)
  SetGadgetText(0, "CLICK!")
  If CreateImage(1, width, height, 24)
    hdc = StartDrawing(ImageOutput(1))
    If hdc
      Box(0, 0, width, height, #Green)
      PrintWindow(WindowID(0), hdc, 0)
      StopDrawing()
    EndIf
  EndIf

  ScrollAreaGadget(20, 10, 10, 600, 600, width, height, 20, #PB_ScrollArea_BorderLess)
    ImageGadget(10, 0, 0, width, height, ImageID(1))
  CloseGadgetList()

  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Does this work for you?

I also have to use SetGadgetText(0, "CLICK!") after SetActiveWindow(0) to make the ButtonGadget visible in the first window...strange...

Re: Curious PrintWindow_() behaviour!

Posted: Mon Mar 22, 2010 10:42 pm
by RASHAD
@srod
I think the problem is with PureBasic PanelGadget
If you created the Panel Gadet with API everything goes OK

Re: Curious PrintWindow_() behaviour!

Posted: Tue Mar 23, 2010 12:10 am
by srod
@Marco, that is interesting. I was going to try that, but got side-tracked! :) I think I am beginning to see what is going on. No SetGadgetText() is needed here on Vista unless I add a second button.

**EDIT : yep tried with panels in panels in panels.... providing you use a container for each panel gadget and invalidate the window being copied immediately prior to using PrintWindow_(), it all seems to work fine on XP and Vista. That should be enough for my needs. Thanks Marco.

@Rashad, yes that is probably because an API tab control doesn't come with the themed 'inner containers' which PB adds.

Re: Curious PrintWindow_() behaviour!

Posted: Tue Mar 23, 2010 12:24 am
by Demivec
Marco2007 wrote:I also have to use SetGadgetText(0, "CLICK!") after SetActiveWindow(0) to make the ButtonGadget visible in the first window...strange...
To get the ButtonGadget to appear I just do an event loop to clear the events before using SetActiveWindow(0).