2647 lines
91 KiB
C++
2647 lines
91 KiB
C++
#include "precomp.h"
|
|
#pragma hdrstop
|
|
#include <windows.h>
|
|
#include <wia.h>
|
|
#include <wiadef.h>
|
|
#include <commctrl.h>
|
|
#include <comctrlp.h>
|
|
#include <propidl.h>
|
|
#include "simstr.h"
|
|
#include "camdlg.h"
|
|
#include "camdlg.rh"
|
|
#include "simcrack.h"
|
|
#include "pviewids.h"
|
|
#include "dlgunits.h"
|
|
#include "miscutil.h"
|
|
#include "waitcurs.h"
|
|
#include "movewnd.h"
|
|
#include "simrect.h"
|
|
#include "simbstr.h"
|
|
#include "uiexthlp.h"
|
|
#include "gwiaevnt.h"
|
|
#include "wiacsh.h"
|
|
#include "wiadevdp.h"
|
|
|
|
//
|
|
// Thread queue messages
|
|
//
|
|
#define TQ_DESTROY (WM_USER+1)
|
|
#define TQ_GETTHUMBNAIL (WM_USER+2)
|
|
#define TQ_GETPREVIEW (WM_USER+3)
|
|
#define TQ_DELETEITEM (WM_USER+4)
|
|
|
|
//
|
|
// Control ids
|
|
//
|
|
#define IDC_TOOLBAR 1112
|
|
#define IDC_SIZEBOX 1113
|
|
|
|
//
|
|
// The UI thread will notify us that it took ownership of the data.
|
|
// otherwise, it will be deleted in the worker thread
|
|
//
|
|
#define HANDLED_THREAD_MESSAGE 1000
|
|
|
|
//
|
|
// Help IDs
|
|
//
|
|
static const DWORD g_HelpIDs[] =
|
|
{
|
|
IDC_CAMDLG_BIG_TITLE, -1,
|
|
IDC_CAMDLG_SUBTITLE, -1,
|
|
IDC_TOOLBAR_FRAME, IDH_WIA_BUTTONS,
|
|
IDC_TOOLBAR, IDH_WIA_BUTTONS,
|
|
IDOK, IDH_WIA_GET_PICS,
|
|
IDC_THUMBNAILLIST, IDH_WIA_PIC_LIST,
|
|
IDC_YOU_CAN_ALSO, IDH_WIA_VIEW_PIC_INFO,
|
|
IDC_CAMDLG_PROPERTIES, IDH_WIA_VIEW_PIC_INFO,
|
|
IDC_PREVIEW, IDH_WIA_PREVIEW_DETAIL,
|
|
IDC_INNER_PREVIEW_WINDOW, IDH_WIA_PREVIEW_DETAIL,
|
|
IDCANCEL, IDH_CANCEL,
|
|
0, 0
|
|
};
|
|
|
|
//
|
|
// Update timer
|
|
//
|
|
#define IDT_UPDATEPREVIEW 1000
|
|
#define UPDATE_PREVIEW_DELAY 500
|
|
|
|
//
|
|
// Number of milliseconds between percent display updates
|
|
//
|
|
#define PERCENT_UPDATE_GRANULARITY 1000
|
|
|
|
//
|
|
// Private messages
|
|
//
|
|
#define PWM_POSTINIT (WM_USER+1)
|
|
#define PWM_CHANGETOPARENT (WM_USER+2)
|
|
#define PWM_THUMBNAILSTATUS (WM_USER+3)
|
|
#define PWM_PREVIEWSTATUS (WM_USER+4)
|
|
#define PWM_PREVIEWPERCENT (WM_USER+5)
|
|
#define PWM_ITEMDELETED (WM_USER+6)
|
|
#define PWM_WIAEVENT (WM_USER+7)
|
|
|
|
|
|
//
|
|
// Thumbnail whitespace: the space in between images and their selection rectangles
|
|
// These values were discovered by trail and error. For instance, if you reduce
|
|
// c_nAdditionalMarginY to 20, you get really bizarre spacing problems in the list view
|
|
// in vertical mode. These values could become invalid in future versions of the listview.
|
|
//
|
|
static const int c_nAdditionalMarginX = 10;
|
|
static const int c_nAdditionalMarginY = 6;
|
|
|
|
static int c_nMinThumbnailWidth = 90;
|
|
static int c_nMinThumbnailHeight = 90;
|
|
|
|
static int c_nMaxThumbnailWidth = 120;
|
|
static int c_nMaxThumbnailHeight = 120;
|
|
|
|
//
|
|
// Button bar button bitmap sizes
|
|
//
|
|
static const int c_nButtonBitmapSizeX = 16;
|
|
static const int c_nButtonBitmapSizeY = 16;
|
|
|
|
//
|
|
// Button bar button sizes
|
|
//
|
|
static const int c_nButtonSizeX = 300; // Ridiculously large size to compensate for BTNS_AUTOSIZE bug.
|
|
static const int c_nButtonSizeY = 16;
|
|
|
|
//
|
|
// Default preview mode list width
|
|
//
|
|
static const int c_nDefaultListViewWidth = 120;
|
|
|
|
//
|
|
// These defines let me compile with pre-nt5 headers
|
|
//
|
|
#ifndef BTNS_SEP
|
|
#define BTNS_SEP TBSTYLE_SEP
|
|
#endif
|
|
|
|
#ifndef BTNS_BUTTON
|
|
#define BTNS_BUTTON TBSTYLE_BUTTON
|
|
#endif
|
|
|
|
#ifndef ListView_SetExtendedListViewStyleEx
|
|
#define ListView_SetExtendedListViewStyleEx( h, m, s )
|
|
#endif
|
|
|
|
|
|
class CGlobalInterfaceTableThreadMessage : public CNotifyThreadMessage
|
|
{
|
|
private:
|
|
DWORD m_dwGlobalInterfaceTableCookie;
|
|
|
|
private:
|
|
//
|
|
// No implementation
|
|
//
|
|
CGlobalInterfaceTableThreadMessage(void);
|
|
CGlobalInterfaceTableThreadMessage &operator=( const CGlobalInterfaceTableThreadMessage & );
|
|
CGlobalInterfaceTableThreadMessage( const CGlobalInterfaceTableThreadMessage & );
|
|
|
|
public:
|
|
CGlobalInterfaceTableThreadMessage( int nMessage, HWND hWndNotify, DWORD dwGlobalInterfaceTableCookie )
|
|
: CNotifyThreadMessage( nMessage, hWndNotify ),
|
|
m_dwGlobalInterfaceTableCookie(dwGlobalInterfaceTableCookie)
|
|
{
|
|
}
|
|
DWORD GlobalInterfaceTableCookie(void) const
|
|
{
|
|
return(m_dwGlobalInterfaceTableCookie);
|
|
}
|
|
};
|
|
|
|
|
|
class CThumbnailThreadMessage : public CGlobalInterfaceTableThreadMessage
|
|
{
|
|
private:
|
|
SIZE m_sizeThumb;
|
|
|
|
private:
|
|
//
|
|
// No implementation
|
|
//
|
|
CThumbnailThreadMessage(void);
|
|
CThumbnailThreadMessage &operator=( const CThumbnailThreadMessage & );
|
|
CThumbnailThreadMessage( const CThumbnailThreadMessage & );
|
|
|
|
public:
|
|
CThumbnailThreadMessage( HWND hWndNotify, DWORD dwGlobalInterfaceTableCookie, const SIZE &sizeThumb )
|
|
: CGlobalInterfaceTableThreadMessage( TQ_GETTHUMBNAIL, hWndNotify, dwGlobalInterfaceTableCookie ),
|
|
m_sizeThumb(sizeThumb)
|
|
{
|
|
}
|
|
const SIZE &ThumbSize(void) const
|
|
{
|
|
return(m_sizeThumb);
|
|
}
|
|
};
|
|
|
|
class CDeleteThreadMessage : public CGlobalInterfaceTableThreadMessage
|
|
{
|
|
private:
|
|
//
|
|
// No implementation
|
|
//
|
|
CDeleteThreadMessage(void);
|
|
CDeleteThreadMessage &operator=( const CDeleteThreadMessage & );
|
|
CDeleteThreadMessage( const CDeleteThreadMessage & );
|
|
|
|
public:
|
|
CDeleteThreadMessage( HWND hWndNotify, DWORD dwGlobalInterfaceTableCookie )
|
|
: CGlobalInterfaceTableThreadMessage( TQ_DELETEITEM, hWndNotify, dwGlobalInterfaceTableCookie )
|
|
{
|
|
}
|
|
};
|
|
|
|
|
|
class CPreviewThreadMessage : public CGlobalInterfaceTableThreadMessage
|
|
{
|
|
private:
|
|
CSimpleEvent m_CancelEvent;
|
|
|
|
private:
|
|
//
|
|
// No implementation
|
|
//
|
|
CPreviewThreadMessage(void);
|
|
CPreviewThreadMessage &operator=( const CPreviewThreadMessage & );
|
|
CPreviewThreadMessage( const CPreviewThreadMessage & );
|
|
|
|
public:
|
|
CPreviewThreadMessage( HWND hWndNotify, DWORD dwGlobalInterfaceTableCookie, HANDLE hCancelEvent )
|
|
: CGlobalInterfaceTableThreadMessage( TQ_GETPREVIEW, hWndNotify, dwGlobalInterfaceTableCookie ),
|
|
m_CancelEvent(hCancelEvent)
|
|
{
|
|
}
|
|
CSimpleEvent &CancelEvent(void)
|
|
{
|
|
return(m_CancelEvent);
|
|
}
|
|
};
|
|
|
|
|
|
BOOL WINAPI CCameraAcquireDialog::OnThreadDestroy( CThreadMessage * )
|
|
{
|
|
WIA_PUSHFUNCTION(TEXT("CCameraAcquireDialog::OnThreadDestroy"));
|
|
return(FALSE);
|
|
}
|
|
|
|
BOOL WINAPI CCameraAcquireDialog::OnThreadDeleteItem( CThreadMessage *pMsg )
|
|
{
|
|
WIA_PUSHFUNCTION(TEXT("CCameraAcquireDialog::OnThreadDeleteItem"));
|
|
CDeleteThreadMessage *pDeleteMsg = (CDeleteThreadMessage *)(pMsg);
|
|
if (pDeleteMsg)
|
|
{
|
|
CComPtr<IGlobalInterfaceTable> pGlobalInterfaceTable;
|
|
HRESULT hr = CoCreateInstance( CLSID_StdGlobalInterfaceTable, NULL, CLSCTX_INPROC_SERVER, IID_IGlobalInterfaceTable, (void **)&pGlobalInterfaceTable);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CComPtr<IWiaItem> pIWiaItem;
|
|
hr = pGlobalInterfaceTable->GetInterfaceFromGlobal( pDeleteMsg->GlobalInterfaceTableCookie(), IID_IWiaItem, (void**)&pIWiaItem );
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = WiaUiUtil::DeleteItemAndChildren(pIWiaItem);
|
|
WIA_TRACE((TEXT("********************* pIWiaItem->DeleteItem returned %08X"), hr ));
|
|
PostMessage( pDeleteMsg->NotifyWindow(), PWM_ITEMDELETED, pDeleteMsg->GlobalInterfaceTableCookie(), SUCCEEDED(hr) );
|
|
}
|
|
}
|
|
}
|
|
return(TRUE);
|
|
}
|
|
|
|
class CWiaDataCallback : public IWiaDataCallback
|
|
{
|
|
private:
|
|
ULONG m_cRef;
|
|
HWND m_hWndNotify;
|
|
DWORD m_dwGlobalInterfaceTableCookie;
|
|
CSimpleEvent m_CancelEvent;
|
|
DWORD m_dwPreviousTickCount;
|
|
int m_nPercentGranularity;
|
|
public:
|
|
CWiaDataCallback();
|
|
~CWiaDataCallback();
|
|
|
|
HRESULT _stdcall QueryInterface(const IID&,void**);
|
|
ULONG _stdcall AddRef();
|
|
ULONG _stdcall Release();
|
|
|
|
HRESULT _stdcall Initialize( HWND hWndNotify, DWORD dwGlobalInterfaceTableCookie, HANDLE hCancelEvent );
|
|
|
|
HRESULT _stdcall BandedDataCallback(
|
|
LONG lReason,
|
|
LONG lStatus,
|
|
LONG lPercentComplete,
|
|
LONG lOffset,
|
|
LONG lLength,
|
|
LONG lReserved,
|
|
LONG lResLength,
|
|
BYTE *pbBuffer );
|
|
};
|
|
|
|
|
|
|
|
|
|
HRESULT _stdcall CWiaDataCallback::QueryInterface(const IID& iid, void** ppv)
|
|
{
|
|
*ppv = NULL;
|
|
|
|
if (iid == IID_IUnknown || iid == IID_IWiaDataCallback)
|
|
{
|
|
*ppv = (IWiaDataCallback*)this;
|
|
}
|
|
else
|
|
{
|
|
return(E_NOINTERFACE);
|
|
}
|
|
|
|
AddRef();
|
|
return(S_OK);
|
|
}
|
|
|
|
ULONG _stdcall CWiaDataCallback::AddRef()
|
|
{
|
|
InterlockedIncrement((long*) &m_cRef);
|
|
return(m_cRef);
|
|
}
|
|
|
|
ULONG _stdcall CWiaDataCallback::Release()
|
|
{
|
|
ULONG ulRefCount = m_cRef - 1;
|
|
if (InterlockedDecrement((long*) &m_cRef) == 0)
|
|
{
|
|
delete this;
|
|
return(0);
|
|
}
|
|
return(ulRefCount);
|
|
}
|
|
|
|
CWiaDataCallback::CWiaDataCallback()
|
|
: m_cRef(0),
|
|
m_hWndNotify(NULL)
|
|
{
|
|
}
|
|
|
|
|
|
CWiaDataCallback::~CWiaDataCallback()
|
|
{
|
|
}
|
|
|
|
|
|
HRESULT _stdcall CWiaDataCallback::Initialize( HWND hWndNotify, DWORD dwGlobalInterfaceTableCookie, HANDLE hCancelEvent )
|
|
{
|
|
m_hWndNotify = hWndNotify;
|
|
m_dwGlobalInterfaceTableCookie = dwGlobalInterfaceTableCookie;
|
|
m_CancelEvent = hCancelEvent;
|
|
m_dwPreviousTickCount = 0xFFFFFF;
|
|
m_nPercentGranularity = 3;
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
|
|
HRESULT _stdcall CWiaDataCallback::BandedDataCallback(
|
|
LONG lMessage,
|
|
LONG lStatus,
|
|
LONG lPercentComplete,
|
|
LONG lOffset,
|
|
LONG lLength,
|
|
LONG lReserved,
|
|
LONG lResLength,
|
|
BYTE * /* pbBuffer */
|
|
)
|
|
{
|
|
WIA_TRACE((TEXT("BandedDataCallback: lMessage: %d, lStatus: %d, lPercentComplete: %d, lOffset: %d, lLength: %d, lReserved: %d, lResLength: %d"), lMessage, lStatus, lPercentComplete, lOffset, lLength, lReserved, lResLength ));
|
|
if (m_CancelEvent.Signalled())
|
|
return(S_FALSE);
|
|
switch (lMessage)
|
|
{
|
|
case IT_MSG_DATA_HEADER:
|
|
{
|
|
} // IT_MSG_DATA_HEADER
|
|
|
|
case IT_MSG_DATA:
|
|
{
|
|
} // IT_STATUS_TRANSFER_TO_CLIENT
|
|
break;
|
|
|
|
case IT_MSG_STATUS:
|
|
{
|
|
// Don't send status messages too frequently. Limit to one per PERCENT_UPDATE_GRANULARITY ms
|
|
DWORD dwTickCount = GetTickCount();
|
|
if ((dwTickCount - m_dwPreviousTickCount >= PERCENT_UPDATE_GRANULARITY) || (m_dwPreviousTickCount > dwTickCount))
|
|
{
|
|
m_dwPreviousTickCount = dwTickCount;
|
|
PostMessage( m_hWndNotify, PWM_PREVIEWPERCENT, (WPARAM)m_dwGlobalInterfaceTableCookie, (LPARAM)MAKELPARAM((WORD)lPercentComplete,(WORD)lStatus));
|
|
}
|
|
} // IT_MSG_STATUS
|
|
break;
|
|
|
|
case IT_MSG_TERMINATION:
|
|
{
|
|
} // IT_MSG_TERMINATION
|
|
break;
|
|
}
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
BOOL WINAPI CCameraAcquireDialog::OnGetPreview( CThreadMessage *pMsg )
|
|
{
|
|
WIA_PUSHFUNCTION(TEXT("CCameraAcquireDialog::OnGetThumbnail"));
|
|
CSimpleStringWide strwImageName(L"");
|
|
CPreviewThreadMessage *pPreviewMsg = (CPreviewThreadMessage *)(pMsg);
|
|
if (pPreviewMsg)
|
|
{
|
|
CComPtr<IGlobalInterfaceTable> pGlobalInterfaceTable;
|
|
HRESULT hr = CoCreateInstance( CLSID_StdGlobalInterfaceTable,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IGlobalInterfaceTable,
|
|
(void **)&pGlobalInterfaceTable);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CComPtr<IWiaItem> pIWiaItem;
|
|
hr = pGlobalInterfaceTable->GetInterfaceFromGlobal( pPreviewMsg->GlobalInterfaceTableCookie(), IID_IWiaItem, (void**)&pIWiaItem );
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CComPtr<IWiaDataTransfer> pIBandedTran;
|
|
WIA_TRACE((TEXT("Preparing to call pIWiaItem->QueryInterface for IID_IWiaDataTransfer")));
|
|
hr = pIWiaItem->QueryInterface(IID_IWiaDataTransfer, (void**)&pIBandedTran);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (PropStorageHelpers::SetProperty( pIWiaItem, WIA_IPA_FORMAT, WiaImgFmt_BMP, WIA_IPA_FIRST ) &&
|
|
PropStorageHelpers::SetProperty( pIWiaItem, WIA_IPA_TYMED, TYMED_FILE, WIA_IPA_FIRST ))
|
|
{
|
|
CWiaDataCallback* pCDataCB = new CWiaDataCallback();
|
|
WIA_TRACE((TEXT("Preparing to call pCDataCB->Initialize")));
|
|
if (pCDataCB)
|
|
{
|
|
hr = pCDataCB->Initialize( pPreviewMsg->NotifyWindow(), pPreviewMsg->GlobalInterfaceTableCookie(), pPreviewMsg->CancelEvent().Event() );
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
WIA_TRACE((TEXT("Preparing to call pCDataCB->QueryInterface on IID_IWiaDataCallback")));
|
|
CComPtr<IWiaDataCallback> pIWiaDataCallback;
|
|
hr = pCDataCB->QueryInterface(IID_IWiaDataCallback,(void **)&pIWiaDataCallback);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
STGMEDIUM StgMedium;
|
|
StgMedium.tymed = TYMED_FILE;
|
|
StgMedium.pUnkForRelease = NULL;
|
|
StgMedium.hGlobal = NULL;
|
|
StgMedium.lpszFileName = NULL;
|
|
|
|
WIA_TRACE((TEXT("Preparing to call pIBandedTran->ibtGetData")));
|
|
hr = pIBandedTran->idtGetData( &StgMedium, pIWiaDataCallback );
|
|
if (SUCCEEDED(hr) && S_FALSE != hr)
|
|
{
|
|
strwImageName = StgMedium.lpszFileName;
|
|
WIA_TRACE((TEXT("pIBandedTran->ibtGetData returned %s"),StgMedium.lpszFileName));
|
|
}
|
|
else
|
|
{
|
|
WIA_PRINTHRESULT((hr,TEXT("CCameraAcquireDialog::OnGetPreview, ibtGetData failed")));
|
|
}
|
|
//
|
|
// Prevent leaks by freeing the filename. We don't call ReleaseStgMeduim, because
|
|
// it deletes the file as well.
|
|
//
|
|
if (SUCCEEDED(hr) && StgMedium.lpszFileName)
|
|
{
|
|
CoTaskMemFree(StgMedium.lpszFileName);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WIA_PRINTHRESULT((hr,TEXT("CCameraAcquireDialog::OnGetPreview, QI of IID_IWiaDataCallback failed")));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WIA_PRINTHRESULT((hr,TEXT("pCDataCB->Initialize failed")));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WIA_ERROR((TEXT("CCameraAcquireDialog::OnGetPreview, new on CWiaDataCallback failed")));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = MAKE_HRESULT(3,FACILITY_WIN32,ERROR_INVALID_DATA);
|
|
WIA_ERROR((TEXT("SetProperty on TYMED or FORMAT failed")));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WIA_PRINTHRESULT((hr,TEXT("CCameraAcquireDialog::OnGetPreview, QI of IID_IWiaDataTransfer failed")));
|
|
}
|
|
WIA_TRACE((TEXT("End CCameraAcquireDialog::OnGetPreviewBandedTransfer")));
|
|
}
|
|
}
|
|
|
|
//
|
|
// Allocate the filename string to return to the UI thread
|
|
//
|
|
CSimpleString *pstrDibFilename = new CSimpleString( CSimpleStringConvert::NaturalString(strwImageName) );
|
|
|
|
//
|
|
// Send the message to the UI thread
|
|
//
|
|
LRESULT lRes = SendMessage( pPreviewMsg->NotifyWindow(), PWM_PREVIEWSTATUS, pPreviewMsg->GlobalInterfaceTableCookie(), reinterpret_cast<LPARAM>(pstrDibFilename));
|
|
|
|
//
|
|
// If it fails for any reason, we will clean up to avoid leaks and orphaned temp files
|
|
//
|
|
if (HANDLED_THREAD_MESSAGE != lRes)
|
|
{
|
|
DeleteFile(CSimpleStringConvert::NaturalString(strwImageName));
|
|
if (pstrDibFilename)
|
|
{
|
|
delete pstrDibFilename;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
BOOL WINAPI CCameraAcquireDialog::OnGetThumbnail( CThreadMessage *pMsg )
|
|
{
|
|
WIA_PUSHFUNCTION(TEXT("CCameraAcquireDialog::OnGetThumbnail"));
|
|
HBITMAP hBmpThumbnail = NULL;
|
|
CThumbnailThreadMessage *pThumbMsg = (CThumbnailThreadMessage *)(pMsg);
|
|
if (pThumbMsg)
|
|
{
|
|
CComPtr<IGlobalInterfaceTable> pGlobalInterfaceTable;
|
|
HRESULT hr = CoCreateInstance( CLSID_StdGlobalInterfaceTable,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IGlobalInterfaceTable,
|
|
(void **)&pGlobalInterfaceTable);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CComPtr<IWiaItem> pIWiaItem;
|
|
hr = pGlobalInterfaceTable->GetInterfaceFromGlobal( pThumbMsg->GlobalInterfaceTableCookie(), IID_IWiaItem, (void**)&pIWiaItem );
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
#if defined(DBG)
|
|
CSimpleStringWide strItemName;
|
|
PropStorageHelpers::GetProperty( pIWiaItem, WIA_IPA_FULL_ITEM_NAME, strItemName );
|
|
WIA_TRACE((TEXT("Getting thumbnail for %ws (0x%d, 0x%p)"), strItemName.String(), pThumbMsg->GlobalInterfaceTableCookie(), pIWiaItem.p ));
|
|
#endif
|
|
CComPtr<IWiaPropertyStorage> pIWiaPropertyStorage;
|
|
hr = pIWiaItem->QueryInterface(IID_IWiaPropertyStorage, (void**)&pIWiaPropertyStorage);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
PROPVARIANT PropVar[3];
|
|
PROPSPEC PropSpec[3];
|
|
|
|
PropSpec[0].ulKind = PRSPEC_PROPID;
|
|
PropSpec[0].propid = WIA_IPC_THUMB_WIDTH;
|
|
|
|
PropSpec[1].ulKind = PRSPEC_PROPID;
|
|
PropSpec[1].propid = WIA_IPC_THUMB_HEIGHT;
|
|
|
|
PropSpec[2].ulKind = PRSPEC_PROPID;
|
|
PropSpec[2].propid = WIA_IPC_THUMBNAIL;
|
|
hr = pIWiaPropertyStorage->ReadMultiple(ARRAYSIZE(PropSpec),PropSpec,PropVar );
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
WIA_TRACE((TEXT("Attempting to get the thumbnail for GIT entry: %08X, %08X, %08X, %08X"),pThumbMsg->GlobalInterfaceTableCookie(),PropVar[0].vt,PropVar[1].vt,PropVar[2].vt));
|
|
if ((PropVar[0].vt == VT_I4 || PropVar[0].vt == VT_UI4) &&
|
|
(PropVar[1].vt == VT_I4 || PropVar[1].vt == VT_UI4) &&
|
|
(PropVar[2].vt == (VT_UI1|VT_VECTOR)))
|
|
{
|
|
UINT nBitmapDataSize = WiaUiUtil::Align(PropVar[0].ulVal*3,sizeof(DWORD)) * PropVar[1].ulVal;
|
|
if (nBitmapDataSize <= PropVar[2].caub.cElems)
|
|
{
|
|
BITMAPINFO bmi = {0};
|
|
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
bmi.bmiHeader.biWidth = PropVar[0].ulVal;
|
|
bmi.bmiHeader.biHeight = PropVar[1].ulVal;
|
|
bmi.bmiHeader.biPlanes = 1;
|
|
bmi.bmiHeader.biBitCount = 24;
|
|
bmi.bmiHeader.biCompression = BI_RGB;
|
|
bmi.bmiHeader.biSizeImage = 0;
|
|
bmi.bmiHeader.biXPelsPerMeter = 0;
|
|
bmi.bmiHeader.biYPelsPerMeter = 0;
|
|
bmi.bmiHeader.biClrUsed = 0;
|
|
bmi.bmiHeader.biClrImportant = 0;
|
|
|
|
HDC hDC = GetDC(NULL);
|
|
if (hDC)
|
|
{
|
|
PBYTE *pBits;
|
|
HBITMAP hDibSection = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS, (PVOID*)&pBits, NULL, 0 );
|
|
if (hDibSection)
|
|
{
|
|
WIA_TRACE((TEXT("pBits: 0x%p, PropVar[2].caub.pElems: 0x%p, PropVar[2].caub.cElems: %d"), pBits, PropVar[2].caub.pElems, PropVar[2].caub.cElems));
|
|
CopyMemory( pBits, PropVar[2].caub.pElems, nBitmapDataSize );
|
|
hr = ScaleImage( hDC, hDibSection, hBmpThumbnail, pThumbMsg->ThumbSize());
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
WIA_TRACE((TEXT("Sending this image (%p) to the notification window: %p"), hBmpThumbnail, pThumbMsg->NotifyWindow() ));
|
|
}
|
|
else hBmpThumbnail = NULL;
|
|
DeleteObject(hDibSection);
|
|
}
|
|
else
|
|
{
|
|
WIA_PRINTHRESULT((HRESULT_FROM_WIN32(GetLastError()),TEXT("CreateDIBSection failed")));
|
|
}
|
|
ReleaseDC(NULL,hDC);
|
|
}
|
|
else
|
|
{
|
|
WIA_PRINTHRESULT((HRESULT_FROM_WIN32(GetLastError()),TEXT("GetDC failed")));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WIA_ERROR((TEXT("nBitmapDataSize <= PropVar[2].caub.cElems was FALSE (%d, %d)"), nBitmapDataSize, PropVar[2].caub.cElems ));
|
|
}
|
|
}
|
|
PropVariantClear(&PropVar[0]);
|
|
PropVariantClear(&PropVar[1]);
|
|
PropVariantClear(&PropVar[2]);
|
|
}
|
|
else
|
|
{
|
|
WIA_PRINTHRESULT((hr,TEXT("pIWiaPropertyStorage->ReadMultiple failed")));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WIA_PRINTHRESULT((hr,TEXT("QueryInterface failed on IID_IWiaPropertyStorage")));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WIA_PRINTHRESULT((hr,TEXT("GetInterfaceFromGlobal failed on %08X"), pThumbMsg->GlobalInterfaceTableCookie() ));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WIA_PRINTHRESULT((hr,TEXT("CoCreateInstance failed on CLSID_StdGlobalInterfaceTable")));
|
|
}
|
|
|
|
//
|
|
// Send the message to the UI thread
|
|
//
|
|
LRESULT lRes = SendMessage( pThumbMsg->NotifyWindow(), PWM_THUMBNAILSTATUS, (WPARAM)pThumbMsg->GlobalInterfaceTableCookie(), (LPARAM)hBmpThumbnail );
|
|
|
|
//
|
|
// If it fails for any reason, we will clean up to avoid leaks
|
|
//
|
|
if (HANDLED_THREAD_MESSAGE != lRes)
|
|
{
|
|
if (hBmpThumbnail)
|
|
{
|
|
DeleteObject( hBmpThumbnail );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WIA_ERROR((TEXT("pThumbMsg")));
|
|
}
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
int CCameraAcquireDialog::FindItemInList( CCameraItem *pItem )
|
|
{
|
|
WIA_PUSH_FUNCTION((TEXT("CCameraAcquireDialog::FindItemInList( %08X )"), pItem ));
|
|
if (pItem)
|
|
{
|
|
HWND hwndList = GetDlgItem( m_hWnd, IDC_THUMBNAILLIST );
|
|
if (hwndList)
|
|
{
|
|
for (int i=0;i<ListView_GetItemCount(hwndList);i++)
|
|
{
|
|
CCameraItem *pCurrItem = GetListItemNode(i);
|
|
if (pCurrItem)
|
|
{
|
|
WIA_TRACE((TEXT("Comparing %08X and %08X [%ws] [%ws]"), pCurrItem, pItem, pCurrItem->FullItemName().String(), pItem->FullItemName().String() ));
|
|
if (*pCurrItem == *pItem)
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return(-1);
|
|
}
|
|
|
|
CCameraItem *CCameraAcquireDialog::GetCurrentPreviewItem(void)
|
|
{
|
|
CSimpleDynamicArray<int> aSelIndices;
|
|
GetSelectionIndices(aSelIndices);
|
|
if (0 == aSelIndices.Size())
|
|
return(NULL);
|
|
if (1 == aSelIndices.Size())
|
|
return(GetListItemNode(aSelIndices[0]));
|
|
return(NULL);
|
|
}
|
|
|
|
bool CCameraAcquireDialog::SetCurrentPreviewImage( const CSimpleString &strFilename, const CSimpleString &strTitle )
|
|
{
|
|
CWaitCursor wc;
|
|
bool bResult = true;
|
|
SendDlgItemMessage( m_hWnd, IDC_PREVIEW, WM_SETTEXT, 0, (LPARAM)strTitle.String() );
|
|
SIZE sizeSavedAspectRatio = m_CurrentAspectRatio;
|
|
// Set up a reasonable default
|
|
m_CurrentAspectRatio.cx = 4;
|
|
m_CurrentAspectRatio.cy = 3;
|
|
if (strFilename.Length())
|
|
{
|
|
HBITMAP hBmp = (HBITMAP)LoadImage( g_hInstance, strFilename.String(), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE );
|
|
if (hBmp)
|
|
{
|
|
BITMAP bm;
|
|
if (GetObject( hBmp, sizeof(BITMAP), &bm ))
|
|
{
|
|
m_CurrentAspectRatio.cx = bm.bmWidth;
|
|
m_CurrentAspectRatio.cy = bm.bmHeight;
|
|
}
|
|
}
|
|
SendDlgItemMessage( m_hWnd, IDC_PREVIEW, PWM_SETBITMAP, MAKEWPARAM(FALSE,FALSE), (LPARAM)hBmp );
|
|
if (memcmp(&sizeSavedAspectRatio,&m_CurrentAspectRatio,sizeof(SIZE)))
|
|
ResizeAll();
|
|
bResult = (hBmp != NULL);
|
|
}
|
|
else
|
|
{
|
|
if (SendDlgItemMessage( m_hWnd, IDC_PREVIEW, PWM_GETBITMAP, 0, 0 ))
|
|
SendDlgItemMessage( m_hWnd, IDC_PREVIEW, PWM_SETBITMAP, MAKEWPARAM(FALSE,FALSE), 0 );
|
|
if (memcmp(&sizeSavedAspectRatio,&m_CurrentAspectRatio,sizeof(SIZE)))
|
|
ResizeAll();
|
|
}
|
|
InvalidateRect( GetDlgItem( m_hWnd, IDC_PREVIEW ), NULL, FALSE );
|
|
UpdateWindow( GetDlgItem( m_hWnd, IDC_PREVIEW ) );
|
|
return(bResult);
|
|
}
|
|
|
|
// wParam = GIT cookie
|
|
// lParam = nPercent
|
|
LRESULT CCameraAcquireDialog::OnPreviewPercent( WPARAM wParam, LPARAM lParam )
|
|
{
|
|
WIA_PUSHFUNCTION(TEXT("CCameraAcquireDialog::OnPreviewPercent"));
|
|
CCameraItem *pCameraItem = m_CameraItemList.Find( (DWORD)wParam );
|
|
if (pCameraItem)
|
|
{
|
|
pCameraItem->CurrentPreviewPercentage((int)LOWORD(lParam));
|
|
CCameraItem *pCurrSel = GetCurrentPreviewItem();
|
|
if (pCameraItem == pCurrSel)
|
|
{
|
|
UpdatePreview();
|
|
}
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
// wParam = GIT cookie
|
|
// lParam = HBITMAP
|
|
LRESULT CCameraAcquireDialog::OnPreviewStatus( WPARAM wParam, LPARAM lParam )
|
|
{
|
|
WIA_PUSHFUNCTION(TEXT("CCameraAcquireDialog::OnPreviewStatus"));
|
|
CSimpleString *pstrFilename = reinterpret_cast<CSimpleString*>(lParam);
|
|
if (pstrFilename)
|
|
{
|
|
CCameraItem *pCameraItem = m_CameraItemList.Find( static_cast<DWORD>(wParam) );
|
|
if (pCameraItem)
|
|
{
|
|
if (!pCameraItem->CancelQueueEvent().Signalled())
|
|
{
|
|
// If we weren't cancelled, set the filename
|
|
pCameraItem->PreviewFileName(*pstrFilename);
|
|
}
|
|
pCameraItem->CloseCancelEvent();
|
|
|
|
CCameraItem *pCurrSel = GetCurrentPreviewItem();
|
|
if (pCameraItem == pCurrSel)
|
|
{
|
|
SetCurrentPreviewImage( pCameraItem->PreviewFileName() );
|
|
}
|
|
}
|
|
delete pstrFilename;
|
|
}
|
|
|
|
return HANDLED_THREAD_MESSAGE;
|
|
}
|
|
|
|
LRESULT CCameraAcquireDialog::OnThumbnailStatus( WPARAM wParam, LPARAM lParam )
|
|
{
|
|
WIA_PUSHFUNCTION(TEXT("CCameraAcquireDialog::OnThumbnailStatus"));
|
|
WIA_TRACE((TEXT("Looking for the item with the ID %08X"),wParam));
|
|
CCameraItem *pCameraItem = m_CameraItemList.Find( (DWORD)wParam );
|
|
if (pCameraItem)
|
|
{
|
|
WIA_TRACE((TEXT("Found a CameraItem * (%08X)"),pCameraItem));
|
|
HWND hwndList = GetDlgItem( m_hWnd, IDC_THUMBNAILLIST );
|
|
if (hwndList)
|
|
{
|
|
WIA_TRACE((TEXT("Got the list control")));
|
|
HIMAGELIST hImageList = ListView_GetImageList( hwndList, LVSIL_NORMAL );
|
|
if (hImageList)
|
|
{
|
|
WIA_TRACE((TEXT("Got the image list")));
|
|
if ((HBITMAP)lParam)
|
|
{
|
|
WIA_TRACE((TEXT("hBitmap = %p"), lParam));
|
|
if (ImageList_Replace( hImageList, pCameraItem->ImageListIndex(), reinterpret_cast<HBITMAP>(lParam), NULL ))
|
|
{
|
|
WIA_TRACE((TEXT("Replaced the image in the list")));
|
|
int nItem = FindItemInList(pCameraItem);
|
|
if (nItem >= 0)
|
|
{
|
|
WIA_TRACE((TEXT("Found the item in the list")));
|
|
//
|
|
// Set the image to a dummy image
|
|
//
|
|
LV_ITEM lvItem;
|
|
::ZeroMemory(&lvItem,sizeof(LV_ITEM));
|
|
lvItem.iItem = nItem;
|
|
lvItem.mask = LVIF_IMAGE;
|
|
lvItem.iImage = -1;
|
|
ListView_SetItem( hwndList, &lvItem );
|
|
|
|
//
|
|
// Then set the image to the real image
|
|
//
|
|
::ZeroMemory(&lvItem,sizeof(LV_ITEM));
|
|
lvItem.iItem = nItem;
|
|
lvItem.mask = LVIF_IMAGE;
|
|
lvItem.iImage = pCameraItem->ImageListIndex();
|
|
ListView_SetItem( hwndList, &lvItem );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Clean up the bitmap, regardless of any other failures, to avoid memory leaks
|
|
//
|
|
HBITMAP hBmpThumb = reinterpret_cast<HBITMAP>(lParam);
|
|
if (hBmpThumb)
|
|
{
|
|
DeleteObject(hBmpThumb);
|
|
}
|
|
return HANDLED_THREAD_MESSAGE;
|
|
}
|
|
|
|
static CThreadMessageMap g_MsgMap[] =
|
|
{
|
|
{ TQ_DESTROY, CCameraAcquireDialog::OnThreadDestroy },
|
|
{ TQ_GETTHUMBNAIL, CCameraAcquireDialog::OnGetThumbnail },
|
|
{ TQ_GETPREVIEW, CCameraAcquireDialog::OnGetPreview },
|
|
{ TQ_DELETEITEM, CCameraAcquireDialog::OnThreadDeleteItem },
|
|
{ 0, NULL}
|
|
};
|
|
|
|
//
|
|
// Sole constructor
|
|
//
|
|
CCameraAcquireDialog::CCameraAcquireDialog( HWND hWnd )
|
|
: m_hWnd(hWnd),
|
|
m_bPreviewActive(false),
|
|
m_pCurrentParentItem(NULL),
|
|
m_bFirstTime(true),
|
|
m_hBackgroundThread(NULL),
|
|
m_hBigFont(NULL),
|
|
m_nDialogMode(0),
|
|
m_hAccelTable(NULL),
|
|
m_nListViewWidth(0),
|
|
m_hIconLarge(NULL),
|
|
m_hIconSmall(NULL),
|
|
m_pThreadMessageQueue(NULL),
|
|
m_bTakePictureIsSupported(false),
|
|
m_ToolbarBitmapInfo( g_hInstance, IDB_TOOLBAR )
|
|
{
|
|
m_pThreadMessageQueue = new CThreadMessageQueue;
|
|
if (m_pThreadMessageQueue)
|
|
{
|
|
//
|
|
// Note that CBackgroundThread takes ownership of m_pThreadMessageQueue, and it doesn't have to be deleted in this thread
|
|
//
|
|
m_hBackgroundThread = CBackgroundThread::Create( m_pThreadMessageQueue, g_MsgMap, m_CancelEvent.Event(), g_hInstance );
|
|
}
|
|
m_sizeThumbnails.cx = c_nMaxThumbnailWidth;
|
|
m_sizeThumbnails.cy = c_nMaxThumbnailHeight;
|
|
m_CurrentAspectRatio.cx = 4;
|
|
m_CurrentAspectRatio.cy = 3;
|
|
WIA_ASSERT(m_hBackgroundThread != NULL);
|
|
}
|
|
|
|
HWND CCameraAcquireDialog::CreateCameraDialogToolbar(VOID)
|
|
{
|
|
ToolbarHelper::CButtonDescriptor aSingleSelModeButtons[] =
|
|
{
|
|
{ 0, IDC_ICONMODE, TBSTATE_ENABLED|TBSTATE_CHECKED, BTNS_AUTOSIZE|BTNS_BUTTON|BTNS_CHECK, true, NULL, IDS_ICONMODE },
|
|
{ 1, IDC_PREVIEWMODE, TBSTATE_ENABLED, BTNS_AUTOSIZE|BTNS_BUTTON|BTNS_CHECK, true, NULL, IDS_PREVIEWMODE },
|
|
{ 2, IDC_TAKEPICTURE, TBSTATE_ENABLED, BTNS_AUTOSIZE|BTNS_BUTTON, true, &m_bTakePictureIsSupported, IDS_TAKEPICTURE },
|
|
{ 4, IDC_DELETE, TBSTATE_ENABLED, BTNS_AUTOSIZE|BTNS_BUTTON, false, NULL, IDS_DELETE_SINGULAR }
|
|
};
|
|
ToolbarHelper::CButtonDescriptor aMultiSelModeButtons[] =
|
|
{
|
|
{ 0, IDC_ICONMODE, TBSTATE_ENABLED|TBSTATE_CHECKED, BTNS_AUTOSIZE|BTNS_BUTTON|BTNS_CHECK, true, NULL, IDS_ICONMODE },
|
|
{ 1, IDC_PREVIEWMODE, TBSTATE_ENABLED, BTNS_AUTOSIZE|BTNS_BUTTON|BTNS_CHECK, true, NULL, IDS_PREVIEWMODE },
|
|
{ 2, IDC_TAKEPICTURE, TBSTATE_ENABLED, BTNS_AUTOSIZE|BTNS_BUTTON, true, &m_bTakePictureIsSupported, IDS_TAKEPICTURE },
|
|
{ 3, IDC_SELECTALL, TBSTATE_ENABLED, BTNS_AUTOSIZE|BTNS_BUTTON, true, NULL, IDS_SELECTALL },
|
|
{ 4, IDC_DELETE, TBSTATE_ENABLED, BTNS_AUTOSIZE|BTNS_BUTTON, false, NULL, IDS_DELETE }
|
|
};
|
|
|
|
ToolbarHelper::CButtonDescriptor *pButtonDescriptors = aSingleSelModeButtons;
|
|
int nButtonDescriptorCount = ARRAYSIZE(aSingleSelModeButtons);
|
|
if (m_nDialogMode & MULTISEL_MODE)
|
|
{
|
|
pButtonDescriptors = aMultiSelModeButtons;
|
|
nButtonDescriptorCount = ARRAYSIZE(aMultiSelModeButtons);
|
|
}
|
|
|
|
return ToolbarHelper::CreateToolbar( m_hWnd, GetDlgItem( m_hWnd, IDC_CAMDLG_SUBTITLE ), GetDlgItem( m_hWnd, IDC_TOOLBAR_FRAME ), ToolbarHelper::AlignLeft|ToolbarHelper::AlignTop, IDC_TOOLBAR, m_ToolbarBitmapInfo, pButtonDescriptors, nButtonDescriptorCount );
|
|
}
|
|
|
|
|
|
HRESULT CCameraAcquireDialog::EnumerateItems( CCameraItem *pCurrentParent, IEnumWiaItem *pIEnumWiaItem )
|
|
{
|
|
WIA_PUSHFUNCTION(TEXT("CCameraItemList::EnumerateItems"));
|
|
HRESULT hr = E_FAIL;
|
|
if (pIEnumWiaItem != NULL)
|
|
{
|
|
hr = pIEnumWiaItem->Reset();
|
|
while (hr == S_OK)
|
|
{
|
|
CComPtr<IWiaItem> pIWiaItem;
|
|
hr = pIEnumWiaItem->Next(1, &pIWiaItem, NULL);
|
|
if (hr == S_OK)
|
|
{
|
|
CCameraItem *pNewCameraItem = new CCameraItem( pIWiaItem );
|
|
if (pNewCameraItem && pNewCameraItem->Item())
|
|
{
|
|
LONG ItemType = 0;
|
|
hr = pNewCameraItem->Item()->GetItemType(&ItemType);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//
|
|
// If it is an image, add it to the list
|
|
//
|
|
if (ItemType & WiaItemTypeImage)
|
|
{
|
|
//
|
|
// Add it to the list
|
|
//
|
|
m_CameraItemList.Add( pCurrentParent, pNewCameraItem );
|
|
WIA_TRACE((TEXT("Found an image")));
|
|
}
|
|
|
|
//
|
|
// If it is a folder, enumerate its child items and recurse
|
|
//
|
|
else if (ItemType & WiaItemTypeFolder)
|
|
{
|
|
//
|
|
// Add this folder to the list
|
|
//
|
|
m_CameraItemList.Add( pCurrentParent, pNewCameraItem );
|
|
|
|
//
|
|
// Enumerate the child items
|
|
//
|
|
CComPtr <IEnumWiaItem> pIEnumChildItem;
|
|
if (S_OK == pIWiaItem->EnumChildItems(&pIEnumChildItem))
|
|
{
|
|
EnumerateItems( pNewCameraItem, pIEnumChildItem );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Delete this item, since we didn't add it to the list
|
|
//
|
|
delete pNewCameraItem;
|
|
WIA_TRACE((TEXT("Found something that is NOT an image")));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
HRESULT CCameraAcquireDialog::EnumerateAllCameraItems(void)
|
|
{
|
|
CComPtr<IEnumWiaItem> pIEnumItem;
|
|
HRESULT hr = m_pDeviceDialogData->pIWiaItemRoot->EnumChildItems(&pIEnumItem);
|
|
if (hr == S_OK)
|
|
{
|
|
hr = EnumerateItems( NULL, pIEnumItem );
|
|
}
|
|
return(hr);
|
|
}
|
|
|
|
void CCameraAcquireDialog::OnItemCreatedEvent( CGenericWiaEventHandler::CEventMessage *pEventMessage )
|
|
{
|
|
//
|
|
// Get the listview, which we'll need later
|
|
//
|
|
HWND hwndListview = GetDlgItem( m_hWnd, IDC_THUMBNAILLIST );
|
|
if (hwndListview)
|
|
{
|
|
//
|
|
// Get the image list
|
|
//
|
|
HIMAGELIST hImageList = ListView_GetImageList( hwndListview, LVSIL_NORMAL );
|
|
if (hImageList)
|
|
{
|
|
//
|
|
// Make sure we don't already have this item
|
|
//
|
|
CCameraItem *pCreatedItem = m_CameraItemList.Find(CSimpleBStr(pEventMessage->FullItemName()));
|
|
if (!pCreatedItem)
|
|
{
|
|
//
|
|
// Get the IWiaItem* for this item
|
|
//
|
|
CComPtr<IWiaItem> pWiaItem;
|
|
HRESULT hr = m_pDeviceDialogData->pIWiaItemRoot->FindItemByName(0,CSimpleBStr(pEventMessage->FullItemName()).BString(),&pWiaItem);
|
|
if (SUCCEEDED(hr) && pWiaItem.p)
|
|
{
|
|
//
|
|
// Create an item wrapper
|
|
//
|
|
CCameraItem *pNewCameraItem = new CCameraItem( pWiaItem );
|
|
if (pNewCameraItem && pNewCameraItem->Item())
|
|
{
|
|
//
|
|
// Add it to the list
|
|
//
|
|
m_CameraItemList.Add( NULL, pNewCameraItem );
|
|
|
|
//
|
|
// Generate a thumbnail
|
|
//
|
|
CreateThumbnail( pNewCameraItem, hImageList, false );
|
|
|
|
//
|
|
// If this item is in the current folder, add it to the listview
|
|
//
|
|
if (m_pCurrentParentItem == pNewCameraItem->Parent())
|
|
{
|
|
int nListViewCount = ListView_GetItemCount(hwndListview);
|
|
|
|
//
|
|
// Add the item
|
|
//
|
|
LVITEM lvItem = {0};
|
|
lvItem.iItem = nListViewCount;
|
|
lvItem.mask = LVIF_IMAGE|LVIF_PARAM;
|
|
lvItem.iImage = pNewCameraItem->ImageListIndex();
|
|
lvItem.lParam = reinterpret_cast<LPARAM>(pNewCameraItem);
|
|
int nIndex = ListView_InsertItem( hwndListview, &lvItem );
|
|
|
|
//
|
|
// Make sure the new item is visible
|
|
//
|
|
if (nIndex >= 0)
|
|
{
|
|
ListView_EnsureVisible( hwndListview, nIndex, FALSE );
|
|
}
|
|
}
|
|
|
|
//
|
|
// Request a thumbnail from the background thread
|
|
//
|
|
m_pThreadMessageQueue->Enqueue( new CThumbnailThreadMessage( m_hWnd, pNewCameraItem->GlobalInterfaceTableCookie(), m_sizeThumbnails ) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
bool CCameraAcquireDialog::PopulateList( CCameraItem *pOldParent )
|
|
{
|
|
//
|
|
// Which item should be selected?
|
|
//
|
|
int nSelItem = 0;
|
|
|
|
//
|
|
// Get the list view control
|
|
//
|
|
HWND hwndList = GetDlgItem( m_hWnd, IDC_THUMBNAILLIST );
|
|
if (hwndList)
|
|
{
|
|
//
|
|
// Empty the list
|
|
//
|
|
ListView_DeleteAllItems( hwndList );
|
|
|
|
//
|
|
// Where to insert the current item
|
|
//
|
|
int nCurrentItem = 0;
|
|
|
|
|
|
CCameraItem *pCurr;
|
|
|
|
//
|
|
// If this is a child directory...
|
|
//
|
|
if (m_pCurrentParentItem)
|
|
{
|
|
//
|
|
// Start adding children
|
|
//
|
|
pCurr = m_pCurrentParentItem->Children();
|
|
|
|
//
|
|
// Insert a dummy item that the user can use to switch to the parent directory
|
|
//
|
|
LVITEM lvItem;
|
|
ZeroMemory( &lvItem, sizeof(lvItem) );
|
|
lvItem.iItem = nCurrentItem++;
|
|
lvItem.mask = LVIF_IMAGE|LVIF_PARAM;
|
|
lvItem.iImage = m_nParentFolderImageListIndex;
|
|
lvItem.lParam = 0;
|
|
ListView_InsertItem( hwndList, &lvItem );
|
|
}
|
|
//
|
|
// Otherwise, we are at the root
|
|
//
|
|
else pCurr = m_CameraItemList.Root();
|
|
|
|
//
|
|
// Iterate through this list of images, and add each one
|
|
//
|
|
while (pCurr)
|
|
{
|
|
//
|
|
// If this is the last parent directory, we want it to be selected instead of the first image
|
|
//
|
|
if (pOldParent && *pCurr == *pOldParent)
|
|
{
|
|
nSelItem = nCurrentItem;
|
|
}
|
|
|
|
//
|
|
// If this image hasn't been deleted
|
|
//
|
|
if (pCurr->DeleteState() != CCameraItem::Delete_Deleted)
|
|
{
|
|
//
|
|
// Add the item
|
|
//
|
|
LVITEM lvItem = {0};
|
|
lvItem.iItem = nCurrentItem++;
|
|
lvItem.mask = LVIF_IMAGE|LVIF_PARAM;
|
|
lvItem.iImage = pCurr->ImageListIndex();
|
|
lvItem.lParam = reinterpret_cast<LPARAM>(pCurr);
|
|
int nIndex = ListView_InsertItem( hwndList, &lvItem );
|
|
|
|
if (nIndex >= 0 && pCurr->DeleteState() == CCameraItem::Delete_Pending)
|
|
{
|
|
MarkItemDeletePending(nIndex,true);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Advance
|
|
//
|
|
pCurr = pCurr->Next();
|
|
}
|
|
}
|
|
|
|
//
|
|
// If we've not calculated the width of the list in preview mode, attempt to do it
|
|
//
|
|
if (!m_nListViewWidth)
|
|
{
|
|
RECT rcItem;
|
|
if (ListView_GetItemRect( GetDlgItem( m_hWnd, IDC_THUMBNAILLIST ), 0, &rcItem, LVIR_ICON ))
|
|
{
|
|
m_nListViewWidth = (rcItem.right-rcItem.left) + rcItem.left * 2 + GetSystemMetrics(SM_CXHSCROLL) + c_nAdditionalMarginX;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Set the selected item to either the previous directory, or the first image
|
|
//
|
|
SetSelectedListItem(nSelItem);
|
|
return(true);
|
|
}
|
|
|
|
void CCameraAcquireDialog::CreateThumbnail( CCameraItem *pCurr, HIMAGELIST hImageList, bool bForce )
|
|
{
|
|
//
|
|
// Make sure we have a valid item
|
|
//
|
|
if (pCurr && (pCurr->ImageListIndex()<0 || bForce))
|
|
{
|
|
//
|
|
// Get the item name
|
|
//
|
|
CSimpleStringWide strItemName;
|
|
PropStorageHelpers::GetProperty( pCurr->Item(), WIA_IPA_ITEM_NAME, strItemName );
|
|
|
|
//
|
|
// Create the title for the icon
|
|
//
|
|
CSimpleString strIconTitle;
|
|
if (pCurr->IsFolder())
|
|
{
|
|
strIconTitle = CSimpleStringConvert::NaturalString(strItemName);
|
|
}
|
|
else if (strItemName.Length())
|
|
{
|
|
strIconTitle.Format( IDS_DOWNLOADINGTHUMBNAIL, g_hInstance, CSimpleStringConvert::NaturalString(strItemName).String() );
|
|
}
|
|
|
|
//
|
|
// Create the thumbnail
|
|
//
|
|
HBITMAP hBmp = WiaUiUtil::CreateIconThumbnail( GetDlgItem( m_hWnd, IDC_THUMBNAILLIST ), m_sizeThumbnails.cx, m_sizeThumbnails.cy, g_hInstance, pCurr->IsImage()?IDI_UNAVAILABLE:IDI_FOLDER, strIconTitle );
|
|
if (hBmp)
|
|
{
|
|
//
|
|
// If we don't have an image yet, add it
|
|
//
|
|
if (pCurr->ImageListIndex()<0)
|
|
{
|
|
pCurr->ImageListIndex(ImageList_Add( hImageList, hBmp, NULL ));
|
|
}
|
|
|
|
//
|
|
// Otherwise, replace it
|
|
//
|
|
else
|
|
{
|
|
pCurr->ImageListIndex(ImageList_Replace( hImageList, pCurr->ImageListIndex(), hBmp, NULL ));
|
|
}
|
|
|
|
//
|
|
// Delete it, since the imagelist makes a copy
|
|
//
|
|
DeleteObject(hBmp);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CCameraAcquireDialog::CreateThumbnails( CCameraItem *pRoot, HIMAGELIST hImageList, bool bForce )
|
|
{
|
|
CCameraItem *pCurr = pRoot;
|
|
while (pCurr)
|
|
{
|
|
//
|
|
// Create the thumbnail
|
|
//
|
|
CreateThumbnail( pCurr, hImageList, bForce );
|
|
|
|
//
|
|
// If there are children, recurse into that list
|
|
//
|
|
CreateThumbnails( pCurr->Children(), hImageList, bForce );
|
|
|
|
//
|
|
// Advance
|
|
//
|
|
pCurr = pCurr->Next();
|
|
}
|
|
}
|
|
|
|
|
|
void CCameraAcquireDialog::RequestThumbnails( CCameraItem *pRoot )
|
|
{
|
|
WIA_PUSHFUNCTION(TEXT("CCameraAcquireDialog::RequestThumbnails"));
|
|
CCameraItem *pCurr = pRoot;
|
|
while (pCurr)
|
|
{
|
|
if (pCurr->IsImage())
|
|
{
|
|
m_pThreadMessageQueue->Enqueue( new CThumbnailThreadMessage( m_hWnd, pCurr->GlobalInterfaceTableCookie(), m_sizeThumbnails ) );
|
|
}
|
|
if (pCurr->Children())
|
|
{
|
|
RequestThumbnails( pCurr->Children() );
|
|
}
|
|
pCurr = pCurr->Next();
|
|
}
|
|
}
|
|
|
|
|
|
void CCameraAcquireDialog::CreateThumbnails( bool bForce )
|
|
{
|
|
HWND hwndList = GetDlgItem( m_hWnd, IDC_THUMBNAILLIST );
|
|
if (hwndList)
|
|
{
|
|
HIMAGELIST hImageList = ListView_GetImageList( hwndList, LVSIL_NORMAL );
|
|
if (hImageList)
|
|
{
|
|
//
|
|
// Create the parent folder image
|
|
//
|
|
HBITMAP hParentBitmap = WiaUiUtil::CreateIconThumbnail( hwndList, m_sizeThumbnails.cx, m_sizeThumbnails.cy, g_hInstance, IDI_PARENTFOLDER, TEXT("(..)") );
|
|
if (hParentBitmap)
|
|
{
|
|
m_nParentFolderImageListIndex = ImageList_Add( hImageList, hParentBitmap, NULL );
|
|
DeleteObject(hParentBitmap);
|
|
}
|
|
CCameraAcquireDialog::CreateThumbnails( m_CameraItemList.Root(), hImageList, bForce );
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CCameraAcquireDialog::FindMaximumThumbnailSize(void)
|
|
{
|
|
WIA_PUSHFUNCTION(TEXT("CCameraAcquireDialog::FindMaximumThumbnailSize"));
|
|
bool bResult = false;
|
|
if (m_pDeviceDialogData && m_pDeviceDialogData->pIWiaItemRoot)
|
|
{
|
|
LONG nWidth, nHeight;
|
|
if (PropStorageHelpers::GetProperty( m_pDeviceDialogData->pIWiaItemRoot, WIA_DPC_THUMB_WIDTH, nWidth ) &&
|
|
PropStorageHelpers::GetProperty( m_pDeviceDialogData->pIWiaItemRoot, WIA_DPC_THUMB_WIDTH, nHeight ))
|
|
{
|
|
m_sizeThumbnails.cx = max(c_nMinThumbnailWidth,min(nWidth,c_nMaxThumbnailWidth));
|
|
m_sizeThumbnails.cy = max(c_nMinThumbnailHeight,min(nHeight,c_nMaxThumbnailHeight));
|
|
}
|
|
else WIA_TRACE((TEXT("FindMaximumThumbnailSize: Unable to retrieve thumbnail size for device")));
|
|
}
|
|
return(bResult && m_sizeThumbnails.cx && m_sizeThumbnails.cy);
|
|
}
|
|
|
|
//
|
|
// Hook procedure and static variables used to handle accelerators
|
|
//
|
|
LRESULT CALLBACK CCameraAcquireDialog::DialogHookProc( int nCode, WPARAM wParam, LPARAM lParam )
|
|
{
|
|
if (nCode < 0)
|
|
return CallNextHookEx( s_hMessageHook, nCode, wParam, lParam );
|
|
if (nCode == MSGF_DIALOGBOX)
|
|
{
|
|
MSG *pMsg = reinterpret_cast<MSG*>(lParam);
|
|
if (pMsg)
|
|
{
|
|
if (pMsg->hwnd == s_hWndDialog || (s_hWndDialog && IsChild(s_hWndDialog,pMsg->hwnd)))
|
|
{
|
|
CCameraAcquireDialog *pCameraAcquireDialog = reinterpret_cast<CCameraAcquireDialog*>(GetWindowLongPtr(s_hWndDialog,DWLP_USER));
|
|
if (pCameraAcquireDialog && pCameraAcquireDialog->m_hAccelTable)
|
|
{
|
|
if (TranslateAccelerator(s_hWndDialog,pCameraAcquireDialog->m_hAccelTable,pMsg))
|
|
return 1; // Ensure the window won't process the message
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return CallNextHookEx( s_hMessageHook, nCode, wParam, lParam );
|
|
}
|
|
|
|
|
|
LRESULT CCameraAcquireDialog::OnInitDialog( WPARAM, LPARAM lParam )
|
|
{
|
|
WIA_PUSHFUNCTION(TEXT("CCameraAcquireDialog::OnInitDialog"));
|
|
CWaitCursor wc;
|
|
|
|
//
|
|
// Make sure the background queue was successfully created
|
|
//
|
|
if (!m_pThreadMessageQueue)
|
|
{
|
|
WIA_ERROR((TEXT("CAMDLG: unable to start background queue")));
|
|
EndDialog( m_hWnd, E_OUTOFMEMORY );
|
|
return(0);
|
|
}
|
|
|
|
m_pDeviceDialogData = (PDEVICEDIALOGDATA)lParam;
|
|
|
|
// Save the window handle for the hook
|
|
s_hWndDialog = m_hWnd;
|
|
|
|
// Install the message hook, which we use for accelerator support
|
|
s_hMessageHook = SetWindowsHookEx( WH_MSGFILTER, DialogHookProc, g_hInstance, GetCurrentThreadId() );
|
|
if (!s_hMessageHook)
|
|
{
|
|
WIA_ERROR((TEXT("CAMDLG: Unable to set thread msg hook")));
|
|
EndDialog( m_hWnd, HRESULT_FROM_WIN32(GetLastError()));
|
|
return(0);
|
|
}
|
|
|
|
// Make sure we have valid arguments
|
|
if (!m_pDeviceDialogData)
|
|
{
|
|
WIA_ERROR((TEXT("CAMDLG: Invalid paramater: PDEVICEDIALOGDATA")));
|
|
EndDialog( m_hWnd, E_INVALIDARG );
|
|
return(0);
|
|
}
|
|
|
|
// Initialialize our return stuff
|
|
if (m_pDeviceDialogData)
|
|
{
|
|
m_pDeviceDialogData->lItemCount = 0;
|
|
m_pDeviceDialogData->ppWiaItems = NULL;
|
|
}
|
|
|
|
// Make sure we have valid a valid device
|
|
if (!m_pDeviceDialogData->pIWiaItemRoot)
|
|
{
|
|
WIA_ERROR((TEXT("CAMDLG: Invalid paramaters: pIWiaItem")));
|
|
EndDialog( m_hWnd, E_INVALIDARG );
|
|
return(0);
|
|
}
|
|
|
|
//
|
|
// Find out if Take Picture is supported
|
|
//
|
|
m_bTakePictureIsSupported = WiaUiUtil::IsDeviceCommandSupported( m_pDeviceDialogData->pIWiaItemRoot, WIA_CMD_TAKE_PICTURE );
|
|
|
|
// Prevent multiple selection
|
|
if (m_pDeviceDialogData->dwFlags & WIA_DEVICE_DIALOG_SINGLE_IMAGE)
|
|
{
|
|
LONG_PTR lStyle = GetWindowLongPtr( GetDlgItem( m_hWnd, IDC_THUMBNAILLIST ), GWL_STYLE );
|
|
SetWindowLongPtr( GetDlgItem( m_hWnd, IDC_THUMBNAILLIST ), GWL_STYLE, lStyle | LVS_SINGLESEL );
|
|
|
|
// Set the single sel titles
|
|
CSimpleString( IDS_TITLE_SINGLE_SEL, g_hInstance ).SetWindowText( GetDlgItem( m_hWnd, IDC_CAMDLG_BIG_TITLE ) );
|
|
CSimpleString( IDS_SUBTITLE_SINGLE_SEL, g_hInstance ).SetWindowText( GetDlgItem( m_hWnd, IDC_CAMDLG_SUBTITLE ) );
|
|
CSimpleString( IDS_OK_SINGLE_SEL, g_hInstance ).SetWindowText( GetDlgItem( m_hWnd, IDOK ) );
|
|
m_nDialogMode = SINGLESEL_MODE;
|
|
}
|
|
else
|
|
{
|
|
// Set the multi sel subtitle
|
|
CSimpleString( IDS_TITLE_MULTI_SEL, g_hInstance ).SetWindowText( GetDlgItem( m_hWnd, IDC_CAMDLG_BIG_TITLE ) );
|
|
CSimpleString( IDS_SUBTITLE_MULTI_SEL, g_hInstance ).SetWindowText( GetDlgItem( m_hWnd, IDC_CAMDLG_SUBTITLE ) );
|
|
CSimpleString( IDS_OK_MULTI_SEL, g_hInstance ).SetWindowText( GetDlgItem( m_hWnd, IDOK ) );
|
|
m_nDialogMode = MULTISEL_MODE;
|
|
}
|
|
|
|
|
|
// Make the lovely font
|
|
m_hBigFont = WiaUiUtil::CreateFontWithPointSizeFromWindow( GetDlgItem(m_hWnd,IDC_CAMDLG_BIG_TITLE), 14, false, false );
|
|
if (m_hBigFont)
|
|
SendDlgItemMessage( m_hWnd, IDC_CAMDLG_BIG_TITLE, WM_SETFONT, reinterpret_cast<WPARAM>(m_hBigFont), MAKELPARAM(TRUE,0));
|
|
|
|
|
|
// Create the Tool Bar and resize the dialog to accommodate it
|
|
(void)CreateCameraDialogToolbar();
|
|
|
|
// Get the minimum size of the dialog
|
|
RECT rcWindow;
|
|
GetWindowRect( m_hWnd, &rcWindow );
|
|
m_sizeMinimumWindow.cx = rcWindow.right - rcWindow.left;
|
|
m_sizeMinimumWindow.cy = rcWindow.bottom - rcWindow.top;
|
|
|
|
// Initialize the preview control
|
|
WiaPreviewControl_AllowNullSelection( GetDlgItem( m_hWnd, IDC_PREVIEW ), TRUE );
|
|
WiaPreviewControl_ClearSelection( GetDlgItem( m_hWnd, IDC_PREVIEW ) );
|
|
WiaPreviewControl_DisableSelection( GetDlgItem( m_hWnd, IDC_PREVIEW ), TRUE );
|
|
WiaPreviewControl_SetBorderSize( GetDlgItem( m_hWnd, IDC_PREVIEW ), FALSE, FALSE, 0 );
|
|
WiaPreviewControl_SetBgAlpha( GetDlgItem( m_hWnd, IDC_PREVIEW ), FALSE, 0xFF );
|
|
|
|
// Set the lovely title
|
|
CSimpleStringWide strwDeviceName;
|
|
if (PropStorageHelpers::GetProperty( m_pDeviceDialogData->pIWiaItemRoot, WIA_DIP_DEV_NAME, strwDeviceName ))
|
|
{
|
|
CSimpleString().Format( IDS_CAMERADLG_TITLE, g_hInstance, strwDeviceName.String() ).SetWindowText( m_hWnd );
|
|
}
|
|
|
|
// Create the sizing control
|
|
(void)CreateWindowEx( 0, TEXT("scrollbar"), TEXT(""),
|
|
WS_CHILD|WS_VISIBLE|SBS_SIZEGRIP|WS_CLIPSIBLINGS|SBS_SIZEBOXBOTTOMRIGHTALIGN|SBS_BOTTOMALIGN|WS_GROUP,
|
|
CSimpleRect(m_hWnd).Width()-GetSystemMetrics(SM_CXVSCROLL),
|
|
CSimpleRect(m_hWnd).Height()-GetSystemMetrics(SM_CYHSCROLL),
|
|
GetSystemMetrics(SM_CXVSCROLL),
|
|
GetSystemMetrics(SM_CYHSCROLL),
|
|
m_hWnd, reinterpret_cast<HMENU>(IDC_SIZEBOX),
|
|
g_hInstance, NULL );
|
|
|
|
// Reposition all the controls
|
|
ResizeAll();
|
|
|
|
// Center the window over its parent
|
|
WiaUiUtil::CenterWindow( m_hWnd, GetParent(m_hWnd) );
|
|
|
|
// Get the device icons and set the window icons
|
|
CSimpleStringWide strwDeviceId, strwClassId;
|
|
LONG nDeviceType;
|
|
if (PropStorageHelpers::GetProperty(m_pDeviceDialogData->pIWiaItemRoot,WIA_DIP_UI_CLSID,strwClassId) &&
|
|
PropStorageHelpers::GetProperty(m_pDeviceDialogData->pIWiaItemRoot,WIA_DIP_DEV_ID,strwDeviceId) &&
|
|
PropStorageHelpers::GetProperty(m_pDeviceDialogData->pIWiaItemRoot,WIA_DIP_DEV_TYPE,nDeviceType))
|
|
{
|
|
//
|
|
// Register for disconnect event
|
|
//
|
|
CGenericWiaEventHandler::RegisterForWiaEvent( strwDeviceId.String(), WIA_EVENT_DEVICE_DISCONNECTED, &m_DisconnectEvent, m_hWnd, PWM_WIAEVENT );
|
|
CGenericWiaEventHandler::RegisterForWiaEvent( strwDeviceId.String(), WIA_EVENT_ITEM_DELETED, &m_DeleteItemEvent, m_hWnd, PWM_WIAEVENT );
|
|
CGenericWiaEventHandler::RegisterForWiaEvent( strwDeviceId.String(), WIA_EVENT_ITEM_CREATED, &m_CreateItemEvent, m_hWnd, PWM_WIAEVENT );
|
|
|
|
if (SUCCEEDED(WiaUiExtensionHelper::GetDeviceIcons( CSimpleBStr(strwClassId), nDeviceType, &m_hIconSmall, &m_hIconLarge )))
|
|
{
|
|
if (m_hIconSmall)
|
|
{
|
|
SendMessage( m_hWnd, WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(m_hIconSmall) );
|
|
}
|
|
if (m_hIconLarge)
|
|
{
|
|
SendMessage( m_hWnd, WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(m_hIconLarge) );
|
|
}
|
|
}
|
|
}
|
|
|
|
int nAcceleratorCount = 0;
|
|
ACCEL Accelerators[10];
|
|
//
|
|
// Load the accelerator table resource and convert it to an ACCEL array
|
|
//
|
|
HACCEL hAccel = LoadAccelerators( g_hInstance, MAKEINTRESOURCE(IDR_CAMERA_ACCEL) );
|
|
if (hAccel)
|
|
{
|
|
//
|
|
// Copy the accelerator table to an array of ACCEL
|
|
//
|
|
nAcceleratorCount = CopyAcceleratorTable( hAccel, Accelerators, ARRAYSIZE(Accelerators) );
|
|
|
|
//
|
|
// Free the accelerator table
|
|
//
|
|
DestroyAcceleratorTable( hAccel );
|
|
}
|
|
|
|
//
|
|
// Create the accelerator table for the toolbar
|
|
//
|
|
nAcceleratorCount += ToolbarHelper::GetButtonBarAccelerators( GetDlgItem( m_hWnd, IDC_TOOLBAR ), Accelerators+nAcceleratorCount, ARRAYSIZE(Accelerators)-nAcceleratorCount );
|
|
if (nAcceleratorCount)
|
|
{
|
|
m_hAccelTable = CreateAcceleratorTable( Accelerators, nAcceleratorCount );
|
|
if (!m_hAccelTable)
|
|
{
|
|
WIA_PRINTHRESULT((HRESULT_FROM_WIN32(GetLastError()),TEXT("CreateAcceleratorTable failed")));
|
|
}
|
|
}
|
|
|
|
SetForegroundWindow(m_hWnd);
|
|
|
|
//
|
|
// Make sure the listview has the focus
|
|
//
|
|
SetFocus( GetDlgItem( m_hWnd, IDC_THUMBNAILLIST ) );
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
VOID CCameraAcquireDialog::ResizeAll(VOID)
|
|
{
|
|
CSimpleRect rcClient(m_hWnd);
|
|
CMoveWindow mw;
|
|
CDialogUnits dialogUnits(m_hWnd);
|
|
|
|
// Resize the big title
|
|
mw.Size( GetDlgItem( m_hWnd, IDC_CAMDLG_BIG_TITLE ),
|
|
rcClient.Width() - dialogUnits.StandardMargin().cx * 2,
|
|
0,
|
|
CMoveWindow::NO_SIZEY );
|
|
|
|
// Resize the subtitle
|
|
mw.Size( GetDlgItem( m_hWnd, IDC_CAMDLG_SUBTITLE ),
|
|
rcClient.Width() - dialogUnits.StandardMargin().cx * 2,
|
|
0,
|
|
CMoveWindow::NO_SIZEY );
|
|
|
|
int nToolBarHeight = (int)(HIWORD((DWORD)(SendMessage(GetDlgItem( m_hWnd, IDC_TOOLBAR ), TB_GETBUTTONSIZE, 0,0))));
|
|
|
|
// Resize the toolbar frame
|
|
mw.Size( GetDlgItem(m_hWnd,IDC_TOOLBAR_FRAME),
|
|
rcClient.Width() - dialogUnits.StandardMargin().cx * 2,
|
|
nToolBarHeight + 4,
|
|
0 );
|
|
|
|
// Get the dialog's client coordinates of the toolbar frame's client rect
|
|
CSimpleRect rcToolbarFrameInside( GetDlgItem(m_hWnd,IDC_TOOLBAR_FRAME), CSimpleRect::ClientRect );
|
|
rcToolbarFrameInside = rcToolbarFrameInside.ClientToScreen(GetDlgItem(m_hWnd,IDC_TOOLBAR_FRAME));
|
|
rcToolbarFrameInside = rcToolbarFrameInside.ScreenToClient(m_hWnd);
|
|
|
|
// Move and resize the toolbar
|
|
mw.SizeMove( GetDlgItem( m_hWnd, IDC_TOOLBAR ),
|
|
rcToolbarFrameInside.left + 2,
|
|
rcToolbarFrameInside.top + 2,
|
|
rcClient.Width() - dialogUnits.StandardMargin().cx * 2 - 4,
|
|
nToolBarHeight,
|
|
0 );
|
|
|
|
// Save the bottom of this control for later
|
|
int nBottomOfToolbarFrame = CSimpleRect( GetDlgItem(m_hWnd,IDC_TOOLBAR_FRAME), CSimpleRect::WindowRect ).ScreenToClient(m_hWnd).top + nToolBarHeight + 4;
|
|
|
|
|
|
// Move the Properties control
|
|
mw.SizeMove( GetDlgItem( m_hWnd, IDC_CAMDLG_PROPERTIES ),
|
|
0,
|
|
rcClient.Height() - dialogUnits.StandardMargin().cy - dialogUnits.Y(8) + 2,
|
|
dialogUnits.StandardMargin().cx,
|
|
dialogUnits.Y(8) + 2,
|
|
CMoveWindow::NO_MOVEX|CMoveWindow::NO_SIZEX );
|
|
|
|
// Move the static text above it
|
|
mw.Move( GetDlgItem( m_hWnd, IDC_YOU_CAN_ALSO ),
|
|
dialogUnits.StandardMargin().cx,
|
|
rcClient.Height() - dialogUnits.StandardMargin().cy - dialogUnits.Y(8) - 2 - dialogUnits.Y(8)
|
|
);
|
|
|
|
|
|
CSimpleRect rcOK( GetDlgItem( m_hWnd, IDOK ), CSimpleRect::WindowRect );
|
|
CSimpleRect rcCancel( GetDlgItem( m_hWnd, IDOK ), CSimpleRect::WindowRect );
|
|
|
|
// Move the OK button
|
|
mw.Move( GetDlgItem( m_hWnd, IDOK ),
|
|
rcClient.Width() - dialogUnits.StandardMargin().cx - dialogUnits.StandardButtonMargin().cx - rcCancel.Width() - rcOK.Width(),
|
|
rcClient.Height() - dialogUnits.StandardMargin().cy - rcOK.Height(),
|
|
0 );
|
|
|
|
// Move the cancel button
|
|
mw.Move( GetDlgItem( m_hWnd, IDCANCEL ),
|
|
rcClient.Width() - dialogUnits.StandardMargin().cx - rcCancel.Width(),
|
|
rcClient.Height() - dialogUnits.StandardMargin().cy - rcCancel.Height(),
|
|
0 );
|
|
|
|
// Move the resizing handle
|
|
mw.Move( GetDlgItem( m_hWnd, IDC_SIZEBOX ),
|
|
rcClient.Width() - GetSystemMetrics(SM_CXVSCROLL),
|
|
rcClient.Height() - GetSystemMetrics(SM_CYHSCROLL)
|
|
);
|
|
|
|
int nHeightOfBottomControls =
|
|
dialogUnits.Y(8) + 2 + // Highlight control
|
|
dialogUnits.Y(8) + // Static description text
|
|
dialogUnits.StandardMargin().cy; // Top of these controls
|
|
|
|
CSimpleRect rcAvailableArea(
|
|
dialogUnits.StandardMargin().cx,
|
|
nBottomOfToolbarFrame + dialogUnits.StandardMargin().cy,
|
|
rcClient.right - dialogUnits.StandardMargin().cx,
|
|
rcClient.bottom - nHeightOfBottomControls - dialogUnits.StandardMargin().cy
|
|
);
|
|
|
|
if (m_bPreviewActive)
|
|
{
|
|
// If we've already calculated the actual width of the preview mode list, use it, otherwise use the default
|
|
int nListViewWidth = m_nListViewWidth ? m_nListViewWidth : c_nDefaultListViewWidth;
|
|
|
|
// Move the thumbnail list
|
|
mw.SizeMove( GetDlgItem( m_hWnd, IDC_THUMBNAILLIST ),
|
|
rcAvailableArea.left,
|
|
rcAvailableArea.top,
|
|
nListViewWidth,
|
|
rcAvailableArea.Height()
|
|
);
|
|
|
|
// Remove the rect of the list view from the preview area
|
|
rcAvailableArea.left += nListViewWidth + dialogUnits.StandardMargin().cx;
|
|
|
|
// Use up the remaining area
|
|
mw.SizeMove( GetDlgItem( m_hWnd, IDC_PREVIEW ),
|
|
rcAvailableArea.left,
|
|
rcAvailableArea.top,
|
|
rcAvailableArea.Width(),
|
|
rcAvailableArea.Height() );
|
|
|
|
}
|
|
else
|
|
{
|
|
// Move the thumbnail list
|
|
mw.SizeMove( GetDlgItem( m_hWnd, IDC_THUMBNAILLIST ),
|
|
rcAvailableArea.left,
|
|
rcAvailableArea.top,
|
|
rcAvailableArea.Width(),
|
|
rcAvailableArea.Height()
|
|
);
|
|
|
|
}
|
|
|
|
// Explicitly apply the moves, because the toolbar frame doesn't get painted properly
|
|
mw.Apply();
|
|
|
|
if (m_bPreviewActive)
|
|
{
|
|
// Show the preview in case it isn't visible
|
|
mw.Show( GetDlgItem( m_hWnd, IDC_PREVIEW ) );
|
|
}
|
|
else
|
|
{
|
|
// Hide the preview in case it is visible
|
|
mw.Hide( GetDlgItem( m_hWnd, IDC_PREVIEW ) );
|
|
}
|
|
|
|
//
|
|
// Update the dialog's background to remove any weird stuff left behind
|
|
//
|
|
InvalidateRect( m_hWnd, NULL, FALSE );
|
|
UpdateWindow( m_hWnd );
|
|
}
|
|
|
|
|
|
LRESULT CCameraAcquireDialog::OnItemDeleted( WPARAM wParam, LPARAM lParam )
|
|
{
|
|
WIA_PUSHFUNCTION(TEXT("CCameraAcquireDialog::OnItemDeleted"));
|
|
CCameraItem *pDeletedItem = m_CameraItemList.Find((DWORD)wParam);
|
|
if (pDeletedItem)
|
|
{
|
|
BOOL bSuccess = (BOOL)lParam;
|
|
pDeletedItem->DeleteState( bSuccess ? CCameraItem::Delete_Deleted : CCameraItem::Delete_Visible );
|
|
if (pDeletedItem == m_pCurrentParentItem)
|
|
{
|
|
ChangeFolder(m_pCurrentParentItem->Parent());
|
|
}
|
|
|
|
int nIndex = FindItemInList(pDeletedItem);
|
|
if (nIndex >= 0)
|
|
{
|
|
if (bSuccess)
|
|
{
|
|
// Remove the item from the list
|
|
ListView_DeleteItem(GetDlgItem( m_hWnd, IDC_THUMBNAILLIST ),nIndex);
|
|
|
|
// Make sure we leave something selected
|
|
if (!ListView_GetSelectedCount(GetDlgItem( m_hWnd, IDC_THUMBNAILLIST )))
|
|
{
|
|
int nItemCount = ListView_GetItemCount(GetDlgItem( m_hWnd, IDC_THUMBNAILLIST ));
|
|
if (nItemCount)
|
|
{
|
|
if (nIndex >= nItemCount)
|
|
nIndex = nItemCount-1;
|
|
SetSelectedListItem(nIndex);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Make sure we update control's state when the list is empty
|
|
HandleSelectionChange();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// If the delete failed, remove the deleted state
|
|
MarkItemDeletePending(nIndex,false);
|
|
|
|
// Tell the user
|
|
MessageBeep( MB_ICONASTERISK );
|
|
}
|
|
}
|
|
}
|
|
return (0);
|
|
}
|
|
|
|
LRESULT CCameraAcquireDialog::OnWiaEvent( WPARAM, LPARAM lParam )
|
|
{
|
|
WIA_PUSHFUNCTION(TEXT("CCameraAcquireDialog::OnWiaEvent"));
|
|
CGenericWiaEventHandler::CEventMessage *pEventMessage = reinterpret_cast<CGenericWiaEventHandler::CEventMessage *>(lParam);
|
|
if (pEventMessage)
|
|
{
|
|
if (pEventMessage->EventId() == WIA_EVENT_DEVICE_DISCONNECTED)
|
|
{
|
|
WIA_TRACE((TEXT("Received disconnect event")));
|
|
EndDialog( m_hWnd, WIA_ERROR_OFFLINE );
|
|
}
|
|
else if (pEventMessage->EventId() == WIA_EVENT_ITEM_CREATED)
|
|
{
|
|
OnItemCreatedEvent( pEventMessage );
|
|
}
|
|
else if (pEventMessage->EventId() == WIA_EVENT_ITEM_DELETED)
|
|
{
|
|
WIA_TRACE((TEXT("Received deleted item event")));
|
|
|
|
CCameraItem *pDeletedItem = m_CameraItemList.Find(CSimpleBStr(pEventMessage->FullItemName()));
|
|
if (pDeletedItem)
|
|
{
|
|
//
|
|
// If we're deleting the current parent item,
|
|
// select a new one.
|
|
//
|
|
if (pDeletedItem == m_pCurrentParentItem)
|
|
{
|
|
ChangeFolder(m_pCurrentParentItem->Parent());
|
|
}
|
|
|
|
int nIndex = FindItemInList(pDeletedItem);
|
|
if (nIndex >= 0)
|
|
{
|
|
//
|
|
// Remove the item from the listview
|
|
//
|
|
ListView_DeleteItem(GetDlgItem( m_hWnd, IDC_THUMBNAILLIST ),nIndex);
|
|
|
|
//
|
|
// Make sure we leave something selected
|
|
//
|
|
if (!ListView_GetSelectedCount(GetDlgItem( m_hWnd, IDC_THUMBNAILLIST )))
|
|
{
|
|
int nItemCount = ListView_GetItemCount(GetDlgItem( m_hWnd, IDC_THUMBNAILLIST ));
|
|
if (nItemCount)
|
|
{
|
|
if (nIndex >= nItemCount)
|
|
{
|
|
nIndex = nItemCount-1;
|
|
}
|
|
|
|
SetSelectedListItem(nIndex);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Make sure we update control's state when the list is empty
|
|
//
|
|
HandleSelectionChange();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WIA_ERROR((TEXT("FindItemInList coulnd't find the item")));
|
|
}
|
|
|
|
//
|
|
// Mark the item as deleted.
|
|
//
|
|
pDeletedItem->DeleteState( CCameraItem::Delete_Deleted );
|
|
|
|
}
|
|
else
|
|
{
|
|
WIA_ERROR((TEXT("The item could not be found in m_CameraItemList")));
|
|
}
|
|
}
|
|
delete pEventMessage;
|
|
}
|
|
return HANDLED_EVENT_MESSAGE;
|
|
}
|
|
|
|
|
|
LRESULT CCameraAcquireDialog::OnEnterSizeMove( WPARAM, LPARAM )
|
|
{
|
|
SendDlgItemMessage( m_hWnd, IDC_PREVIEW, WM_ENTERSIZEMOVE, 0, 0 );
|
|
return(0);
|
|
}
|
|
|
|
|
|
LRESULT CCameraAcquireDialog::OnExitSizeMove( WPARAM, LPARAM )
|
|
{
|
|
SendDlgItemMessage( m_hWnd, IDC_PREVIEW, WM_EXITSIZEMOVE, 0, 0 );
|
|
return(0);
|
|
}
|
|
|
|
|
|
LRESULT CCameraAcquireDialog::OnSize( WPARAM, LPARAM )
|
|
{
|
|
ResizeAll();
|
|
return(0);
|
|
}
|
|
|
|
|
|
LRESULT CCameraAcquireDialog::OnShow( WPARAM, LPARAM )
|
|
{
|
|
if (m_bFirstTime)
|
|
{
|
|
PostMessage( m_hWnd, PWM_POSTINIT, 0, 0 );
|
|
m_bFirstTime = false;
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
LRESULT CCameraAcquireDialog::OnGetMinMaxInfo( WPARAM, LPARAM lParam )
|
|
{
|
|
LPMINMAXINFO pMinMaxInfo = (LPMINMAXINFO)lParam;
|
|
pMinMaxInfo->ptMinTrackSize.x = m_sizeMinimumWindow.cx;
|
|
pMinMaxInfo->ptMinTrackSize.y = m_sizeMinimumWindow.cy;
|
|
return(0);
|
|
}
|
|
|
|
|
|
LRESULT CCameraAcquireDialog::OnDestroy( WPARAM, LPARAM )
|
|
{
|
|
//
|
|
// Get rid of all preview requests
|
|
//
|
|
CancelAllPreviewRequests( m_CameraItemList.Root() );
|
|
|
|
//
|
|
// Tell the background thread to destroy itself
|
|
//
|
|
m_pThreadMessageQueue->Enqueue( new CThreadMessage(TQ_DESTROY),CThreadMessageQueue::PriorityUrgent);
|
|
|
|
//
|
|
// Set the window icon to NULL
|
|
//
|
|
SendMessage( m_hWnd, WM_SETICON, ICON_BIG, 0 );
|
|
SendMessage( m_hWnd, WM_SETICON, ICON_SMALL, 0 );
|
|
|
|
//
|
|
// Clear the image list and list view. This should be unnecessary, but BoundsChecker
|
|
// complains if I don't do it.
|
|
//
|
|
HWND hwndList = GetDlgItem( m_hWnd, IDC_THUMBNAILLIST );
|
|
if (hwndList)
|
|
{
|
|
ListView_DeleteAllItems(hwndList);
|
|
|
|
HIMAGELIST hImgList = ListView_SetImageList( hwndList, NULL, LVSIL_NORMAL );
|
|
if (hImgList)
|
|
{
|
|
ImageList_Destroy(hImgList);
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Delete resources
|
|
//
|
|
if (m_hBigFont)
|
|
{
|
|
DeleteObject(m_hBigFont);
|
|
m_hBigFont = NULL;
|
|
}
|
|
if (m_hImageList)
|
|
{
|
|
m_hImageList = NULL;
|
|
}
|
|
if (m_hAccelTable)
|
|
{
|
|
DestroyAcceleratorTable(m_hAccelTable);
|
|
m_hAccelTable = NULL;
|
|
}
|
|
if (s_hMessageHook)
|
|
{
|
|
UnhookWindowsHookEx(s_hMessageHook);
|
|
s_hMessageHook = NULL;
|
|
}
|
|
if (m_hIconLarge)
|
|
{
|
|
DestroyIcon(m_hIconLarge);
|
|
m_hIconLarge = NULL;
|
|
}
|
|
if (m_hIconSmall)
|
|
{
|
|
DestroyIcon(m_hIconSmall);
|
|
m_hIconSmall = NULL;
|
|
}
|
|
if (m_hBackgroundThread)
|
|
{
|
|
CloseHandle(m_hBackgroundThread);
|
|
m_hBackgroundThread = NULL;
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
|
|
VOID CCameraAcquireDialog::OnPreviewMode( WPARAM, LPARAM )
|
|
{
|
|
m_bPreviewActive = true;
|
|
SendDlgItemMessage( m_hWnd, IDC_TOOLBAR, TB_SETSTATE, IDC_PREVIEWMODE, MAKELONG(TBSTATE_ENABLED|TBSTATE_CHECKED,0) );
|
|
SendDlgItemMessage( m_hWnd, IDC_TOOLBAR, TB_SETSTATE, IDC_ICONMODE, MAKELONG(TBSTATE_ENABLED,0) );
|
|
ResizeAll();
|
|
UpdatePreview();
|
|
}
|
|
|
|
VOID CCameraAcquireDialog::OnTakePicture( WPARAM, LPARAM )
|
|
{
|
|
//
|
|
// Tell the device to snap a picture
|
|
//
|
|
if (m_pDeviceDialogData->pIWiaItemRoot && m_bTakePictureIsSupported)
|
|
{
|
|
CWaitCursor wc;
|
|
CComPtr<IWiaItem> pNewWiaItem;
|
|
m_pDeviceDialogData->pIWiaItemRoot->DeviceCommand(0,&WIA_CMD_TAKE_PICTURE,&pNewWiaItem);
|
|
}
|
|
}
|
|
|
|
VOID CCameraAcquireDialog::OnIconMode( WPARAM, LPARAM )
|
|
{
|
|
m_bPreviewActive = false;
|
|
SendDlgItemMessage( m_hWnd, IDC_TOOLBAR, TB_SETSTATE, IDC_ICONMODE, MAKELONG(TBSTATE_ENABLED|TBSTATE_CHECKED,0) );
|
|
SendDlgItemMessage( m_hWnd, IDC_TOOLBAR, TB_SETSTATE, IDC_PREVIEWMODE, MAKELONG(TBSTATE_ENABLED,0) );
|
|
ResizeAll();
|
|
UpdatePreview();
|
|
}
|
|
|
|
LRESULT CCameraAcquireDialog::OnPostInit( WPARAM, LPARAM )
|
|
{
|
|
//
|
|
// Create the progress dialog
|
|
//
|
|
CComPtr<IWiaProgressDialog> pWiaProgressDialog;
|
|
HRESULT hr = CoCreateInstance( CLSID_WiaDefaultUi, NULL, CLSCTX_INPROC_SERVER, IID_IWiaProgressDialog, (void**)&pWiaProgressDialog );
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//
|
|
// Initialize the progress dialog
|
|
//
|
|
pWiaProgressDialog->Create( m_hWnd, WIA_PROGRESSDLG_ANIM_CAMERA_COMMUNICATE|WIA_PROGRESSDLG_NO_PROGRESS|WIA_PROGRESSDLG_NO_CANCEL|WIA_PROGRESSDLG_NO_TITLE );
|
|
pWiaProgressDialog->SetTitle( CSimpleStringConvert::WideString(CSimpleString(IDS_CAMDLG_PROGDLG_TITLE,g_hInstance)));
|
|
pWiaProgressDialog->SetMessage( CSimpleStringConvert::WideString(CSimpleString(IDS_CAMDLG_PROGDLG_MESSAGE,g_hInstance)));
|
|
|
|
//
|
|
// Show the progress dialog
|
|
//
|
|
pWiaProgressDialog->Show();
|
|
|
|
//
|
|
// Find all of the images in the camera
|
|
//
|
|
EnumerateAllCameraItems();
|
|
|
|
//
|
|
// Find the largest possible thumbnail
|
|
//
|
|
FindMaximumThumbnailSize();
|
|
|
|
//
|
|
// Initialize Thumbnail Listview control
|
|
//
|
|
HWND hwndList = GetDlgItem( m_hWnd, IDC_THUMBNAILLIST );
|
|
if (hwndList)
|
|
{
|
|
//
|
|
// Get rid of the border and icon labels
|
|
//
|
|
ListView_SetExtendedListViewStyleEx( hwndList, LVS_EX_BORDERSELECT|LVS_EX_HIDELABELS|LVS_EX_DOUBLEBUFFER, LVS_EX_BORDERSELECT|LVS_EX_HIDELABELS|LVS_EX_DOUBLEBUFFER );
|
|
|
|
//
|
|
// Create the large image list
|
|
//
|
|
m_hImageList = ImageList_Create( m_sizeThumbnails.cx, m_sizeThumbnails.cy, ILC_COLOR24|ILC_MIRROR, 50, 50 );
|
|
if (m_hImageList)
|
|
{
|
|
|
|
//
|
|
// Set the image list
|
|
//
|
|
ListView_SetImageList( hwndList, m_hImageList, LVSIL_NORMAL );
|
|
}
|
|
|
|
//
|
|
// Set the icon spacing
|
|
//
|
|
ListView_SetIconSpacing( hwndList, m_sizeThumbnails.cx + c_nAdditionalMarginX, m_sizeThumbnails.cy + c_nAdditionalMarginY );
|
|
}
|
|
|
|
//
|
|
// Create all of the initial thumbnails
|
|
//
|
|
CreateThumbnails();
|
|
|
|
//
|
|
// This causes the list to be populated
|
|
//
|
|
ChangeFolder(NULL);
|
|
|
|
//
|
|
// Force a selection change
|
|
//
|
|
HandleSelectionChange();
|
|
|
|
//
|
|
// Download all of the thumbnails
|
|
//
|
|
RequestThumbnails( m_CameraItemList.Root() );
|
|
|
|
//
|
|
// Close the progress dialog
|
|
//
|
|
pWiaProgressDialog->Destroy();
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
LRESULT CCameraAcquireDialog::OnChangeToParent( WPARAM, LPARAM )
|
|
{
|
|
if (m_pCurrentParentItem)
|
|
ChangeFolder(m_pCurrentParentItem->Parent());
|
|
return(0);
|
|
}
|
|
|
|
VOID CCameraAcquireDialog::OnParentDir( WPARAM, LPARAM )
|
|
{
|
|
if (m_pCurrentParentItem && m_pCurrentParentItem->Parent())
|
|
ChangeFolder(m_pCurrentParentItem->Parent());
|
|
else ChangeFolder(NULL);
|
|
}
|
|
|
|
void CCameraAcquireDialog::MarkItemDeletePending( int nIndex, bool bSet )
|
|
{
|
|
HWND hwndList = GetDlgItem( m_hWnd, IDC_THUMBNAILLIST );
|
|
if (hwndList)
|
|
{
|
|
ListView_SetItemState( hwndList, nIndex, bSet ? LVIS_CUT : 0, LVIS_CUT );
|
|
}
|
|
}
|
|
|
|
// Recursively delete items
|
|
void CCameraAcquireDialog::DeleteItem( CCameraItem *pItemNode )
|
|
{
|
|
if (pItemNode)
|
|
{
|
|
CCameraItem *pChild = pItemNode->Children();
|
|
while (pChild)
|
|
{
|
|
DeleteItem(pChild);
|
|
pChild = pChild->Next();
|
|
}
|
|
if (pItemNode->DeleteState() == CCameraItem::Delete_Visible)
|
|
{
|
|
int nIndex = FindItemInList( pItemNode );
|
|
if (nIndex >= 0)
|
|
{
|
|
//
|
|
// Mark it pending in the UI
|
|
//
|
|
MarkItemDeletePending(nIndex,true);
|
|
}
|
|
//
|
|
// Mark it pending
|
|
//
|
|
pItemNode->DeleteState( CCameraItem::Delete_Pending );
|
|
|
|
//
|
|
// Fire off the request
|
|
//
|
|
m_pThreadMessageQueue->Enqueue( new CDeleteThreadMessage(m_hWnd, pItemNode->GlobalInterfaceTableCookie()), CThreadMessageQueue::PriorityHigh );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
VOID CCameraAcquireDialog::OnDelete( WPARAM, LPARAM )
|
|
{
|
|
CSimpleDynamicArray<int> aSelIndices;
|
|
if (GetSelectionIndices( aSelIndices ))
|
|
{
|
|
//
|
|
// We only want to show the confirm dialog once
|
|
//
|
|
bool bShowConfirmDialog = true;
|
|
for (int i=0;i<aSelIndices.Size();i++)
|
|
{
|
|
CCameraItem *pItemNode = GetListItemNode(aSelIndices[i]);
|
|
|
|
//
|
|
// If we haven't already deleted this image, do so
|
|
//
|
|
if (pItemNode && pItemNode->DeleteState() == CCameraItem::Delete_Visible && pItemNode->ItemRights() & WIA_ITEM_CAN_BE_DELETED)
|
|
{
|
|
if (bShowConfirmDialog)
|
|
{
|
|
bShowConfirmDialog = false;
|
|
if (IDYES!=MessageBox( m_hWnd, CSimpleString( IDS_DELETE_CONFIRM, g_hInstance ), CSimpleString( IDS_DELETE_CONFIRM_TITLE, g_hInstance ), MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2 ))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
DeleteItem( pItemNode );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
int CCameraAcquireDialog::GetSelectionIndices( CSimpleDynamicArray<int> &aIndices )
|
|
{
|
|
HWND hwndList = GetDlgItem( m_hWnd, IDC_THUMBNAILLIST );
|
|
if (!hwndList)
|
|
return(0);
|
|
int iCount = ListView_GetItemCount(hwndList);
|
|
for (int i=0;i<iCount;i++)
|
|
if (ListView_GetItemState(hwndList,i,LVIS_SELECTED) & LVIS_SELECTED)
|
|
aIndices.Append(i);
|
|
return(aIndices.Size());
|
|
}
|
|
|
|
bool CCameraAcquireDialog::SetSelectedListItem( int nIndex )
|
|
{
|
|
HWND hwndList = GetDlgItem( m_hWnd, IDC_THUMBNAILLIST );
|
|
if (!hwndList)
|
|
return(false);
|
|
int iCount = ListView_GetItemCount(hwndList);
|
|
for (int i=0;i<iCount;i++)
|
|
ListView_SetItemState(hwndList,i,LVIS_SELECTED|LVIS_FOCUSED,0);
|
|
ListView_SetItemState(hwndList,nIndex,LVIS_SELECTED|LVIS_FOCUSED,LVIS_SELECTED|LVIS_FOCUSED);
|
|
ListView_EnsureVisible(hwndList,nIndex,FALSE);
|
|
return(true);
|
|
}
|
|
|
|
CCameraItem *CCameraAcquireDialog::GetListItemNode( int nIndex )
|
|
{
|
|
HWND hwndList = GetDlgItem( m_hWnd, IDC_THUMBNAILLIST );
|
|
if (!hwndList)
|
|
return(NULL);
|
|
LV_ITEM lvItem;
|
|
::ZeroMemory(&lvItem,sizeof(LV_ITEM));
|
|
lvItem.mask = LVIF_PARAM;
|
|
lvItem.iItem = nIndex;
|
|
if (!ListView_GetItem( hwndList, &lvItem ))
|
|
return(NULL);
|
|
return((CCameraItem *)lvItem.lParam);
|
|
}
|
|
|
|
bool CCameraAcquireDialog::ChangeFolder( CCameraItem *pNode )
|
|
{
|
|
CCameraItem *pOldParent = m_pCurrentParentItem;
|
|
m_pCurrentParentItem = pNode;
|
|
return(PopulateList(pOldParent));
|
|
}
|
|
|
|
bool CCameraAcquireDialog::ChangeToSelectedFolder(void)
|
|
{
|
|
CSimpleDynamicArray<int> aSelIndices;
|
|
if (GetSelectionIndices(aSelIndices))
|
|
{
|
|
//
|
|
// Find out if only folders are selected
|
|
//
|
|
bool bOnlyFoldersSelected = true;
|
|
for (int i=0;i<aSelIndices.Size();i++)
|
|
{
|
|
CCameraItem *pItemNode = GetListItemNode(aSelIndices[i]);
|
|
if (pItemNode && !pItemNode->IsFolder())
|
|
{
|
|
bOnlyFoldersSelected = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
WIA_TRACE((TEXT("bOnlyFoldersSelected = %d"),bOnlyFoldersSelected));
|
|
|
|
//
|
|
// If only folders are selected, switch to the first selected folder
|
|
//
|
|
if (bOnlyFoldersSelected && aSelIndices.Size())
|
|
{
|
|
CCameraItem *pItemNode = GetListItemNode(aSelIndices[0]);
|
|
if (!pItemNode)
|
|
{
|
|
//
|
|
// NULL item node == parent folder
|
|
//
|
|
SendMessage( m_hWnd, PWM_CHANGETOPARENT, 0, 0 );
|
|
return(true);
|
|
}
|
|
if (pItemNode && pItemNode->IsFolder() && pItemNode->DeleteState() == CCameraItem::Delete_Visible)
|
|
{
|
|
if (ChangeFolder(pItemNode))
|
|
{
|
|
return(true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return(false);
|
|
}
|
|
|
|
VOID CCameraAcquireDialog::OnOK( WPARAM, LPARAM )
|
|
{
|
|
if (!ChangeToSelectedFolder())
|
|
{
|
|
HRESULT hr = S_OK;
|
|
m_pDeviceDialogData->lItemCount = 0;
|
|
m_pDeviceDialogData->ppWiaItems = NULL;
|
|
CSimpleDynamicArray<int> aIndices;
|
|
GetSelectionIndices( aIndices );
|
|
if (aIndices.Size())
|
|
{
|
|
int nArraySizeInBytes = sizeof(IWiaItem*) * aIndices.Size();
|
|
m_pDeviceDialogData->ppWiaItems = (IWiaItem**)CoTaskMemAlloc(nArraySizeInBytes);
|
|
if (m_pDeviceDialogData->ppWiaItems)
|
|
{
|
|
ZeroMemory( m_pDeviceDialogData->ppWiaItems, nArraySizeInBytes );
|
|
int nCurrItem = 0;
|
|
for (int i=0;i<aIndices.Size();i++)
|
|
{
|
|
CCameraItem *pItem = GetListItemNode(aIndices[i]);
|
|
|
|
//
|
|
// Add the item to the list if it is both a valid picture item and it hasn't been deleted
|
|
//
|
|
if (pItem && pItem->Item() && pItem->IsImage() && pItem->DeleteState() == CCameraItem::Delete_Visible)
|
|
{
|
|
m_pDeviceDialogData->ppWiaItems[nCurrItem] = pItem->Item();
|
|
m_pDeviceDialogData->ppWiaItems[nCurrItem]->AddRef();
|
|
nCurrItem++;
|
|
}
|
|
}
|
|
m_pDeviceDialogData->lItemCount = nCurrItem;
|
|
}
|
|
else
|
|
{
|
|
// Unable to alloc mem
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
EndDialog( m_hWnd, hr );
|
|
}
|
|
}
|
|
|
|
|
|
VOID CCameraAcquireDialog::OnCancel( WPARAM, LPARAM )
|
|
{
|
|
EndDialog( m_hWnd, S_FALSE );
|
|
}
|
|
|
|
VOID CCameraAcquireDialog::OnSelectAll( WPARAM, LPARAM )
|
|
{
|
|
ListView_SetItemState( GetDlgItem( m_hWnd, IDC_THUMBNAILLIST ), -1, LVIS_SELECTED, LVIS_SELECTED );
|
|
}
|
|
|
|
VOID CCameraAcquireDialog::OnProperties( WPARAM, LPARAM )
|
|
{
|
|
CSimpleDynamicArray<int> aSelIndices;
|
|
if (GetSelectionIndices( aSelIndices ))
|
|
{
|
|
if (aSelIndices.Size() == 1)
|
|
{
|
|
CCameraItem *pItemNode = GetListItemNode(aSelIndices[0]);
|
|
if (pItemNode && pItemNode->Item())
|
|
{
|
|
m_pThreadMessageQueue->Pause();
|
|
HRESULT hr = WiaUiUtil::SystemPropertySheet( g_hInstance, m_hWnd, pItemNode->Item(), CSimpleString( IDS_CAMDLG_PROPERTIES_TITLE, g_hInstance ) );
|
|
if (!SUCCEEDED(hr))
|
|
{
|
|
if (PROP_SHEET_ERROR_NO_PAGES == hr)
|
|
{
|
|
MessageBox( m_hWnd, CSimpleString( IDS_CAMDLG_PROPSHEETNOPAGES, g_hInstance ), CSimpleString( IDS_CAMDLG_ERROR_TITLE, g_hInstance ), MB_ICONINFORMATION );
|
|
}
|
|
else
|
|
{
|
|
MessageBox( m_hWnd, CSimpleString( IDS_CAMDLG_PROPSHEETERROR, g_hInstance ), CSimpleString( IDS_CAMDLG_ERROR_TITLE, g_hInstance ), MB_ICONINFORMATION );
|
|
}
|
|
WIA_PRINTHRESULT((hr,TEXT("SystemPropertySheet failed")));
|
|
}
|
|
m_pThreadMessageQueue->Resume();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
LRESULT CCameraAcquireDialog::OnDblClkImageList( WPARAM, LPARAM )
|
|
{
|
|
SendMessage( m_hWnd, WM_COMMAND, MAKEWPARAM(IDOK,0), 0 );
|
|
return(0);
|
|
}
|
|
|
|
void CCameraAcquireDialog::CancelAllPreviewRequests( CCameraItem *pRoot )
|
|
{
|
|
CCameraItem *pCurr = pRoot;
|
|
while (pCurr)
|
|
{
|
|
if (pCurr->PreviewRequestPending())
|
|
pCurr->SetCancelEvent();
|
|
if (pCurr->Children())
|
|
CancelAllPreviewRequests( pCurr->Children() );
|
|
pCurr = pCurr->Next();
|
|
}
|
|
}
|
|
|
|
void CCameraAcquireDialog::UpdatePreview(void)
|
|
{
|
|
if (m_bPreviewActive)
|
|
{
|
|
CCameraItem *pCurrPreviewItem = GetCurrentPreviewItem();
|
|
if (pCurrPreviewItem && pCurrPreviewItem->IsImage())
|
|
{
|
|
// If we're not already downloading this preview image...
|
|
if (!pCurrPreviewItem->PreviewRequestPending())
|
|
{
|
|
// Cancel all other preview requests
|
|
CancelAllPreviewRequests( m_CameraItemList.Root() );
|
|
|
|
if (pCurrPreviewItem->PreviewFileName().Length())
|
|
{
|
|
// Set the preview if we've got it cached
|
|
SetCurrentPreviewImage( pCurrPreviewItem->PreviewFileName() );
|
|
}
|
|
else
|
|
{
|
|
CSimpleString strPct;
|
|
strPct.Format( IDS_DOWNLOADINGPREVIEW, g_hInstance, 0 );
|
|
|
|
// Clear the preview window
|
|
SetCurrentPreviewImage( TEXT(""), strPct );
|
|
|
|
// Create our cancel event
|
|
pCurrPreviewItem->CreateCancelEvent();
|
|
// Reset it, just in case
|
|
pCurrPreviewItem->ResetCancelEvent();
|
|
// Make the request
|
|
m_pThreadMessageQueue->Enqueue( new CPreviewThreadMessage( m_hWnd, pCurrPreviewItem->GlobalInterfaceTableCookie(), pCurrPreviewItem->CancelQueueEvent().Event() ), CThreadMessageQueue::PriorityHigh );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CSimpleString strPct;
|
|
strPct.Format( IDS_DOWNLOADINGPREVIEW, g_hInstance, pCurrPreviewItem->CurrentPreviewPercentage() );
|
|
|
|
SetCurrentPreviewImage( TEXT(""), strPct );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetCurrentPreviewImage( TEXT("") );
|
|
CancelAllPreviewRequests( m_CameraItemList.Root() );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CancelAllPreviewRequests( m_CameraItemList.Root() );
|
|
SetCurrentPreviewImage( TEXT("") );
|
|
}
|
|
}
|
|
|
|
LRESULT CCameraAcquireDialog::OnTimer( WPARAM wParam, LPARAM )
|
|
{
|
|
switch (wParam)
|
|
{
|
|
case IDT_UPDATEPREVIEW:
|
|
{
|
|
KillTimer( m_hWnd, IDT_UPDATEPREVIEW );
|
|
UpdatePreview();
|
|
}
|
|
break;
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
// Avoids unnecessary state changes
|
|
static inline void MyEnableWindow( HWND hWnd, BOOL bEnable )
|
|
{
|
|
if (bEnable && !IsWindowEnabled(hWnd))
|
|
EnableWindow(hWnd,TRUE);
|
|
else if (!bEnable && IsWindowEnabled(hWnd))
|
|
EnableWindow(hWnd,FALSE);
|
|
}
|
|
|
|
// Avoids unnecessary state changes
|
|
static inline void MyEnableToolbarButton( HWND hWnd, int nId, BOOL bEnable )
|
|
{
|
|
LRESULT nState = SendMessage( hWnd, TB_GETSTATE, nId, 0 );
|
|
if (nState < 0)
|
|
return;
|
|
if ((nState & TBSTATE_ENABLED) && !bEnable)
|
|
SendMessage( hWnd, TB_ENABLEBUTTON, nId, nState & ~TBSTATE_ENABLED);
|
|
else if (!(nState & TBSTATE_ENABLED) && bEnable)
|
|
SendMessage( hWnd, TB_ENABLEBUTTON, nId, nState | TBSTATE_ENABLED );
|
|
}
|
|
|
|
|
|
void CCameraAcquireDialog::HandleSelectionChange(void)
|
|
{
|
|
CWaitCursor wc;
|
|
int nSelCount = ListView_GetSelectedCount(GetDlgItem( m_hWnd, IDC_THUMBNAILLIST ) );
|
|
int nItemCount = ListView_GetItemCount(GetDlgItem( m_hWnd, IDC_THUMBNAILLIST ) );
|
|
|
|
//
|
|
// Properties should be disabled for multiple items
|
|
// and parent folder icons
|
|
//
|
|
bool bDisableProperties = true;
|
|
if (nSelCount == 1)
|
|
{
|
|
CSimpleDynamicArray<int> aIndices;
|
|
if (CCameraAcquireDialog::GetSelectionIndices( aIndices ))
|
|
{
|
|
if (CCameraAcquireDialog::GetListItemNode( aIndices[0] ))
|
|
{
|
|
bDisableProperties = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
MyEnableWindow( GetDlgItem(m_hWnd,IDC_CAMDLG_PROPERTIES), !bDisableProperties );
|
|
|
|
// OK should be disabled for 0 items
|
|
MyEnableWindow( GetDlgItem(m_hWnd,IDOK), nSelCount != 0 );
|
|
|
|
// Select all should be disabled for 0 items
|
|
MyEnableToolbarButton( GetDlgItem(m_hWnd,IDC_TOOLBAR), IDC_SELECTALL, nItemCount != 0 );
|
|
|
|
//
|
|
// Decide whether or not delete should be enabled
|
|
// If any of the selected items are deletable, then delete is enabled
|
|
//
|
|
bool bEnableDelete = false;
|
|
|
|
//
|
|
// Get the selected items
|
|
//
|
|
CSimpleDynamicArray<int> aSelIndices;
|
|
if (GetSelectionIndices( aSelIndices ))
|
|
{
|
|
//
|
|
// Loop through all of the selected items. Break out if we find a reason
|
|
// to enable delete.
|
|
//
|
|
for (int i=0;i<aSelIndices.Size() && !bEnableDelete;i++)
|
|
{
|
|
//
|
|
// Get the item
|
|
//
|
|
CCameraItem *pItemNode = GetListItemNode(aSelIndices[i]);
|
|
|
|
//
|
|
// If we don't have an item, it is a parent folder
|
|
//
|
|
if (pItemNode)
|
|
{
|
|
//
|
|
// If the access rights include the right to delete items,
|
|
// break out.
|
|
//
|
|
if (pItemNode->ItemRights() & WIA_ITEM_CAN_BE_DELETED)
|
|
{
|
|
//
|
|
// Found one, so we are done.
|
|
//
|
|
bEnableDelete = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
MyEnableToolbarButton( GetDlgItem(m_hWnd,IDC_TOOLBAR), IDC_DELETE, bEnableDelete );
|
|
|
|
KillTimer( m_hWnd, IDT_UPDATEPREVIEW );
|
|
SetTimer( m_hWnd, IDT_UPDATEPREVIEW, UPDATE_PREVIEW_DELAY, NULL );
|
|
}
|
|
|
|
|
|
LRESULT CCameraAcquireDialog::OnImageListItemChanged( WPARAM, LPARAM )
|
|
{
|
|
HandleSelectionChange();
|
|
return(0);
|
|
}
|
|
|
|
LRESULT CCameraAcquireDialog::OnImageListKeyDown( WPARAM, LPARAM lParam )
|
|
{
|
|
LPNMLVKEYDOWN pnkd = reinterpret_cast<LPNMLVKEYDOWN>(lParam);
|
|
if (pnkd)
|
|
{
|
|
bool bAlt = ((GetKeyState(VK_MENU) & 0x8000) != 0);
|
|
bool bControl = ((GetKeyState(VK_CONTROL) & 0x8000) != 0);
|
|
bool bShift = ((GetKeyState(VK_SHIFT) & 0x8000) != 0);
|
|
if (VK_LEFT == pnkd->wVKey && bAlt && !bControl && !bShift)
|
|
{
|
|
SendMessage( m_hWnd, PWM_CHANGETOPARENT, 0, 0 );
|
|
}
|
|
else if (VK_BACK == pnkd->wVKey && !bAlt && !bControl && !bShift)
|
|
{
|
|
SendMessage( m_hWnd, PWM_CHANGETOPARENT, 0, 0 );
|
|
}
|
|
else if (VK_DELETE == pnkd->wVKey)
|
|
{
|
|
SendMessage( m_hWnd, WM_COMMAND, IDC_DELETE, 0 );
|
|
}
|
|
}
|
|
return (0);
|
|
}
|
|
|
|
LRESULT CCameraAcquireDialog::OnHelp( WPARAM wParam, LPARAM lParam )
|
|
{
|
|
return WiaHelp::HandleWmHelp( wParam, lParam, g_HelpIDs );
|
|
}
|
|
|
|
LRESULT CCameraAcquireDialog::OnContextMenu( WPARAM wParam, LPARAM lParam )
|
|
{
|
|
return WiaHelp::HandleWmContextMenu( wParam, lParam, g_HelpIDs );
|
|
}
|
|
|
|
LRESULT CCameraAcquireDialog::OnSysColorChange( WPARAM wParam, LPARAM lParam )
|
|
{
|
|
WiaPreviewControl_SetBkColor( GetDlgItem( m_hWnd, IDC_PREVIEW ), TRUE, TRUE, GetSysColor(COLOR_WINDOW) );
|
|
WiaPreviewControl_SetBkColor( GetDlgItem( m_hWnd, IDC_PREVIEW ), TRUE, FALSE, GetSysColor(COLOR_WINDOW) );
|
|
SendDlgItemMessage( m_hWnd, IDC_THUMBNAILLIST, WM_SYSCOLORCHANGE, wParam, lParam );
|
|
SendDlgItemMessage( m_hWnd, IDC_TOOLBAR, WM_SYSCOLORCHANGE, wParam, lParam );
|
|
SendDlgItemMessage( m_hWnd, IDC_CAMDLG_PROPERTIES, WM_SYSCOLORCHANGE, wParam, lParam );
|
|
m_ToolbarBitmapInfo.ReloadAndReplaceBitmap();
|
|
return 0;
|
|
}
|
|
|
|
LRESULT CCameraAcquireDialog::OnNotify( WPARAM wParam, LPARAM lParam )
|
|
{
|
|
SC_BEGIN_NOTIFY_MESSAGE_HANDLERS()
|
|
{
|
|
SC_HANDLE_NOTIFY_MESSAGE_CONTROL( NM_DBLCLK, IDC_THUMBNAILLIST, OnDblClkImageList );
|
|
SC_HANDLE_NOTIFY_MESSAGE_CONTROL( LVN_ITEMCHANGED, IDC_THUMBNAILLIST, OnImageListItemChanged );
|
|
SC_HANDLE_NOTIFY_MESSAGE_CONTROL( LVN_KEYDOWN, IDC_THUMBNAILLIST, OnImageListKeyDown );
|
|
}
|
|
SC_END_NOTIFY_MESSAGE_HANDLERS();
|
|
}
|
|
|
|
// WM_COMMAND Handler
|
|
LRESULT CCameraAcquireDialog::OnCommand( WPARAM wParam, LPARAM lParam )
|
|
{
|
|
SC_BEGIN_COMMAND_HANDLERS()
|
|
{
|
|
SC_HANDLE_COMMAND(IDOK,OnOK);
|
|
SC_HANDLE_COMMAND(IDCANCEL,OnCancel);
|
|
SC_HANDLE_COMMAND(IDC_CAMDLG_PROPERTIES,OnProperties);
|
|
SC_HANDLE_COMMAND(IDC_PREVIEWMODE,OnPreviewMode);
|
|
SC_HANDLE_COMMAND(IDC_TAKEPICTURE,OnTakePicture);
|
|
SC_HANDLE_COMMAND(IDC_ICONMODE,OnIconMode);
|
|
SC_HANDLE_COMMAND(IDC_DELETE,OnDelete);
|
|
SC_HANDLE_COMMAND(IDC_SELECTALL,OnSelectAll);
|
|
}
|
|
SC_END_COMMAND_HANDLERS();
|
|
}
|
|
|
|
INT_PTR CALLBACK CCameraAcquireDialog::DialogProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
|
|
{
|
|
SC_BEGIN_DIALOG_MESSAGE_HANDLERS(CCameraAcquireDialog)
|
|
{
|
|
SC_HANDLE_DIALOG_MESSAGE( WM_INITDIALOG, OnInitDialog );
|
|
SC_HANDLE_DIALOG_MESSAGE( WM_SIZE, OnSize );
|
|
SC_HANDLE_DIALOG_MESSAGE( WM_SHOWWINDOW, OnShow );
|
|
SC_HANDLE_DIALOG_MESSAGE( WM_ENTERSIZEMOVE, OnEnterSizeMove );
|
|
SC_HANDLE_DIALOG_MESSAGE( WM_EXITSIZEMOVE, OnExitSizeMove );
|
|
SC_HANDLE_DIALOG_MESSAGE( WM_COMMAND, OnCommand );
|
|
SC_HANDLE_DIALOG_MESSAGE( WM_GETMINMAXINFO, OnGetMinMaxInfo );
|
|
SC_HANDLE_DIALOG_MESSAGE( WM_NOTIFY, OnNotify );
|
|
SC_HANDLE_DIALOG_MESSAGE( WM_DESTROY, OnDestroy );
|
|
SC_HANDLE_DIALOG_MESSAGE( PWM_POSTINIT, OnPostInit );
|
|
SC_HANDLE_DIALOG_MESSAGE( PWM_CHANGETOPARENT, OnChangeToParent );
|
|
SC_HANDLE_DIALOG_MESSAGE( PWM_THUMBNAILSTATUS, OnThumbnailStatus );
|
|
SC_HANDLE_DIALOG_MESSAGE( PWM_PREVIEWSTATUS, OnPreviewStatus );
|
|
SC_HANDLE_DIALOG_MESSAGE( PWM_PREVIEWPERCENT, OnPreviewPercent );
|
|
SC_HANDLE_DIALOG_MESSAGE( PWM_ITEMDELETED, OnItemDeleted );
|
|
SC_HANDLE_DIALOG_MESSAGE( PWM_WIAEVENT, OnWiaEvent );
|
|
SC_HANDLE_DIALOG_MESSAGE( WM_TIMER, OnTimer );
|
|
SC_HANDLE_DIALOG_MESSAGE( WM_HELP, OnHelp );
|
|
SC_HANDLE_DIALOG_MESSAGE( WM_CONTEXTMENU, OnContextMenu );
|
|
SC_HANDLE_DIALOG_MESSAGE( WM_SYSCOLORCHANGE, OnSysColorChange );
|
|
}
|
|
SC_END_DIALOG_MESSAGE_HANDLERS();
|
|
}
|
|
|
|
// Static hook-related data
|
|
HWND CCameraAcquireDialog::s_hWndDialog = NULL;
|
|
HHOOK CCameraAcquireDialog::s_hMessageHook = NULL;
|
|
|