// wiatestView.cpp : implementation of the CWiatestView class // #include "stdafx.h" #include "wiatest.h" #include "wiatestDoc.h" #include "wiatestView.h" #include "wiaeditpropdlg.h" #include "wiacapdlg.h" #include "wiaacquiredlg.h" #include "wiadatacallback.h" #include "wiadocacqsettings.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CWiatestView IMPLEMENT_DYNCREATE(CWiatestView, CFormView) BEGIN_MESSAGE_MAP(CWiatestView, CFormView) //{{AFX_MSG_MAP(CWiatestView) ON_NOTIFY(TVN_SELCHANGED, IDC_ITEM_TREECTRL, OnSelchangedItemTreectrl) ON_WM_SIZE() ON_NOTIFY(NM_DBLCLK, IDC_ITEMPROPERTIES_LISTCTRL, OnDblclkItempropertiesListctrl) ON_COMMAND(IDM_ACQUIREIMAGE, OnAcquireimage) ON_COMMAND(IDM_LOAD_WIAPROPERTYSTREAM, OnLoadWiapropertystream) ON_COMMAND(IDM_SAVE_WIAPROPERTYSTREAM, OnSaveWiapropertystream) ON_NOTIFY(NM_RCLICK, IDC_ITEMPROPERTIES_LISTCTRL, OnRclickItempropertiesListctrl) ON_COMMAND(ID_PROPERTYEDITPOPUPMENU_EDITPROPERTYVALUE, OnPropertyeditpopupmenuEditpropertyvalue) ON_COMMAND(IDM_VIEW_CAPABILITIES, OnViewCapabilities) ON_NOTIFY(NM_RCLICK, IDC_ITEM_TREECTRL, OnRclickItemTreectrl) ON_COMMAND(IDM_DELETE_ITEM, OnDeleteItem) ON_COMMAND(IDM_ACQUIREIMAGE_COMMONUI, OnAcquireimageCommonui) ON_COMMAND(IDM_EDIT_DEBUGOUT, OnEditDebugout) ON_UPDATE_COMMAND_UI(IDM_EDIT_DEBUGOUT, OnUpdateEditDebugout) ON_WM_SHOWWINDOW() ON_COMMAND(IDM_DOCUMENT_ACQUISITION_SETTINGS, OnDocumentAcquisitionSettings) ON_UPDATE_COMMAND_UI(IDM_DOCUMENT_ACQUISITION_SETTINGS, OnUpdateDocumentAcquisitionSettings) ON_LBN_SELCHANGE(IDC_SUPPORTED_TYMED_AND_FORMAT_LISTBOX, OnSelchangeSupportedTymedAndFormatListbox) ON_BN_CLICKED(IDC_THUMBNAIL_PREVIEW, OnThumbnailPreview) //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CFormView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CFormView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CFormView::OnFilePrintPreview) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CWiatestView construction/destruction CWiatestView::CWiatestView() : CFormView(CWiatestView::IDD) { m_bOutputToDebuggerON = FALSE; m_hThumbNailBitmap = NULL; m_bHasDocumentFeeder = FALSE; //{{AFX_DATA_INIT(CWiatestView) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // TODO: add construction code here } CWiatestView::~CWiatestView() { } void CWiatestView::DoDataExchange(CDataExchange* pDX) { CFormView::DoDataExchange(pDX); //{{AFX_DATA_MAP(CWiatestView) DDX_Control(pDX, IDC_SUPPORTED_TYMED_AND_FORMAT_LISTBOX, m_SupportedTymedAndFormatsListBox); DDX_Control(pDX, IDC_THUMBNAIL_PREVIEW, m_ThumbnailPreviewWindow); DDX_Control(pDX, IDC_ITEMPROPERTIES_LISTCTRL, m_ItemPropertiesListCtrl); DDX_Control(pDX, IDC_ITEM_TREECTRL, m_ItemTreeCtrl); //}}AFX_DATA_MAP } BOOL CWiatestView::PreCreateWindow(CREATESTRUCT& cs) { return CFormView::PreCreateWindow(cs); } void CWiatestView::OnInitialUpdate() { CFormView::OnInitialUpdate(); GetParentFrame()->RecalcLayout(); ResizeParentToFit(FALSE); // get associated document CWiatestDoc* pDocument = NULL; pDocument = (CWiatestDoc*)m_pDocument; if(pDocument){ // initialize item tree control AddWiaItemsToTreeControl(TVI_ROOT, pDocument->m_pIRootItem); // initialize property list control m_ItemPropertiesListCtrl.SetupColumnHeaders(); // initialize supported TYMED and formats list box AddSupportedTYMEDAndFormatsToListBox(pDocument->m_pIRootItem); // initialize device type specifics for UI AdjustViewForDeviceType(); // register for events RegisterForEvents(); // maximize window CWnd* Parent = GetParent(); Parent->ShowWindow(SW_SHOWMAXIMIZED); } } ///////////////////////////////////////////////////////////////////////////// // CWiatestView printing BOOL CWiatestView::OnPreparePrinting(CPrintInfo* pInfo) { // default preparation return DoPreparePrinting(pInfo); } void CWiatestView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add extra initialization before printing } void CWiatestView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add cleanup after printing } void CWiatestView::OnPrint(CDC* pDC, CPrintInfo* /*pInfo*/) { // TODO: add customized printing code here } ///////////////////////////////////////////////////////////////////////////// // CWiatestView diagnostics #ifdef _DEBUG void CWiatestView::AssertValid() const { CFormView::AssertValid(); } void CWiatestView::Dump(CDumpContext& dc) const { CFormView::Dump(dc); } CWiatestDoc* CWiatestView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CWiatestDoc))); return (CWiatestDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CWiatestView message handlers void CWiatestView::AddWiaItemsToTreeControl(HTREEITEM hParent, IWiaItem *pIWiaItem) { if(hParent == TVI_ROOT){ // delete any old items in tree m_ItemTreeCtrl.DeleteAllItems(); } TV_INSERTSTRUCT tv; HRESULT hr = S_OK; IEnumWiaItem* pIEnumWiaItem = NULL; LONG lItemType = 0; HTREEITEM hNewParent = NULL; TCHAR szItemName[MAX_PATH]; CWiahelper WIA; memset(szItemName,0,sizeof(szItemName)); tv.hParent = hParent; tv.hInsertAfter = TVI_LAST; tv.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT | TVIF_PARAM; tv.item.hItem = NULL; tv.item.state = TVIS_EXPANDED; tv.item.stateMask = TVIS_STATEIMAGEMASK; tv.item.cchTextMax = 6; tv.item.cChildren = 0; tv.item.lParam = 0; // get item's full name WIA.SetIWiaItem(pIWiaItem); WIA.ReadPropertyString(WIA_IPA_FULL_ITEM_NAME,szItemName); tv.item.pszText = szItemName; // insert item into tree hNewParent = m_ItemTreeCtrl.InsertItem(&tv); // check item type to see if it is a parent hr = pIWiaItem->GetItemType(&lItemType); if(SUCCEEDED(hr)){ if(lItemType & (WiaItemTypeFolder | WiaItemTypeHasAttachments)){ // we have a potential parent hr = pIWiaItem->EnumChildItems(&pIEnumWiaItem); if(S_OK == hr){ ULONG ulFetched = 0; IWiaItem *pFoundIWiaItem = NULL; // we have a parent with children hr = pIEnumWiaItem->Next(1,&pFoundIWiaItem,&ulFetched); while(S_OK == hr){ // add item to tree AddWiaItemsToTreeControl(hNewParent,pFoundIWiaItem); // release enumerated item pFoundIWiaItem->Release(); hr = pIEnumWiaItem->Next(1,&pFoundIWiaItem,&ulFetched); } } } } } void CWiatestView::OnSelchangedItemTreectrl(NMHDR* pNMHDR, LRESULT* pResult) { NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; HTREEITEM hTreeItem = NULL; hTreeItem = m_ItemTreeCtrl.GetSelectedItem(); if(hTreeItem){ CString cszItemName = m_ItemTreeCtrl.GetItemText(hTreeItem); if(cszItemName.GetLength() > 0){ CWiatestDoc* pDocument = NULL; pDocument = (CWiatestDoc*)m_pDocument; if(pDocument){ BSTR bstrFullItemName = NULL; bstrFullItemName = cszItemName.AllocSysString(); if(bstrFullItemName){ HRESULT hr = S_OK; IWiaItem *pFoundIWiaItem = NULL; hr = pDocument->m_pIRootItem->FindItemByName(0,bstrFullItemName,&pFoundIWiaItem); if(SUCCEEDED(hr)){ if(NULL != pFoundIWiaItem){ hr = pDocument->SetCurrentIWiaItem(pFoundIWiaItem); if(SUCCEEDED(hr)){ // update list control with properties of the selected (found) item AddWiaItemPropertiesToListControl(pDocument->m_pICurrentItem); // update valid TYMED/Formats listbox selections AddSupportedTYMEDAndFormatsToListBox(pDocument->m_pICurrentItem); // disable supported TYMED and format selection if the item selected // is a root item. if(pDocument->m_pICurrentItem == pDocument->m_pIRootItem){ m_SupportedTymedAndFormatsListBox.SetCurSel(-1); m_SupportedTymedAndFormatsListBox.EnableWindow(FALSE); } else { m_SupportedTymedAndFormatsListBox.EnableWindow(TRUE); // set current selection for TYMED and format listbox SetCurrentSelectionForTYMEDAndFormat(); } // display thumbnail if one exists DisplayThumbnail(pDocument->m_pICurrentItem); // release IWiaItem pFoundIWiaItem->Release(); pFoundIWiaItem = NULL; } } else { ErrorMessageBox(IDS_WIATESTERROR_ITEMNOTFOUND,hr); } } else { ErrorMessageBox(IDS_WIATESTERROR_ITEMNOTFOUND,hr); } SysFreeString(bstrFullItemName); bstrFullItemName = NULL; } } } } *pResult = 0; } void CWiatestView::AddWiaItemPropertiesToListControl(IWiaItem *pIWiaItem) { // erase any old properties m_ItemPropertiesListCtrl.DeleteAllItems(); // insert new properties HRESULT hr = S_OK; IWiaPropertyStorage *pIWiaPropStg = NULL; INT ItemNumber = 0; hr = pIWiaItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg); if(hr == S_OK) { IEnumSTATPROPSTG *pIPropEnum = NULL; hr = pIWiaPropStg->Enum(&pIPropEnum); if(hr == S_OK) { STATPROPSTG StatPropStg; memset(&StatPropStg,0,sizeof(StatPropStg)); do { hr = pIPropEnum->Next(1,&StatPropStg,NULL); if (hr == S_OK) { if (StatPropStg.lpwstrName != NULL) { // read property value PROPSPEC PropSpec; PROPVARIANT PropVar; PropSpec.ulKind = PRSPEC_PROPID; PropSpec.propid = StatPropStg.propid; hr = pIWiaPropStg->ReadMultiple(1,&PropSpec,&PropVar); if (hr == S_OK) { TCHAR szPropName[MAX_PATH]; memset(szPropName,0,sizeof(szPropName)); TCHAR szValue[MAX_PATH]; memset(szValue,0,sizeof(szValue)); TCHAR szText[MAX_PATH]; memset(szText,0,sizeof(szText)); LV_ITEM lvitem; lvitem.mask = LVIF_TEXT | LVIF_PARAM; lvitem.iItem = ItemNumber; lvitem.iSubItem = 0; lvitem.pszText = szText; lvitem.iImage = NULL; lvitem.lParam = StatPropStg.propid; // Write property name to list control if (WideCharToMultiByte(CP_ACP, 0,StatPropStg.lpwstrName,-1, szPropName, MAX_PATH,NULL,NULL) > 0) { lstrcpy(szText,szPropName); // insert name into list control m_ItemPropertiesListCtrl.InsertItem(&lvitem); // move to next column for setting the value lvitem.mask = LVIF_TEXT; lvitem.iSubItem = 1; } else { lstrcpy(szPropName,TEXT("")); } // Write property value to list control PROPVAR2TSTR(&PropVar,szText); m_ItemPropertiesListCtrl.SetItem(&lvitem); // display access flags and var type ULONG AccessFlags = 0; ULONG VarType = 0; PROPVARIANT AttrPropVar; // not used at this time hr = pIWiaPropStg->GetPropertyAttributes(1, &PropSpec,&AccessFlags,&AttrPropVar); if (hr != S_OK) { hr = S_OK; // do this to continue property traversal } else { // display access flags lvitem.mask = LVIF_TEXT; lvitem.iSubItem = 3; memset(lvitem.pszText,0,sizeof(szText)); AccessFlags2TSTR(lvitem.pszText,AccessFlags); m_ItemPropertiesListCtrl.SetItem(&lvitem); } // display var type lvitem.mask = LVIF_TEXT; lvitem.iSubItem = 2; VT2TSTR(lvitem.pszText,PropVar.vt); m_ItemPropertiesListCtrl.SetItem(&lvitem); // increment Row counter ItemNumber++; } } else { } } // clean up property name CoTaskMemFree(StatPropStg.lpwstrName); } while (hr == S_OK); pIPropEnum->Release(); } else { ErrorMessageBox(IDS_WIATESTERROR_ENUMERATE_PROPERTIES,hr); } pIWiaPropStg->Release(); } else { ErrorMessageBox(IDS_WIATESTERROR_WIAPROPERTYSTORAGE,hr); } // auto resize columns for (int Col = 0; Col <4;Col++){ m_ItemPropertiesListCtrl.SetColumnWidth(Col, LVSCW_AUTOSIZE); } } void CWiatestView::VT2TSTR(TCHAR *pszText,ULONG VarType) { if (pszText == NULL) return; switch (VarType) { case VT_EMPTY: // nothing lstrcpy(pszText,TEXT("VT_EMPTY")); break; case VT_NULL: // SQL style Null lstrcpy(pszText,TEXT("VT_NULL")); break; case VT_I2: // 2 byte signed int lstrcpy(pszText,TEXT("VT_I2")); break; case VT_I4: // 4 byte signed int lstrcpy(pszText,TEXT("VT_I4")); break; case VT_R4: // 4 byte real lstrcpy(pszText,TEXT("VT_R4")); break; case VT_R8: // 8 byte real lstrcpy(pszText,TEXT("VT_R8")); break; case VT_CY: // currency lstrcpy(pszText,TEXT("VT_CY")); break; case VT_DATE: // date lstrcpy(pszText,TEXT("VT_DATE")); break; case VT_BSTR: // OLE Automation string lstrcpy(pszText,TEXT("VT_BSTR")); break; case VT_DISPATCH: // IDispatch * lstrcpy(pszText,TEXT("VT_DISPATCH")); break; case VT_ERROR: // SCODE lstrcpy(pszText,TEXT("VT_ERROR")); break; case VT_BOOL: // True=-1, False=0 lstrcpy(pszText,TEXT("VT_BOOL")); break; case VT_VARIANT: // VARIANT * lstrcpy(pszText,TEXT("VT_VARIANT")); break; case VT_UNKNOWN: // IUnknown * lstrcpy(pszText,TEXT("VT_UNKNOWN")); break; case VT_DECIMAL: // 16 byte fixed point lstrcpy(pszText,TEXT("VT_DECIMAL")); break; case VT_RECORD: // user defined type lstrcpy(pszText,TEXT("VT_RECORD")); break; case VT_I1: // signed char lstrcpy(pszText,TEXT("VT_I1")); break; case VT_UI1: // unsigned char lstrcpy(pszText,TEXT("VT_UI1")); break; case VT_UI2: // unsigned short lstrcpy(pszText,TEXT("VT_UI2")); break; case VT_UI4: // unsigned short lstrcpy(pszText,TEXT("VT_UI4")); break; case VT_I8: // signed 64-bit int lstrcpy(pszText,TEXT("VT_I8")); break; case VT_UI8: // unsigned 64-bit int lstrcpy(pszText,TEXT("VT_UI8")); break; case VT_INT: // signed machine int lstrcpy(pszText,TEXT("VT_INT")); break; case VT_UINT: // unsigned machine int lstrcpy(pszText,TEXT("VT_UINT")); break; case VT_VOID: // C style void lstrcpy(pszText,TEXT("VT_VOID")); break; case VT_HRESULT: // Standard return type lstrcpy(pszText,TEXT("VT_HRESULT")); break; case VT_PTR: // pointer type lstrcpy(pszText,TEXT("VT_PTR")); break; case VT_SAFEARRAY: // (use VT_ARRAY in VARIANT) lstrcpy(pszText,TEXT("VT_SAFEARRAY")); break; case VT_CARRAY: // C style array lstrcpy(pszText,TEXT("VT_CARRAY")); break; case VT_USERDEFINED: // user defined type lstrcpy(pszText,TEXT("VT_USERDEFINED")); break; case VT_LPSTR: // null terminated string lstrcpy(pszText,TEXT("VT_LPSTR")); break; case VT_LPWSTR: // wide null terminated string lstrcpy(pszText,TEXT("VT_LPWSTR")); break; case VT_FILETIME: // FILETIME lstrcpy(pszText,TEXT("VT_FILETIME")); break; case VT_BLOB: // Length prefixed bytes lstrcpy(pszText,TEXT("VT_BLOB")); break; case VT_STREAM: // Name of the stream follows lstrcpy(pszText,TEXT("VT_STREAM")); break; case VT_STORAGE: // Name of the storage follows lstrcpy(pszText,TEXT("VT_STORAGE")); break; case VT_STREAMED_OBJECT: // Stream contains an object lstrcpy(pszText,TEXT("VT_STREAMED_OBJECT")); break; case VT_STORED_OBJECT: // Storage contains an object lstrcpy(pszText,TEXT("VT_STORED_OBJECT")); break; case VT_VERSIONED_STREAM: // Stream with a GUID version lstrcpy(pszText,TEXT("VT_VERSIONED_STREAM")); break; case VT_BLOB_OBJECT: // Blob contains an object lstrcpy(pszText,TEXT("VT_BLOB_OBJECT")); break; case VT_CF: // Clipboard format lstrcpy(pszText,TEXT("VT_CF")); break; case VT_CLSID: // A Class ID lstrcpy(pszText,TEXT("VT_CLSID")); break; case VT_VECTOR: // simple counted array lstrcpy(pszText,TEXT("VT_VECTOR")); break; case VT_ARRAY: // SAFEARRAY* lstrcpy(pszText,TEXT("VT_ARRAY")); break; case VT_BYREF: // void* for local use lstrcpy(pszText,TEXT("VT_BYREF")); break; case VT_BSTR_BLOB: // Reserved for system use lstrcpy(pszText,TEXT("VT_BSTR_BLOB")); break; case VT_VECTOR|VT_I4: lstrcpy(pszText,TEXT("VT_VECTOR | VT_I4")); break; case VT_VECTOR | VT_UI1: lstrcpy(pszText,TEXT("VT_VECTOR | VT_UI1")); break; case VT_VECTOR | VT_UI2: lstrcpy(pszText,TEXT("VT_VECTOR | VT_UI2")); break; case VT_VECTOR | VT_UI4: lstrcpy(pszText,TEXT("VT_VECTOR | VT_UI4")); break; default: // unknown type detected!! lstrcpy(pszText,TEXT("VT_UNKNOWNTYPE")); break; } } void CWiatestView::AccessFlags2TSTR(TCHAR *pszText,ULONG AccessFlags) { if (pszText == NULL) return; if ((AccessFlags & WIA_PROP_READ) == WIA_PROP_READ){ lstrcat(pszText,TEXT("WIA_PROP_READ | ")); } if ((AccessFlags & WIA_PROP_WRITE) == WIA_PROP_WRITE){ lstrcat(pszText,TEXT("WIA_PROP_WRITE | ")); } if (lstrcmp(pszText,TEXT("WIA_PROP_READ | WIA_PROP_WRITE | ")) == 0){ lstrcpy(pszText,TEXT("WIA_PROP_RW | ")); } if ((AccessFlags & WIA_PROP_NONE) == WIA_PROP_NONE){ lstrcat(pszText,TEXT("WIA_PROP_NONE | ")); } if ((AccessFlags & WIA_PROP_RANGE) == WIA_PROP_RANGE){ lstrcat(pszText,TEXT("WIA_PROP_RANGE | ")); } if ((AccessFlags & WIA_PROP_LIST) == WIA_PROP_LIST){ lstrcat(pszText,TEXT("WIA_PROP_LIST | ")); } if ((AccessFlags & WIA_PROP_FLAG) == WIA_PROP_FLAG){ lstrcat(pszText,TEXT("WIA_PROP_FLAG | ")); } LONG lLen = 0; lLen = lstrlen(pszText); // check for unknown access flags if (lLen == 0){ TSPRINTF(pszText,TEXT("WIA_PROP_UNKNOWN = %d "),AccessFlags); return; } pszText[lLen - (2 * sizeof(TCHAR))] = 0; } void CWiatestView::PROPVAR2TSTR(PROPVARIANT *pPropVar,TCHAR *szValue) { SYSTEMTIME *pSystemTime = NULL; switch (pPropVar->vt) { case VT_I1: TSPRINTF(szValue,TEXT("%d"),pPropVar->cVal); break; case VT_UI1: TSPRINTF(szValue,TEXT("%d"),pPropVar->bVal); break; case VT_I2: TSPRINTF(szValue,TEXT("%d"),pPropVar->iVal); break; case VT_UI2: TSPRINTF(szValue,TEXT("%d"),pPropVar->uiVal); break; case VT_UI4: TSPRINTF(szValue,TEXT("%d"),pPropVar->ulVal); break; case VT_UI8: TSPRINTF(szValue,TEXT("%d"),pPropVar->lVal); break; case VT_INT: TSPRINTF(szValue,TEXT("%d"),pPropVar->intVal); break; case VT_I4: TSPRINTF(szValue,TEXT("%d"),pPropVar->lVal); break; case VT_I8: TSPRINTF(szValue,TEXT("%d"),pPropVar->hVal); break; case VT_R4: TSPRINTF(szValue,TEXT("%2.5f"),pPropVar->fltVal); break; case VT_R8: TSPRINTF(szValue,TEXT("%2.5f"),pPropVar->dblVal); break; case VT_BSTR: #ifndef UNICODE WideCharToMultiByte(CP_ACP, 0,pPropVar->bstrVal, -1, szValue, MAX_PATH,NULL,NULL); #else TSPRINTF(szValue,TEXT("%ws"),pPropVar->bstrVal); #endif break; case VT_LPSTR: TSPRINTF(szValue,TEXT("%s"),pPropVar->pwszVal); break; case VT_LPWSTR: TSPRINTF(szValue,TEXT("%ws"),pPropVar->pwszVal); break; case VT_UINT: TSPRINTF(szValue,TEXT("%d"),pPropVar->uintVal); break; case VT_CLSID: { UCHAR *pwszUUID = NULL; UuidToString(pPropVar->puuid,&pwszUUID); if(NULL != pwszUUID){ TSPRINTF(szValue,TEXT("%s"),pwszUUID); // free allocated string RpcStringFree(&pwszUUID); } } break; case VT_VECTOR | VT_UI2: pSystemTime = (SYSTEMTIME*)pPropVar->caui.pElems; if(NULL != pSystemTime){ // ( YYYY:MM:W:DD:HH:MM:SS:ms ) TSPRINTF(szValue,TEXT("%d:%d:%d:%d:%d:%d:%d:%d"),pSystemTime->wYear, pSystemTime->wMonth, pSystemTime->wDay, pSystemTime->wDayOfWeek, pSystemTime->wHour, pSystemTime->wMinute, pSystemTime->wSecond, pSystemTime->wMilliseconds); } break; default: TSPRINTF(szValue,TEXT("%d"),pPropVar->lVal); break; } } void CWiatestView::TSTR2PROPVAR(TCHAR *szValue, PROPVARIANT *pPropVar) { WCHAR wszbuffer[MAX_PATH]; CHAR szbuffer[MAX_PATH]; memset(wszbuffer,0,sizeof(wszbuffer)); memset(szbuffer,0,sizeof(szbuffer)); switch (pPropVar->vt) { case VT_I1: TSSCANF(szValue,TEXT("%li"),&pPropVar->cVal); break; case VT_I2: TSSCANF(szValue,TEXT("%li"),&pPropVar->bVal); break; case VT_I4: TSSCANF(szValue,TEXT("%li"),&pPropVar->lVal); break; case VT_I8: TSSCANF(szValue,TEXT("%li"),&pPropVar->hVal); break; case VT_UI1: TSSCANF(szValue,TEXT("%li"),&pPropVar->bVal); break; case VT_UI2: TSSCANF(szValue,TEXT("%li"),&pPropVar->uiVal); break; case VT_UI4: TSSCANF(szValue,TEXT("%li"),&pPropVar->ulVal); break; case VT_UI8: TSSCANF(szValue,TEXT("%li"),&pPropVar->lVal); break; case VT_INT: TSSCANF(szValue,TEXT("%li"),&pPropVar->intVal); break; case VT_R4: TSSCANF(szValue,TEXT("%f"),&pPropVar->fltVal); break; case VT_R8: TSSCANF(szValue,TEXT("%f"),&pPropVar->fltVal); break; case VT_BSTR: #ifndef UNICODE MultiByteToWideChar(CP_ACP, 0,szValue,-1,wszbuffer,MAX_PATH); pPropVar->bstrVal = SysAllocString(wszbuffer); #else pPropVar->bstrVal = SysAllocString(szValue); #endif break; case VT_CLSID: #ifndef UNICODE pPropVar->puuid = (GUID*)CoTaskMemAlloc(sizeof(UUID)); UuidFromString((UCHAR*)szValue,pPropVar->puuid); #else pPropVar->puuid = CoTaskMemAlloc(sizeof(UUID)); WideCharToMultiByte(CP_ACP, 0,szValue,-1,szbuffer,MAX_PATH,NULL,NULL); UuidFromString((UCHAR*)szbuffer,pPropVar->puuid); #endif break; case VT_UINT: TSSCANF(szValue,TEXT("%li"),&pPropVar->uintVal); break; case VT_VECTOR | VT_UI2: { TCHAR *psz = NULL; // is this a SYSTEMTIME formatted string? psz = TSTRSTR(szValue,TEXT(":")); if(NULL != psz){ SYSTEMTIME *pSystemTime = NULL; pSystemTime = (SYSTEMTIME*)CoTaskMemAlloc(sizeof(SYSTEMTIME)); if(pSystemTime){ memset(pSystemTime,0,sizeof(SYSTEMTIME)); // fill out SYSTEMTIME structure TSSCANF(szValue,TEXT("%hd:%hd:%hd:%hd:%hd:%hd:%hd:%hd"),&pSystemTime->wYear, &pSystemTime->wMonth, &pSystemTime->wDay, &pSystemTime->wDayOfWeek, &pSystemTime->wHour, &pSystemTime->wMinute, &pSystemTime->wSecond, &pSystemTime->wMilliseconds); // set count pPropVar->caui.cElems = (sizeof(SYSTEMTIME) / sizeof(WORD)); // set pointer (array of WORD values) pPropVar->caui.pElems = (WORD*)pSystemTime; } } } break; default: TSSCANF(szValue,"%li",&pPropVar->lVal); break; } } void CWiatestView::OnSize(UINT nType, int cx, int cy) { CFormView::OnSize(nType, cx, cy); CRect ParentWindowRect; LONG lOffset = 0; // get parent window rect GetWindowRect(ParentWindowRect); ScreenToClient(ParentWindowRect); // resize property list control if(NULL != m_ItemPropertiesListCtrl.m_hWnd){ CRect ListBoxRect; // get list control rect m_ItemPropertiesListCtrl.GetWindowRect(ListBoxRect); ScreenToClient(ListBoxRect); // adjust width ListBoxRect.right = ParentWindowRect.right - 10; lOffset = ListBoxRect.right; // adjust height ListBoxRect.bottom = ParentWindowRect.bottom - 10; m_ItemPropertiesListCtrl.MoveWindow(ListBoxRect); } if(GET_STIDEVICE_TYPE(m_lDeviceType) == StiDeviceTypeDigitalCamera){ // move thumbnail control if(NULL != m_ThumbnailPreviewWindow.m_hWnd){ CRect ThumbnailRect; // get thumbnail rect m_ThumbnailPreviewWindow.GetWindowRect(ThumbnailRect); ScreenToClient(ThumbnailRect); // adjust position INT iWidth = ThumbnailRect.Width(); ThumbnailRect.right = lOffset; ThumbnailRect.left = (ThumbnailRect.right - iWidth); m_ThumbnailPreviewWindow.MoveWindow(ThumbnailRect); } // resize supported TYMED and Format listbox if(NULL != m_SupportedTymedAndFormatsListBox.m_hWnd){ CRect ListBoxRect; CRect ThumbnailRect; // get list box rect m_SupportedTymedAndFormatsListBox.GetWindowRect(ListBoxRect); ScreenToClient(ListBoxRect); // get thumbnail rect m_ThumbnailPreviewWindow.GetWindowRect(ThumbnailRect); ScreenToClient(ThumbnailRect); // adjust width ListBoxRect.right = ThumbnailRect.left - 10; m_SupportedTymedAndFormatsListBox.MoveWindow(ListBoxRect); } } else { // resize supported TYMED listbox if(NULL != m_SupportedTymedAndFormatsListBox.m_hWnd){ CRect ListBoxRect; CRect ThumbnailRect; // get list box rect m_SupportedTymedAndFormatsListBox.GetWindowRect(ListBoxRect); ScreenToClient(ListBoxRect); // adjust width ListBoxRect.right = lOffset; m_SupportedTymedAndFormatsListBox.MoveWindow(ListBoxRect); } } } void CWiatestView::OnDblclkItempropertiesListctrl(NMHDR* pNMHDR, LRESULT* pResult) { // find out what property is selected HD_NOTIFY* phdn = (HD_NOTIFY *) pNMHDR; TCHAR pszPropertyName[MAX_PATH]; memset(pszPropertyName,0,sizeof(pszPropertyName)); TCHAR pszPropertyValue[MAX_PATH]; memset(pszPropertyValue,0,sizeof(pszPropertyValue)); LV_ITEM lvitem; lvitem.mask = LVIF_PARAM; lvitem.iItem = phdn->iItem; lvitem.iSubItem = ITEMPROPERTYLISTCTRL_COLUMN_PROPERTYNAME; lvitem.pszText = NULL; // is an item selected? if (phdn->iItem < ITEMPROPERTYLISTCTRL_COLUMN_PROPERTYNAME) return; m_ItemPropertiesListCtrl.GetItem(&lvitem); // get stored property ID LONG iProp = 0; iProp = (LONG)lvitem.lParam; m_ItemPropertiesListCtrl.GetItemText(phdn->iItem, ITEMPROPERTYLISTCTRL_COLUMN_PROPERTYNAME, pszPropertyName, sizeof(pszPropertyName)); m_ItemPropertiesListCtrl.GetItemText(phdn->iItem, ITEMPROPERTYLISTCTRL_COLUMN_PROPERTYVALUE, pszPropertyValue, sizeof(pszPropertyValue)); // get document CWiatestDoc* pDocument = NULL; pDocument = (CWiatestDoc*)m_pDocument; if(pDocument){ IWiaPropertyStorage *pIWiaPropStg = NULL; HRESULT hr = S_OK; hr = pDocument->m_pICurrentItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg); if(SUCCEEDED(hr)) { // read property value for type and current value PROPVARIANT PropVar[1]; PROPVARIANT AttrPropVar[1]; PROPSPEC PropSpec[1]; PropSpec[0].ulKind = PRSPEC_PROPID; PropSpec[0].propid = iProp; ULONG ulAttributes = 0; CWiaeditpropDlg PropertyEditDlg; hr = pIWiaPropStg->ReadMultiple(1,PropSpec,PropVar); if (S_OK == hr) { PropertyEditDlg.SetVarType(PropVar[0].vt); // clear variant PropVariantClear(PropVar); hr = pIWiaPropStg->GetPropertyAttributes(1, PropSpec,&ulAttributes,AttrPropVar); if(S_OK == hr){ PropertyEditDlg.SetAttributes(ulAttributes, (PROPVARIANT*)AttrPropVar); BOOL bRefreshCurrentTYMEDAndFormatSelection = FALSE; if((lstrcmpi(pszPropertyName,TEXT("Format")) == 0) || (lstrcmpi(pszPropertyName,TEXT("Media Type")) == 0)){ bRefreshCurrentTYMEDAndFormatSelection = TRUE; } if(PropertyEditDlg.DoModal(pszPropertyName,pszPropertyValue) == IDOK){ memset(pszPropertyValue,0,sizeof(pszPropertyValue)); PropertyEditDlg.GetPropertyValue(pszPropertyValue); PropVar[0].vt = PropertyEditDlg.GetVarType(); TSTR2PROPVAR(pszPropertyValue,(PROPVARIANT*)PropVar); hr = pIWiaPropStg->WriteMultiple(1,PropSpec,PropVar,MIN_PROPID); if(S_OK == hr){ // get current document, and refresh the property list with the current // selected item CWiatestDoc* pDocument = NULL; pDocument = (CWiatestDoc*)m_pDocument; if(pDocument){ // update list control with properties AddWiaItemPropertiesToListControl(pDocument->m_pICurrentItem); if(bRefreshCurrentTYMEDAndFormatSelection){ SetCurrentSelectionForTYMEDAndFormat(); } } } else if FAILED(hr){ // failure ErrorMessageBox(IDS_WIATESTERROR_WRITING_PROPERTY,hr); } else { // S_FALSE ErrorMessageBox(IDS_WIATESTWARNING_ADDITIONAL_PROPERTY); } // clear variant PropVariantClear(PropVar); } else { // user decided not to write the property } } } // release property storage pIWiaPropStg->Release(); pIWiaPropStg = NULL; } } *pResult = 0; } void CWiatestView::AddSupportedTYMEDAndFormatsToListBox(IWiaItem *pIWiaItem) { m_SupportedTymedAndFormatsListBox.ResetContent(); HRESULT hr = S_OK; IWiaDataTransfer *pIWiaDataTransfer = NULL; hr = pIWiaItem->QueryInterface(IID_IWiaDataTransfer, (void **)&pIWiaDataTransfer); if (S_OK == hr) { IEnumWIA_FORMAT_INFO *pIEnumWIA_FORMAT_INFO = NULL; WIA_FORMAT_INFO pfe; hr = pIWiaDataTransfer->idtEnumWIA_FORMAT_INFO(&pIEnumWIA_FORMAT_INFO); if (SUCCEEDED(hr)) { do { memset(&pfe,0,sizeof(pfe)); hr = pIEnumWIA_FORMAT_INFO->Next(1, &pfe, NULL); if (hr == S_OK) { TCHAR szFormat[MAX_PATH]; TCHAR szGuid[MAX_PATH]; TCHAR szTYMED[MAX_PATH]; memset(szFormat,0,sizeof(szFormat)); memset(szGuid,0,sizeof(szGuid)); memset(szTYMED,0,sizeof(szTYMED)); if(!WIACONSTANT2TSTR(TEXT("Media Type"),(LONG)pfe.lTymed,szTYMED)){ lstrcpy(szTYMED,TEXT("TYMED_UNKNOWN")); } FORMAT2TSTR(pfe.guidFormatID,szGuid); TSPRINTF(szFormat,TEXT("%s - %s"),szTYMED,szGuid); m_SupportedTymedAndFormatsListBox.AddString(szFormat); } else { if (FAILED(hr)) { ErrorMessageBox(IDS_WIATESTERROR_ENUMFORMATS,hr); } } } while (hr == S_OK); pIEnumWIA_FORMAT_INFO->Release(); pIEnumWIA_FORMAT_INFO = NULL; } else { ErrorMessageBox(IDS_WIATESTERROR_ENUMFORMATS,hr); } pIWiaDataTransfer->Release(); pIWiaDataTransfer = NULL; } else { ErrorMessageBox(IDS_WIATESTERROR_IWIADATATRANSFER,hr); } } void CWiatestView::FORMAT2TSTR(GUID guidFormat, TCHAR *pszFormat) { if(guidFormat == WiaImgFmt_UNDEFINED) lstrcpy(pszFormat,TEXT("WiaImgFmt_UNDEFINED:")); else if(guidFormat == WiaImgFmt_MEMORYBMP) lstrcpy(pszFormat,TEXT("WiaImgFmt_MEMORYBMP:")); else if(guidFormat == WiaImgFmt_BMP) lstrcpy(pszFormat,TEXT("WiaImgFmt_BMP:")); else if(guidFormat == WiaImgFmt_EMF) lstrcpy(pszFormat,TEXT("WiaImgFmt_EMF:")); else if(guidFormat == WiaImgFmt_WMF) lstrcpy(pszFormat,TEXT("WiaImgFmt_WMF:")); else if(guidFormat == WiaImgFmt_JPEG) lstrcpy(pszFormat,TEXT("WiaImgFmt_JPEG:")); else if(guidFormat == WiaImgFmt_PNG) lstrcpy(pszFormat,TEXT("WiaImgFmt_PNG:")); else if(guidFormat == WiaImgFmt_GIF) lstrcpy(pszFormat,TEXT("WiaImgFmt_GIF:")); else if(guidFormat == WiaImgFmt_TIFF) lstrcpy(pszFormat,TEXT("WiaImgFmt_TIFF:")); else if(guidFormat == WiaImgFmt_EXIF) lstrcpy(pszFormat,TEXT("WiaImgFmt_EXIF:")); else if(guidFormat == WiaImgFmt_PHOTOCD) lstrcpy(pszFormat,TEXT("WiaImgFmt_PHOTOCD:")); else if(guidFormat == WiaImgFmt_FLASHPIX) lstrcpy(pszFormat,TEXT("WiaImgFmt_FLASHPIX:")); else { lstrcpy(pszFormat,TEXT("Custom Format:")); } TCHAR szGUID[MAX_PATH]; memset(szGUID,0,sizeof(szGUID)); UCHAR *pwszUUID = NULL; UuidToString(&guidFormat,&pwszUUID); TSPRINTF(szGUID," (%s)",pwszUUID); lstrcat(pszFormat,szGUID); // free allocated string RpcStringFree(&pwszUUID); } void CWiatestView::OnAcquireimage() { // delete old temp image files DeleteTempDataTransferFiles(); CWiatestDoc* pDocument = NULL; pDocument = (CWiatestDoc*)m_pDocument; if(pDocument){ if(pDocument->m_pICurrentItem == pDocument->m_pIRootItem){ // use the common UI, because we can not transfer from the root item OnAcquireimageCommonui(); return; } TCHAR szFileName[MAX_PATH]; TCHAR szTempFile[MAX_PATH]; memset(szFileName,0,sizeof(szFileName)); memset(szTempFile,0,sizeof(szTempFile)); CWiahelper WIA; HRESULT hr = S_OK; LONG lTymed = 0; hr = WIA.SetIWiaItem(pDocument->m_pICurrentItem); if (SUCCEEDED(hr)) { hr = WIA.ReadPropertyLong(WIA_IPA_TYMED,&lTymed); if (S_OK == hr) { switch (lTymed) { case TYMED_CALLBACK: case TYMED_MULTIPAGE_CALLBACK: GetTempPath(sizeof(szFileName),szFileName); RC2TSTR(IDS_WIATEST_MEMORYTRANSFER_FILENAME,szTempFile,sizeof(szTempFile)); lstrcat(szFileName,szTempFile); hr = TransferToMemory(szFileName, pDocument->m_pICurrentItem); break; case TYMED_FILE: case TYMED_MULTIPAGE_FILE: GetTempPath(sizeof(szFileName),szFileName); RC2TSTR(IDS_WIATEST_FILETRANSFER_FILENAME,szTempFile,sizeof(szTempFile)); lstrcat(szFileName,szTempFile); hr = TransferToFile(szFileName,pDocument->m_pICurrentItem); break; default: ErrorMessageBox(IDS_WIATESTERROR_UNSUPPORTEDTYMED); break; } } else if (S_FALSE == hr) { ErrorMessageBox(IDS_WIATESTERROR_READINGTYMED_EXIST,hr); } else { ErrorMessageBox(IDS_WIATESTERROR_READINGTYMED,hr); } } else { ErrorMessageBox(IDS_WIATESTERROR_READINGTYMED,hr); } if ((hr == S_OK)||(WIA_STATUS_END_OF_MEDIA == hr)) { CWiahelper WIA; WIA.SetIWiaItem(pDocument->m_pICurrentItem); GUID guidFormat; memset(&guidFormat,0,sizeof(guidFormat)); hr = WIA.ReadPropertyGUID(WIA_IPA_FORMAT,&guidFormat); if(S_OK == hr){ RenameTempDataTransferFilesAndLaunchViewer(guidFormat,lTymed); } } } } HRESULT CWiatestView::TransferToFile(TCHAR *szFileName, IWiaItem *pIWiaItem) { STGMEDIUM StgMedium; HRESULT hr = S_OK; // get IWiaDatatransfer interface IWiaDataTransfer *pIWiaDataTransfer = NULL; hr = pIWiaItem->QueryInterface(IID_IWiaDataTransfer, (void **)&pIWiaDataTransfer); if (SUCCEEDED(hr)) { WCHAR wszFileName[MAX_PATH]; memset(wszFileName,0,sizeof(wszFileName)); #ifndef UNICODE MultiByteToWideChar(CP_ACP, 0,szFileName,-1,wszFileName,MAX_PATH); #else lstrcpy(wszFileName,szFileName); #endif CWiahelper WIA; LONG lTymed = TYMED_FILE; WIA.SetIWiaItem(pIWiaItem); hr = WIA.ReadPropertyLong(WIA_IPA_TYMED, &lTymed); if (SUCCEEDED(hr)) { StgMedium.tymed = lTymed; StgMedium.pUnkForRelease = NULL; StgMedium.hGlobal = NULL; StgMedium.lpszFileName = wszFileName; IWiaDataCallback* pIWiaDataCallback = NULL; CWiaDataCallback WiaDataCallback; hr = WiaDataCallback.QueryInterface(IID_IWiaDataCallback,(void **)&pIWiaDataCallback); if (hr == S_OK) { hr = pIWiaDataTransfer->idtGetData(&StgMedium,pIWiaDataCallback); if ((hr == S_OK)||(WIA_STATUS_END_OF_MEDIA == hr)) { // successful transfer } else if (S_FALSE == hr) { ErrorMessageBox(IDS_WIATESTERROR_CANCEL_ACQUISITION); } else { ErrorMessageBox(IDS_WIATESTERROR_ACQUISITION,hr); } pIWiaDataTransfer->Release(); //WiaDataCallback.Release(); } } } return hr; } HRESULT CWiatestView::TransferToMemory(TCHAR *szFileName, IWiaItem *pIWiaItem) { HRESULT hr = S_OK; // get IWiaDatatransfer interface IWiaDataTransfer *pIWiaDataTransfer = NULL; hr = pIWiaItem->QueryInterface(IID_IWiaDataTransfer, (void **)&pIWiaDataTransfer); if (SUCCEEDED(hr)) { WIA_DATA_TRANSFER_INFO WiaDataTransferInformation; memset(&WiaDataTransferInformation,0,sizeof(WiaDataTransferInformation)); WiaDataTransferInformation.ulSize = sizeof(WiaDataTransferInformation); WiaDataTransferInformation.ulBufferSize = (ReadMinBufferSizeProperty(pIWiaItem) * MIN_BUFFER_FACTOR); IWiaDataCallback* pIWiaDataCallback = NULL; CWiaDataCallback WiaDataCallback; hr = WiaDataCallback.QueryInterface(IID_IWiaDataCallback,(void **)&pIWiaDataCallback); if (hr == S_OK) { hr = pIWiaDataTransfer->idtGetBandedData(&WiaDataTransferInformation,pIWiaDataCallback); if ((hr == S_OK)||(WIA_STATUS_END_OF_MEDIA == hr)) { HANDLE hMemoryDataFile = NULL; hMemoryDataFile = CreateFile(szFileName, GENERIC_WRITE,FILE_SHARE_READ,NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); if (hMemoryDataFile != INVALID_HANDLE_VALUE && hMemoryDataFile != NULL) { LONG lDataSize = 0; BYTE *pData = WiaDataCallback.GetCallbackMemoryPtr(&lDataSize); DWORD dwBytesWritten = 0; if (lDataSize > 0) { // handle BITMAP DATA (special case) if (WiaDataCallback.IsBITMAPDATA()) { // we need to adjust any headers, because the height and image size information // could be incorrect. (this will handle infinite page length devices) BITMAPFILEHEADER bmfh; BITMAPINFOHEADER *pbmh = NULL; pbmh = (BITMAPINFOHEADER*)pData; if(pbmh->biHeight < 0){ StatusMessageBox(IDS_WIATESTWARNING_NEGATIVE_HEIGHTBITMAP); pbmh->biHeight = abs(pbmh->biHeight); } LONG lPaletteSize = pbmh->biClrUsed * sizeof(RGBQUAD); bmfh.bfType = BMPFILE_HEADER_MARKER; bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + lPaletteSize; bmfh.bfSize = sizeof(BITMAPFILEHEADER) + lDataSize; bmfh.bfReserved1 = 0; bmfh.bfReserved2 = 0; // only fix the BITMAPINFOHEADER if height needs to be calculated if (pbmh->biHeight == 0) { StatusMessageBox(IDS_WIATESTWARNING_ZERO_HEIGHTBITMAP); LONG lWidthBytes = CalculateWidthBytes(pbmh->biWidth,pbmh->biBitCount); pbmh->biSizeImage = lDataSize - lPaletteSize - sizeof(BITMAPINFOHEADER); pbmh->biHeight = LONG(pbmh->biSizeImage/lWidthBytes); pbmh->biXPelsPerMeter = 0; // zero out pbmh->biYPelsPerMeter = 0; // zero out } WriteFile(hMemoryDataFile,&bmfh,sizeof(bmfh),&dwBytesWritten,NULL); } // write data to disk WriteFile(hMemoryDataFile,pData,lDataSize,&dwBytesWritten,NULL); } // flush and close FlushFileBuffers(hMemoryDataFile); CloseHandle(hMemoryDataFile); } } else if (S_FALSE == hr) { ErrorMessageBox(IDS_WIATESTERROR_CANCEL_ACQUISITION); } else { ErrorMessageBox(IDS_WIATESTERROR_ACQUISITION,hr); } pIWiaDataTransfer->Release(); //WiaDataCallback.Release(); } } return hr; } void CWiatestView::OnLoadWiapropertystream() { CWiatestDoc* pDocument = NULL; pDocument = (CWiatestDoc*)m_pDocument; if(pDocument){ CWiahelper WIA; WIA.SetIWiaItem(pDocument->m_pICurrentItem); HRESULT hr = S_OK; TCHAR szPropertyStreamFile[MAX_PATH]; memset(szPropertyStreamFile,0,sizeof(szPropertyStreamFile)); // select saving location OPENFILENAME ofn; // common dialog box structure TCHAR szLoadPropStreamTitle[MAX_PATH]; memset(szLoadPropStreamTitle,0,sizeof(szLoadPropStreamTitle)); RC2TSTR(IDS_WIATESTLOADPROPSTREAM_DIALOGTITLE,szLoadPropStreamTitle,sizeof(szLoadPropStreamTitle)); memset(&ofn,0,sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = m_hWnd; ofn.lpstrFile = szPropertyStreamFile; ofn.nMaxFile = sizeof(szPropertyStreamFile); ofn.lpstrFilter = "*.wia\0*.wia\0"; ofn.nFilterIndex = 1; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = NULL; ofn.lpstrTitle = szLoadPropStreamTitle; ofn.Flags = 0; ofn.lpstrDefExt = "wia"; if (!GetOpenFileName(&ofn)) { return; } hr = WIA.ReadPropertyStreamFile(szPropertyStreamFile); if(FAILED(hr)){ ErrorMessageBox(IDS_WIATESTERROR_READPROPERTYSTREAMFILE,hr); } else { // refresh the item tree AddWiaItemsToTreeControl(TVI_ROOT,pDocument->m_pIRootItem); // refresh the properties AddWiaItemPropertiesToListControl(pDocument->m_pIRootItem); } } } void CWiatestView::OnSaveWiapropertystream() { CWiatestDoc* pDocument = NULL; pDocument = (CWiatestDoc*)m_pDocument; if(pDocument){ CWiahelper WIA; WIA.SetIWiaItem(pDocument->m_pICurrentItem); HRESULT hr = S_OK; TCHAR szPropertyStreamFile[MAX_PATH]; memset(szPropertyStreamFile,0,sizeof(szPropertyStreamFile)); // select saving location OPENFILENAME ofn; // common dialog box structure TCHAR szSavePropStreamTitle[MAX_PATH]; memset(szSavePropStreamTitle,0,sizeof(szSavePropStreamTitle)); RC2TSTR(IDS_WIATESTSAVEPROPSTREAM_DIALOGTITLE,szSavePropStreamTitle,sizeof(szSavePropStreamTitle)); memset(&ofn,0,sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = m_hWnd; ofn.lpstrFile = szPropertyStreamFile; ofn.nMaxFile = sizeof(szPropertyStreamFile); ofn.lpstrFilter = "*.wia\0*.wia\0"; ofn.nFilterIndex = 1; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = NULL; ofn.lpstrTitle = szSavePropStreamTitle; ofn.Flags = 0; ofn.lpstrDefExt = "wia"; if (!GetSaveFileName(&ofn)) { return; } hr = WIA.WritePropertyStreamFile(szPropertyStreamFile); if(FAILED(hr)){ ErrorMessageBox(IDS_WIATESTERROR_WRITEPROPERTYSTREAMFILE,hr); } } } void CWiatestView::OnRclickItempropertiesListctrl(NMHDR* pNMHDR, LRESULT* pResult) { POINT MousePos; CMenu PopupMenu; CMenu *pEditMenu = NULL; if(PopupMenu.LoadMenu(IDR_PROPERTY_EDIT_POPUPMENU)){ GetCursorPos(&MousePos); pEditMenu = PopupMenu.GetSubMenu(0); if(pEditMenu){ pEditMenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON, MousePos.x, MousePos.y, this); } } *pResult = 0; } void CWiatestView::OnPropertyeditpopupmenuEditpropertyvalue() { PROPVARIANT *pPropertyVariants = NULL; PROPSPEC *pPropertySpecs = NULL; UINT uiNumProperties = m_ItemPropertiesListCtrl.GetSelectedCount(); if(uiNumProperties <=0){ return; } BOOL bWriteProperties = TRUE; IWiaPropertyStorage *pIWiaPropStg = NULL; HRESULT hr = S_OK; UINT iPropertyIndex = 0; pPropertyVariants = new PROPVARIANT[uiNumProperties]; if(pPropertyVariants){ pPropertySpecs = new PROPSPEC[uiNumProperties]; if(pPropertySpecs){ POSITION pos = NULL; pos = m_ItemPropertiesListCtrl.GetFirstSelectedItemPosition(); if (NULL != pos){ while (pos && bWriteProperties){ int iItem = m_ItemPropertiesListCtrl.GetNextSelectedItem(pos); // find out what property is selected TCHAR pszPropertyName[MAX_PATH]; memset(pszPropertyName,0,sizeof(pszPropertyName)); TCHAR pszPropertyValue[MAX_PATH]; memset(pszPropertyValue,0,sizeof(pszPropertyValue)); LV_ITEM lvitem; lvitem.mask = LVIF_PARAM; lvitem.iItem = iItem; lvitem.iSubItem = ITEMPROPERTYLISTCTRL_COLUMN_PROPERTYNAME; lvitem.pszText = NULL; // is an item selected? if (iItem < ITEMPROPERTYLISTCTRL_COLUMN_PROPERTYNAME) return; m_ItemPropertiesListCtrl.GetItem(&lvitem); // get stored property ID LONG iProp = 0; iProp = (LONG)lvitem.lParam; m_ItemPropertiesListCtrl.GetItemText(iItem, ITEMPROPERTYLISTCTRL_COLUMN_PROPERTYNAME, pszPropertyName, sizeof(pszPropertyName)); m_ItemPropertiesListCtrl.GetItemText(iItem, ITEMPROPERTYLISTCTRL_COLUMN_PROPERTYVALUE, pszPropertyValue, sizeof(pszPropertyValue)); // get document CWiatestDoc* pDocument = NULL; pDocument = (CWiatestDoc*)m_pDocument; if(pDocument){ hr = pDocument->m_pICurrentItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg); if(SUCCEEDED(hr)) { // read property value for type and current value PROPVARIANT PropVar[1]; PROPVARIANT AttrPropVar[1]; PROPSPEC PropSpec[1]; PropSpec[0].ulKind = PRSPEC_PROPID; PropSpec[0].propid = iProp; // set propspec pPropertySpecs[iPropertyIndex].ulKind = PRSPEC_PROPID; pPropertySpecs[iPropertyIndex].propid = iProp; ULONG ulAttributes = 0; CWiaeditpropDlg PropertyEditDlg; hr = pIWiaPropStg->ReadMultiple(1,PropSpec,PropVar); if (S_OK == hr) { PropertyEditDlg.SetVarType(PropVar[0].vt); // clear variant PropVariantClear(PropVar); hr = pIWiaPropStg->GetPropertyAttributes(1, PropSpec,&ulAttributes,AttrPropVar); if(S_OK == hr){ PropertyEditDlg.SetAttributes(ulAttributes, (PROPVARIANT*)AttrPropVar); if(PropertyEditDlg.DoModal(pszPropertyName,pszPropertyValue) == IDOK){ memset(pszPropertyValue,0,sizeof(pszPropertyValue)); PropertyEditDlg.GetPropertyValue(pszPropertyValue); // set variant pPropertyVariants[iPropertyIndex].vt = PropertyEditDlg.GetVarType(); TSTR2PROPVAR(pszPropertyValue,(PROPVARIANT*)&pPropertyVariants[iPropertyIndex]); iPropertyIndex++; } else { // user decided not to write the property bWriteProperties = FALSE; } } } // release property storage pIWiaPropStg->Release(); pIWiaPropStg = NULL; } } } } } if(bWriteProperties){ // get current document, and refresh the property list with the current // selected item CWiatestDoc* pDocument = NULL; pDocument = (CWiatestDoc*)m_pDocument; if(pDocument){ hr = pDocument->m_pICurrentItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg); if(SUCCEEDED(hr)) { hr = pIWiaPropStg->WriteMultiple(uiNumProperties,pPropertySpecs,pPropertyVariants,MIN_PROPID); if(S_OK == hr){ // success } else if FAILED(hr){ // failure ErrorMessageBox(IDS_WIATESTERROR_WRITING_PROPERTY,hr); } else { // S_FALSE ErrorMessageBox(IDS_WIATESTWARNING_ADDITIONAL_PROPERTY); } pIWiaPropStg->Release(); pIWiaPropStg = NULL; } // update list control with properties AddWiaItemPropertiesToListControl(pDocument->m_pICurrentItem); // update TYMED and format selection listbox SetCurrentSelectionForTYMEDAndFormat(); } } if(pPropertyVariants){ PropVariantClear(pPropertyVariants); delete [] pPropertyVariants; pPropertyVariants = NULL; } if(pPropertySpecs){ delete [] pPropertySpecs; pPropertySpecs = NULL; } } } void CWiatestView::OnViewCapabilities() { CWiacapDlg CapabilitiesDlg; CWiatestDoc* pDocument = NULL; pDocument = (CWiatestDoc*)m_pDocument; if(pDocument){ CapabilitiesDlg.SetIWiaItem(pDocument->m_pIRootItem); CapabilitiesDlg.DoModal(); #ifdef FORCE_UPDATE if(CapabilitiesDlg.m_bCommandSent){ // refresh the item tree AddWiaItemsToTreeControl(TVI_ROOT,pDocument->m_pIRootItem); // refresh the properties AddWiaItemPropertiesToListControl(pDocument->m_pIRootItem); } #endif } } void CWiatestView::OnRclickItemTreectrl(NMHDR* pNMHDR, LRESULT* pResult) { POINT MousePos; CMenu PopupMenu; CMenu *pEditMenu = NULL; if(PopupMenu.LoadMenu(IDR_ITEMTREE_POPUPMENU)){ GetCursorPos(&MousePos); pEditMenu = PopupMenu.GetSubMenu(0); if(pEditMenu){ CWiatestDoc* pDocument = NULL; pDocument = (CWiatestDoc*)m_pDocument; if(pDocument){ if(pDocument->m_pICurrentItem == pDocument->m_pIRootItem){ pEditMenu->EnableMenuItem(IDM_DELETE_ITEM,MF_BYCOMMAND|MF_GRAYED); pEditMenu->RemoveMenu(IDM_ACQUIREIMAGE,MF_BYCOMMAND); } else { pEditMenu->RemoveMenu(IDM_ACQUIREIMAGE_COMMONUI,MF_BYCOMMAND); } pEditMenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON, MousePos.x, MousePos.y, this); } } } *pResult = 0; } ULONG CWiatestView::ReadMinBufferSizeProperty(IWiaItem *pIWiaItem) { LONG lMinBufferSize = 0; CWiahelper WIA; WIA.SetIWiaItem(pIWiaItem); HRESULT hr = S_OK; hr = WIA.ReadPropertyLong(WIA_IPA_MIN_BUFFER_SIZE,&lMinBufferSize); if(FAILED(hr)){ ErrorMessageBox(IDS_WIATESTERROR_READINGMINBUFFERSIZE,hr); } return lMinBufferSize; } void CWiatestView::SetCurrentSelectionForTYMEDAndFormat() { TCHAR szTymed[MAX_PATH]; memset(szTymed,0,sizeof(szTymed)); TCHAR szFormat[MAX_PATH]; memset(szFormat,0,sizeof(szFormat)); INT iItem = 0; LVFINDINFO info; info.flags = LVFI_PARTIAL|LVFI_STRING; // find current TYMED setting info.psz = TEXT("Media Type"); iItem = m_ItemPropertiesListCtrl.FindItem(&info,-1); if(iItem != -1){ // item Found // get current value from control m_ItemPropertiesListCtrl.GetItemText(iItem,ITEMPROPERTYLISTCTRL_COLUMN_PROPERTYVALUE, szTymed, sizeof(szTymed)); LONG lTymed = 0; TSSCANF(szTymed,"%d",&lTymed); WIACONSTANT2TSTR(TEXT("Media Type"), lTymed, szTymed); } // find current Format setting info.psz = TEXT("Format"); iItem = m_ItemPropertiesListCtrl.FindItem(&info,-1); if(iItem != -1){ // item Found // get current value from control m_ItemPropertiesListCtrl.GetItemText(iItem,ITEMPROPERTYLISTCTRL_COLUMN_PROPERTYVALUE, szFormat, sizeof(szFormat)); } // find and select the current TYMED / format pair in the selection control. INT iNumListBoxItems = 0; iNumListBoxItems = m_SupportedTymedAndFormatsListBox.GetCount(); if(iNumListBoxItems > 0){ for(INT i = 0; i < iNumListBoxItems; i++){ TCHAR szText[MAX_PATH]; memset(szText,0,sizeof(szText)); m_SupportedTymedAndFormatsListBox.GetText(i,szText); if(TSTRSTR(szText,szTymed) != NULL){ // found TYMED if(TSTRSTR(szText,szFormat) != NULL){ // found format m_SupportedTymedAndFormatsListBox.SetCurSel(i); // exit loop i = iNumListBoxItems; } } } } } void CWiatestView::DeleteTempDataTransferFiles() { } void CWiatestView::RenameTempDataTransferFilesAndLaunchViewer(GUID guidFormat, LONG lTymed) { TCHAR *pszFileExt = NULL; TCHAR szOriginalFileName[MAX_PATH]; TCHAR szFileName[MAX_PATH]; TCHAR szTempPath[MAX_PATH]; TCHAR szFullLaunchPath[MAX_PATH]; TCHAR szOriginalFullLaunchPath[MAX_PATH]; memset(szFileName,0,sizeof(szFileName)); memset(szTempPath,0,sizeof(szTempPath)); memset(szFullLaunchPath,0,sizeof(szFullLaunchPath)); memset(szOriginalFileName,0,sizeof(szOriginalFileName)); memset(szOriginalFullLaunchPath,0,sizeof(szOriginalFullLaunchPath)); GetTempPath(sizeof(szTempPath),szTempPath); BOOL bKnownFormat = TRUE; switch(lTymed){ case TYMED_CALLBACK: case TYMED_MULTIPAGE_CALLBACK: RC2TSTR(IDS_WIATEST_MEMORYTRANSFER_FILENAME,szOriginalFileName,sizeof(szOriginalFileName)); lstrcpy(szFileName,szOriginalFileName); pszFileExt = TSTRSTR(szFileName,TEXT("mem")); break; case TYMED_FILE: case TYMED_MULTIPAGE_FILE: RC2TSTR(IDS_WIATEST_FILETRANSFER_FILENAME,szOriginalFileName,sizeof(szOriginalFileName)); lstrcpy(szFileName,szOriginalFileName); pszFileExt = TSTRSTR(szFileName,TEXT("fil")); break; default: break; } if(lstrlen(szFileName) > 0){ if(pszFileExt){ // rename to known image formats if(guidFormat == WiaImgFmt_UNDEFINED) lstrcpy(pszFileExt,TEXT("bmp")); else if(guidFormat == WiaImgFmt_MEMORYBMP) lstrcpy(pszFileExt,TEXT("bmp")); else if(guidFormat == WiaImgFmt_BMP) lstrcpy(pszFileExt,TEXT("bmp")); else if(guidFormat == WiaImgFmt_EMF) lstrcpy(pszFileExt,TEXT("emf")); else if(guidFormat == WiaImgFmt_WMF) lstrcpy(pszFileExt,TEXT("wmf")); else if(guidFormat == WiaImgFmt_JPEG) lstrcpy(pszFileExt,TEXT("jpg")); else if(guidFormat == WiaImgFmt_PNG) lstrcpy(pszFileExt,TEXT("png")); else if(guidFormat == WiaImgFmt_GIF) lstrcpy(pszFileExt,TEXT("gif")); else if(guidFormat == WiaImgFmt_TIFF) lstrcpy(pszFileExt,TEXT("tif")); else if(guidFormat == WiaImgFmt_EXIF) lstrcpy(pszFileExt,TEXT("jpg")); else if(guidFormat == WiaImgFmt_PHOTOCD) lstrcpy(pszFileExt,TEXT("pcd")); else if(guidFormat == WiaImgFmt_FLASHPIX) lstrcpy(pszFileExt,TEXT("fpx")); else { TCHAR szValue[MAX_PATH]; memset(szValue,0,sizeof(szValue)); UCHAR *pwszUUID = NULL; UuidToString(&guidFormat,&pwszUUID); TSPRINTF(szValue,TEXT("%s"),pwszUUID); // (TEXT("(Unknown Image type) GUID: %s"),pwszUUID); // free allocated string RpcStringFree(&pwszUUID); bKnownFormat = FALSE; } } } if(bKnownFormat){ // launch viewer lstrcpy(szFullLaunchPath,szTempPath); lstrcat(szFullLaunchPath,szFileName); lstrcpy(szOriginalFullLaunchPath,szTempPath); lstrcat(szOriginalFullLaunchPath,szOriginalFileName); // delete any duplicates DeleteFile(szFullLaunchPath); // rename file MoveFile(szOriginalFullLaunchPath,szFullLaunchPath); HINSTANCE hInst = NULL; hInst = ShellExecute(m_hWnd,NULL,szFullLaunchPath,NULL,szTempPath,SW_SHOW); } else { ErrorMessageBox(IDS_WIATESTERROR_UNKNOWN_IMAGEFORMAT); } } LONG CWiatestView::CalculateWidthBytes(LONG lWidthPixels, LONG lbpp) { LONG lWidthBytes = 0; lWidthBytes = (lWidthPixels * lbpp) + 31; lWidthBytes = ((lWidthBytes/8) & 0xfffffffc); return lWidthBytes; } void CWiatestView::OnDeleteItem() { HRESULT hr = S_OK; CWiatestDoc* pDocument = NULL; pDocument = (CWiatestDoc*)m_pDocument; if(pDocument){ if(pDocument->m_pICurrentItem != pDocument->m_pIRootItem){ pDocument->m_pICurrentItem->DeleteItem(0); pDocument->m_pICurrentItem->Release(); pDocument->m_pICurrentItem = NULL; // refresh the item tree AddWiaItemsToTreeControl(TVI_ROOT,pDocument->m_pIRootItem); // refresh the properties AddWiaItemPropertiesToListControl(pDocument->m_pIRootItem); } else { ErrorMessageBox(IDS_WIATESTERROR_DELETEROOTITEM); } } } void CWiatestView::OnAcquireimageCommonui() { // delete old temp image files DeleteTempDataTransferFiles(); HRESULT hr = S_OK; IWiaItem **pIWiaItemArray = NULL; LONG lItemCount = 0; CWiatestDoc* pDocument = NULL; pDocument = (CWiatestDoc*)m_pDocument; if(pDocument){ hr = pDocument->m_pIRootItem->DeviceDlg(m_hWnd,0,WIA_INTENT_MINIMIZE_SIZE,&lItemCount,&pIWiaItemArray); if(S_OK == hr){ // get temp file name TCHAR szTempFile[MAX_PATH]; memset(szTempFile,0,sizeof(szTempFile)); RC2TSTR(IDS_WIATEST_FILETRANSFER_FILENAME,szTempFile,sizeof(szTempFile)); for(LONG lItem = 0; lItem < lItemCount; lItem++){ // get temp path TCHAR szFileName[MAX_PATH]; memset(szFileName,0,sizeof(szFileName)); GetTempPath(sizeof(szFileName),szFileName); // create new temp file with image index number TCHAR szFinalFileName[MAX_PATH]; memset(szFinalFileName,0,sizeof(szFinalFileName)); TSPRINTF(szFinalFileName,TEXT("%d%s"),lItem,szTempFile); // add new temp file to temp path lstrcat(szFileName,szFinalFileName); // set TYMED_FILE CWiahelper WIA; WIA.SetIWiaItem(pIWiaItemArray[lItem]); hr = WIA.WritePropertyLong(WIA_IPA_TYMED,TYMED_FILE); if (S_OK == hr) { // transfer to this file hr = TransferToFile(szFileName,pIWiaItemArray[lItem]); if ((hr == S_OK)||(WIA_STATUS_END_OF_MEDIA == hr)) { GUID guidFormat; memset(&guidFormat,0,sizeof(guidFormat)); hr = WIA.ReadPropertyGUID(WIA_IPA_FORMAT,&guidFormat); if (S_OK == hr) { RenameTempDataTransferFilesAndLaunchViewer(szFileName,guidFormat,TYMED_FILE); } else { ErrorMessageBox(IDS_WIATESTERROR_READINGFORMAT,hr); } } else if (FAILED(hr)) { ErrorMessageBox(IDS_WIATESTERROR_ACQUISITION,hr); } } else { ErrorMessageBox(IDS_WIATESTERROR_WRITINGTYMED,hr); } // release item after acquisition pIWiaItemArray[lItem]->Release(); } } } } void CWiatestView::OnEditDebugout() { if(m_bOutputToDebuggerON){ m_bOutputToDebuggerON = FALSE; DBG_SET_FLAGS(COREDBG_ERRORS); } else { m_bOutputToDebuggerON = TRUE; DBG_SET_FLAGS(COREDBG_ERRORS | COREDBG_WARNINGS | COREDBG_TRACES); } } void CWiatestView::OnUpdateEditDebugout(CCmdUI* pCmdUI) { pCmdUI->SetCheck(m_bOutputToDebuggerON); } void CWiatestView::RenameTempDataTransferFilesAndLaunchViewer(TCHAR *szFileName, GUID guidFormat, LONG lTymed) { TCHAR *pszFileExt = NULL; TCHAR szOriginalFileName[MAX_PATH]; TCHAR szTempPath[MAX_PATH]; memset(szTempPath,0,sizeof(szTempPath)); memset(szOriginalFileName,0,sizeof(szOriginalFileName)); // copy original filename lstrcpy(szOriginalFileName,szFileName); // get temp launch path GetTempPath(sizeof(szTempPath),szTempPath); BOOL bKnownFormat = TRUE; switch(lTymed){ case TYMED_CALLBACK: case TYMED_MULTIPAGE_CALLBACK: pszFileExt = TSTRSTR(szFileName,TEXT("mem")); break; case TYMED_FILE: case TYMED_MULTIPAGE_FILE: pszFileExt = TSTRSTR(szFileName,TEXT("fil")); break; default: break; } if(lstrlen(szFileName) > 0){ if(pszFileExt){ // rename to known image formats if(guidFormat == WiaImgFmt_UNDEFINED) lstrcpy(pszFileExt,TEXT("bmp")); else if(guidFormat == WiaImgFmt_MEMORYBMP) lstrcpy(pszFileExt,TEXT("bmp")); else if(guidFormat == WiaImgFmt_BMP) lstrcpy(pszFileExt,TEXT("bmp")); else if(guidFormat == WiaImgFmt_EMF) lstrcpy(pszFileExt,TEXT("emf")); else if(guidFormat == WiaImgFmt_WMF) lstrcpy(pszFileExt,TEXT("wmf")); else if(guidFormat == WiaImgFmt_JPEG) lstrcpy(pszFileExt,TEXT("jpg")); else if(guidFormat == WiaImgFmt_PNG) lstrcpy(pszFileExt,TEXT("png")); else if(guidFormat == WiaImgFmt_GIF) lstrcpy(pszFileExt,TEXT("gif")); else if(guidFormat == WiaImgFmt_TIFF) lstrcpy(pszFileExt,TEXT("tif")); else if(guidFormat == WiaImgFmt_EXIF) lstrcpy(pszFileExt,TEXT("jpg")); else if(guidFormat == WiaImgFmt_PHOTOCD) lstrcpy(pszFileExt,TEXT("pcd")); else if(guidFormat == WiaImgFmt_FLASHPIX) lstrcpy(pszFileExt,TEXT("fpx")); else { TCHAR szValue[MAX_PATH]; memset(szValue,0,sizeof(szValue)); UCHAR *pwszUUID = NULL; UuidToString(&guidFormat,&pwszUUID); TSPRINTF(szValue,TEXT("%s"),pwszUUID); // (TEXT("(Unknown Image type) GUID: %s"),pwszUUID); // free allocated string RpcStringFree(&pwszUUID); bKnownFormat = FALSE; } } } if(bKnownFormat){ // delete any duplicates DeleteFile(szFileName); // rename file MoveFile(szOriginalFileName,szFileName); HINSTANCE hInst = NULL; hInst = ShellExecute(m_hWnd,NULL,szFileName,NULL,szTempPath,SW_SHOW); } else { ErrorMessageBox(IDS_WIATESTERROR_UNKNOWN_IMAGEFORMAT); } } void CWiatestView::DisplayMissingThumbnail() { //m_hThumbNailBitmap = ::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_THUMBNAIL_MISSING_BITMAP)); //if(m_hThumbNailBitmap){ // display thumbnail(deleting any old one) HBITMAP hPreviousBitmap = NULL; //hPreviousBitmap = m_ThumbnailPreviewWindow.SetBitmap(m_hThumbNailBitmap); hPreviousBitmap = m_ThumbnailPreviewWindow.GetBitmap(); if(hPreviousBitmap){ DeleteObject(hPreviousBitmap); hPreviousBitmap = NULL; } m_ThumbnailPreviewWindow.Invalidate(); Invalidate(); //} } void CWiatestView::DisplayThumbnail(IWiaItem *pIWiaItem) { if(GET_STIDEVICE_TYPE(m_lDeviceType) == StiDeviceTypeDigitalCamera){ HRESULT hr = S_OK; BYTE *pThumbNail = NULL; CWiahelper WIA; WIA.SetIWiaItem(pIWiaItem); long lThumbNailHeight = 0; long lThumbNailWidth = 0; long lThumbNailSize = 0; // // read thumbnail height // hr = WIA.ReadPropertyLong(WIA_IPC_THUMB_HEIGHT,&lThumbNailHeight); if(hr != S_OK){ if(FAILED(hr)){ ErrorMessageBox(IDS_WIATESTERROR_THUMBNAILHEIGHT,hr); } DisplayMissingThumbnail(); return; } // // read thumbnail width // hr = WIA.ReadPropertyLong(WIA_IPC_THUMB_WIDTH,&lThumbNailWidth); if(hr != S_OK){ if(FAILED(hr)){ ErrorMessageBox(IDS_WIATESTERROR_THUMBNAILWIDTH,hr); } DisplayMissingThumbnail(); return; } // // read thumbnail data // LONG lDataSize = 0; BYTE *pData = NULL; hr = WIA.ReadPropertyData(WIA_IPC_THUMBNAIL,&pData,&lDataSize); if (hr == S_OK) { lThumbNailSize = lThumbNailWidth * lThumbNailHeight * 3; if (lThumbNailSize != lDataSize) { TCHAR szErrorResourceText[MAX_PATH]; memset(szErrorResourceText,0,sizeof(szErrorResourceText)); TCHAR szErrorText[MAX_PATH]; memset(szErrorText,0,sizeof(szErrorText)); RC2TSTR(IDS_WIATESTERROR_PROCESSING_THUMBNAILDATA,szErrorResourceText,sizeof(szErrorResourceText)); TSPRINTF(szErrorText,szErrorResourceText,lThumbNailSize,lDataSize); ErrorMessageBox(szErrorText); // free temp memory if(pData){ GlobalFree(pData); pData = NULL; } DisplayMissingThumbnail(); return; } BITMAPINFO bmi; memset(&bmi,0,sizeof(bmi)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = lThumbNailWidth; bmi.bmiHeader.biHeight = lThumbNailHeight; 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; PBYTE pThumbNailData = NULL; HDC hdc = ::GetDC(NULL); if(hdc){ HDC hdcm = CreateCompatibleDC(hdc); } m_hThumbNailBitmap = CreateDIBSection(hdc,&bmi,DIB_RGB_COLORS,(void **)&pThumbNailData,NULL,0); if(m_hThumbNailBitmap){ memcpy(pThumbNailData,pData,lDataSize); } // free temp memory if(pData){ GlobalFree(pData); pData = NULL; } // display thumbnail(deleting any old one) HBITMAP hPreviousBitmap = NULL; hPreviousBitmap = m_ThumbnailPreviewWindow.SetBitmap(m_hThumbNailBitmap); if(hPreviousBitmap){ DeleteObject(hPreviousBitmap); hPreviousBitmap = NULL; } m_ThumbnailPreviewWindow.Invalidate(); } else if(hr != S_OK){ if(FAILED(hr)){ ErrorMessageBox(IDS_WIATESTERROR_THUMBNAILDATA,hr); } DisplayMissingThumbnail(); return; } } } void CWiatestView::AdjustViewForDeviceType() { // get associated document CWiatestDoc* pDocument = NULL; pDocument = (CWiatestDoc*)m_pDocument; if(pDocument){ m_lDeviceType = 0; CWiahelper WIA; HRESULT hr = S_OK; WIA.SetIWiaItem(pDocument->m_pIRootItem); hr = WIA.ReadPropertyLong(WIA_DIP_DEV_TYPE,&m_lDeviceType); if(S_OK == hr){ if(GET_STIDEVICE_TYPE(m_lDeviceType) == StiDeviceTypeScanner){ // disable thumbnail preview window m_ThumbnailPreviewWindow.ShowWindow(SW_HIDE); LONG lDocHandlingSelect = 0; hr = WIA.ReadPropertyLong(WIA_DPS_DOCUMENT_HANDLING_SELECT,&lDocHandlingSelect); if(S_OK == hr){ // enable Document Acquisition settings menu option, and toolbar m_bHasDocumentFeeder = TRUE; } } } else { // error? } } } void CWiatestView::RegisterForEvents() { HRESULT hr = S_OK; IWiaDevMgr *pIWiaDevMgr = NULL; hr = CoCreateInstance(CLSID_WiaDevMgr, NULL, CLSCTX_LOCAL_SERVER, IID_IWiaDevMgr,(void**)&pIWiaDevMgr); if(FAILED(hr)){ // creation of device manager failed, so we can not continue ErrorMessageBox(IDS_WIATESTERROR_COCREATEWIADEVMGR,hr); return; } CWiatestDoc* pDocument = NULL; pDocument = (CWiatestDoc*)m_pDocument; if (pDocument) { // read device ID CWiahelper WIA; WIA.SetIWiaItem(pDocument->m_pIRootItem); BSTR bstrDeviceID = NULL; hr = WIA.ReadPropertyBSTR(WIA_DIP_DEV_ID,&bstrDeviceID); if (FAILED(hr)) { ErrorMessageBox(IDS_WIATESTERROR_DEVICEID,hr); return; } WIA_DEV_CAP DevCap; IEnumWIA_DEV_CAPS* pIEnumWiaDevCaps = NULL; // enumerate all device events supported hr = pDocument->m_pIRootItem->EnumDeviceCapabilities(WIA_DEVICE_EVENTS,&pIEnumWiaDevCaps); if (S_OK == hr) { LONG lEventIndex = 0; IWiaEventCallback* pIWiaEventCallback = NULL; hr = m_WiaEventCallback.QueryInterface(IID_IWiaEventCallback,(void **)&pIWiaEventCallback); if (SUCCEEDED(hr)) { do { memset(&DevCap,0,sizeof(DevCap)); hr = pIEnumWiaDevCaps->Next(1,&DevCap,NULL); if (S_OK == hr) { // DevCap.ulFlags; // DevCap.bstrIcon; // DevCap.bstrCommanline; // DevCap.guid; hr = pIWiaDevMgr->RegisterEventCallbackInterface(0, bstrDeviceID, &DevCap.guid, pIWiaEventCallback, &m_WiaEventCallback.m_pIUnkRelease[lEventIndex]); if (FAILED(hr)) { ErrorMessageBox(IDS_WIATESTERROR_REGISTER_EVENT_CALLBACK,hr); } else { // increment index lEventIndex++; } // free allocated strings if (DevCap.bstrName) { SysFreeString(DevCap.bstrName); } if (DevCap.bstrDescription) { SysFreeString(DevCap.bstrDescription); } } }while (hr == S_OK); } pIEnumWiaDevCaps->Release(); pIEnumWiaDevCaps = NULL; } } pIWiaDevMgr->Release(); pIWiaDevMgr = NULL; //CWnd* pParent = GetParent(); m_WiaEventCallback.SetViewWindowHandle(m_hWnd); } LRESULT CWiatestView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { BOOL bProcessMessage = FALSE; // is it one of the user defined messages?? switch (message) { case WM_DEVICE_DISCONNECTED: case WM_DEVICE_CONNECTED: case WM_ITEM_DELETED: case WM_ITEM_CREATED: case WM_TREE_UPDATED: case WM_STORAGE_CREATED: case WM_STORAGE_DELETED: bProcessMessage = TRUE; break; default: break; } // if it is process it... if (bProcessMessage) { HRESULT hr = S_OK; CWnd *pParent = GetParent(); if (pParent) { CWiatestDoc* pDocument = NULL; pDocument = (CWiatestDoc*)m_pDocument; if (pDocument) { switch (message) { case WM_DEVICE_DISCONNECTED: return pParent->PostMessage(WM_CLOSE,0,0); break; case WM_DEVICE_CONNECTED: break; case WM_ITEM_DELETED: case WM_ITEM_CREATED: case WM_TREE_UPDATED: case WM_STORAGE_CREATED: case WM_STORAGE_DELETED: // refresh the item tree AddWiaItemsToTreeControl(TVI_ROOT,pDocument->m_pIRootItem); // refresh the properties AddWiaItemPropertiesToListControl(pDocument->m_pIRootItem); break; default: break; } } } } // do default processing return CFormView::WindowProc(message, wParam, lParam); } void CWiatestView::OnShowWindow(BOOL bShow, UINT nStatus) { CFormView::OnShowWindow(bShow, nStatus); } void CWiatestView::OnDocumentAcquisitionSettings() { CWiatestDoc* pDocument = NULL; pDocument = (CWiatestDoc*)m_pDocument; if (pDocument) { CWiaDocAcqSettings DocumentAcquisitionSettingsDlg(IDS_WIATEST_DOCUMENT_SETTINGS_TITLE, pDocument->m_pIRootItem); if (DocumentAcquisitionSettingsDlg.DoModal() != IDCANCEL) { // refresh the item tree AddWiaItemsToTreeControl(TVI_ROOT,pDocument->m_pIRootItem); // refresh the properties AddWiaItemPropertiesToListControl(pDocument->m_pIRootItem); } } } void CWiatestView::OnUpdateDocumentAcquisitionSettings(CCmdUI* pCmdUI) { pCmdUI->Enable(m_bHasDocumentFeeder); } void CWiatestView::OnSelchangeSupportedTymedAndFormatListbox() { CWiatestDoc* pDocument = NULL; pDocument = (CWiatestDoc*)m_pDocument; if(pDocument){ TCHAR szTymedAndFormat[MAX_PATH]; memset(szTymedAndFormat,0,sizeof(szTymedAndFormat)); INT iCurrentSelection = 0; iCurrentSelection = m_SupportedTymedAndFormatsListBox.GetCurSel(); if(iCurrentSelection != -1){ m_SupportedTymedAndFormatsListBox.GetText(iCurrentSelection,szTymedAndFormat); // find current TYMED selection (located in selected string) LONG lTymed = TYMED_CALLBACK; if(TSTRSTR(szTymedAndFormat,TEXT("TYMED_CALLBACK")) != NULL){ lTymed = TYMED_CALLBACK; } if(TSTRSTR(szTymedAndFormat,TEXT("TYMED_FILE")) != NULL){ lTymed = TYMED_FILE; } if(TSTRSTR(szTymedAndFormat,TEXT("TYMED_MULTIPAGE_CALLBACK")) != NULL){ lTymed = TYMED_MULTIPAGE_CALLBACK; } if(TSTRSTR(szTymedAndFormat,TEXT("TYMED_MULTIPAGE_FILE")) != NULL){ lTymed = TYMED_MULTIPAGE_FILE; } HRESULT hr = S_OK; CWiahelper WIA; WIA.SetIWiaItem(pDocument->m_pICurrentItem); // write TYMED to device hr = WIA.WritePropertyLong(WIA_IPA_TYMED,lTymed); if (FAILED(hr)){ ErrorMessageBox(IDS_WIATESTERROR_WRITINGTYMED,hr); return; } // find current format selection TCHAR *pszGUID = NULL; // trim off trailing ')' on guid string LONG lLen = 0; lLen = lstrlen(szTymedAndFormat); szTymedAndFormat[(lLen * sizeof(TCHAR)) - sizeof(TCHAR)] = 0; pszGUID = TSTRSTR(szTymedAndFormat,TEXT("(")); if(pszGUID){ pszGUID+=sizeof(TCHAR); // we are on the GUID GUID guidFormat = GUID_NULL; memset(&guidFormat,0,sizeof(guidFormat)); #ifndef UNICODE UuidFromString((UCHAR*)pszGUID,&guidFormat); #else WideCharToMultiByte(CP_ACP, 0,pszGUID,-1,szbuffer,MAX_PATH,NULL,NULL); UuidFromString((UCHAR*)szbuffer,&guidFormat); #endif if(guidFormat != GUID_NULL){ hr = WIA.WritePropertyGUID(WIA_IPA_FORMAT,guidFormat); if(SUCCEEDED(hr)){ AddWiaItemPropertiesToListControl(pDocument->m_pICurrentItem); } else { ErrorMessageBox(IDS_WIATESTERROR_WRITINGFORMAT,hr); } } } } } } void CWiatestView::OnThumbnailPreview() { }