Page 1 of 1

Video Application

Posted: Thu Nov 07, 2013 7:17 am
by rdonnay
Here is a sample application that uses the VideoCapX ActiveX control.

I have a customer application (written in Xbase++) that controls the world's most sensitive metal detector.
The Xbase++ app communicates with 2 microprocessors via IP to control scanning the user's access card, reading the electric field of the arch, opening the door, displaying graphs and charts, etc.

What it didn't do (until now) is capture a video of persons entering the arch.
Here's the test code. Now I only need to add it to the application. Works great!!!

Code: Select all

#INCLUDE "dcdialog.CH"
#INCLUDE "videocapx.CH"

FUNCTION Main()

LOCAL GetList[0], oVideo1, oVideo2, GetOptions, oTimer

PUBLIC oVideo

@ 0,0 DCACTIVEXCONTROL oVideo1 ;
      CLSID 'VIDEOCAPX.VideoCapXCtrl.1' SIZE 300,300 PIXEL ;

@ 330, 0 DCPUSHBUTTON CAPTION 'Start Capture' SIZE 100,22 PIXEL ;
      ACTION {||oVideo1:capFileName := '.\Camera1\' + Dtos(Date())+'_'+Strtran(Time(),':','-')+'.Avi', ;
                oVideo1:startCapture()}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'End Capture' SIZE 100,22 PIXEL ;
      ACTION {||oVideo1:stopCapture()}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'SnapShot' SIZE 100,22 PIXEL ;
      ACTION {|x,c,o,b|oVideo1:CopyFrame(), ;
                       b := GetBitmapFromClipboard(), ;
                       b:saveFile(GetFileName('.\Camera1\','.jpg'),XBPBMP_FORMAT_JPG)}


@ 360,0 DCACTIVEXCONTROL oVideo2 ;
      CLSID 'VIDEOCAPX.VideoCapXCtrl.1' SIZE 300,300 PIXEL ;

@ 700, 0 DCPUSHBUTTON CAPTION 'Start Capture' SIZE 100,22 PIXEL ;
      ACTION {||oVideo2:capFileName := GetFileName('.\Camera2\','.Avi'), ;
                oVideo2:startCapture()}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'End Capture' SIZE 100,22 PIXEL ;
      ACTION {||oVideo2:stopCapture()}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'SnapShot' SIZE 100,22 PIXEL ;
      ACTION {|x,c,o,b|oVideo2:CopyFrame(), ;
                       b := GetBitmapFromClipboard(), ;
                       b:saveFile(GetFileName('.\Camera2\','.jpg'),XBPBMP_FORMAT_JPG)}


DCGETOPTIONS RESIZE RESIZEDEFAULT DCGUI_RESIZE_AUTORESIZE

DCREAD GUI FIT TITLE 'VideoCapX Sample Program' ;
   OPTIONS GetOptions ;
   EVAL {|o|oVideo2:DebugMode := 1, ;
            oVideo2:UseVideoFilter := vcxBoth, ;
            oVideo2:PreviewAudio := .f., ;
            oVideo2:VideoDeviceIndex := 1, ;
            oVideo2:Connected := .t., ;
            oVideo2:Preview := .t., ;
            oVideo1:DebugMode := 1, ;
            oVideo1:UseVideoFilter := vcxBoth, ;
            oVideo1:PreviewAudio := .f., ;
            oVideo1:VideoDeviceIndex := 0, ;
            oVideo1:Connected := .t., ;
            oVideo1:Preview := .t., ;
            M->oVideo := oVideo1, ;
            oTimer := DC_SetTimerEvent():new(100,{||CheckForMotion(oVideo1,oVideo2)}), ;
            nil }

oTimer:destroy()

RETURN nil

* ---------

PROC appsys ; RETURN

* ---------

STATIC FUNCTION GetFileName( cPath, cExt )

RETURN cPath + Dtos(Date())+'_'+Strtran(Time(),':','-') + cExt

* ---------

STATIC FUNCTION CheckForMotion( oVideo1, oVideo2 )

IF oVideo1:isCapturing .AND. oVideo1:DetectMotion() < 3
  oVideo1:stopCapture()
  DC_SpawnUrl(oVideo1:capFileName)
ELSEIF !oVideo1:isCapturing .AND. oVideo1:DetectMotion() >= 5
  oVideo1:capFileName := GetFileName('.\Camera1\','.Avi')
  oVideo1:startCapture()
ENDIF

IF oVideo2:isCapturing .AND. oVideo2:DetectMotion() < 3
  oVideo2:stopCapture()
  DC_SpawnUrl(oVideo2:capFileName)
ELSEIF !oVideo2:isCapturing .AND. oVideo2:DetectMotion() >= 5
  oVideo2:capFileName := GetFileName('.\Camera2\','.Avi')
  oVideo2:startCapture()
ENDIF

RETURN nil

* ------------

STATIC FUNCTION GetBitmapFromClipBoard()

LOCAL oClipBoard, oBitmap

oClipBoard := XbpClipBoard():new():create()
oClipBoard:open()
oBitMap := oClipBoard:getBuffer( XBPCLPBRD_BITMAP )
oClipBoard:close()

RETURN oBitmap

Re: Video Application

Posted: Thu Nov 07, 2013 1:49 pm
by digitsoft
rdonnay wrote:Here is a sample application that uses the VideoCapX ActiveX control.
Hi Roger
Error Automation/6500
description: Could not create ActiveX control
Thread ID: 1
Called Frim DC_XBPACTIVEXCONTROL:CREATE(5979)
Called Frim DC_GETLIST:CREATEOBJECT(12030)
Called Frim DC_GETLIST:READGUI(2294)
Called Frim DC_READGUI(109)
Called Frim MAIN(60)




I have a customer application (written in Xbase++) that controls the world's most sensitive metal detector.
The Xbase++ app communicates with 2 microprocessors via IP to control scanning the user's access card, reading the electric field of the arch, opening the door, displaying graphs and charts, etc.

What it didn't do (until now) is capture a video of persons entering the arch.
Here's the test code. Now I only need to add it to the application. Works great!!!

Code: Select all

#INCLUDE "dcdialog.CH"
#INCLUDE "videocapx.CH"

FUNCTION Main()

LOCAL GetList[0], oVideo1, oVideo2, GetOptions, oTimer

PUBLIC oVideo

@ 0,0 DCACTIVEXCONTROL oVideo1 ;
      CLSID 'VIDEOCAPX.VideoCapXCtrl.1' SIZE 300,300 PIXEL ;

@ 330, 0 DCPUSHBUTTON CAPTION 'Start Capture' SIZE 100,22 PIXEL ;
      ACTION {||oVideo1:capFileName := '.\Camera1\' + Dtos(Date())+'_'+Strtran(Time(),':','-')+'.Avi', ;
                oVideo1:startCapture()}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'End Capture' SIZE 100,22 PIXEL ;
      ACTION {||oVideo1:stopCapture()}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'SnapShot' SIZE 100,22 PIXEL ;
      ACTION {|x,c,o,b|oVideo1:CopyFrame(), ;
                       b := GetBitmapFromClipboard(), ;
                       b:saveFile(GetFileName('.\Camera1\','.jpg'),XBPBMP_FORMAT_JPG)}


@ 360,0 DCACTIVEXCONTROL oVideo2 ;
      CLSID 'VIDEOCAPX.VideoCapXCtrl.1' SIZE 300,300 PIXEL ;

@ 700, 0 DCPUSHBUTTON CAPTION 'Start Capture' SIZE 100,22 PIXEL ;
      ACTION {||oVideo2:capFileName := GetFileName('.\Camera2\','.Avi'), ;
                oVideo2:startCapture()}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'End Capture' SIZE 100,22 PIXEL ;
      ACTION {||oVideo2:stopCapture()}

@ DCGUI_ROW, DCGUI_COL + 20 DCPUSHBUTTON CAPTION 'SnapShot' SIZE 100,22 PIXEL ;
      ACTION {|x,c,o,b|oVideo2:CopyFrame(), ;
                       b := GetBitmapFromClipboard(), ;
                       b:saveFile(GetFileName('.\Camera2\','.jpg'),XBPBMP_FORMAT_JPG)}


DCGETOPTIONS RESIZE RESIZEDEFAULT DCGUI_RESIZE_AUTORESIZE

DCREAD GUI FIT TITLE 'VideoCapX Sample Program' ;
   OPTIONS GetOptions ;
   EVAL {|o|oVideo2:DebugMode := 1, ;
            oVideo2:UseVideoFilter := vcxBoth, ;
            oVideo2:PreviewAudio := .f., ;
            oVideo2:VideoDeviceIndex := 1, ;
            oVideo2:Connected := .t., ;
            oVideo2:Preview := .t., ;
            oVideo1:DebugMode := 1, ;
            oVideo1:UseVideoFilter := vcxBoth, ;
            oVideo1:PreviewAudio := .f., ;
            oVideo1:VideoDeviceIndex := 0, ;
            oVideo1:Connected := .t., ;
            oVideo1:Preview := .t., ;
            M->oVideo := oVideo1, ;
            oTimer := DC_SetTimerEvent():new(100,{||CheckForMotion(oVideo1,oVideo2)}), ;
            nil }

oTimer:destroy()

RETURN nil

* ---------

PROC appsys ; RETURN

* ---------

STATIC FUNCTION GetFileName( cPath, cExt )

RETURN cPath + Dtos(Date())+'_'+Strtran(Time(),':','-') + cExt

* ---------

STATIC FUNCTION CheckForMotion( oVideo1, oVideo2 )

IF oVideo1:isCapturing .AND. oVideo1:DetectMotion() < 3
  oVideo1:stopCapture()
  DC_SpawnUrl(oVideo1:capFileName)
ELSEIF !oVideo1:isCapturing .AND. oVideo1:DetectMotion() >= 5
  oVideo1:capFileName := GetFileName('.\Camera1\','.Avi')
  oVideo1:startCapture()
ENDIF

IF oVideo2:isCapturing .AND. oVideo2:DetectMotion() < 3
  oVideo2:stopCapture()
  DC_SpawnUrl(oVideo2:capFileName)
ELSEIF !oVideo2:isCapturing .AND. oVideo2:DetectMotion() >= 5
  oVideo2:capFileName := GetFileName('.\Camera2\','.Avi')
  oVideo2:startCapture()
ENDIF

RETURN nil

* ------------

STATIC FUNCTION GetBitmapFromClipBoard()

LOCAL oClipBoard, oBitmap

oClipBoard := XbpClipBoard():new():create()
oClipBoard:open()
oBitMap := oClipBoard:getBuffer( XBPCLPBRD_BITMAP )
oClipBoard:close()

RETURN oBitmap

Re: Video Application

Posted: Thu Nov 07, 2013 3:57 pm
by rdonnay
You need to download and install the VideoCapX 30-day trial.

http://www.fathsoft.com/vctsetup.exe

Re: Video Application

Posted: Thu Nov 07, 2013 5:55 pm
by Auge_Ohr
rdonnay wrote:What it didn't do (until now) is capture a video of persons entering the arch.
when using WebCam from Notebook you can access WM_CAP*** Event with ot4xb to capture Picture.
***http://msdn.microsoft.com/en-us/library ... S.85).aspx

more Info @ Pablos Website http://www.xbwin.com -> Forum

Who can help ?
ot4xb.public
28. April 2012
Jack Duijf

read Thread and see Attachments while there are 3 Solution.
here is my Version NEED ot4xb to compile !
WebCam.zip
Source NEED ot4xb
(245.87 KiB) Downloaded 650 times

Re: Video Application

Posted: Thu Nov 07, 2013 8:23 pm
by rdonnay
when using WebCam from Notebook you can access WM_CAP*** Event with ot4xb to capture Picture.
This is an eXpress++ forum.
It is intended to help eXpress++ users learn how to do new things in eXpress++, not ot4xb.

Re: Video Application

Posted: Thu Nov 07, 2013 11:28 pm
by Auge_Ohr
rdonnay wrote:This is an eXpress++ forum.
It is intended to help eXpress++ users learn how to do new things in eXpress++, not ot4xb.
Yes ...
but Xbase++ is so limited without ot4xb in Windows World where you have all those DLL already
on your PC when install WDM Hardware and do not need to buy external activeX.

when you disable ONE line with ot4xb in my Demo Code it still work while it is pure Xbase++.
Jack Duijf had ask in Pablos Forum why he have to "move Mouse" to get Picture move ... hm.
he had reach limit of Xbase++ with his Code and only Solution was ot4xb

Code: Select all

    ::hHwnd := delegated_eval( {|| capCreateCaptureWindowA("CapWindow",;
                                       dwStyle               ,;
                                       0, 0, nWidth, nHeight ,;
                                       ::oStatic:getHWND()   ,;
                                       0 ) } )
so my Intend was to show what can be done if someone got in similar Situation when try to capture Video / Picture.

Re: Video Application

Posted: Fri Nov 08, 2013 5:39 am
by rdonnay
This application had a requirement to show 2 video windows, (1 for each camera), and to capture the video to a file whenever there was motion detected. The ActiveX control that provides this capability costs $99 and easily integrates with Xbase++. eXpress++ developers do not consider a $99 expense to be excessive. They consider their time to be valuable and this takes almost none of their time. This is a nice "black box" solution. This control provides another 10 features that will be easily integrated into the application with a few lines of code.
Your solution would require that they learn a lot more new stuff. You still don't get it. Every time I post a solution to a problem using eXpress++, you followup with a posting about a solution that is more complicated and will consume more time.

I will remind you again that this forum is for eXpress++ users, NOT ot4xb.

If you really want to support eXpress++ users, then provide some source code that shows how to do this using the eXpress++ method. Make a screen using DC* commands and embed a video control using ot4xb. If you cannot do this then you are not helping.

Re: Video Application

Posted: Fri Nov 08, 2013 7:03 am
by unixkd
Thanks so much Roger.

You spoke my mind. Alaska added ActiveX support to Xbase++ because they know that will improve productivity immensely. Express++ developers have goals viz: productivity, maintainabily, robustness, reliability, functionality etc. and calling windows API achieve non of these goals. The learning curve for WIN API is very steep, I can tell you that. Majority of Express++ programmers we former clipper programmers without sound knowledge of C/C++ and Assembly languages. Roger understand this very perfectly if you study his wonderful approach to Express++.

ActiveX components extend Xbase++ functionalities and I will not waste my time creating those functionalities if I can buy them right away.

Roger Kudos to you !!!

Joe.

Re: Video Application

Posted: Fri Nov 08, 2013 9:38 pm
by Auge_Ohr
rdonnay wrote:If you really want to support eXpress++ users, then provide some source code that shows how to do this using the eXpress++ method. Make a screen using DC* commands and embed a video control using ot4xb.
as you know i do not use Express++ only "pure" Xbase++ Class Code that every Express++ User can use.

to "that" one line of ot4xb Code, which you have used with Express++ / Codejock in FUNCTION CJ_SetAppFocus()

Code: Select all

  nDllHandle := DllLoad('ot4xb.dll')
  IF nDllHandle > 0
    &("Delegated_Eval")( {|| &("nFpCall")( {"user32","SetFocus"} , nHandle ) } )
  ELSE
    DC_WinAlert('CJ_SetAppFocus() requires ot4xb.dll')
  ENDIF
how can i write it better Code than you did already.

but back to Question as you say you have NOT try capture Picture from Stream : is it possible with that activeX ?

Xbase++ activeX are running in GUI Thread and i do had Problem with WMP > 9 to capture Picture from Stream.
Solution was Delegated_Eval, which Eval a codeblock at the GUI thread, as we have to use it with Codejock.