Displaying RAW and ROI images (C++ example)
GBG provides the CppAdvancedExample to demonstrate how to implement RAW and ROI functionality and to display RAW and ROI images. The CppAdvancedExample C++ project is based on the CPPSimpleExample C++ project. The CppAdvancedExample project displays RAW and ROI images according to selected regions.
DocumentRegionAdded event
Section titled “DocumentRegionAdded event”Use the following DocumentRegionAdded defined event to get all regions information:
DISP_FUNCTION_ID(CMainDialog, "DocumentRegionAdded", DISPID_DOCUMENTREGIONADDED, OnDocumentRegionAdded, VT_EMPTY, VTS_DISPATCH)
void CMainDialog::OnDocumentRegionAdded(IDocumentRegionEventArgs *pArgs){ CComPtr<IDocumentRegion> pDocumentRegion; if (SUCCEEDED(pArgs->get_Region(&pDocumentRegion))) //Get document region pointer { BSTR vtRegionName; pDocumentRegion->get_Name(&vtRegionName); //Get region name Rectangle nodeRect; pDocumentRegion->get_Rectangle(&nodeRect); //Get region rectangle //==Insert Tree Item with region name TV_INSERTSTRUCT tvInsertStruct; tvInsertStruct.hParent = NULL; tvInsertStruct.hInsertAfter = TVI_SORT; std::wstring name_wstr = L" ..."; const WCHAR* nameWchar = name_wstr.c_str()+ _bstr_t(vtRegionName); tvInsertStruct.item.pszText = LPWSTR(nameWchar); tvInsertStruct.item.mask = TVIF_TEXT | TVIF_IMAGE; tvInsertStruct.item.iImage = 0; HTREEITEM hItem = treeRegionsView.InsertItem(&tvInsertStruct); //==Insert Tree sub Item with rectangle points. TV_INSERTSTRUCT tvInsertStruct2; tvInsertStruct2.hParent = hItem; tvInsertStruct2.hInsertAfter = TVI_LAST; std::wstring disply_wstr =L"...{X=" +std::to_wstring(nodeRect.X) + L",Y="+ std::to_wstring(nodeRect.Y) + L",Width=" +std::to_wstring(nodeRect.Width)+L",Hight=" + std::to_wstring(nodeRect.Height); const WCHAR* dispWchar = disply_wstr.c_str(); tvInsertStruct2.item.pszText = LPWSTR(dispWchar); tvInsertStruct2.item.mask = TVIF_TEXT | TVIF_IMAGE; tvInsertStruct2.item.iImage = 2; HTREEITEM hRegionItem = treeRegionsView.InsertItem(&tvInsertStruct2); //====Store the pointer as ItemData at the tree. IUnknown* pUnk = NULL; HRESULT hr = pDocumentRegion->QueryInterface(IID_PPV_ARGS(&pUnk)); treeRegionsView.SetItemData(hItem, reinterpret_cast<DWORD_PTR> (pUnk)); DeleteObject(pUnk); }}Displaying the Regions tree
Section titled “Displaying the Regions tree”This section gets all regions information and stores them in the Regions tree. Each region displays the Region Name and Region rectangle.

Regions Display tree view item selection (Click Event )
onTreeViewRegionsItemSelect event
Section titled “onTreeViewRegionsItemSelect event”ON_NOTIFY(TVN_SELCHANGED, IDC_TREE1, &CMainDialog::onTreeViewRegionsItemSelect)
void CMainDialog::onTreeViewRegionsItemSelect(NMHDR *pNMHDR, LRESULT *pResult)
{ //Get selected tree item text HTREEITEM hItem = treeRegionsView.GetSelectedItem(); CComPtr<IDocumentRegion> region; //Get the Stored pointer to the region. DWORD_PTR pRegionObj = treeRegionsView.GetItemData(hItem); //==With region Pointer when clicked the parent item the region is displayed region = (IDocumentRegion*)pRegionObj; HTREEITEM hParent = treeRegionsView.GetParentItem(hItem); if (region && hParent==NULL) { setRegion(region); } else { treeRegionsView.SetItemImage(hItem, 2, 2); treeRegionsView.Invalidate(); }}Display the region at m_ClipImageTab
Section titled “Display the region at m_ClipImageTab”//Displays the region at the m_ClipImageTab Tabvoid CMainDialog::setRegion(CComPtr<IDocumentRegion> region){ int last_cure_sel= m_ClipImageTab.GetCurSel(); RemoveAllClipImageTabs(); //Raw Tab CComPtr<IBitmap> pBMap; region->get_Bitmap(&pBMap); Rectangle regionRect; region->get_Rectangle(®ionRect); CString strImageName = CString("Raw"); // Create RAW image tab with the RAW bitmap. TCITEM tcItem = { 0 }; tcItem.mask = TCIF_PARAM; tcItem.pszText = strImageName.GetBuffer(); CImageWnd* pImageWnd = new CImageWnd(pBMap); CRect rcWindow; m_ClipImageTab.GetWindowRect(&rcWindow); ScreenToClient(&rcWindow); m_ClipImageTab.AdjustRect(FALSE, &rcWindow); pImageWnd->Create(NULL, NULL, WS_CHILD, rcWindow, this, 0); tcItem.mask |= TCIF_PARAM; tcItem.lParam = (LPARAM)pImageWnd; m_ClipImageTab.SetItem(1, &tcItem);Get ROI information
Section titled “Get ROI information”The following section gets region references by using the get_References method, gets reference images by using the get_images method from the image collection, and crops the region rectangle from the image.
Section titled “The following section gets region references by using the get_References method, gets reference images by using the get_images method from the image collection, and crops the region rectangle from the image.” //ROI TAB CComPtr<IDocumentObjectReferences> PtrDocRef; HRESULT result = region->get_References(&PtrDocRef);//Get the References. if (SUCCEEDED(result) && PtrDocRef != NULL) { CComPtr<IDocumentObjectCollection> imageColection; CComPtr<IDocumentImage> pDocumentImage; result = PtrDocRef->get_Images(&imageColection);//Get the Image collection. long count = 0; result = imageColection->get_Count(&count);//Get the imagecollection count. if (SUCCEEDED(result) && imageColection != NULL) { CComPtr<IDispatch> imagePtr; result = imageColection->get_Item(0,&imagePtr);//Imageitem pointer if (SUCCEEDED(result)) { pDocumentImage = imagePtr; CComPtr<IBitmap> pBitmapROI; pDocumentImage->get_Bitmap(&pBitmapROI); //Get the bitmap Rectangle rect; region->get_Rectangle(&rect); CString strImageName = CString("ROI"); // Create ROI image tab. TCITEM tcItemROI = { 0 }; tcItemROI.mask = TCIF_TEXT; tcItemROI.pszText = strImageName.GetBuffer(); //Get the handle to the bitmap.. HBITMAP hBitmap2; if (pBitmapROI!=NULL && SUCCEEDED(pBitmapROI->GetHbitmap((long*)&hBitmap2))) { BITMAP bm; PAINTSTRUCT ps; HWND hwnd = GetDlgItem(IDC_CLIP_IMAGE_TAB)->m_hWnd; HDC hdc = ::BeginPaint(hwnd, &ps); HDC hdcMem = CreateCompatibleDC(hdc); HGDIOBJ hbmOld = SelectObject(hdcMem, hBitmap2); GetObject(hBitmap2, sizeof(bm), &bm); CImage image; image.Create(rect.Width, rect.Height, 32); HDC imageHDC = image.GetDC(); //Crop the region rectangle from the image and display it. ::SetStretchBltMode(imageHDC, HALFTONE); ::StretchBlt(imageHDC, 0, 0, rect.Width, rect.Height, hdcMem, rect.X, rect.Y, rect.Width, rect.Height, SRCCOPY | CAPTUREBLT); //Release image handels... image.ReleaseDC(); DeleteDC(hdcMem); DeleteDC(hdc); ::EndPaint(hwnd, &ps); // ROI tab . CImageWnd* pImageWndROI = new CImageWnd(pBitmapROI); CRect rcWindowROI; m_ClipImageTab.GetWindowRect(&rcWindowROI); ScreenToClient(&rcWindowROI); pImageWndROI = new CImageWnd(image); m_ClipImageTab.AdjustRect(FALSE, &rcWindowROI); pImageWndROI->Create(NULL, NULL, WS_CHILD, rcWindowROI, this, 0); tcItemROI.mask |= TCIF_PARAM; tcItemROI.lParam = ((LPARAM)pImageWndROI); m_ClipImageTab.SetItem(0, &tcItemROI); if (last_cure_sel != 1) { m_ClipImageTab.SetCurSel(0); pImageWndROI->ShowWindow(SW_SHOW); } //Release images. image.Destroy(); DeleteObject(hBitmap2); DeleteObject(hbmOld); } } }}Display ROI and RAW bitmap
Section titled “Display ROI and RAW bitmap”The ROI tab displays the cropped image. The RAW tab displays the raw bitmap.


OnDocumentImageTabSelChange event
Section titled “OnDocumentImageTabSelChange event”The OnDocumentImageTabSelChange event is fired when the user selects the ROI or RAW tab.
ON_NOTIFY(TCN_SELCHANGE, IDC_DOCUMENT_IMAGE_TAB, &CMainDialog::OnDocumentImageTabSelChange)/** * Handles when the currently selected tab has changed and displays the appropriate * document image. */void CMainDialog::OnDocumentImageTabSelChange(NMHDR *pNMHDR, LRESULT *pResult){int nIndex = m_ImageTabCtrl.GetCurSel(); for (int i = 0; i < m_ImageTabCtrl.GetItemCount(); i++) { TCITEM tcItem = { 0 }; tcItem.mask = TCIF_PARAM; m_ImageTabCtrl.GetItem(i, &tcItem); CImageWnd *pImageWnd = (CImageWnd*)tcItem.lParam; pImageWnd->ShowWindow((nIndex == i) ? SW_SHOW : SW_HIDE); DeleteObject(pImageWnd); }}Fields and Regions
Section titled “Fields and Regions”OnDocumentFieldChanged event
Section titled “OnDocumentFieldChanged event”The OnDocumentFieldChanged event is used to get all fields and images of the fields information.
DISP_FUNCTION_ID(CMainDialog, "DocumentFieldChanged", DISPID_DOCUMENTFIELDCHANGED, OnDocumentFieldChanged, VT_EMPTY, VTS_DISPATCH)/*** Handles the DocumentFieldChanged event. Populates the UI with the data from* the most recent Document transaction.*/void CMainDialog::OnDocumentFieldChanged(IDocumentFieldEventArgs *pArgs){ int itemCount = m_ListCtlFields.GetItemCount(); InsertField(pArgs, itemCount);}void CMainDialog::InsertField(IDocumentFieldEventArgs *pArgs,int index){ CComPtr<IDocumentField> pDocumentField; if (SUCCEEDED(pArgs->get_Field(&pDocumentField))) { CComBSTR bsName; pDocumentField->get_Name(&bsName); VARIANT bsValue; HRESULT hr = pDocumentField->get_Value(&bsValue); CComBSTR bsdescription; pDocumentField->get_Description(&bsdescription); DocumentDataSource bsdataSource; pDocumentField->get_DataSource(&bsdataSource); m_ListCtlFields.InsertItem(index, _T("")); m_ListCtlFields.SetItemText(index, 0, bsName); m_ListCtlFields.SetItemText(index, 1, GetValueAsString(bsValue)); m_ListCtlFields.SetItemText(index, 2, bsdescription); m_ListCtlFields.SetItemText(index, 3, ToDocumentDataSource(bsdataSource)); // Set Field ItemData if (pDocumentField != NULL) IUnknown* pUnk = NULL; HRESULT hr = pDocumentField->QueryInterface(IID_PPV_ARGS(&pUnk)); m_ListCtlFields.SetItemData(index, reinterpret_cast<DWORD_PTR> (pUnk)); DeleteObject(pUnk); } //=======UPDATE at the Boigraphic fields... if (bsName == _T("Full Name")) { m_NameStatic.SetWindowText(CString(bsValue)); } else if (bsName == _T("Sex")) { CString sexString = CString(bsValue); CString sex = CString(""); if (sexString.MakeLower().Find(_T("m")) >= 0) sex = "Male"; else if (sexString.MakeLower().Find(_T("f")) >= 0) sex = "Female"; m_Gender.SetWindowText(sex); } else if (bsName == _T("Expiration Date")) { if (IsValidDate(CString(bsValue))) m_ExpirationDate.SetWindowText(CString(bsValue)); } else if (bsName == _T("Birth Date")) { if (IsValidDate(CString(bsValue))) m_BirthDateStatic.SetWindowText(CString(bsValue)); } else if (bsName == _T("Issue Date")) { if (IsValidDate(CString(bsValue))) m_IssueDate.SetWindowText(CString(bsValue)); } else if (bsName == _T("Document Number")) { m_DocumentNumber.SetWindowText(CString(bsValue)); } }}Select ListCtlFields to display the selected field on the ROI and RAW tabs:
ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, &CMainDialog::onListFieldItemSelect)
ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, &CMainDialog::onListFieldItemSelect)
void CMainDialog::onListFieldItemSelect(NMHDR *pNMHDR, LRESULT *pResult){ int m_SelCount = m_ListCtlFields.GetSelectedCount(); if (m_SelCount == 1) { int dgvRow = -1; dgvRow = m_ListCtlFields.GetNextItem(dgvRow, LVNI_SELECTED); DWORD_PTR ptrItem = m_ListCtlFields.GetItemData(dgvRow); CString s_value = m_ListCtlFields.GetItemText(dgvRow,1); CString s_Name = m_ListCtlFields.GetItemText(dgvRow, 0); if (ptrItem == NULL) { RemoveAllClipImageTabs(); return; } //Get Field ItemData CComPtr<IDocumentField> pDocumentField = (IDocumentField*)ptrItem; CComPtr<IDocumentRegion> pDocumentRegion = getRegionFromField(pDocumentField); CComPtr<IDocumentRegion> region; region = (IDocumentRegion*)pDocumentRegion; if (region != NULL) { setRegion(region); } else { RemoveAllClipImageTabs(); } }}// Get Region From FieldCComPtr<IDocumentRegion> CMainDialog::getRegionFromField(CComPtr<IDocumentField> pDocumentField){CComPtr<IDocumentRegion> pDocumentRegion = getRegionFromFieldDirect(pDocumentField);if (pDocumentRegion != NULL) return pDocumentRegion; pDocumentRegion = getRegionFromFieldRecursive(pDocumentField); return pDocumentRegion;}// Get Region From Field DirectCComPtr<IDocumentRegion> CMainDialog::getRegionFromFieldDirect(CComPtr<IDocumentField> pDocumentField){ CComPtr<IDocumentRegion> pDocumentRegion = NULL; // Get field references CComPtr<IDocumentObjectReferences> PtrDocRef; HRESULT result = pDocumentField->get_References(&PtrDocRef); if (SUCCEEDED(result) && PtrDocRef != NULL) return getRegionFromReferences(PtrDocRef); return NULL;}//Get Region From Field RecursiveCComPtr<IDocumentRegion> CMainDialog::getRegionFromFieldRecursive(CComPtr<IDocumentField> pDocumentField){ CComPtr<IDocumentRegion> pDocumentRegion = NULL; // Get field references CComPtr<IDocumentObjectReferences> PtrDocRef; HRESULT result = pDocumentField->get_References(&PtrDocRef); if (SUCCEEDED(result) && PtrDocRef != NULL) { // Get all fields CComPtr<IDocumentObjectCollection> pDocumentObjectFields; result = PtrDocRef->get_Fields(&pDocumentObjectFields); if (SUCCEEDED(result) && pDocumentObjectFields != NULL) { long f_count = 0; pDocumentObjectFields->get_Count(&f_count); for (int iField = 0; iField < f_count; iField++) { CComPtr<IDispatch> fieldPtr; result = pDocumentObjectFields->get_Item(iField, &fieldPtr); if (fieldPtr != NULL) { CComPtr<IDocumentField> pDocumentFieldNext; pDocumentFieldNext = fieldPtr; pDocumentRegion = getRegionFromFieldDirect(pDocumentFieldNext); if (pDocumentRegion != NULL) return pDocumentRegion; pDocumentRegion = getRegionFromFieldRecursive(pDocumentFieldNext); if (pDocumentRegion != NULL) return pDocumentRegion; } } } } return NULL;}Alerts descriptions
Section titled “Alerts descriptions”
The OnDocumentAlertAdded event is used to get all Alerts information.
DISP_FUNCTION_ID(CMainDialog, "DocumentAlertAdded", DISPID_DOCUMENTALERTADDED, OnDocumentAlertAdded, VT_EMPTY, VTS_DISPATCH)void CMainDialog::OnDocumentAlertAdded(IDocumentAlertEventArgs *pArgs){ CComPtr<IDocumentAlert> pDocumentAlert; if (SUCCEEDED(pArgs->get_Alert(&pDocumentAlert))) { InsertAlert(pDocumentAlert); }}void CMainDialog::InsertAlert(CComPtr<IDocumentAlert> pDocumentAlert){ CComBSTR bsName; pDocumentAlert->get_Name(&bsName); CComBSTR bsdescription; pDocumentAlert->get_Description(&bsdescription); AuthenticationResult AuthoResult; pDocumentAlert->get_Result(&AuthoResult); int itemCount = m_AlertsList.GetItemCount(); m_AlertsList.InsertItem(itemCount, _T(""), static_cast<int>(AuthoResult)); m_AlertsList.SetImageList(&m_ImageList, LVSIL_SMALL); CComBSTR bsDisplayName; pDocumentAlert->get_DisplayName(&bsDisplayName); m_AlertsList.SetItemText(itemCount, 1, bsDisplayName); m_AlertsList.SetItemText(itemCount, 2, bsdescription); // Set Alert ItemData if (pDocumentAlert != NULL) { IUnknown* pUnk = NULL; HRESULT hr = pDocumentAlert->QueryInterface(IID_PPV_ARGS(&pUnk)); m_AlertsList.SetItemData(itemCount, reinterpret_cast<DWORD_PTR> (pUnk)); DeleteObject(pUnk); }}Select On Alert item from m_AlertsList
Section titled “Select On Alert item from m_AlertsList”The selected field is displayed on the ROI and RAW tabs.

ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST2, &CMainDialog::onListAlertItemSelect)void CMainDialog::onListAlertItemSelect(NMHDR *pNMHDR, LRESULT *pResult){int m_SelCount = m_AlertsList.GetSelectedCount();if (m_SelCount == 1){ int dgvRow = -1; dgvRow = m_AlertsList.GetNextItem(dgvRow, LVNI_SELECTED); DWORD_PTR ptrItem = m_AlertsList.GetItemData(dgvRow); CString s_value = m_AlertsList.GetItemText(dgvRow, 1); CString s_Name = m_AlertsList.GetItemText(dgvRow, 0); if (ptrItem == NULL) { RemoveAllClipImageTabs(); return; } //Get Alert ItemData CComPtr<IDocumentAlert> pDocumentAlert = (IDocumentAlert*)ptrItem; CComPtr<IDocumentRegion> pDocumentRegion = getRegionFromAlert(pDocumentAlert); CComPtr<IDocumentRegion> region; region = (IDocumentRegion*)pDocumentRegion; if (region != NULL) { setRegion(region); } else { RemoveAllClipImageTabs(); } }}CComPtr<IDocumentRegion> CMainDialog::getRegionFromAlert(CComPtr<IDocumentAlert> pDocumentAlert){ CComPtr<IDocumentRegion> pDocumentRegion = getRegionFromAlertDirect(pDocumentAlert); if (pDocumentRegion != NULL) return pDocumentRegion; pDocumentRegion = getRegionFromAlertRecursive(pDocumentAlert); return pDocumentRegion;}CComPtr<IDocumentRegion> CMainDialog::getRegionFromAlertDirect(CComPtr<IDocumentAlert> pDocumentAlert){ CComPtr<IDocumentRegion> pDocumentRegion = NULL; // Get field references CComPtr<IDocumentObjectReferences> PtrDocRef; HRESULT result = pDocumentAlert->get_References(&PtrDocRef); if (SUCCEEDED(result) && PtrDocRef != NULL) return getRegionFromReferences(PtrDocRef); return NULL;}CComPtr<IDocumentRegion> CMainDialog::getRegionFromAlertRecursive(CComPtr<IDocumentAlert> pDocumentAlert){ CComPtr<IDocumentRegion> pDocumentRegion = NULL; // Get alert references CComPtr<IDocumentObjectReferences> PtrDocRef; HRESULT result = pDocumentAlert->get_References(&PtrDocRef); if (SUCCEEDED(result) && PtrDocRef != NULL) { // Get all fields CComPtr<IDocumentObjectCollection> pDocumentObjectFields; result = PtrDocRef->get_Fields(&pDocumentObjectFields); if (SUCCEEDED(result) && pDocumentObjectFields != NULL) { long f_count = 0; pDocumentObjectFields->get_Count(&f_count); for (int iField = 0; iField < f_count; iField++) { CComPtr<IDispatch> fieldPtr; result = pDocumentObjectFields->get_Item(iField, &fieldPtr); if (fieldPtr != NULL) { CComPtr<IDocumentField> pDocumentFieldNext; pDocumentFieldNext = fieldPtr; pDocumentRegion = getRegionFromField(pDocumentFieldNext); if (pDocumentRegion != NULL) return pDocumentRegion; } } } } return NULL;}