www.pudn.com > VideoCam.rar > Videocap.pas


unit Videocap; 
 
interface 
 
uses 
 Windows, Messages, SysUtils, Classes, Graphics, Controls,stdctrls, 
 ExtCtrls,vfw,mmsystem,syncobjs; 
 
 /////////////////////////////////////////////////////////////////////////////// 
// Video Capturing 
 
type 
// Types for audio-settings 
 TChannel = (Stereo, Mono); 
 TFrequency = (f8000Hz, f11025Hz, f22050Hz, f44100Hz); 
 TResolution  = (r8Bit, r16Bit); 
 
 
// Types for event-procedures 
type 
  TCapStatusProc = procedure(Sender: TObject) of object; 
  TCapStatusCallback = procedure (Sender:TObject;nID:integer;status:string) of object; 
  TVideoStream = procedure (sender:TObject;lpVhdr:PVIDEOHDR) of object; 
  TAudioStream = procedure (sender:TObject;lpWHdr:PWAVEHDR) of object; 
  TError       = procedure (sender:TObject;nID:integer; errorstr:string) of object; 
 
 
// Exceptions 
type ENoDriverException      = class(Exception); 
type ENoCapWindowException   = class(Exception); 
type ENotConnectException    = class(Exception); 
type ENoOverlayException     = class(Exception); 
type EFalseFormat            = class(Exception); 
type ENotOpen                = class(Exception); 
type EBufferFileError        = class(Exception); 
 
 
type 
TAudioFormat = class (TPersistent) 
   private 
    FChannels : TChannel; 
    FFrequency: TFrequency; 
    FRes      : TResolution; 
  private 
    procedure SetAudio(handle:Thandle); // Setting Audio Data to Capture Window 
 
  public 
   constructor create; 
 
   published 
     property Channels: TChannel read FChannels write Fchannels     default Mono; 
     property Frequency: TFrequency read FFrequency write fFrequency default f8000Hz; 
     property Resolution : TResolution read FRes write FRes         default r8Bit; 
 end; 
 
 
 
 
 
