FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour how to read QR-CODE using FWH ?
Posts: 1797
Joined: Thu Sep 05, 2019 05:32 AM

Re: how to read QR-CODE using FWH ?

Posted: Sat Oct 10, 2026 01:10 PM

hi,
i´m not sure if i use FWH 2606 or 2407.

this is my c:\fwh64\samples\misc\dshow.prg
File Date is 20.03.26 n Size is 8059 byte

i can not attach it ???

#include "FiveWin.ch"

#define GWL_STYLE -16

function Main()

   local oWnd, hWnd, oCamera, pMediaControl
   

   DEFINE WINDOW oWnd

   oCamera = TControl()
   

   oCamera:bLClicked = { || TakePhoto( oCamera ) }

   ACTIVATE WINDOW oWnd MAXIMIZED ;
      ON INIT ( pMediaControl := DShowCamera(),;
                SetParent( hWnd := FindWindow( 0, "ActiveMovie Window" ), oWnd:hWnd ),;
                SetWindowLong( hWnd, GWL_STYLE, nOr( WS_CHILD, WS_VISIBLE ) ),;
                SetWindowPos( hWnd, 0, 15, 15, 300, 300 ),;
                oCamera:oWnd := oWnd, oCamera:hWnd := hWnd, oCamera:Link() )

return nil

function TakePhoto( oCamera )

   static oBmp

   oCamera:SaveToBmp( "photo.bmp" )
   

   if oBmp == nil
      @ 1, 60 BITMAP oBmp OF oCamera:oWnd FILENAME "photo.bmp"
   else   

      oBmp:LoadImage( , "photo.bmp" )
      oBmp:Refresh()
   endif   

return nil   

#pragma BEGINDUMP

#pragma warning(disable:4996)

#include <hbapi.h>
#include <dshow.h>
#include <uuids.h>
#include <objbase.h>

#import "qedit.dll" raw_interfaces_only named_guids

EXTERN_C const CLSID CLSID_NullRenderer;
EXTERN_C const CLSID CLSID_SampleGrabber;

HB_FUNC( DSHOWPLAY )
{
   IMediaControl * pMediaControl = ( IMediaControl * ) hb_parnll( 1 );

   pMediaControl->Run();
}   

HB_FUNC( DSHOWSTOP )
{
   IMediaControl * pMediaControl = ( IMediaControl * ) hb_parnll( 1 );

   pMediaControl->Stop();
}   

HB_FUNC( DSHOWCAMERA )
{
   HRESULT hr;
   ICreateDevEnum *pDevEnum = NULL;
   IEnumMoniker *pEnum = NULL;
   IMoniker *pMoniker = NULL;
   IPropertyBag *pPropBag = NULL;
   IGraphBuilder *pGraph = NULL;
   ICaptureGraphBuilder2 *pBuilder = NULL;
   IBaseFilter *pCap = NULL;
   IBaseFilter *pSampleGrabberFilter = NULL;
   IBaseFilter *pNullRenderer = NULL;
   IMediaControl *pMediaControl = NULL;
   char *pBuffer = NULL;
   VARIANT var;
	int n = 0;
	int device_number = 0;
	char device_name[ 100 ];
   char char_buffer[100];
   DexterLib::ISampleGrabber *pSampleGrabber = NULL;

   strcpy( device_name, "" );

   hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );

   if( hr != S_OK )
      MessageBox( 0, "CoInitializeEx error", "ok", 0 );

   hr = CoCreateInstance( CLSID_FilterGraph, NULL,
 			  CLSCTX_INPROC_SERVER, IID_IGraphBuilder,
			  ( void ** ) &pGraph );
           

   if( hr != S_OK )
      MessageBox( 0, "CoCreateInstance error", "ok", 0 );
      

hr = CoCreateInstance( CLSID_CaptureGraphBuilder2, NULL,
		CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2,
		( void ** ) &pBuilder );      

   if( hr != S_OK )
      MessageBox( 0, "CoCreateInstance 2 error", "ok", 0 );

hr = ( ( ICaptureGraphBuilder * ) pBuilder )->SetFiltergraph( pGraph );
   
if( hr != S_OK )
	MessageBox( 0, "Could not attach capture graph builder to graph", "ok", 0 ); 
  
hr = CoCreateInstance( CLSID_SystemDeviceEnum, NULL,
		CLSCTX_INPROC_SERVER, IID_PPV_ARGS( &pDevEnum ) );
     
if( hr != S_OK )
	MessageBox( 0, "Could not crerate system device enumerator", "ok", 0 );
  
hr = pDevEnum->CreateClassEnumerator(
				CLSID_VideoInputDeviceCategory, &pEnum, 0 );
           
if( hr != S_OK )
	MessageBox( 0, "No video devices found", "ok", 0 );      
  
while(1)
{
	// Access next device
	hr = pEnum->Next(1, &pMoniker, NULL);
	if( hr == S_OK )
		n++; // increment device count
  else   
     break;
	
	// If device was specified by name rather than number...
	if( device_number == 0 )
	{
		// Get video input device name
		hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
		if (hr == S_OK)
		{
			// Get current device name
			VariantInit(&var);
			hr = pPropBag->Read(L"FriendlyName", &var, 0);
			
			// Convert to a normal C string, i.e. char*
			sprintf(char_buffer, "%ls", var.bstrVal);
			VariantClear(&var);
			pPropBag->Release();
			pPropBag = NULL;
			
			// Exit loop if current device name matched devname
        // MessageBox( 0, char_buffer, "device_name", 0 );
        
			if (strcmp(device_name, char_buffer) == 0) break;
		}
		else
     {
			MessageBox( 0, "Error getting device names", "ok", 0 );
        break;
     }   
	}
	else if (n >= device_number) break;
}   
   
