936 lines
30 KiB
C++
936 lines
30 KiB
C++
/*
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
*
|
|
* Sample application that demonstrates photo acquisitions
|
|
* using methods of IPhotoAcquire
|
|
*
|
|
*/
|
|
#define UNICODE
|
|
#include <windows.h>
|
|
#include <windowsx.h>
|
|
#include <PhotoAcquire.h>
|
|
#include <shlobj.h>
|
|
#include <shellapi.h>
|
|
#include <StrSafe.h>
|
|
#include "resource.h"
|
|
|
|
|
|
HINSTANCE g_hInstance = NULL;
|
|
bool g_fSuppressErrorMessageDialog = false;
|
|
bool g_fInfiniteLoop = false;
|
|
bool g_fDeleteFilesWhenDone = false;
|
|
|
|
void OutputFormattedDebugString(PCWSTR pszFormat, ...)
|
|
{
|
|
TCHAR szBuffer[1024];
|
|
va_list pArgPtr;
|
|
va_start(pArgPtr, pszFormat);
|
|
StringCchVPrintf(szBuffer, ARRAYSIZE(szBuffer), pszFormat, pArgPtr);
|
|
va_end(pArgPtr);
|
|
|
|
OutputDebugString(szBuffer);
|
|
}
|
|
|
|
class PhotoAcquireProgressCB : public IPhotoAcquireProgressCB
|
|
{
|
|
private:
|
|
LONG m_cRef;
|
|
|
|
private:
|
|
PhotoAcquireProgressCB()
|
|
: m_cRef(1)
|
|
{
|
|
}
|
|
virtual ~PhotoAcquireProgressCB()
|
|
{
|
|
}
|
|
|
|
public:
|
|
// IUnknown methods
|
|
STDMETHODIMP_(ULONG) AddRef()
|
|
{
|
|
return InterlockedIncrement(&m_cRef);
|
|
}
|
|
|
|
|
|
STDMETHODIMP_(ULONG) Release()
|
|
{
|
|
LONG nRefCount = InterlockedDecrement(&m_cRef);
|
|
if (!nRefCount)
|
|
{
|
|
delete this;
|
|
}
|
|
return nRefCount;
|
|
}
|
|
|
|
STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObject)
|
|
{
|
|
if (IsEqualIID(riid, IID_IUnknown))
|
|
{
|
|
*ppvObject = static_cast<IPhotoAcquireProgressCB*>(this);
|
|
}
|
|
else if (IsEqualIID(riid, IID_IPhotoAcquireProgressCB))
|
|
{
|
|
*ppvObject = static_cast<IPhotoAcquireProgressCB*>(this);
|
|
}
|
|
else
|
|
{
|
|
*ppvObject = NULL;
|
|
return E_NOINTERFACE;
|
|
}
|
|
reinterpret_cast<IUnknown*>(*ppvObject)->AddRef();
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
// IPhotoAcquireProgressCB methods
|
|
STDMETHODIMP Cancelled(__out BOOL *pfCancelled)
|
|
{
|
|
OutputFormattedDebugString(L"Cancelled(pfCancelled: 0x%p)\n", pfCancelled);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP StartEnumeration(IPhotoAcquireSource *pPhotoAcquireSource)
|
|
{
|
|
OutputFormattedDebugString(L"StartEnumeration(pPhotoAcquireSource: 0x%p)\n", pPhotoAcquireSource);
|
|
return E_NOTIMPL;
|
|
}
|
|
STDMETHODIMP FoundItem(IPhotoAcquireItem *pPhotoAcquireItem)
|
|
{
|
|
OutputFormattedDebugString(L"FoundItem(pPhotoAcquireItem: 0x%p)\n", pPhotoAcquireItem);
|
|
return E_NOTIMPL;
|
|
}
|
|
STDMETHODIMP EndEnumeration(HRESULT hrEnumerate)
|
|
{
|
|
OutputFormattedDebugString(L"EndEnumeration(hr: 0x%08X)\n", hrEnumerate);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP StartTransfer(IPhotoAcquireSource *pPhotoAcquireSource)
|
|
{
|
|
OutputFormattedDebugString(L"StartTransfer(pPhotoAcquireSource: 0x%p)\n", pPhotoAcquireSource);
|
|
return E_NOTIMPL;
|
|
}
|
|
STDMETHODIMP StartItemTransfer(UINT nItemIndex, IPhotoAcquireItem *pPhotoAcquireItem)
|
|
{
|
|
OutputFormattedDebugString(L"StartItemTransfer(nItemIndex: %u, pPhotoAcquireItem: 0x%p)\n", nItemIndex, pPhotoAcquireItem);
|
|
return E_NOTIMPL;
|
|
}
|
|
STDMETHODIMP DirectoryCreated(LPCWSTR pszDirectory)
|
|
{
|
|
OutputFormattedDebugString(L"DirectoryCreated(pszDirectory: %ws)\n", pszDirectory);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
STDMETHODIMP UpdateTransferPercent(BOOL fOverall, UINT nPercent)
|
|
{
|
|
OutputFormattedDebugString(L"UpdateTransferPercent(fOverall: %d, nPercent: %u)\n", fOverall, nPercent);
|
|
return E_NOTIMPL;
|
|
}
|
|
STDMETHODIMP EndItemTransfer(UINT nItemIndex, IPhotoAcquireItem *pPhotoAcquireItem, HRESULT hr)
|
|
{
|
|
OutputFormattedDebugString(L"EndItemTransfer(nItemIndex: %d, pPhotoAcquireItem: %p, hr: 0x%08X)\n", nItemIndex, pPhotoAcquireItem, hr);
|
|
return E_NOTIMPL;
|
|
}
|
|
STDMETHODIMP EndTransfer(HRESULT hrTransfer)
|
|
{
|
|
OutputFormattedDebugString(L"EndTransfer(hr: 0x%08X)\n", hrTransfer);
|
|
return E_NOTIMPL;
|
|
}
|
|
STDMETHODIMP StartDelete(IPhotoAcquireSource* pPhotoAcquireSource)
|
|
{
|
|
OutputFormattedDebugString(L"StartDelete(pPhotoAcquireSource: 0x%p)\n", pPhotoAcquireSource);
|
|
return E_NOTIMPL;
|
|
}
|
|
STDMETHODIMP StartItemDelete(UINT nItemIndex, IPhotoAcquireItem *pPhotoAcquireItem)
|
|
{
|
|
OutputFormattedDebugString(L"StartItemDelete(nItemIndex: %u, pPhotoAcquireItem: 0x%p)\n", nItemIndex, pPhotoAcquireItem);
|
|
return E_NOTIMPL;
|
|
}
|
|
STDMETHODIMP UpdateDeletePercent(UINT nPercent)
|
|
{
|
|
OutputFormattedDebugString(L"UpdateDeletePercent(nPercent: %u)\n", nPercent);
|
|
return E_NOTIMPL;
|
|
}
|
|
STDMETHODIMP EndItemDelete(UINT nItemIndex, IPhotoAcquireItem *pPhotoAcquireItem, HRESULT hr)
|
|
{
|
|
OutputFormattedDebugString(L"EndItemDelete(nItemIndex: %u, pPhotoAcquireItem: 0x%p, hr: 0x%08X)\n", nItemIndex, pPhotoAcquireItem, hr);
|
|
return E_NOTIMPL;
|
|
}
|
|
STDMETHODIMP EndDelete(HRESULT hrDelete)
|
|
{
|
|
OutputFormattedDebugString(L"EndDelete(hr: 0x%08X)\n", hrDelete);
|
|
return E_NOTIMPL;
|
|
}
|
|
STDMETHODIMP EndSession(HRESULT hrSession)
|
|
{
|
|
OutputFormattedDebugString(L"EndSession(hr: 0x%08X)\n", hrSession);
|
|
return E_NOTIMPL;
|
|
}
|
|
STDMETHODIMP GetDeleteAfterAcquire(__out BOOL* pfDeleteAfterAcquire)
|
|
{
|
|
OutputFormattedDebugString(L"GetDeleteAfterAcquire(pfDeleteAfterAcquire: 0x%p)\n", pfDeleteAfterAcquire);
|
|
return E_NOTIMPL;
|
|
}
|
|
STDMETHODIMP ErrorAdvise(HRESULT hrError, PCWSTR pszErrorMessage, ERROR_ADVISE_MESSAGE_TYPE nMessageType, __out ERROR_ADVISE_RESULT *pnErrorAdviseResult)
|
|
{
|
|
OutputFormattedDebugString(L"ErrorAdvise(hr: 0x%08X, pszErrorMessage: %ws, nMessageType: %d, pnErrorAdviseResult: %p)\n", hrError, pszErrorMessage, nMessageType, pnErrorAdviseResult);
|
|
return E_NOTIMPL;
|
|
}
|
|
STDMETHODIMP GetUserInput(REFIID, IUnknown*, PROPVARIANT* pPropVar, const PROPVARIANT* pPropVarDefault)
|
|
{
|
|
if (g_fInfiniteLoop)
|
|
{
|
|
return PropVariantCopy(pPropVar, pPropVarDefault);
|
|
}
|
|
else
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
}
|
|
|
|
public:
|
|
static HRESULT Create(REFIID riid, __out void** ppv)
|
|
{
|
|
*ppv = NULL;
|
|
|
|
HRESULT hr;
|
|
PhotoAcquireProgressCB* pPhotoAcquireProgressCB = new PhotoAcquireProgressCB;
|
|
if (pPhotoAcquireProgressCB != NULL)
|
|
{
|
|
hr = pPhotoAcquireProgressCB->QueryInterface(riid, ppv);
|
|
pPhotoAcquireProgressCB->Release();
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
return hr;
|
|
}
|
|
};
|
|
|
|
|
|
HRESULT MsgWaitForSingleHandle(HANDLE hHandle, DWORD dwMilliseconds)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
BOOL fDone = FALSE;
|
|
while (!fDone)
|
|
{
|
|
// pull any messages out of the queue and process them
|
|
MSG msg;
|
|
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
|
|
// Wait for the handle to be signalled OR an input event
|
|
DWORD dwResult = MsgWaitForMultipleObjects(1, &hHandle, FALSE, dwMilliseconds, QS_ALLINPUT);
|
|
switch (dwResult)
|
|
{
|
|
case WAIT_OBJECT_0:
|
|
fDone = TRUE;
|
|
break;
|
|
|
|
case WAIT_OBJECT_0+1:
|
|
// Process messages
|
|
break;
|
|
|
|
case WAIT_ABANDONED:
|
|
// This handle is an abandoned mutex. Exit with a failure.
|
|
hr = HRESULT_FROM_WIN32(ERROR_ABANDONED_WAIT_0);
|
|
fDone = TRUE;
|
|
break;
|
|
|
|
case WAIT_TIMEOUT:
|
|
// The wait time expired
|
|
hr = HRESULT_FROM_WIN32(ERROR_TIMEOUT);
|
|
fDone = TRUE;
|
|
break;
|
|
|
|
case WAIT_FAILED:
|
|
default:
|
|
// Something bad happened
|
|
hr = E_UNEXPECTED;
|
|
fDone = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
class AcquireThreadData
|
|
{
|
|
private:
|
|
HWND m_hWndParent;
|
|
BOOL m_fShowProgressUi;
|
|
PWSTR m_pszCustomTemplate;
|
|
|
|
private:
|
|
// No implementation
|
|
AcquireThreadData(const AcquireThreadData&);
|
|
AcquireThreadData& operator=(const AcquireThreadData&);
|
|
|
|
public:
|
|
AcquireThreadData()
|
|
: m_hWndParent(NULL)
|
|
, m_fShowProgressUi(TRUE)
|
|
, m_pszCustomTemplate(NULL)
|
|
{
|
|
}
|
|
~AcquireThreadData()
|
|
{
|
|
if (m_pszCustomTemplate != NULL)
|
|
{
|
|
delete[] m_pszCustomTemplate;
|
|
m_pszCustomTemplate = NULL;
|
|
}
|
|
}
|
|
|
|
void SetParentWindow(HWND hWndParent)
|
|
{
|
|
m_hWndParent = hWndParent;
|
|
}
|
|
HWND GetParentWindow() const
|
|
{
|
|
return m_hWndParent;
|
|
}
|
|
|
|
void SetShowProgressUi(BOOL fShowProgressUi)
|
|
{
|
|
m_fShowProgressUi = fShowProgressUi;
|
|
}
|
|
BOOL GetShowProgressUi() const
|
|
{
|
|
return m_fShowProgressUi;
|
|
}
|
|
|
|
HRESULT SetCustomTemplate(PCWSTR pszCustomTemplate)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
if (m_pszCustomTemplate != NULL)
|
|
{
|
|
delete[] m_pszCustomTemplate;
|
|
m_pszCustomTemplate = NULL;
|
|
}
|
|
if (pszCustomTemplate != NULL)
|
|
{
|
|
size_t cchLength = lstrlen(pszCustomTemplate);
|
|
m_pszCustomTemplate = new WCHAR[cchLength + 1];
|
|
if (m_pszCustomTemplate != NULL)
|
|
{
|
|
hr = StringCchCopy(m_pszCustomTemplate, cchLength + 1, pszCustomTemplate);
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
PCWSTR GetCustomTemplate() const
|
|
{
|
|
return m_pszCustomTemplate;
|
|
}
|
|
};
|
|
|
|
HRESULT SelectDevice(HWND hWndParent, __out BSTR* pstrSelectedDeviceId)
|
|
{
|
|
*pstrSelectedDeviceId = L"";
|
|
|
|
// Create the devuce selection dialog
|
|
IPhotoAcquireDeviceSelectionDialog* pPhotoAcquireDeviceSelectionDialog = NULL;
|
|
HRESULT hr = CoCreateInstance(CLSID_PhotoAcquireDeviceSelectionDialog, NULL, CLSCTX_INPROC_SERVER, IID_IPhotoAcquireDeviceSelectionDialog, (void**)&pPhotoAcquireDeviceSelectionDialog);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Load the prompt string
|
|
WCHAR szSubmitButtonText[MAX_PATH] = {0};
|
|
LoadString(g_hInstance, IDS_SELECTION_SUBMIT_TEXT, szSubmitButtonText, ARRAYSIZE(szSubmitButtonText));
|
|
|
|
// Load the caption string
|
|
WCHAR szCaption[MAX_PATH] = {0};
|
|
LoadString(g_hInstance, IDS_SELECTION_CAPTION, szCaption, ARRAYSIZE(szCaption));
|
|
|
|
// Set the prompt
|
|
hr = pPhotoAcquireDeviceSelectionDialog->SetSubmitButtonText(szSubmitButtonText);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Set the caption
|
|
hr = pPhotoAcquireDeviceSelectionDialog->SetTitle(szCaption);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Select a device
|
|
DEVICE_SELECTION_DEVICE_TYPE nType;
|
|
hr = pPhotoAcquireDeviceSelectionDialog->DoModal(hWndParent, DSF_WPD_DEVICES|DSF_FS_DEVICES, pstrSelectedDeviceId, &nType);
|
|
}
|
|
}
|
|
pPhotoAcquireDeviceSelectionDialog->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT EnumerateTransferredFilesFromEnum(IPhotoAcquire* pPhotoAcquire)
|
|
{
|
|
OutputFormattedDebugString(L"***********************************************************\n"
|
|
L"Begin enumeration of files using IPhotoAcquire::EnumResults\n");
|
|
IEnumString* pEnumString = NULL;
|
|
HRESULT hr = pPhotoAcquire->EnumResults(&pEnumString);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
for (int nCurrentFile = 1; ; ++nCurrentFile)
|
|
{
|
|
PWSTR pszCurrent = NULL;
|
|
if (S_OK == pEnumString->Next(1, &pszCurrent, NULL))
|
|
{
|
|
OutputFormattedDebugString(L"%8d. %s\n", nCurrentFile, pszCurrent);
|
|
CoTaskMemFree(pszCurrent);
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
pEnumString->Release();
|
|
}
|
|
OutputFormattedDebugString(L"End enumeration of files using IPhotoAcquire::EnumResults\n"
|
|
L"***********************************************************\n\n");
|
|
return hr;
|
|
}
|
|
|
|
HRESULT EnumerateTransferredFilesFromItems(IPhotoAcquireSource* pPhotoAcquireSource)
|
|
{
|
|
OutputFormattedDebugString(L"***********************************************************\n"
|
|
L"Begin enumeration of files using PKEY_PhotoAcquire_FinalFilename\n");
|
|
UINT nItemCount = 0;
|
|
HRESULT hr = pPhotoAcquireSource->GetItemCount(&nItemCount);
|
|
for (UINT nCurr = 0; nCurr < nItemCount && SUCCEEDED(hr); ++nCurr)
|
|
{
|
|
IPhotoAcquireItem* pPhotoAcquireItem = NULL;
|
|
hr = pPhotoAcquireSource->GetItemAt(nCurr, &pPhotoAcquireItem);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
PROPVARIANT pv = {0};
|
|
hr = pPhotoAcquireItem->GetProperty(PKEY_PhotoAcquire_FinalFilename, &pv);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (g_fDeleteFilesWhenDone)
|
|
{
|
|
DeleteFileW(pv.pwszVal);
|
|
}
|
|
OutputFormattedDebugString(L"%8d. %s\n", nCurr + 1, pv.pwszVal);
|
|
PropVariantClear(&pv);
|
|
}
|
|
UINT nSubItemCount = 0;
|
|
hr = pPhotoAcquireItem->GetSubItemCount(&nSubItemCount);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
for (UINT nCurrentSubItem = 0; nCurrentSubItem < nSubItemCount && SUCCEEDED(hr); ++nCurrentSubItem)
|
|
{
|
|
IPhotoAcquireItem* pPhotoAcquireSubItem = NULL;
|
|
hr = pPhotoAcquireItem->GetSubItemAt(nCurrentSubItem, &pPhotoAcquireSubItem);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pPhotoAcquireSubItem->GetProperty(PKEY_PhotoAcquire_FinalFilename, &pv);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (g_fDeleteFilesWhenDone)
|
|
{
|
|
DeleteFileW(pv.pwszVal);
|
|
}
|
|
OutputFormattedDebugString(L" %8d. %s\n", nCurrentSubItem + 1, pv.pwszVal);
|
|
PropVariantClear(&pv);
|
|
}
|
|
pPhotoAcquireSubItem->Release();
|
|
}
|
|
}
|
|
}
|
|
pPhotoAcquireItem->Release();
|
|
}
|
|
}
|
|
OutputFormattedDebugString(L"End enumeration of files using PKEY_PhotoAcquire_FinalFilename\n"
|
|
L"***********************************************************\n\n");
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT TransferPhotosAndVideos(HWND hWndParent, BOOL fShowProgressUi, BOOL fUseCustomTemplate, PCWSTR pszCustomTemplate, PCWSTR pszDeviceId)
|
|
{
|
|
IPhotoAcquireProgressCB* pPhotoAcquireProgressCB = NULL;
|
|
HRESULT hr = PhotoAcquireProgressCB::Create(IID_PPV_ARGS(&pPhotoAcquireProgressCB));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
IPhotoAcquire* pPhotoAcquire = NULL;
|
|
hr = CoCreateInstance(CLSID_PhotoAcquire, NULL, CLSCTX_INPROC, IID_PPV_ARGS(&pPhotoAcquire));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
IPhotoAcquireSource* pPhotoAcquireSource = NULL;
|
|
hr = pPhotoAcquire->CreatePhotoSource(pszDeviceId, &pPhotoAcquireSource);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (fUseCustomTemplate)
|
|
{
|
|
IPhotoAcquireSettings* pPhotoAcquireSettings = NULL;
|
|
hr = pPhotoAcquireSource->GetPhotoAcquireSettings(&pPhotoAcquireSettings);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pPhotoAcquireSettings->SetOutputFilenameTemplate(pszCustomTemplate);
|
|
pPhotoAcquireSettings->Release();
|
|
}
|
|
}
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pPhotoAcquire->Acquire(pPhotoAcquireSource, fShowProgressUi, hWndParent, L"Test Application", pPhotoAcquireProgressCB);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = EnumerateTransferredFilesFromEnum(pPhotoAcquire);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = EnumerateTransferredFilesFromItems(pPhotoAcquireSource);
|
|
}
|
|
}
|
|
}
|
|
pPhotoAcquireSource->Release();
|
|
}
|
|
pPhotoAcquire->Release();
|
|
}
|
|
pPhotoAcquireProgressCB->Release();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
DWORD CALLBACK AcquireThread(__in PVOID pVoid)
|
|
{
|
|
AcquireThreadData* pAcquireThreadData = reinterpret_cast<AcquireThreadData*>(pVoid);
|
|
if (pAcquireThreadData != NULL)
|
|
{
|
|
HRESULT hr = CoInitialize(NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
BSTR bstrSelectedDeviceId = NULL;
|
|
hr = SelectDevice(pAcquireThreadData->GetParentWindow(), &bstrSelectedDeviceId);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Launch acquisition
|
|
hr = TransferPhotosAndVideos(pAcquireThreadData->GetParentWindow(), pAcquireThreadData->GetShowProgressUi(), pAcquireThreadData->GetCustomTemplate() != NULL, pAcquireThreadData->GetCustomTemplate(), bstrSelectedDeviceId);
|
|
|
|
SysFreeString(bstrSelectedDeviceId);
|
|
}
|
|
CoUninitialize();
|
|
}
|
|
|
|
delete pAcquireThreadData;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int PhotoAcquireTest_GetCheckedRadioButton(HWND hWnd)
|
|
{
|
|
int nResult = -1;
|
|
|
|
static const int s_Controls[] =
|
|
{
|
|
IDC_ACQUISITION_RADIO,
|
|
IDC_DEVSEL_RADIO,
|
|
IDC_SETTINGS_RADIO
|
|
};
|
|
for (int i = 0; i < _ARRAYSIZE(s_Controls); ++i)
|
|
{
|
|
if (IsDlgButtonChecked(hWnd, s_Controls[i]) == BST_CHECKED)
|
|
{
|
|
nResult = s_Controls[i];
|
|
break;
|
|
}
|
|
}
|
|
return nResult;
|
|
}
|
|
|
|
void PhotoAcquireTest_LaunchDeviceSelectionDialog(HWND hWnd)
|
|
{
|
|
DWORD dwDeviceTypes = 0;
|
|
static const struct
|
|
{
|
|
int nControlId;
|
|
DWORD dwDeviceType;
|
|
} s_DeviceTypes[] =
|
|
{
|
|
{IDC_DEVSEL_FS_DEVICES, DSF_FS_DEVICES},
|
|
{IDC_DEVSEL_WPD_DEVICES, DSF_WPD_DEVICES},
|
|
{IDC_DEVSEL_WIA_CAMERAS, DSF_WIA_CAMERAS},
|
|
{IDC_DEVSEL_WIA_SCANNERS, DSF_WIA_SCANNERS},
|
|
{IDC_DEVSEL_STI_DEVICES, DSF_STI_DEVICES},
|
|
{IDC_DEVSEL_DV_DEVICES, DSF_DV_DEVICES},
|
|
{IDC_DEVSEL_SHOW_OFFLINE, DSF_SHOW_OFFLINE},
|
|
{IDC_DEVSEL_CPANEL_MODE, DSF_CPL_MODE}
|
|
};
|
|
for (int i = 0; i < _ARRAYSIZE(s_DeviceTypes); ++i)
|
|
{
|
|
if (IsDlgButtonChecked(hWnd, s_DeviceTypes[i].nControlId) == BST_CHECKED)
|
|
{
|
|
dwDeviceTypes |= s_DeviceTypes[i].dwDeviceType;
|
|
}
|
|
}
|
|
|
|
// Create the device selection dialog
|
|
IPhotoAcquireDeviceSelectionDialog* pPhotoAcquireDeviceSelectionDialog = NULL;
|
|
HRESULT hr = CoCreateInstance(CLSID_PhotoAcquireDeviceSelectionDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pPhotoAcquireDeviceSelectionDialog));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Load the caption string
|
|
WCHAR szCaption[MAX_PATH] = {0};
|
|
LoadString(g_hInstance, IDS_SELECTION_CAPTION, szCaption, ARRAYSIZE(szCaption));
|
|
|
|
// Load the submit button text string
|
|
WCHAR szSubmitButtonText[MAX_PATH] = {0};
|
|
LoadString(g_hInstance, IDS_SELECTION_SUBMIT_TEXT, szSubmitButtonText, ARRAYSIZE(szSubmitButtonText));
|
|
|
|
// Set the title
|
|
hr = pPhotoAcquireDeviceSelectionDialog->SetTitle(szCaption);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Set the title
|
|
hr = pPhotoAcquireDeviceSelectionDialog->SetSubmitButtonText(szSubmitButtonText);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Select a device
|
|
if ((dwDeviceTypes & DSF_CPL_MODE) == 0)
|
|
{
|
|
BSTR bstrDeviceId = NULL;
|
|
DEVICE_SELECTION_DEVICE_TYPE nDeviceSelectionType;
|
|
hr = pPhotoAcquireDeviceSelectionDialog->DoModal(hWnd, dwDeviceTypes, &bstrDeviceId, &nDeviceSelectionType);
|
|
if (S_OK == hr)
|
|
{
|
|
TCHAR szMessage[MAX_PATH] = TEXT("");
|
|
StringCchPrintf(szMessage, ARRAYSIZE(szMessage), TEXT("Device ID: %ws, Device Type: %d"), bstrDeviceId, nDeviceSelectionType);
|
|
MessageBox(hWnd, szMessage, TEXT("Device Selection Result"), IDOK|MB_ICONINFORMATION);
|
|
SysFreeString(bstrDeviceId);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pPhotoAcquireDeviceSelectionDialog->DoModal(hWnd, dwDeviceTypes, NULL, NULL);
|
|
}
|
|
}
|
|
}
|
|
pPhotoAcquireDeviceSelectionDialog->Release();
|
|
}
|
|
}
|
|
|
|
|
|
void PhotoAcquireTest_LaunchAcquisition(HWND hWnd)
|
|
{
|
|
// Create the thread data object
|
|
AcquireThreadData* pAcquireThreadData = new AcquireThreadData;
|
|
if (pAcquireThreadData != NULL)
|
|
{
|
|
// Set the parent window unless it was suppressed
|
|
if (IsDlgButtonChecked(hWnd, IDC_ACQUIRE_USE_NULL_HWND) != BST_CHECKED)
|
|
{
|
|
pAcquireThreadData->SetParentWindow(hWnd);
|
|
}
|
|
|
|
// Suppress the progress UI if requested
|
|
if (IsDlgButtonChecked(hWnd, IDC_ACQUIRE_SUPPRESS_PROGRESS) == BST_CHECKED)
|
|
{
|
|
pAcquireThreadData->SetShowProgressUi(FALSE);
|
|
}
|
|
|
|
// Set the custom naming template if it was supplied
|
|
if (IsDlgButtonChecked(hWnd, IDC_ACQUIRE_USE_CUSTOM_TEMPLATE) == BST_CHECKED)
|
|
{
|
|
int nTextLength = GetWindowTextLength(GetDlgItem(hWnd, IDC_ACQUIRE_CUSTOM_TEMPLATE));
|
|
if (nTextLength != 0)
|
|
{
|
|
PWSTR pszText = new WCHAR[nTextLength + 1];
|
|
if (pszText != NULL)
|
|
{
|
|
GetDlgItemText(hWnd, IDC_ACQUIRE_CUSTOM_TEMPLATE, pszText, nTextLength + 1);
|
|
pAcquireThreadData->SetCustomTemplate(pszText);
|
|
delete[] pszText;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Create the worker thread
|
|
DWORD dwThreadId;
|
|
HANDLE hThread = CreateThread(NULL, 0, AcquireThread, pAcquireThreadData, 0, &dwThreadId);
|
|
if (hThread != NULL)
|
|
{
|
|
// Wait for it to finish
|
|
MsgWaitForSingleHandle(hThread, INFINITE);
|
|
CloseHandle(hThread);
|
|
}
|
|
else
|
|
{
|
|
// If we couldn't create the thread, delete the thread data
|
|
delete pAcquireThreadData;
|
|
}
|
|
}
|
|
}
|
|
|
|
void PhotoAcquireTest_LaunchSettings(HWND hWnd)
|
|
{
|
|
// Create the settings dialog object
|
|
IPhotoAcquireOptionsDialog* pDialog = NULL;
|
|
HRESULT hr = CoCreateInstance(CLSID_PhotoAcquireOptionsDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDialog));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Initialize it
|
|
hr = pDialog->Initialize(NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Run the dialog modally
|
|
INT_PTR nResult = 0;
|
|
hr = pDialog->DoModal(hWnd, &nResult);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// If the user clicked OK, then save the updated settings
|
|
if (nResult == IDOK)
|
|
{
|
|
pDialog->SaveData();
|
|
}
|
|
}
|
|
}
|
|
pDialog->Release();
|
|
}
|
|
}
|
|
|
|
|
|
void PhotoAcquireTest_UpdateControlState(HWND hWnd)
|
|
{
|
|
static const struct
|
|
{
|
|
int nControlId;
|
|
int nRadioButton;
|
|
} s_SubControls[] =
|
|
{
|
|
{IDC_ACQUIRE_USE_NULL_HWND, IDC_ACQUISITION_RADIO},
|
|
{IDC_ACQUIRE_SUPPRESS_PROGRESS, IDC_ACQUISITION_RADIO},
|
|
{IDC_ACQUIRE_USE_CUSTOM_TEMPLATE, IDC_ACQUISITION_RADIO},
|
|
{IDC_DEVSEL_FS_DEVICES, IDC_DEVSEL_RADIO},
|
|
{IDC_DEVSEL_WPD_DEVICES, IDC_DEVSEL_RADIO},
|
|
{IDC_DEVSEL_WIA_CAMERAS, IDC_DEVSEL_RADIO},
|
|
{IDC_DEVSEL_WIA_SCANNERS, IDC_DEVSEL_RADIO},
|
|
{IDC_DEVSEL_STI_DEVICES, IDC_DEVSEL_RADIO},
|
|
{IDC_DEVSEL_DV_DEVICES, IDC_DEVSEL_RADIO},
|
|
{IDC_DEVSEL_SHOW_OFFLINE, IDC_DEVSEL_RADIO},
|
|
{IDC_DEVSEL_CPANEL_MODE, IDC_DEVSEL_RADIO}
|
|
};
|
|
|
|
int nCurrentRadioButton = PhotoAcquireTest_GetCheckedRadioButton(hWnd);
|
|
for (int i = 0; i < _ARRAYSIZE(s_SubControls); ++i)
|
|
{
|
|
EnableWindow(GetDlgItem(hWnd, s_SubControls[i].nControlId), s_SubControls[i].nRadioButton == nCurrentRadioButton);
|
|
}
|
|
|
|
// Enable the custom template edit control if the currently selected radio button is IDC_ACQUISITION_RADIO, and IDC_ACQUIRE_USE_CUSTOM_TEMPLATE is checked
|
|
EnableWindow(GetDlgItem(hWnd, IDC_ACQUIRE_CUSTOM_TEMPLATE), (nCurrentRadioButton == IDC_ACQUISITION_RADIO) && (IsDlgButtonChecked(hWnd, IDC_ACQUIRE_USE_CUSTOM_TEMPLATE) == BST_CHECKED));
|
|
}
|
|
|
|
|
|
LRESULT PhotoAcquireTest_InitDialog(HWND hWnd)
|
|
{
|
|
Button_SetCheck(GetDlgItem(hWnd, IDC_ACQUISITION_RADIO), BST_CHECKED);
|
|
|
|
// Set the device types in the device selection dialog
|
|
Button_SetCheck(GetDlgItem(hWnd, IDC_DEVSEL_FS_DEVICES), BST_CHECKED);
|
|
Button_SetCheck(GetDlgItem(hWnd, IDC_DEVSEL_WPD_DEVICES), BST_CHECKED);
|
|
Button_SetCheck(GetDlgItem(hWnd, IDC_DEVSEL_WIA_CAMERAS), BST_CHECKED);
|
|
Button_SetCheck(GetDlgItem(hWnd, IDC_DEVSEL_WIA_SCANNERS), BST_CHECKED);
|
|
Button_SetCheck(GetDlgItem(hWnd, IDC_DEVSEL_SHOW_OFFLINE), BST_CHECKED);
|
|
Button_SetCheck(GetDlgItem(hWnd, IDC_DEVSEL_STI_DEVICES), BST_CHECKED);
|
|
Button_SetCheck(GetDlgItem(hWnd, IDC_DEVSEL_DV_DEVICES), BST_CHECKED);
|
|
Button_SetCheck(GetDlgItem(hWnd, IDC_DEVSEL_CPANEL_MODE), BST_UNCHECKED);
|
|
|
|
PhotoAcquireTest_UpdateControlState(hWnd);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//**************************************************************
|
|
// WM_COMMAND handlers
|
|
//**************************************************************
|
|
|
|
void PhotoAcquireTest_OnOK(HWND hWnd)
|
|
{
|
|
if (Button_GetCheck(GetDlgItem(hWnd, IDC_ACQUISITION_RADIO)) == BST_CHECKED)
|
|
{
|
|
PhotoAcquireTest_LaunchAcquisition(hWnd);
|
|
}
|
|
else if (Button_GetCheck(GetDlgItem(hWnd, IDC_DEVSEL_RADIO)) == BST_CHECKED)
|
|
{
|
|
PhotoAcquireTest_LaunchDeviceSelectionDialog(hWnd);
|
|
}
|
|
else if (Button_GetCheck(GetDlgItem(hWnd, IDC_SETTINGS_RADIO)) == BST_CHECKED)
|
|
{
|
|
PhotoAcquireTest_LaunchSettings(hWnd);
|
|
}
|
|
}
|
|
|
|
void PhotoAcquireTest_OnCancel(HWND hWnd)
|
|
{
|
|
EndDialog(hWnd, 0);
|
|
}
|
|
|
|
void PhotoAcquireTest_OnRadioButton(HWND hWnd)
|
|
{
|
|
PhotoAcquireTest_UpdateControlState(hWnd);
|
|
}
|
|
|
|
void PhotoAcquireTest_OnCustomTemplate(HWND hWnd)
|
|
{
|
|
PhotoAcquireTest_UpdateControlState(hWnd);
|
|
}
|
|
|
|
//**************************************************************
|
|
// Internal helpers
|
|
//**************************************************************
|
|
|
|
|
|
INT_PTR CALLBACK PhotoAcquireTestDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
INT_PTR fResult = FALSE;
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
fResult = PhotoAcquireTest_InitDialog(hWnd);
|
|
}
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
{
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDOK:
|
|
PhotoAcquireTest_OnOK(hWnd);
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
PhotoAcquireTest_OnCancel(hWnd);
|
|
break;
|
|
|
|
case IDC_ACQUISITION_RADIO:
|
|
PhotoAcquireTest_OnRadioButton(hWnd);
|
|
break;
|
|
|
|
case IDC_DEVSEL_RADIO:
|
|
PhotoAcquireTest_OnRadioButton(hWnd);
|
|
break;
|
|
|
|
case IDC_SETTINGS_RADIO:
|
|
PhotoAcquireTest_OnRadioButton(hWnd);
|
|
break;
|
|
|
|
case IDC_ACQUIRE_USE_CUSTOM_TEMPLATE:
|
|
PhotoAcquireTest_OnCustomTemplate(hWnd);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
return fResult;
|
|
}
|
|
|
|
|
|
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE, __in __nullterminated wchar_t*, int)
|
|
{
|
|
g_hInstance = hInstance;
|
|
|
|
HRESULT hr = CoInitialize(NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
bool fAcquireWithoutTestDialog = false;
|
|
WCHAR szDeviceId[MAX_PATH] = {0};
|
|
|
|
// Convert to an array of arguments
|
|
int nArgCount;
|
|
PWSTR *ppszArgs = CommandLineToArgvW(GetCommandLineW(), &nArgCount);
|
|
if (ppszArgs != NULL)
|
|
{
|
|
// Loop through all of the arguments
|
|
int nCurrentArg = 1;
|
|
while (nCurrentArg<nArgCount)
|
|
{
|
|
// Is this a switch?
|
|
if (lstrlen(ppszArgs[nCurrentArg]) >= 2 && (L'/'==ppszArgs[nCurrentArg][0] || L'-'==ppszArgs[nCurrentArg][0]))
|
|
{
|
|
switch (towupper(ppszArgs[nCurrentArg][1]))
|
|
{
|
|
case L'A':
|
|
fAcquireWithoutTestDialog = true;
|
|
break;
|
|
|
|
case L'S':
|
|
g_fSuppressErrorMessageDialog = true;
|
|
break;
|
|
|
|
case L'I':
|
|
g_fInfiniteLoop = true;
|
|
g_fDeleteFilesWhenDone = true;
|
|
fAcquireWithoutTestDialog = true;
|
|
break;
|
|
|
|
case L'D':
|
|
g_fDeleteFilesWhenDone = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Don't we have a device yet? Save this as a device ID.
|
|
else if (lstrlen(szDeviceId) == 0)
|
|
{
|
|
StringCchCopy(szDeviceId, ARRAYSIZE(szDeviceId), ppszArgs[nCurrentArg]);
|
|
}
|
|
|
|
++nCurrentArg;
|
|
}
|
|
|
|
LocalFree(ppszArgs);
|
|
}
|
|
|
|
if (fAcquireWithoutTestDialog)
|
|
{
|
|
// If we don't have a device, get one
|
|
if (lstrlen(szDeviceId) == 0)
|
|
{
|
|
// Select the device
|
|
BSTR bstrSelectedDeviceId = NULL;
|
|
hr = SelectDevice(NULL, &bstrSelectedDeviceId);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Save the device ID
|
|
hr = StringCchCopy(szDeviceId, ARRAYSIZE(szDeviceId), bstrSelectedDeviceId);
|
|
|
|
SysFreeString(bstrSelectedDeviceId);
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
do
|
|
{
|
|
// Launch acquisition
|
|
hr = TransferPhotosAndVideos(g_fInfiniteLoop ? GetDesktopWindow() : NULL, TRUE, FALSE, NULL, szDeviceId);
|
|
}
|
|
while (g_fInfiniteLoop && hr != E_ABORT);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Initialize the common controls library
|
|
INITCOMMONCONTROLSEX icex = {0};
|
|
icex.dwSize = sizeof(icex);
|
|
icex.dwICC = ICC_LINK_CLASS|ICC_STANDARD_CLASSES;
|
|
InitCommonControlsEx(&icex);
|
|
|
|
DialogBox(hInstance, MAKEINTRESOURCE(IDD_TEST_DIALOG), NULL, PhotoAcquireTestDialogProc);
|
|
}
|
|
CoUninitialize();
|
|
}
|
|
return 0;
|
|
}
|
|
|