type 
  TVideoCap = class(TCustomControl) 
  private 
 
   fdriverIndex:integer;                                  // Videodriver index 
   fVideoDriverName     : string;                         // name of videodriver 
   fhCapWnd             : THandle;                        // handle for CAP-Window 
   fpDrivercaps         : PCapDriverCaps;                 // propertys of videodriver 
   fpDriverStatus       : pCapStatus;                     // status of capdriver 
   fscale               : boolean;                        // window scaling 
   fprop                : boolean;                        // proportional scaling 
   fpreviewrate         : word;                           // Frames p. sec during preview 
   fmicrosecpframe      : cardinal;                       // framerate as microsconds 
   fCapVideoFileName    : string;                         // name of the capture file 
   fTempFileName        : String;                         // Name of temporary avi-file 
   fTempFileSize        : word;                           // size of Tmp- File in MB 
 
   fCapSingleImageFileName : string;                      // name of the file for a single image 
   fcapAudio               :boolean;                      // Capture also audio stream 
   fcapTimeLimit           :word;                         // Time limit for captureing 
   fIndexSize             :cardinal;                      // size of the index in the capture file 
   fcapToFile             : boolean;                      // Write frames to file druing capturing 
   FAudioFormat           : TAudioFormat;                 // Audio Format 
   fCapStatusProcedure     : TCapStatusProc;              // Event procedure for internal component status 
   fcapStatusCallBack      : TCapStatusCallback;          // Event procedure for status of then driver 
   fcapVideoStream         : TVideoStream;                // Event procedure for each Video frame during capturing 
   fcapAudioStream         : TAudiostream;                // Event procedure for each Audio buffer 
   fcapFrameCallback       : TVideoStream;                // Event procedure for each Video frame during preview 
   fcapError               : TError;                      // Event procedure for Error 
 
 
 
 
   procedure setsize(var msg:TMessage); message WM_SIZE;  // Changing size of cap window 
   function GetDriverCaps:boolean;                        // get driver capitiyties 
   procedure DeleteDriverProps;                           // delete driver capitilyites 
   procedure CreateTmpFile(drvopn:boolean);               // Create or delete a temp avi´-file 
 
   function GetDriverStatus(callback:boolean):boolean;    // Getting state of driver 
   Procedure SetDriverOpen(Value:boolean) ;               // Open and Close the driver 
   function GetDriverOpen:boolean;                        // is Driver open ? 
   function GetPreview:boolean;                           // previwe mode 
   function GetOverlay:Boolean;                           // overlay eode; 
   procedure SizeCap;                                     // calc size of the Capture Window 
   procedure Setprop(Value:Boolean);                      // Stretch Picture proportional to Window Size 
   procedure SetMicroSecPerFrame(Value:cardinal);         // micro seconds between two frames 
   procedure setFrameRate(Value:word);                    // Setting Frames p. second 
   function  GetFrameRate:word;                           // Getting Frames p. second. 
 
 
 
    // Handlers for Propertys 
 
   procedure SetDriverIndex(Value:integer);               // Select Driver by setting driver index 
   function CreateCapWindow:boolean;                      // Opening driver, create capture window 
   procedure DestroyCapwindow;                            //  Closing Driver, destrying capture window 
    function GetCapWidth:word;                            // Width and Heigth of Video-Frame 
    function GetCapHeight:word; 
    function  GetHasDlgVFormat  : Boolean;                // Driver has a format dialog 
    function  GetHasDlgVDisplay : Boolean;                // Driver has a display dialog 
    function  GetHasDlgVSource  : Boolean;                // Driver has a source dialog 
    function  GetHasVideoOverlay: Boolean;                // Driver has overlay mode 
    procedure Setoverlay(Value:boolean);                  // Driver will use overlay mode 
    procedure SetPreview(Value:boolean);                  // Driver will use preview mode 
    procedure SetScale(Value:Boolean);                    //  Stretching Frame to component size 
    procedure SetpreviewRate(Value:word);                 // Setting preview frame rate 
    function GetCapInProgress:boolean;                    // Capturing  in progress 
    procedure SetIndexSize(Value:cardinal);               // Setting index size in capture file 
    function GetBitMapInfoNP:TBITMAPINFO;                 // Bitmapinfo Without Palette 
    function GetBitmapHeader:TBitmapInfoHeader;           // Get only Header; 
    procedure SetBitmapHeader(Header:TBitmapInfoHeader);  // Set only Header 
    procedure SetBufferFileSize(Value:word);              // Setting of Tmp-File 
 
 
  // Setting callbacks as events 
    procedure SetStatCallBack(Value:TCapStatusCallback); 
    procedure SetCapVideoStream(Value:TVideoStream); 
    procedure SetCapAudioStream(Value:TAudioStream); 
    procedure SetCapFrameCallback(Value:TVideoStream); 
    procedure SetCapError(Value:TError); 
 
  public 
     procedure SetDriverName(Value:String);                    // Select Driver by setting driver name 
 
    constructor Create(AOwner: TComponent); override; 
    destructor destroy; override; 
 
    property  HasDlgFormat:Boolean read GetHasDlgVFormat;      // Driver has a format dialog 
    property  HasDlgDisplay:Boolean read GetHasDlgVDisplay;    // Driver has a display dialog 
    property  HasDlgSource:Boolean read GetHasDlgVSource;      // Driver has a sourve dialog 
    property  HasVideoOverlay:boolean read GetHasVideoOverlay; // Driver has overlay mode 
    property  CapWidth: word read GetCapWidth;                 // Width of the captured frames 
    property  CapHeight: word read GetCapHeight;               // Hight of the captured frames 
    property  CapInProgess: boolean read getCapinProgress;     // capturing is progress 
    property  BitMapInfo:TBitmapinfo read GetBitmapInfoNP;     // Get the Bitmapinfo of the frames wiht no legal palette 
   //Header of the Bitmapinfo 
    function DlgVFormat:Boolean;                               // Shows VideoFormat dialog of the Driver 
    function DlgVDisplay:boolean;                              // Shows VideoDisplay dialog of the Driver 
    function DlgVSource:boolean;                               // Shows   VideoSource  dialog of the Driver 
    function DlgVCompression:Boolean;                          // Shows  VideoCompression dialog from VfW 
    function GrabFrame:boolean;                                // Capture one Frame and stops overlay or preview mode 
    function GrabFrameNoStop:boolean;                          // Capture one frame without stoppin overlay or preview 
    function SaveAsDIB:Boolean;                                // saves actual frame as DIB 
    function SaveToClipboard:Boolean;                          // Puts actual fasme to then Clipboard 
    function StartCapture:Boolean;                             // Starts Capturing 
    function StopCapture:Boolean;                              // Stops capturing 
    function GetBitmapInfo(var p:Pointer):integer;             // The whole Bitmap-Info with complete palette 
    procedure SetBitmapInfo(p:Pointer;size:integer);           // Setting whole Bitmap-Info with complete palette 
    property  BitMapInfoHeader:TBitmapInfoHeader read GetBitmapHeader write SetBitmapHeader; 
    function SaveCap:boolean;                                  // Saves Avi-File if Bufferfile is used 
    function CapSingleFramesOpen:boolean;                      // Opens AVI-File for Singe Image Capturing 
    function CapSingleFramesClose:boolean;                     // Close AVI-File after Singe Image Capturing 
    function CapSingleFrame:boolean;                           // Captures a Single frame to File 
 
 published 
   property align; 
   property color; 
   property visible; 
   property DriverOpen: boolean read getDriveropen write setDriverOpen;                         // Opens the Driver / or is Driver open 
   property DriverIndex:integer read fdriverindex write SetDriverIndex;                         // Index of driver 
   property DriverName: string read fVideoDriverName write SetDrivername;                       // Name of the Driver 
   property VideoOverlay:boolean read GetOverlay write SetOverlay;                              // Overlay - Mode 
   property VideoPreview:boolean read GetPreview write SetPreview;                              // Preview - Mode 
   property PreviewScaleToWindow:boolean read fscale write Setscale;                            // Stretching Frame to component size 
   property PreviewScaleProportional:boolean read  fprop write Setprop;                         // Stretching Frame poportional to original size 
   property PreviewRate:word read fpreviewrate write SetpreviewRate;                            // Preview frame rate 
   property MicroSecPerFrame:cardinal read  fmicrosecpframe write SetMicroSecPerFrame;          // micro seconds between two frames 
   property FrameRate:word read  getFramerate write setFrameRate;                               // Frames p. second 
   Property CapAudio:Boolean read fcapAudio write fcapAudio;                                    // Captue audio stream to 
   property VideoFileName:string read fCapVideoFileName   write fCapVideoFileName  ;            // Name of capture file 
   property SingleImageFile:string read FCapSingleImageFileName write FCapSingleImageFileName;  // Name of file for single image 
   property CapTimeLimit:word read fCapTimeLimit write fCapTimeLimit;                           // time limit for Capturing 
   property CapIndexSize:cardinal read findexSize write setIndexSize;                           // Size of the index for capture file 
   property CapToFile:boolean read fcaptoFile write fcapToFile;                                 // Write Frames to capture file 
   property CapAudioFormat:TAudioformat read FAudioformat write FAudioFormat;                   // Format of captuing Audiodata 
   property BufferFileSize:word read ftempfilesize write SetBufferFileSize;                     // Size of Bufferfile in MB 
  // Internal Events and Callbacks as Events 
   property OnStatus:TCapStatusProc read fCapStatusProcedure write FCapStatusProcedure; 
   property OnStatusCallback:TCapStatusCallback read fcapStatuscallback write SetStatCallback; 
   property OnVideoStream:TVideoStream read fcapVideoStream write SetCapVideoStream; 
   property OnFrameCallback:TVideoStream read FcapFramecallback write SetCapFrameCallback; 
   property OnAudioStream:TAudioStream read fcapAudioStream write SetCapAudioStream; 
   property OnError:TError read fcapError write SetCapError; 
   property OnMouseMove; 
   property OnMouseUp; 
   property OnMouseDown; 
   property OnClick; 
   Property OnDblClick; 
 end; 
 
 
 
