Chapter 5 erratap132-print, p248-pdf The last sentence of the second paragraph should be removed. The first sentence of the third paragraph should be changed from: First ... to: Before we discuss how this is done ... p133-print, p249-pdf The second paragraph should be changed to the following: Displaying a hint after a pause, as is normally done can be done in one of two ways. The first is to use CancelHint() in place of ActivateHint(). This cancels any current hint and resets the control's hint status allowing further hints for the control to be displayed. The second is to use the WinAPI SetTimer() function to install a callback function that lets us know when the desired time period has elapsed. When it has, the hint is displayed using ActivateHint(). For this several functions are required. The additional declarations needed in the form's header file are shown in Listing 5.6. p133-print, p249-pdf Listing 5.7 contains several problems and should be replaced with the following (note that a line was also removed): //---------------------------------------------------------------------------//
void CALLBACK TMainForm::HintTimerCallback(HWND Wnd,
UINT Msg,
UINT TimerID,
DWORD Time)
{
// Add a bit of type safety
TObject* VCLObject = reinterpret_cast<TObject*>(TimerID);
TMainForm* MainFormObject = dynamic_cast<TMainForm*>(VCLObject);
if(MainFormObject) MainFormObject->HintTimerExpired();
}
//---------------------------------------------------------------------------//
void __fastcall TMainForm::HintTimerExpired()
{
StopHintTimer();
Application->ActivateHint(Mouse->CursorPos);
}
//---------------------------------------------------------------------------//
void __fastcall TMainForm::DisplayHint(int Pause)
{
StopHintTimer();
Application->HideHint();
HintTimerHandle = SetTimer(Handle,
reinterpret_cast
See also the CD-ROM Files section at the end of this document. p135-print, p251-pdf The first two paragraphs need to be changed due to the previous changes in Listing 5.7. Replace the paragraphs with the following: When DisplayHint() is called, it first stops any previous timer that is in use. It then hides any currently displayed hint. Finally it sets a new timer, passing as arguments the window handle of the current form (Handle); the this pointer as the TimerID parameter, allowing the HintTimerExpired() function to be called from the static callback function; the required delay in milliseconds (Pause); and a pointer to the callback function to receive the message that the timer has finished. Notice that the this pointer needs to be cast to an UINT and the callback function pointer needs to be cast to TIMERPROC. In the first case we use reinterpret_cast because we are casting a pointer type to non-pointer type and in the second case because we are casting a function pointer. When the timer expires, our callback function is called. It has four parameters, but we are interested in only the second, the UINT TimerID parameter. This is where we stored our this pointer in the call to SetTimer(). With this we can call the HintTimerExpired() function to actually display the hint. Because the TimerID is not a pointer, we first cast it to a TObject* using reinterpret_cast. Then we try to cast the TObject* to a TMainForm* using dynamic_cast. This gives us a chance to check if the pointer is valid before we dereference it. Dereferencing an invalid pointer is an access violation and something we would like to avoid. p166-print, p282-pdf The end of listing line in Listing 5.19 should be moved down to include the last two lines of the code listing. p175-print, p291-pdf The lower akBottom box on the right of Figure 5.6 should have the longest dashes in the box outline, as per the first item in the Key. A more clear figure using shading is provided in the file 05Fig06.zip p212-print, p328-pdf Change the third paragraph to the following. This describes why the there are problems using the technique due to bugs in C++Builder. When you create an application, set the designtime PixelsPerInch property of the forms you use as this indicates the font size used during development. This allows you to resize controls when a different font size is used during runtime. Relying solely on the forms' property to represent designtime font size does not work. See the sample project ScreenInfo.bpr for an example. By default, TForm's Scaled property is set to true. This means that your form and the controls on them will be automatically resized when the font size changes, though the form size itself will not be altered. In many cases, such as in the MiniCalculator program, you do not want this to happen. To prevent this automatic scaling, set Scaled to false. To determine the font size at runtime, simply read the PixelsPerInch property of the global Screen variable. CD-ROM The following file should be replaced with the file Unit1.cpp It contains important fixes as listed in the changes to the text earlier in this document: \source\Chapter05\MiniCalculator\Unit1.cpp A correct complete set of files for the Chapter05 folder is provided in the file Chapter05.zip |