This repository has been archived on 2024-12-16. You can view files and clone it, but cannot push or open issues or pull requests.
CodeBlocksPortable/Borland/BCC55/Include/bpcsusp.h

124 lines
4.5 KiB
C++

#pragma option push -b -a8 -pc -A- /*P_O_Push*/
//// bpcsuspend.h - header file for interface that allows external apps
// to request that the bpc video server release all of its devices and
// shutdown its directshow graph.
// USAGE:
// in order to request that the bpc subsystem release its devices
// create an instance of the CBPCSuspend class
// to check if this succeeded use the IsBPCSuspended member function. if IsBPCSuspended returns false
// then that means that there are active bpc video clients and you must treat this as you would a
// device busy or device open type of failure.
// when you are done with the devices destroy the CBPCSuspend class and this will notify vidsvr
// that it can resume using the devices and return to background data capturing
//
// NOTE: you must compile vidsvr.odl and include the resulting .h before including this file
// NOTE: you must have initialized com prior on this thread prior to using this object.
//
// CLSID_BPCSuspend comes from the header file generated from compiling vidsvr.odl
// IBPCSuspended comes from the header file generated from compiling vidsvr.odl
// theory of operation:
// by using GetActiveObject instead of CoCreateInstance we don't force vidsvr to be loaded just to find
// out that it wasn't running in the first place.
// by returning an object that must be released to free the devices so that vidsvr can continue background
// data capture we utilize COM to manage this resource. this means that if the external app that requested
// the devices crashes or leaks then the suspension object will be automatically released and
// vidsvr can resume using the devices without requiring a system reboot or some other unfriendly intervention.
#ifndef _MSBPCVideo_H_
#error you must include the .h generated from compiling vidsvr.odl before including this file
#endif
#ifndef BPCSUSP_H
#define BPCSUSP_H
#pragma once
#include <oleauto.h>
#ifdef _CPPUNWIND
#pragma message("bpcsusp.h using exceptions")
#define BPCTRY try {
#ifdef _DEBUG
#define BPCCATCH } catch(...) { OutputDebugString("CBPCSuspend exception\r\n");}
#else
#define BPCCATCH } catch(...) {}
#endif
#define BPCNOTHROW throw()
#else
#define BPCTRY
#define BPCCATCH
#define BPCNOTHROW
#endif
class CBPCSuspend {
IDispatch* m_pSuspended;
bool m_fBPCExists;
public:
inline CBPCSuspend() BPCNOTHROW : m_pSuspended(NULL), m_fBPCExists(false) {
BPCTRY
#ifdef _DEBUG
OutputDebugString("CBPCSuspend()::CBPCSuspend()\r\n");
TCHAR msgtemp[256];
#endif
IUnknown *pUnkSuspendor = NULL;
DWORD dwReserved;
HRESULT hr = GetActiveObject(CLSID_BPCSuspend, &dwReserved, &pUnkSuspendor);
if (SUCCEEDED(hr) && pUnkSuspendor) {
IBPCSuspend *pSuspendor = NULL;
hr = pUnkSuspendor->QueryInterface(IID_IBPCSuspend, reinterpret_cast<void **>(&pSuspendor));
pUnkSuspendor->Release();
if (SUCCEEDED(hr) && pSuspendor) {
#ifdef _DEBUG
OutputDebugString("CBPCSuspend()::CBPCSuspend() BPC exists\r\n");
#endif
m_fBPCExists = true;
hr = pSuspendor->DeviceRelease(0L, &m_pSuspended);
if (FAILED(hr) || !m_pSuspended) {
#ifdef _DEBUG
wsprintf(msgtemp, "CBPCSuspend()::CBPCSuspend() Suspendor->DeviceRelease() rc = %lx\r\n", hr);
OutputDebugString(msgtemp);
#endif
ASSERT(!m_pSuspended);
}
#ifdef _DEBUG
else {
wsprintf(msgtemp, "CBPCSuspend()::CBPCSuspend() BPC video server suspended\r\n");
OutputDebugString(msgtemp);
}
#endif
pSuspendor->Release();
}
} else {
#ifdef _DEBUG
wsprintf(msgtemp, "CBPCSuspend()::CBPCSuspend() GetActiveObject() rc = %lx\r\n", hr);
OutputDebugString(msgtemp);
#endif
}
BPCCATCH
}
inline ~CBPCSuspend() BPCNOTHROW {
BPCTRY
if (m_fBPCExists && m_pSuspended) {
m_pSuspended->Release();
m_pSuspended = NULL;
}
BPCCATCH
}
inline bool IsBPCSuspended() BPCNOTHROW {
// if m_fBPCExists but we weren't able to retrieve a suspension object then
// there are active video clients and you must treat this as a device busy/failed to open type error
if (m_fBPCExists && !m_pSuspended) {
return false;
}
return true;
}
};
#endif
// end of file - bpcsusp.h
#pragma option pop /*P_O_Pop*/