Code archives/User Libs/Capture Screen functions

This code has been declared by its author to be Public Domain code.

Download source code

Capture Screen functions by markcw2006
I was looking at how to use the clipboard in blitz3d (using the win32 api) and found some PB code to capture the screen and send it to the clipboard.

edit: found some more code on the PB forum that extended this function, it used GetSystemMetrics (for the desktop size) which was better than GetDeviceCaps.

You need to have a file named "User32.decls" in your "userlibs" folder with these declared.
.lib "User32.dll"

; Window Functions
Api_GetClientRect%(hWnd,lpRect*):"GetClientRect"
Api_GetDesktopWindow%():"GetDesktopWindow"
Api_GetForegroundWindow%():"GetForegroundWindow"
Api_GetWindowRect%(hWnd,lpRect*):"GetWindowRect"
; Clipboard Functions
Api_CloseClipboard%():"CloseClipboard"
Api_EmptyClipboard%():"EmptyClipboard"
Api_GetClipboardData%(uFormat):"GetClipboardData"
Api_IsClipboardFormatAvailable%(format):"IsClipboardFormatAvailable"
Api_OpenClipboard%(hwnd):"OpenClipboard"
Api_SetClipboardData%(uFormat,hData):"SetClipboardData"
; Coordinate Space and Transformation Functions
Api_ClientToScreen%(hWnd,lpPoint*):"ClientToScreen"
; Device Context Functions
Api_GetDC%(hWnd):"GetDC"
Api_ReleaseDC%(hwnd,hdc):"ReleaseDC"
; Accessibility Functions
Api_GetSystemMetrics%(nIndex):"GetSystemMetrics"

And a file named "Gdi32.decls" in the "userlibs" folder with these declared.
.lib "Gdi32.dll"

; Bitmap Functions
Api_BitBlt%(hdcDest,nXDest,nYDest,nWidth,nHeight,hdcSrc,nXSrc,nYSrc,dwRop):"BitBlt"
Api_CreateCompatibleBitmap%(hdc,nWidth,nHeight):"CreateCompatibleBitmap"
Api_GetPixel%(hdc,nXPos,nYPos):"GetPixel"
Api_SetPixel%(hdc,X,Y,crColor):"SetPixel"
; Device Context Functions
Api_CreateCompatibleDC%(hdc):"CreateCompatibleDC"
Api_CreateDC%(lpszDriver$,lpszDevice$,lpszOutput$,lpInitData*):"CreateDCA"
Api_DeleteDC%(hdc):"DeleteDC"
Api_DeleteObject%(hObject):"DeleteObject"
Api_GetDeviceCaps%(hdc,nIndex):"GetDeviceCaps"
Api_GetObject%(hgdiobj,cbBuffer,lpvObject*):"GetObjectA"
Api_SelectObject%(hdc,hgdiobj):"SelectObject"

Or you can use the user32.dll decls and gdi32.dll decls.

The CaptureScreenArea function.
;Capture Screen Area function, by markcw on 14 Jul 06

Graphics3D 320,240,0,2
SetBuffer BackBuffer()

initime=MilliSecs()

While Not KeyHit(1)

 If done=0 And MilliSecs()>initime+50 ;wait for text info
  done=1 : CaptureScreenArea(0,0,320,240) ;x,y,width,height
 EndIf

 Cls
 Text 0,0,"OK, paste the current clipboard data"
 Text 0,12,"to whatever program you use to see"
 Text 0,24,"the results of the screen capture."
 Text 0,36,"done="+done+" initime="+initime

Flip
Wend

Function CaptureScreenArea(sx,sy,swidth,sheight)
 ;Capture a given screen area to the clipboard
 ;From PureBasic CodeArchiv source, by wayne1 on 30/1/2002

 Local hdcSrc,hdcDst,hbmp,hold

 hdcSrc=Api_GetDC(0) ;hwnd
 hdcDst=Api_CreateCompatibleDC(hdcSrc) ;hdc
 hbmp=Api_CreateCompatibleBitmap(hdcSrc,swidth,sheight) ;hdc,width,height
 hold=Api_SelectObject(hdcDst,hbmp) ;hdc,hobject[bitmap]
 Api_BitBlt(hdcDst,0,0,swidth,sheight,hdcSrc,sx,sy,$00CC0020) ;SrcCopy
 Api_SelectObject(hdcDst,hold) ;restore old to dc
 If Api_OpenClipboard(0) ;hwnd
  Api_EmptyClipboard() ;free last data
  Api_SetClipboardData(2,hbmp) ;CF_Bitmap,hdata[bitmap]
  Api_CloseClipboard()
 EndIf
 Api_ReleaseDC(0,hdcSrc) ;hwnd,hdc
 Api_DeleteDC(hdcDst) ;hdc

End Function

Comments

markcw2006
A CaptureDesktop function, which uses the CaptureScreenArea function.




markcw2006
A CaptureWindow function, which also uses the CaptureScreenArea function.




markcw2006
A CaptureClient function, again using the CaptureScreenArea function.




markcw2006
A CaptureClientArea function, like the CaptureClient function except lets you capture a given area, ie. an image.




Wayne2006
Right on Muk, good stuff !


markcw2006
Thanks Wayne. I am going to see if i can copy a FreeImage bitmap directly now.


markcw2006
just updated these examples to use the "Api_" prefix so there are no functions of the same name and so you can tell an api function straight away.

Also, i changed to using Api_GetDC instead of Api_CreateDC because it does the same thing and is simpler to use.


Wayne2006
I would of thought create would be functionaly differet from get. hmm


markcw2006
well it's instead of creating a dc you just get an existing one, when you call getdc(0) it gets the display/desktop window, both can be used afaik.


markcw2006
ok, i updated this code again.

it doesn't really make much difference, but apparently you're supposed to put/reselect a dc's original dummy object back before deleting the dc.

also, there was no need to delete the bitmap object as the clipboard uses it, i thought it made a copy but it just becomes the new owner.


schilcote2008
Umm... CaptureDesktop doesn't work for me.


markcw2008
It might be because the CaptureWindow/Client/ClientArea functions use Api_GetForegroundWindow to get the window handle which is not as reliable as using Api_FindWindow as there may be another foreground/active window. In order to use Api_FindWindow you need the define the Blitz app class (different in B+) and title, like so. Edit: SystemProperty("AppHWND") does the same thing as FindWindow.
.lib "User32.dll"
Api_FindWindow%(classname$, windowname$):"FindWindowA"
; Const class$="GX_WIN32_CLASS" ;BlitzPlus 1.11
; Const class$="BLITZMAX_WINDOW_CLASS" ;BlitzPlus 1.34
Const class$="Blitz Runtime Class" ;Blitz3D, app class
Const title$ = "My Blitz Window" ;app title

AppTitle title$
hwnd = Api_FindWindow(class$, title$)

As for CaptureDesktop not working I can only assume that Api_GetDC(0) isn't working for some reason.


Code Archives Forum