Screenshot of Windows?

BlitzMax Forums/BlitzMax Programming/Screenshot of Windows?

Is there anyone who knows a way to grab a screenshot of the entire screen in Windows, including the blitzmax window? I've tried a few things, and searching, but came up blank..

Hoping someone can point me in the right direction! :)

chaos.mod/desktopext.mod can do that, and more:

Public Domain by hamZta, Suco-X, d-bug

See below:

'-- HEADER  ----------------------------------------------------------------------------------------------------------------------

Rem
	bbdoc:    DesktopExt
	about:    DesktopExt dient der Komunikation zwischen BMax und dem Desktop,
                ohne dabei auf MaxGUI Funktionen zurück greifen zu müssen.
End Rem

Module chaos.desktopext
ModuleInfo "Version: 1.13"
ModuleInfo "Author: hamZta, Suco-X, d-bug"
ModuleInfo "License: Public Domain"
ModuleInfo "Contact: d-bug@..."
ModuleInfo "Homepage: www.chaos-interactive.de"

ModuleInfo "History: 1.13 DesktopRatio hinzu"
ModuleInfo "History: 1.12 Macos 'identifer screen not found' bug behoben"
ModuleInfo "History: 1.11 Win32 Unterstützung mehrerer Desktops überarbeitet (danke klepto2 und Suco-X)"
ModuleInfo "History: 1.10 Unterstützung mehrerer Monitore für Win32 implementiert"
ModuleInfo "History: 1.09 Pixmap wird wieder konvertiert"
ModuleInfo "History: 1.08 Optionaler Flip und Pixmapformatierung bei DesktopPixmap implementiert"
ModuleInfo "History: 1.07 Unterstützung mehrerer Monitore für MacOS implementiert"
ModuleInfo "History: 1.06 'TPixmap not found' repariert"
ModuleInfo "History: 1.05 DesktopMouseX() bzw DesktopMouseY() für Win32"
ModuleInfo "History: 1.04 DesktopPixmap() für Win32"
ModuleInfo "History: 1.03 Dokumentation ist ab jetzt in deutsch"
ModuleInfo "History: 1.02 Scope von dbug. nach chaos. geändert"
ModuleInfo "History: 1.01 ReleaseDC eingefügt"
ModuleInfo "History: 1.00 Erster Release (16.05.2006)"



SuperStrict

Import brl.standardio
Import brl.pixmap
Import brl.linkedlist


?Win32 

	Import pub.win32

	Private 

		Const SM_CXVIRTUALSCREEN:Int = 78
		Const SM_CYVIRTUALSCREEN:Int = 79
		Const SM_CMONITORS:Int = 80
		Const SM_SAMEDISPLAYFORMAT:Int = 81
	
		Type TDisplay
			Global List:TList = New TList
			Field id:Int
			Field handle:Int
			Field x:Int
			Field y:Int
			Field width:Int
			Field height:Int
		End Type

		Type TRect
		   Field rLeft:Int
		   Field rTop:Int
		   Field rRight:Int
		   Field rBottom:Int
		End Type
		
		Extern "Win32"
			Function GetSystemMetrics:Int (nIndex:Int)"Win32"
			Function EnumDisplayMonitors:Int (hdc:Int, lprcClip:Byte Ptr, lpfnEnum:Byte Ptr, dwData:Byte Ptr)"Win32"
			Function GetCursorPos(lpPoint:Byte Ptr)"Win32" = "GetCursorPos@4"
			Function GetDIBits(hdc:Int, bitmap:Int, Start:Int, Num:Int, bits:Byte Ptr, lpbi:Byte Ptr, usage:Int)"Win32"
			Function GetWindowDC(hwnd:Int)"Win32"
			Function ReleaseDC(hwnd:Int, hdc:Int)"Win32"
		End Extern
		
		Function MonitorEnumProc:Byte (hMonitor:Int,hdcMonitor:Int,lprcMonitor:Byte Ptr,dwData:Int)
			Local tempRect:TRect = New TRect
			MemCopy(tempRect, lprcMonitor, SizeOf(tempRect))
			Local display:TDisplay = New TDisplay
			TDisplay.List.AddLast(display)
			display.id = TDisplay.List.Count()
			display.handle = hMonitor
			display.x = tempRect.rLeft
			display.y = tempRect.rTop
			display.width = tempRect.rRight - display.x
			display.height = tempRect.rBottom - display.y
			Return True
		End Function
		EnumDisplayMonitors (Null , Null , MonitorEnumProc , Null)
	
	Public 