function GetDriverList:TStringList;                                                   // Fill stringlist with names and versioninfo of all installed capture drivers 
procedure FrameToBitmap(Bitmap:TBitmap;FrameBuffer:pointer; BitmapInfo:TBitmapInfo);  // Make a TBitmap from a Frame 
procedure BitmapToFrame(Bitmap:TBitmap; FrameBuffer:pointer; BitmapInfo:TBitmapInfo); // Make a Frame form a Bitmap 
 
 
procedure Register; 
 
implementation 
 
 // Callback for status of video captures 
function StatusCallbackProc(hWnd : HWND; nID : Integer; lpsz : Pchar): LongInt; stdcall; 
var Control:TVideoCap; 
begin 
  control := TVideoCap(capGetUserData(hwnd)); 
  if assigned(control) then 
   begin 
     if assigned(control.fcapStatusCallBack) then 
       control.fcapStatusCallBack(control,nId,strPas(lpsz)); 
   end; 
  Result := 1; 
end; 
 
// ·µ»ØÊÓÆµÁ÷ 
function VideoStreamCallbackProc(hWnd:Hwnd; lpVHdr:PVIDEOHDR):longint; stdcall; 
 var Control:TVideoCap; 
begin 
   control := TVideoCap(capGetUserData(hwnd)); 
  if assigned(control) then 
   begin 
    if assigned(control.fcapVideoStream ) then 
      control.fcapVideoStream(control,lpvHdr); 
   end; 
 Result := 1; 
end; 
 
//Callback for Frames during Preview 
function FrameCallbackProc(hwnd:Hwnd; lpvhdr:PVideoHdr):longint;stdcall; 
var Control:TVideoCap; 
 
begin 
  control := TVideoCap(capGetUserData(hwnd)); 
  if assigned(control) then 
   begin 
    if assigned(control.fcapFrameCallback ) then 
      control.fcapFrameCallback(control,lpvHdr); 
   end; 
 Result := 1; 
end; 
 
 
// Callback for audio stream 
function AudioStreamCallbackProc(hwnd:HWND;lpWHdr:PWaveHdr):longInt; stdcall; 
var control:TVideoCap; 
begin 
 control := TVideoCap(capGetUserData(hwnd)); 
 if assigned(control) then 
  if assigned(control.fcapAudioStream) then 
  begin 
    control.fcapAudioStream(control,lpwhdr); 
  end; 
 Result := 1; 
end; 
 
// Callback for Error 
function ErrorCallbackProc(hwnd:HWND;nId:integer;lzError:Pchar):longint;stdcall; 
var 
  Control: TVideoCap; 
begin 
  control := TVideoCap(capGetUserData(hwnd)); 
  if assigned(control) then 
    if assigned(control.fcaperror) then 
    begin 
     control.fcapError(control,nId,StrPas(lzError)); 
    end; 
  Result := 1; 
end; 
 
// New Window-Procedure for CaputreWindow to post messages like WM_MouseMove to Component 
function WCapproc(hw:THandle;messa:DWord; w:wParam; l:lParam):integer;stdcall; 
var 
  oldwndProc: Pointer; 
  parentWnd: Thandle; 
begin 
  oldwndproc := Pointer(GetWindowLong(hw,GWL_USERDATA)); 
  case Messa of 
    WM_MOUSEMOVE, 
    WM_LBUTTONDBLCLK, 
    WM_LBUTTONDOWN,WM_RBUTTONDOWN,WM_MBUTTONDOWN , 
    WM_LBUTTONUP,WM_RBUTTONUP,WM_MBUTTONUP: 
    begin 
      ParentWnd:=Thandle(GetWindowLong(hw,GWL_HWNDPARENT)); 
      SendMessage(ParentWnd,messa,w,l); 
      Result := Integer(True); 
    end 
    else 
      Result := callWindowProc(oldwndproc,hw,messa,w,l); 
  end; 
end; 
 
(*---------------------------------------------------------------*) 
// constructor and Destructor 
constructor TVideoCap.Create(aowner:TComponent); 
 
begin 
 inherited create(aowner); 
 height                  := 100; 
 width                   := 100; 
 Color                   :=clblack; 
 fVideoDriverName        := ''; 
 fdriverindex            := -1 ; 
 fhCapWnd                := 0; 
 fCapVideoFileName       := 'Video.avi'; 
 fCapSingleImageFileName := 'Capture.bmp'; 
 fscale                  := false; 
 fprop                   := false; 
 fpreviewrate            := 30; 
 fmicrosecpframe         := 66667; 
 fpDrivercaps            := nil; 
 fpDriverStatus          := nil; 
 fcapToFile              := true; 
 findexSize              := 0; 
 ftempFileSize           := 0; 
 fCapStatusProcedure     := nil; 
 fcapStatusCallBack      := nil; 
 fcapVideoStream         := nil; 
 fcapAudioStream         := nil; 
 
 FAudioformat:=TAudioFormat.Create; 
 
end; 
 
destructor TVideoCap.destroy; 
begin 
  DestroyCapWindow; 
  deleteDriverProps; 
  fAudioformat.Free; 
  inherited destroy; 
end; 
 
// Messagehandler for sizing the capture window 
procedure TVideoCap.SetSize(var msg:TMessage); 
begin 
  if (fhCapWnd <> 0) and (Fscale) then 
  begin 
   if msg.msg = WM_SIZE then SizeCap; 
  end; 
end; 
 
 
// Sizing capture window 
procedure TVideoCap.SizeCap; 
var 
  h,w: Integer; 
  f,cf: Single; 
