Enregistrement de flux provenant de ma webcam

Programmation d'applications complexes
creale
Messages : 16
Inscription : sam. 29/janv./2011 14:33

Enregistrement de flux provenant de ma webcam

Message par creale »

Bonjour à tous,

Je cherche depuis pas mal de temps une librairie/un code me permettant de faire une capture de se que voie ma webcam...et de l'enregistrer tous simplement.

J'ai trouvé moult librairies et posts sur le forum anglais, mais rien en semble fonctionner correctement.

L'un d'entre vous à-t-il quelques chose sur ce sujet ?

Merci d'avance !
Agence web https://www.atoneo.com
Bougie personnalisée https://www.bougie-personnalisee.fr
Fabrication bougie https://www.fabricant-bougie.fr
Avis externalisés https://satisfactions-clients.com
Ecommerçants Alsaciens https://www.alsazon.shop
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Enregistrement de flux provenant de ma webcam

Message par Ar-S »

Essaye la très bonne RCAM de Progi1984
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
creale
Messages : 16
Inscription : sam. 29/janv./2011 14:33

Re: Enregistrement de flux provenant de ma webcam

Message par creale »

Merci, j'ai téléchargé la librairie, mais aucun exemple ne fonctionne...

Y a t-il un manip particulière à faire ?
Agence web https://www.atoneo.com
Bougie personnalisée https://www.bougie-personnalisee.fr
Fabrication bougie https://www.fabricant-bougie.fr
Avis externalisés https://satisfactions-clients.com
Ecommerçants Alsaciens https://www.alsazon.shop
Avatar de l’utilisateur
venom
Messages : 3137
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: Enregistrement de flux provenant de ma webcam

Message par venom »

As tu bien installer les fichiers aux bon endroits avant de lancer les codes ?

tu doit mettre le fichier RCam dans le repertoire suivant: (avec une installation de base)
C:\Program Files\PureBasic\PureLibraries\UserLibraries

Et le fichier RCam.res dans:
C:\Program Files\PureBasic\Residents

seulement là tu peut lancer les codes :wink:






@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Enregistrement de flux provenant de ma webcam

Message par Ar-S »

Commente les lignes qui te donnent des erreurs.

----edit-----
Après reinstallation sur la 4.51, aucun exemple ne fonctionnent effectivement..
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Enregistrement de flux provenant de ma webcam

Message par Ar-S »

Trouvé sur le fofo anglais
Voilà un code de détection de mouvement fait par JLC et adapté en 4.51 par Dobro. Il est fonctionnel, tu devrais pouvoir l'adapter à tes besoins.

Code : Tout sélectionner

; codé par by JLC
; Modifié par Dobro pour le Purebasic 4.51
; et utilisation des prototypes
; ce prg repere un mouvement et signale a l'aide de carré vert

;EnableExplicit

Prototype.l appel_fonction1(titr$, type,type1,type2, type3, type4, id ,type5)

;{ CAP constants
#WM_CAP_START = #WM_USER
#WM_CAP_DRIVER_CONNECT = #WM_CAP_START + 10
#WM_CAP_DRIVER_DISCONNECT = #WM_CAP_START + 11
#WM_CAP_DRIVER_GET_CAPS = #WM_CAP_START + 14
#WM_CAP_EDIT_COPY = #WM_CAP_START + 30
#WM_CAP_SET_PREVIEW = #WM_CAP_START + 50
#WM_CAP_SET_PREVIEWRATE = #WM_CAP_START + 52
#WM_CAP_STOP = #WM_CAP_START + 68
#WM_CAP_SET_SCALE = #WM_CAP_START + 53
#WM_CAP_START = #WM_USER
#WM_CAP_DLG_VIDEOSOURCE = #WM_CAP_START + 42
;}
#Main =0
#camWidth = 640
#camHeight = 480
#w16 = 40
#h16 = 30

Structure avg
  r.l
  g.l
  b.l
EndStructure

Global hWndC
Define Ccam_lib1, *capAddress

Procedure rotate90(*MemoryTarget,W,H,size)
  Protected x,Y,Target, Origin, *MemoryOrigin = AllocateMemory (size)
  CopyMemory (*MemoryTarget,*MemoryOrigin,size)
  For Y = 0 To H - 1
    For x = 0 To W - 1
      Origin = (Y * W + x) << 2
      Target = ((H - Y - 1) + (x * H)) << 2
      PokeL (*MemoryTarget + Target, PeekL (*MemoryOrigin + Origin))
    Next
  Next
  FreeMemory (*MemoryOrigin)
EndProcedure



Procedure greyScale(*Memory, memorysize )
  Protected Counter, Color
  For Counter = 0 To memorysize - 1 Step 4
    Color = PeekL (*Memory + Counter)
    Color = ( Red (Color) + Green (Color) + Blue (Color)) / 3
    PokeL (*Memory + Counter, RGB (Color, Color, Color))
  Next
EndProcedure



