|
|
// acqmgr.h : Declaration of the CAcquisitionManager
#ifndef __AcquisitionManager_H_INCLUDED
#define __AcquisitionManager_H_INCLUDED
#include "resource.h" // main symbols
#include "acqthrd.h"
#include "shmemsec.h"
#include "mintrans.h"
#include "stievent.h"
//
// Number of times we will spin before giving up on
// getting the window of the previous wizard's instance
//
const int c_nMaxActivationRetryCount = 40;
//
// Amount of time to wait between efforts to obtain the previous
// wizard's instance
//
const DWORD c_nActivationRetryWait = 500;
/////////////////////////////////////////////////////////////////////////////
// CAcquisitionManager
class ATL_NO_VTABLE CAcquisitionManager : public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<CAcquisitionManager, &CLSID_AcquisitionManager>, public IWiaEventCallback { public: CAcquisitionManager() { }
~CAcquisitionManager() { }
DECLARE_REGISTRY_RESOURCEID(IDR_ACQUISITIONMANAGER)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CAcquisitionManager) COM_INTERFACE_ENTRY(IWiaEventCallback) END_COM_MAP()
public: // IManager
HRESULT STDMETHODCALLTYPE ImageEventCallback( const GUID *pEventGUID, BSTR bstrEventDescription, BSTR bstrDeviceID, BSTR bstrDeviceDescription, DWORD dwDeviceType, BSTR bstrFullItemName, ULONG *pulEventType, ULONG ulReserved ) { WIA_PUSHFUNCTION((TEXT("CAcquisitionManager::ImageEventCallback")));
//
// Don't want to run if this is a scanner connection event
//
if (pEventGUID && *pEventGUID==WIA_EVENT_DEVICE_CONNECTED && GET_STIDEVICE_TYPE(dwDeviceType)==StiDeviceTypeScanner) { return S_FALSE; }
//
// Try to create or open the shared memory section.
//
CSharedMemorySection<HWND> *pWizardSharedMemory = new CSharedMemorySection<HWND>; if (pWizardSharedMemory) { //
// Assume we'll be running the wizard.
//
bool bRun = true;
//
// If we were able to open the memory section
//
if (CSharedMemorySection<HWND>::SmsOpened == pWizardSharedMemory->Open( CSimpleStringConvert::NaturalString(CSimpleStringWide(bstrDeviceID)), true )) { //
// Try to get the previous instance
//
for (int i=0;i<c_nMaxActivationRetryCount;i++) { //
// if we were able to open the shared memory section, there is already one running.
// so get a mutex'ed pointer to the shared memory.
//
HWND *pHwnd = pWizardSharedMemory->Lock(); if (pHwnd) { //
// If we were able to get the pointer, get the window handle stored in it.
// Set bRun to false, so we don't start up a new wizard
//
bRun = false; if (*pHwnd && IsWindow(*pHwnd)) { //
// If it is a valid window, bring it to the foreground.
//
SetForegroundWindow(*pHwnd); } //
// Release the mutex
//
pWizardSharedMemory->Release();
//
// We found the window the window handle, so we can exit the loop now.
//
break; }
//
// Wait a while for the previous instance to be created
//
Sleep(c_nActivationRetryWait); } }
//
// We only do this if we need to open a new instance
//
if (bRun) { //
// Prepare the event data
//
CEventParameters EventParameters; EventParameters.EventGUID = *pEventGUID; EventParameters.strEventDescription = static_cast<LPCWSTR>(bstrEventDescription); EventParameters.strDeviceID = static_cast<LPCWSTR>(bstrDeviceID); EventParameters.strDeviceDescription = static_cast<LPCWSTR>(bstrDeviceDescription); EventParameters.ulReserved = ulReserved; EventParameters.ulEventType = *pulEventType; EventParameters.hwndParent = NULL; EventParameters.pWizardSharedMemory = pWizardSharedMemory;
//
// If we are started manually, it will be with the IID_NULL event
// If this is the case, we are going to treat the number stored as text as
// the "parent" window handle, over which all windows will be centered
//
if (pEventGUID && *pEventGUID==IID_NULL) { EventParameters.hwndParent = reinterpret_cast<HWND>(static_cast<UINT_PTR>(WiaUiUtil::StringToLong(CSimpleStringConvert::NaturalString(CSimpleStringWide(bstrEventDescription))))); }
//
// Start up the thread that actually displays the wizard
//
HANDLE hThread = CAcquisitionThread::Create( EventParameters ); if (hThread) { //
// Prevent deletion of this structure later
//
pWizardSharedMemory = NULL;
//
// Don't need this anymore
//
CloseHandle(hThread); } } else { WIA_TRACE((TEXT("There is already an instance of %ws running"), bstrDeviceID )); }
//
// Delete this memory mapped file, to prevent leaks
//
if (pWizardSharedMemory) { delete pWizardSharedMemory; } } return S_OK; } };
class ATL_NO_VTABLE CMinimalTransfer : public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<CMinimalTransfer, &CLSID_MinimalTransfer>, public IWiaEventCallback { public: CMinimalTransfer() { }
~CMinimalTransfer() { }
DECLARE_REGISTRY_RESOURCEID(IDR_MINIMALTRANSFER)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CMinimalTransfer) COM_INTERFACE_ENTRY(IWiaEventCallback) END_COM_MAP()
public: // IManager
HRESULT STDMETHODCALLTYPE ImageEventCallback( const GUID *pEventGUID, BSTR bstrEventDescription, BSTR bstrDeviceID, BSTR bstrDeviceDescription, DWORD dwDeviceType, BSTR bstrFullItemName, ULONG *pulEventType, ULONG ulReserved ) { if (pEventGUID && *pEventGUID==WIA_EVENT_DEVICE_CONNECTED && GET_STIDEVICE_TYPE(dwDeviceType)==StiDeviceTypeScanner) { return S_FALSE; } DWORD dwThreadId; _Module.Lock(); HANDLE hThread = CreateThread( NULL, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(MinimalTransferThreadProc), SysAllocString(bstrDeviceID), 0, &dwThreadId ); if (hThread) { CloseHandle(hThread); return S_OK; } else { _Module.Unlock(); return HRESULT_FROM_WIN32(GetLastError()); } } };
class ATL_NO_VTABLE CStiEventHandler : public CComObjectRootEx<CComSingleThreadModel>, public CComCoClass<CStiEventHandler, &CLSID_StiEventHandler>, public IWiaEventCallback { public: CStiEventHandler() { }
~CStiEventHandler() { }
DECLARE_REGISTRY_RESOURCEID(IDR_STIEVENTHANDLER)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CStiEventHandler) COM_INTERFACE_ENTRY(IWiaEventCallback) END_COM_MAP()
public: HRESULT STDMETHODCALLTYPE ImageEventCallback( const GUID *pEventGUID, BSTR bstrEventDescription, BSTR bstrDeviceID, BSTR bstrDeviceDescription, DWORD dwDeviceType, BSTR bstrFullItemName, ULONG *pulEventType, ULONG ulReserved ) { //
// Package the event data for the handler
//
CStiEventData StiEventData( pEventGUID, bstrEventDescription, bstrDeviceID, bstrDeviceDescription, dwDeviceType, bstrFullItemName, pulEventType, ulReserved );
//
// Just call the handler and return it.
//
return StiEventHandler( StiEventData ); } };
#endif //__AcquisitionManager_H_INCLUDED
|