home *** CD-ROM | disk | FTP | other *** search
/ Mastering MFC Development / MMD.ISO / labs / c09 / lab01 / ex02 / employeeview.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-20  |  8.2 KB  |  338 lines

  1. // EmployeeView.cpp : implementation of the CEmployeeView class
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "Employee.h"
  6.  
  7. #include "EmployeePaySet.h"
  8. #include "EmployeePersonalSet.h"
  9. #include "EmployeeDoc.h"
  10. #include "EmployeeView.h"
  11. #include "EmployeeDDX.cpp"
  12.  
  13. #ifdef _DEBUG
  14. #define new DEBUG_NEW
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18.  
  19. /////////////////////////////////////////////////////////////////////////////
  20. // CEmployeeView
  21.  
  22.  
  23. IMPLEMENT_DYNCREATE(CEmployeeView, CRecordView)
  24.  
  25. BEGIN_MESSAGE_MAP(CEmployeeView, CRecordView)
  26.     //{{AFX_MSG_MAP(CEmployeeView)
  27.     ON_COMMAND(ID_RECORD_ADD, OnRecordAdd)
  28.     ON_COMMAND(ID_RECORD_CLEAR, OnRecordClear)
  29.     ON_COMMAND(ID_RECORD_DELETE, OnRecordDelete)
  30.     ON_UPDATE_COMMAND_UI(ID_RECORD_ADD, OnUpdateRecordAdd)
  31.     ON_UPDATE_COMMAND_UI(ID_RECORD_DELETE, OnUpdateRecordDelete)
  32.     //}}AFX_MSG_MAP
  33. END_MESSAGE_MAP()
  34.  
  35. /////////////////////////////////////////////////////////////////////////////
  36. // CEmployeeView construction/destruction
  37.  
  38. CEmployeeView::CEmployeeView()
  39.     : CRecordView(CEmployeeView::IDD)
  40. {
  41.     //{{AFX_DATA_INIT(CEmployeeView)
  42.     m_pSet = NULL;
  43.     m_pEmplInfoSet = NULL;
  44.     //}}AFX_DATA_INIT
  45.     // TODO: add construction code here
  46. }
  47.  
  48. CEmployeeView::~CEmployeeView()
  49. {
  50. }
  51.  
  52. void CEmployeeView::DoDataExchange(CDataExchange* pDX)
  53. {
  54.     CRecordView::DoDataExchange(pDX);
  55.     //{{AFX_DATA_MAP(CEmployeeView)
  56.     DDX_FieldText(pDX, IDC_FNAME, m_pSet->m_First_Name, m_pSet);
  57.     DDX_FieldText(pDX, IDC_LNAME, m_pSet->m_Last_Name, m_pSet);
  58.     DDX_FieldText(pDX, IDC_EMP_NO, m_pSet->m_Employee_Number, m_pSet);
  59.     DDX_FieldText(pDX, IDC_DEPT, m_pSet->m_Department__, m_pSet);
  60.     DDX_FieldText(pDX, IDC_PAY_TYPE, m_pSet->m_Employee_Pay_Type, m_pSet);
  61.     DDX_FieldText(pDX, IDC_HOUR_RATE, m_pSet->m_Hourly_Rate, m_pSet);
  62.     //}}AFX_DATA_MAP
  63.     
  64.     //Ensure pointer is valid
  65.     if ( NULL != m_pEmplInfoSet )
  66.     {
  67.         DDX_FieldText(pDX, IDC_BIRTH, m_pEmplInfoSet->m_Birthdate, m_pEmplInfoSet);
  68.         DDV_Date( pDX, m_pEmplInfoSet->m_Birthdate, m_pEmplInfoSet );
  69.         DDX_FieldText(pDX, IDC_MARITAL_STATUS, m_pEmplInfoSet->m_Sex___Marital_Status, m_pEmplInfoSet);
  70.         DDX_FieldText(pDX, IDC_HEIGHT, m_pEmplInfoSet->m_Height, m_pEmplInfoSet);
  71.         DDX_FieldText(pDX, IDC_WEIGHT, m_pEmplInfoSet->m_Weight, m_pEmplInfoSet);
  72.     }
  73. }
  74.  
  75. BOOL CEmployeeView::PreCreateWindow(CREATESTRUCT& cs)
  76. {
  77.     return CRecordView::PreCreateWindow(cs);
  78. }
  79.  
  80. void CEmployeeView::OnInitialUpdate()
  81. {
  82.     // AppWizard provided this line. 
  83.     // m_pSet = &GetDocument( )->m_employeePaySet;
  84.  
  85.     // Best to replace it with an accessor function.
  86.     m_pSet = GetDocument( )->GetEmployeePaySet( );
  87.  
  88.     m_pEmplInfoSet = GetDocument( )->GetEmployeeInfoSet( );
  89.     GetParentFrame( )->RecalcLayout( );
  90.     ResizeParentToFit( FALSE );
  91.  
  92.     try
  93.     {
  94.         //Open the primary table
  95.         m_pSet->Open( );    
  96.         m_pEmplInfoSet->m_EmployeeNumberParam 
  97.             = m_pSet->m_Employee_Number;    //Set join param
  98.         //Open foreign table
  99.         m_pEmplInfoSet->Open( );    
  100.     }
  101.     catch( CException * pEx )
  102.     {
  103.         pEx->ReportError( );
  104.         pEx->Delete( );
  105.         return;
  106.     }
  107.  
  108.     UpdateData( FALSE );
  109.     SetAddMode( FALSE );
  110.  
  111.     CRecordView::OnInitialUpdate( );
  112. }
  113.  
  114. /////////////////////////////////////////////////////////////////////////////
  115. // CEmployeeView diagnostics
  116.  
  117. #ifdef _DEBUG
  118. void CEmployeeView::AssertValid() const
  119. {
  120.     CRecordView::AssertValid();
  121. }
  122.  
  123. void CEmployeeView::Dump(CDumpContext& dc) const
  124. {
  125.     CRecordView::Dump(dc);
  126. }
  127.  
  128. CEmployeeDoc* CEmployeeView::GetDocument() // non-debug version is inline
  129. {
  130.     ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CEmployeeDoc)));
  131.     return (CEmployeeDoc*)m_pDocument;
  132. }
  133. #endif //_DEBUG
  134.  
  135. /////////////////////////////////////////////////////////////////////////////
  136. // CEmployeeView database support
  137. CRecordset* CEmployeeView::OnGetRecordset()
  138. {
  139.     return m_pSet;
  140. }
  141.  
  142.  
  143. /////////////////////////////////////////////////////////////////////////////
  144. // CEmployeeView message handlers
  145.  
  146. BOOL CEmployeeView::OnMove(UINT nIDMoveCommand) 
  147. {
  148.     if ( IsAddMode( ) )
  149.         AddRecordCancel( );
  150.  
  151.     if ( ! UpdateData( TRUE ) )
  152.         return FALSE;    //Bad data: We don't want to move
  153.     
  154.     m_pSet->SetFieldDirty( NULL );    //Otherwise DB update won't occur
  155.     
  156.     BOOL bMove = CRecordView::OnMove(nIDMoveCommand);    //Primary table updated
  157.  
  158.     if ( bMove )    //If successful update the foreign info
  159.     {
  160.         m_pEmplInfoSet->Edit( );                //Turn on edit mode
  161.         m_pEmplInfoSet->SetFieldDirty( NULL );    //Mark the fields dirty
  162.         m_pEmplInfoSet->Update( );
  163.         m_pEmplInfoSet->m_EmployeeNumberParam = 
  164.             m_pSet->m_Employee_Number;
  165.         m_pEmplInfoSet->Requery( );        //Find foreign record
  166.         UpdateData( FALSE );            //Display foreign record
  167.     }
  168.     return bMove;
  169. }
  170.  
  171. void CEmployeeView::OnRecordAdd() 
  172. {
  173.     CDatabase * pDB = m_pSet->m_pDatabase;
  174.     BOOL bTrans = pDB->CanTransact( );
  175.  
  176.     if ( UpdateData( TRUE ) )    //Scrape the screen data into memory
  177.         try
  178.         {
  179.             m_pEmplInfoSet->m_Employee_Number = 
  180.                 m_pSet->m_Employee_Number;    //Update the foreign table emp num
  181.             m_pSet->Update( );
  182.             m_pEmplInfoSet->Update( );
  183.             if ( bTrans )
  184.             {
  185.                 BOOL bCommitOk = pDB->CommitTrans( );
  186.                 if ( ! bCommitOk ||
  187.                         SQL_CB_PRESERVE != pDB->GetCursorCommitBehavior( ) ) //See TN068
  188.                 {
  189.                     m_pSet->Close( );
  190.                     m_pEmplInfoSet->Close( );
  191.                     m_pSet->Open( );
  192.                     m_pEmplInfoSet->Open( );
  193.                 }
  194.             }
  195.             SetAddMode( FALSE );
  196.             OnRecordClear( );    //Set up to add the next record
  197.         }    //End try
  198.     
  199.     catch ( CDBException * pEx )
  200.     {
  201.         pEx->ReportError( );
  202.         pEx->Delete( );
  203.         if ( bTrans )
  204.         {
  205.             pDB->Rollback( );
  206.             
  207.             m_pSet->Close( );    //Assume worst case
  208.             m_pEmplInfoSet->Close( );
  209.             
  210.             pDB->BeginTrans( );    //Start trans, again
  211.             m_pSet->Open( );
  212.             m_pEmplInfoSet->Open( );
  213.             
  214.             m_pSet->AddNew( );
  215.             m_pEmplInfoSet->AddNew( );
  216.         }    //End if bTrans
  217.     }    //End catch
  218. }
  219.  
  220. void CEmployeeView::OnRecordClear( ) 
  221. {
  222.     CDatabase * pDB = m_pSet->m_pDatabase;
  223.  
  224.     //Cannot transact across multiple databases
  225.     ASSERT ( m_pEmplInfoSet->m_pDatabase == pDB );
  226.     
  227.     if ( IsAddMode( ) )
  228.     {
  229.         m_pSet->CancelUpdate( );
  230.         m_pEmplInfoSet->CancelUpdate( );
  231.     }
  232.     else if ( pDB->CanTransact( ) )
  233.     {
  234.         if ( SQL_CB_PRESERVE == pDB->GetCursorCommitBehavior( ) ) //See TN068
  235.             pDB->BeginTrans( );
  236.         else    //Cannot have an open recordset to start transaction
  237.         {
  238.             m_pSet->Close( );
  239.             m_pEmplInfoSet->Close( );
  240.             pDB->BeginTrans( );
  241.             m_pSet->Open( );
  242.             m_pEmplInfoSet->Open( );
  243.         }
  244.     }    //End can transact
  245.     m_pSet->AddNew( );
  246.     m_pEmplInfoSet->AddNew( );
  247.     SetAddMode( );
  248.     UpdateData( FALSE );
  249. }
  250.  
  251. void CEmployeeView::OnRecordDelete() 
  252. {
  253.     CDatabase * pDB = m_pSet->m_pDatabase;
  254.     BOOL bTrans = 
  255.         m_pSet->CanTransact( );
  256.     if ( bTrans  )
  257.         pDB->BeginTrans( );
  258.     try
  259.     {
  260.         m_pEmplInfoSet->Delete( );
  261.         m_pSet->Delete( );
  262.         if ( bTrans )
  263.             pDB->CommitTrans( );
  264.     }
  265.     catch( CDBException * pEx )
  266.     {
  267.         pEx->ReportError( );
  268.         pEx->Delete( );
  269.         if ( bTrans )
  270.             pDB->Rollback( );
  271.     }    //End catch
  272.  
  273.     m_pSet->Close( );    //Assume minimal ODBC support
  274.     m_pEmplInfoSet->Close( );
  275.     m_pSet->Open( );
  276.     m_pEmplInfoSet->Open( );
  277.  
  278.     m_pSet->Requery( );    //Get a record
  279.     m_pEmplInfoSet->m_EmployeeNumberParam = m_pSet->m_Employee_Number;
  280.     m_pEmplInfoSet->Requery( );    //Get related data
  281.     UpdateData( FALSE );    //Show the data
  282. }
  283.  
  284. void CEmployeeView::OnUpdateRecordAdd(CCmdUI* pCmdUI) 
  285. {
  286.     pCmdUI->Enable( IsAddMode( ) ); 
  287. }
  288.  
  289. void CEmployeeView::OnUpdateRecordDelete(CCmdUI* pCmdUI) 
  290. {
  291.     pCmdUI->Enable( ! IsAddMode( ) );    
  292. }
  293.  
  294. void CEmployeeView::SetAddMode( BOOL bAddMode)
  295. {
  296.     m_bAddMode = bAddMode;
  297.     CEdit * pField = ( CEdit * ) GetDlgItem( IDC_EMP_NO );
  298.     pField->SetReadOnly( ! bAddMode );
  299.     if ( bAddMode )
  300.     {
  301.         pField = ( CEdit * ) GetDlgItem( IDC_FNAME );
  302.         pField->SetFocus( );
  303.     }
  304. }
  305.  
  306. BOOL CEmployeeView::IsAddMode()
  307. {
  308.     return m_bAddMode;
  309. }
  310.  
  311. void CEmployeeView::AddRecordCancel()
  312. {
  313.     if ( ! IsAddMode( ) )
  314.         return;
  315.     SetAddMode( FALSE );
  316.     m_pSet->CancelUpdate( );
  317.     m_pEmplInfoSet->CancelUpdate( );
  318.  
  319.     CDatabase * pDB = m_pSet->m_pDatabase;
  320.     if ( pDB->CanTransact( ) )
  321.     {
  322.         pDB->Rollback( );
  323.         if ( SQL_CB_DELETE == pDB->GetCursorRollbackBehavior( ) )
  324.         {
  325.             m_pSet->Close( );
  326.             m_pEmplInfoSet->Close( );
  327.             m_pSet->Open( );
  328.             m_pEmplInfoSet->Open( );
  329.         }
  330.         m_pSet->Requery( );
  331.         m_pEmplInfoSet->m_EmployeeNumberParam =
  332.             m_pSet->m_Employee_Number;
  333.         m_pEmplInfoSet->Requery( );
  334.     }
  335.     UpdateData( FALSE );
  336. }
  337.  
  338.