Procedure captureImage(dummy)
  Protected image, bmp.BITMAP, imageid , imageSize, *bits, pos
  Protected Dim prev.avg( #w16 , #h16 )
  Protected x,Y,yy,xx, avg.avg, Color, diff
  
  Repeat
    SendMessage_ (hWndC, #WM_CAP_EDIT_COPY ,0,0)
    image = GetClipboardImage ( #PB_Any ,32)
    If image<>0
      imageid = ImageID (image) ;maybe flip it first
      
      GetObject_ ( imageid , SizeOf (BITMAP),@bmp.BITMAP)
      imageSize = bmp\bmWidthBytes * bmp\bmHeight
      *bits = bmp\bmBits
      
      StartDrawing ( WindowOutput (0))
        DrawImage ( imageid ,0,0) ;____________________________________________ici
        DrawingMode ( #PB_2DDrawing_Outlined )
        
        For x=0 To #w16 -1
          For Y=0 To #h16 -1
            avg\r = 0: avg\g=0: avg\b=0
            For xx=x*16 To x*16+16-1
              For yy=Y*16 To Y*16+16-1
                pos = (yy * bmp\bmWidth + xx) << 2
                Color = PeekL (*bits+pos)
                avg\r + Red (Color)
                avg\g + Green (Color)
                avg\b + Blue (Color)
                ;Plot(xx,479-yy,color)
              Next
            Next
            avg\r = avg\r / 256
            avg\g = avg\g / 256
            avg\b = avg\b / 256
            ; Box(X*16,Y*16,16,16,RGB(avg\r,avg\g,avg\b))
            diff = 0
            diff + Abs (prev(x,Y)\r - avg\r)
            diff + Abs (prev(x,Y)\g - avg\g)
            diff + Abs (prev(x,Y)\b - avg\b)
            If diff > 40
              Box (x*16,464-Y*16,15,15, #Green )
              ; Circle(X*16+8,464-Y*16+8,8,#Green) ;Or circleIfif you want
            EndIf
            prev(x,Y)\r = avg\r
            prev(x,Y)\g = avg\g
            prev(x,Y)\b = avg\b
          Next
        Next
        
        ; DrawImage(imageID,0,0)
      StopDrawing ()
      FreeImage (image)
    EndIf
    
    ;Delay(2000)
  ForEver
EndProcedure



If OpenWindow ( #Main ,0,0,640,480, "Webcam Motion Detector by JLC" , #PB_Window_ScreenCentered|#PB_Window_SystemMenu )
  Ccam_lib1 = OpenLibrary ( #PB_Any , "avicap32.dll" )
  If Ccam_lib1
    appel_fonction1.appel_fonction1 = GetFunction (Ccam_lib1, "capCreateCaptureWindowA" )
    hWndC= appel_fonction1( "My Capture Window" , #WS_CHILD | #WS_VISIBLE , 0,0, 1 , 1, WindowID ( #Main ),0)
    SendMessage_ (hWndC, #WM_CAP_DRIVER_CONNECT , 0, 0)
    SendMessage_ (hWndC, #WM_CAP_SET_OVERLAY , #True , 0)
    SendMessage_ (hWndC, #WM_CAP_SET_PREVIEW , #True , 0)
    SendMessage_ (hWndC, #WM_CAP_SET_PREVIEWRATE , 1, 0)
  EndIf
EndIf


CreateThread (@captureImage(),0)

Repeat
  Delay (10)
Until WaitWindowEvent () = #PB_Event_CloseWindow

SendMessage_ (hWndC, #WM_CAP_STOP ,0,0)
SendMessage_ (hWndC, #WM_CAP_DRIVER_DISCONNECT ,0,0)
DestroyWindow_ (hWndC)
CloseLibrary (Ccam_lib1)
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
creale
Messages : 16
Inscription : sam. 29/janv./2011 14:33

Re: Enregistrement de flux provenant de ma webcam

Message par creale »

Excellent ce code !!

J'ai pas vu de fonction qui enregistre la vidéo, j'ai cru comprendre aussi que le flux est découpé image par image dans la variable imagid c'est ça ?

Si tel est le cas, je vais devoir trouver une fonction qui recompose la video en image par image...


Autre petite question, savez vous s'il est possible de bloquer l'allumage du voyant webcam (sur mon pc portable le voyant s'allume lorsque la cam est sollicitée)



Merci d'avance
Agence web https://www.atoneo.com
Bougie personnalisée https://www.bougie-personnalisee.fr
Fabrication bougie https://www.fabricant-bougie.fr
Avis externalisés https://satisfactions-clients.com
Ecommerçants Alsaciens https://www.alsazon.shop
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Enregistrement de flux provenant de ma webcam

Message par Ar-S »

Je n'utilise pas ce code et n'ai pas le temps pour le moment donc je ne peux t'aider. Concernant la led de la caméra, c'est un truc qui selon moi dépend de ta webcam. Il e semble que sur la mienne (quickam pro 9000) je peux désactiver la led dans les préférences, mais dans ma précédente (quickam pro 3000) je ne pouvais pas.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
creale
Messages : 16
Inscription : sam. 29/janv./2011 14:33

Re: Enregistrement de flux provenant de ma webcam

Message par creale »

Merci de l'info,

Personne n'as d'idée concernant l'enregistrement d'un .avi ? lors d'une detection ?
Agence web https://www.atoneo.com
Bougie personnalisée https://www.bougie-personnalisee.fr
Fabrication bougie https://www.fabricant-bougie.fr
Avis externalisés https://satisfactions-clients.com
Ecommerçants Alsaciens https://www.alsazon.shop
idle
Messages : 63
Inscription : ven. 30/juil./2010 2:31

Re: Enregistrement de flux provenant de ma webcam

Message par idle »

voici une tête de fichier avi compleate, avec une détection de mouvement par moments
c'est de ne pas difficile d'enregistrer de la vidéo

Code : Tout sélectionner

;quick port from Ray Mercers VB stuff 
#WM_USER = $400
#WM_CAP_START = #WM_USER

#WM_CAP_GET_CAPSTREAMPTR = #WM_CAP_START + 1

#WM_CAP_SET_CALLBACK_ERROR = #WM_CAP_START + 2
#WM_CAP_SET_CALLBACK_STATUS = #WM_CAP_START + 3
#WM_CAP_SET_CALLBACK_YIELD = #WM_CAP_START + 4
#WM_CAP_SET_CALLBACK_FRAME = #WM_CAP_START + 5
#WM_CAP_SET_CALLBACK_VIDEOSTREAM = #WM_CAP_START + 6
#WM_CAP_SET_CALLBACK_WAVESTREAM = #WM_CAP_START + 7
#WM_CAP_GET_USER_DATA = #WM_CAP_START + 8
#WM_CAP_SET_USER_DATA = #WM_CAP_START + 9
    
#WM_CAP_DRIVER_CONNECT = #WM_CAP_START + 10
#WM_CAP_DRIVER_DISCONNECT = #WM_CAP_START + 11
#WM_CAP_DRIVER_GET_NAME = #WM_CAP_START + 12
#WM_CAP_DRIVER_GET_VERSION = #WM_CAP_START + 13
#WM_CAP_DRIVER_GET_CAPS = #WM_CAP_START + 14

#WM_CAP_FILE_SET_CAPTURE_FILE = #WM_CAP_START + 20
#WM_CAP_FILE_GET_CAPTURE_FILE = #WM_CAP_START + 21
#WM_CAP_FILE_ALLOCATE = #WM_CAP_START + 22
#WM_CAP_FILE_SAVEAS = #WM_CAP_START + 23
#WM_CAP_FILE_SET_INFOCHUNK = #WM_CAP_START + 24
#WM_CAP_FILE_SAVEDIB = #WM_CAP_START + 25

#WM_CAP_EDIT_COPY = #WM_CAP_START + 30

#WM_CAP_SET_AUDIOFORMAT = #WM_CAP_START + 35
#WM_CAP_GET_AUDIOFORMAT = #WM_CAP_START + 36

#WM_CAP_DLG_VIDEOFORMAT = #WM_CAP_START + 41
#WM_CAP_DLG_VIDEOSOURCE = #WM_CAP_START + 42
#WM_CAP_DLG_VIDEODISPLAY = #WM_CAP_START + 43
#WM_CAP_GET_VIDEOFORMAT = #WM_CAP_START + 44
#WM_CAP_SET_VIDEOFORMAT = #WM_CAP_START + 45
#WM_CAP_DLG_VIDEOCOMPRESSION = #WM_CAP_START + 46

#WM_CAP_SET_PREVIEW = #WM_CAP_START + 50
#WM_CAP_SET_OVERLAY = #WM_CAP_START + 51
#WM_CAP_SET_PREVIEWRATE = #WM_CAP_START + 52
#WM_CAP_SET_SCALE = #WM_CAP_START + 53
#WM_CAP_GET_STATUS = #WM_CAP_START + 54
#WM_CAP_SET_SCROLL = #WM_CAP_START + 55

#WM_CAP_GRAB_FRAME = #WM_CAP_START + 60
#WM_CAP_GRAB_FRAME_NOSTOP = #WM_CAP_START + 61

#WM_CAP_SEQUENCE = #WM_CAP_START + 62
#WM_CAP_SEQUENCE_NOFILE = #WM_CAP_START + 63
#WM_CAP_SET_SEQUENCE_SETUP = #WM_CAP_START + 64
#WM_CAP_GET_SEQUENCE_SETUP = #WM_CAP_START + 65
#WM_CAP_SET_MCI_DEVICE = #WM_CAP_START + 66
#WM_CAP_GET_MCI_DEVICE = #WM_CAP_START + 67
#WM_CAP_STOP = #WM_CAP_START + 68
#WM_CAP_ABORT = #WM_CAP_START + 69

#WM_CAP_SINGLE_FRAME_OPEN = #WM_CAP_START + 70
#WM_CAP_SINGLE_FRAME_CLOSE = #WM_CAP_START + 71
#WM_CAP_SINGLE_FRAME = #WM_CAP_START + 72

#WM_CAP_PAL_OPEN = #WM_CAP_START + 80
#WM_CAP_PAL_SAVE = #WM_CAP_START + 81
#WM_CAP_PAL_PASTE = #WM_CAP_START + 82
#WM_CAP_PAL_AUTOCREATE = #WM_CAP_START + 83
#WM_CAP_PAL_MANUALCREATE = #WM_CAP_START + 84

#WM_CAP_SET_CALLBACK_CAPCONTROL = #WM_CAP_START + 85
Global gkill

Structure VFWPOINT ;'strange name to avoid collision with other POINT UDTs
        x.i
        y.i
EndStructure

Structure CAPDRIVERCAPS
    wDeviceIndex.i                    ; Driver index in system.ini
    fHasOverlay.i                     ; Can device overlay?
    fHasDlgVideoSource.i              ; Has Video source dlg?
    fHasDlgVideoFormat.i              ; Has Format dlg?
    fHasDlgVideoDisplay.i             ; Has External out dlg?
    fCaptureInitialized.i             ; Driver ready to capture?
    fDriverSuppliesPalettes.i         ; Can driver make palettes?
    hVideoIn.i                        ; Driver In channel
    hVideoOut.i                       ; Driver Out channel
    hVideoExtIn.i                     ; Driver Ext In channel
    hVideoExtOut.i                    ; Driver Ext Out channel
EndStructure

Structure CAPSTATUS
    uiImageWidth.i                    ; Width of the image
    uiImageHeight.i                   ; Height of the image
    fLiveWindow.i                     ; Now Previewing video?
    fOverlayWindow.i                  ; Now Overlaying video?
    fScale.i                          ; Scale image to client?
    ptScroll.VFWPOINT                    ; Scroll position
    fUsingDefaultPalette.i            ; Using default driver palette?
    fAudioHardware.i                  ; Audio hardware present?
    fCapFileExists.i                  ; Does capture file exist?
    dwCurrentVideoFrame.i             ; # of video frames cap'td
    dwCurrentVideoFramesDropped.i     ; # of video frames dropped
    dwCurrentWaveSamples.i            ; # of wave samples cap'td
    dwCurrentTimeElapsedMS.i          ; Elapsed capture duration
    hPalCurrent.i                     ; Current palette in use
    fCapturingNow.i                   ; Capture in progress?
    dwReturn.i                        ; Error value after any operation
    wNumVideoAllocated.i              ; Actual number of video buffers
    wNumAudioAllocated.i              ; Actual number of audio buffers
EndStructure

#AVSTREAMMASTER_AUDIO = 0             ;; Audio master (VFW 1.0, 1.1) */
#AVSTREAMMASTER_NONE = 1              ;; No master */

Structure CAPTUREPARMS
    dwRequestMicroSecPerFrame.i       ; Requested capture rate
    fMakeUserHitOKToCapture.i         ; Show "Hit OK to cap" dlg?
    wPercentDropForError.i            ; Give error msg if > (10% default)
    fYield.i                          ; Capture via background task?
    dwIndexSize.i                     ; Max index size in frames (32K default)
    wChunkGranularity.i               ; Junk chunk granularity (2K default)
    fUsingDOSMemory.i                 ; Use DOS buffers? (obsolete)
    wNumVideoRequested.i              ; # video buffers, If 0, autocalc
    fCaptureAudio.i                   ; Capture audio?
    wNumAudioRequested.i              ; # audio buffers, If 0, autocalc
    vKeyAbort.i                       ; Virtual key causing abort
    fAbortLeftMouse.i                 ; Abort on left mouse?
    fAbortRightMouse.i                ; Abort on right mouse?
    fLimitEnabled.i                   ; Use wTimeLimit?
    wTimeLimit.i                      ; Seconds to capture
    fMCIControl.i                     ; Use MCI video source?
    fStepMCIDevice.i                  ; Step MCI device?
    dwMCIStartTime.i                  ; Time to start in MS
    dwMCIStopTime.i                   ; Time to stop in MS
    fStepCaptureAt2x.i                ; Perform spatial averaging 2x
    wStepCaptureAverageFrames.i       ; Temporal average n Frames
    dwAudioBufferSize.i               ; Size of audio bufs (0 = default)
    fDisableWriteCache.i              ; Attempt to disable write cache
    AVStreamMaster.i                  ; Which stream controls length?
EndStructure
                         

Structure CAPINFOCHUNK
    fccInfoID.i                       ; Chunk ID, "ICOP" for copyright
    lpData.i                          ; pointer to data
    cbData.i                          ; size of lpData
EndStructure

Structure VIDEOHDR
    lpData.i                          ; address of video buffer
    dwBufferLength.i                  ; size, in bytes, of the Data buffer
    dwBytesUsed.i                     ; see below
    dwTimeCaptured.i                  ; see below
    dwUser.i                          ; user-specific data
    dwFlags.i                         ; see below
    dwReserved.i[3]                   ; reserved; do not use
EndStructure

;Capture Procedure Declares
Import "avicap32.lib"
CapCreateCaptureWindow.i(name.s, style.i, x.i, y.i, width.i, height.i, hWndParent.i, nId.i) As "_capCreateCaptureWindowA@32"
CapGetDriverDescription.i(index.i, name.i, cbName.i, ver.i, cbVer.i) As "_capGetDriverDescriptionA@20"
EndImport

;======if the compiler can't find the lib use this and call close library at the end of your code 
; Prototype.i ProtCapCreateCaptureWindow(name.s, style.i, x.i, y.i, width.i, height.i, hWndParent.i, nId.i)
; Prototype.i ProtCapGetDriverDescription(index.i, name.i, cbName.i, ver.i, cbVer.i)
; 
; If OpenLibrary(0, "avicap32.dll")
;    Global CapCreateCaptureWindow.ProtCapCreateCaptureWindow = GetFunction(0, "capCreateCaptureWindowA")
;    Global CapGetDriverDescription.ProtCapGetDriverDescription = GetFunction(0, "capGetDriverDescriptionA")
; EndIf

;======================================================


; Import "msvfw32.lib"
;   GetOpenFileNamePreview.i(filestruct.OPENFILENAME) As "_GetOpenFileNamePreview"
;   GetSaveFileNamePreview.i(filestruct.OPENFILENAME) As "_GetSaveFileNamePreview"
; EndImport

; ------------------------------------------------------------------
; IDs for status and error callbacks
; ------------------------------------------------------------------

#IDS_CAP_BEGIN = 300              ; "Capture Start" */
#IDS_CAP_END = 301                ; "Capture End" */

#IDS_CAP_INFO = 401               ; "%s" */
#IDS_CAP_OUTOFMEM = 402           ; "Out of memory" */
#IDS_CAP_FILEEXISTS = 403         ; "File '%s' exists -- overwrite it?" */
#IDS_CAP_ERRORPALOPEN = 404       ; "Error opening palette '%s'" */
#IDS_CAP_ERRORPALSAVE = 405       ; "Error saving palette '%s'" */
#IDS_CAP_ERRORDIBSAVE = 406       ; "Error saving frame '%s'" */
#IDS_CAP_DEFAVIEXT = 407          ; "avi" */
#IDS_CAP_DEFPALEXT = 408          ; "pal" */
#IDS_CAP_CANTOPEN = 409           ; "Cannot open '%s'" */
#IDS_CAP_SEQ_MSGSTART = 410       ; "Select OK to start capture\nof video sequence\nto %s." */
#IDS_CAP_SEQ_MSGSTOP = 411        ; "Hit ESCAPE or click to end capture" */
                
#IDS_CAP_VIDEDITERR = 412         ; "An error occurred while trying to run VidEdit." */
#IDS_CAP_READONLYFILE = 413       ; "The file '%s' is a read-only file." */
#IDS_CAP_WRITEERROR = 414         ; "Unable to write to file '%s'.\nDisk may be full." */
#IDS_CAP_NODISKSPACE = 415        ; "There is no space to create a capture file on the specified device." */
#IDS_CAP_SETFILESIZE = 416        ; "Set File Size" */
#IDS_CAP_SAVEASPERCENT = 417      ; "SaveAs: %2ld%%  Hit Escape to abort." */
                
#IDS_CAP_DRIVER_ERROR = 418       ; Driver specific error message */

#IDS_CAP_WAVE_OPEN_ERROR = 419    ; "Error: Cannot open the wave input device.\nCheck sample size, frequency, and channels." */
#IDS_CAP_WAVE_ALLOC_ERROR = 420   ; "Error: Out of memory for wave buffers." */
#IDS_CAP_WAVE_PREPARE_ERROR = 421 ; "Error: Cannot prepare wave buffers." */
#IDS_CAP_WAVE_ADD_ERROR = 422     ; "Error: Cannot add wave buffers." */
#IDS_CAP_WAVE_SIZE_ERROR = 423    ; "Error: Bad wave size." */
                
#IDS_CAP_VIDEO_OPEN_ERROR = 424   ; "Error: Cannot open the video input device." */
#IDS_CAP_VIDEO_ALLOC_ERROR = 425  ; "Error: Out of memory for video buffers." */
#IDS_CAP_VIDEO_PREPARE_ERROR = 426 ; "Error: Cannot prepare video buffers." */
#IDS_CAP_VIDEO_ADD_ERROR = 427    ; "Error: Cannot add video buffers." */
#IDS_CAP_VIDEO_SIZE_ERROR = 428   ; "Error: Bad video size." */
                
#IDS_CAP_FILE_OPEN_ERROR = 429    ; "Error: Cannot open capture file." */
#IDS_CAP_FILE_WRITE_ERROR = 430   ; "Error: Cannot write to capture file.  Disk may be full." */
#IDS_CAP_RECORDING_ERROR = 431    ; "Error: Cannot write to capture file.  Data rate too high or disk full." */
#IDS_CAP_RECORDING_ERROR2 = 432   ; "Error while recording" */
#IDS_CAP_AVI_INIT_ERROR = 433     ; "Error: Unable to initialize for capture." */
#IDS_CAP_NO_FRAME_CAP_ERROR = 434 ; "Warning: No frames captured.\nConfirm that vertical sync interrupts\nare configured and enabled." */
#IDS_CAP_NO_PALETTE_WARN = 435    ; "Warning: Using default palette." */
#IDS_CAP_MCI_CONTROL_ERROR = 436  ; "Error: Unable to access MCI device." */
#IDS_CAP_MCI_CANT_STEP_ERROR = 437 ; "Error: Unable to step MCI device." */
#IDS_CAP_NO_AUDIO_CAP_ERROR = 438 ; "Error: No audio data captured.\nCheck audio card settings." */
#IDS_CAP_AVI_DRAWDIB_ERROR = 439  ; "Error: Unable to draw this data format." */
#IDS_CAP_COMPRESSOR_ERROR = 440   ; "Error: Unable to initialize compressor." */
#IDS_CAP_AUDIO_DROP_ERROR = 441   ; "Error: Audio data was lost during capture, reduce capture rate." */
                
; status string IDs */
#IDS_CAP_STAT_LIVE_MODE = 500      ; "Live window" */
#IDS_CAP_STAT_OVERLAY_MODE = 501   ; "Overlay window" */
#IDS_CAP_STAT_CAP_INIT = 502       ; "Setting up for capture - Please wait" */
#IDS_CAP_STAT_CAP_FINI = 503       ; "Finished capture, now writing frame %ld" */
#IDS_CAP_STAT_PALETTE_BUILD = 504  ; "Building palette map" */
#IDS_CAP_STAT_OPTPAL_BUILD = 505   ; "Computing optimal palette" */
#IDS_CAP_STAT_I_FRAMES = 506       ; "%d frames" */
#IDS_CAP_STAT_L_FRAMES = 507       ; "%ld frames" */
#IDS_CAP_STAT_CAP_L_FRAMES = 508   ; "Captured %ld frames" */
#IDS_CAP_STAT_CAP_AUDIO = 509      ; "Capturing audio" */
#IDS_CAP_STAT_VIDEOCURRENT = 510   ; "Captured %ld frames (%ld dropped) %d.%03d sec." */
#IDS_CAP_STAT_VIDEOAUDIO = 511     ; "Captured %d.%03d sec.  %ld frames (%ld dropped) (%d.%03d fps).  %ld audio bytes (%d,%03d sps)" */
#IDS_CAP_STAT_VIDEOONLY = 512      ; "Captured %d.%03d sec.  %ld frames (%ld dropped) (%d.%03d fps)" */

;Translations of C- "Message Cracker" Macros to VB (declared in vfw.h)

Procedure capSetCallbackOnError(hCapWnd.i,lpProc.i) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_SET_CALLBACK_ERROR,0,lpProc)
EndProcedure
Procedure capSetCallbackOnStatus(hCapWnd.i,lpProc.i) 
    ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_SET_CALLBACK_STATUS, 0, lpProc)
EndProcedure
Procedure capSetCallbackOnYield( hCapWnd.i,  lpProc.i) 
    ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_SET_CALLBACK_YIELD, 0, lpProc)
EndProcedure
Procedure capSetCallbackOnFrame( hCapWnd.i,  lpProc.i) 
    ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_SET_CALLBACK_FRAME, 0, lpProc)
EndProcedure
Procedure capSetCallbackOnVideoStream( hCapWnd.i,  lpProc.i) 
    ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, lpProc)
EndProcedure
Procedure capSetCallbackOnWaveStream( hCapWnd.i,  lpProc.i) 
    ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_SET_CALLBACK_WAVESTREAM, 0, lpProc)
EndProcedure
Procedure capSetCallbackOnCapControl( hCapWnd.i,  lpProc.i) 
    ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_SET_CALLBACK_CAPCONTROL, 0, lpProc)
EndProcedure
Procedure capSetUserData( hCapWnd.i,  lUser.i) 
    ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_SET_USER_DATA, 0, lUser)
EndProcedure
Procedure capGetUserData( hCapWnd.i)
    ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_GET_USER_DATA, 0, 0)
EndProcedure
Procedure capDriverConnect( hCapWnd.i,i.i=0) 
    ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_DRIVER_CONNECT, i, 0)
EndProcedure
Procedure capDriverDisconnect( hCapWnd.i) 
    ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_DRIVER_DISCONNECT, 0, 0)
EndProcedure
Procedure.s capDriverGetName(hCapWnd.i)
   szBuffer.s = Space(128)
   SendMessage_(hCapWnd, #WM_CAP_DRIVER_GET_NAME, 128, @szBuffer)
   ProcedureReturn szBuffer
EndProcedure
Procedure.s capDriverGetVersion(hCapWnd.i)
   szBuffer.s = Space(128)
   retVal = SendMessage_(hCapWnd, #WM_CAP_DRIVER_GET_VERSION, 128, @szBuffer)
   ProcedureReturn szbuffer 
EndProcedure
Procedure capDriverGetCaps(hCapWnd.i,*lpCaps) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_DRIVER_GET_CAPS,SizeOf(CAPDRIVERCAPS), *lpCaps)
EndProcedure
Procedure capFileSetCaptureFile(hCapWnd.i,FilePath.s) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_FILE_SET_CAPTURE_FILE,0,@FilePath)
EndProcedure
Procedure.s capFileGetCaptureFile(hCapWnd.i) 
   szBuffer.s = Space(128)
   SendMessage_(hCapWnd, #WM_CAP_FILE_GET_CAPTURE_FILE, 128, @szBuffer)
   ProcedureReturn szBuffer
EndProcedure
Procedure capFileAlloc(hCapWnd.i,dwSize.i) 
   ProcedureReturn  SendMessage_(hCapWnd, #WM_CAP_FILE_ALLOCATE, 0, dwSize)
EndProcedure
Procedure capFileSaveAs(hCapWnd.i,FilePath.s) 
   ProcedureReturn SendMessage_(hCapWnd,#WM_CAP_FILE_SAVEAS, 0, @FilePath)
EndProcedure
Procedure capFileSetInfoChunk(hCapWnd.i,*InfChunk.CAPINFOCHUNK) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_FILE_SET_INFOCHUNK, 0, *InfChunk)
EndProcedure
Procedure capFileSaveDIB(hCapWnd.i,FilePath.s) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_FILE_SAVEDIB, 0, @FilePath)
EndProcedure
Procedure capEditCopy( hCapWnd.i) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_EDIT_COPY, 0, 0)
EndProcedure
Procedure capSetAudioFormat(hCapWnd.i, *wavFormat.WAVEFORMATEX,  WavFormatSize.i) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_SET_AUDIOFORMAT, WavFormatSize, *wavFormat)
EndProcedure
Procedure capSetAudioFormatAsArray(hCapWnd.i, *wavFormat, WavFormatSize.i) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_SET_AUDIOFORMAT, WavFormatSize, *wavFormat)
EndProcedure
Procedure capGetAudioFormat( hCapWnd.i, *wavFormat.WAVEFORMATEX,  WavFormatSize.i)
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_GET_AUDIOFORMAT, WavFormatSize, *wavFormat)
EndProcedure
Procedure capGetAudioFormatAsArray( hCapWnd.i,  *wavFormat,  WavFormatSize.i)
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_GET_AUDIOFORMAT,WavFormatSize, *wavFormat)
EndProcedure
Procedure capGetAudioFormatSize(hCapWnd.i)
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_GET_AUDIOFORMAT, 0, 0)
EndProcedure
Procedure capDlgVideoFormat(hCapWnd.i) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_DLG_VIDEOFORMAT, 0, 0)
EndProcedure
Procedure capDlgVideoSource(hCapWnd.i) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_DLG_VIDEOSOURCE, 0, 0)
EndProcedure
Procedure capDlgVideoDisplay(hCapWnd.i) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_DLG_VIDEODISPLAY, 0, 0)
EndProcedure
Procedure capDlgVideoCompression( hCapWnd.i) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_DLG_VIDEOCOMPRESSION, 0, 0)
EndProcedure
Procedure capGetVideoFormat(hCapWnd.i, *BmpFormat.BITMAPINFO,  CapFormatSize.i)
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_GET_VIDEOFORMAT, CapFormatSize, *BmpFormat)
EndProcedure
Procedure capGetVideoFormatSize(hCapWnd.i, *BmpFormat.BITMAPINFO,  CapFormatSize.i) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_GET_VIDEOFORMAT, CapFormatSize, *BmpFormat)
EndProcedure
Procedure capSetVideoFormat( hCapWnd.i, *BmpFormat.BITMAPINFO,  CapFormatSize.i) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_SET_VIDEOFORMAT, CapFormatSize, *BmpFormat)
EndProcedure
Procedure capPreview(hCapWnd.i,true) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_SET_PREVIEW,true,0) ;'convert the VB Boolean to a C BOOL with the - sign
EndProcedure
Procedure capPreviewRate( hCapWnd.i, wMS.i) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_SET_PREVIEWRATE, wMS, 0)
EndProcedure
Procedure capOverlay( hCapWnd.i,true) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_SET_OVERLAY,true, 0)
EndProcedure
Procedure capPreviewScale(hCapWnd.i,true) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_SET_SCALE,true, 0)
EndProcedure
Procedure capGetStatus(hCapWnd.i,*capStat.CAPSTATUS) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_GET_STATUS, SizeOf(capstatus), *capStat)
EndProcedure
Procedure capSetScrollPos(hCapWnd.i,*pt.VFWPOINT) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_SET_SCROLL, 0, *pt)
EndProcedure
Procedure capGrabFrame(hCapWnd.i) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_GRAB_FRAME, 0, 0)
EndProcedure
Procedure capGrabFrameNoStop( hCapWnd.i) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_GRAB_FRAME_NOSTOP, 0, 0)
EndProcedure
Procedure capCaptureSequence( hCapWnd.i) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_SEQUENCE, 0, 0)
EndProcedure
Procedure capCaptureSequenceNoFile( hCapWnd.i) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_SEQUENCE_NOFILE, 0, 0)
EndProcedure
Procedure capCaptureStop( hCapWnd.i) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_STOP, 0, 0)
EndProcedure
Procedure capCaptureAbort( hCapWnd.i) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_ABORT, 0, 0)
EndProcedure
Procedure capCaptureSingleFrameOpen( hCapWnd.i) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_SINGLE_FRAME_OPEN, 0, 0)
EndProcedure
Procedure capCaptureSingleFrameClose( hCapWnd.i) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_SINGLE_FRAME_CLOSE, 0, 0)
EndProcedure
Procedure capCaptureSingleFrame( hCapWnd.i) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_SINGLE_FRAME, 0, 0)
EndProcedure
Procedure capCaptureGetSetup( hCapWnd.i, *capParms.CAPTUREPARMS) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_GET_SEQUENCE_SETUP, SizeOf(CAPTUREPARMS), *capParms)
EndProcedure
Procedure capCaptureSetSetup( hCapWnd.i, *capParms.CAPTUREPARMS) 
    ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_SET_SEQUENCE_SETUP, SizeOf(CAPTUREPARMS), *capParms)
