[Solved] Capture window as an image
Posted: Thu Jun 01, 2017 8:18 am
Is there a way for a running program to take a graphic snapshot of one of its windows and all objects on it as an image?
http://www.purebasic.com
https://www.purebasic.fr/english/
Code: Select all
OpenWindow(0, 0, 0, 640, 480, "Test", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
ButtonGadget(1, 20, 20, 100, 20, "Go")
ImageGadget(2, 20, 50, 640, 480, 0)
AddKeyboardShortcut(0, #PB_Shortcut_1, 2)
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_CloseWindow
Quit = #True
Case #PB_Event_Menu
Select EventMenu()
Case 2
If StartDrawing(WindowOutput(0))
GrabDrawingImage(1, 0, 0, OutputWidth(), OutputHeight())
StopDrawing()
SetGadgetState(2, ImageID(1))
EndIf
EndSelect
EndSelect
Until QuitCode: Select all
Procedure PrintMyStuffNow()
Protected Handle
Protected hDC
Protected RECT.RECT
Protected hPrinterDC
Handle = GetForegroundWindow_()
hDC = GetWindowDC_(Handle)
GetWindowRect_(Handle, @RECT.RECT)
With RECT
\right - \left
\bottom - \top
ImageHandle.i = CreateImage(#PB_Any, \right, \bottom)
hPrinterDC = StartDrawing(ImageOutput(ImageHandle.i))
If hPrinterDC
BitBlt_(hPrinterDC, 0, 0, \right, \bottom, hDC, 0, 0, #SRCCOPY)
StopDrawing()
EndIf
;EndWith
ReleaseDC_(Handle, hDC)
If PrintRequester()
If StartPrinting("Print window")
If StartDrawing(PrinterOutput())
DrawImage(ImageID(ImageHandle.i), \right, \bottom)
StopDrawing()
EndIf
StopPrinting()
EndIf
EndIf
EndWith
;SetClipboardImage(ImageHandle.i)
EndProcedure
Code: Select all
Width = OutputWidth()
Height = OutputHeight()
ResizeImage(ImageHandle, Width, Height)Code: Select all
DrawImage(ImageID, x, y [, Width, Height])
Code: Select all
If StartVectorDrawing(PrinterOutput(#PB_Unit_Millimeter)
MovePathCursor(x.d, y.d [, Flags])
DrawVectorImage(ImageID [, Alpha [, Width.d, Height.d]])
StopDrawing()
EndIf
Code: Select all
If PrintRequester()
If StartPrinting("Print window")
Factor.f = PrinterPageWidth() / ImageWidth(ImageHandle)
If StartVectorDrawing(PrinterVectorOutput(#PB_Unit_Pixel))
MovePathCursor(0, 0)
DrawVectorImage(ImageID(ImageHandle), 255, ImageWidth(ImageHandle)*Factor, ImageHeight(ImageHandle)*Factor)
StopVectorDrawing()
EndIf
StopPrinting()
EndIf
EndIf"The requested page could not be found".idle wrote:Have you tried PrintWindow_ ?
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
Code: Select all
Protected Handle
Protected hDC
Protected RECT.RECT
Protected hPrinterDC
Handle = GetForegroundWindow_()
hDC = GetWindowDC_(Handle)
GetWindowRect_(Handle, @RECT.RECT)
With RECT
\right - \left
\bottom - \top
ImageHandle.i = CreateImage(#PB_Any, \right, \bottom)
hPrinterDC = StartDrawing(ImageOutput(ImageHandle.i))
\If hPrinterDC
BitBlt_(hPrinterDC, 0, 0, \right, \bottom, hDC, 0, 0, #SRCCOPY)
StopDrawing()
EndIf
ReleaseDC_(Handle, hDC)
If PrintRequester()
If StartPrinting("MyStuff Record Print")
Factor.f = PrinterPageWidth() / ImageWidth(ImageHandle)
If StartVectorDrawing(PrinterVectorOutput(#PB_Unit_Pixel))
MovePathCursor(0, 0)
DrawVectorImage(ImageID(ImageHandle), 255, ImageWidth(ImageHandle) * Factor, ImageHeight(ImageHandle) * Factor)
StopVectorDrawing()
EndIf
StopPrinting()
EndIf
EndIf
EndWith
Code: Select all
Prototype.i ptPrintWindow(hWnd, hdc, flags)
OpenLibrary(0, "User32.dll")
PrintWindow.ptPrintWindow = GetFunction(0, "PrintWindow")
ID = RunProgram("Notepad.exe","","",#PB_Program_Open)
Delay(100)
Repeat
hWnd = FindWindow_(0,"Untitled - Notepad")
Until hWnd
SetWindowLongPtr_(hWnd, #GWL_STYLE, GetWindowLongPtr_(hWnd, #GWL_STYLE) | #WS_CLIPSIBLINGS)
SetWindowPos_(hWnd, #HWND_BOTTOM, -1, -1, -1, -1, #SWP_NOSIZE | #SWP_NOMOVE)
GetWindowRect_(hWnd,r.RECT)
ww = r\right-r\left
wh = r\bottom-r\top
If CreateImage(1, ww,wh, 24)
hdc = StartDrawing(ImageOutput(1))
If hdc
PrintWindow(hWnd, hdc,0)
StopDrawing()
EndIf
EndIf
SaveImage(1,GetHomeDirectory()+"Test.bmp")
KillProgram(ID)
CloseLibrary(0)
Code: Select all
Procedure PrintThisStuffFromRecord()
;
HideGadget(#Gadget_Datasheet_cControl, #True)
ResizeWindow(#Window_Datasheet, #PB_Ignore, #PB_Ignore, 1000, 645)
; Test function from RASHAD to print window image without side bars from wallpaper
OpenLibrary(0, "User32.dll") ;
PrintWindow.ptPrintWindow = GetFunction(0, "PrintWindow") ;
WindowHandle.i = WindowID(#Window_Datasheet)
SetWindowLongPtr_(WindowHandle.i, #GWL_STYLE, GetWindowLongPtr_(WindowHandle.i, #GWL_STYLE) | #WS_CLIPSIBLINGS)
SetWindowPos_(WindowHandle.i, #HWND_BOTTOM, -1, -1, -1, -1, #SWP_NOSIZE | #SWP_NOMOVE)
GetWindowRect_(WindowHandle.i, r.RECT)
WindowsWidth.i = r\right - r\left
WindowsHeight.i = r\bottom - r\top
PrintableImage.i = CreateImage(#PB_Any, WindowsWidth.i, WindowsHeight.i, 24)
If PrintableImage.i
DeviceContextHandle.i = StartDrawing(ImageOutput(PrintableImage.i))
If DeviceContextHandle.i
PrintWindow(WindowHandle.i, DeviceContextHandle.i, 0)
StopDrawing()
EndIf
;SaveImage(PrintableImage.i,"D:\Test.jpg", #PB_ImagePlugin_PNG)
If PrintRequester()
If StartPrinting("MyStuff Record Print")
Factor.f = PrinterPageWidth() / ImageWidth(PrintableImage.i)
If StartVectorDrawing(PrinterVectorOutput(#PB_Unit_Pixel))
MovePathCursor(0, 0)
DrawVectorImage(ImageID(PrintableImage.i), 255, ImageWidth(PrintableImage.i) * Factor, ImageHeight(PrintableImage.i) * Factor)
StopVectorDrawing()
Else
; Could not print to the requested output
EndIf
StopPrinting()
Else
; Vector printer failed to start
EndIf
Else
; Print requester failed
EndIf
Else
; No image generated, could not print
EndIf
;
CloseLibrary(0)
;
HideGadget(#Gadget_Datasheet_cControl, #False)
ResizeWindow(#Window_Datasheet, #PB_Ignore, #PB_Ignore, 1000, 750)
;
EndProcedure