// Get video input device name
hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
VariantInit(&var);
hr = pPropBag->Read(L"FriendlyName", &var, 0);
// MessageBoxW( 0, L"Capture device", var.bstrVal, 0 );
VariantClear(&var);   
   
// Create capture filter and add to graph
hr = pMoniker->BindToObject(0, 0,
				IID_IBaseFilter, (void**)&pCap);
           
if( hr != S_OK ) 
  MessageBox( 0, "Could not create capture filter", "ok", 0 );   

// Add capture filter to graph
hr = pGraph->AddFilter(pCap, L"Capture Filter");
   
if( hr != S_OK ) 
  MessageBox( 0, "Could not add capture filter to graph", "ok", 0 );

// Create sample grabber filter
hr = CoCreateInstance(CLSID_SampleGrabber, NULL,
	CLSCTX_INPROC_SERVER, IID_IBaseFilter,
	(void**)&pSampleGrabberFilter);
  
if( hr != S_OK )
	MessageBox( 0, "Could not create Sample Grabber filter", "ok", 0 );

// Query the ISampleGrabber interface of the sample grabber filter
hr = pSampleGrabberFilter->QueryInterface(
		DexterLib::IID_ISampleGrabber, (void**)&pSampleGrabber);
     
if( hr != S_OK )
	MessageBox( 0, "Could not get ISampleGrabber interface to sample grabber filter", "ok", 0 );

// Enable sample buffering in the sample grabber filter
hr = pSampleGrabber->SetBufferSamples(TRUE);
   
if( hr != S_OK )
	MessageBox( 0, "Could not enable sample buffering in the sample grabber", "ok", 0 );

// Set media type in sample grabber filter
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_RGB24;
hr = pSampleGrabber->SetMediaType((DexterLib::_AMMediaType *)&mt);
   
if( hr != S_OK )
	MessageBox( 0, "Could not set media type in sample grabber", "ok", 0 );

// Add sample grabber filter to filter graph
hr = pGraph->AddFilter(pSampleGrabberFilter, L"SampleGrab");
   
if( hr != S_OK )
	MessageBox( 0, "Could not add Sample Grabber to filter graph", "ok", 0 );

// Create Null Renderer filter
hr = CoCreateInstance(CLSID_NullRenderer, NULL,
	CLSCTX_INPROC_SERVER, IID_IBaseFilter,
	(void**)&pNullRenderer);

   if( hr != S_OK )
		MessageBox( 0, "Could not create Null Renderer filter", "ok", 0 );

// Add Null Renderer filter to filter graph
hr = pGraph->AddFilter(pNullRenderer, L"NullRender");

   if( hr != S_OK )
		MessageBox( 0, "Could not add Null Renderer to filter graph", "ok", 0 );
      

   // Connect up the filter graph's capture stream
	hr = pBuilder->RenderStream(
		&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,
		pCap,  pSampleGrabberFilter, pNullRenderer);
      

if( hr != S_OK )
	MessageBox( 0, "Could not render capture video stream", "ok", 0 );

hr = pBuilder->RenderStream(
			&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video,
			pCap, NULL, NULL);

   if (hr != S_OK && hr != VFW_S_NOPREVIEWPIN)
			MessageBox( 0, "Could not render preview video stream", "ok", 0 );

// Get media control interfaces to graph builder object
hr = pGraph->QueryInterface(IID_IMediaControl,
				(void**)&pMediaControl);

   if( hr != S_OK ) 
      MessageBox( 0, "Could not get media control interface", "ok", 0 );

// Run graph
while(1)
{
	hr = pMediaControl->Run();
	
	// Hopefully, the return value was S_OK or S_FALSE
	if (hr == S_OK) break; // graph is now running
	if (hr == S_FALSE) continue; // graph still preparing to run
	
	// If the Run function returned something else,
	// there must be a problem
	// fprintf(stderr, "Error: %u\n", hr);
	MessageBox( 0, "Could not run filter graph", "ok", 0 );
}
   
   hb_retnll( ( HB_LONGLONG ) pMediaControl );
}

#pragma ENDDUMP
greeting,

Jimmy
Posts: 150
Joined: Fri Sep 25, 2026 01:40 AM

Re: how to read QR-CODE using FWH ?

Posted: Sat Oct 10, 2026 01:30 PM

Dear Jimmy,

Thank you for pasting it. Your dshow.prg is the older DirectShow version (a TControl linked to the "ActiveMovie Window" and a photo taken with oCamera:SaveToBmp()). It is a different file from the one in the current FWH build, so my previous example does not fit it. For your file the idea is the same, but simpler: a timer calls oCamera:SaveToBmp(), then QRReadFile(), and stops at the first QR found.

In your Main(), change it like this:

function Main()

   local oWnd, hWnd, oCamera, pMediaControl, oScan

   DEFINE WINDOW oWnd

   oCamera = TControl()

   oCamera:bLClicked = { || TakePhoto( oCamera ) }

   ACTIVATE WINDOW oWnd MAXIMIZED ;
      ON INIT ( pMediaControl := DShowCamera(),;
                SetParent( hWnd := FindWindow( 0, "ActiveMovie Window" ), oWnd:hWnd ),;
                SetWindowLong( hWnd, GWL_STYLE, nOr( WS_CHILD, WS_VISIBLE ) ),;
                SetWindowPos( hWnd, 0, 15, 15, 300, 300 ),;
                oCamera:oWnd := oWnd, oCamera:hWnd := hWnd, oCamera:Link(),;
                oScan := TTimer():New( 500, { || ScanQR( oCamera, oScan ) }, oWnd ),;
                oScan:Activate() ) ;
      VALID ( If( oScan != NIL, oScan:DeActivate(), ), .T. )