begin 
  if not fscale then 
    MoveWindow(fhcapWnd,0,0,Capwidth,capheight,True) 
  else 
  begin 
    if fprop then 
    begin 
      f := Width/Height; 
      cf := CapWidth/CapHeight; 
      if f >  cf then 
      begin 
        h := Height; 
        w := Round(h*cf); 
      end 
      else 
      begin 
        w := Width; 
        h := Round(w*1/cf); 
      end 
    end 
    else 
    begin 
      h := Height; 
      w := Width; 
    end; 
    MoveWindow(fhcapWnd,0,0,w, h,True); 
  end; 
end; 
 
// Delete driver infos 
procedure TVideoCap.DeleteDriverProps; 
begin 
  if assigned(fpDrivercaps) then 
  begin 
    dispose(fpDrivercaps); 
    fpDriverCaps:= nil; 
  end; 
  if assigned(fpDriverStatus) then 
  begin 
    dispose(fpDriverStatus); 
    fpDriverStatus:= nil; 
  end; 
end; 
 
// Buffer File 
procedure TVideoCap.CreateTmpFile(drvOpn:boolean); 
var 
  s,f: array [0..MAX_PATH] of char; 
  size: Word; 
  ok: Boolean; 
  e: Exception; 
begin 
  if (ftempFileName ='') and (ftempFileSize = 0) then Exit; 
  if drvOpn then Size := ftempFileSize else size := 0; 
  if fTempFileName = '' then 
  begin 
    GetTempPath(sizeof(s),@s); 
    GetTempFileName(s,'cap',0,f); 
    ftempfilename := f; 
  end; 
  if size <> 0 then 
  begin 
    capFileSetCaptureFile(fhCapWnd,strpCopy(f,ftempfilename)); 
    ok := capFileAlloc(fhcapWnd,1024*1024* ftempFileSize); 
    if not ok then 
    begin 
      e := EBufferFileError.Create('²»Äܽ¨Á¢ÁÙʱÎļþ!        '); 
      raise e; 
    end; 
  end 
  else 
  begin 
    capFileSetCaptureFile(fhCapWnd,strpCopy(f, fCapVideoFileName)); 
    DeleteFile(fTempfileName); 
    fTempFileName := ''; 
  end; 
end; 
 
procedure TVideoCap.SetBufferFileSize(Value:word); 
begin 
  if Value = fTempFilesize then Exit; 
  ftempFileSize := Value; 
  if DriverOpen then 
    CreateTmpFile(True); 
end; 
(*---------------------------------------------------------------*) 
// Capitilies of the Driver 
 
function TVideoCap.GetDriverCaps:boolean; 
var 
  savestat: Integer; 
begin 
  Result := False; 
  if Assigned(fpDrivercaps) then 
  begin 
    Result := True; 
    Exit; 
  end; 
  if fdriverIndex = -1 then Exit; 
  savestat := fhCapwnd;  // save state of the window 
  if fhCapWnd = 0 then CreateCapWindow; 
  if fhCapWnd = 0 then Exit; 
  new(fpDrivercaps); 
  if capDriverGetCaps(fhCapWnd, fpDriverCaps, sizeof(TCapDriverCaps)) then 
  begin 
    Result := True; 
    if savestat = 0 then destroyCapWindow; 
    Exit; 
  end; 
  dispose(fpDriverCaps);  // Error can't open then Driver 
  fpDriverCaps := nil; 
  if savestat = 0 then destroyCapWindow; 
end; 
 
(*---------------------------------------------------------------*) 
 // BitmapInfo without a Palette 
function TVideoCap.GetBitMapInfoNp:TBitmapinfo; 
var 
  e: Exception; 
begin 
  if driveropen then 
  begin 
    capGetVideoFormat(fhcapWnd, @result,sizeof(TBitmapInfo)); 
    Exit; 
  end; 
  fillchar(Result,sizeof(TBitmapInfo),0); 
  e := ENotOpen.Create('É豸ûÓдò¿ª!         '); 
  raise e; 
 end; 
 
// Whole BitmapInfo 
function TVideoCap.GetBitMapInfo(var p:Pointer):integer; 
var 
  size: Integer; 
  e: Exception; 
begin 
  p := nil; 
  if driverOpen then 
  begin 
    size:= capGetVideoFormat(fhcapWnd,p,0); 
    getmem(p,size); 
    capGetVideoFormat(fhcapwnd,p,size); 
    Result := size; 
    Exit; 
  end; 
  e := ENotOpen.Create('É豸ûÓдò¿ª!         '); 
  raise e; 
end; 
 
// Setting whole BitmapInfo 
procedure TVideoCap.SetBitmapInfo(p:Pointer;size:integer); 
var 
  e: Exception; 
  supported: Boolean; 
begin 
  if driverOpen then 
  begin 
    supported := capSetVideoFormat(fhcapWnd,p,size); 
    if not supported then 
    begin 
      e := EFalseFormat.Create('²»Ö§³ÖµÄ¸ñʽ!          ' ); 
      raise e; 
    end; 
    Exit; 
  end; 
  e := ENotOpen.Create('É豸ûÓдò¿ª!         '); 
  raise e; 
end; 
 
// Only Header of BitmapInfo 
function TVideoCap.GetBitMapHeader:TBitmapinfoHeader; 
var 
  e: Exception; 
begin 
  if driveropen then 
  begin 
    capGetVideoFormat(fhcapWnd, @result,sizeof(TBitmapInfoHeader)); 
    Exit; 
  end ; 
  FillChar(result,sizeof(TBitmapInfoHeader),0); 
  e := ENotOpen.Create('É豸ûÓдò¿ª!         '); 
  raise e; 
end; 
 
procedure TVideoCap.SetBitMapHeader(header:TBitmapInfoHeader); 
var 
  e: Exception; 
begin 
  if driveropen then 
  begin 
    if not capSetVideoFormat(fhcapWnd,@header,sizeof(TBitmapInfoHeader)) then 
    begin 
      e := EFalseFormat.Create('²»Ö§³ÖµÄ¸ñʽ!          '); 
      raise e; 
    end; 
    Exit; 
  end 
  else 
  begin 
    e := ENotOpen.Create('É豸ûÓдò¿ª!         '); 
    raise e; 
  end; 