?MacOS
	Import "macscreen.c"
	Private
		Extern
			Function CGDisplayCurrentMode:Byte Ptr(displayID:Byte Ptr)"MacOS"
			Function CGGetActiveDisplayList:Byte Ptr(kMaxDisplays:Int, display:Byte Ptr, numDisplays:Int Var)"MacOS"
			Function MACOS_GetWidth:Int(mode:Byte Ptr)"C"
			Function MACOS_GetHeight:Int(mode:Byte Ptr)"C"
			Function MACOS_GetBPP:Int(mode:Byte Ptr)"C"
			Function MACOS_GetHertz:Int(mode:Byte Ptr)"C"
		End Extern 
	Public
?Linux
	Import brl.graphics
? 



Rem
	bbdoc:		Aspekt-Ratio des Desktops (Monitors) abfragen
	returns:	AspektRatio als String
	about:		<table>
							<tr><th>Parameter</th><th>Wert</th><th>Beschreibung</th><th>Windows</th><th>MacOSX</th><th>Linux</th></tr>
							<tr><td>screen</td><td>0</td><td>Primärer Desktop (Monitor)</td><td>X</td><td></td><td></td></tr>
							<tr><td>screen</td><td>1 - x</td><td>Sekundäre Desktops (Monitore)</td><td>X</td><td></td><td></td></tr>
						</table>
End Rem
Function DesktopRatio:String (screen:Int=0)

			Function DAR:Int (a:Int, b:Int)
				Local fudge:Int = 0
				Local Result:Int
				If b mod a <= fudge
					Result = a
				Else
					Result = DAR (b, a mod b)
				EndIf
				Return Result
			End Function

	Local X:Int = DesktopWidth(screen)
	Local Y:Int = DesktopHeight(screen)
	Local Div:Int = DAR(X,Y)
	Local Result:String = String (X/Div) + ":" + String(Y/Div)
	Select Result
		Case "8:5" ; 	Return "16:10"
		Default ; 		Return Result
	End Select

End Function


Rem
	bbdoc:		Anzahl der Desktops (Monitore) abfragen
	returns:	Anzahl als Integer
	about:		<table>
							<tr><th>Windows</th><th>MacOSX</th><th>Linux</th></tr>
							<tr><td>X</td><td>X</td><td></td></tr>
						</table>
End Rem

Function DesktopCount:Int () 

	?Win32
		Return GetSystemMetrics (SM_CMONITORS)
	?MacOS
		Local display:Byte Ptr[] = New Byte Ptr[1]
		Local iMode:Byte Ptr = Null
		Local iCount:Int
		CGGetActiveDisplayList 1, display, iCount
		Return iCount
	?Linux
		Return 0
	?

End Function 


							

Rem
	bbdoc:		X-Koordinate des Desktops (Monitors) abfragen
	returns:	X-koordinate als Integer
	about:		<table>
							<tr><th>Parameter</th><th>Wert</th><th>Beschreibung</th><th>Windows</th><th>MacOSX</th><th>Linux</th></tr>
							<tr><td>screen</td><td>0</td><td>Primärer Desktop (Monitor)</td><td>X</td><td></td><td></td></tr>
							<tr><td>screen</td><td>1 - x</td><td>Sekundäre Desktops (Monitore)</td><td>X</td><td></td><td></td></tr>
						</table>
End Rem
Function DesktopX:Int (screen:Int = 0) 
	If screen < 0 Then screen = 0
	?Win32
			For Local display:TDisplay = EachIn TDisplay.List
				If display.id = screen+1
					Return display.X
				EndIf
			Next
			Return 0
	?MacOS
		Return 0
	?Linux
		Return 0
	?
End Function 

Rem
	bbdoc:		Y-Koordinate des Desktops (Monitors) abfragen
	returns:	Y-koordinate als Integer
	about:		<table>
							<tr><th>Parameter</th><th>Wert</th><th>Beschreibung</th><th>Windows</th><th>MacOSX</th><th>Linux</th></tr>
							<tr><td>screen</td><td>0</td><td>Primärer Desktop (Monitor)</td><td>X</td><td></td><td></td></tr>
							<tr><td>screen</td><td>1 - x</td><td>Sekundäre Desktops (Monitore)</td><td>X</td><td></td><td></td></tr>
						</table>
End Rem
Function DesktopY:Int (screen:Int = 0) 
	If screen < 0 Then screen = 0
	?Win32
			For Local display:TDisplay = EachIn TDisplay.List
				If display.id = screen+1
					Return display.Y
				EndIf
			Next
			Return 0
	?MacOS
		Return 0
	?Linux
		Return 0
	?
End Function 


