How to print window contents?
How to print window contents?
It seems like this should be easy. (Hasn't this been asked before?)
How can I get the active window into an image so I can send it to the printer? It seems like I would read the Point(x,y) of the window and Plot(x,y) them to an image.. or maybe it is something entirely different.
There isn't any API here (on a Mac), so how do I do it with pb only?
How can I get the active window into an image so I can send it to the printer? It seems like I would read the Point(x,y) of the window and Plot(x,y) them to an image.. or maybe it is something entirely different.
There isn't any API here (on a Mac), so how do I do it with pb only?
MacBook Pro-M1 (2021), Sequoia 15.4, PB 6.20
Re: How to print window contents?
Here is some code that will copy a section of a window and put it into a image (which can be sent to the printer). All code was written by luis but I cannot find which thread he posted it in. I do not profess to understand how the code works... many thanks luis!
Code: Select all
;this code will copy a part of the Window (not screen) into an image
;all code written by luis in thread (http://www.purebasic.fr/english/viewtopic.php?f=12&t=38975&hilit=rotate+image )
procedure CopyImageToMemory(image_no.l,w,h, *mem)
Protected x.l, y.l, mem_pos.l ; Mac only
mem_pos = 0
StartDrawing(WindowOutput(image_no))
For y = 0 To h - 1
For x = 0 To w - 1
PokeL(*mem + mem_pos,(Point(x, y)))
mem_pos + 4
Next
Next
StopDrawing()
EndProcedure
Procedure CopyMemoryToImage(*mem,w,h, image_no.l)
Protected x.l, y.l, mem_pos.l
mem_pos = 0
If CreateImage(image_no,w,h)
StartDrawing(ImageOutput(image_no))
For y = 0 To ImageHeight(image_no) - 1
For x = 0 To ImageWidth(image_no) - 1
Plot(x, y, (PeekL(*mem + mem_pos)))
mem_pos + 4
Next
Next
StopDrawing()
Else
MessageRequester("Image not created","")
EndIf
EndProcedure
#wndw=1
#imageid=2
#gadgetid=3
w=200
h=200
If OpenWindow(#wndw,0,0,400,400, "2D Drawing Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If StartDrawing(WindowOutput(#wndw))
Box(150,20,20,20,RGB(0,255,0))
Circle(100,100,50,RGB(0,0,255)) ; filled circle
DrawingMode(#PB_2DDrawing_Outlined)
Circle(110,110,50,RGB(0,0,255)) ; empty cirle
For k=0 To 20
LineXY(10,10+k*8,200, 0,RGB(k*10,0,k*10))
Next
DrawingMode(#PB_2DDrawing_Transparent)
DrawText(10,50,"Hello, this is a test",$00FF00)
StopDrawing()
EndIf
mem_size = w * h << 2
*mem = AllocateMemory(mem_size)
If *mem = 0
MessageRequester("NO *mem","")
EndIf
CopyImageToMemory(#wndw,w,h, *mem)
CopyMemoryToImage(*mem,w,h,#imageid)
ImageGadget(#gadgetid, 0,200,w,h, ImageID(#imageid))
Repeat
EventID = WaitWindowEvent()
Until EventID = #PB_Event_CloseWindow
EndIf
End
MacBook Pro-M1 (2021), Sequoia 15.4, PB 6.20
Re: How to print window contents?
UH ? Maybe you got inspired in some way by that thread but honestly I don't think you have to thanks me, what you posted here it's not something "I" wrote, it's all yours.
Bye !
Bye !
"Have you tried turning it off and on again ?"
A little PureBasic review
A little PureBasic review
Re: How to print window contents?
There is GrabDrawingImage() in PB 4.40 

quidquid Latine dictum sit altum videtur
-
- Enthusiast
- Posts: 796
- Joined: Tue May 20, 2008 2:12 am
- Location: Cologne, Germany
- Contact:
Re: How to print window contents?
Great, I was going to post this... This Function copys the content of the current StartDrawing()-destination into an image using a memory buffer and Point()...freak wrote:There is GrabDrawingImage() in PB 4.40
freak, You could have saved me about one hour or so to figure this out...

Do I have to read the manual??? :roll:
Code: Select all
Procedure CopyScreenToImage(Breite, Hoehe, Image_No) ; working on Mac OS X - yeah!
Protected x.l, y.l, mem_pos.l, *Cache
*Cache = AllocateMemory(Breite * Hoehe * 4)
Mem_Pos = 0
For y = 0 To Hoehe - 1
For x = 0 To Breite - 1
PokeL(*Cache + Mem_Pos, Point(x,y))
Mem_Pos + 4
Next x
Next y
StopDrawing()
CreateImage(Image_No, Breite, Hoehe, 32)
StartDrawing(ImageOutput(Image_No))
Mem_Pos = 0
For y = 0 To Hoehe - 1
For x = 0 To Breite - 1
Plot(x, y, PeekL(*Cache + Mem_Pos));Point(x,y))
Mem_Pos + 4
Next x
Next y
StopDrawing()
FreeMemory(*Cache)
EndProcedure
Regards,
JamiroKwai
JamiroKwai
Re: How to print window contents?
Yep, I knew just as soon as I posted the code someone would have a much better solution.- Added: GrabDrawingImage(), DrawRotatedText()
I don't see GrabDrawingImage() in the manual so how about some info? Would it be GrabDrawingImage(WindowOutput(#wndid),w,h) or what?
@Freak - you should have let me enjoy the effort for a few minutes.. at least.

@jamirokwai » Thanks for the effort. I appreciate it. Maybe I can repay you by getting an explanation of how the command works.
MacBook Pro-M1 (2021), Sequoia 15.4, PB 6.20
Re: How to print window contents?
http://www.purebasic.com/documentation/ ... image.htmlWilliamL wrote: I don't see GrabDrawingImage() in the manual so how about some info?
It's in the helpfile too, at least in the 4.41 RC1.
"Have you tried turning it off and on again ?"
A little PureBasic review
A little PureBasic review
Re: How to print window contents?
Thanks again luis,
I see it with your link. I'm really glad to have this info so I can 'get on with it'.. what a time saver.
I see it with your link. I'm really glad to have this info so I can 'get on with it'.. what a time saver.
Code: Select all
#wndw=1
#imageid=2
#gadgetid=3
w=200
h=200
If OpenWindow(#wndw,0,0,400,400, "2D Drawing Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If StartDrawing(WindowOutput(#wndw))
Box(150,20,20,20,RGB(0,255,0))
Circle(100,100,50,RGB(0,0,255)) ; filled circle
DrawingMode(#PB_2DDrawing_Outlined)
Circle(110,110,50,RGB(0,0,255)) ; empty cirle
For k=0 To 20
LineXY(10,10+k*8,200, 0,RGB(k*10,0,k*10))
Next
DrawingMode(#PB_2DDrawing_Transparent)
DrawText(10,50,"Hello, this is a test",$00FF00)
GrabDrawingImage(#imageid,0,0,w,h)
StopDrawing()
EndIf
ImageGadget(#gadgetid, 0,200,w,h, ImageID(#imageid))
Repeat
EventID = WaitWindowEvent()
Until EventID = #PB_Event_CloseWindow
EndIf
End
Last edited by WilliamL on Thu Jan 21, 2010 1:38 am, edited 2 times in total.
MacBook Pro-M1 (2021), Sequoia 15.4, PB 6.20
Re: How to print window contents?
Here is a stab at printing the window. This does not work and I get a black box in the print-out. (I use Preview in the Print dialoge to save paper) Any ideas why?
Code: Select all
>>>>. see the example below, by luis, that works!
[code]#wndw=1
#gadget1=2
Procedure PrintWindow(wndid.l)
Define imageid.l
w=WindowWidth(wndid)
h=WindowHeight(wndid)
If CreateImage(imageid,w,h)
If StartDrawing(WindowOutput(wndid))
GrabDrawingImage(ImageOutput(imageid),0,0,w,h)
StopDrawing()
EndIf
EndIf
If PrintRequester()
If StartPrinting("Print window")
If StartDrawing(PrinterOutput())
DrawImage(ImageID(imageid),0,0,w,h)
StopDrawing()
EndIf
StopPrinting()
EndIf
EndIf
EndProcedure
w=200
h=200
If OpenWindow(#wndw,0,0,w,h+64, "2D Drawing Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If StartDrawing(WindowOutput(#wndw))
Box(150,20,20,20,RGB(0,255,0))
Circle(100,100,50,RGB(0,0,255)) ; filled circle
DrawingMode(#PB_2DDrawing_Outlined)
Circle(110,110,50,RGB(0,0,255)) ; empty cirle
For k=0 To 20
LineXY(10,10+k*8,200, 0,RGB(k*10,0,k*10))
Next
DrawingMode(#PB_2DDrawing_Transparent)
DrawText(10,50,"Hello, this is a test",$00FF00)
StopDrawing()
EndIf
ListViewGadget(#gadget1,4,210,w-8,50)
AddGadgetItem(#gadget1,-1,"Line 1")
PrintWindow(#wndw)
Repeat
EventID = WaitWindowEvent()
Until EventID = #PB_Event_CloseWindow
EndIf
End
Last edited by WilliamL on Wed Jan 20, 2010 11:49 pm, edited 6 times in total.
MacBook Pro-M1 (2021), Sequoia 15.4, PB 6.20
Re: How to print window contents?
I'm not sure what you are trying to accomplish, if to get an hard-copy of the window (with buttons, gui elements, etc.) or to print the content of graphic area (a bitmap on the window)
Anyway, for the example you posted probably it's better to use an image and draw to that...
This *should* work... oh , maybe you have to fill the image white before drawing to it, I cannot test it right now.
Anyway, for the example you posted probably it's better to use an image and draw to that...
Code: Select all
#wndw=1
#img=1
Procedure PrintWindow(nImage)
; Define imageid.l
;
; w=WindowWidth(wndid)
; h=WindowHeight(wndid)
; If CreateImage(imageid,w,h)
; If StartDrawing(ImageOutput(imageid))
; GrabDrawingImage(WindowOutput(wndid),0,0,w,h)
; StopDrawing()
; EndIf
; Else
;
; EndIf
If PrintRequester()
If StartPrinting("Print window")
If StartDrawing(PrinterOutput())
DrawImage(ImageID(nImage),ImageWidth(nImage),ImageHeight(nImage))
StopDrawing()
EndIf
StopPrinting()
EndIf
EndIf
EndProcedure
w=200
h=200
If OpenWindow(#wndw,0,0,w,h, "2D Drawing Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
nImage = CreateImage(#PB_Any, w,h)
ImageGadget(#img, 0,0,w,h,ImageID(nImage))
If StartDrawing(ImageOutput(nImage))
Box(150,20,20,20,RGB(0,255,0))
Circle(100,100,50,RGB(0,0,255)) ; filled circle
DrawingMode(#PB_2DDrawing_Outlined)
Circle(110,110,50,RGB(0,0,255)) ; empty cirle
For k=0 To 20
LineXY(10,10+k*8,200, 0,RGB(k*10,0,k*10))
Next
DrawingMode(#PB_2DDrawing_Transparent)
DrawText(10,50,"Hello, this is a test",$00FF00)
StopDrawing()
EndIf
PrintWindow(nImage)
Repeat
EventID = WaitWindowEvent()
Until EventID = #PB_Event_CloseWindow
EndIf
End
"Have you tried turning it off and on again ?"
A little PureBasic review
A little PureBasic review
Re: How to print window contents?
luis,
Yes, that does work and I've used it before. I'm trying to get all the graphics and gadgets in the window to print (actually I'm more interested in gadgets at this point). I edited my code above.
Yes, that does work and I've used it before. I'm trying to get all the graphics and gadgets in the window to print (actually I'm more interested in gadgets at this point). I edited my code above.
Last edited by WilliamL on Thu Jan 21, 2010 12:00 am, edited 3 times in total.
MacBook Pro-M1 (2021), Sequoia 15.4, PB 6.20
Re: How to print window contents?
You are using GrabDrawingImage() the wrong way I believe. I never used before but I seee in the help the first param is an image number or #PB_Any, check your code 
I imagine it works grabbing the area from the currently "open" output, you don't have to pass it as a param !

I imagine it works grabbing the area from the currently "open" output, you don't have to pass it as a param !
"Have you tried turning it off and on again ?"
A little PureBasic review
A little PureBasic review
Re: How to print window contents?
Code: Select all
#wndw=1
#gadget1=1
#gadget2=2
Procedure PrintWindow(wndid.l)
Define imageid.l
w=WindowWidth(wndid)
h=WindowHeight(wndid)
If CreateImage(imageid,w,h)
If StartDrawing(WindowOutput(wndid))
imageid = GrabDrawingImage(#PB_Any,0,0,w,h)
StopDrawing()
EndIf
EndIf
If PrintRequester()
If StartPrinting("Print window")
If StartDrawing(PrinterOutput())
DrawImage(ImageID(imageid),w,h)
StopDrawing()
EndIf
StopPrinting()
EndIf
EndIf
EndProcedure
w=200
h=200
If OpenWindow(#wndw,0,0,w,h+64, "tes", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(#gadget2, 10, 10, 100, 30, "print")
ListViewGadget(#gadget1,4,210,w-8,50)
AddGadgetItem(#gadget1,-1,"Line 1")
Repeat
EventID = WaitWindowEvent()
If EventID = #PB_Event_Gadget
If EventGadget() = #gadget2
PrintWindow(#wndw)
EndIf
EndIf
Until EventID = #PB_Event_CloseWindow
EndIf
End
"Have you tried turning it off and on again ?"
A little PureBasic review
A little PureBasic review
Re: How to print window contents?
Your code was using the GrabDrawingImage() in the wrong way, see the code above.
Another problem was the fact you have to give time to the window to process the events to paint itself, you shouldn't try to print it while constructing it (adding the pieces).
Another problem was the fact you have to give time to the window to process the events to paint itself, you shouldn't try to print it while constructing it (adding the pieces).
"Have you tried turning it off and on again ?"
A little PureBasic review
A little PureBasic review
Re: How to print window contents?
luis,
Yes, that works! I'm studying your code to understand the event problem. I would normally use the print routine with a button anyway and my example was for brevity.
Thanks again and again for your help, I was about to give up.
Yes, that works! I'm studying your code to understand the event problem. I would normally use the print routine with a button anyway and my example was for brevity.
Thanks again and again for your help, I was about to give up.

Last edited by WilliamL on Wed Jan 20, 2010 11:38 pm, edited 1 time in total.
MacBook Pro-M1 (2021), Sequoia 15.4, PB 6.20