May 26, 2020, 06:51:36 PM

Author Topic: [bb] Capture Screen functions by markcw [ 1+ years ago ]  (Read 4065 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bb] Capture Screen functions by markcw [ 1+ years ago ]
« on: June 29, 2017, 12:28:43 AM »
Title : Capture Screen functions
Author : markcw
Posted : 1+ years ago

Description : 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.
Code: [Select]
.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.
Code: [Select]
.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 <a href="codearcsbcfe.html?code=1179" target="_blank">user32.dll decls[/url] and <a href="codearcs3907-2.html?code=1181" target="_blank">gdi32.dll decls[/url].

The CaptureScreenArea function. [/i]

Code :
Code: BlitzBasic
  1. ;Capture Screen Area function, by markcw on 14 Jul 06
  2.  
  3. Graphics3D 320,240,0,2
  4. SetBuffer BackBuffer()
  5.  
  6. initime=MilliSecs()
  7.  
  8. While Not KeyHit(1)
  9.  
  10.  If done=0 And MilliSecs()>initime+50 ;wait for text info
  11.   done=1 : CaptureScreenArea(0,0,320,240) ;x,y,width,height
  12.  EndIf
  13.  
  14.  Cls
  15.  Text 0,0,"OK, paste the current clipboard data"
  16.  Text 0,12,"to whatever program you use to see"
  17.  Text 0,24,"the results of the screen capture."
  18.  Text 0,36,"done="+done+" initime="+initime
  19.  
  20. Flip
  21. Wend
  22.  
  23. Function CaptureScreenArea(sx,sy,swidth,sheight)
  24.  ;Capture a given screen area to the clipboard
  25.  ;From PureBasic CodeArchiv source, by wayne1 on 30/1/2002
  26.  
  27.  Local hdcSrc,hdcDst,hbmp,hold
  28.  
  29.  hdcSrc=Api_GetDC(0) ;hwnd
  30.  hdcDst=Api_CreateCompatibleDC(hdcSrc) ;hdc
  31.  hbmp=Api_CreateCompatibleBitmap(hdcSrc,swidth,sheight) ;hdc,width,height
  32.  hold=Api_SelectObject(hdcDst,hbmp) ;hdc,hobject[bitmap]
  33.  Api_BitBlt(hdcDst,0,0,swidth,sheight,hdcSrc,sx,sy,$00CC0020) ;SrcCopy
  34.  Api_SelectObject(hdcDst,hold) ;restore old to dc
  35.  If Api_OpenClipboard(0) ;hwnd
  36.   Api_EmptyClipboard() ;free last data
  37.   Api_SetClipboardData(2,hbmp) ;CF_Bitmap,hdata[bitmap]
  38.   Api_CloseClipboard()
  39.  EndIf
  40.  Api_ReleaseDC(0,hdcSrc) ;hwnd,hdc
  41.  Api_DeleteDC(hdcDst) ;hdc
  42.  
  43. End Function


Comments :


markcw(Posted 1+ years ago)

 A CaptureDesktop function, which uses the CaptureScreenArea function.
Code: [Select]
;Capture Desktop function, by markcw on 16 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 : CaptureDesktop()
 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 CaptureDesktop()
 ;Capture the entire desktop area to the clipboard
 ;From PureBasic Forum source, by Droopy on 18/10/2005

 Local dwidth,dheight

 dwidth=Api_GetSystemMetrics(0) ;SM_CXScreen
 dheight=Api_GetSystemMetrics(1) ;SM_CYScreen
 CaptureScreenArea(0,0,dwidth,dheight) ;x,y,width,height

End Function

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



markcw(Posted 1+ years ago)

 A CaptureWindow function, which also uses the CaptureScreenArea function.