Rem
	bbdoc:		Breite des Desktops (Monitors) abfragen
	returns:	Breite als Integer
	about:		<table>
							<tr><th>Parameter</th><th>Wert</th><th>Beschreibung</th><th>Windows</th><th>MacOSX</th><th>Linux</th></tr>
							<tr><td>screen</td><td>-1</td><td>Gesammtbreite aller Desktops (Monitore)</td><td>X</td><td></td><td></td></tr>
							<tr><td>screen</td><td>0</td><td>Primärer Desktop (Monitor)</td><td>X</td><td>X</td><td>X</td></tr>
							<tr><td>screen</td><td>1 - x</td><td>Sekundäre Desktops (Monitore)</td><td>X</td><td>X</td><td></td></tr>
						</table>
End Rem
Function DesktopWidth:Int (screen:Int=0) 
	Local width:Int,height:Int,depth:Int,hertz:Int
	GetDesktopMode (width, height, depth, hertz, screen)
	Return width
End Function 


Rem
	bbdoc:		Höhe des Desktops (Monitors) abfragen
	returns:	Höhe als Integer
	about:		<table>
							<tr><th>Parameter</th><th>Wert</th><th>Beschreibung</th><th>Windows</th><th>MacOSX</th><th>Linux</th></tr>
							<tr><td>screen</td><td>-1</td><td>Gesammthöhe aller Desktops (Monitore)</td><td>X</td><td></td><td></td></tr>
							<tr><td>screen</td><td>0</td><td>Primärer Desktop (Monitor)</td><td>X</td><td>X</td><td>X</td></tr>
							<tr><td>screen</td><td>1 - x</td><td>Sekundäre Desktops (Monitore)</td><td>X</td><td>X</td><td></td></tr>
						</table>
End Rem
Function DesktopHeight:Int (screen:Int=0) 
	Local width:Int,height:Int,depth:Int,hertz:Int
	GetDesktopMode (width, height, depth, hertz, screen)
	Return height
End Function 

Rem
	bbdoc:		Tiefe des Desktops (Monitors) abfragen
	returns:	Tiefe als Integer
	about:		<table>
							<tr><th>Parameter</th><th>Wert</th><th>Beschreibung</th><th>Windows</th><th>MacOSX</th><th>Linux</th></tr>
							<tr><td>screen</td><td>0</td><td>Primärer Desktop (Monitor)</td><td>X</td><td>X</td><td>X</td></tr>
							<tr><td>screen</td><td>1 - x</td><td>Sekundäre Desktops (Monitore)</td><td></td><td>X</td><td></td></tr>
						</table>
End Rem
Function DesktopDepth:Int (screen:Int=0) 
	Local width:Int,height:Int,depth:Int,hertz:Int
	GetDesktopMode (width, height, depth, hertz, screen)
	Return depth
End Function 

Rem
	bbdoc:		Wiederholrate des Desktops (Monitors) abfragen
	returns:	Wiederholrate als Integer
	about:		<table>
							<tr><th>Parameter</th><th>Wert</th><th>Beschreibung</th><th>Windows</th><th>MacOSX</th><th>Linux</th></tr>
							<tr><td>screen</td><td>0</td><td>Primärer Desktop (Monitor)</td><td>X</td><td>X</td><td>X</td></tr>
							<tr><td>screen</td><td>1 - x</td><td>Sekundäre Desktops (Monitore)</td><td></td><td>X</td><td></td></tr>
						</table>
End Rem
Function DesktopHertz:Int (screen:Int=0) 
	Local width:Int,height:Int,depth:Int,hertz:Int
	GetDesktopMode (width, height, depth, hertz, screen)
	Return hertz
End Function 


Rem
	bbdoc:		Breite, Höhe, Tiefe und Wiederholrate des Desktops (Monitors) abfragen
	about:		Kompatibilität siehe DesktopWidth(), DesktopHeight(), DesktopDepth() und DesktopHertz()
End Rem
Function GetDesktopMode:Int (width:Int Var, height:Int Var, depth:Int Var, hertz:Int Var, screen:Int=0) 
	?Win32
		Local hwnd:Int = GetDesktopWindow()
		Local hdc:Int = GetDC(hwnd)
		If hdc = Null Then Return -1
		depth  = GetDeviceCaps(hdc, BITSPIXEL)
		hertz  = GetDeviceCaps(hdc, VREFRESH)
		ReleaseDC(hwnd,hdc)
		If screen = -1
			width = GetSystemMetrics (SM_CXVIRTUALSCREEN)
			height = GetSystemMetrics (SM_CYVIRTUALSCREEN)
		Else
			Local valid:Byte = True
			For Local display:TDisplay = EachIn TDisplay.List
				If display.id = screen+1
					width = display.width
					height = display.height
					Exit
				EndIf
			Next
		EndIf	
	?MacOS
		Local display:Byte Ptr[] = New Byte Ptr[screen+1]
		Local iMode:Byte Ptr = Null
		Local iCount:Int
		CGGetActiveDisplayList screen+1, display, iCount
		If (screen < iCount)
			iMode  = CGDisplayCurrentMode(display[screen])
		Else
			Throw " [DesktopExt] Screen '"+screen+"' does not exist!"
		End If
		width  = MACOS_GetWidth(iMode)
		height = MACOS_GetHeight(iMode)
		depth  = MACOS_GetBPP(iMode)
		hertz  = MACOS_GetHertz(iMode)
	?Linux
		CountGraphicsModes()
		GetGraphicsMode (0,width,height,depth,hertz)
	?
