From: Dan Crevier, dan@rhino.harvard.edu Subject: Mastering TCL errata ERRATA FOR MASTERING THE THINK CLASS LIBRARY BOOK (2/24/96) This file contains code that is missing or in error in the book. If you find other errors in the book (other than typos), please EMAIL me what needs to be corrected to one of the following adresses: CompuServe: 76556, 1132 Internet: rparker@s2.sonnet.com (Rich Parker) Several of the code examples in the book are missing #include statements or have other errors that this document addresses. Please make the following corrections or additions to your code. ======================================================================= CHAPTER 3: Managing the Document's Data On page-69, the CApp::DoNewDialog function includes the statement: filetype = CMainFType; This should be changed to read: *filetype = CMainFType; ----- Add the following #include statements at the top of the CApp.cp file, beginning on page-74: #include "CNewFile.h" #include "CMain.h" #include "CNewView.h" Also, in the CApp.h file, change the declaration of the GetDocTypeFromDialog function to read as follows: virtual OSType GetDocTypeFromDialog(CNewFile *dialog); The additions to the CNewView.h header file are not shown in the book. These are as follows: public: virtual void OpenFile(SFReply *macSFReply); protected: virtual void MakeNewWindow (void); ----- Also, the code for the OpenFile member function of the CNewView class wasn't shown in the section dealing with source code additions to the CNewView.cp source file. This function should be added, as follows: void CNewView::OpenFile (SFReply *macSFReply) { // override the immediate base class version of this // function in order to open a file using the version // implemented in the CTextData class. CTextData::OpenFile (macSFReply); } ======================================================================= CHAPTER 4: Creating a Business Account View When creating the NewAccount dialog, the following identifiers were assigned to the various controls in the VA (see pp. 114): Checking button: CheckingRadio Savings button: SavingsRadio Cash button: CashRadio Credit Card button: CreditRadio Asset button: AssetRadio Liability button: LiabilityRadio Account name field: AcctName Info field: InfoText The foregoing are used to generate the names that appear in the enumeration listed on page 133. ----- The code for the CMain::GetAcctSettings and CMain::UpdateMenus functions is not provided in the book. It is as follows: void CMain::GetAcctSettings (Boolean fromDocument, CNewAccountData *data) { if (fromDocument) { *data = itsAcctData; } else { itsAcctData = *data; } } void CMain::UpdateMenus() { Cell curCell = {0, 0}; long nextAccount = ((CApp *)gApplication)->theNextAccount; x_CMain::UpdateMenus(); if (itsMainPane != NULL) { if (!((CArrayPane *)itsMainPane)->GetSelect (TRUE, &curCell)) { gBartender->DisableCmd (cmdEditAcct); gBartender->DisableCmd (cmdDeleteAcct); } } else { gBartender->DisableCmd (cmdNewAcct); gBartender->DisableCmd (cmdEditAcct); gBartender->DisableCmd (cmdDeleteAcct); } for (long cmd = kFirstAcctCmdID; cmd < nextAccount; cmd++) { gBartender->EnableCmd (cmd); } } ----- Missing #include statements for CMain.cp file (pp. 126) Add the following #include statements at the top of the CMain.cp file: #include #include #include #include #include #include "CAccount.h" #include "CNewAccount.h" #include "CTransaction.h" #include "CAcctList.h" #include "CApp.h" #include "CMainList.h" also these statements: extern CBartender *gBartender; extern CDesktop *gDesktop extern CBureaucrat *gGopher; extern CApplication *gApplication; ----- Missing code from DoCmdDeleteAcct function on page 132 Add the following statement right after the "break;" statement, toward the top of the page: TCLForgetObject (anAccount); // delete the matching CAccount object ----- Missing code from functions in the CNewAccount class not documented: void CNewAccount::BeginData(CNewAccountData *initial) { // use data supplied by CMain's GetAcctSettings function ((CMain *)itsSupervisor)->GetAcctSettings (TRUE, initial); } void CNewAccount::EndData(CNewAccountData *final) { // return final settings to the CMain class ((CMain *)itsSupervisor)->GetAcctSettings (FALSE, final); } ======================================================================= Chapter 5: Examining the CFontList and CSizeList Code (page 208) The following declaration should be added to the CFontList.h header file that was generated by the VA: public: // overrides void GetCellText(Cell aCell, short availableWidth, StringPtr itsText); The corresponding definition of the GetCellText function to be added to the CFontList.cp file is as follows: /****************************************************************************** GetCellText (override) Get the contents of the indicated cell ******************************************************************************/ void CFontList::GetCellText (Cell aCell, short availableWidth, StringPtr itsText) { StringPtr pString; CArray *itsArray = GetArray(); itsArray->GetArrayItem (&pString, aCell.v+1); TCLpstrcpy(itsText, pString); } ----- The following declaration should be added to the CSizeList.h header file that was generated by the VA: public: // overrides void GetCellText (Cell aCell, short availableWidth, StringPtr itsText); Then add the following global "fontSizes" definitions to the beginning of the CSizeList.cp file, as follows: unsigned char *fontSizes[] = { "\p 8", "\p 9", "\p10", "\p12", "\p14", "\p16", "\p18", "\p20", "\p24", "\p28", "\p32", "\p36", "\p40", "\p48", "\p60", "\p64", "\p72", NULL }; Finally, add the following definition of the GetCellText function to the CSizeList.cp file, as follows: /****************************************************************************** GetCellText (override) Get the contents of the indicated cell ******************************************************************************/ void CSizeList::GetCellText (Cell aCell, short availableWidth, StringPtr itsText) { StringPtr pString; CArray *itsArray = GetArray(); itsArray->GetArrayItem (&pString, aCell.v+1); TCLpstrcpy(itsText, pString); } ======================================================================= Chapter 9: When you don't want to use Object I/O (page 406) At the top of page 406, right after the declaration of the WriteContents function, add the following inline function call and private variable declaration: virtual void OpenFile (SFReply *macSFReply) { CSimpleSaver::OpenFile(macSFReply); } private: Handle h; // text handle We have to override the OpenFile function because the x_CMain.h header file contains an empty version of this function. ----- Then on the same page (406) modify the ReadContents function to look like the following: void CMain::ReadContents (CFileStream *aStream) { h = aStream->GetHandle(); // read the file's data into the handle } ----- And then finally, put the remainder of the code that appeared in the original version of ReadContents into the ContentsToWindow function in the CMain.cp file, as follows: void CMain::ContentsToWindow() { HLock(h); try_ { fMain_TextPane->SetTextPtr(*h, GetHandleSize(h)); DisposeHandle(h); } catch_all_() { DisposeHandle(h); } end_try_ } =======================================================================