end; 
 
 
function TVideoCap.getDriverStatus(callback:boolean):boolean; 
begin 
  Result := False; 
  if fhCapWnd <> 0 then 
  begin 
    if not assigned(fpDriverstatus) then new(fpDriverStatus); 
    if capGetStatus(fhCapWnd,fpdriverstatus, sizeof(TCapStatus)) then 
    begin 
      Result := True; 
    end; 
  end; 
  if assigned(fCapStatusProcedure)and callback then 
    fcapStatusProcedure(Self); 
end; 
 
(*---------------------------------------------------------------*) 
// Setting name of driver 
procedure TVideoCap.SetDrivername(Value:string); 
var 
  I: Integer; 
  name: array[0..80] of char; 
  ver: array[0..80] of char; 
begin 
  if fVideoDrivername = Value then Exit; 
  for I := 0 to 9 do 
  if capGetDriverDescription( i,name,80,ver,80) then 
    if strpas(name) = Value then 
    begin 
      fVideoDriverName := Value; 
      Driverindex := I; 
      Exit; 
    end; 
  fVideoDrivername := ''; 
  DriverIndex:= -1; 
end; 
(*---------------------------------------------------------------*) 
procedure TVideoCap.SetDriverIndex(Value:integer); 
var 
  name: array[0..80] of Char; 
  ver: array[0..80] of Char; 
begin 
  if Value = fdriverindex then Exit; 
  destroyCapWindow; 
  deleteDriverProps;  // Alte Treiberfähigkeiten Löschen 
  if Value > -1 then 
  begin 
    if capGetDriverDescription(Value,name,80,ver,80) then 
      fVideoDriverName := StrPas(name) 
    else 
      Value := -1; 
  end; 
  if Value = -1 then  fvideoDriverName := ''; 
  fdriverindex := Value; 
end; 
 
function TVideoCap.CreateCapWindow; 
var 
  Ex: Exception; 
  savewndproc: Integer; 
begin 
  if fhCapWnd <> 0 then 
  begin 
    Result := True; 
    Exit; 
  end; 
  if fdriverIndex = -1 then 
  begin 
    Ex := ENoDriverException.Create('ûÓÐÑ¡ÔñÏÔʾÉ豸!        '); 
    GetDriverStatus(True); 
    raise Ex; 
    Exit; 
  end; 
  fhCapWnd := capCreateCaptureWindow( PChar(Name), 
              WS_CHILD or WS_VISIBLE , 0, 0, 
               Width, Height, 
              Handle, 5001); 
  if fhCapWnd =0 then 
  begin 
    Ex := ENoCapWindowException.Create('²»Äܽ¨Á¢ÏÔʾ´°¿Ú!        '); 
    GetDriverStatus(True); 
    raise Ex; 
    Exit; 
  end; 
  // Set our own Adress to the CapWindow 
  capSetUserData(fhCapwnd,integer(self)); 
  // Set our own window procedure to Capture-Window 
  savewndproc:=SetWindowLong(fhcapWnd,GWL_WNDPROC,integer(@WCapProc)); 
  // User Data for old WndProc adress 
  SetWindowLong(fhcapWnd,GWL_USERDATA,savewndProc); 
  // Setting callbacks as events 
  if assigned(fcapStatusCallBack ) then 
    capSetCallbackOnStatus(fhcapWnd ,StatusCallbackProc); 
  if assigned(fcapFrameCallback) then 
    capSetCallbackOnFrame(fhcapWnd,FrameCallbackProc); 
  if assigned(fcapError) then 
    capSetCallbackOnError(fhcapWnd,ErrorCallBackProc); 
 
  if assigned(fcapVideoStream) then 
    capSetCallbackOnVideoStream(fhcapwnd,VideoStreamCallbackProc); 
  if assigned(fcapAudioStream) then 
    capSetCallbackOnWaveStream(fhcapWnd,AudioStreamCallbackProc); 
  if not capDriverConnect(fhCapWnd, fdriverIndex) then 
  begin 
    Ex := ENotConnectException.Create('ÏÔʾ´°¿Ú²»ÄÜÁ¬½ÓÏÔʾÉ豸!      '); 
    Destroycapwindow; 
    GetDriverStatus(true); 
    raise Ex; 
    Exit; 
  end; 
 
  CreateTmpFile(True); 
  capPreviewScale(fhCapWnd, fscale); 
  capPreviewRate(fhCapWnd, round(1/fpreviewrate*1000)); 
  GetDriverStatus(True); 
  Sizecap; 
  Result := True; 
end; 
 
(*------------------------------------------------------------------------*) 
// Setting callbacks as events 
procedure TVideoCap.SetStatCallBack(Value:TCapStatusCallback); 
begin 
  fcapStatusCallBack := Value; 
  if DriverOpen then 
    if assigned(fcapStatusCallBack) then 
      capSetCallbackOnStatus(fhcapWnd ,StatusCallbackProc) 
    else 
      capSetCallbackOnStatus(fhcapWnd ,nil); 
end; 
 
 
procedure TVideoCap.SetCapVideoStream(Value:TVideoStream); 
begin 
  fcapVideoStream := Value; 
  if DriverOpen then 
    if assigned(fcapVideoStream) then 
      capSetCallbackOnVideoStream(fhcapwnd,VideoStreamCallbackProc) 
    else 
     capSetCallbackOnVideoStream(fhcapwnd, nil); 
end; 
 
procedure TVideoCap.SetCapFrameCallback(Value:TVideoStream); 
begin 
  fcapframeCallback := Value; 
  if DriverOpen then 
    if assigned(fcapFrameCallback) then 
      capSetCallbackOnFrame(fhcapwnd,FrameCallBackProc) 
    else 
      capSetCallbackOnFrame(fhcapwnd, nil); 
end; 
 