EndProcedure
Procedure capSetMCIDeviceName( hCapWnd.i,DeviceName.s) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_SET_MCI_DEVICE, 0, @DeviceName)
EndProcedure
Procedure.s capGetMCIDeviceName( hCapWnd.i)
   szBuffer.s = Space(128)
   SendMessage_(hCapWnd, #WM_CAP_GET_MCI_DEVICE, dwSize, @szBuffer)
   ProcedureReturn szBuffer
EndProcedure
Procedure capPaletteOpen(hCapWnd.i,FilePath.s) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_PAL_OPEN, 0, @FilePath)
EndProcedure
Procedure capPaletteSave( hCapWnd.i,FilePath.s) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_PAL_SAVE, 0, @FilePath)
EndProcedure
Procedure capPalettePaste( hCapWnd.i) 
   ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_PAL_PASTE, 0, 0)
EndProcedure
Procedure capPaletteAuto( hCapWnd.i,  iFrames.i,  iColors.i) 
   If iColors > 256
     ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_PAL_AUTOCREATE, iFrames, iColors)
   Else 
     ProcedureReturn 0
   EndIf   
EndProcedure
Procedure capPaletteManual(hCapWnd.i,true,iColors.i) 
   If iColors > 256
      ProcedureReturn SendMessage_(hCapWnd, #WM_CAP_PAL_MANUALCREATE, true, iColors)
   Else 
     ProcedureReturn 0
   EndIf     
EndProcedure

;motion stuff=============================================================

Global lz.f,lx.f,ly.f,t,sWidth,sHeight,sw12,sh12,t,fw,fh,img1,gsx,gsy,gsz.f
Global *appCallback,img1,mwind

Procedure SetAppCallBack(*mappCallback)
  *appCallback = *mappCallback  
EndProcedure
Procedure SetFrameCallbackSize(*bmp.BITMAPINFO,UserWidth=0,UserHeight=0)

If UserWidth = 0
  ExamineDesktops()
  sw12 = DesktopWidth(0)/2
  sh12 = DesktopHeight(0)/2
Else 
  sw12 = UserWidth/2
  sh12 = UserHeight/2
EndIf 

fW = *bmp\bmiheader\biWidth 
FH = *bmp\bmiheader\biHeight

gsx = sw12 / (fw/3)
gsy = sh12 / (fh/3)
gsz = 0.1

;img1 = CreateImage(#PB_Any,fw,fh)

EndProcedure

Procedure FrameCallBack(hCapWnd,*vid.VIDEOHDR):
*px.long=*vid\lpdata

;motion detection uses averages of pixel color masses centroids  
;returns coordinates relative to desktop or dimentions  

Dim sumx.f(255)
Dim sumy.f(255) 
Dim area.f(255)
Static Dim scx.i(12)
Static Dim scy.i(12)
Static Dim scz.i(12)

Static dx.f,dy.f,ldtx,ldty,lcy,ct,dz.f,ldz.f,bsend,ct1 
Protected sxx.f
Protected syy.f
Protected szz.f
Protected aa.f
    
  StartDrawing(ImageOutput(img1))
  For y = fh - 1 To 0 Step -1
    For x = 0 To fw - 1
      
      c=(*px\l & $FF )
      sumx(c)+x*c:
      sumy(c)+y*c:
      area(c)+c
      r = (*px\l >> 16) & $ff 
      g = (*px\l >> 8) & $ff
      b = c
      If x > 0 And x < ImageWidth(img1) And y > 0 And y < ImageHeight(img1)
        Plot(x,y,RGB(r,g,b)) 
      EndIf   
      *px+3:
      
    Next
  Next
  
  cc=1                  
  For cc =0 To 150 ;not looking at pixels > 150 
   If area(cc) <> 0
    sxx + (sumx(cc)/area(cc))  
    syy + (sumy(cc)/area(cc))
    aa+1
    szz + area(cc)
   EndIf  
  Next 
  
  sxx / aa
  syy / aa    
  szz / aa  
  If t>20:  ;wait for the camera to adjust brightness
    dx.f=((sxx)-lx)*gsx 
    dy.f=((syy)-ly)*gsy  
    dz.f=((szz)-lz)*gsz
    lx = sxx
    ly = syy 
    lz = szz
  Else:
    lx= sxx
    ly= syy
    lz= szz
    t+1:
  EndIf
  sw12-dx  
  sh12+dy
  sz12-dz  
  scx(ct)=sw12
  scy(ct)=sh12 
  scz(ct)+sz12
  ct+1 
  
  If ct = 11 
    bsend = 1 
  EndIf   
  ct % 11
  For a = 0 To 11 
    sumx + scx(a)
    sumy + scy(a)
    sumz + scz(a)
  Next 
  spx.f = sumx /12
  spy.f = sumy /12   
  spz.f = sumz /12
  Circle(spx/gsx,spy/gsy,spz,RGB(0,255,0))
  StopDrawing()
  If bsend    
  
  If *appCallback
    CallFunctionFast(*appCallback,spx,spy,spz)
  EndIf 
  
  EndIf 
  
EndProcedure

Procedure CapBackground(hCapWnd)
  
  capCaptureSingleFrameOpen(hCapWnd)
  Repeat 
    capCaptureSingleFrame(hCapWnd)
    Delay(20)
  Until gkill 
  capCaptureSingleFrameClose(hCapWnd)
EndProcedure

Procedure ConnectCapDriver(hCapWnd,nDriverIndex,visible)
         
   retVal = capDriverConnect(hCapWnd, nDriverIndex)
   If Not retVal
     ProcedureReturn 0
   EndIf
   
   If Visible 
      capPreviewRate(hCapWnd,20) ;'15 FPS
      capPreview(hCapWnd, #True)
      
   Else 
     CreateThread(@CapBackground(),hCapWnd)     
   EndIf    
   ProcedureReturn 1
EndProcedure

Procedure StatusProc(hCapWnd,StatusCode,lpStatusString)
  Select StatusCode
     Case 0 
     Case #IDS_CAP_END 
                
     Case #IDS_CAP_STAT_VIDEOAUDIO , #IDS_CAP_STAT_VIDEOONLY
           MessageRequester("Capture Status", PeekS(lpStatusString))
     Default 
           Debug PeekS(lpStatusString)
  EndSelect
  Debug "Driver returned code " + Str(StatusCode) + " to StatusProc"
  ProcedureReturn  1
EndProcedure 

Procedure CapDestroy(hCapWnd)
  gkill =1
  capCaptureStop(hCapWnd)
  capDriverDisconnect(hCapWnd)
  DestroyWindow_(hCapWnd)
EndProcedure

Procedure Cap(win,flags,visible,*FrameCallback,*appcallback=0,UserWidth=0,UserHeight=0,capWidth=0,capHeight=0)
  
  #USECALLBACKS = 0 
 lpszName.s = Space(128)
 lpszVer.s = Space(128)
 CapGetDriverDescription(0,@lpszName,128,@lpszVer,128)
 Debug lpszName
 Debug lpszVer 
 If IsWindow(win)
   id = WindowID(win)
   If visible 
     twidth = WindowWidth(win)
     theight = WindowHeight(win)
   Else 
     twidth = 1
     theight = 1
   EndIf    
  Else 
   id =0 
   twidth = 1
   theight = 1
 EndIf    
    
 hCapWnd = capCreateCaptureWindow("", flags, 0, 0, twidth,theight,id,0)
 If hCapWnd
    retVal = ConnectCapDriver(hCapWnd,0,visible)
    bmp.BITMAPINFO
    
    If capGetVideoFormatSize(hCapWnd,@bmp,SizeOf(BITMAPINFO))
       If bmp\bmiHeader\biWidth <> capWidth 
          capDlgVideoFormat(hcapwnd) 
          capGetVideoFormatSize(hCapWnd,@bmp,SizeOf(BITMAPINFO))
       EndIf 
       SetFrameCallbackSize(@bmp,UserWidth,UserHeight)
       
       Debug bmp\bmiHeader\biWidth
       Debug bmp\bmiHeader\biHeight 
    
    EndIf   
    
    If retVal 
      If #USECALLBACKS = 1 
         capSetCallbackOnStatus(hCapWnd, @StatusProc())
            Debug "---Callback set on capture status---"
        EndIf
    EndIf
    If *appcallback
       SetAppCallBack(*appcallback)
    EndIf 
    If *FrameCallback
       capSetCallbackOnFrame(hCapWnd, *FrameCallback)
    EndIf 
 EndIf 
 
 ProcedureReturn hCapWnd 
    
EndProcedure 

;=======================================================================

Structure MotionConfig 
   userWidth.i       ;window width if not native monitor size  
   userHeight.i      ;windoscreen height if not native monitor size
   visible.i         ;show preview window 
   *AppCallback.i      ;call back for x and y coordinates 
   *CaptureWindow.i    ;So you can send a #wm_close message
   *Parent.i           ;parent window  
   closeKey.i        ;#VK_ESCAPE for testing to quit the camera
   capWidth.i
   capHeight.i 
EndStructure 
  
Procedure destroy(hCapWnd)
 CapDestroy(hCapWnd)
EndProcedure

Procedure MotionCap(*config.MotionConfig) 

If *config\visible 
    flags = $50000000
Else 
    flags = #WS_EX_TOPMOST | #PB_Window_BorderLess | #PB_Window_Invisible 
EndIf 

hwnd = *config\parent 
hCapWnd = Cap(hwnd,flags,*config\visible,@FrameCallBack(),*config\AppCallback,*config\UserWidth,*config\UserHeight,*config\capWidth,*config\capHeight);

SetForegroundWindow_(WindowID(hwnd))

Repeat

Until WaitWindowEvent()=#WM_CLOSE  Or GetAsyncKeyState_(*config\closekey)&$1  
 
CapDestroy(hCapWnd)

EndProcedure

;usage 

;specify a call back in you app to recieve the coordinates 

Procedure AppCallBack(x.f,y.f,z.f)
   ;whatever 
   xx= Int(x)
   yy= Int(y)
   SetCursorPos_(x,y)
   Debug z 
   PostMessage_(WindowID(mwind),#WM_USER +1,0,0)
EndProcedure

;Declare the config 
mconfig.MotionConfig

mwind = OpenWindow(#PB_Any,0,0,160,120,"test",#PB_Window_SystemMenu) 
img1 = CreateImage(#PB_Any,160,120)
ImageGadget(0,0,0,160,120,ImageID(img1))

mconfig\userwidth = 1440   ;the screen size your using if not fullscreed 
mconfig\userheight = 900
mconfig\AppCallBack = @AppCallBack()
mconfig\closekey = #VK_ESCAPE    ;key to quit the capture 
mconfig\parent = mwind
mconfig\visible=0   ;will display the window 
mconfig\capWidth = 320  ;prefered capture width 
mconfig\capHeight =240
CreateThread(@MotionCap(),@mconfig)  ;create thread 

;rest of your app  
Repeat

ev = WaitWindowEvent()
If ev = #WM_USER+1
  SetGadgetState(0,ImageID(img1))
  FreeImage(img1)
  img1 = CreateImage(#PB_Any,160,120)

EndIf   

Until ev=#WM_CLOSE 
CapDestroy(hCapWnd)
Répondre