End Function 



Rem
	bbdoc:		Screenshot des Desktops in einer Pixmap erstellen
	returns:	Screenshot als TPixmap
	about:		<table>
							<tr><th>Windows</th><th>MacOSX</th><th>Linux</th></tr>
							<tr><td>X</td><td></td><td></td></tr>
						</table>
End Rem
Function DesktopPixmap:TPixmap (flag:Byte = True) 

	'Original Funktion von Suco-X

	?Linux
		Return Null
	?MacOS
		Return Null
	?Win32
		Local hwnd:Int = GetDesktopWindow()
		If Not hwnd Return Null
		Local hdc:Int = GetWindowDC(hwnd)
		If Not hdc Return Null
		Local hdcmem:Int = CreateCompatibleDC(hdc)
     	If Not hdcmem Return Null
		Local info:BITMAPINFOHEADER = New BITMAPINFOHEADER
		info.biSize = SizeOf(info)
		info.biPlanes = 1
		info.biCompression = 0
		Local hertz:Int,depth:Int
		GetDesktopMode:Int (info.biWidth,info.biHeight,depth,hertz,-1)
		info.biBitCount = depth
		Local bmpmem:Int  = CreateCompatibleBitmap(hdc, info.biWidth, info.biHeight)
 		If (Not bmpmem) Or (Not SelectObject(hdcmem, bmpmem)) Return Null
		If Not BitBlt(hdcmem,0,0,info.biWidth,info.biHeight,hdc,0,0,ROP_SRCCOPY) Return Null
		Local out:TPixmap = CreatePixmap(info.biWidth, info.biHeight, PF_BGRA8888)
		If Not GetDIBits(hdcmem, bmpmem, 0, info.biHeight, out.PixelPtr(0,0), info, 0) Return Null
	      DeleteDC(hdcmem)
	      DeleteObject(bmpmem)
		ReleaseDC(hwnd, hdc)
		out = out.Convert(PF_BGR888) 'dumm gelaufen, man kann nicht direkt in dem Format grabben
		If flag = True out = YFlipPixmap(out)
		Return out
	?
End Function 


Rem
	bbdoc:		Globale Maus X-Koordinate abfragen
	returns:	X-Koordinate als Integer
	about:		<table>
							<tr><th>Windows</th><th>MacOSX</th><th>Linux</th></tr>
							<tr><td>X</td><td></td><td></td></tr>
						</table>
End Rem
Function DesktopMouseX:Int () 
	?Linux
		Return 0
	?MacOS
		Return 0
	?Win32
		Local Coord:Int[2]
		GetCursorPos(Coord)
		Return Coord[0]
	?
End Function 


Rem
	bbdoc:		Globale Maus Y-Koordinate abfragen
	returns:	Y-Koordinate als Integer
	about:		<table>
							<tr><th>Windows</th><th>MacOSX</th><th>Linux</th></tr>
							<tr><td>X</td><td></td><td></td></tr>
						</table>
End Rem
Function DesktopMouseY:Int () 
	?Linux
		Return 0
	?MacOS
		Return 0
	?Win32
		Local Coord:Int[2]
		GetCursorPos(Coord)
		Return Coord[1]
	?
End Function 






Or just press the PRINT SCREEN key and paste in MS Paint or any other image program.

Or just press the PRINT SCREEN key and paste in MS Paint or any other image program.


Or that.

I figured he was looking for a programmatic way since he posted it in the 'Blitzmax programming' forum instead of 'general help'

It's better to use the zipped version of the module. The code from xlsior's post will not work on OS X becourse macscreen.c is missing.

See link in my signature.

Did you update this to add dual monitor support to DesktopPixmap()?

No sorry, was it requested anywhere? I'll have a look at it this evening.

~edit~
oops, had done this long time ago, but never updated the version on our website.
please download latest version (1.15).

Yep, it was me you originally did it for, but you only ever posted a modification for me to make to the code myself. :)