procedure TVideoCap.SetCapAudioStream(Value:TAudioStream); 
begin 
  fcapAudioStream := Value; 
  if DriverOpen then 
    if assigned(fcapAudioStream) then 
      capSetCallbackOnWaveStream(fhcapWnd,AudioStreamCallbackProc) 
    else 
      capSetCallbackOnWaveStream(fhcapWnd,nil); 
end; 
 
procedure TVideoCap.SetCapError(Value: TError); 
begin 
  fcapError := Value; 
  if DriverOpen then 
    if assigned(fcapError) then 
      capSetCallbackOnError(fhcapWnd,ErrorCallbackProc) 
    else 
      capSetCallbackOnError(fhcapWnd,nil); 
end; 
 
procedure TVideoCap.DestroyCapWindow; 
begin 
  if fhCapWnd = 0 then Exit; 
  CreateTmpFile(False); 
  CapDriverDisconnect(fhCapWnd); 
  SetWindowLong(fhcapWnd,GWL_WNDPROC,GetWindowLong(fhcapwnd,GWL_USERDATA)); // Old windowproc 
  DestroyWindow(fhCapWnd) ; 
  fhCapWnd := 0; 
end; 
 
function  TVideoCap.GetHasVideoOverlay: Boolean; 
begin 
  if getDriverCaps then 
    Result := fpDriverCaps^.fHasOverlay 
  else 
    Result := False; 
 end; 
 
function  TVideoCap.GetHasDlgVFormat: Boolean; 
begin 
  if getDriverCaps then 
     Result := fpDriverCaps^.fHasDlgVideoFormat 
   else 
     result:= False; 
end; 
 
function  TVideoCap.GetHasDlgVDisplay: Boolean; 
begin 
  if getDriverCaps then 
    Result := fpDriverCaps^.fHasDlgVideoDisplay 
  else 
    Result := False; 
end; 
 
function  TVideoCap.GetHasDlgVSource: Boolean; 
begin 
  if getDriverCaps then 
     Result := fpDriverCaps^.fHasDlgVideoSource 
   else 
     result:= False; 
end; 
 
function TVideoCap.DlgVFormat: Boolean; 
var 
  savestat: Integer; 
begin 
  Result := False; 
  if fdriverIndex = -1 then Exit; 
    savestat := fhCapwnd; 
  if fhCapWnd = 0 then 
    if not CreateCapWindow then Exit; 
  Result := capDlgVideoFormat(fhCapWnd); 
  if Result then GetDriverStatus(True); 
  if savestat = 0 then destroyCapWindow; 
  if Result then 
  begin 
    Sizecap; 
    Repaint; 
  end; 
end; 
 
function TVideoCap.DlgVDisplay: Boolean; 
var 
  savestat: Integer; 
begin 
  Result := False; 
  if fdriverIndex = -1 then Exit; 
  savestat := fhCapwnd; 
  if fhCapWnd = 0 then 
    if not CreateCapWindow then Exit; 
  result:=capDlgVideoDisplay(fhCapWnd) ; 
  if Result then GetDriverStatus(True); 
  if savestat = 0 then destroyCapWindow; 
  if Result then 
  begin 
    SizeCap; 
    Repaint; 
  end; 
end; 
 
function TVideoCap.DlgVSource: Boolean; 
var 
  savestat: Integer; 
begin 
  Result := False; 
  if fdriverIndex = -1 then Exit; 
  savestat := fhCapwnd; 
  if fhCapWnd = 0 then 
    if not createCapWindow then Exit; 
  Result := capDlgVideoSource(fhCapWnd); 
  if Result then GetDriverStatus(true); 
  if savestat = 0 then destroyCapWindow; 
  if Result then 
  begin 
    SizeCap; 
    Repaint; 
  end; 
end; 
 
function TVideoCap.DlgVCompression; 
var 
  savestat: Integer; 
begin 
  Result := False; 
  if fdriverIndex = -1 then Exit; 
  savestat := fhCapwnd; 
  if fhCapWnd = 0 then 
    if not createCapWindow then Exit; 
      Result := capDlgVideoCompression(fhCapWnd); 
  if savestat = 0 then destroyCapWindow; 
end; 
 
// Single Frame Grabbling 
function TVideoCap.GrabFrame: Boolean; 
begin 
  Result := False; 
  if not DriverOpen then Exit; 
  Result:= capGrabFrame(fhcapwnd); 
  if Result then GetDriverStatus(True); 
end; 
 
function TVideoCap.GrabFrameNoStop: Boolean; 
begin 
  Result := False; 
  if not DriverOpen then Exit; 
  Result := capGrabFrameNoStop(fhcapwnd); 
  if Result then GetDriverStatus(True); 
end; 
 
// save frame as DIP 
function TVideoCap.SaveAsDIB: Boolean; 
var 
 S: array[0..MAX_PATH] of Char; 
begin 
  Result := False; 
  if not DriverOpen then Exit; 
  Result := capFileSaveDIB(fhcapwnd,strpCopy(s,fCapSingleImageFileName)); 
end; 
 
function TVideoCap.SaveToClipboard: Boolean; 
begin 
  Result := False; 
  if not Driveropen then Exit; 
  Result := capeditCopy(fhcapwnd); 
end; 
 
procedure TVideoCap.Setoverlay(Value: Boolean); 
var 
 Ex: Exception; 
begin 
  if Value = GetOverlay then Exit; 
  if gethasVideoOverlay = False then 
  begin 
    Ex:= ENoOverlayException.Create('Çý¶¯²»Ö§³Ö¸²¸Ç·½Ê½!       '); 
    raise Ex; 
    Exit; 
  end; 
  if Value = True then 
  begin 
    if fhcapWnd = 0 then CreateCapWindow; 
    GrabFrame; 
  end; 
  capOverlay(fhCapWnd,Value); 
  GetDriverStatus(True); 
  invalidate; 
end; 
 
