This console application demonstrates the holding of buffers.
#include "stdafx.h"
#include "CircHoldSimple.h"
#include "BFErApi.h"                            
#include <queue>
#include <conio.h>
#include "DSapi.h"
#include "BFIOApi.h"
#include <iomanip>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
CWinApp theApp;
UINT WorkerThread(LPVOID lpdwParam);            
UINT WaitForFrameThread(LPVOID lpdwParam);      
typedef struct _DataStruct
{
    queue<BiCirHandle>* pBufferHandleQueue;     
    HANDLE*     pNewHandleSemaphore;            
    HANDLE*     pBufferQueueMutex;              
}DataStruct;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    int nRetCode = 0;
    
#if defined(_MSC_VER) && defined(_DEBUG)
    AfxEnableMemoryLeakDump(false);
    DispSurfAfxCrtWorkaround_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
    
    
    if (!AfxWinInit(::GetModuleHandle(
BFNULL), 
BFNULL, ::GetCommandLine(), 0))
 
    {
        
        _tprintf(_T("Fatal Error: MFC initialization failed\n"));
        nRetCode = 1;
    }
    else
    {
        BFU32   boardType, boardNum, init, serNum;  
 
        BFU32   cirSetupOptions = 0;                
 
        queue<BiCirHandle> BufferHandleQueue;       
        CWinThread* pWorkerThread;                  
        CWinThread* pWaitFrameThread;               
        MSG     Msg;                                
        
        
        if( DoBrdOpenDialog(BOD_BRD_NUM_NON_FAMILY|BOD_HIDEJUSTOPEN, 
            FF_BITFLOW_MODERN, &boardType, &boardNum, &init, &serNum))
        {
            return -1;
        }
        
        cout << "Enter the number of buffers to allocate: ";
        scanf_s("%d", &numBuffers);
        
        
        
        
        HANDLE NewHandleSemaphore = CreateSemaphore(
BFNULL, 0, 0x7FFFFFFF, 
BFNULL);
 
        
        srand( (
unsigned)time( 
BFNULL ) );
 
        BFU32 randNum = (
BFU32)(numBuffers * rand() / (RAND_MAX + 1.0));
 
        
        try
        {
            
            
            {
                cout << "Couldn't create display surface" << endl;
                CloseHandle(BufferQueueMutex);
                CloseHandle(NewHandleSemaphore);
                return 1;
            }
            
            cout << "\nHit any key to end application." << endl;
            
            
            DataStruct data;
            data.pBufferQueueMutex = &BufferQueueMutex;
            data.pCirc = circ;
            data.pBufferHandleQueue = &BufferHandleQueue;
            data.phDspSrf = &hDspSrf;
            data.pNewHandleSemaphore = &NewHandleSemaphore;
            data.pThreadDone = &ThreadDone;
            data.numBuffers = numBuffers;
            
            pWorkerThread = AfxBeginThread(WorkerThread, (LPVOID)&data, THREAD_PRIORITY_NORMAL);
            pWaitFrameThread = AfxBeginThread(WaitForFrameThread, (LPVOID)&data, THREAD_PRIORITY_NORMAL);
            
        }
        {
            nRetCode = -1;
        }
        
        
        while(!BFkbhit() && !ThreadDone)
        {
            if(PeekMessage(&Msg,
BFNULL,0,0,PM_REMOVE))
 
                DispatchMessage(&Msg);
            else
                Sleep(10);
        }
        
        
        ReleaseSemaphore(NewHandleSemaphore, 1, 
BFNULL);
 
        
        
        DWORD exitCode;
        while(GetExitCodeThread(pWorkerThread->m_hThread, &exitCode) && 
                                                    exitCode == STILL_ACTIVE)
        {
            Sleep(10); 
        }
        
        while(GetExitCodeThread(pWaitFrameThread->m_hThread, &exitCode) && 
                                                    exitCode == STILL_ACTIVE)
        {
            Sleep(10); 
        }
        
        
        DispSurfClose(hDspSrf);
        CloseHandle(BufferQueueMutex);
        CloseHandle(NewHandleSemaphore);
        delete circ;
        if (BFkbhit()) 
            BFgetch();
        cout << "\nHit any key to continue." << endl;
        while(!BFkbhit())
        {
            Sleep(1);
        }
    }
    return nRetCode;
}
UINT WorkerThread(LPVOID lpdwParam)
{
    DataStruct* pData = (DataStruct*)lpdwParam;
    
    
    while(*pData->pThreadDone == 
FALSE)
 
    {
        
        WaitForSingleObject(*pData->pNewHandleSemaphore, INFINITE);
        
        
        if(*pData->pThreadDone)
            break;
        
        
        WaitForSingleObject(pData->pBufferQueueMutex, INFINITE);
        cirHandle = pData->pBufferHandleQueue->front();
        pData->pBufferHandleQueue->pop();
        ReleaseMutex(pData->pBufferQueueMutex);
        try
        {
            
            
            if(!DispSurfFormatBlit(*pData->phDspSrf, cirHandle.pBufData, 
            {
                cout << "Error displaying the held buffer." << endl;
                *pData->pThreadDone = 
TRUE;
 
            }
    
            
        }
        {
            *pData->pThreadDone = 
TRUE;
 
        }
    }
    return 0;
}
UINT WaitForFrameThread(LPVOID lpdwParam)
{
    DataStruct* pData = (DataStruct*)lpdwParam;
    srand( (
unsigned)time( 
BFNULL ) );
 
    BFU32 randNum = (
BFU32)(pData->numBuffers * rand() / (RAND_MAX + 1.0));
 
    try
    {
        while(*pData->pThreadDone == 
FALSE)
 
        {
            
            rv = pData->pCirc->waitDoneFrame(INFINITE, &cirHandle);
            {
                
                
                BFU32 er = pData->pCirc->getCirError();
 
                {
                    pData->pCirc->showError(er);
                    er = pData->pCirc->getCirError();
                }
                *pData->pThreadDone = 
TRUE;
 
                return -1;
            }
            
            
            
            if(cirHandle.BufferNumber == randNum)
            {
                
                
                rv = pData->pCirc->setBufferStatus(cirHandle, 
BIHOLD);
 
                {
                    
                    
                    WaitForSingleObject(*pData->pBufferQueueMutex, INFINITE);
                    pData->pBufferHandleQueue->push(cirHandle);
                    ReleaseMutex(*pData->pBufferQueueMutex);
                    
                    
                    ReleaseSemaphore(*pData->pNewHandleSemaphore, 1, 
BFNULL);
 
                }
                else
                {
                    
                    
                    
                }
                
                randNum = (
BFU32)(pData->numBuffers * rand() / (RAND_MAX + 1.0));
 
            }
            else
            {
                
                
            }
            cout << "Acquired Buffer = " << setw(8) << cirHandle.BufferNumber << "\r";
            
        }
    }
    {
        *pData->pThreadDone = 
TRUE;
 
    }
        
    return 0;
}