Web-cam in Delphi 7

To use web-cam in Delphi, we are going to use:

To import and use WinAPI functions in Delphi we need to use ShellAPI module

Uses
  ... , ShellAPI

For AVICap we need to define some constants and function signatures (for C++ version you can just include vfw.hwhich already have all needed functions and constants):

const
WM_CAP_START = WM_USER;
WM_CAP_STOP = WM_CAP_START + 68;
WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10;
WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11;
WM_CAP_SAVEDIB = WM_CAP_START + 25;
WM_CAP_GRAB_FRAME = WM_CAP_START + 60;
WM_CAP_SEQUENCE = WM_CAP_START + 62;
WM_CAP_FILE_SET_CAPTURE_FILEA = WM_CAP_START + 20;
 
function capCreateCaptureWindowA(lpszWindowName : PCHAR;
dwStyle : longint;
x : integer;
y : integer;
nWidth : integer;
nHeight : integer;
ParentWin : HWND;
nId : integer): HWND; stdcall external 'AVICAP32.DLL';
 
var hWndC : THandle;

Code for the function which start capturing the video from web-cam:

procedure TForm1.Button1Click(Sender: TObject);
begin
 hWndC := capCreateCaptureWindowA('My Own Capture Window',
WS_CHILD or WS_VISIBLE ,
0,
0,
Panel1.Width,
Panel1.Height,
Panel1.Handle,
0); // using Panel object to output our image from webcams
 
if hWndC <> 0 then // if Panel object is available and there were not errors during capCreateCaptureWindowA call
    SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, 0, 0);  // starting capturing
 
end;

Here you need to find a correct ID of your web-cam device. It could be 0,1,2,… depends on how many web-cams or other capturing devices you have installed.

SendMessage(hWndC, WM_CAP_DRIVER_CONNECT, <device-number>, 0);

To finish:

procedure TForm1.Button2Click(Sender: TObject);
begin
  if hWndC <> 0 then
  begin
    SendMessage(hWndC, WM_CAP_DRIVER_DISCONNECT, 0, 0);  // finish capturing
    hWndC := 0;
  end;
end;

Capture the image and show on Panel by Timer:

procedure TForm1.Timer1Timer(Sender: TObject);
begin
if hWndC <> 0 then SendMessage(hWndC, WM_CAP_GRAB_FRAME, 0, 0);
end;

One thing to mention, Panel object does not have Bitmap property, so if you want to work with image with classic GDI tools you need to use other component. For example, you can use Form component:

{…}
hWndC := capCreateCaptureWindowA(‘My Own Capture Window’,
     WS_CHILD or WS_VISIBLE ,
     0,
     0,
     Form1.Width,
     Form1.Height,
     Form1.Handle,
     0);

{…}
var
   bmp: TBitmap;
{…}
begin
{…}
   bmp := TBitmap.Create;
   bmp.Width := Form1.Width;
   bmp.Height:=Form1.Height;
   bmp.Canvas.CopyRect(Rect(0,0,Form1.Width, Form1.Height), Form1.Canvas, 
   Rect(0,0,Form1.Width, Form1.Height));
   bmp.SaveToFile('path for BMP file');
end;
{…}

WinAPI Threads

There are 2 main things to know to create a thread in Windows:

#include <windows.h>
#include <stdio.h>

void *mainThread;
DWORD * id;

// Code to execute inside thread function based on ThreadProc signature
DWORD WINAPI treadFunction(LPVOID lpParameter) {
     DWORD exitCode;
     while (GetExitCodeThread(mainThread,&exitCode) && exitCode == STILL_ACTIVE) { // while main thread did not finiched
           // executing our code in separate thread
           printf("-----------------  Hello from sub thread\r\n");
           Sleep(5000);
     }     
     return 0; 
}

int main() {
       mainThread = GetCurrentThread(); // reference to main thread of the process
       CreateThread(NULL,0,treadFunction,NULL,0,id); // creating our separate thread
       
       while(true) {
                   //  executing some code in the main process thread
                   printf("Hello from main thread\r\n");
                   Sleep(1000);
       }
       return 0;
}