function TVideoCap.GetOverlay: Boolean; 
begin 
  if fhcapWnd = 0 then Result := False 
  else 
    Result := fpDriverStatus^.fOverlayWindow; 
end; 
 
procedure TVideoCap.SetPreview(Value: Boolean); 
begin 
  if Value = GetPreview then Exit; 
  if Value = True then 
    if fhcapWnd = 0 then CreateCapWindow; 
  capPreview(fhCapWnd,Value); 
  GetDriverStatus(True); 
  invalidate; 
end; 
 
function TVideoCap.GetPreview:Boolean; 
begin 
  if fhcapWnd = 0 then Result := False 
  else 
    Result := fpDriverStatus^.fLiveWindow; 
end; 
 
procedure TVideoCap.SetPreviewRate(Value:word); 
begin 
  if Value = fpreviewrate then Exit; 
  if Value < 1 then Value := 1; 
  if Value > 30 then Value := 30; 
  fpreviewrate := Value; 
  if DriverOpen then capPreviewRate(fhCapWnd, round(1/fpreviewrate*1000)); 
end; 
 
procedure TVideoCap.SetMicroSecPerFrame(Value:cardinal); 
begin 
  if Value = fmicrosecpframe then Exit; 
  if Value < 33333 then Value := 33333; 
  fmicrosecpframe := Value; 
end; 
 
procedure TVideoCap.setFrameRate(Value:word); 
begin 
  if Value <> 0 then fmicrosecpframe := round(1.0/Value*1000000.0); 
end; 
 
function TVideoCap.GetFrameRate: Word; 
begin 
 if fmicrosecpFrame > 0   then 
   Result := round(1./fmicrosecpframe * 1000000.0) 
else 
  Result := 0; 
end; 
 
function TVideoCap.StartCapture; 
var 
  CapParms:TCAPTUREPARMS; 
  name: array[0..MAX_PATH] of Char; 
begin 
  Result := False; 
  if not DriverOpen then Exit; 
  capCaptureGetSetup(fhCapWnd, @CapParms, sizeof(TCAPTUREPARMS)); 
  if ftempfilename = '' then 
    capFileSetCaptureFile(fhCapWnd,strpCopy(name, fCapVideoFileName)); 
  CapParms.dwRequestMicroSecPerFrame := fmicrosecpframe; 
  CapParms.fLimitEnabled    := BOOL(FCapTimeLimit); 
  CapParms.wTimeLimit       := fCapTimeLimit; 
  CapParms.fCaptureAudio    := fCapAudio; 
  CapParms.fMCIControl      := False; 
  CapParms.fYield           := True; 
  CapParms.vKeyAbort        := VK_ESCAPE; 
  CapParms.fAbortLeftMouse  := False; 
  CapParms.fAbortRightMouse := False; 
  if CapParms.fLimitEnabled then // Calculate Indexsize 
  begin 
    CapParms.dwIndexSize := frameRate*FCapTimeLimit; // For Video Frames 
    if fCapAudio then 
      CapParms.dwIndexSize := CapParms.dwIndexSize + 5*FCapTimeLimit; // Additional Buffer for Audio 
  end 
  else 
  begin 
    if CapParms.dwIndexSize = 0 then        // Default Value 
      CapParms.DwIndexSize := 100000        // Value bigger then default for larger Videos 
    else 
      CapParms.dwIndexSize := findexSize;   // IndexSize by user 
  end; 
  if CapParms.dwIndexSize < 1800 then CapParms.dwIndexSize := 1800;  // Limit Control 
  if CapParms.dwIndexSize > 324000 then CapParms.dwIndexSize := 324000; 
  capCaptureSetSetup(fhCapWnd, @CapParms, sizeof(TCAPTUREPARMS)); 
  if fCapAudio then FAudioformat.SetAudio(fhcapWnd); 
  if CapToFile then 
    Result := capCaptureSequence(fhCapWnd) 
  else 
    Result := capCaptureSequenceNoFile(fhCapWnd); 
  GetDriverStatus(True); 
end; 
 
 
function TVideoCap.StopCapture; 
begin 
  Result := False; 
  if not DriverOpen then Exit; 
  Result := CapCaptureStop(fhcapwnd); 
  GetDriverStatus(true); 
end; 
 
function TVideoCap.SaveCap: Boolean; 
var 
  name: array[0..MAX_PATH] of Char; 
begin 
  Result := capFileSaveAs(fhcapwnd,strPCopy(name,fCapVideoFileName)); // strpCopy(name, fCapVideoFileName)); 
end; 
 
procedure TVideoCap.SetIndexSize(Value: cardinal); 
begin 
  if Value = 0 then 
  begin 
    findexSize := 0; 
    Exit; 
  end; 
  if Value < 1800 then Value := 1800; 
  if Value > 324000 then Value := 324000; 
  findexsize := Value; 
end; 
 
 
function TVideoCap.GetCapInProgress: Boolean; 
begin 
  Result := False; 
  if not DriverOpen then Exit; 
  GetDriverStatus(False); 
  Result := fpDriverStatus^.fCapturingNow ; 
end; 
 
Procedure TVideoCap.SetScale(Value:boolean); 
begin 
  if Value = fscale then Exit; 
  fscale := Value; 
  if DriverOpen then 
  begin 
    capPreviewScale(fhCapWnd, fscale); 
    SizeCap; 
  end; 
  Repaint; 
end; 
 
Procedure TVideoCap.Setprop(Value:Boolean); 
begin 
  if Value = fprop then Exit; 
  fprop := Value; 
  if DriverOpen then Sizecap; 
  Repaint; 
end; 
 
function TVideoCap.GetCapWidth; 
begin 
  if assigned(fpDriverStatus) then 
    Result := fpDriverStatus^.uiImageWidth 
  else 
    Result := 0; 
end; 
 
function TVideoCap.GetCapHeight; 
begin 
  if assigned(fpDriverStatus) then 
    Result := fpDriverStatus^.uiImageHeight 
  else 
    Result := 0; 
end; 
 