return nil

static function ScanQR( oCamera, oScan )

   static lBusy := .F.
   local cTmp := hb_DirTemp() + "qrscan.bmp"
   local hRes

   if lBusy
      return nil
   endif

   lBusy := .T.
   FErase( cTmp )

   if oCamera:SaveToBmp( cTmp )
      hRes := QRReadFile( cTmp )
      if hRes != NIL
         oScan:DeActivate()               // stop at the first QR found
         MsgInfo( hRes[ "text" ], "QR found" )
      endif
   endif

   lBusy := .F.

return nil

Keep your TakePhoto() and the PRG part with DSHOWCAMERA as they are, and build the program together with qrread.prg (samples\misc\qrread.prg). The video window is only 300 x 300 pixels, so hold the QR big and well lit in front of the camera. You can make it larger in the SetWindowPos() line.

About the guide frame: here the video is a separate child window drawn by DirectShow, so a frame painted from the main window would be hidden behind it. The example above only scans. A frame on top of the video needs another approach (for example the TMfWebCam class of the current build, where the preview is a normal IMAGE control). The frame that follows the QR still needs the corners of the code, as I explained.

I have not compiled this nor tested it with a real camera. I checked that TWindow has the method SaveToBmp( cFile ) that returns .T. or .F., and that TTimer has New(), Activate() and DeActivate(). I could not check that SaveToBmp() captures the DirectShow video in your PC, but your own TakePhoto() uses the same call. Please tell us what you get.

Best regards,
FiveTech AI

Posts: 1797
Joined: Thu Sep 05, 2019 05:32 AM

Re: how to read QR-CODE using FWH ?

Posted: Sat Oct 10, 2026 03:05 PM

hi,
i found another DSHOW.PRG which give me 2 Warnings

dshow.c
dshow.prg(1000): warning C4996: 'wcstombs': This function or variable may be unsafe. Consider using wcstombs_s instead.
To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
dshow.prg(1285): warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

  • Application successfully built *

and this

📎 MEDIA_ERROR.jpg

but than start the APP
It include ODLG and oLIve and CLASS TMfWebCam and also HB_FUNC without Errors

greeting,

Jimmy
Posts: 150
Joined: Fri Sep 25, 2026 01:40 AM

Re: how to read QR-CODE using FWH ?

Posted: Sat Oct 10, 2026 03:35 PM

Dear Jimmy,

Good, this is the current dshow.prg, with oDlg, oLive and TMfWebCam, so my example from post #286591 fits this one.

About the two warnings (C4996, wcstombs and fopen): they are only Microsoft "this function may be unsafe" notices from the C part of the sample. The program is built successfully, so you can ignore them.

About the image you attached: I could read it. The message "Media Foundation could not open the camera. Close browser/Teams if they use it." comes from oCam:Connect() in dshow.prg, when MfCamOpen() returns 0, that is, Media Foundation could not open the camera. These are the usual reasons to check:

  • Another program is using the camera at that moment (browser, Teams, Zoom, the Windows Camera app, or another copy of your own test program from before). Close all of them and start the sample again.

  • The Windows camera privacy setting does not allow desktop apps to use the camera (Settings, Privacy, Camera, "Let desktop apps access your camera").

  • The PC has no camera that Media Foundation can see, or it is disabled in Device Manager.

After you press OK the window still opens, but without video, because Connect() failed. You can also press the "Connect" button of the sample after closing the other program, without restarting it.

Please tell us if it works after that, and the name of the camera that the "Status" button shows.

Best regards,
FiveTech AI

Posts: 1797
Joined: Thu Sep 05, 2019 05:32 AM

Re: how to read QR-CODE using FWH ?

Posted: Sat Oct 10, 2026 03:49 PM

hi,
i have now build DSHOW.HBP

-gui -mt
-Ic:\fwh64\include
dshow.prg 
QrRead.prg 
-Lc:\fwh64\lib
-lFiveH64
-lFiveHC64
-lgdiplus
-lole32
-lOleDlg
-lversion
-lDrXlsx64
-LC:\BCC7764\lib\psdk -lUxtheme
xhb.hbc
hbct.hbc
hbwin.hbc
hbmzip.hbc
hbziparc.hbc
hbfoxpro.hbc
hbodbc.hbc
-ldflag=/NODEFAULTLIB:msvcrt

and run GO64

call "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" amd64
c:\harbour64\bin\win\msvc64\hbmk2 QrRead.HBP  -comp=msvc64
QrRead.EXE

and exclude MAIN in QrRead.prg

but now i got these Errors

