You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2613 lines
80 KiB
2613 lines
80 KiB
/*****************************************************************************
|
|
*
|
|
* (C) CORPYRIGHT MICROSOFT CORPORATION, 1999 - 2000
|
|
*
|
|
* TITLE: videodlg.cpp
|
|
*
|
|
* VERSION: 1.0
|
|
*
|
|
* AUTHOR: RickTu
|
|
*
|
|
* DATE: 10/14/99
|
|
*
|
|
* DESCRIPTION: Implementation of DialogProc for video capture common dialog
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#include <precomp.h>
|
|
#pragma hdrstop
|
|
#include "wiacsh.h"
|
|
#include "modlock.h"
|
|
#include "wiadevdp.h"
|
|
|
|
//
|
|
// Help IDs
|
|
//
|
|
static const DWORD g_HelpIDs[] =
|
|
{
|
|
IDC_VIDDLG_BIG_TITLE, -1,
|
|
IDC_VIDDLG_LITTLE_TITLE, -1,
|
|
IDC_VIDDLG_PREVIEW, IDH_WIA_VIDEO,
|
|
IDC_VIDDLG_THUMBNAILLIST, IDH_WIA_CAPTURED_IMAGES,
|
|
IDC_VIDDLG_CAPTURE, IDH_WIA_CAPTURE,
|
|
IDOK, IDH_WIA_VIDEO_GET_PICTURE,
|
|
IDCANCEL, IDH_CANCEL,
|
|
0, 0
|
|
};
|
|
|
|
#define IDC_SIZEBOX 1113
|
|
|
|
//
|
|
// If the callee doesn't return this value, we delete the message data ourselves.
|
|
//
|
|
#ifndef HANDLED_THREAD_MESSAGE
|
|
#define HANDLED_THREAD_MESSAGE 2032
|
|
#endif
|
|
|
|
// Thumbnail whitespace: the space in between images and their selection rectangles
|
|
// CThese 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;
|
|
|
|
//
|
|
// Map of background thread messages
|
|
//
|
|
|
|
static CThreadMessageMap g_MsgMap[] =
|
|
{
|
|
{ TQ_DESTROY, CVideoCaptureDialog::OnThreadDestroy},
|
|
{ TQ_GETTHUMBNAIL, CVideoCaptureDialog::OnGetThumbnail},
|
|
{ 0, NULL}
|
|
};
|
|
|
|
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);
|
|
}
|
|
};
|
|
|
|
//
|
|
// 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);
|
|
}
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog constructor
|
|
|
|
We don't have a destructor
|
|
|
|
*****************************************************************************/
|
|
|
|
CVideoCaptureDialog::CVideoCaptureDialog( HWND hWnd )
|
|
: m_hWnd(hWnd),
|
|
m_bFirstTime(true),
|
|
m_hBigFont(NULL),
|
|
m_nListViewWidth(0),
|
|
m_hIconLarge(NULL),
|
|
m_hIconSmall(NULL),
|
|
m_hBackgroundThread(NULL),
|
|
m_nDialogMode(0),
|
|
m_hAccelTable(NULL),
|
|
m_nParentFolderImageListIndex(0),
|
|
m_pThreadMessageQueue(NULL)
|
|
{
|
|
WIA_PUSHFUNCTION((TEXT("CVideoCaptureDialog::CVideoCaptureDialog")));
|
|
|
|
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_CurrentAspectRatio.cx = 4;
|
|
m_CurrentAspectRatio.cy = 3;
|
|
|
|
m_sizeThumbnails.cx = c_nMaxThumbnailWidth;
|
|
m_sizeThumbnails.cy = c_nMaxThumbnailHeight;
|
|
|
|
WIA_ASSERT(m_hBackgroundThread != NULL);
|
|
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::OnInitDialog
|
|
|
|
Handle WM_INITIDIALOG
|
|
|
|
*****************************************************************************/
|
|
|
|
LRESULT CVideoCaptureDialog::OnInitDialog( WPARAM, LPARAM lParam )
|
|
{
|
|
WIA_PUSHFUNCTION(TEXT("CVideoCaptureDialog::OnInitDialog"));
|
|
|
|
HRESULT hr;
|
|
|
|
//
|
|
// Make sure the background queue was successfully created
|
|
//
|
|
if (!m_pThreadMessageQueue)
|
|
{
|
|
WIA_ERROR((TEXT("VIDEODLG: unable to start background queue")));
|
|
EndDialog( m_hWnd, E_OUTOFMEMORY );
|
|
return(0);
|
|
}
|
|
|
|
//
|
|
// Save incoming data
|
|
//
|
|
|
|
m_pDeviceDialogData = (PDEVICEDIALOGDATA)lParam;
|
|
|
|
//
|
|
// Make sure we have valid arguments
|
|
//
|
|
|
|
if (!m_pDeviceDialogData)
|
|
{
|
|
WIA_ERROR((TEXT("VIDEODLG: 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 a valid device
|
|
//
|
|
|
|
if (!m_pDeviceDialogData->pIWiaItemRoot)
|
|
{
|
|
WIA_ERROR((TEXT("VIDEODLG: Invalid paramaters: pIWiaItem")));
|
|
EndDialog( m_hWnd, E_INVALIDARG );
|
|
return(0);
|
|
}
|
|
|
|
//
|
|
// Get deviceID for this device
|
|
//
|
|
|
|
PropStorageHelpers::GetProperty(m_pDeviceDialogData->pIWiaItemRoot,WIA_DIP_DEV_ID,m_strwDeviceId);
|
|
|
|
//
|
|
// Register for device disconnected, item creation and deletion events...
|
|
//
|
|
|
|
hr = CoCreateInstance( CLSID_WiaDevMgr, NULL, CLSCTX_LOCAL_SERVER, IID_IWiaDevMgr, (LPVOID *)&m_pDevMgr );
|
|
WIA_CHECK_HR(hr,"CoCreateInstance( WiaDevMgr )");
|
|
|
|
if (SUCCEEDED(hr) && m_pDevMgr)
|
|
{
|
|
CVideoCallback *pVC = new CVideoCallback();
|
|
if (pVC)
|
|
{
|
|
hr = pVC->Initialize( m_hWnd );
|
|
WIA_CHECK_HR(hr,"pVC->Initialize()");
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CComPtr<IWiaEventCallback> pWiaEventCallback;
|
|
|
|
hr = pVC->QueryInterface( IID_IWiaEventCallback,
|
|
(void**)&pWiaEventCallback
|
|
);
|
|
WIA_CHECK_HR(hr,"pVC->QI( IID_IWiaEventCallback )");
|
|
|
|
if (SUCCEEDED(hr) && pWiaEventCallback)
|
|
{
|
|
CSimpleBStr bstr( m_strwDeviceId );
|
|
|
|
hr = m_pDevMgr->RegisterEventCallbackInterface( WIA_REGISTER_EVENT_CALLBACK,
|
|
bstr,
|
|
&WIA_EVENT_DEVICE_DISCONNECTED,
|
|
pWiaEventCallback,
|
|
&m_pDisconnectedCallback
|
|
);
|
|
WIA_CHECK_HR(hr,"RegisterEvent( DEVICE_DISCONNECTED )");
|
|
|
|
|
|
hr = m_pDevMgr->RegisterEventCallbackInterface( WIA_REGISTER_EVENT_CALLBACK,
|
|
bstr,
|
|
&WIA_EVENT_ITEM_DELETED,
|
|
pWiaEventCallback,
|
|
&m_pCreateCallback
|
|
);
|
|
WIA_CHECK_HR(hr,"RegisterEvent( ITEM_DELETE )");
|
|
|
|
hr = m_pDevMgr->RegisterEventCallbackInterface( WIA_REGISTER_EVENT_CALLBACK,
|
|
bstr,
|
|
&WIA_EVENT_ITEM_CREATED,
|
|
pWiaEventCallback,
|
|
&m_pDeleteCallback
|
|
);
|
|
WIA_CHECK_HR(hr,"RegisterEvent( ITEM_CREATED )");
|
|
}
|
|
else
|
|
{
|
|
WIA_ERROR((TEXT("Either QI failed or pWiaEventCallback is NULL!")));
|
|
}
|
|
}
|
|
pVC->Release();
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr) )
|
|
{
|
|
// Create the WiaVideo object
|
|
hr = CoCreateInstance(CLSID_WiaVideo, NULL, CLSCTX_INPROC_SERVER,
|
|
IID_IWiaVideo, (LPVOID *)&m_pWiaVideo);
|
|
|
|
WIA_CHECK_HR(hr,"CoCreateInstance( WiaVideo )");
|
|
}
|
|
|
|
//
|
|
// Prevent multiple selection
|
|
//
|
|
|
|
if (m_pDeviceDialogData->dwFlags & WIA_DEVICE_DIALOG_SINGLE_IMAGE)
|
|
{
|
|
LONG_PTR lStyle = GetWindowLongPtr( GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST ), GWL_STYLE );
|
|
SetWindowLongPtr( GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST ), GWL_STYLE, lStyle | LVS_SINGLESEL );
|
|
|
|
m_nDialogMode = SINGLESEL_MODE;
|
|
|
|
//
|
|
// Hide the "Select All" button
|
|
//
|
|
ShowWindow( GetDlgItem( m_hWnd, IDC_VIDDLG_SELECTALL ), SW_HIDE );
|
|
|
|
//
|
|
// Change text accordingly
|
|
//
|
|
|
|
CSimpleString( IDS_VIDDLG_TITLE_SINGLE_SEL, g_hInstance ).SetWindowText( GetDlgItem( m_hWnd, IDC_VIDDLG_BIG_TITLE ) );
|
|
CSimpleString( IDS_VIDDLG_SUBTITLE_SINGLE_SEL, g_hInstance ).SetWindowText( GetDlgItem( m_hWnd, IDC_VIDDLG_LITTLE_TITLE ) );
|
|
CSimpleString( IDS_VIDDLG_OK_SINGLE_SEL, g_hInstance ).SetWindowText( GetDlgItem( m_hWnd, IDOK ) );
|
|
|
|
}
|
|
else
|
|
{
|
|
m_nDialogMode = MULTISEL_MODE;
|
|
}
|
|
|
|
//
|
|
// Make the lovely font
|
|
//
|
|
|
|
m_hBigFont = WiaUiUtil::CreateFontWithPointSizeFromWindow( GetDlgItem(m_hWnd,IDC_VIDDLG_BIG_TITLE), 14, false, false );
|
|
if (m_hBigFont)
|
|
{
|
|
SendDlgItemMessage( m_hWnd,
|
|
IDC_VIDDLG_BIG_TITLE,
|
|
WM_SETFONT,
|
|
reinterpret_cast<WPARAM>(m_hBigFont),
|
|
MAKELPARAM(TRUE,0)
|
|
);
|
|
}
|
|
|
|
//
|
|
// Save 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;
|
|
|
|
//
|
|
// Create the sizing control
|
|
//
|
|
|
|
HWND hWndSizingControl = 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 );
|
|
if (!hWndSizingControl)
|
|
{
|
|
WIA_ERROR((TEXT("CreateWindowEx( sizing control ) failed!")));
|
|
}
|
|
|
|
//
|
|
// 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))
|
|
{
|
|
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) );
|
|
}
|
|
}
|
|
}
|
|
|
|
SetForegroundWindow(m_hWnd);
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::ResizeAll
|
|
|
|
Resizes and repositions all the controls when the dialog size
|
|
changes.
|
|
|
|
*****************************************************************************/
|
|
|
|
VOID CVideoCaptureDialog::ResizeAll(VOID)
|
|
{
|
|
WIA_PUSHFUNCTION((TEXT("CVideoCaptureDialog::ResizeAll")));
|
|
|
|
CSimpleRect rcClient(m_hWnd);
|
|
CMoveWindow mw;
|
|
CDialogUnits dialogUnits(m_hWnd);
|
|
|
|
//WIA_TRACE((TEXT("rcClient is l(%d) t(%d) r(%d) b(%d)"),rcClient.left, rcClient.top, rcClient.right, rcClient.bottom));
|
|
//WIA_TRACE((TEXT("rcClient is w(%d) h(%d)"),rcClient.Width(),rcClient.Height()));
|
|
//WIA_TRACE((TEXT("dialogUnits.StandardMargin is cx(%d) cy(%d)"),dialogUnits.StandardMargin().cx,dialogUnits.StandardMargin().cy));
|
|
//WIA_TRACE((TEXT("dialogUnits.StandardButtonMargin is cx(%d) cy(%d)"),dialogUnits.StandardButtonMargin().cx,dialogUnits.StandardButtonMargin().cy));
|
|
|
|
//
|
|
// Resize the big title
|
|
//
|
|
|
|
mw.Size( GetDlgItem( m_hWnd, IDC_VIDDLG_BIG_TITLE ),
|
|
rcClient.Width() - dialogUnits.StandardMargin().cx * 2,
|
|
0,
|
|
CMoveWindow::NO_SIZEY );
|
|
|
|
//
|
|
// Resize the subtitle
|
|
//
|
|
|
|
mw.Size( GetDlgItem( m_hWnd, IDC_VIDDLG_LITTLE_TITLE ),
|
|
rcClient.Width() - dialogUnits.StandardMargin().cx * 2,
|
|
0,
|
|
CMoveWindow::NO_SIZEY );
|
|
|
|
|
|
CSimpleRect rcOK( GetDlgItem( m_hWnd, IDOK ), CSimpleRect::WindowRect );
|
|
CSimpleRect rcCancel( GetDlgItem( m_hWnd, IDCANCEL ), CSimpleRect::WindowRect );
|
|
|
|
//WIA_TRACE((TEXT("rcOK is l(%d) t(%d) r(%d) b(%d)"),rcOK.left, rcOK.top, rcOK.right, rcOK.bottom));
|
|
//WIA_TRACE((TEXT("rcOK is w(%d) h(%d)"),rcOK.Width(), rcOK.Height()));
|
|
//WIA_TRACE((TEXT("rcCancel is l(%d) t(%d) r(%d) b(%d)"),rcCancel.left, rcCancel.top, rcCancel.right, rcCancel.bottom));
|
|
//WIA_TRACE((TEXT("rcCancel is w(%d) h(%d)"),rcCancel.Width(), rcCancel.Height()));
|
|
|
|
//
|
|
// Move the OK button
|
|
//
|
|
|
|
LONG x,y;
|
|
|
|
x = rcClient.Width() - dialogUnits.StandardMargin().cx - dialogUnits.StandardButtonMargin().cx - rcCancel.Width() - rcOK.Width();
|
|
y = rcClient.Height() - dialogUnits.StandardMargin().cy - rcOK.Height();
|
|
|
|
//WIA_TRACE((TEXT("Moving IDOK to x(%x) y(%d)"),x,y));
|
|
mw.Move( GetDlgItem( m_hWnd, IDOK ), x, y, 0 );
|
|
|
|
INT nTopOfOK = y;
|
|
INT nBottomOfSub = CSimpleRect( GetDlgItem(m_hWnd,IDC_VIDDLG_LITTLE_TITLE), CSimpleRect::WindowRect ).ScreenToClient(m_hWnd).bottom;
|
|
|
|
//
|
|
// Move the cancel button
|
|
//
|
|
|
|
x = rcClient.Width() - dialogUnits.StandardMargin().cx - rcCancel.Width();
|
|
y = rcClient.Height() - dialogUnits.StandardMargin().cy - rcCancel.Height();
|
|
|
|
//WIA_TRACE((TEXT("Moving IDCANCEL to x(%x) y(%d)"),x,y));
|
|
mw.Move( GetDlgItem( m_hWnd, IDCANCEL ), x, y, 0 );
|
|
|
|
//
|
|
// Move the resizing handle
|
|
//
|
|
|
|
x = rcClient.Width() - GetSystemMetrics(SM_CXVSCROLL);
|
|
y = rcClient.Height() - GetSystemMetrics(SM_CYHSCROLL);
|
|
|
|
//WIA_TRACE((TEXT("Moving IDC_SIZEBOX to x(%x) y(%d)"),x,y));
|
|
mw.Move( GetDlgItem( m_hWnd, IDC_SIZEBOX ), x, y );
|
|
|
|
//
|
|
// Resize the preview window & move the capture button
|
|
//
|
|
|
|
CSimpleRect rcSubTitle( GetDlgItem( m_hWnd, IDC_VIDDLG_LITTLE_TITLE ), CSimpleRect::ClientRect );
|
|
CSimpleRect rcCapture( GetDlgItem( m_hWnd, IDC_VIDDLG_CAPTURE ), CSimpleRect::ClientRect );
|
|
CSimpleRect rcSelectAll( GetDlgItem( m_hWnd, IDC_VIDDLG_SELECTALL ), CSimpleRect::ClientRect );
|
|
|
|
//WIA_TRACE((TEXT("rcSubTitle is l(%d) t(%d) r(%d) b(%d)"),rcSubTitle.left, rcSubTitle.top, rcSubTitle.right, rcSubTitle.bottom));
|
|
//WIA_TRACE((TEXT("rcSubTitle is w(%d) h(%d)"),rcSubTitle.Width(), rcSubTitle.Height()));
|
|
//WIA_TRACE((TEXT("rcCapture is l(%d) t(%d) r(%d) b(%d)"),rcCapture.left, rcCapture.top, rcCapture.right, rcCapture.bottom));
|
|
//WIA_TRACE((TEXT("rcCapture is w(%d) h(%d)"),rcCapture.Width(), rcCapture.Height()));
|
|
//WIA_TRACE((TEXT("rcSelectAll is l(%d) t(%d) r(%d) b(%d)"),rcSelectAll.left, rcSelectAll.top, rcSelectAll.right, rcSelectAll.bottom));
|
|
//WIA_TRACE((TEXT("rcSelectAll is w(%d) h(%d)"),rcSelectAll.Width(), rcSelectAll.Height()));
|
|
|
|
|
|
//WIA_TRACE((TEXT("nTopOfOK is (%d)"),nTopOfOK));
|
|
//WIA_TRACE((TEXT("nBottomOfSub is (%d)"),nBottomOfSub));
|
|
|
|
CSimpleRect rcAvailableArea(
|
|
dialogUnits.StandardMargin().cx,
|
|
nBottomOfSub + dialogUnits.StandardMargin().cy,
|
|
rcClient.right - dialogUnits.StandardMargin().cx,
|
|
nTopOfOK - (dialogUnits.StandardButtonMargin().cy * 2)
|
|
);
|
|
|
|
//WIA_TRACE((TEXT("rcAvailableArea is l(%d) t(%d) r(%d) b(%d)"),rcAvailableArea.left, rcAvailableArea.top, rcAvailableArea.right, rcAvailableArea.bottom));
|
|
//WIA_TRACE((TEXT("rcAvailableArea is w(%d) h(%d)"),rcAvailableArea.Width(), rcAvailableArea.Height()));
|
|
|
|
INT full_width = rcAvailableArea.right - rcAvailableArea.left;
|
|
INT preview_width = (full_width * 53) / 100;
|
|
|
|
//WIA_TRACE((TEXT("full_width is (%d)"),full_width));
|
|
//WIA_TRACE((TEXT("preview_width is (%d)"),preview_width));
|
|
|
|
//WIA_TRACE((TEXT("SizeMoving IDC_VIDDLG_PREVIEW to x(%d) y(%d) w(%d) h(%d)"),rcAvailableArea.left,rcAvailableArea.top,preview_width,rcAvailableArea.Height() - rcCapture.Height() - dialogUnits.StandardButtonMargin().cy));
|
|
mw.SizeMove( GetDlgItem( m_hWnd, IDC_VIDDLG_PREVIEW ),
|
|
rcAvailableArea.left,
|
|
rcAvailableArea.top,
|
|
preview_width,
|
|
rcAvailableArea.Height() - rcCapture.Height() - dialogUnits.StandardButtonMargin().cy
|
|
);
|
|
|
|
INT offset = (preview_width - rcCapture.Width()) / 2;
|
|
|
|
//WIA_TRACE((TEXT("offset is (%d)"),offset));
|
|
|
|
//WIA_TRACE((TEXT("Moving IDC_VIDDLG_CAPTURE to x(%d) y(%d)"),rcAvailableArea.left + offset,rcAvailableArea.bottom - rcCapture.Height()));
|
|
mw.Move( GetDlgItem( m_hWnd, IDC_VIDDLG_CAPTURE ),
|
|
rcAvailableArea.left + offset,
|
|
rcAvailableArea.bottom - rcCapture.Height(),
|
|
0 );
|
|
|
|
//
|
|
// Resize the thumbnail list & move the selectall button
|
|
//
|
|
|
|
INT leftThumbEdge = rcAvailableArea.left + preview_width + dialogUnits.StandardMargin().cx;
|
|
|
|
//WIA_TRACE((TEXT("leftThumbEdge is (%d)"),leftThumbEdge));
|
|
|
|
//WIA_TRACE((TEXT("SizeMoving IDC_VIDDLG_THUMBNAILLIST to x(%d) y(%d) w(%d) h(%d)"),leftThumbEdge,rcAvailableArea.top,rcAvailableArea.Width() - preview_width - dialogUnits.StandardMargin().cx,rcAvailableArea.Height() - rcSelectAll.Height() - dialogUnits.StandardButtonMargin().cy));
|
|
mw.SizeMove( GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST ),
|
|
leftThumbEdge,
|
|
rcAvailableArea.top,
|
|
rcAvailableArea.Width() - preview_width - dialogUnits.StandardMargin().cx,
|
|
rcAvailableArea.Height() - rcSelectAll.Height() - dialogUnits.StandardButtonMargin().cy
|
|
);
|
|
|
|
offset = ((rcAvailableArea.right - leftThumbEdge - rcSelectAll.Width()) / 2);
|
|
|
|
//WIA_TRACE((TEXT("offset(new) is (%d)"),offset));
|
|
|
|
//WIA_TRACE((TEXT("Moving IDC_VIDDLG_SELECTALL to x(%d) y(%d)"),leftThumbEdge + offset,rcAvailableArea.bottom - rcSelectAll.Height()));
|
|
mw.Move( GetDlgItem( m_hWnd, IDC_VIDDLG_SELECTALL ),
|
|
leftThumbEdge + offset,
|
|
rcAvailableArea.bottom - rcSelectAll.Height(),
|
|
0 );
|
|
|
|
//
|
|
// Explicitly apply the moves, because the toolbar frame doesn't get painted properly
|
|
//
|
|
|
|
mw.Apply();
|
|
|
|
//
|
|
// Update the dialog's background to remove any weird stuff left behind
|
|
//
|
|
|
|
InvalidateRect( m_hWnd, NULL, FALSE );
|
|
UpdateWindow( m_hWnd );
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::OnSize
|
|
|
|
Handle WM_SIZE messages
|
|
|
|
*****************************************************************************/
|
|
|
|
LRESULT CVideoCaptureDialog::OnSize( WPARAM, LPARAM )
|
|
{
|
|
WIA_PUSHFUNCTION((TEXT("CVideoCaptureDialog::OnSize")));
|
|
|
|
ResizeAll();
|
|
|
|
//
|
|
// Tell the video preview window to resize in within it's
|
|
// container window as best it can.
|
|
//
|
|
|
|
if (m_pWiaVideo)
|
|
{
|
|
m_pWiaVideo->ResizeVideo(FALSE);
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::OnShow
|
|
|
|
Handle WM_SHOW message
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
LRESULT CVideoCaptureDialog::OnShow( WPARAM, LPARAM )
|
|
{
|
|
WIA_PUSHFUNCTION((TEXT("CVideoCaptureDialog::OnShow")));
|
|
|
|
if (m_bFirstTime)
|
|
{
|
|
PostMessage( m_hWnd, PWM_POSTINIT, 0, 0 );
|
|
m_bFirstTime = false;
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCameraDialog::OnGetMinMaxInfo
|
|
|
|
Handle WM_GETMINMAXINFO
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
LRESULT CVideoCaptureDialog::OnGetMinMaxInfo( WPARAM, LPARAM lParam )
|
|
{
|
|
WIA_PUSHFUNCTION((TEXT("CVideoCaptureDialog::OnGetMinMaxInfo")));
|
|
WIA_TRACE((TEXT("m_sizeMinimumWindow = %d,%d"),m_sizeMinimumWindow.cx,m_sizeMinimumWindow.cy));
|
|
|
|
LPMINMAXINFO pMinMaxInfo = (LPMINMAXINFO)lParam;
|
|
pMinMaxInfo->ptMinTrackSize.x = m_sizeMinimumWindow.cx;
|
|
pMinMaxInfo->ptMinTrackSize.y = m_sizeMinimumWindow.cy;
|
|
return(0);
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCameraDialog::OnDestroy
|
|
|
|
Handle WM_DESTROY message and do cleanup
|
|
|
|
*****************************************************************************/
|
|
|
|
LRESULT CVideoCaptureDialog::OnDestroy( WPARAM, LPARAM )
|
|
{
|
|
WIA_PUSHFUNCTION((TEXT("CVideoCaptureDialog::OnDestroy")));
|
|
|
|
//
|
|
// Unregister for events
|
|
//
|
|
|
|
m_pCreateCallback = NULL;
|
|
m_pDeleteCallback = NULL;
|
|
m_pDisconnectedCallback = NULL;
|
|
|
|
//
|
|
// Tell the background thread to destroy itself
|
|
//
|
|
|
|
m_pThreadMessageQueue->Enqueue( new CThreadMessage(TQ_DESTROY),CThreadMessageQueue::PriorityUrgent );
|
|
|
|
//
|
|
// Close the thread handle
|
|
//
|
|
CloseHandle( m_hBackgroundThread );
|
|
|
|
if (m_pDeviceDialogData && m_pDeviceDialogData->pIWiaItemRoot && m_pWiaVideo)
|
|
{
|
|
m_pWiaVideo->DestroyVideo();
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// 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 (m_hIconLarge)
|
|
{
|
|
DestroyIcon(m_hIconLarge);
|
|
m_hIconLarge = NULL;
|
|
}
|
|
if (m_hIconSmall)
|
|
{
|
|
DestroyIcon(m_hIconSmall);
|
|
m_hIconSmall = NULL;
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::OnOK
|
|
|
|
Handle when the user presses "Get Pictures"
|
|
|
|
*****************************************************************************/
|
|
|
|
VOID CVideoCaptureDialog::OnOK( WPARAM, LPARAM )
|
|
{
|
|
WIA_PUSHFUNCTION((TEXT("CVideoCameraDialog::OnOK")));
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
//
|
|
// Start w/nothing to return
|
|
//
|
|
|
|
m_pDeviceDialogData->lItemCount = 0;
|
|
m_pDeviceDialogData->ppWiaItems = NULL;
|
|
|
|
//
|
|
// Get the indicies of the items that are selected
|
|
//
|
|
|
|
CSimpleDynamicArray<int> aIndices;
|
|
GetSelectionIndices( aIndices );
|
|
|
|
//
|
|
// Are there any items selected?
|
|
//
|
|
|
|
if (aIndices.Size())
|
|
{
|
|
//
|
|
// Calculate the size of the buffer needed
|
|
//
|
|
|
|
INT nArraySizeInBytes = sizeof(IWiaItem*) * aIndices.Size();
|
|
|
|
//
|
|
// Alloc a buffer to hold the items
|
|
//
|
|
m_pDeviceDialogData->ppWiaItems = (IWiaItem**)CoTaskMemAlloc(nArraySizeInBytes);
|
|
|
|
//
|
|
// If we allocated a buffer, fill it up with the
|
|
// items to return...
|
|
//
|
|
|
|
if (m_pDeviceDialogData->ppWiaItems)
|
|
{
|
|
INT i;
|
|
|
|
ZeroMemory( m_pDeviceDialogData->ppWiaItems, nArraySizeInBytes );
|
|
|
|
for (i=0;i<aIndices.Size();i++)
|
|
{
|
|
CCameraItem *pItem = GetListItemNode(aIndices[i]);
|
|
if (pItem && pItem->Item())
|
|
{
|
|
m_pDeviceDialogData->ppWiaItems[i] = pItem->Item();
|
|
m_pDeviceDialogData->ppWiaItems[i]->AddRef();
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Somehow the list got corrupted
|
|
//
|
|
hr = E_UNEXPECTED;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!SUCCEEDED(hr))
|
|
{
|
|
//
|
|
// Clean up if we had a failure
|
|
//
|
|
|
|
for (i=0;i<aIndices.Size();i++)
|
|
{
|
|
if (m_pDeviceDialogData->ppWiaItems[i])
|
|
{
|
|
m_pDeviceDialogData->ppWiaItems[i]->Release();
|
|
}
|
|
}
|
|
|
|
CoTaskMemFree( m_pDeviceDialogData->ppWiaItems );
|
|
m_pDeviceDialogData->ppWiaItems = NULL;
|
|
}
|
|
else
|
|
{
|
|
m_pDeviceDialogData->lItemCount = aIndices.Size();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Unable to alloc buffer
|
|
//
|
|
|
|
WIA_ERROR((TEXT("Couldn't allocate a buffer")));
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// There aren't any items selected, so just return without
|
|
// ending the dialog...
|
|
//
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
EndDialog( m_hWnd, hr );
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::OnCancel
|
|
|
|
Handle when the user presses cancel.
|
|
|
|
*****************************************************************************/
|
|
|
|
VOID CVideoCaptureDialog::OnCancel( WPARAM, LPARAM )
|
|
{
|
|
WIA_PUSHFUNCTION((TEXT("CVideoCameraDialog::OnCancel")));
|
|
|
|
EndDialog( m_hWnd, S_FALSE );
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::OnSelectAll
|
|
|
|
Handle when the user presses "Select All" button
|
|
|
|
*****************************************************************************/
|
|
|
|
VOID CVideoCaptureDialog::OnSelectAll( WPARAM, LPARAM )
|
|
{
|
|
WIA_PUSHFUNCTION((TEXT("CVideoCameraDialog::OnSelectAll")));
|
|
|
|
LVITEM lvItem;
|
|
lvItem.mask = LVIF_STATE;
|
|
lvItem.iItem = 0;
|
|
lvItem.state = LVIS_SELECTED;
|
|
lvItem.stateMask = LVIS_SELECTED;
|
|
SendMessage( GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST ), LVM_SETITEMSTATE, -1, reinterpret_cast<LPARAM>(&lvItem) );
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::AddItemToListView
|
|
|
|
Adds a new IWiaItem to the list view...
|
|
|
|
*****************************************************************************/
|
|
|
|
BOOL CVideoCaptureDialog::AddItemToListView( IWiaItem * pItem )
|
|
{
|
|
WIA_PUSHFUNCTION((TEXT("CVideoCameraDialog::AddItemToListView")));
|
|
|
|
if (!pItem)
|
|
{
|
|
WIA_ERROR((TEXT("pItem is NULL!")));
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Add the new picture to our list
|
|
//
|
|
|
|
CCameraItem * pNewCameraItem = new CCameraItem( pItem );
|
|
if (pNewCameraItem)
|
|
{
|
|
WIA_TRACE((TEXT("Attempting to add new item to tree")));
|
|
m_CameraItemList.Add( NULL, pNewCameraItem );
|
|
|
|
}
|
|
else
|
|
{
|
|
WIA_ERROR((TEXT("Couldn't create a new pNewCameraItem")));
|
|
}
|
|
|
|
//
|
|
// Create a thumbnail for the new item
|
|
//
|
|
|
|
HWND hwndList = GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST );
|
|
|
|
if (hwndList && pNewCameraItem)
|
|
{
|
|
HIMAGELIST hImageList = ListView_GetImageList( hwndList, LVSIL_NORMAL );
|
|
if (hImageList)
|
|
{
|
|
CVideoCaptureDialog::CreateThumbnails( pNewCameraItem,
|
|
hImageList,
|
|
FALSE
|
|
);
|
|
}
|
|
else
|
|
{
|
|
WIA_ERROR((TEXT("Couldn't get hImageList to get new thumbnail")));
|
|
}
|
|
|
|
//
|
|
// Update the listview with the new item
|
|
//
|
|
|
|
LVITEM lvItem;
|
|
INT iItem = ListView_GetItemCount( hwndList ) + 1;
|
|
ZeroMemory( &lvItem, sizeof(lvItem) );
|
|
lvItem.iItem = iItem;
|
|
lvItem.mask = LVIF_IMAGE|LVIF_PARAM;
|
|
lvItem.iImage = pNewCameraItem->ImageListIndex();
|
|
lvItem.lParam = (LPARAM)pNewCameraItem;
|
|
int nIndex = ListView_InsertItem( hwndList, &lvItem );
|
|
|
|
//
|
|
// Retrieve actual thumbnail
|
|
//
|
|
|
|
RequestThumbnails( pNewCameraItem );
|
|
|
|
//
|
|
// Select the new item
|
|
//
|
|
|
|
SetSelectedListItem( nIndex );
|
|
|
|
//
|
|
// Make sure the item is visible
|
|
//
|
|
|
|
ListView_EnsureVisible( hwndList, nIndex, FALSE );
|
|
|
|
}
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::OnCapture
|
|
|
|
Handle when the user presses the "Capture" button
|
|
|
|
*****************************************************************************/
|
|
|
|
VOID CVideoCaptureDialog::OnCapture( WPARAM, LPARAM )
|
|
{
|
|
WIA_PUSHFUNCTION((TEXT("CVideoCameraDialog::OnCapture")));
|
|
|
|
//
|
|
// Disable capture button until we're done with this iteration
|
|
//
|
|
|
|
MyEnableWindow( GetDlgItem( m_hWnd, IDC_VIDDLG_CAPTURE ), FALSE );
|
|
|
|
//
|
|
// Tell the video device to snap a picture
|
|
//
|
|
|
|
CComPtr<IWiaItem> pItem;
|
|
|
|
if (m_pDeviceDialogData && m_pDeviceDialogData->pIWiaItemRoot && m_pWiaVideo)
|
|
{
|
|
WIA_TRACE((TEXT("Telling WiaVideo to take a picture")));
|
|
BSTR bstrNewImageFileName = NULL;
|
|
|
|
//
|
|
// Take the picture
|
|
//
|
|
HRESULT hr = m_pWiaVideo->TakePicture(&bstrNewImageFileName);
|
|
|
|
WIA_CHECK_HR(hr,"m_pWiaVideo->TakePicture");
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
//
|
|
// Succeeded in taking the picture, setting the LAST_PICTURE_TAKEN property
|
|
// on the video driver to create a new item.
|
|
//
|
|
|
|
BOOL bSuccess = FALSE;
|
|
PROPVARIANT pv;
|
|
|
|
PropVariantInit(&pv);
|
|
|
|
pv.vt = VT_BSTR;
|
|
pv.bstrVal = bstrNewImageFileName;
|
|
|
|
bSuccess = PropStorageHelpers::SetProperty(m_pDeviceDialogData->pIWiaItemRoot,
|
|
WIA_DPV_LAST_PICTURE_TAKEN,
|
|
pv);
|
|
|
|
//
|
|
// Note that this will free the bstrNewImageFileName returned to
|
|
// us by WiaVideo
|
|
//
|
|
PropVariantClear(&pv);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Re-Enable capture button now that we're done
|
|
//
|
|
|
|
MyEnableWindow( GetDlgItem( m_hWnd, IDC_VIDDLG_CAPTURE ), TRUE );
|
|
|
|
//
|
|
// Make sure the focus is still on our control
|
|
//
|
|
|
|
SetFocus( GetDlgItem( m_hWnd, IDC_VIDDLG_CAPTURE ) );
|
|
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::OnDblClickImageList
|
|
|
|
Translate a dbl-click on a thumbnail in the listview into a click
|
|
on the "Get Pictures" button.
|
|
|
|
*****************************************************************************/
|
|
|
|
LRESULT CVideoCaptureDialog::OnDblClkImageList( WPARAM, LPARAM )
|
|
{
|
|
WIA_PUSHFUNCTION((TEXT("CVideoCaptureDialog::OnDblClkImageList")));
|
|
|
|
SendMessage( m_hWnd, WM_COMMAND, MAKEWPARAM(IDOK,0), 0 );
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::OnImageListItemChanged
|
|
|
|
Sent whenever an item in the thumbnail list changes.
|
|
|
|
*****************************************************************************/
|
|
|
|
LRESULT CVideoCaptureDialog::OnImageListItemChanged( WPARAM, LPARAM )
|
|
{
|
|
WIA_PUSHFUNCTION((TEXT("CVideoCaptureDialog::OnImageListItemChanged")));
|
|
|
|
HandleSelectionChange();
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::OnImageListKeyDown
|
|
|
|
Forward the keyboard messages within the listview appropriately.
|
|
|
|
*****************************************************************************/
|
|
|
|
LRESULT CVideoCaptureDialog::OnImageListKeyDown( WPARAM, LPARAM lParam )
|
|
{
|
|
LPNMLVKEYDOWN pnkd = reinterpret_cast<LPNMLVKEYDOWN>(lParam);
|
|
if (pnkd)
|
|
{
|
|
if (VK_LEFT == pnkd->wVKey && (GetKeyState(VK_MENU) & 0x8000))
|
|
{
|
|
SendMessage( m_hWnd, PWM_CHANGETOPARENT, 0, 0 );
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::OnNotify
|
|
|
|
Handle WM_NOTIFY messages
|
|
|
|
*****************************************************************************/
|
|
|
|
LRESULT CVideoCaptureDialog::OnNotify( WPARAM wParam, LPARAM lParam )
|
|
{
|
|
SC_BEGIN_NOTIFY_MESSAGE_HANDLERS()
|
|
{
|
|
SC_HANDLE_NOTIFY_MESSAGE_CONTROL( NM_DBLCLK, IDC_VIDDLG_THUMBNAILLIST, OnDblClkImageList );
|
|
SC_HANDLE_NOTIFY_MESSAGE_CONTROL( LVN_ITEMCHANGED, IDC_VIDDLG_THUMBNAILLIST, OnImageListItemChanged );
|
|
SC_HANDLE_NOTIFY_MESSAGE_CONTROL( LVN_KEYDOWN, IDC_VIDDLG_THUMBNAILLIST, OnImageListKeyDown );
|
|
}
|
|
SC_END_NOTIFY_MESSAGE_HANDLERS();
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::OnCommand
|
|
|
|
Handle WM_COMMAND messages
|
|
|
|
*****************************************************************************/
|
|
|
|
LRESULT CVideoCaptureDialog::OnCommand( WPARAM wParam, LPARAM lParam )
|
|
{
|
|
SC_BEGIN_COMMAND_HANDLERS()
|
|
{
|
|
SC_HANDLE_COMMAND(IDOK, OnOK);
|
|
SC_HANDLE_COMMAND(IDCANCEL, OnCancel);
|
|
SC_HANDLE_COMMAND(IDC_VIDDLG_CAPTURE, OnCapture);
|
|
SC_HANDLE_COMMAND(IDC_VIDDLG_SELECTALL, OnSelectAll);
|
|
}
|
|
SC_END_COMMAND_HANDLERS();
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::OnGetThumbnail
|
|
|
|
Called by background thread to get the thumbnail for a given item.
|
|
|
|
*****************************************************************************/
|
|
|
|
BOOL WINAPI CVideoCaptureDialog::OnGetThumbnail( CThreadMessage *pMsg )
|
|
{
|
|
WIA_PUSHFUNCTION(TEXT("CVideoCaptureDialog::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) && pGlobalInterfaceTable)
|
|
{
|
|
CComPtr<IWiaItem> pIWiaItem;
|
|
|
|
hr = pGlobalInterfaceTable->GetInterfaceFromGlobal(
|
|
pThumbMsg->GlobalInterfaceTableCookie(),
|
|
IID_IWiaItem,
|
|
(void**)&pIWiaItem);
|
|
|
|
if (SUCCEEDED(hr) && pIWiaItem)
|
|
{
|
|
CComPtr<IWiaPropertyStorage> pIWiaPropertyStorage;
|
|
|
|
hr = pIWiaItem->QueryInterface( IID_IWiaPropertyStorage,
|
|
(void**)&pIWiaPropertyStorage
|
|
);
|
|
|
|
if (SUCCEEDED(hr) && pIWiaPropertyStorage)
|
|
{
|
|
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)))
|
|
{
|
|
//
|
|
// Calculate the actual amount of data to copy from the thumbnail bitmap.
|
|
// We have to round up to the nearest DWORD boundary, so we align on Width * BYTES_PER_PIXEL
|
|
//
|
|
UINT nBitmapDataSize = WiaUiUtil::Align( PropVar[0].ulVal * 3, sizeof(DWORD) ) * PropVar[1].ulVal;
|
|
if (nBitmapDataSize <= PropVar[2].caub.cElems)
|
|
{
|
|
BITMAPINFO bmi;
|
|
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)
|
|
{
|
|
CopyMemory( pBits, PropVar[2].caub.pElems, nBitmapDataSize );
|
|
hr = ScaleImage( hDC, hDibSection, hBmpThumbnail, pThumbMsg->ThumbSize());
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
WIA_TRACE((TEXT("Sending this image to the notification window: %08X"),pThumbMsg->NotifyWindow()));
|
|
}
|
|
else
|
|
{
|
|
hBmpThumbnail = NULL;
|
|
}
|
|
DeleteObject(hDibSection);
|
|
}
|
|
ReleaseDC(NULL,hDC);
|
|
}
|
|
}
|
|
}
|
|
PropVariantClear(&PropVar[0]);
|
|
PropVariantClear(&PropVar[1]);
|
|
PropVariantClear(&PropVar[2]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
LRESULT lRes = SendMessage( pThumbMsg->NotifyWindow(), PWM_THUMBNAILSTATUS, (WPARAM)pThumbMsg->GlobalInterfaceTableCookie(), (LPARAM)hBmpThumbnail );
|
|
if (HANDLED_THREAD_MESSAGE != lRes && hBmpThumbnail)
|
|
{
|
|
DeleteObject( hBmpThumbnail );
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::OnThreadDestroy
|
|
|
|
<Notes>
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
BOOL WINAPI CVideoCaptureDialog::OnThreadDestroy( CThreadMessage * )
|
|
{
|
|
WIA_PUSHFUNCTION(TEXT("CVideoCaptureDialog::OnThreadDestroy"));
|
|
|
|
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::SetSelectedListItem
|
|
|
|
<Notes>
|
|
|
|
*****************************************************************************/
|
|
|
|
BOOL
|
|
CVideoCaptureDialog::SetSelectedListItem( int nIndex )
|
|
{
|
|
HWND hwndList = GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST );
|
|
|
|
//
|
|
// Check for bad args
|
|
//
|
|
|
|
if (!hwndList)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
int iCount = ListView_GetItemCount(hwndList);
|
|
for (int i=0;i<iCount;i++)
|
|
{
|
|
ListView_SetItemState(hwndList,i,0,LVIS_SELECTED|LVIS_FOCUSED);
|
|
}
|
|
|
|
ListView_SetItemState(hwndList,nIndex,LVIS_SELECTED|LVIS_FOCUSED,LVIS_SELECTED|LVIS_FOCUSED);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::MarkItemDeletePending
|
|
|
|
<Notes>
|
|
|
|
*****************************************************************************/
|
|
|
|
VOID
|
|
CVideoCaptureDialog::MarkItemDeletePending( INT nIndex, BOOL bSet )
|
|
{
|
|
HWND hwndList = GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST );
|
|
if (hwndList)
|
|
{
|
|
ListView_SetItemState( hwndList, nIndex, bSet ? LVIS_CUT : 0, LVIS_CUT );
|
|
}
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::PopulateList
|
|
|
|
Populates the listview with the current items.
|
|
|
|
*****************************************************************************/
|
|
|
|
BOOL
|
|
CVideoCaptureDialog::PopulateList( CCameraItem *pOldParent )
|
|
{
|
|
HWND hwndList = GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST );
|
|
int nSelItem = 0;
|
|
if (hwndList)
|
|
{
|
|
ListView_DeleteAllItems( hwndList );
|
|
int nItem = 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 = nItem++;
|
|
lvItem.mask = LVIF_IMAGE|LVIF_PARAM;
|
|
lvItem.iImage = m_nParentFolderImageListIndex;
|
|
lvItem.lParam = 0;
|
|
ListView_InsertItem( hwndList, &lvItem );
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// if it's a parent directory...
|
|
//
|
|
|
|
pCurr = m_CameraItemList.Root();
|
|
}
|
|
|
|
while (pCurr)
|
|
{
|
|
if (pOldParent && *pCurr == *pOldParent)
|
|
{
|
|
nSelItem = nItem;
|
|
}
|
|
|
|
if (pCurr->DeleteState() != CCameraItem::Delete_Deleted)
|
|
{
|
|
LVITEM lvItem;
|
|
ZeroMemory( &lvItem, sizeof(lvItem) );
|
|
lvItem.iItem = nItem++;
|
|
lvItem.mask = LVIF_IMAGE|LVIF_PARAM;
|
|
lvItem.iImage = pCurr->ImageListIndex();
|
|
lvItem.lParam = (LPARAM)pCurr;
|
|
int nIndex = ListView_InsertItem( hwndList, &lvItem );
|
|
if (nIndex >= 0 && pCurr->DeleteState() == CCameraItem::Delete_Pending)
|
|
{
|
|
MarkItemDeletePending(nIndex,true);
|
|
}
|
|
}
|
|
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_VIDDLG_THUMBNAILLIST ), 0, &rcItem, LVIR_ICON ))
|
|
{
|
|
m_nListViewWidth = (rcItem.right-rcItem.left) + rcItem.left * 2 + GetSystemMetrics(SM_CXHSCROLL) + c_nAdditionalMarginX;
|
|
}
|
|
}
|
|
|
|
SetSelectedListItem(nSelItem);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::OnThumbnailStatus
|
|
|
|
<Notes>
|
|
|
|
*****************************************************************************/
|
|
|
|
LRESULT
|
|
CVideoCaptureDialog::OnThumbnailStatus( WPARAM wParam, LPARAM lParam )
|
|
{
|
|
WIA_PUSHFUNCTION(TEXT("CVideoCaptureDialog::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_VIDDLG_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)
|
|
{
|
|
if (ImageList_Replace( hImageList, pCameraItem->ImageListIndex(), (HBITMAP)lParam, NULL ))
|
|
{
|
|
WIA_TRACE((TEXT("Replaced the image in the list")));
|
|
int nItem = FindItemInList(pCameraItem);
|
|
if (nItem >= 0)
|
|
{
|
|
LV_ITEM lvItem;
|
|
::ZeroMemory(&lvItem,sizeof(LV_ITEM));
|
|
lvItem.iItem = nItem;
|
|
lvItem.mask = LVIF_IMAGE;
|
|
lvItem.iImage = pCameraItem->ImageListIndex();
|
|
ListView_SetItem( hwndList, &lvItem );
|
|
ListView_Update( hwndList, nItem );
|
|
InvalidateRect( hwndList, NULL, FALSE );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Clean up the bitmap, regardless of any other failures, to avoid memory leaks
|
|
//
|
|
|
|
HBITMAP hBmpThumb = (HBITMAP)lParam;
|
|
if (hBmpThumb)
|
|
{
|
|
DeleteObject(hBmpThumb);
|
|
}
|
|
|
|
return HANDLED_THREAD_MESSAGE;
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::CreateThumbnails
|
|
|
|
<Notes>
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
void CVideoCaptureDialog::CreateThumbnails( CCameraItem *pRoot, HIMAGELIST hImageList, bool bForce )
|
|
{
|
|
CCameraItem *pCurr = pRoot;
|
|
while (pCurr)
|
|
{
|
|
if (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_VIDDLG_DOWNLOADINGTHUMBNAIL, g_hInstance, CSimpleStringConvert::NaturalString(strItemName).String() );
|
|
}
|
|
|
|
//
|
|
// Create the thumbnail
|
|
//
|
|
HBITMAP hBmp = WiaUiUtil::CreateIconThumbnail( GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST ), m_sizeThumbnails.cx, m_sizeThumbnails.cy, g_hInstance, pCurr->IsFolder()?IDI_VIDDLG_FOLDER:IDI_VIDDLG_UNAVAILABLE, strIconTitle );
|
|
if (hBmp)
|
|
{
|
|
if (pCurr->ImageListIndex()<0)
|
|
{
|
|
pCurr->ImageListIndex(ImageList_Add( hImageList, hBmp, NULL ));
|
|
}
|
|
else
|
|
{
|
|
pCurr->ImageListIndex(ImageList_Replace( hImageList, pCurr->ImageListIndex(), hBmp, NULL ));
|
|
}
|
|
DeleteObject(hBmp);
|
|
}
|
|
}
|
|
if (pCurr->Children())
|
|
{
|
|
CreateThumbnails( pCurr->Children(), hImageList, bForce );
|
|
}
|
|
pCurr = pCurr->Next();
|
|
}
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::RequestThumbnails
|
|
|
|
<Notes>
|
|
|
|
*****************************************************************************/
|
|
VOID
|
|
CVideoCaptureDialog::RequestThumbnails( CCameraItem *pRoot )
|
|
{
|
|
WIA_PUSHFUNCTION(TEXT("CVideoCaptureDialog::RequestThumbnails"));
|
|
|
|
CCameraItem *pCurr = pRoot;
|
|
|
|
while (pCurr)
|
|
{
|
|
if (!pCurr->IsFolder())
|
|
{
|
|
m_pThreadMessageQueue->Enqueue( new CThumbnailThreadMessage( m_hWnd, pCurr->GlobalInterfaceTableCookie(), m_sizeThumbnails ) );
|
|
}
|
|
|
|
if (pCurr->Children())
|
|
{
|
|
RequestThumbnails( pCurr->Children() );
|
|
}
|
|
|
|
pCurr = pCurr->Next();
|
|
}
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::CreateThumbnails
|
|
|
|
<Notes>
|
|
|
|
*****************************************************************************/
|
|
|
|
VOID
|
|
CVideoCaptureDialog::CreateThumbnails( BOOL bForce )
|
|
{
|
|
HWND hwndList = GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST );
|
|
|
|
if (hwndList)
|
|
{
|
|
HIMAGELIST hImageList = ListView_GetImageList( hwndList, LVSIL_NORMAL );
|
|
if (hImageList)
|
|
{
|
|
//
|
|
// Create the parent folder image and add it to the image list
|
|
//
|
|
HBITMAP hParentBitmap = WiaUiUtil::CreateIconThumbnail(
|
|
hwndList,
|
|
m_sizeThumbnails.cx,
|
|
m_sizeThumbnails.cy,
|
|
g_hInstance,
|
|
IDI_VIDDLG_PARENTFOLDER,
|
|
TEXT("(..)") );
|
|
if (hParentBitmap)
|
|
{
|
|
m_nParentFolderImageListIndex = ImageList_Add( hImageList, hParentBitmap, NULL );
|
|
DeleteObject(hParentBitmap);
|
|
}
|
|
|
|
//
|
|
// Create all of the other images
|
|
//
|
|
CreateThumbnails( m_CameraItemList.Root(), hImageList, bForce != 0 );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::FindMaximumThumbnailSize
|
|
|
|
Looks through entire item list to get larget thumbnail.
|
|
|
|
*****************************************************************************/
|
|
|
|
BOOL
|
|
CVideoCaptureDialog::FindMaximumThumbnailSize( VOID )
|
|
{
|
|
WIA_PUSHFUNCTION(TEXT("CVideoCaptureDialog::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);
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::EnumerateItems
|
|
|
|
Enumerate all the items at this level of the camera.
|
|
|
|
*****************************************************************************/
|
|
|
|
HRESULT
|
|
CVideoCaptureDialog::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())
|
|
{
|
|
m_CameraItemList.Add( pCurrentParent, pNewCameraItem );
|
|
|
|
LONG ItemType;
|
|
HRESULT hr2;
|
|
|
|
hr2 = pNewCameraItem->Item()->GetItemType(&ItemType);
|
|
|
|
if (SUCCEEDED(hr2))
|
|
{
|
|
if (ItemType & WiaItemTypeImage)
|
|
{
|
|
WIA_TRACE((TEXT("Found an image")));
|
|
}
|
|
else
|
|
{
|
|
WIA_TRACE((TEXT("Found something that is NOT an image")));
|
|
}
|
|
|
|
CComPtr <IEnumWiaItem> pIEnumChildItem;
|
|
hr2 = pIWiaItem->EnumChildItems(&pIEnumChildItem);
|
|
if (hr2 == S_OK)
|
|
{
|
|
EnumerateItems( pNewCameraItem, pIEnumChildItem );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::EnumerateAllCameraItems
|
|
|
|
Enumerate all the items in camera, including folders.
|
|
|
|
*****************************************************************************/
|
|
|
|
HRESULT CVideoCaptureDialog::EnumerateAllCameraItems(void)
|
|
{
|
|
CComPtr<IEnumWiaItem> pIEnumItem;
|
|
HRESULT hr = m_pDeviceDialogData->pIWiaItemRoot->EnumChildItems(&pIEnumItem);
|
|
if (hr == S_OK)
|
|
{
|
|
hr = EnumerateItems( NULL, pIEnumItem );
|
|
}
|
|
return(hr);
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::GetSelectionIndices
|
|
|
|
Returns an array with the list indicies of the items that are
|
|
selected in IDC_VIDDLG_THUMBNAILLIST
|
|
|
|
*****************************************************************************/
|
|
|
|
INT
|
|
CVideoCaptureDialog::GetSelectionIndices( CSimpleDynamicArray<int> &aIndices )
|
|
{
|
|
HWND hwndList = GetDlgItem( m_hWnd, IDC_VIDDLG_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();
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::OnPostInit
|
|
|
|
Handle the post WM_INIT processing that needs to take place.
|
|
|
|
*****************************************************************************/
|
|
|
|
LRESULT CVideoCaptureDialog::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_VIDEO_COMMUNICATE|WIA_PROGRESSDLG_NO_PROGRESS|WIA_PROGRESSDLG_NO_CANCEL|WIA_PROGRESSDLG_NO_TITLE );
|
|
pWiaProgressDialog->SetTitle( CSimpleStringConvert::WideString(CSimpleString(IDS_VIDDLG_PROGDLG_TITLE,g_hInstance)));
|
|
pWiaProgressDialog->SetMessage( CSimpleStringConvert::WideString(CSimpleString(IDS_VIDDLG_PROGDLG_MESSAGE,g_hInstance)));
|
|
|
|
//
|
|
// Show the progress dialog
|
|
//
|
|
pWiaProgressDialog->Show();
|
|
|
|
if (m_pDeviceDialogData && m_pDeviceDialogData->pIWiaItemRoot && m_pWiaVideo)
|
|
{
|
|
CSimpleString strImagesDirectory;
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
BOOL bSuccess = FALSE;
|
|
//
|
|
// Get the IMAGES_DIRECTORY property from the Wia Video Driver.
|
|
//
|
|
|
|
bSuccess = PropStorageHelpers::GetProperty(m_pDeviceDialogData->pIWiaItemRoot,
|
|
WIA_DPV_IMAGES_DIRECTORY,
|
|
strImagesDirectory);
|
|
|
|
if (!bSuccess)
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
WIAVIDEO_STATE VideoState = WIAVIDEO_NO_VIDEO;
|
|
|
|
//
|
|
// Get the current state of the WiaVideo object. If we just created it
|
|
// then the state will be NO_VIDEO, otherwise, it could already be previewing video,
|
|
// in which case we shouldn't do anything.
|
|
//
|
|
hr = m_pWiaVideo->GetCurrentState(&VideoState);
|
|
|
|
if (VideoState == WIAVIDEO_NO_VIDEO)
|
|
{
|
|
//
|
|
// Set the directory we want to save our images to. We got the image directory
|
|
// from the Wia Video Driver IMAGES_DIRECTORY property
|
|
//
|
|
if (hr == S_OK)
|
|
{
|
|
hr = m_pWiaVideo->put_ImagesDirectory(CSimpleBStr(strImagesDirectory));
|
|
}
|
|
|
|
//
|
|
// Create the video preview as a child of the IDC_VIDSEL_PREVIEW dialog item
|
|
// and automatically begin playback after creating the preview.
|
|
//
|
|
if (hr == S_OK)
|
|
{
|
|
hr = m_pWiaVideo->CreateVideoByWiaDevID(CSimpleBStr(m_strwDeviceId),
|
|
GetDlgItem( m_hWnd, IDC_VIDDLG_PREVIEW ),
|
|
FALSE,
|
|
TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (hr != S_OK)
|
|
{
|
|
|
|
//
|
|
// Let the user know that the graph is most likely already
|
|
// in use...
|
|
//
|
|
|
|
MessageBox( m_hWnd,
|
|
CSimpleString(IDS_VIDDLG_BUSY_TEXT, g_hInstance),
|
|
CSimpleString(IDS_VIDDLG_BUSY_TITLE, g_hInstance),
|
|
MB_OK | MB_ICONWARNING | MB_SETFOREGROUND
|
|
);
|
|
|
|
//
|
|
// Disable the capture button since we have no graph
|
|
//
|
|
|
|
MyEnableWindow( GetDlgItem(m_hWnd,IDC_VIDDLG_CAPTURE), FALSE );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
//
|
|
// Go get all the items..
|
|
//
|
|
EnumerateAllCameraItems();
|
|
FindMaximumThumbnailSize();
|
|
|
|
//
|
|
// Initialize Thumbnail Listview control
|
|
//
|
|
HWND hwndList = GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST );
|
|
if (hwndList)
|
|
{
|
|
ListView_SetExtendedListViewStyleEx( hwndList,
|
|
LVS_EX_BORDERSELECT|LVS_EX_HIDELABELS,
|
|
LVS_EX_BORDERSELECT|LVS_EX_HIDELABELS
|
|
);
|
|
|
|
m_hImageList = ImageList_Create( m_sizeThumbnails.cx,
|
|
m_sizeThumbnails.cy,
|
|
ILC_COLOR24|ILC_MIRROR, 1, 1
|
|
);
|
|
if (m_hImageList)
|
|
{
|
|
ListView_SetImageList( hwndList,
|
|
m_hImageList,
|
|
LVSIL_NORMAL
|
|
);
|
|
|
|
ListView_SetIconSpacing( hwndList,
|
|
m_sizeThumbnails.cx + c_nAdditionalMarginX,
|
|
m_sizeThumbnails.cy + c_nAdditionalMarginY
|
|
);
|
|
}
|
|
}
|
|
|
|
CreateThumbnails();
|
|
|
|
//
|
|
// This causes the list to be populated
|
|
//
|
|
|
|
ChangeFolder(NULL);
|
|
|
|
HandleSelectionChange();
|
|
|
|
RequestThumbnails( m_CameraItemList.Root() );
|
|
|
|
//
|
|
// Close the progress dialog
|
|
//
|
|
pWiaProgressDialog->Destroy();
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::FindItemInList
|
|
|
|
<Notes>
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
INT CVideoCaptureDialog::FindItemInList( CCameraItem *pItem )
|
|
{
|
|
if (pItem)
|
|
{
|
|
HWND hwndList = GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST );
|
|
if (hwndList)
|
|
{
|
|
for (int i=0;i<ListView_GetItemCount(hwndList);i++)
|
|
{
|
|
if (pItem == GetListItemNode(i))
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::GetListItemNode
|
|
|
|
<Notes>
|
|
|
|
*****************************************************************************/
|
|
|
|
CCameraItem *
|
|
CVideoCaptureDialog::GetListItemNode( int nIndex )
|
|
{
|
|
HWND hwndList = GetDlgItem( m_hWnd, IDC_VIDDLG_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);
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::ChangeFolder
|
|
|
|
Change the current folder being viewed
|
|
|
|
*****************************************************************************/
|
|
|
|
BOOL
|
|
CVideoCaptureDialog::ChangeFolder( CCameraItem *pNode )
|
|
{
|
|
CCameraItem *pOldParent = m_pCurrentParentItem;
|
|
m_pCurrentParentItem = pNode;
|
|
|
|
return PopulateList(pOldParent);
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::OnChangeToParent
|
|
|
|
<Notes>
|
|
|
|
*****************************************************************************/
|
|
|
|
LRESULT
|
|
CVideoCaptureDialog::OnChangeToParent( WPARAM, LPARAM )
|
|
{
|
|
if (m_pCurrentParentItem)
|
|
{
|
|
ChangeFolder(m_pCurrentParentItem->Parent());
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::HandleSelectionChange
|
|
|
|
<Notes>
|
|
|
|
*****************************************************************************/
|
|
|
|
VOID
|
|
CVideoCaptureDialog::HandleSelectionChange( VOID )
|
|
{
|
|
CWaitCursor wc;
|
|
INT nSelCount = ListView_GetSelectedCount(GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST ) );
|
|
INT nItemCount = ListView_GetItemCount(GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST ) );
|
|
|
|
//
|
|
// OK should be disabled for 0 items
|
|
//
|
|
|
|
MyEnableWindow( GetDlgItem(m_hWnd,IDOK), nSelCount != 0 );
|
|
|
|
//
|
|
// Select all should be disabled for 0 items
|
|
//
|
|
MyEnableWindow( GetDlgItem(m_hWnd,IDC_VIDDLG_SELECTALL), nItemCount != 0 );
|
|
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::OnTimer
|
|
|
|
Handle WM_TIMER messages
|
|
|
|
*****************************************************************************/
|
|
|
|
LRESULT
|
|
CVideoCaptureDialog::OnTimer( WPARAM wParam, LPARAM )
|
|
{
|
|
/*
|
|
switch (wParam)
|
|
{
|
|
case IDT_UPDATEPREVIEW:
|
|
{
|
|
KillTimer( m_hWnd, IDT_UPDATEPREVIEW );
|
|
UpdatePreview();
|
|
}
|
|
break;
|
|
}
|
|
*/
|
|
return(0);
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::OnNewItemEvent
|
|
|
|
This gets called when get an event from the driver that a new item has
|
|
been created.
|
|
|
|
*****************************************************************************/
|
|
|
|
LRESULT
|
|
CVideoCaptureDialog::OnNewItemEvent( WPARAM, LPARAM lParam )
|
|
{
|
|
WIA_PUSHFUNCTION((TEXT("CVideoCaptureDialog::OnNewItemEvent")));
|
|
|
|
//
|
|
// Make sure we have a valid item name
|
|
//
|
|
BSTR bstrFullItemName = reinterpret_cast<BSTR>(lParam);
|
|
if (!bstrFullItemName)
|
|
{
|
|
WIA_TRACE((TEXT("bstrFullItemName was NULL")));
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// Check to see if the item is already in our list
|
|
//
|
|
CCameraItem *pListItem = m_CameraItemList.Find(bstrFullItemName);
|
|
if (!pListItem)
|
|
{
|
|
if (m_pDeviceDialogData && m_pDeviceDialogData->pIWiaItemRoot)
|
|
{
|
|
WIA_TRACE((TEXT("Finding new item in device")));
|
|
|
|
//
|
|
// Get an IWiaItem ptr to new item
|
|
//
|
|
CComPtr<IWiaItem> pItem;
|
|
HRESULT hr = m_pDeviceDialogData->pIWiaItemRoot->FindItemByName(0,bstrFullItemName,&pItem);
|
|
WIA_CHECK_HR(hr,"pWiaItemRoot->FindItemByName()");
|
|
|
|
if (SUCCEEDED(hr) && pItem)
|
|
{
|
|
//
|
|
// Add the item to the list
|
|
//
|
|
AddItemToListView( pItem );
|
|
|
|
//
|
|
// Make sure we update controls' states
|
|
//
|
|
HandleSelectionChange();
|
|
}
|
|
else
|
|
{
|
|
WIA_ERROR((TEXT("FindItemByName returned NULL pItem")));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WIA_ERROR((TEXT("m_pDeviceDialogData or m_pDeviceDialogData->pIWiaItemRoot were NULL")));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WIA_TRACE((TEXT("We found the item is already in our list, doing nothing")));
|
|
}
|
|
|
|
//
|
|
// Free the item name
|
|
//
|
|
SysFreeString(bstrFullItemName);
|
|
|
|
return HANDLED_THREAD_MESSAGE;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::OnDeleteItemEvent
|
|
|
|
This gets called when we get an event from the driver that an item has
|
|
been deleted.
|
|
|
|
*****************************************************************************/
|
|
|
|
LRESULT
|
|
CVideoCaptureDialog::OnDeleteItemEvent( WPARAM, LPARAM lParam )
|
|
{
|
|
WIA_PUSHFUNCTION((TEXT("CVideoCaptureDialog::OnDeleteItemEvent")));
|
|
|
|
CSimpleBStr bstrFullItem = reinterpret_cast<BSTR>(lParam);
|
|
SysFreeString( reinterpret_cast<BSTR>(lParam) );
|
|
|
|
WIA_TRACE((TEXT("The deleted item is %s"),CSimpleStringConvert::NaturalString(CSimpleStringWide(bstrFullItem)).String()));
|
|
|
|
CCameraItem *pDeletedItem = m_CameraItemList.Find(bstrFullItem);
|
|
|
|
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_VIDDLG_THUMBNAILLIST ),nIndex);
|
|
|
|
//
|
|
// Make sure we leave something selected
|
|
//
|
|
|
|
if (!ListView_GetSelectedCount(GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST )))
|
|
{
|
|
int nItemCount = ListView_GetItemCount(GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST ));
|
|
if (nItemCount)
|
|
{
|
|
if (nIndex >= nItemCount)
|
|
{
|
|
nIndex = nItemCount-1;
|
|
}
|
|
|
|
SetSelectedListItem(nIndex);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Make sure we update controls' states
|
|
//
|
|
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")));
|
|
}
|
|
|
|
return HANDLED_THREAD_MESSAGE;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::OnDeviceDisconnect
|
|
|
|
This gets called when we get an event from the driver that device has
|
|
been disconnected.
|
|
|
|
*****************************************************************************/
|
|
|
|
LRESULT
|
|
CVideoCaptureDialog::OnDeviceDisconnect( WPARAM, LPARAM )
|
|
{
|
|
WIA_PUSHFUNCTION((TEXT("CVideoCaptureDialog::OnDeviceDisconnect")));
|
|
|
|
//
|
|
// Close the dialog with the approriate error
|
|
//
|
|
|
|
EndDialog( m_hWnd, WIA_ERROR_OFFLINE );
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::GetGraphWindowHandle
|
|
|
|
Find the window handle of the video window
|
|
|
|
*****************************************************************************/
|
|
HWND
|
|
CVideoCaptureDialog::GetGraphWindowHandle(void)
|
|
{
|
|
HWND hWndGraphParent = GetDlgItem( m_hWnd, IDC_VIDDLG_PREVIEW );
|
|
if (hWndGraphParent)
|
|
{
|
|
return FindWindowEx( hWndGraphParent, NULL, TEXT("VideoRenderer"), NULL );
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
CCameraAcquireDialog::OnContextMenu
|
|
|
|
Message handler for WM_HELP message
|
|
|
|
*****************************************************************************/
|
|
|
|
LRESULT
|
|
CVideoCaptureDialog::OnHelp( WPARAM wParam, LPARAM lParam )
|
|
{
|
|
HELPINFO *pHelpInfo = reinterpret_cast<HELPINFO*>(lParam);
|
|
if (pHelpInfo && HELPINFO_WINDOW==pHelpInfo->iContextType && GetGraphWindowHandle()==pHelpInfo->hItemHandle)
|
|
{
|
|
pHelpInfo->hItemHandle = GetDlgItem( m_hWnd, IDC_VIDDLG_PREVIEW );
|
|
}
|
|
return WiaHelp::HandleWmHelp( wParam, lParam, g_HelpIDs );
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CCameraAcquireDialog::OnContextMenu
|
|
|
|
Message handler for right-mouse-button click
|
|
|
|
*****************************************************************************/
|
|
|
|
LRESULT
|
|
CVideoCaptureDialog::OnContextMenu( WPARAM wParam, LPARAM lParam )
|
|
{
|
|
if (GetGraphWindowHandle() == reinterpret_cast<HWND>(wParam))
|
|
{
|
|
wParam = reinterpret_cast<WPARAM>(GetDlgItem( m_hWnd, IDC_VIDDLG_PREVIEW ));
|
|
}
|
|
return WiaHelp::HandleWmContextMenu( wParam, lParam, g_HelpIDs );
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCaptureDialog::DialogProc
|
|
|
|
Dialog proc for video capture dialog
|
|
|
|
*****************************************************************************/
|
|
|
|
INT_PTR PASCAL CVideoCaptureDialog::DialogProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
|
|
{
|
|
SC_BEGIN_DIALOG_MESSAGE_HANDLERS(CVideoCaptureDialog)
|
|
{
|
|
SC_HANDLE_DIALOG_MESSAGE( WM_INITDIALOG, OnInitDialog );
|
|
SC_HANDLE_DIALOG_MESSAGE( WM_SIZE, OnSize );
|
|
SC_HANDLE_DIALOG_MESSAGE( WM_COMMAND, OnCommand );
|
|
SC_HANDLE_DIALOG_MESSAGE( WM_NOTIFY, OnNotify );
|
|
SC_HANDLE_DIALOG_MESSAGE( WM_GETMINMAXINFO, OnGetMinMaxInfo );
|
|
SC_HANDLE_DIALOG_MESSAGE( WM_DESTROY, OnDestroy );
|
|
SC_HANDLE_DIALOG_MESSAGE( WM_SHOWWINDOW, OnShow );
|
|
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( PWM_POSTINIT, OnPostInit );
|
|
SC_HANDLE_DIALOG_MESSAGE( PWM_CHANGETOPARENT, OnChangeToParent );
|
|
SC_HANDLE_DIALOG_MESSAGE( PWM_THUMBNAILSTATUS, OnThumbnailStatus );
|
|
SC_HANDLE_DIALOG_MESSAGE( VD_NEW_ITEM, OnNewItemEvent );
|
|
SC_HANDLE_DIALOG_MESSAGE( VD_DELETE_ITEM, OnDeleteItemEvent );
|
|
SC_HANDLE_DIALOG_MESSAGE( VD_DEVICE_DISCONNECTED, OnDeviceDisconnect );
|
|
}
|
|
SC_END_DIALOG_MESSAGE_HANDLERS();
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCallback::CVideoCallback
|
|
|
|
Constructor for class
|
|
|
|
*****************************************************************************/
|
|
|
|
CVideoCallback::CVideoCallback()
|
|
: m_cRef(1),
|
|
m_hWnd(NULL)
|
|
{
|
|
WIA_PUSHFUNCTION((TEXT("CVideoCallback::CVideoCallback()")));
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCallback::Initialize
|
|
|
|
Let us set which hwnd to notify when events come
|
|
|
|
*****************************************************************************/
|
|
|
|
STDMETHODIMP
|
|
CVideoCallback::Initialize( HWND hWnd )
|
|
{
|
|
WIA_PUSHFUNCTION((TEXT("CVideoCallback::Initialize()")));
|
|
|
|
m_hWnd = hWnd;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCallback::AddRef
|
|
|
|
Standard COM
|
|
|
|
*****************************************************************************/
|
|
|
|
STDMETHODIMP_(ULONG)
|
|
CVideoCallback::AddRef( VOID )
|
|
{
|
|
WIA_PUSHFUNCTION((TEXT("CVideoCallback::AddRef")));
|
|
return(InterlockedIncrement(&m_cRef));
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCallback::Release
|
|
|
|
Standard COM
|
|
|
|
*****************************************************************************/
|
|
|
|
STDMETHODIMP_(ULONG)
|
|
CVideoCallback::Release( VOID )
|
|
{
|
|
WIA_PUSHFUNCTION(TEXT("CVideoCallback::Release"));
|
|
LONG nRefCount = InterlockedDecrement(&m_cRef);
|
|
if (!nRefCount)
|
|
{
|
|
delete this;
|
|
}
|
|
return(nRefCount);
|
|
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCallback::QueryInterface
|
|
|
|
Standard COM
|
|
|
|
*****************************************************************************/
|
|
|
|
STDMETHODIMP
|
|
CVideoCallback::QueryInterface( REFIID riid, LPVOID *ppvObject )
|
|
{
|
|
WIA_PUSHFUNCTION((TEXT("CVideoCallback::QueryInterface")));
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if (ppvObject)
|
|
{
|
|
if (IsEqualIID( riid, IID_IUnknown ))
|
|
{
|
|
WIA_TRACE((TEXT("Supported RIID asked for was IID_IUnknown")));
|
|
*ppvObject = static_cast<IUnknown*>(this);
|
|
reinterpret_cast<IUnknown*>(*ppvObject)->AddRef();
|
|
}
|
|
else if (IsEqualIID( riid, IID_IWiaEventCallback ))
|
|
{
|
|
WIA_TRACE((TEXT("Supported RIID asked for was IID_IWiaEventCallback")));
|
|
*ppvObject = static_cast<IWiaEventCallback*>(this);
|
|
reinterpret_cast<IUnknown*>(*ppvObject)->AddRef();
|
|
}
|
|
else
|
|
{
|
|
WIA_PRINTGUID((riid,TEXT("Unsupported interface!")));
|
|
*ppvObject = NULL;
|
|
hr = E_NOINTERFACE;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
hr = E_INVALIDARG;
|
|
}
|
|
|
|
WIA_RETURN_HR(hr);
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
CVideoCallback::ImageEventCallback
|
|
|
|
WIA callback interface for events.
|
|
|
|
*****************************************************************************/
|
|
|
|
STDMETHODIMP
|
|
CVideoCallback::ImageEventCallback( const GUID *pEventGUID,
|
|
BSTR bstrEventDescription,
|
|
BSTR bstrDeviceID,
|
|
BSTR bstrDeviceDescription,
|
|
DWORD dwDeviceType,
|
|
BSTR bstrFullItemName,
|
|
ULONG *pulEventType,
|
|
ULONG ulReserved)
|
|
{
|
|
|
|
WIA_PUSHFUNCTION((TEXT("CVideoCallback::ImageEventCallback")));
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if (pEventGUID)
|
|
{
|
|
if (IsEqualGUID( *pEventGUID, WIA_EVENT_ITEM_CREATED ))
|
|
{
|
|
WIA_TRACE((TEXT("Got WIA_EVENT_ITEM_CREATED")));
|
|
|
|
BSTR bstrToSend = SysAllocString( bstrFullItemName );
|
|
|
|
LRESULT lRes = SendMessage( m_hWnd, VD_NEW_ITEM, 0, reinterpret_cast<LPARAM>(bstrToSend) );
|
|
if (HANDLED_THREAD_MESSAGE != lRes && bstrToSend)
|
|
{
|
|
SysFreeString( bstrToSend );
|
|
}
|
|
|
|
}
|
|
else if (IsEqualGUID( *pEventGUID, WIA_EVENT_ITEM_DELETED ))
|
|
{
|
|
WIA_TRACE((TEXT("Got WIA_EVENT_ITEM_DELETED")));
|
|
|
|
BSTR bstrToSend = SysAllocString( bstrFullItemName );
|
|
|
|
LRESULT lRes = SendMessage( m_hWnd, VD_DELETE_ITEM, 0, reinterpret_cast<LPARAM>(bstrToSend) );
|
|
if (HANDLED_THREAD_MESSAGE != lRes && bstrToSend)
|
|
{
|
|
SysFreeString( bstrToSend );
|
|
}
|
|
|
|
}
|
|
else if (IsEqualGUID( *pEventGUID, WIA_EVENT_DEVICE_DISCONNECTED ))
|
|
{
|
|
PostMessage( m_hWnd, VD_DEVICE_DISCONNECTED, 0, 0 );
|
|
}
|
|
else
|
|
{
|
|
WIA_ERROR((TEXT("Got an event other that what we registered for!")));
|
|
}
|
|
}
|
|
|
|
|
|
WIA_RETURN_HR(hr);
|
|
}
|
|
|
|
|
|
|