Procedure TVideoCap.SetDriverOpen(Value: Boolean); 
begin 
  if Value = GetDriverOpen then Exit; 
  if Value = False then DestroyCapWindow; 
  if Value = True then CreateCapWindow; 
end; 
 
 
function TVideoCap.GetDriverOpen: Boolean; 
begin 
  Result := fhcapWnd <> 0; 
end; 
 
// Singele frame Capturing 
function TVideoCap.CapSingleFramesOpen:boolean; 
var 
  name: array [0..MAX_PATH] of Char; 
  CapParms: TCAPTUREPARMS; 
begin 
  Result := False; 
  if not DriverOpen then Exit; 
  capCaptureGetSetup(fhCapWnd, @CapParms, sizeof(TCAPTUREPARMS)); 
  if ftempfilename = '' then 
    capFileSetCaptureFile(fhCapWnd,strpCopy(name, fCapVideoFileName)); 
  CapParms.dwRequestMicroSecPerFrame := fmicrosecpframe; 
  CapParms.fLimitEnabled    := Bool(0); 
  CapParms.fCaptureAudio    := False; 
  CapParms.fMCIControl      := False; 
  CapParms.fYield           := True; 
  CapParms.vKeyAbort        := VK_ESCAPE; 
  CapParms.dwIndexSize := findexSize; // IndexSize by user 
  if CapParms.dwIndexSize < 1800 then CapParms.dwIndexSize := 1800;  // Limit Control 
  if CapParms.dwIndexSize > 324000 then CapParms.dwIndexSize := 324000; 
  capCaptureSetSetup(fhCapWnd, @CapParms, sizeof(TCAPTUREPARMS)); 
  Result := capCaptureSingleFrameOpen(fhcapWnd); 
end; 
 
function TVideoCap.CapSingleFramesClose: Boolean; 
var 
  E: Exception; 
begin 
   if not driverOpen then 
   begin 
     E := ENotOpen.Create('É豸ûÓдò¿ª!         '); 
     raise E; 
     Exit; 
   end; 
   Result := CapCaptureSingleFrameClose(fhcapWnd); 
end; 
 
function TVideoCap.CapSingleFrame: Boolean; 
var 
  E: Exception; 
begin 
  if not driverOpen then 
  begin 
    E := ENotOpen.Create('É豸ûÓдò¿ª!         '); 
      raise E; 
      Exit; 
  end; 
  Result := CapCaptureSingleFrame(fhcapWnd); 
end; 
 
constructor TAudioFormat.create; 
begin 
  inherited create; 
  FChannels := Mono; 
  FFrequency := f8000Hz; 
  Fres := r8Bit; 
end; 
 
procedure TAudioFormat.SetAudio(handle:Thandle); 
var 
 WAVEFORMATEX: TWAVEFORMATEX; 
begin 
  if handle= 0 then Exit;  // No CapWindow 
  capGetAudioFormat(handle,@WAVEFORMATEX, SizeOf(TWAVEFORMATEX)); 
  case FFrequency of 
       f8000hz : WAVEFORMATEX.nSamplesPerSec := 8000; 
       f11025Hz: WAVEFORMATEX.nSamplesPerSec := 11025; 
       f22050Hz: WAVEFORMATEX.nSamplesPerSec := 22050; 
       f44100Hz: WAVEFORMATEX.nSamplesPerSec := 44100; 
  end; 
  WAVEFORMATEX.nAvgBytesPerSec := WAVEFORMATEX.nSamplesPerSec; 
  if FChannels = Mono then 
    WAVEFORMATEX.nChannels := 1 
  else 
    WAVEFORMATEX.nChannels := 2; 
  if FRes = r8Bit then 
    WAVEFORMATEX.wBitsPerSample := 8 
  else 
    WAVEFORMATEX.wBitsPerSample := 16; 
  capSetAudioFormat(handle,@WAVEFORMATEX, SizeOf(TWAVEFORMATEX)); 
end; 
 
// Creating a list with capture drivers 
function GetDriverList:TStringList; 
var 
  I: Integer; 
  name: array[0..80] of Char; 
  ver: array[0..80] of Char; 
begin 
  Result := TStringList.Create; 
  Result.Capacity := 10; 
  Result.Sorted := False; 
  for I := 0 to 9 do 
    if capGetDriverDescription( I,name,80,ver,80) then 
      Result.Add(StrPas(name)+ ' '+strpas(ver)) 
    else 
      Break; 
end; 
 
procedure FrameToBitmap(Bitmap:TBitmap;FrameBuffer:pointer; BitmapInfo:TBitmapInfo); 
var 
  hdd: Thandle; 
begin 
  with Bitmap  do 
  begin 
    Width := BitmapInfo.bmiHeader.biWidth;      // New size of Bitmap 
    Height := Bitmapinfo.bmiHeader.biHeight; 
    hdd := DrawDibOpen; 
    DrawDibDraw(hdd,canvas.handle,0,0,BitmapInfo.BmiHeader.biwidth,BitmapInfo.bmiheader.biheight,@BitmapInfo.bmiHeader, 
                  frameBuffer,0,0,bitmapInfo.bmiHeader.biWidth,bitmapInfo.bmiHeader.biheight,0); 
    DrawDibClose(hdd); 
  end; 
end; 
 
procedure BitmapToFrame(Bitmap:TBitmap; FrameBuffer:pointer; BitmapInfo: TBitmapInfo); 
var 
  Ex: Exception; 
begin 
  if bitmapInfo.bmiHeader.BiCompression <> bi_RGB then 
  begin 
    Ex := EFalseFormat.Create('²»Ö§³ÖDIB¸ñʽ!          '); 
    raise Ex ; 
  end; 
  with Bitmap do 
    GetDiBits(canvas.handle,handle,0,BitmapInfo.bmiHeader.biheight,FrameBuffer,BitmapInfo,DIB_RGB_COLORS); 
end; 
 
procedure Register; 
begin 
  RegisterComponents( 'Video', [TVideoCap]); 
end; 
 
end.