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