Code: [Select]
;Capture Window function, by markcw on 15 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 : CaptureWindow()
 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 CaptureWindow()
 ;Capture the entire window area to the clipboard
 ;From PureBasic Forum source, by Droopy on 18/10/2005

 Local hwnd,prect,rx,ry,rwidth,rheight

 hwnd=Api_GetForegroundWindow()
 If hwnd ;window valid
  prect=CreateBank(16) ;bank structure
  Api_GetWindowRect(hwnd,prect) ;hwnd,rect[left,top,right,bottom]
  rx=PeekInt(prect,0) ;rect left
  ry=PeekInt(prect,4) ;rect top
  rwidth=PeekInt(prect,8)-PeekInt(prect,0) ;rect right-left
  rheight=PeekInt(prect,12)-PeekInt(prect,4) ;rect bottom-top
  CaptureScreenArea(rx,ry,rwidth,rheight) ;x,y,width,height
  FreeBank prect ;free from memory
 EndIf

End Function

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



markcw(Posted 1+ years ago)

 A CaptureClient function, again using the CaptureScreenArea function.
Code: [Select]
;Capture Client function, by markcw on 16 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 : CaptureClient()
 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 CaptureClient()
 ;Capture the entire client area to the clipboard
 ;From PureBasic CodeArchiv source, by Edwin Knoppert on 24/11/2003

 Local hwnd,prect,rx,ry,rwidth,rheight

 hwnd=Api_GetForegroundWindow()
 If hwnd ;window valid
  prect=CreateBank(16) ;bank structure
  Api_GetClientRect(hwnd,prect) ;hwnd,rect[left,top,right,bottom]
  Api_ClientToScreen(hwnd,prect) ;hwnd,point[x,y]
  rx=PeekInt(prect,0) ;point x
  ry=PeekInt(prect,4) ;point y
  rwidth=PeekInt(prect,8) ;rect right
  rheight=PeekInt(prect,12) ;rect bottom
  CaptureScreenArea(rx,ry,rwidth,rheight) ;x,y,width,height
  FreeBank prect ;free from memory
 EndIf

End Function

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



markcw(Posted 1+ years ago)

 A CaptureClientArea function, like the CaptureClient function except lets you capture a given area, ie. an image.
Code: [Select]
;Capture Client Area function, by markcw on 16 Jul 06

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

image=CreateImage(128,128) ;new image
For y=0 To ImageHeight(image)-1
 For x=0 To ImageWidth(image)-1
  rgba=y+(y*256)+(x*256^2) ;gradient color
  WritePixel x,y,rgba,ImageBuffer(image)
 Next
Next

initime=MilliSecs()

While Not KeyHit(1)

 If done=0 And MilliSecs()>initime+50 ;wait for text info
  done=1 : CaptureClientArea(64,64,ImageWidth(image),ImageHeight(image))
 EndIf

 Cls
 DrawImage image,64,64 ;draw the image

 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 CaptureClientArea(cx,cy,cwidth,cheight)
 ;Capture a given client area to the clipboard
 ;From PureBasic CodeArchiv source, by Edwin Knoppert on 24/11/2003

 Local hwnd,ppoint,px,py

 hwnd=Api_GetForegroundWindow()
 If hwnd ;window valid
  ppoint=CreateBank(8) ;bank structure
  Api_ClientToScreen(hwnd,ppoint) ;hwnd,point[x,y]
  px=PeekInt(ppoint,0) ;point x
  py=PeekInt(ppoint,4) ;point y
  CaptureScreenArea(px+cx,py+cy,cwidth,cheight) ;x,y,width,height
  FreeBank ppoint ;free from memory
 EndIf

End Function

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



Wayne(Posted 1+ years ago)

 Right on Muk, good stuff !


markcw(Posted 1+ years ago)

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


markcw(Posted 1+ years ago)

 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.


Wayne(Posted 1+ years ago)

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


markcw(Posted 1+ years ago)

 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.


markcw(Posted 1+ years ago)

 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.


schilcote(Posted 1+ years ago)

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


markcw(Posted 1+ years ago)

 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.
Code: [Select]
.lib "User32.dll"
Api_FindWindow%(classname$, windowname$):"FindWindowA"
Code: [Select]
; 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. [/i]

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal