title: How capture continuos frames from camera?
body: <p>I'm using the following code to capture the camera:</p>
  <pre><code>unit Webcam;
  
  interface
  
  uses
    Windows, Messages, SysUtils, Graphics, ExtCtrls, Classes, VFW {https://drkb.ru/multimedia/audio/extract_track/ed7dcb6994c641e4};
  
  type
    TCamera = class(TObject)
    private
      class var VideoHwnd: HWND;
      class function FrameCallback(hCapWnd: HWND; lpVHdr: PVIDEOHDR): DWORD;
        stdcall; static;
    public
      constructor Create(Owner: TPanel);
      destructor Destroy; override;
    end;
  
  var
    Camera: TCamera;
  
  implementation
  
  constructor TCamera.Create(Owner: TPanel);
  begin
    VideoHwnd := capCreateCaptureWindowA('', WS_CHILD or WS_VISIBLE, 0, 0, 640,
      480, Owner.Handle, 0);
    if (SendMessage(VideoHwnd, WM_CAP_DRIVER_CONNECT, 0, 0) &lt;&gt; 0) then
    begin
      SendMessage(VideoHwnd, WM_CAP_SET_PREVIEW, 1, 0);
      SendMessage(VideoHwnd, WM_CAP_SET_PREVIEWRATE, 1, 0);
      SendMessage(VideoHwnd, WM_CAP_SET_OVERLAY, 1, 0);
      SendMessage(VideoHwnd, WM_CAP_SET_SCALE, 1, 0);
      SendMessage(VideoHwnd, WM_CAP_SET_CALLBACK_FRAME, 1,
        lParam(@FrameCallback));
      SendMessage(VideoHwnd,
        { WM_CAP_GRAB_FRAME } WM_CAP_GRAB_FRAME_NOSTOP, 1, 0);
    end;
  end;
  
  destructor TCamera.Destroy;
  begin
    if (VideoHwnd &lt;&gt; 0) then
    begin
      SendMessage(VideoHwnd, WM_CAP_DRIVER_DISCONNECT, 1, 0);
      SendMessage(VideoHwnd, WM_CLOSE, 1, 0);
    end;
    inherited;
  end;
  
  class function TCamera.FrameCallback(hCapWnd: HWND; lpVHdr: PVIDEOHDR)
    : DWORD; stdcall;
  var
    MemoryStream: TMemoryStream;
    BitmapInfo: TBitmapInfo;
    Bitmap: TBitmap;
    Hdb: Thandle;
  begin
    FillChar(BitmapInfo, SizeOf(BitmapInfo), 0);
  
    if (SendMessage(hCapWnd, WM_CAP_GET_VIDEOFORMAT, SizeOf(BitmapInfo),
      lParam(@BitmapInfo)) &lt;&gt; 0) then
    begin
      MemoryStream := TMemoryStream.Create;
      try
        Bitmap := TBitmap.Create;
        try
          with Bitmap do
          begin
            Width := BitmapInfo.bmiHeader.biWidth;
            Height := BitmapInfo.bmiHeader.biHeight;
  
            case BitmapInfo.bmiHeader.biBitCount of
              1:
                PixelFormat := pf1bit;
              4:
                PixelFormat := pf4bit;
              8:
                PixelFormat := pf8bit;
              15:
                PixelFormat := pf15bit;
              16:
                PixelFormat := pf16bit;
              24:
                PixelFormat := pf24bit;
              32:
                PixelFormat := pf32bit;
            end;
  
            Hdb := DrawDibOpen;
  
            DrawDibDraw(Hdb, Canvas.Handle, 0, 0, BitmapInfo.bmiHeader.biWidth,
              BitmapInfo.bmiHeader.biHeight, @BitmapInfo.bmiHeader,
              lpVHdr^.lpdata, 0, 0, BitmapInfo.bmiHeader.biWidth,
              BitmapInfo.bmiHeader.biHeight, 0);
  
            DrawDibClose(Hdb);
  
            SaveToStream(MemoryStream);
          end;
  
          MemoryStream.Position := 0;
        finally
          Bitmap.Free;
        end;
      finally
        MemoryStream.Free;
      end;
    end;
  end;
  
  procedure GetDriverList(List: TStrings);
  var
    wIndex: Word;
    szDeviceName: array [0 .. MAX_PATH] of AnsiChar;
    szDeviceVersion: array [0 .. MAX_PATH] of AnsiChar;
  begin
    List.Clear;
    for wIndex := 0 to 9 do
    begin
      if capGetDriverDescriptionA(wIndex, @szDeviceName, SizeOf(szDeviceName),
        @szDeviceVersion, SizeOf(szDeviceVersion)) then
        List.AddObject(szDeviceName, Pointer(wIndex));
    end;
    if List.Count = 0 then
      RaiseLastOSError;
  end;
  
  end.
  </code></pre>
  <p>When my Form is visible, all works fine. On the other hand, when my Form is configured with <code>wsMinimize</code>, or hidden via code for example, only one frame is displayed/captured and then it stops.</p>
  <p>Is there a solution for that?</p>
  <pre><code>var
    Form2: TForm2;
  
  implementation
  
  {$R *.dfm}
  
  procedure TForm2.FormActivate(Sender: TObject);
  begin
    ShowWindow(Handle, SW_HIDE);
  end;
  
  end.
  </code></pre>
  <p><strong>EDIT:</strong></p>
  <p>I inserted a error <a href="https://docs.microsoft.com/en-us/windows/win32/multimedia/creating-an-error-callback-function" rel="nofollow noreferrer">callback function</a> suggested in a comment, but all seems well (no error is reported).</p>
  <pre><code> // inside TCamera class (private declarations):
  
   class function ErrorCallback(hCapWnd: HWND; nErrID: Integer;
     lpErrorText: LPTSTR): LRESULT; stdcall; static;
  
   //...
  
  class function TCamera.ErrorCallback(hCapWnd: HWND; nErrID: Integer;
    lpErrorText: LPTSTR): LRESULT; stdcall;
  begin
    Result := 1;
  
    if hCapWnd &lt;= 0 then
    begin
      Result := 0;
      Exit;
    end;
  
    if nErrID = 0 then
    begin
      Result := 1;
      Exit;
    end;
  
    Writeln(IntToStr(nErrID) + ' : ' + PAnsiChar(lpErrorText) + ' : ' +
      IntToStr(hCapWnd));
  end;
  </code></pre>