capturing windows with WM_PRINT

BlitzMax Forums/BlitzMax Beginners Area/capturing windows with WM_PRINT

I tried using the WM_PRINT method, but couldnt get it to work :(

You could try this instead, it needs the window to be visible on screen though so it may not be what you want...
SuperStrict

Import PUB.Win32

Extern "Win32"
	Function ReleaseDC:Int( hwnd:Int, dc:Int)
	Function GetDIBits:Int( dc:Int, bm:Int, x:Int,y:Int, src:Byte Ptr, bmi:Byte Ptr, flags:Int)
	Function FindWindowA:Int( classname$z, windowtitle$z)
	Function BitBlt:Int( destdc:Int, destx:Int,desty:Int, width:Int,height:Int, srcdc:Int, srcx:Int,srcy:Int, rop:Int)
EndExtern

Local hwnd:Int = FindWindowA( Null, "Calculator")
If hwnd Then
	Local pix:TPixmap = GrabWindowPixmap( hwnd)
	If pix Then
		Print "saving png..."
		SavePixmapPNG pix, "c:\test.png"
	Else
		Print "could not capture window"
	EndIf
Else
	Print "could not find window"
EndIf

Function GrabWindowPixmap:TPixmap( hwnd:Int)
	If hwnd = 0 Then Return Null
	
	' need to show the window to capture it
	SetWindowPos( hwnd, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE)
	SetWindowPos( hwnd, HWND_NOTOPMOST, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE)
	ShowWindow( hwnd, SW_SHOW)	
	Delay 50
	
	' get window size
	Local rect:Int[4]
	GetClientRect( hwnd, rect)
	Local w:Int = rect[2] - rect[0]
	Local h:Int = rect[3] - rect[1]	
	
	Local srcdc:Int = GetDC(hwnd)
	Local memdc:Int = CreateCompatibleDC(srcdc)
	Local bmp:Int = CreateCompatibleBitmap( srcdc, w,h)
	Local oldbmp:Int = SelectObject( memdc, bmp)
	
	BitBlt( memdc, 0,0,w,h, srcdc,0,0, ROP_SRCCOPY)
	
	Local pixmap:TPixmap, bits:Int = GetDeviceCaps( srcdc, BITSPIXEL)
	Select bits
		Case 24	pixmap = CreatePixmap( w,h, PF_BGR888)
		Case 32	pixmap = CreatePixmap( w,h, PF_BGRA8888)
		Default
			Throw "GrabWindowPixmap() supports only 24 and 32 bits"
	EndSelect

	Local bmphdr:BITMAPINFOHEADER = New BITMAPINFOHEADER
	bmphdr.biSize = SizeOf(bmphdr)
	bmphdr.biWidth = pixmap.width
	bmphdr.biHeight = pixmap.height
	bmphdr.biPlanes = 1
	bmphdr.biBitCount = bits
	bmphdr.biCompression = BI_RGB

	Local p:Byte Ptr = pixmap.pixels
	For Local y:Int = 0 Until pixmap.height
		GetDIBits( memdc,bmp, pixmap.height - y - 1,1, p, bmphdr, DIB_RGB_COLORS)	
		p :+ pixmap.pitch
	Next
	' make sure its visible
	If pixmap.Format =  PF_BGRA8888 Then
		Local pp:Byte Ptr = pixmap.pixels
		While pp < p
			pp[3] = $FF
			pp :+ 4
		Wend
	EndIf
	
	SelectObject( memdc, oldbmp)
	DeleteObject(bmp)
	DeleteDC(memdc)
	ReleaseDC( hwnd, srcdc)
	
	Return pixmap
EndFunction