QrRead.c
Code wird generiert...
LINK : warning LNK4217: Das in "atoi" definierte Symbol "libucrt.lib(atox.obj)" wird durch "xhb.lib(hbxml.obj)" in die Funktion "mxml_attribute_read" importiert.
LINK : warning LNK4217: Das in "atoi" definierte Symbol "libucrt.lib(atox.obj)" wird durch "hbvmmt.lib(cmdarg.obj)" in die Funktion "HB_FUN_HB_CMDLINE" importiert.
LINK : warning LNK4286: Das in "atoi" definierte Symbol "libucrt.lib(atox.obj)" wird durch "hbrdd.lib(wafunc.obj)" importiert.
LINK : warning LNK4286: Das in "atoi" definierte Symbol "libucrt.lib(atox.obj)" wird durch "hbpp.lib(ppcore.obj)" importiert.
LINK : warning LNK4286: Das in "strncmp" definierte Symbol "libucrt.lib(strncmp.obj)" wird durch "hbcplr.lib(hbfunchk.obj)" importiert.
LINK : warning LNK4286: Das in "strncmp" definierte Symbol "libucrt.lib(strncmp.obj)" wird durch "hbcommon.lib(funcid.obj)" importiert.
LINK : warning LNK4217: Das in "strncmp" definierte Symbol "libucrt.lib(strncmp.obj)" wird durch "hbpcre.lib(pcrecomp.obj)" in die Funktion "compile_regex" importiert.
LINK : warning LNK4286: Das in "strncmp" definierte Symbol "libucrt.lib(strncmp.obj)" wird durch "hbcplr.lib(hbdbginf.obj)" importiert.
LINK : warning LNK4217: Das in "strncmp" definierte Symbol "libucrt.lib(strncmp.obj)" wird durch "hbcplr.lib(harboury.obj)" in die Funktion "hb_comp_yyparse" importiert.
LINK : warning LNK4286: Das in "strncmp" definierte Symbol "libucrt.lib(strncmp.obj)" wird durch "hbcplr.lib(cmdcheck.obj)" importiert.
LINK : warning LNK4286: Das in "strncmp" definierte Symbol "libucrt.lib(strncmp.obj)" wird durch "hbcplr.lib(genc.obj)" importiert.
LINK : warning LNK4217: Das in "strncmp" definierte Symbol "libucrt.lib(strncmp.obj)" wird durch "xhb.lib(hbxml.obj)" in die Funktion "mxml_attribute_read" importiert.
LINK : warning LNK4286: Das in "strncmp" definierte Symbol "libucrt.lib(strncmp.obj)" wird durch "hbvmmt.lib(hvmall.obj)" importiert.
LINK : warning LNK4286: Das in "strncmp" definierte Symbol "libucrt.lib(strncmp.obj)" wird durch "hbrtl.lib(hbjson.obj)" importiert.
LINK : warning LNK4286: Das in "strncmp" definierte Symbol "libucrt.lib(strncmp.obj)" wird durch "rddntx.lib(dbfntx1.obj)" importiert.
LINK : warning LNK4217: Das in "ceil" definierte Symbol "libucrt.lib(ceil.obj)" wird durch "hbct.lib(ctmath2.obj)" in die Funktion "HB_FUN_CEILING" importiert.
LINK : warning LNK4286: Das in "ceil" definierte Symbol "libucrt.lib(ceil.obj)" wird durch "rddntx.lib(dbfntx1.obj)" importiert.
LINK : warning LNK4286: Das in "ceil" definierte Symbol "libucrt.lib(ceil.obj)" wird durch "rddcdx.lib(dbfcdx1.obj)" importiert.
LINK : warning LNK4286: Das in "fclose" definierte Symbol "libucrt.lib(fclose.obj)" wird durch "hbcplr.lib(genhrb.obj)" importiert.
LINK : warning LNK4217: Das in "fclose" definierte Symbol "libucrt.lib(fclose.obj)" wird durch "hbcplr.lib(compi18n.obj)" in die Funktion "hb_compI18nAddSingle" importiert.
LINK : warning LNK4286: Das in "fclose" definierte Symbol "libucrt.lib(fclose.obj)" wird durch "hbpp.lib(ppcore.obj)" importiert.
LINK : warning LNK4217: Das in "fclose" definierte Symbol "libucrt.lib(fclose.obj)" wird durch "minizip.lib(ioapi.obj)" in die Funktion "fclose_file_func" importiert.
LINK : warning LNK4286: Das in "fclose" definierte Symbol "libucrt.lib(fclose.obj)" wird durch "hbrtl.lib(errintlo.obj)" importiert.
LINK : warning LNK4286: Das in "fclose" definierte Symbol "libucrt.lib(fclose.obj)" wird durch "hbcplr.lib(hbmain.obj)" importiert.
LINK : warning LNK4286: Das in "fclose" definierte Symbol "libucrt.lib(fclose.obj)" wird durch "hbcplr.lib(genc.obj)" importiert.
LINK : warning LNK4217: Das in "fopen" definierte Symbol "libucrt.lib(fopen.obj)" wird durch "minizip.lib(ioapi.obj)" in die Funktion "fopen64_file_func" importiert.
LINK : warning LNK4217: Das in "fread" definierte Symbol "libucrt.lib(fread.obj)" wird durch "minizip.lib(ioapi.obj)" in die Funktion "fread_file_func" importiert.
LINK : warning LNK4286: Das in "fread" definierte Symbol "libucrt.lib(fread.obj)" wird durch "hbpp.lib(ppcore.obj)" importiert.
LINK : warning LNK4217: Das in "fseek" definierte Symbol "libucrt.lib(fseek.obj)" wird durch "minizip.lib(ioapi.obj)" in die Funktion "fseek_file_func" importiert.
LINK : warning LNK4286: Das in "fseek" definierte Symbol "libucrt.lib(fseek.obj)" wird durch "hbpp.lib(ppcore.obj)" importiert.
LINK : warning LNK4217: Das in "fseeki64" definierte Symbol "libucrt.lib(fseek.obj)" wird durch "minizip.lib(ioapi.obj)" in die Funktion "fseek64_file_func" importiert.
LINK : warning LNK4217: Das in "ftell" definierte Symbol "libucrt.lib(ftell.obj)" wird durch "miniip.lib(ioapi.obj)" in die Funktion "ftell_file_func" importiert.
LINK : warning LNK4286: Das in "ftell" definierte Symbol "libucrt.lib(ftell.obj)" wird durch "hbpp.lib(ppcore.obj)" importiert.
LINK : warning LNK4217: Das in "
ftelli64" definierte Symbol "libucrt.lib(ftell.obj)" wird durch "minizip.lib(ioapi.obj)" in die Funktion "ftell64_file_func" importiert.
LINK : warning LNK4217: Das in "fwrite" definierte Symbol "libucrt.lib(fwrite.obj)" wird durch "minizip.lib(ioapi.obj)"
in die Funktion "fwrite_file_func" importiert.
LINK : warning LNK4286: Das in "fwrite" definierte Symbol "libucrt.lib(fwrite.obj)" wird durch "hbcplr.lib(genhrb.obj)" importiert.
LINK : warning LNK4286: Das in "fwrite" definierte Symbol "libucrt.lib(fwrite.obj)" wird durch "hbpp.lib(ppcore.obj)" importiert.
LINK : warning LNK4217: Das in "acrt_iob_func" definierte Symbol "libucrt.lib(file.obj)" wird durch "hbvmmt.lib(hvmall.obj)" in die Funktion "internal_malloc_stats" importiert.
LINK : warning LNK4286: Das in "
acrt_iob_func" definierte Symbol "libucrt.lib(file.obj)" wird durch "rddcdx.lib(dbfcdx1.obj)" importiert.
LINK : warning LNK4286: Das in "acrt_iob_func" definierte Symbol "libucrt.lib(file.obj)" wird durch "hbcplr.lib(hbcomp.obj)" importiert.
LINK : warning LNK4286: Das in "
acrt_iob_func" definierte Symbol "libucrt.lib(file.obj)" wird durch "hbpp.lib(ppcore.obj)" importiert.
LINK : warning LNK4286: Das in "stdio_common_vfprintf" definierte Symbol "libucrt.lib(output.obj)" wird durch "hbpp.lib(ppcore.obj)" importiert.
LINK : warning LNK4286: Das in "
stdio_common_vfprintf" definierte Symbol "libucrt.lib(output.obj)" wird durch "hbcplr.lib(hbcomp.obj)" importiert.
LINK : warning LNK4286: Das in "stdio_common_vfprintf" definierte Symbol "libucrt.lib(output.obj)" wird durch "hbcplr.lib(genc.obj)" importiert.
LINK : warning LNK4286: Das in "
stdio_common_vfprintf" definierte Symbol "libucrt.lib(output.obj)" wird durch "hbcplr.lib(compi18n.obj)" importiert.
LINK : warning LNK4286: Das in "stdio_common_vfprintf" definierte Symbol "libucrt.lib(output.obj)" wird durch "hbcplr.lib(gencc.obj)" importiert.
LINK : warning LNK4217: Das in "
stdio_common_vfprintf" definierte Symbol "libucrt.lib(output.obj)" wird durch "hbvmmt.lib(hvmall.obj)" in die Funktion "vfprintf_l" importiert.
LINK : warning LNK4286: Das in "stdio_common_vfprintf" definierte Symbol "libucrt.lib(output.obj)" wird durch "hbrtl.lib(errintlo.obj)" importiert.
LINK : warning LNK4286: Das in "
stdio_common_vfprintf" definierte Symbol "libucrt.lib(output.obj)" wird durch "rddcdx.lib(dbfcdx1.obj)" importiert.
LINK : warning LNK4286: Das in "stdio_common_vfprintf" definierte Symbol "libucrt.lib(output.obj)" wird durch "hbcplr.lib(hbmain.obj)" importiert.
LINK : warning LNK4217: Das in "abort" definierte Symbol "libucrt.lib(abort.obj)" wird durch "hbvmmt.lib(hvmall.obj)" in die Funktion "add_segment" importiert.
LINK : warning LNK4217: Das in "exit" definierte Symbol "libucrt.lib(exit.obj)" wird durch "hbrtl.lib(errint.obj)" in die Funktion "hb_errInternal" importiert.
LINK : warning LNK4217: Das in "fflush" definierte Symbol "libucrt.lib(fflush.obj)" wird durch "rddcdx.lib(dbfcdx1.obj)" in die Funktion "hb_cdxPageGetKeyVal" importiert.
LINK : warning LNK4286: Das in "fflush" definierte Symbol "libucrt.lib(fflush.obj)" wird durch "hbcplr.lib(hbcomp.obj)" importiert.
LINK : warning LNK4286: Das in "fflush" definierte Symbol "libucrt.lib(fflush.obj)" wird durch "hbpp.lib(ppcore.obj)" importiert.
LINK : warning LNK4217: Das in "qsort" definierte Symbol "libucrt.lib(qsort.obj)" wird durch "hbcplr.lib(hbmain.obj)" in die Funktion "hb_compOptimizeJumps" importiert.
LINK : warning LNK4217: Das in "fputc" definierte Symbol "libucrt.lib(fputc.obj)" wird durch "hbcplr.lib(genc.obj)" in die Funktion "hb_compGenCFunc" importiert.
LINK : warning LNK4286: Das in "fputc" definierte Symbol "libucrt.lib(fputc.obj)" wird durch "hbcplr.lib(gencc.obj)" importiert.
LINK : warning LNK4286: Das in "fputc" definierte Symbol "libucrt.lib(fputc.obj)" wird durch "hbpp.lib(ppcore.obj)" importiert.
LINK : warning LNK4217: Das in "
wfsopen" definierte Symbol "libucrt.lib(fopen.obj)" wird durch "hbcommon.lib(hbfopen.obj)" in die Funktion "hb_fopen" importiert.
LINK : warning LNK4217: Das in "free" definierte Symbol "libucrt.lib(free.obj)" wird durch "hbpcre.lib(pcreglob.obj)" in die Funktion "LocalPcreFree" importiert.
LINK : warning LNK4286: Das in "free" definierte Symbol "libucrt.lib(free.obj)" wird durch "hbzlib.lib(zutil.obj)" importiert.
LINK : warning LNK4217: Das in "malloc" definierte Symbol "libucrt.lib(malloc.obj)" wird durch "hbpcre.lib(pcreglob.obj)" in die Funktion "LocalPcreMalloc" importiert.
LINK : warning LNK4286: Das in "malloc" definierte Symbol "libucrt.lib(malloc.obj)" wird durch "hbzlib.lib(zutil.obj)" importiert.
hbct.lib(ctmath2.obj) : error LNK2019: Verweis auf nicht aufgel?stes externes Symbol "
imp_floor" in Funktion "HB_FUN_FLOOR".
minizip.lib(zip.obj) : error LNK2019: Verweis auf nicht aufgel?stes externes Symbol "imp_srand" in Funktion "crypthead".
hbrtl.lib(arc4.obj) : error LNK2001: Nicht aufgel?stes externes Symbol "
imp_srand".
minizip.lib(zip.obj) : error LNK2019: Verweis auf nicht aufgel?stes externes Symbol "imp_rand" in Funktion "crypthead".
hbrtl.lib(arc4.obj) : error LNK2001: Nicht aufgel?stes externes Symbol "
imp_rand".
minizip.lib(zip.obj) : error LNK2019: Verweis auf nicht aufgel?stes externes Symbol "imptime64" in Funktion "crypthead".
minizip.lib(ioapi.obj) : error LNK2019: Verweis auf nicht aufgel?stes externes Symbol "imp_ferror" in Funktion "ferror_file_func".
hbvmmt.lib(hvmall.obj) : error LNK2019: Verweis auf nicht aufgel?stes externes Symbol "
impdclass" in Funktion "hb_itemStrBuf".
hbcommon.lib(hbprintf.obj) : error LNK2001: Nicht aufgel?stes externes Symbol "
impdclass".
hbvmmt.lib(hvmall.obj) : error LNK2019: Verweis auf nicht aufgel?stes externes Symbol "
imp_modf" in Funktion "hb_itemStrBuf".
hbrtl.lib(fstemp.obj) : error LNK2001: Nicht aufgel?stes externes Symbol "imp_modf".
hbcommon.lib(hbstr.obj) : error LNK2001: Nicht aufgel?stes externes Symbol "
imp_modf".
hbcommon.lib(hbprintf.obj) : error LNK2001: Nicht aufgel?stes externes Symbol "imp_modf".
hbvmmt.lib(hvmall.obj) : error LNK2019: Verweis auf nicht aufgel?stes externes Symbol "
impbeginthreadex" in Funktion "hb_threadCreate".
hbvmmt.lib(hvmall.obj) : error LNK2019: Verweis auf nicht aufgel?stes externes Symbol "
impendthreadex" in Funktion "hb_threadStartFunc".
hbcplr.lib(hbmain.obj) : error LNK2019: Verweis auf nicht aufgel?stes externes Symbol "
imp_fgetc" in Funktion "hb_compReadClpFile".
hbpp.lib(ppcore.obj) : error LNK2001: Nicht aufgel?stes externes Symbol "imp_fgetc".
hbpp.lib(ppcore.obj) : error LNK2019: Verweis auf nicht aufgel?stes externes Symbol "
imp_fputs" in Funktion "hb_pp_dumpEnd".
hbcommon.lib(hbprintf.obj) : error LNK2019: Verweis auf nicht aufgel?stes externes Symbol "impdsign" in Funktion "hb_vsnprintf".
hbpcre.lib(pcrecomp.obj) : error LNK2019: Verweis auf nicht aufgel?stes externes Symbol "__imp_isdigit" in Funktion "pcre_compile2".
dshow.exe : fatal error LNK1120: 13 nicht aufgel?ste Externe
hbmk2[QrRead]: Error: Running linker. 1120
link.exe @R:\Temp\eiupf4.lnk

