Teach Yourself Visual C++ 6 in 21 Days phần 9 pot

80 272 0
Teach Yourself Visual C++ 6 in 21 Days phần 9 pot

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Answers 621 B Exercise Add a menu entry and dialog to let the user indicate the record number to move to, and then move to that record. 1. Create a new dialog, designing the dialog layout as in Figure B.1. Configure the controls as in Table B.4. TABLE B.4. DIALOG PROPERTY SETTINGS. Object Property Setting Static Text ID IDC_STATIC Caption Move to record: Edit Box ID IDC_ERECNBR 2. Open the Class Wizard. Create a new class for the new dialog. Give the new class the name CMoveToDlg. After you create the new class, add a variable to the Edit Box control. Specify the variable type as long and the name as m_lRowNbr. 3. Add another menu entry to the main application menu. Specify the menu properties as in Table B.5. FIGURE B.1. The Move To dialog layout. 030 31240-9 APP B 4/27/00 1:07 PM Page 621 TABLE B.5. MENU PROPERTY SETTINGS. Object Property Setting Menu Entry ID IDM_RECORD_MOVE Caption &Move To Prompt Move to a specific record\nMove To 4. Open the Class Wizard and add an event-handler function for the COMMAND message for this new menu to the view class. Edit this function, adding the code in Listing B.25. LISTING B.25. THE CDbOdbcView OnRecordMove FUNCTION. 1: void CTestdb5View::OnRecordMove() 2: { 3: // TODO: Add your command handler code here 4: // Create an instance of the Move To dialog 5: CMoveToDlg dlgMoveTo; 6: // Get the row number to move to 7: if (dlgMoveTo.DoModal() == IDOK) 8: { 9: // Get a pointer to the record set 10: CRecordset* pSet = OnGetRecordset(); 11: // Make sure that there are no outstanding changes to be saved 12: if (pSet->CanUpdate() && !pSet->IsDeleted()) 13: { 14: pSet->Edit(); 15: if (!UpdateData()) 16: return; 17: 18: pSet->Update(); 19: } 20: // Set the new position 21: pSet->SetAbsolutePosition(dlgMoveTo.m_lRowNbr); 22: // Update the form 23: UpdateData(FALSE); 24: } 25: } 5. Include the header file for the new dialog in the view class source code, as in line 10 of Listing B.26. 622 Appendix B 030 31240-9 APP B 4/27/00 1:07 PM Page 622 Answers 623 B LISTING B.26. THE CDbOdbcView INCLUDES. 1: // DbOdbcView.cpp : implementation of the CDbOdbcView class 2: // 3: 4: #include “stdafx.h” 5: #include “DbOdbc.h” 6: 7: #include “DbOdbcSet.h” 8: #include “DbOdbcDoc.h” 9: #include “DbOdbcView.h” 10: #include “MoveToDlg.h” 6. Add a toolbar button for the new menu entry. Day 15 Quiz 1. What does ADO stand for? ActiveX Data Objects. 2. What does ADO use for database access? OLE DB. 3. What are the objects in ADO? Connection, Command, Parameter, Error, Recordset, and Field. 4. How do you initialize the COM environment? ::CoInitialize(NULL); 5. How do you associate a Connection object with a Command object? pCmd->ActiveConnection = pConn; 6. How do you associate a Command object with and populate a Recordset object? One of two ways: _RecordsetPtr pRs; pRs = pCmd->Execute(); Or _RecordsetPtr pRs; pRs.CreateInstance(__uuidof(Recordset)); pRs->PutRefSource(pCmd); 030 31240-9 APP B 4/27/00 1:07 PM Page 623 Exercise Enable and disable the navigation menus and toolbar buttons based on whether the recordset is at the beginning of file (BOF) or end of file (EOF, renamed to EndOfFile). Add event-handler functions to the document class for the navigation menu entries’ UPDATE_COMMAND_UI event message. Edit these functions, adding the code in Listing B.27 to the functions for the First and Previous menus, and the code in Listing B.28 to the functions for the Last and Next menus. LISTING B.27. THE CDbAdoDoc OnUpdateDataFirst FUNCTION. 1: void CDbAdoDoc::OnUpdateDataFirst(CCmdUI* pCmdUI) 2: { 3: // TODO: Add your command update UI handler code here 4: // Does the record set exist? 5: if (m_pRs) 6: { 7: // Are we at the BOF? 8: if (m_pRs->BOF) 9: pCmdUI->Enable(FALSE); 10: else 11: pCmdUI->Enable(TRUE); 12: } 13: } LISTING B.28. THE CDbAdoDoc OnUpdateDataLast FUNCTION. 1: void CDbAdoDoc::OnUpdateDataLast(CCmdUI* pCmdUI) 2: { 3: // TODO: Add your command update UI handler code here 4: // Does the record set exist? 5: if (m_pRs) 6: { 7: // Are we at the EOF? 8: if (m_pRs->EndOfFile) 9: pCmdUI->Enable(FALSE); 10: else 11: pCmdUI->Enable(TRUE); 12: } 13: } 624 Appendix B 030 31240-9 APP B 4/27/00 1:07 PM Page 624 Answers 625 B Day 16 Quiz 1. When do you want to create a new MFC class? When you need to create a new class that is inherited from an existing MFC class. 2. When you make changes to a library file, what do you have to do to the applica- tions that use the library file? They all have to be relinked. 3. What are the different types of classes that you can create? MFC, generic, and form. 4. When you package some functionality in a library file, what do you need to give to other programmers who want to use your library module? The LIB library file and the header files for the objects in the module. 5. What are two of the basic principles in object-oriented software design? Encapsulation and inheritance. The third principle is polymorphism, which was not discussed today. Exercises Separate the CLine class into a different library module from the drawing class so that you have two library modules instead of one. Link them into the test application. 1. Create a new project. Specify that the project is a Win32 Static Library project. Give the project a suitable name, such as Line. 2. Specify that the project contain support for MFC and precompiled headers. 3. Copy the Line.cpp and Line.h files into the project directory. Add both of these files to the project. Compile the library module. 4. Open the original library module project. Delete the Line.cpp and Line.h files from the project. Edit the include statement at the top of the drawing object source- code file to include the Line.h file from the Line module project directory, as on line 9 of Listing B.29. Recompile the project. LISTING B.29. THE CModArt INCLUDES AND COLOR TABLE. 1: // ModArt.cpp: implementation of the CModArt class. 2: // 3: ////////////////////////////////////////////////////////////////////// 4: continues 030 31240-9 APP B 4/27/00 1:07 PM Page 625 LISTING B.29. CONTINUED 5: #include <stdlib.h> 6: #include <time.h> 7: 8: #include “stdafx.h” 9: #include “ \Line\Line.h” 10: #include “ModArt.h” 5. Open the test application project. Add the Line library file to the project. Build the project. Day 17 Quiz 1. What kind of DLL do you have to create to make classes in the DLL available to applications? An MFC extension DLL. 2. What do you have to add to the class to export it from a DLL? The AFX_EXT_CLASS macro in the class declaration. 3. What kind of DLL can be used with other programming languages? A regular DLL. 4. If you make changes in a DLL, do you have to recompile the applications that use the DLL? Normally, no. Only if changes were made in the exported interface for the DLL do you need to recompile the applications that use the DLL. 5. What function does the LIB file provide for a DLL? The LIB file contains stubs of the functions in the DLL, along with the code to locate and pass the function call along to the real function in the DLL. Exercises 1. Separate the line class into its own MFC extension DLL and use it with the second (regular) DLL. Create a new project. Specify that the project is an AppWizard (DLL) project, and give the project a suitable name, such as LineDll. Specify that the DLL will be an MFC extension DLL. 626 Appendix B 030 31240-9 APP B 4/27/00 1:07 PM Page 626 Answers 627 B After generating the project skeleton, copy the line source code and header files into the project directory. Add these files into the project. Edit the CLine class declaration, adding the AFX_EXT_CLASS macro to the class dec- laration. Compile the DLL. Copy the DLL into the debug directory for the test application. Open the regular DLL project. Delete the line source code and header files from the project in the File View of the workspace pane. Add the line DLL LIB file to the project. Edit the drawing functionality source-code file, changing the line class header include to include the version in the CLine DLL project directory, as in Listing B.30. LISTING B.30. THE CModArt INCLUDES. 1: // ModArt.cpp: implementation of the CModArt class. 2: // 3: ///////////////////////////////////////////////////////////////////// 4: 5: #include <stdlib.h> 6: #include <time.h> 7: 8: #include “stdafx.h” 9: #include “ \LineDll\Line.h” 10: #include “ModArt.h” Compile the project. Copy the DLL into the test application project debug directory. Run the test application. 2. Alter the line class DLL so that it uses a consistent line width for all lines. Open the line class DLL project that you created in the previous exercise. Edit the class constructor, replacing the initialization of the m_nWidth variable with a con- stant value, as in Listing B.31. LISTING B.31. THE CLine CONSTRUCTOR. 1: CLine::CLine(CPoint ptFrom, CPoint ptTo, UINT nWidth, COLORREF crColor) 2: { 3: m_ptFrom = ptFrom; 4: m_ptTo = ptTo; 5: m_nWidth = 1; 6: m_crColor = crColor; 7: } 030 31240-9 APP B 4/27/00 1:07 PM Page 627 Compile the DLL. Copy the DLL into the test application project debug directory. Run the test application. Day 18 Quiz 1. When is the OnIdle function called? When the application is idle and there are no messages in the application message queue. 2. How can you cause the OnIdle function to be repeatedly called while the applica- tion is sitting idle? Returning a value of TRUE will cause the OnIdle function to continue to be called as long as the application remains idle. 3. What is the difference between an OnIdle task and a thread? An OnIdle task executes only when the application is idle and there are no mes- sages in the message queue. A thread executes independently of the rest of the application. 4. What are the four thread synchronization objects? Critical sections, mutexes, semaphores, and events. 5. Why shouldn’t you specify a higher than normal priority for the threads in your application? The rest of the threads and processes running on the computer will receive a greatly reduced amount of processor time. Exercises 1. If you open a performance monitor on your system while the application that you built today is running, you’ll find that even without any of the threads running, the processor usage remains 100 percent, as in Figure 18.11. The OnIdle function is continuously being called even when there is nothing to be done. Modify the OnIdle function so that if there’s nothing to be done, neither of the OnIdle tasks are active. Then, the OnIdle function will not continue to be called until one of these threads is active, at which time it should be continuously called until both threads are once again turned off. This will allow the processor to drop to a minimal utilization, as in Figure 18.12. Edit the OnIdle function as in Listing B.32. 628 Appendix B 030 31240-9 APP B 4/27/00 1:07 PM Page 628 Answers 629 B LISTING B.32. THE MODIFIED CTaskingApp OnIdle FUNCTION. 1: BOOL CTaskingApp::OnIdle(LONG lCount) 2: { 3: // TODO: Add your specialized code here and/or call the base class 4: 5: // Call the ancestor’s idle processing 6: BOOL bRtn = CWinApp::OnIdle(lCount); 7: 8: // Get the position of the first document template 9: POSITION pos = GetFirstDocTemplatePosition(); 10: // Do we have a valid template position? 11: if (pos) 12: { 13: // Get a pointer to the document template 14: CDocTemplate* pDocTemp = GetNextDocTemplate(pos); 15: // Do we have a valid pointer? 16: if (pDocTemp) 17: { 18: // Get the position of the first document 19: POSITION dPos = pDocTemp->GetFirstDocPosition(); 20: // Do we have a valid document position? 21: if (dPos) 22: { 23: // Get a pointer to the document 24: CTaskingDoc* pDocWnd = 25: (CTaskingDoc*)pDocTemp->GetNextDoc(dPos); 26: // Do we have a valid pointer? 27: if (pDocWnd) 28: { 29: // Get the position of the view 30: POSITION vPos = pDocWnd->GetFirstViewPosition(); 31: // Do we have a valid view position? 32: if (vPos) 33: { 34: // Get a pointer to the view 35: CTaskingView* pView = ➥(CTaskingView*)pDocWnd->GetNextView(vPos); 36: // Do we have a valid pointer? 37: if (pView) 38: { 39: // Should we spin the first idle thread? 40: if (pView->m_bOnIdle1) 41: { 42: // Spin the first idle thread 43: pDocWnd->DoSpin(0); 44: bRtn = TRUE; 45: } 46: // Should we spin the second idle thread? 47: if (pView->m_bOnIdle2) continues 030 31240-9 APP B 4/27/00 1:07 PM Page 629 LISTING B.32. CONTINUED 48: { 49: // Spin the second idle thread 50: pDocWnd->DoSpin(2); 51: bRtn = TRUE; 52: } 53: } 54: } 55: } 56: } 57: } 58: } 59: return bRtn; 60: } 2. When starting the independent threads, give one of the threads a priority of THREAD_PRIORITY_NORMAL and the other a priority of THREAD_PRIORITY_LOWEST. Edit the SuspendSpinner function as in Listing B.33. LISTING B.33. THE MODIFIED CTaskingDoc SuspendSpinner FUNCTION. 1: void CTaskingDoc::SuspendSpinner(int nIndex, BOOL bSuspend) 2: { 3: // if suspending the thread 4: if (!bSuspend) 5: { 6: // Is the pointer for the thread valid? 7: if (m_pSpinThread[nIndex]) 8: { 9: // Get the handle for the thread 10: HANDLE hThread = m_pSpinThread[nIndex]->m_hThread; 11: // Wait for the thread to die 12: ::WaitForSingleObject (hThread, INFINITE); 13: } 14: } 15: else // We are running the thread 16: { 17: int iSpnr; 18: int iPriority; 19: // Which spinner to use? 20: switch (nIndex) 21: { 22: case 0: 23: iSpnr = 1; 24: iPriority = THREAD_PRIORITY_NORMAL; 25: break; 26: case 1: 27: iSpnr = 3; 28: iPriority = THREAD_PRIORITY_LOWEST; 630 Appendix B 030 31240-9 APP B 4/27/00 1:07 PM Page 630 [...]... screen display LISTING C.1 LST23_1.CPP—DRAWING 1: 2: 3: 4: 5: IN OnDraw TO PRODUCE A PRINT SAMPLE void CPrintItView::OnDraw(CDC* pDC) { CPrintItDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); 031 31240 -9 APP C 4/27/00 1:07 PM Page 63 9 Printing and Print Previewing 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42:... C .6 LST23 _6. CPP—VALIDATING THE STANDARD PRINT DIALOG BOX FOR A SPECIFIC NUMBER OF COPIES 1: 2: 3: 4: BOOL CPrintItView::OnPreparePrinting(CPrintInfo* pInfo) { pInfo->SetMinPage(1); pInfo->SetMaxPage(10); continues C 031 31240 -9 APP C 4/27/00 1:08 PM 65 4 Page 65 4 Appendix C LISTING C .6 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: pInfo->m_pPD->m_pd.nCopies = 3; do { // ** Check if user has cancelled print if (DoPreparePrinting(pInfo)... Previewing BYPASSING THE 64 9 PRINT DIALOG BOX WHEN PRINTING You don’t always need to bother the user with the Print dialog box; this can be bypassed by setting the pInfo->m_bDirect variable to TRUE in OnPreparePrinting() To emphasize the difference between a full report and a window print, you can implement a completely different drawing in the OnPrint() function than OnDraw(), as shown in Listing C.4 In. .. created at line 13 and used to draw the sample text at line 61 Lines 40 to 50 draw the arty “peg and string” frame using the client rectangle coordinates I’ll let you decipher the details; the important thing here is to investigate the business of printing 031 31240 -9 APP C 4/27/00 1:08 PM Page 64 1 Printing and Print Previewing 64 1 If you build and run the program after adding these lines to the OnDraw()... complex 100-page report using lots of GDI resources, you’d definitely find this technique useful in speeding up the printing USING COORDINATES FROM OnBeginPrinting() You might be tempted to also store the coordinates from OnBeginPrinting() This won’t work because CPrintInfo’s m_rectDraw member hasn’t been initialized by that stage and random coordinates will be used Customizing Device Context Preparation... pDC->LineTo(xm-xo,ym); pDC->LineTo(0,ym-yo); pDC->LineTo(xo,0); } // ** Reselect the old pen pDC->SelectObject(pOldPen); continues 031 31240 -9 APP C 4/27/00 1:08 PM 64 0 Page 64 0 Appendix C LISTING C.1 55: 56: 57: 58: 59: 60 : 61 : 62 : 63 : 64 : 65 : CONTINUED // ** Draw the text on top pDC->SetTextAlign(TA_CENTER+TA_BASELINE); pDC->SetBkMode(TRANSPARENT); // ** Set gray text pDC->SetTextColor(RGB (64 ,64 ,64 )); pDC->TextOut(xm/2,ym/2,”Sample... LARGEST PRINTED REPRESENTATION 1: 2: 3: 4: 5: 6: 7: 8: //** Declare a client rectangle and get the client rect CRect rcClient; GetClientRect(&rcClient); // ** Check the device context for printing mode if (pDC->IsPrinting()) { // ** Find the Print width : Window width ratio continues C 031 31240 -9 APP C 4/27/00 1:08 PM 64 6 Page 64 6 Appendix C LISTING C.3 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: ... DoPreparePrinting() function is called and passed the pInfo pointer to the CPrintInfo object for the print DoPreparePrinting() sets up the required device context and calls the standard Print dialog box if you are printing (not previewing) This dialog box is covered in more detail in the next section, but first you can set up a range of pages to print by modifying the CPrintInfo object before the DoPreparePrinting()... rectangle from the pInfo if (pInfo) m_rcPrintRect = pInfo->m_rectDraw; TODO comment, but before the 031 31240 -9 APP C 4/27/00 1:08 PM Page 64 3 Printing and Print Previewing 64 3 This will store the printing rectangle in the m_rcPrintRect member of the CPrintItView class You must therefore declare this member variable, which is easily done by rightclicking the CPrintItView class in the ClassView pane... shown by the print preview in Figure C.2 LISTING C.2 LST23_2.CPP—ADDING OnDraw() IMPLEMENTATION 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: PRINTING RECTANGLE SUPPORT TO THE STANDARD // Declare a client rectangle CRect rcClient; // ** Check the device context for printing mode if (pDC->IsPrinting()) { // ** Printing, so use the print rectangle rcClient = m_rcPrintRect; } else { // ** Not printing, so client . ////////////////////////////////////////////////////////////////////// 4: continues 030 31240 -9 APP B 4/27/00 1:07 PM Page 62 5 LISTING B. 29. CONTINUED 5: #include <stdlib.h> 6: #include <time.h> 7: 8: #include “stdafx.h” 9: #include “ LineLine.h” 10: #include “ModArt.h” 5 the view class source code, as in line 10 of Listing B. 26. 62 2 Appendix B 030 31240 -9 APP B 4/27/00 1:07 PM Page 62 2 Answers 62 3 B LISTING B. 26. THE CDbOdbcView INCLUDES. 1: // DbOdbcView.cpp. ::WaitForSingleObject (hThread, INFINITE); 13: } 14: } 15: else // We are running the thread 16: { 17: int iSpnr; 18: int iPriority; 19: // Which spinner to use? 20: switch (nIndex) 21: { 22:

Ngày đăng: 13/08/2014, 18:20

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan