// ltcdbView.cpp : implementation of the CLtcdbView class // #include "stdafx.h" #include "ltcdb.h" #include "ltcdbSet.h" #include "ltcdbDoc.h" #include "ocdbView.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif extern CLtcdbApp theApp; ///////////////////////////////////////////////////////////////////////////// // CLtcdbView IMPLEMENT_DYNCREATE(CLtcdbView, CDaoRecordView) BEGIN_MESSAGE_MAP(CLtcdbView, CDaoRecordView) //{{AFX_MSG_MAP(CLtcdbView) ON_MESSAGE(WM_DOREALIZE, OnDoRealize) ON_WM_DESTROY() 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) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CLtcdbView construction/destruction CLtcdbView::CLtcdbView() : CDaoRecordView(CLtcdbView::IDD) { //{{AFX_DATA_INIT(CLtcdbView) m_pSet = NULL; //}}AFX_DATA_INIT // TODO: add construction code here } 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_LEADCTRL1, m_Lead1); //}}AFX_DATA_MAP if ((NormalMove == TRUE) && (NewPosition != m_pSet->GetAbsolutePosition())) { OldPosition = NewPosition; NewPosition = m_pSet->GetAbsolutePosition(); m_Lead1.dbMove(NewPosition - OldPosition); m_Lead1.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::OnInitialUpdate() { m_pSet = &GetDocument()->m_ltcdbSet; CDaoRecordView::OnInitialUpdate(); // Turn off automatic scrolling and repainting UNLOCKSUPPORT(m_Lead1); // Unlock support for the LZW files and express capabilities m_Lead1.SetAutoScroll(FALSE); m_Lead1.SetAutoRepaint(FALSE); m_Lead1.SetPaintSizeMode (PAINTSIZEMODE_FIT); // 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. int nRet = m_Lead1.dbOpen("ODBC;DSN=LEADACCESS", "SELECT photo FROM people ORDER BY who", "photo", DB_OPENOPTIONS_NONE); // Set the LEAD control's database properties m_Lead1.SetDbLoadBits(24); m_Lead1.SetDbLockingMode(DB_LOCKINGMODE_OPTIMISTIC); m_Lead1.SetAnnTool(ANNTOOL_RECT); m_Lead1.SetAnnUserMode(ANNUSERMODE_DESIGN); // 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_LEADCTRL1, 6 /* Change */, OnChangeLeadctrl1, VTS_NONE) //}}AFX_EVENTSINK_MAP END_EVENTSINK_MAP() void CLtcdbView::OnChangeLeadctrl1() { // Avoid sizing images that are not loaded. if (m_Lead1.GetBitmap() == 0) { m_Lead1.ForceRepaint(); // So we can see when images are missing. return; } // Calculate the display rectangle to fit the image inside the control float HeightAllowed = m_Lead1.GetScaleHeight(); float WidthAllowed = m_Lead1.GetScaleWidth(); float XProportion = m_Lead1.GetBitmapWidth(); float YProportion = m_Lead1.GetBitmapHeight(); float DisplayTop; float DisplayHeight; float DisplayWidth; float DisplayLeft; // 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_Lead1.SetDstRect(DisplayLeft, DisplayTop, DisplayWidth, DisplayHeight); m_Lead1.SetDstClipRect(DisplayLeft, DisplayTop, DisplayWidth, DisplayHeight); m_Lead1.ForceRepaint(); } void CLtcdbView::OnDestroy() { if ( IsWindow(m_Lead1.m_hWnd) ) m_Lead1.dbClose(); CDaoRecordView::OnDestroy(); } void CLtcdbView::OnAddnew() { // Make sure we can add records to the database. if (!m_pSet->CanUpdate()) { MessageBox("You cannot update this database.", "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; CWaitCursor wait; // Display an hourglass CString MyFile = OpenFile.GetPathName(); // Disable the normal synchronization code and hide the LEAD control // while we manipulate the recordsets. NormalMove = FALSE; m_Lead1.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_Lead1.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. m_Lead1.dbRequery(); m_pSet->MoveFirst(); NewPosition = 0; m_pSet->MoveLast(); if (NewPosition != m_pSet->GetAbsolutePosition()) { OldPosition = NewPosition; NewPosition = m_pSet->GetAbsolutePosition(); m_Lead1.dbMove(NewPosition - OldPosition); m_Lead1.ForceRepaint(); } if(m_Lead1.GetDbCurrentRecord() != m_pSet->GetAbsolutePosition()) { MessageBox("Synchronization error!\nDelete the record and exit", "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(); m_Lead1.dbMove(NewPosition - OldPosition); m_Lead1.ForceRepaint(); } // Use return values to trap errors. BOOL ErrHand = m_Lead1.GetEnableMethodErrors(); // Save the current setting. m_Lead1.SetEnableMethodErrors(FALSE); // Redisplay the LEAD control, load the image, update the record, // and restore normal recordset synchronization. m_Lead1.ShowWindow(SW_NORMAL); m_Lead1.dbEdit(); int nRet = m_Lead1.Load(MyFile, 0, 0, 1); m_Lead1.SendMessage(WM_QUERYNEWPALETTE,0); if (nRet != 0) { char buffer[50]; sprintf(buffer, "LEAD Error %d loading image.", nRet); MessageBox(buffer, "ERROR", MB_OK); } // Update the recordset using the appropriate format if (m_Lead1.GetBitmapBits() == 1) nRet = m_Lead1.dbUpdate(FILE_LEAD1BIT, 1, 0); else if (m_Lead1.GetBitmapBits() == 4) nRet = m_Lead1.dbUpdate(FILE_PCX, 4, 0); else if (m_Lead1.GetIsGrayscale() == GRAY_NO) nRet = m_Lead1.dbUpdate(FILE_LEAD, 24, QFACTOR_QMS); else // save as grayscale nRet = m_Lead1.dbUpdate(FILE_LEAD, 8, QFACTOR_QMS); if (nRet != 0) { char buffer[50]; sprintf(buffer, "LEAD Error %d saving image to database", nRet); MessageBox(buffer, "ERROR", MB_OK); } // Restore previous error handling. m_Lead1.SetEnableMethodErrors(ErrHand); NormalMove = TRUE; } void CLtcdbView::OnFlip() { // Make sure we can update records in the database. if (m_Lead1.GetDbCanUpdate() == FALSE) { MessageBox("You cannot update this database.", "ERROR"); return; } // Make sure the current record contains an image. if (m_Lead1.GetDbIsEOF() || m_Lead1.GetDbIsBOF() || m_Lead1.GetBitmap() == 0) { MessageBox("No current image", "NOTICE", MB_OK); return; } // Flip the image. m_Lead1.dbEdit(); m_Lead1.Flip(); m_Lead1.ForceRepaint(); // Use return values to trap errors. BOOL ErrHand = m_Lead1.GetEnableMethodErrors(); // Save the current setting. m_Lead1.SetEnableMethodErrors(FALSE); // Update the recordset using the appropriate format int nRet; if (m_Lead1.GetBitmapBits() == 1) nRet = m_Lead1.dbUpdate(FILE_LEAD1BIT, 1, 0); else if (m_Lead1.GetBitmapBits() == 4) nRet = m_Lead1.dbUpdate(FILE_PCX, 4, 0); else if (m_Lead1.GetIsGrayscale() == GRAY_NO) nRet = m_Lead1.dbUpdate(FILE_LEAD, 24, QFACTOR_QMS); else // save as grayscale nRet = m_Lead1.dbUpdate(FILE_LEAD, 8, QFACTOR_QMS); if (nRet != 0) { char buffer[50]; sprintf(buffer, "LEAD Error %d saving image to database", nRet); MessageBox(buffer, "ERROR", MB_OK); } // Restore previous error handling. m_Lead1.SetEnableMethodErrors(ErrHand); } void CLtcdbView::OnDelete() { // Make sure we can delete records from the database. if (!m_pSet->CanUpdate()) { MessageBox("You cannot update this database.", "ERROR"); return; } // Make sure the database is not empty. if (m_pSet->IsEOF() && m_pSet->IsBOF()) { MessageBox("The database is empty", "NOTICE", MB_OK); return; } CWaitCursor wait; // Display an hourglass // Disable the normal record synchronization and hide the LEAD control. NormalMove = FALSE; m_Lead1.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(); m_Lead1.dbRequery(); if(!m_pSet->IsEOF()) m_pSet->MoveLast(); NewPosition = m_pSet->GetAbsolutePosition(); if(NewPosition >=0) { m_Lead1.dbMove(NewPosition); m_Lead1.ForceRepaint(); // Make sure the LEAD control is on the last record. m_Lead1.dbMoveNext(); m_Lead1.ForceRepaint(); if(m_Lead1.GetDbIsEOF()) { m_Lead1.dbMovePrev(); m_Lead1.ForceRepaint(); } else { int nRet = MessageBox("Synchronization error!\nRestart the application", "ERROR", MB_OK); return; } } // Return to the old record position, if possible. NormalMove = TRUE; m_Lead1.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("Not found", "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("Not found", "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); } LRESULT CLtcdbView::OnDoRealize(WPARAM wParam, LPARAM lParam) { if( !IsWindow(m_Lead1.m_hWnd) || !m_Lead1.GetBitmap() ) return FALSE; if(lParam) { return m_Lead1.SendMessage(WM_PALETTECHANGED, wParam); } else { return m_Lead1.SendMessage(WM_QUERYNEWPALETTE,0); } } void CLtcdbView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView) { CFormView::OnActivateView(bActivate, pActivateView, pDeactiveView); if (bActivate) { ASSERT(pActivateView == this); OnDoRealize((WPARAM)theApp.m_pMainWnd->m_hWnd, (LPARAM) FALSE); // same as SendMessage(WM_DOREALIZE); } }