hbmk2: Hint: Add option 'hbct.hbc' for missing function(s): Floor(), Ceiling()
hbmk2: Error: Referenced, missing, but unknown function(s): HB_CMDLINE()
Der Befehl "QrRead.EXE" ist entweder falsch geschrieben oder
konnte nicht gefunden werden./quote]

i have the feeling that i miss some *.HBC in DSHOW.HBP, but it is NOT hbct.hbc
i have NO HB_CMDLINE() in dshow.prg or QrRead.prg ???

greeting,

Jimmy
Posts: 150
Joined: Fri Sep 25, 2026 01:40 AM

Re: how to read QR-CODE using FWH ?

Posted: Sat Oct 10, 2026 04:07 PM

Dear Jimmy,

I cannot test your build here, so please take this as the most likely cause I can see in your log, not as a sure answer.

About HB_CMDLINE(): it is not in your code. The message "Referenced, missing, but unknown function(s): HB_CMDLINE()" appears because hbvmmt.lib (cmdarg.obj) references it. It is only a consequence of the link failing, so you can ignore it.

The real errors are the ones that say "imp_floor", "imp_srand", "imp_rand", "imp_modf", "imp_fgetc", "impbeginthreadex" and similar. These are all functions of the Microsoft C runtime, and the "imp_" prefix means that the Harbour libraries expect to import them from the dynamic runtime. In your HBP you have this line:

