Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 80 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
80
Dung lượng
1,18 MB
Nội dung
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 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 [...]... 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: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 63 9 // TODO: add draw code for native data here // ** Set metric mapping pDC->SetMapMode(MM_LOMETRIC);... ** 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 Print”); // ** Reselect the old font... 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: 22: 23: 24: 25: 26: 27: 28: 29: 30:... if a specific selection of pages is chosen LISTING 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;... LST23_5.CPP—THE PRINTDLG 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: typedef struct tagPD { DWORD lStructSize; HWND hwndOwner; HANDLE hDevMode; HANDLE hDevNames; HDC hDC; DWORD Flags; WORD nFromPage; WORD nToPage; WORD nMinPage; WORD nMaxPage; WORD nCopies; STRUCTURE 031 31240 -9 APP C 4/27/00 1:08 PM Page 65 3 Printing and Print Previewing 13: 14: 15: 16: 17: 18: 19: 20: 21: 65 3 HINSTANCE hInstance; DWORD lCustData;... m_sListenSocket.Accept(sRjctSock); 11: // Send the rejection message 12: sRjctSock.Send(LPCTSTR(strMsg), strMsg.GetLength()); continues B 030 31240 -9 APP B 4/27/00 1:07 PM Page 63 4 63 4 Appendix B LISTING B. 36 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: } CONTINUED // Close the socket sRjctSock.Close(); } else { // Accept the connection request m_sListenSocket.Accept(m_sConnectSocket);\ //... Listing B.38 LISTING B.38 THE CWebBrowseView OnGoStart FUNCTION 1: void CWebBrowseView::OnGoStart() 2: { 3: // TODO: Add your command handler code here continues B 030 31240 -9 APP B 4/27/00 1:07 PM Page 63 6 63 6 Appendix B LISTING B.38 4: 5: 6: 7: } CONTINUED // Go to the start page GoHome(); Add a toolbar button for the menu ID IDM_GO_START 3 Disable the Stop toolbar button and menu entry when the application... here 4: 5: // ** Create and select the font 6: CFont fnTimes; 7: fnTimes.CreatePointFont(720,”Times New Roman”,pDC); 8: CFont* pOldFont=(CFont*)pDC->SelectObject(&fnTimes); 9: 10: // ** Create and select the brush 11: CBrush brHatch(HS_CROSS,RGB (64 ,64 ,64 )); 12: CBrush* pOldBrush = 13: (CBrush*)pDC->SelectObject(&brHatch); 14: 15: // ** Create the page text 16: CString strDocText; 17: strDocText.Format(“Page... Edit the function, adding the code in Listing B. 39 IDM_VIEW_STOP LISTING B. 39 THE CWebBrowseView OnUpdateViewStop FUNCTION 1: void CWebBrowseView::OnUpdateViewStop(CCmdUI* pCmdUI) 2: { 3: // TODO: Add your command update UI handler code here 4: 5: // Enable the button if busy 6: pCmdUI->Enable(GetBusy()); 7: } 031 31240 -9 APP C 4/27/00 1:07 PM Page 63 7 APPENDIX C Printing and Print Previewing by Jon... normal However, a lot now happens when printing, if the IsPrinting() test in line 6 returns TRUE First, you must find the ratios of the window width to the paper width and the 031 31240 -9 APP C 4/27/00 1:08 PM Page 64 7 Printing and Print Previewing 64 7 window height to the paper height You can find these ratios as shown in lines 9 and 13 by dividing the paper dimensions by the window dimensions The next . Set gray text 60 : pDC->SetTextColor(RGB (64 ,64 ,64 )); 61 : pDC->TextOut(xm/2,ym/2,”Sample Print”); 62 : 63 : // ** Reselect the old font 64 : pDC->SelectObject(pOldFont); 65 : } 64 0 Appendix. as LineDll. Specify that the DLL will be an MFC extension DLL. 62 6 Appendix B 030 31240 -9 APP B 4/27/00 1:07 PM Page 62 6 Answers 62 7 B After generating the project skeleton, copy the line source. Go menu. Specify the menu entry properties in Table B .6. 63 4 Appendix B 030 31240 -9 APP B 4/27/00 1:07 PM Page 63 4 Answers 63 5 B TABLE B .6. MENU PROPERTY SETTINGS. Object Property Setting Menu