// ltcdbView.cpp : implementation of the CLtcdbView class // #include "stdafx.h" #include "ltcdb.h" #include "ltcdbDoc.h" #include "ocdbView.h" #include "leadrasterview.h" #include "leadraster.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CLtcdbView IMPLEMENT_DYNCREATE(CLtcdbView, CDaoRecordView) BEGIN_MESSAGE_MAP(CLtcdbView, CDaoRecordView) //{{AFX_MSG_MAP(CLtcdbView) ON_BN_CLICKED(IDC_ADDNEW, OnAddnew) ON_BN_CLICKED(IDC_FLIP, OnFlip) ON_BN_CLICKED(IDC_DELETE, OnDelete) ON_BN_CLICKED(IDC_FINDFIRST, OnFindfirst) ON_BN_CLICKED(IDC_FINDNEXT, OnFindnext) ON_EN_SETFOCUS(IDC_SEARCHTEXT, OnSetfocusSearchtext) ON_WM_DESTROY() ON_WM_CLOSE() ON_UPDATE_COMMAND_UI(ID_RECORD_FIRST, OnUpdateRecordFirst) ON_UPDATE_COMMAND_UI(ID_RECORD_LAST, OnUpdateRecordLast) ON_UPDATE_COMMAND_UI(ID_RECORD_NEXT, OnUpdateRecordNext) ON_UPDATE_COMMAND_UI(ID_RECORD_PREV, OnUpdateRecordPrev) ON_MESSAGE(WM_DOREALIZE, OnDoRealize) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CLtcdbView construction/destruction CLtcdbView::CLtcdbView() : CDaoRecordView(CLtcdbView::IDD) { //{{AFX_DATA_INIT(CLtcdbView) m_pSet = NULL; //}}AFX_DATA_INIT //Instantiate the sink class and hold a pointer to it. } ///////////////////////////////////////////////////////////////////////////// CLtcdbView::~CLtcdbView() { } ///////////////////////////////////////////////////////////////////////////// void CLtcdbView::DoDataExchange(CDataExchange* pDX) { CDaoRecordView::DoDataExchange(pDX); //{{AFX_DATA_MAP(CLtcdbView) DDX_FieldText(pDX, IDC_Cwho, m_pSet->m_who, m_pSet); DDX_Control(pDX, IDC_LEADRASTERVIEW1, m_RasterView); //}}AFX_DATA_MAP CLtcdbApp * pTheApp = (CLtcdbApp * )AfxGetApp(); if ((NormalMove == TRUE) && (NewPosition != m_pSet->GetAbsolutePosition())) { OldPosition = NewPosition; NewPosition = m_pSet->GetAbsolutePosition(); pTheApp->m_pRasterODBC->dbMove(NewPosition - OldPosition); m_RasterView.ForceRepaint(); } } ///////////////////////////////////////////////////////////////////////////// BOOL CLtcdbView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs return CDaoRecordView::PreCreateWindow(cs); } ///////////////////////////////////////////////////////////////////////////// void CLtcdbView::Unlocksupport() { CLEADRaster LeadRaster = m_RasterView.GetRaster(); UNLOCKSUPPORT(LeadRaster); } void CLtcdbView::OnInitialUpdate() { CLtcdbApp * pTheApp = (CLtcdbApp * )AfxGetApp(); m_pSet = &GetDocument()->m_ltcdbSet; CDaoRecordView::OnInitialUpdate(); Unlocksupport(); // Turn off automatic scrolling and repainting m_RasterView.SetAutoScroll(FALSE); m_RasterView.SetBackErase(FALSE); m_RasterView.SetAutoRepaint(FALSE); m_pRasterODBCSink = new CRasterODBCSink; m_pRasterODBCSink->m_pView = this; LPUNKNOWN pUnkSink = m_pRasterODBCSink->GetIDispatch(FALSE); BOOL Conn= AfxConnectionAdvise(pTheApp->m_pRasterODBC, DIID__LEADRasterODBCEvents, pUnkSink, FALSE, &m_dwCookie); pTheApp->m_pRasterODBC->PutRaster((ILEADRaster *)m_RasterView.GetRaster().m_lpDispatch); InitAnnotation(); // IMPORTANT NOTE: // To keep things synchronized, edit the LTCDBSET.CPP and make sure the path // in CLtcdbSet::GetDefaultDBName() points to the real place of the // database file!. // Open the database. // Use the same SELECT statement that is used for the data control. // Note that the image field must be listed first in the SELECT statement. BOOL bRet = pTheApp->m_pRasterODBC->dbOpen("ODBC;DSN=LEADACCESS", "SELECT photo FROM people ORDER BY who", "photo", DB_OPENOPTIONS_NONE); if (pTheApp->m_pRasterODBC->dbRecordCount == 0) AfxMessageBox(TEXT("There are no records to show. Are you sure you set the ODBC source?")); // Set the database properties pTheApp->m_pRasterODBC->PutdbLoadBits(24); pTheApp->m_pRasterODBC->PutdbLockingMode(DB_LOCKINGMODE_OPTIMISTIC); // Enable use of the dbMove method in the data control's Reposition event NormalMove = TRUE; NewPosition = 0; } ///////////////////////////////////////////////////////////////////////////// // CLtcdbView diagnostics #ifdef _DEBUG void CLtcdbView::AssertValid() const { CDaoRecordView::AssertValid(); } ///////////////////////////////////////////////////////////////////////////// void CLtcdbView::Dump(CDumpContext& dc) const { CDaoRecordView::Dump(dc); } ///////////////////////////////////////////////////////////////////////////// CLtcdbDoc* CLtcdbView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CLtcdbDoc))); return (CLtcdbDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CLtcdbView database support CDaoRecordset* CLtcdbView::OnGetRecordset() { return m_pSet; } ///////////////////////////////////////////////////////////////////////////// // CLtcdbView message handlers BEGIN_EVENTSINK_MAP(CLtcdbView, CDaoRecordView) //{{AFX_EVENTSINK_MAP(CLtcdbView) ON_EVENT(CLtcdbView, IDC_LEADRASTERVIEW1, 1 /* Change */, OnChangeLeadrasterview1, VTS_I4 VTS_I4 VTS_I4) //}}AFX_EVENTSINK_MAP END_EVENTSINK_MAP() ///////////////////////////////////////////////////////////////////////////// void CLtcdbView::OnAddnew() { // Make sure we can add records to the database. if (!m_pSet->CanUpdate()) { MessageBox(TEXT("You cannot update this database."), TEXT("ERROR")); return; } // Get the name of the file to load. // This filter list is complete, except for GIF, which requires an LZW license. CString ImageFilter = "Graphics|*.cmp; *.jpg; *.jff; *.jtf; *.bmp; *.tif; *.tga; *.pcx; *.cal; *.mac; *.mac; *.img; *.msp; *.wpg; *.wpg; *.ras; *.pct; *.pcd; *.eps; *.wmf||"; CFileDialog OpenFile(TRUE, NULL, NULL,0,ImageFilter); if (OpenFile.DoModal() != IDOK) return; CLtcdbApp * pTheApp = (CLtcdbApp * )AfxGetApp(); CString MyFile = OpenFile.GetPathName(); int nRet = pTheApp->m_pRasterIO->Load(pTheApp->m_pRaster, MyFile.AllocSysString(), 0, 0, 1); if (nRet != 0) { CString csError; csError.Format(_T("Can not add this file, Error no = %d"), nRet); AfxMessageBox(csError); return; } CWaitCursor wait; // Display an hourglass // Disable the normal synchronization code and hide the LEAD control // while we manipulate the recordsets. NormalMove = FALSE; m_RasterView.ShowWindow(SW_HIDE); // Add a record to the DAO recordset. m_pSet->AddNew(); SetDlgItemText(IDC_Cwho, MyFile); UpdateData(); try { m_pSet->Update(); } catch (CDaoException* e) { AfxMessageBox(e->m_pErrorInfo->m_strDescription, MB_ICONEXCLAMATION); m_pSet->CancelUpdate(); UpdateData(FALSE); m_RasterView.ShowWindow(SW_NORMAL); NormalMove = TRUE; return; } // Requery the DAO recordset and wait for the change to take effect. m_pSet->Requery(); Sleep(5000); // Requery the LEAD recordset and make sure the recordsets match. pTheApp->m_pRasterODBC->dbRequery(); m_pSet->MoveFirst(); NewPosition = 0; m_pSet->MoveLast(); if (NewPosition != m_pSet->GetAbsolutePosition()) { OldPosition = NewPosition; NewPosition = m_pSet->GetAbsolutePosition(); pTheApp->m_pRasterODBC->dbMove(NewPosition - OldPosition); } if(pTheApp->m_pRasterODBC->dbCurrentRecord != m_pSet->GetAbsolutePosition()) { MessageBox(TEXT("Synchronization error!\nDelete the record and exit"), TEXT("ERROR"), MB_OK); m_pSet->FindFirst(CString("who = '") + MyFile + CString("'")); return; } // Find the record we just added and synchronize the recordsets. m_pSet->FindFirst(CString("who = '") + MyFile + CString("'")); if (NewPosition != m_pSet->GetAbsolutePosition()) { OldPosition = NewPosition; NewPosition = m_pSet->GetAbsolutePosition(); pTheApp->m_pRasterODBC->dbMove(NewPosition - OldPosition); } // Use return values to trap errors. BOOL ErrHand = pTheApp->m_pRasterODBC->GetEnableMethodErrors(); // Save the current setting. pTheApp->m_pRasterODBC->EnableMethodErrors = FALSE; // Redisplay the LEAD control, load the image, update the record, // and restore normal recordset synchronization. m_RasterView.ShowWindow(SW_NORMAL); pTheApp->m_pRasterODBC->dbEdit(); nRet = pTheApp->m_pRasterIO->Load(m_RasterView.GetRaster().m_lpDispatch, MyFile.AllocSysString(), 0, 0, 1); if (nRet != 0) { TCHAR buffer[50]; _stprintf(buffer, TEXT("LEAD Error %d loading image."), nRet); MessageBox(buffer, TEXT("ERROR"), MB_OK); } // Update the recordset using the appropriate format if (m_RasterView.GetRaster().GetBitmapBits() == 1) nRet = pTheApp->m_pRasterODBC->dbUpdate(FILE_LEAD1BIT, 1, 0); else if (m_RasterView.GetRaster().GetBitmapBits() == 4) nRet = pTheApp->m_pRasterODBC->dbUpdate(FILE_PCX, 4, 0); else if (m_RasterView.GetRaster().GetIsGrayscale() == GRAY_NO) nRet = pTheApp->m_pRasterODBC->dbUpdate(FILE_LEAD, 24, QFACTOR_QMS); else // save as grayscale nRet = pTheApp->m_pRasterODBC->dbUpdate(FILE_LEAD, 8, QFACTOR_QMS); if (nRet != 0) { TCHAR buffer[50]; _stprintf(buffer, TEXT("LEAD Error %d saving image to database"), nRet); MessageBox(buffer, TEXT("ERROR"), MB_OK); } // Restore previous error handling. pTheApp->m_pRasterODBC->EnableMethodErrors = ErrHand; NormalMove = TRUE; } ///////////////////////////////////////////////////////////////////////////// void CLtcdbView::OnFlip() { // Make sure we can update records in the database. CLtcdbApp * pTheApp = (CLtcdbApp * )AfxGetApp(); if ((!m_pSet->CanUpdate()) || (pTheApp->m_pRasterODBC->dbCanUpdate == FALSE)) { MessageBox(TEXT("You cannot update this database."), TEXT("ERROR")); return; } // Make sure the current record contains an image. if (pTheApp->m_pRasterODBC->dbIsEOF || pTheApp->m_pRasterODBC->dbIsBOF) { MessageBox(TEXT("No current image"), TEXT("NOTICE"), MB_OK); return; } // Flip the image pTheApp->m_pRasterODBC->dbEdit(); pTheApp->m_pRasterProcess->Flip(pTheApp->m_pRasterODBC->GetRaster()); m_RasterView.ForceRepaint(); // Use return values to trap errors. BOOL ErrHand = pTheApp->m_pRasterODBC->GetEnableMethodErrors(); // Save the current setting. pTheApp->m_pRasterODBC->PutEnableMethodErrors(FALSE); // in case the ann objects have changed, lets update the db with // the new objects long hAnn=pTheApp->m_pRasterAnn->GetAnnContainer(); pTheApp->m_pRasterODBC->PutAnnContainer(hAnn); // Update the recordset using the appropriate format int nRet; if (m_RasterView.GetRaster().GetBitmapBits() == 1) nRet = pTheApp->m_pRasterODBC->dbUpdate(FILE_LEAD1BIT, 1, 0); else if (m_RasterView.GetRaster().GetBitmapBits() == 4) nRet = pTheApp->m_pRasterODBC->dbUpdate(FILE_PCX, 4, 0); else if (m_RasterView.GetRaster().GetIsGrayscale() == GRAY_NO) nRet = pTheApp->m_pRasterODBC->dbUpdate(FILE_LEAD, 24, QFACTOR_QMS); else // save as grayscale nRet = pTheApp->m_pRasterODBC->dbUpdate(FILE_LEAD, 8, QFACTOR_QMS); if (nRet != 0) { TCHAR buffer[50]; _stprintf(buffer, TEXT("LEAD Error %d saving image to database"), nRet); MessageBox(buffer, TEXT("ERROR"), MB_OK); } // Restore previous error handling. pTheApp->m_pRasterODBC->PutEnableMethodErrors(ErrHand); } ///////////////////////////////////////////////////////////////////////////// void CLtcdbView::OnDelete() { CLtcdbApp * pTheApp = (CLtcdbApp * )AfxGetApp(); // Make sure we can delete records from the database. if (!m_pSet->CanUpdate()) { MessageBox(TEXT("You cannot update this database."), TEXT("ERROR")); return; } // Make sure the database is not empty. if (m_pSet->IsEOF() && m_pSet->IsBOF()) { MessageBox(TEXT("The database is empty"), TEXT("NOTICE"), MB_OK); return; } CWaitCursor wait; // Display an hourglass // Disable the normal record synchronization and hide the LEAD control. NormalMove = FALSE; m_RasterView.ShowWindow(SW_HIDE); // Save the current position. long RecMarker = m_pSet->GetAbsolutePosition(); // Delete the current record and wait for the change to take effect. m_pSet->Delete(); Sleep(5000); // Requery the recordsets, move to the last record, // and initialize the NewPosition global variable. m_pSet->Requery(); pTheApp->m_pRasterODBC->dbRequery(); try { m_pSet->MoveLast(); } catch (CDaoException* e) { m_RasterView.GetRaster().SetBitmap(0); AfxMessageBox(e->m_pErrorInfo->m_strDescription, MB_ICONEXCLAMATION); UpdateData(FALSE); m_RasterView.ShowWindow(SW_NORMAL); return; } NewPosition = m_pSet->GetAbsolutePosition(); pTheApp->m_pRasterODBC->dbMove(NewPosition); // Make sure the LEAD Raster View control is on the last record. pTheApp->m_pRasterODBC->dbMoveNext(); if (pTheApp->m_pRasterODBC->GetdbIsEOF()) pTheApp->m_pRasterODBC->dbMovePrev(); else { MessageBox(TEXT("Synchronization error!\nRestart the application"), TEXT("ERROR"), MB_OK); m_RasterView.ShowWindow(SW_NORMAL); return; } // Return to the old record position, if possible. NormalMove = TRUE; m_RasterView.ShowWindow(SW_NORMAL); long RelativePosition = RecMarker - NewPosition; if (RelativePosition < 0) { m_pSet->Move(RelativePosition); } // Update the edit box with data from the current record. UpdateData(FALSE); } ///////////////////////////////////////////////////////////////////////////// void CLtcdbView::OnFindfirst() { CString SearchString; GetDlgItemText(IDC_SEARCHTEXT,SearchString); if (m_pSet->FindFirst(CString("who Like '*") + SearchString + CString("*'"))) { // Generate a data exchange event to update the controls UpdateData(FALSE); // Switch the default button to Find Next SendDlgItemMessage(IDC_FINDFIRST, BM_SETSTYLE, BS_PUSHBUTTON, (LPARAM)TRUE); SendMessage(DM_SETDEFID, IDC_FINDNEXT, 0L); SendDlgItemMessage(IDC_FINDNEXT, BM_SETSTYLE, BS_DEFPUSHBUTTON, (LPARAM)TRUE); } else MessageBox(TEXT("Not found"), TEXT("Notice")); } ///////////////////////////////////////////////////////////////////////////// void CLtcdbView::OnFindnext() { CString SearchString; GetDlgItemText(IDC_SEARCHTEXT,SearchString); if (m_pSet->FindNext(CString("who Like '*") + SearchString + CString("*'"))) // Generate a data exchange event to update the controls UpdateData(FALSE); else MessageBox(TEXT("Not found"), TEXT("Notice")); } ///////////////////////////////////////////////////////////////////////////// void CLtcdbView::OnSetfocusSearchtext() { // Set the Find First button as the default button SendMessage(DM_SETDEFID, IDC_FINDFIRST, 0L); SendDlgItemMessage(IDC_FINDFIRST, BM_SETSTYLE, BS_DEFPUSHBUTTON, (LPARAM)TRUE); } ///////////////////////////////////////////////////////////////////////////// void CLtcdbView::OnDestroy() { CLtcdbApp * pTheApp = (CLtcdbApp * )AfxGetApp(); pTheApp->m_pRasterODBC->dbClose(); if (m_pSet) m_pSet->Close(); if (m_pRasterODBCSink) { m_pRasterODBCSink->m_pView = NULL; LPUNKNOWN pUnkSink = m_pRasterODBCSink->GetIDispatch(FALSE); BOOL Conn = AfxConnectionUnadvise(pTheApp->m_pRasterODBC, DIID__LEADRasterODBCEvents, pUnkSink, FALSE, m_dwCookie); pTheApp->m_pRasterODBC->Release(); delete m_pRasterODBCSink; } if (pTheApp->m_pRaster != NULL) pTheApp->m_pRaster->Release(); if (pTheApp->m_pRasterProcess != NULL) pTheApp->m_pRasterProcess->Release(); if (pTheApp->m_pRasterIO != NULL) pTheApp->m_pRasterIO->Release(); if (pTheApp->m_pRasterAnn != NULL) pTheApp->m_pRasterAnn->Release(); CDaoRecordView::OnDestroy(); } void CLtcdbView::InitAnnotation() { CLtcdbApp * pTheApp = (CLtcdbApp * )AfxGetApp(); CLEADRaster LTRas = m_RasterView.GetRaster(); short iRet = LTRas.CreateBitmap(1, 1, 1); LTRas.SetScaleMode(SCALEMODE_PIXEL); IDispatch *pDispatch=NULL; (m_RasterView.GetControlUnknown())->QueryInterface(IID_IDispatch, (void**)&pDispatch); pTheApp->m_pRasterAnn->PutAnnParentRasterView(pDispatch); pTheApp->m_pRasterODBC->PutAnnContainer(pTheApp->m_pRasterAnn->GetAnnContainer()); if(pDispatch) pDispatch->Release(); pTheApp->m_pRasterAnn->PutAnnUserMode(ANN_USERMODE_DESIGN); pTheApp->m_pRasterAnn->PutAnnTool(ANN_TOOL_SELECT); } void CLtcdbView::OnChangeLeadrasterview1(long nChange, long nReserved1, long nReserved2) { if (m_RasterView.GetRaster().GetBitmap() == 0) return; // Calculate the display rectangle to fit the image inside the control float DisplayTop; float DisplayHeight; float DisplayWidth; float DisplayLeft; float HeightAllowed = m_RasterView.GetScaleHeight(); float WidthAllowed = m_RasterView.GetScaleWidth(); float XProportion = m_RasterView.GetRaster().GetBitmapWidth(); float YProportion = m_RasterView.GetRaster().GetBitmapHeight(); // See if using the allowed height makes the image too wide. if ((HeightAllowed * XProportion / YProportion) <= WidthAllowed) { // Use the allowed height. DisplayTop = (float)0; DisplayHeight = HeightAllowed; DisplayWidth = DisplayHeight * XProportion / YProportion; DisplayLeft = (WidthAllowed - DisplayWidth) / 2; } else { // Use the allowed width. DisplayLeft = (float)0; DisplayWidth = WidthAllowed; DisplayHeight = DisplayWidth * YProportion / XProportion; DisplayTop = (HeightAllowed - DisplayHeight) / 2; } // Set the image display size m_RasterView.SetDstRect(DisplayLeft, DisplayTop, DisplayWidth, DisplayHeight); m_RasterView.SetDstClipRect(DisplayLeft, DisplayTop, DisplayWidth, DisplayHeight); m_RasterView.ForceRepaint(); } void CLtcdbView::OnUpdateRecordFirst(CCmdUI* pCmdUI) { CLtcdbApp * pTheApp = (CLtcdbApp * )AfxGetApp(); pCmdUI->Enable(pTheApp->m_pRasterODBC->dbRecordCount); } void CLtcdbView::OnUpdateRecordPrev(CCmdUI* pCmdUI) { CLtcdbApp * pTheApp = (CLtcdbApp * )AfxGetApp(); pCmdUI->Enable(pTheApp->m_pRasterODBC->dbRecordCount); } void CLtcdbView::OnUpdateRecordLast(CCmdUI* pCmdUI) { CLtcdbApp * pTheApp = (CLtcdbApp * )AfxGetApp(); pCmdUI->Enable(pTheApp->m_pRasterODBC->dbRecordCount); } void CLtcdbView::OnUpdateRecordNext(CCmdUI* pCmdUI) { CLtcdbApp * pTheApp = (CLtcdbApp * )AfxGetApp(); pCmdUI->Enable(pTheApp->m_pRasterODBC->dbRecordCount); } void CLtcdbView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView) { CDaoRecordView::OnActivateView(bActivate, pActivateView, pDeactiveView); CLtcdbApp * pTheApp = (CLtcdbApp * )AfxGetApp(); if (bActivate) { ASSERT(pActivateView == this); OnDoRealize((WPARAM)pTheApp->m_pMainWnd->m_hWnd, (LPARAM) FALSE); } } LRESULT CLtcdbView::OnDoRealize(WPARAM wParam, LPARAM lParam) { if( !IsWindow(m_RasterView.m_hWnd) || !m_RasterView.GetRaster().GetBitmap() ) return FALSE; if(lParam) { return m_RasterView.SendMessage(WM_PALETTECHANGED, wParam); } else { return m_RasterView.SendMessage(WM_QUERYNEWPALETTE,0); } }