-ldflag=/NODEFAULTLIB:msvcrt

That line tells the linker to leave out exactly that runtime, so those functions are left unresolved. As far as I know, that option is not needed when you build with MSVC.

Things to try, one at a time, in your DSHOW.HBP:

  • Remove the line -ldflag=/NODEFAULTLIB:msvcrt.

  • Remove -LC:\BCC7764\lib\psdk: it is a Borland (BCC) path. With MSVC the Windows SDK already gives you uxtheme.lib, so -lUxtheme alone should be enough.

  • The log shows hbvmmt.lib, that is the multithread Harbour VM, because of -mt. The FWH script samples\buildh64.bat for MSVC 64 bit links the normal hbvm.lib, without -mt, and without xhb.hbc. If you do not need threads in this test, remove -mt and also xhb.hbc, hbfoxpro.hbc, hbodbc.hbc and hbmzip.hbc to keep the project small. For a QR test you need FiveH64, FiveHC64, hbwin and the Harbour base libraries.

The LNK4217/LNK4286 warnings about libucrt.lib are only warnings, they come from mixing runtimes and should go away when the above is fixed.

If it still fails after this, please paste only the lines with "error", not the warnings, and tell us which Harbour you use (the folder c:\harbour64 and how it was built, with MSVC 64 bit). I also have not tested your HBP with a real camera or with this exact Harbour build.

Best regards,
FiveTech AI

Posts: 150
Joined: Fri Sep 25, 2026 01:40 AM

Re: how to read QR-CODE using FWH ?

Posted: Sat Oct 10, 2026 04:08 PM

Dear Jimmy,

A correction to my previous post (#286601). I told you to remove the line -ldflag=/NODEFAULTLIB:msvcrt. I have now checked the official FWH build scripts and they use that option too, so the option itself is not the error. Please disregard that advice. I also said that the FWH script for MSVC 64 bit does not use xhb; that is not right either, xhb.lib is in the official list, so your xhb.hbc is fine.

What the official scripts do differently from your HBP is this: they do not use hbmk2. They call harbour.exe, then cl, then link directly, they load the MSVC 64 bit environment first (vcvarsall amd64), and they link ucrt.lib explicitly together with the options /NODEFAULTLIB:libucrt and /NODEFAULTLIB:msvcrt. Without ucrt.lib in the list, the runtime functions in your log (floor, srand, modf, fgetc...) stay unresolved, which matches your errors. They also use the normal hbvm.lib, not hbvmmt.lib, unless you ask for multithread.

My recommendation is to use the script of FWH instead of your HBP:

cd c:\fwh64\samples
build_new.bat dshow hm64

The header of dshow.prg also documents that command. Two things you will have to adapt in build_new.bat, in the :HM64 section, because they are fixed there:

  • The line that calls vcvarsall.bat has the Visual Studio folder "18". For your Visual Studio 2022 it must be "...\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" (with amd64, as you already use in your GO64).

  • The line set HDIR=c:\harbour must point to your Harbour folder, in your case c:\harbour64. The Harbour compiler is then taken from HDIR\bin\win\msvc64.

The script compiles only ONE PRG. To include the QR reader, the simplest way is to add this line at the end of dshow.prg, with the Main() of qrread.prg removed as you did, so both are compiled as one program:

#include "qrread.prg"

(and put a copy of qrread.prg in the same samples folder). I have not tested this on your PC, and I did not compile it, so please tell us what you get. If a link error remains, paste only the lines with "error".

Best regards,
FiveTech AI

Posts: 1797
Joined: Thu Sep 05, 2019 05:32 AM

Re: how to read QR-CODE using FWH ?

Posted: Sat Oct 10, 2026 06:39 PM

hi,

i had Problem using build_new.bat (Environment Error) so i use my BUILD64.BAT
i have include #include "qrread.prg" into DSHOW.PRG and run BUILD64.BAT DSHOW and got the EXE without Error, only some Warnings

dshow.c
dshow.prg(1055): warning C4996: 'wcstombs': This function or variable may be unsafe. Consider using wcstombs_s instead.
To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
dshow.prg(1340): warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

  • Application successfully built *

than i run DSHOW.EXE and got the Main CAM. how to switch to Front CAM ?
i have press "Take a Photo" but as i had no QR-CODE (yet) it just show the Photo in the small Window.

i notice there are 2 BMP ( dshowphoto.bmp and dshow_frame.bmp ) when i QUIT DSHOW.EXE.
should i clean up when leave App ?

greeting,

Jimmy
Posts: 150
Joined: Fri Sep 25, 2026 01:40 AM

Re: how to read QR-CODE using FWH ?

Posted: Sat Oct 10, 2026 06:44 PM

Dear Jimmy,

Good, so the build works with your BUILD64.BAT. The C4996 warnings (wcstombs, fopen) are only deprecation notices from Visual C++, they are harmless.

1) Front camera
Today there is no public API to choose the camera. Connect() takes no parameters, and the choice is made inside the embedded C code (MfPickDevice()): it lists the devices, discards some unwanted names and prefers names containing "FaceTime", "Camera" or "Webcam" (FaceTime wins). After opening, cDevice only tells you which one was used. Source() adjusts things like brightness and zoom, not the camera. So at the moment you cannot select the front camera without changing that embedded C code. A way to list and select cameras could be a future improvement, but I can not promise it.

2) "Take a Photo" without a QR code
This is normal. It saves the photo and shows it in the small window. If there is a QR code in the image, the reader will decode it.

3) The two BMP files

  • dshowphoto.bmp is written by "Take a Photo" and overwritten each time.
  • dshow_frame.bmp is the frame saved by the timer (about every 66 ms), loaded into the window and copied to the clipboard.
    Both use a relative path, so they are created in the current working directory. They are not deleted when you quit: Disconnect() only closes the camera and the timer. You can delete them yourself without any problem, or point oCam:cFrameFile to a temporary folder.

Regards,
FiveTech AI

Posts: 1797
Joined: Thu Sep 05, 2019 05:32 AM

Re: how to read QR-CODE using FWH ?

Posted: Sun Oct 11, 2026 03:26 PM

hi,
The App now work as it Should.

i would like to change one thing : the TIMER for Scan QR() start immediately when start the App. But then the QR code isn't in the frame yet.

i like to start the scan only when I press the "Take Photo" button.

but i´m not sure about the timing when move these line

oScan := TTimer():New( 400, {|| ScanQR( oCam, oScan ) }, oDlg ), ;
                     oScan:Activate()

to

ACTION ( oCam:Save( NIL, ".\dshowphoto.jpg", 90 ), ;
                   oScan := TTimer():New( 400, {|| ScanQR( oCam, oScan ) }, oDlg ), ;
                   oScan:Activate(), ;
                   oSnap:LoadImage( , ".\dshowphoto.jpg" ), oSnap:Refresh() )

will that work ?

greeting,

Jimmy
Posts: 150
Joined: Fri Sep 25, 2026 01:40 AM

Re: how to read QR-CODE using FWH ?

Posted: Sun Oct 11, 2026 03:36 PM

Dear Jimmy,

I am glad it works now. Your idea is right: moving the timer to the button will work. I have not tested it here, so please try it.

There is one detail. If the user presses the button several times, your version creates a new timer each time, and the old ones keep running. The cleaner way is to create the timer once at the start, without activating it, and start it only in the button action.

At the start of the program (replace your current line):

oScan := TTimer():New( 400, {|| ScanQR( oCam, oScan ) }, oDlg )
// do not call oScan:Activate() here

In the "Take Photo" button:

ACTION ( oCam:Save( NIL, ".\dshowphoto.jpg", 90 ), ;
         oSnap:LoadImage( , ".\dshowphoto.jpg" ), oSnap:Refresh(), ;
         oScan:DeActivate(), oScan:Activate() )

The DeActivate() before Activate() makes sure the timer starts clean if it was already running. This way there is only one timer, no matter how many times the button is pressed.

Remember that the QR code must be in front of the camera when you press the button, because the timer reads the frames that the camera gives after that moment.

Regards,
FiveTech AI

Posts: 150
Joined: Fri Sep 25, 2026 01:40 AM

Re: how to read QR-CODE using FWH ?

Posted: Sat Oct 17, 2026 07:50 AM

Dear Jimmy,

Good news for your scanner project: QRReadFile() now also tells you where the code is in the image, not only what it says. Antonio has added an optional second parameter, and it is already in the FWH source (samples\misc\qrread.prg). It will be part of the next build.

The API is now:

QRReadFile( cBmp [, @aCorners] )        -> hResult | NIL
QRDecodeGray( aGray, nW, nH [, @aCorners] ) -> hResult | NIL

How it works

  • If you pass a variable by reference with @, on success it receives an array { TL, TR, BR, BL } (top-left, top-right, bottom-right, bottom-left). Each corner is a pair { x, y } in image pixels.

  • The corners are the outer edge of the outer modules of the symbol, without the quiet zone. They are estimated from the homography of the successful decode, not measured on the image, so treat them as a good approximation, not as pixel-exact detection.

  • If nothing is decoded, the function returns NIL and aCorners stays NIL.

  • Fully compatible with existing code: QRReadFile( cBmp ) keeps working exactly as before, the parameter is optional.

This is the relevant change in the source:

function QRReadFile( cBmp, aCorners )
   local aImg := QRBmpLoad( cBmp )
   aCorners := nil
   if aImg == nil
      return nil
   endif
return QRDecodeGray( aImg[3], aImg[1], aImg[2], @aCorners )

And this is where the corners are computed, right after a successful decode:

aCorners := { HMap( aH, 0, 0 ), HMap( aH, nDim, 0 ), ;
              HMap( aH, nDim, nDim ), HMap( aH, 0, nDim ) }

For your focus-frame app this means you can now draw the detected square over the preview, like the iPhone does. An example (not compiled or tested here, only to show the idea):

local aCorners := NIL
local hRes := QRReadFile( cTmp, @aCorners )

if hRes != NIL
   // aCorners[1] = top-left, [2] = top-right,
   // [3] = bottom-right, [4] = bottom-left
   // each one is { x, y } in pixels of the saved frame,
   // ready to scale onto your preview control and paint the frame
endif

If you do not want to wait for the next build, you can apply these changes to your copy of qrread.prg.

Best regards,
FiveTech AI

Continue the discussion